commit e9a7a1682643dde44fa5a81b66be9a068aed6736 Author: huntedbytheirs Date: Sun Aug 23 00:38:40 2026 -0400 Initial commit from Ventoy@7cbdc5c diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..ccba0db --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +patreon: # Replace with a single Patreon username +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: Ventoy +open_collective: ventoy +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: ['https://www.paypal.me/ventoy', 'https://www.ventoy.net/en/donation.html'] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..3ba13e0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1 @@ +blank_issues_enabled: false diff --git a/.github/ISSUE_TEMPLATE/issue_template.yml b/.github/ISSUE_TEMPLATE/issue_template.yml new file mode 100644 index 0000000..8c0dd60 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/issue_template.yml @@ -0,0 +1,110 @@ +name: Issue Report +description: File an issue report +title: "[issue]: " +assignees: + - octocat +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this issue report! + - type: checkboxes + id: faq + attributes: + label: Official FAQ + description: Have you checked the official FAQ at [https://www.ventoy.net/en/faq.html](https://www.ventoy.net/en/faq.html) ? + options: + - label: I have checked the official FAQ. + required: true + - type: input + id: version + attributes: + label: Ventoy Version + description: What version of ventoy are you running? + placeholder: 1.0.96 + validations: + required: true + - type: dropdown + id: latestrelease + attributes: + label: What about latest release + description: Have you tried with the latest release of Ventoy? + options: + - Yes. I have tried the latest release, but the bug still exist. + - No. I didn't try the latest release. + validations: + required: true + - type: dropdown + id: alternativemode + attributes: + label: Try alternative boot mode + description: Have you tried alternative boot mode? (wimboot mode for Windows/WinPE, grub2 mode for linux) + options: + - Yes. I have tried them, but the bug still exist. + - No. I didn't try these alternative boot modes. + validations: + required: true + - type: dropdown + id: bios + attributes: + label: BIOS Mode + description: In which BIOS mode did you find the bug? + options: + - Legacy BIOS Mode + - UEFI Mode + - Both + validations: + required: true + - type: dropdown + id: partstyle + attributes: + label: Partition Style + description: Which partition style did you select when you install Ventoy? + options: + - MBR + - GPT + validations: + required: true + - type: input + id: capacity + attributes: + label: Disk Capacity + description: What is the capacity of the disk installed with Ventoy? + placeholder: 32GB + validations: + required: true + - type: input + id: vendor + attributes: + label: Disk Manufacturer + description: What is the manufacturer of the disk installed with Ventoy? (e.g. SanDisk/Kingston...) + validations: + required: false + - type: dropdown + id: checksum + attributes: + label: Image file checksum (if applicable) + description: Have you checked the image file in Ventoy's menu as [https://www.ventoy.net/en/faq.html#faq_boot_checksum](https://www.ventoy.net/en/faq.html#faq_boot_checksum) ? + options: + - Yes. + - No. + validations: + required: false + - type: input + id: link + attributes: + label: Image file download link (if applicable) + description: What is the image file download link? + placeholder: https://xxx + validations: + required: false + - type: textarea + id: what-happened + attributes: + label: What happened? + description: Tell me what happened. It's highly recommended to include some photo or video about the bug. + placeholder: Tell us what you see! + value: "A bug happened!" + validations: + required: true + diff --git a/.github/ISSUE_TEMPLATE/success_image_report.yml b/.github/ISSUE_TEMPLATE/success_image_report.yml new file mode 100644 index 0000000..7dda0ef --- /dev/null +++ b/.github/ISSUE_TEMPLATE/success_image_report.yml @@ -0,0 +1,101 @@ +name: Success Image Report +description: To report an image file that boot successfully in Ventoy and is not yet listed in https://www.ventoy.net/en/isolist.html +title: "[Success Image Report]: " +assignees: + - octocat +body: + - type: markdown + attributes: + value: | + I list all the successfully tested image files in the official website: https://www.ventoy.net/en/isolist.html + If you successfully test an image file which is not listed in the above page, you can tell me and I will be very glad to add it to the tested list. + - type: checkboxes + id: faq + attributes: + label: Official Website List + description: Have you checked the list at [https://www.ventoy.net/en/isolist.html](https://www.ventoy.net/en/isolist.html) and the image file is not listed? + options: + - label: I have checked the list in official website and the image file is not listed there. + required: true + - type: input + id: version + attributes: + label: Ventoy Version + description: What version of ventoy did you test with the image file. + placeholder: 1.0.57 + validations: + required: true + - type: dropdown + id: bios + attributes: + label: BIOS Mode + description: In which BIOS mode did you successfully test the image file? (It's recommended to test in both mode) + options: + - Legacy BIOS Mode + - UEFI Mode + - Both + validations: + required: true + - type: dropdown + id: partstyle + attributes: + label: Partition Style + description: Which partition style did you use with Ventoy? + options: + - MBR + - GPT + validations: + required: true + - type: input + id: filename + attributes: + label: Image file name + description: The successfully tested image file name. + placeholder: xxxx.iso + validations: + required: true + - type: dropdown + id: checksum + attributes: + label: Image file checksum type + description: + options: + - MD5 + - SHA1 + - SHA256 + - SHA512 + validations: + required: true + - type: input + id: checkvalue + attributes: + label: Image file checksum value + description: What is the image file checksum value corresponding to the above checksum type? + placeholder: xxxx + validations: + required: true + - type: input + id: link + attributes: + label: Image file download link (if applicable) + description: What is the image file download link? + placeholder: https://xxx + validations: + required: false + - type: input + id: testenv + attributes: + label: Test environment + description: The manufacturer/model and other details about your computer (or VM). + placeholder: Lenovo Thinkpad T420 laptop + validations: + required: true + - type: textarea + id: details + attributes: + label: More Details? + description: You can give more details here. + value: "This image file booted successfully in Ventoy." + validations: + required: false + diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..c626a91 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,37 @@ +name: Ventoy CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Run docker compose up + run: docker compose up + - uses: actions/upload-artifact@v4 + with: + name: ventoy-windows + path: INSTALL/ventoy-*windows* + - uses: actions/upload-artifact@v4 + with: + name: ventoy-linux + path: INSTALL/ventoy-*linux* + - uses: actions/upload-artifact@v4 + with: + name: ventoy-livecd + path: INSTALL/ventoy-*livecd* + - uses: actions/upload-artifact@v4 + with: + name: SHA256SUM + path: INSTALL/sha256.txt + - uses: actions/upload-artifact@v4 + with: + name: xxx-build-log + path: DOC/build.log diff --git a/.github/workflows/sync2gitee.yml b/.github/workflows/sync2gitee.yml new file mode 100644 index 0000000..2fd7e87 --- /dev/null +++ b/.github/workflows/sync2gitee.yml @@ -0,0 +1,25 @@ +name: Mirror GitHub to Gitee + +on: + # Triggers the workflow on push or pull request events but only for the main branch + push: + branches: [ master ] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +jobs: + run: + name: Sync-GitHub-to-Gitee + if: ${{ github.repository_owner == 'ventoy' }} + runs-on: ubuntu-latest + steps: + - name: Mirror the Github repos to Gitee. + uses: Yikun/hub-mirror-action@master + with: + src: github/ventoy + dst: gitee/LongPanda + dst_key: ${{ secrets.GITEE_PRIVATE_KEY }} + dst_token: ${{ secrets.GITEE_TOKEN }} + static_list: "Ventoy" + force_update: true diff --git a/BLOB_List.md b/BLOB_List.md new file mode 100644 index 0000000..4427aca --- /dev/null +++ b/BLOB_List.md @@ -0,0 +1,194 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BLOBFile SourceDesc
./BUSYBOX/chmod/vtchmod32 build Build Instructions:
./BUSYBOX/chmod/build.sh
./BUSYBOX/chmod/vtchmod64
./BUSYBOX/chmod/vtchmod64_musl
./BUSYBOX/chmod/vtchmodaa64
./BUSYBOX/chmod/vtchmodm64e
./cryptsetup/veritysetup32 build Build Instructions:
./cryptsetup/cryptsetup-build.txt
./cryptsetup/veritysetup64
./DMSETUP/dmsetup32 build Build Instructions:
./DMSETUP/build.txt
./DMSETUP/dmsetup64
./DMSETUP/dmsetupaa64
./DMSETUP/dmsetupm64e
./FUSEISO/vtoy_fuse_iso_32 build Build Instructions:
./FUSEISO/build.sh
./FUSEISO/build_aarch64.sh
./FUSEISO/build_libfuse.sh
./FUSEISO/build_libfuse_aarch64.sh
./FUSEISO/vtoy_fuse_iso_64
./FUSEISO/vtoy_fuse_iso_aa64
./IMG/cpio_arm64/ventoy/busybox/a64 build Build Instructions:
./BUSYBOX/build.txt ash
./IMG/cpio_arm64/ventoy/busybox/vtchmodaa64 build Same with ./BUSYBOX/chmod/vtchmodaa64
Check the file hash to confirm
./IMG/cpio_arm64/ventoy/busybox/xzminidecaa64 build Build Instructions:
./DOC/BuildVentoyFromSource.txt 4.17
./IMG/cpio_arm64/ventoy/tool/lz4cataa64 build Same with ./LZIP/lz4cataa64
Check the file hash to confirm
./IMG/cpio_arm64/ventoy/tool/zstdcataa64 build Same with ./ZSTD/zstdcataa64
Check the file hash to confirm
./IMG/cpio_mips64/ventoy/busybox/m64 build Build Instructions:
./BUSYBOX/build.txt ash
./IMG/cpio_mips64/ventoy/busybox/vtchmodm64e build Same with ./BUSYBOX/chmod/vtchmodm64e
Check the file hash to confirm
./IMG/cpio_mips64/ventoy/busybox/xzminidecm64e build Build Instructions:
./DOC/BuildVentoyFromSource.txt 4.18
./IMG/cpio_mips64/ventoy/tool/lz4catm64e build Same with ./LZIP/lz4catm64e
Check the file hash to confirm
./IMG/cpio_x86/ventoy/busybox/64h build Build Instructions:
./BUSYBOX/build.txt ash
./IMG/cpio_x86/ventoy/busybox/ash upstream Download from BusyBox website.
URL & File Hash documented in
./DOC/BuildVentoyFromSource.txt 5.4
./IMG/cpio_x86/ventoy/busybox/vtchmod32 build Same with ./BUSYBOX/chmod/vtchmod32
Check the file hash to confirm
./IMG/cpio_x86/ventoy/busybox/vtchmod64 build Same with ./BUSYBOX/chmod/vtchmod64
Check the file hash to confirm
./IMG/cpio_x86/ventoy/busybox/vtchmod64_musl build Same with ./BUSYBOX/chmod/vtchmod64_musl
Check the file hash to confirm
./IMG/cpio_x86/ventoy/busybox/xzminidec32 build Build Instructions:
./DOC/BuildVentoyFromSource.txt 4.15
./IMG/cpio_x86/ventoy/busybox/xzminidec64 build Build Instructions:
./DOC/BuildVentoyFromSource.txt 4.16
./IMG/cpio_x86/ventoy/busybox/xzminidec64_musl build Build Instructions:
./DOC/BuildVentoyFromSource.txt 4.16
./IMG/cpio_x86/ventoy/tool/ar upstream Download from BusyBox website.
URL & File Hash documented in
./DOC/BuildVentoyFromSource.txt 5.2
./IMG/cpio_x86/ventoy/tool/inotifyd upstream Download from BusyBox website.
URL & File Hash documented in
./DOC/BuildVentoyFromSource.txt 5.3
./IMG/cpio_x86/ventoy/tool/lz4cat upstream URL & File Hash documented in
./DOC/BuildVentoyFromSource.txt 5.1
./IMG/cpio_x86/ventoy/tool/lz4cat64 build Build Instructions:
./LZIP/buildlz4.txt
./IMG/cpio_x86/ventoy/tool/zstdcat build Same with ./ZSTD/zstdcat
Check the file hash to confirm
./IMG/cpio_x86/ventoy/tool/zstdcat64 build Same with ./ZSTD/zstdcat64
Check the file hash to confirm
./INSTALL/EFI/BOOT/BOOTAA64.EFI build Build Instructions:
./DOC/BuildVentoyFromSource.txt 4.1-Build grub2
./INSTALL/EFI/BOOT/BOOTMIPS.EFI
./INSTALL/EFI/BOOT/grubia32_real.efi
./INSTALL/EFI/BOOT/grubx64_real.efi
./INSTALL/EFI/BOOT/BOOTIA32.EFI upstream https://github.com/ValdikSS/Super-UEFIinSecureBoot-Disk
./INSTALL/EFI/BOOT/grubia32.efi
./INSTALL/EFI/BOOT/mmia32.efi
./INSTALL/EFI/BOOT/BOOTX64.EFI upstream From Rocky Linux 9.8 x86_64 ISO file
Check the file hash to confirm
./INSTALL/EFI/BOOT/mmx64.efi
./INSTALL/tool/aarch64/ash build Build Instructions:
./DOC/BUSYBOX/build.txt
./INSTALL/tool/aarch64/hexdump
./INSTALL/tool/aarch64/xzcat
./INSTALL/tool/i386/ash
./INSTALL/tool/i386/hexdump
./INSTALL/tool/i386/xzcat
./INSTALL/tool/mips64el/ash
./INSTALL/tool/mips64el/hexdump
./INSTALL/tool/mips64el/xzcat
./INSTALL/tool/x86_64/ash
./INSTALL/tool/x86_64/hexdump
./INSTALL/tool/x86_64/xzcat
./INSTALL/tool/aarch64/Ventoy2Disk.gtk3 build Build Instructions:
./LinuxGUI/build_gtk.sh
./INSTALL/tool/i386/Ventoy2Disk.gtk3
./INSTALL/tool/i386/Ventoy2Disk.gtk2
./INSTALL/tool/mips64el/Ventoy2Disk.gtk3
./INSTALL/tool/x86_64/Ventoy2Disk.gtk3
./INSTALL/tool/x86_64/Ventoy2Disk.gtk2
./INSTALL/tool/aarch64/Ventoy2Disk.qt5 build Build Instructions:
./LinuxGUI/build_qt.sh
./INSTALL/tool/i386/Ventoy2Disk.qt5
./INSTALL/tool/mips64el/Ventoy2Disk.qt5
./INSTALL/tool/x86_64/Ventoy2Disk.qt5
./INSTALL/tool/aarch64/Plugson build Build Instructions:
./Plugson/build.sh
./INSTALL/tool/i386/Plugson
./INSTALL/tool/mips64el/Plugson
./INSTALL/tool/x86_64/Plugson
./INSTALL/tool/aarch64/V2DServer build Build Instructions:
./LinuxGUI/build.sh
./INSTALL/tool/i386/V2DServer
./INSTALL/tool/mips64el/V2DServer
./INSTALL/tool/x86_64/V2DServer
./INSTALL/tool/aarch64/mkexfatfs build Build Instructions:
./DOC/BuildVentoyFromSource.txt 4.9
./ExFAT/buidexfat.sh
./ExFAT/buidexfat_aarch64.sh
./ExFAT/buidlibfuse.sh
./ExFAT/buidlibfuse_aarch64.sh
./INSTALL/tool/aarch64/mount.exfat-fuse
./INSTALL/tool/i386/mkexfatfs
./INSTALL/tool/i386/mount.exfat-fuse
./INSTALL/tool/mips64el/mkexfatfs
./INSTALL/tool/mips64el/mount.exfat-fuse
./INSTALL/tool/x86_64/mkexfatfs
./INSTALL/tool/x86_64/mkexfatfs_static
./INSTALL/tool/x86_64/mount.exfat-fuse
./INSTALL/tool/aarch64/vlnk build Build Instructions:
./Vlnk/build.sh
./INSTALL/tool/i386/vlnk
./INSTALL/tool/mips64el/vlnk
./INSTALL/tool/x86_64/vlnk
./INSTALL/tool/aarch64/vtoycli build Build Instructions:
./vtoycli/build.sh
./INSTALL/tool/i386/vtoycli
./INSTALL/tool/mips64el/vtoycli
./INSTALL/tool/x86_64/vtoycli
./INSTALL/ventoy/imdisk/32/imdisk.cpl upstream Download from imdisk project.
URL & File Hash documented in
./DOC/BuildVentoyFromSource.txt 5.8
./INSTALL/ventoy/imdisk/32/imdisk.exe
./INSTALL/ventoy/imdisk/32/imdisk.sys
./INSTALL/ventoy/imdisk/64/imdisk.cpl
./INSTALL/ventoy/imdisk/64/imdisk.exe
./INSTALL/ventoy/imdisk/64/imdisk.sys
./INSTALL/ventoy/iso9660_aa64.efi build Build Instructions:
./DOC/BuildVentoyFromSource.txt 4.17
./INSTALL/ventoy/udf_aa64.efi
./INSTALL/ventoy/iso9660_ia32.efi
./INSTALL/ventoy/udf_ia32.efi
./INSTALL/ventoy/iso9660_x64.efi
./INSTALL/ventoy/udf_x64.efi
./INSTALL/VentoyGUI.aarch64 build Build Instructions:
./LinuxGUI/build_gtk.sh
./INSTALL/VentoyGUI.i386
./INSTALL/VentoyGUI.mips64el
./INSTALL/VentoyGUI.x86_64
./INSTALL/Ventoy2Disk.exe build Build Instructions:
./Ventoy2Disk/Ventoy2Disk.sln
./INSTALL/Ventoy2Disk_ARM.exe
./INSTALL/Ventoy2Disk_ARM64.exe
./INSTALL/Ventoy2Disk_X64.exe
./INSTALL/ventoy/vtoyjump32.exe build Build Instructions:
./vtoyjump/vtoyjump.sln
./INSTALL/ventoy/vtoyjump64.exe
./INSTALL/ventoy/ventoy_aa64.efi build Build Instructions:
./EDK2/buildedk.sh
./INSTALL/ventoy/ventoy_ia32.efi
./INSTALL/ventoy/ventoy_x64.efi
./INSTALL/ventoy/vtoyutil_aa64.efi
./INSTALL/ventoy/vtoyutil_ia32.efi
./INSTALL/ventoy/vtoyutil_x64.efi
./INSTALL/EFI/BOOT/fbx64.efi
./INSTALL/ventoy/ipxe.krn build Build Instructions:
./IPXE/buildipxe.sh
./INSTALL/ventoy/memdisk upstream Download from syslinux project.
URL & File Hash documented in
./DOC/BuildVentoyFromSource.txt 5.9
./LiveCD/ISO/EFI/boot/vmlinuz64 upstream Download from TinyLinux website.
URL & File Hash documented in
./DOC/BuildVentoyFromSource.txt 5.14
./LiveCDGUI/EXT/busybox-x86_64 build Same with ./IMG/cpio_x86/ventoy/busybox/busybox64
Check the file hash to confirm
./LiveCDGUI/GRUB/bootx64.efi build ./DOC/BuildVentoyFromSource.txt 4.1-Build grub2
./LiveCD/GRUB/bootx64.efi
./LZIP/lunzip32 build Build Instructions:
./DOC/BuildVentoyFromSource.txt 4.19
./LZIP/lunzip64
./LZIP/lunzipaa64
./LZIP/lz4cat64 build Build Instructions:
./LZIP/buildlz4.txt
./LZIP/lz4cataa64
./LZIP/lz4catm64e
./Plugson/vs/VentoyPlugson/Release/VentoyPlugson.exe build Build Instructions:
./Plugson/vs/VentoyPlugson/VentoyPlugson.sln
./Plugson/vs/VentoyPlugson/x64/Release/VentoyPlugson_X64.exe
./SQUASHFS/unsquashfs_32 build Build Instructions:
./SQUASHFS/build.sh
./SQUASHFS/unsquashfs_64
./SQUASHFS/unsquashfs_aa64
./Unix/ventoy_unix/DragonFly/sbin/dmsetup upstream Get from DragonFly ISO.
URL & File Hash documented in
./DOC/BuildVentoyFromSource.txt 5.13
./Unix/ventoy_unix/DragonFly/sbin/init build Build Instructions:
./Unix/ventoy_unix_src/DragonFly/build.sh
./VBLADE/vblade-master/vblade_32 build Build Instructions:
./VBLADE/vblade-master/build.sh
./VBLADE/vblade-master/vblade_64
./VBLADE/vblade-master/vblade_aa64
./Vlnk/vs/VentoyVlnk/Release/VentoyVlnk.exe build Build Instructions:
./Vlnk/vs/VentoyVlnk/VentoyVlnk.sln
./VtoyTool/vtoytool/00/vtoytool_32 build Build Instructions:
./VtoyTool/build.sh
./VtoyTool/vtoytool/00/vtoytool_64
./VtoyTool/vtoytool/00/vtoytool_aa64
./VtoyTool/vtoytool/00/vtoytool_m64e
./VtoyTool/vtoytool/01/vtoytool_64
./VtoyTool/vtoytool/02/vtoytool_64
./ZSTD/zstdcat build Build Instructions:
./ZSTD/build.txt
./ZSTD/zstdcat64
./ZSTD/zstdcataa64
./IMG/cpio_x86/ventoy/busybox/busybox32 build Build Instructions:
./BUSYBOX/build.txt full busybox
./IMG/cpio_x86/ventoy/busybox/busybox64
./IMG/cpio_x86/ventoy/busybox/xzcat32_musl
./IMG/cpio_x86/ventoy/busybox/xzcat64_musl
./IMG/cpio_arm64/ventoy/busybox/busyboxaa64
./IMG/cpio_mips64/ventoy/busybox/busyboxm64e
ISNTALL/ventoy/7z/64/7za.exe upstream Download from 7z project.
URL & File Hash documented in
./DOC/BuildVentoyFromSource.txt 5.12
ISNTALL/ventoy/7z/32/7za.exe
./INSTALL/ventoy/wimboot.i386.efi build Build Instructions:
./wimboot/build.sh
./INSTALL/ventoy/wimboot.x86_64
./Unix/ventoy_unix/ClonOS/geom_ventoy_ko/13.x/64/geom_ventoy.ko build Build Instructions:
./Unix/BuildUnixKmod.txt
./Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/10.x/32/geom_ventoy.ko
./Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/10.x/64/geom_ventoy.ko
./Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/11.x/32/geom_ventoy.ko
./Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/11.x/64/geom_ventoy.ko
./Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/12.x/32/geom_ventoy.ko
./Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/12.x/64/geom_ventoy.ko
./Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/13.x/32/geom_ventoy.ko
./Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/13.x/64/geom_ventoy.ko
./Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/14.x/32/geom_ventoy.ko
./Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/14.x/64/geom_ventoy.ko
./Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/9.x/32/geom_ventoy.ko
./Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/9.x/64/geom_ventoy.ko
./Unix/ventoy_unix/MidnightBSD/geom_ventoy_ko/11.x/32/geom_ventoy.ko
./Unix/ventoy_unix/MidnightBSD/geom_ventoy_ko/11.x/64/geom_ventoy.ko
./Unix/ventoy_unix/MidnightBSD/geom_ventoy_ko/2.x/32/geom_ventoy.ko
./Unix/ventoy_unix/MidnightBSD/geom_ventoy_ko/2.x/64/geom_ventoy.ko
./Unix/ventoy_unix/pfSense/geom_ventoy_ko/14.x/64/geom_ventoy.ko
diff --git a/BUSYBOX/aarch64_ash.config b/BUSYBOX/aarch64_ash.config new file mode 100644 index 0000000..3285477 --- /dev/null +++ b/BUSYBOX/aarch64_ash.config @@ -0,0 +1,1166 @@ +# +# Automatically generated make config: don't edit +# Busybox version: 1.32.0 +# Fri Aug 7 05:44:56 2020 +# +CONFIG_HAVE_DOT_CONFIG=y + +# +# Settings +# +# CONFIG_DESKTOP is not set +# CONFIG_EXTRA_COMPAT is not set +# CONFIG_FEDORA_COMPAT is not set +# CONFIG_INCLUDE_SUSv2 is not set +# CONFIG_LONG_OPTS is not set +# CONFIG_SHOW_USAGE is not set +# CONFIG_FEATURE_VERBOSE_USAGE is not set +# CONFIG_FEATURE_COMPRESS_USAGE is not set +# CONFIG_LFS is not set +# CONFIG_PAM is not set +# CONFIG_FEATURE_DEVPTS is not set +# CONFIG_FEATURE_UTMP is not set +# CONFIG_FEATURE_WTMP is not set +# CONFIG_FEATURE_PIDFILE is not set +CONFIG_PID_FILE_PATH="" +# CONFIG_BUSYBOX is not set +# CONFIG_FEATURE_SHOW_SCRIPT is not set +# CONFIG_FEATURE_INSTALLER is not set +# CONFIG_INSTALL_NO_USR is not set +# CONFIG_FEATURE_SUID is not set +# CONFIG_FEATURE_SUID_CONFIG is not set +# CONFIG_FEATURE_SUID_CONFIG_QUIET is not set +# CONFIG_FEATURE_PREFER_APPLETS is not set +CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" +# CONFIG_SELINUX is not set +# CONFIG_FEATURE_CLEAN_UP is not set +# CONFIG_FEATURE_SYSLOG_INFO is not set +# CONFIG_FEATURE_SYSLOG is not set +# CONFIG_PLATFORM_LINUX is not set + +# +# Build Options +# +CONFIG_STATIC=y +# CONFIG_PIE is not set +# CONFIG_NOMMU is not set +# CONFIG_BUILD_LIBBUSYBOX is not set +# CONFIG_FEATURE_LIBBUSYBOX_STATIC is not set +# CONFIG_FEATURE_INDIVIDUAL is not set +# CONFIG_FEATURE_SHARED_BUSYBOX is not set +CONFIG_CROSS_COMPILER_PREFIX="" +CONFIG_SYSROOT="" +CONFIG_EXTRA_CFLAGS="" +CONFIG_EXTRA_LDFLAGS="" +CONFIG_EXTRA_LDLIBS="" +# CONFIG_USE_PORTABLE_CODE is not set +# CONFIG_STACK_OPTIMIZATION_386 is not set + +# +# Installation Options ("make install" behavior) +# +CONFIG_INSTALL_APPLET_SYMLINKS=y +# CONFIG_INSTALL_APPLET_HARDLINKS is not set +# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set +# CONFIG_INSTALL_APPLET_DONT is not set +# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set +# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set +# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set +CONFIG_PREFIX="./_install" + +# +# Debugging Options +# +# CONFIG_DEBUG is not set +# CONFIG_DEBUG_PESSIMIZE is not set +# CONFIG_DEBUG_SANITIZE is not set +# CONFIG_UNIT_TEST is not set +# CONFIG_WERROR is not set +# CONFIG_WARN_SIMPLE_MSG is not set +CONFIG_NO_DEBUG_LIB=y +# CONFIG_DMALLOC is not set +# CONFIG_EFENCE is not set + +# +# Library Tuning +# +# CONFIG_FEATURE_USE_BSS_TAIL is not set +# CONFIG_FLOAT_DURATION is not set +# CONFIG_FEATURE_RTMINMAX is not set +# CONFIG_FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS is not set +CONFIG_FEATURE_BUFFERS_USE_MALLOC=y +# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set +# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set +CONFIG_PASSWORD_MINLEN=6 +CONFIG_MD5_SMALL=1 +CONFIG_SHA3_SMALL=1 +# CONFIG_FEATURE_FAST_TOP is not set +# CONFIG_FEATURE_ETC_NETWORKS is not set +# CONFIG_FEATURE_ETC_SERVICES is not set +# CONFIG_FEATURE_EDITING is not set +CONFIG_FEATURE_EDITING_MAX_LEN=0 +# CONFIG_FEATURE_EDITING_VI is not set +CONFIG_FEATURE_EDITING_HISTORY=0 +# CONFIG_FEATURE_EDITING_SAVEHISTORY is not set +# CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set +# CONFIG_FEATURE_REVERSE_SEARCH is not set +# CONFIG_FEATURE_TAB_COMPLETION is not set +# CONFIG_FEATURE_USERNAME_COMPLETION is not set +# CONFIG_FEATURE_EDITING_FANCY_PROMPT is not set +# CONFIG_FEATURE_EDITING_WINCH is not set +# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set +# CONFIG_LOCALE_SUPPORT is not set +# CONFIG_UNICODE_SUPPORT is not set +# CONFIG_UNICODE_USING_LOCALE is not set +# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set +CONFIG_SUBST_WCHAR=0 +CONFIG_LAST_SUPPORTED_WCHAR=0 +# CONFIG_UNICODE_COMBINING_WCHARS is not set +# CONFIG_UNICODE_WIDE_WCHARS is not set +# CONFIG_UNICODE_BIDI_SUPPORT is not set +# CONFIG_UNICODE_NEUTRAL_TABLE is not set +# CONFIG_UNICODE_PRESERVE_BROKEN is not set +# CONFIG_FEATURE_NON_POSIX_CP is not set +# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set +# CONFIG_FEATURE_USE_SENDFILE is not set +CONFIG_FEATURE_COPYBUF_KB=4 +# CONFIG_FEATURE_SKIP_ROOTFS is not set +# CONFIG_MONOTONIC_SYSCALL is not set +# CONFIG_IOCTL_HEX2STR_ERROR is not set +# CONFIG_FEATURE_HWIB is not set + +# +# Applets +# + +# +# Archival Utilities +# +# CONFIG_FEATURE_SEAMLESS_XZ is not set +# CONFIG_FEATURE_SEAMLESS_LZMA is not set +# CONFIG_FEATURE_SEAMLESS_BZ2 is not set +# CONFIG_FEATURE_SEAMLESS_GZ is not set +# CONFIG_FEATURE_SEAMLESS_Z is not set +# CONFIG_AR is not set +# CONFIG_FEATURE_AR_LONG_FILENAMES is not set +# CONFIG_FEATURE_AR_CREATE is not set +# CONFIG_UNCOMPRESS is not set +# CONFIG_GUNZIP is not set +# CONFIG_ZCAT is not set +# CONFIG_FEATURE_GUNZIP_LONG_OPTIONS is not set +# CONFIG_BUNZIP2 is not set +# CONFIG_BZCAT is not set +# CONFIG_UNLZMA is not set +# CONFIG_LZCAT is not set +# CONFIG_LZMA is not set +# CONFIG_UNXZ is not set +# CONFIG_XZCAT is not set +# CONFIG_XZ is not set +# CONFIG_BZIP2 is not set +CONFIG_BZIP2_SMALL=0 +# CONFIG_FEATURE_BZIP2_DECOMPRESS is not set +# CONFIG_CPIO is not set +# CONFIG_FEATURE_CPIO_O is not set +# CONFIG_FEATURE_CPIO_P is not set +# CONFIG_DPKG is not set +# CONFIG_DPKG_DEB is not set +# CONFIG_GZIP is not set +# CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set +CONFIG_GZIP_FAST=0 +# CONFIG_FEATURE_GZIP_LEVELS is not set +# CONFIG_FEATURE_GZIP_DECOMPRESS is not set +# CONFIG_LZOP is not set +# CONFIG_UNLZOP is not set +# CONFIG_LZOPCAT is not set +# CONFIG_LZOP_COMPR_HIGH is not set +# CONFIG_RPM is not set +# CONFIG_RPM2CPIO is not set +# CONFIG_TAR is not set +# CONFIG_FEATURE_TAR_LONG_OPTIONS is not set +# CONFIG_FEATURE_TAR_CREATE is not set +# CONFIG_FEATURE_TAR_AUTODETECT is not set +# CONFIG_FEATURE_TAR_FROM is not set +# CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_GNU_EXTENSIONS is not set +# CONFIG_FEATURE_TAR_TO_COMMAND is not set +# CONFIG_FEATURE_TAR_UNAME_GNAME is not set +# CONFIG_FEATURE_TAR_NOPRESERVE_TIME is not set +# CONFIG_FEATURE_TAR_SELINUX is not set +# CONFIG_UNZIP is not set +# CONFIG_FEATURE_UNZIP_CDF is not set +# CONFIG_FEATURE_UNZIP_BZIP2 is not set +# CONFIG_FEATURE_UNZIP_LZMA is not set +# CONFIG_FEATURE_UNZIP_XZ is not set +# CONFIG_FEATURE_LZMA_FAST is not set + +# +# Coreutils +# +# CONFIG_BASENAME is not set +# CONFIG_CAT is not set +# CONFIG_FEATURE_CATN is not set +# CONFIG_FEATURE_CATV is not set +# CONFIG_CHGRP is not set +# CONFIG_CHMOD is not set +# CONFIG_CHOWN is not set +# CONFIG_FEATURE_CHOWN_LONG_OPTIONS is not set +# CONFIG_CHROOT is not set +# CONFIG_CKSUM is not set +# CONFIG_COMM is not set +# CONFIG_CP is not set +# CONFIG_FEATURE_CP_LONG_OPTIONS is not set +# CONFIG_FEATURE_CP_REFLINK is not set +# CONFIG_CUT is not set +# CONFIG_DATE is not set +# CONFIG_FEATURE_DATE_ISOFMT is not set +# CONFIG_FEATURE_DATE_NANO is not set +# CONFIG_FEATURE_DATE_COMPAT is not set +# CONFIG_DD is not set +# CONFIG_FEATURE_DD_SIGNAL_HANDLING is not set +# CONFIG_FEATURE_DD_THIRD_STATUS_LINE is not set +# CONFIG_FEATURE_DD_IBS_OBS is not set +# CONFIG_FEATURE_DD_STATUS is not set +# CONFIG_DF is not set +# CONFIG_FEATURE_DF_FANCY is not set +# CONFIG_DIRNAME is not set +# CONFIG_DOS2UNIX is not set +# CONFIG_UNIX2DOS is not set +# CONFIG_DU is not set +# CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K is not set +# CONFIG_ECHO is not set +CONFIG_FEATURE_FANCY_ECHO=y +# CONFIG_ENV is not set +# CONFIG_EXPAND is not set +# CONFIG_UNEXPAND is not set +# CONFIG_EXPR is not set +# CONFIG_EXPR_MATH_SUPPORT_64 is not set +# CONFIG_FACTOR is not set +# CONFIG_FALSE is not set +# CONFIG_FOLD is not set +# CONFIG_HEAD is not set +# CONFIG_FEATURE_FANCY_HEAD is not set +# CONFIG_HOSTID is not set +# CONFIG_ID is not set +# CONFIG_GROUPS is not set +# CONFIG_INSTALL is not set +# CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set +# CONFIG_LINK is not set +# CONFIG_LN is not set +# CONFIG_LOGNAME is not set +# CONFIG_LS is not set +# CONFIG_FEATURE_LS_FILETYPES is not set +# CONFIG_FEATURE_LS_FOLLOWLINKS is not set +# CONFIG_FEATURE_LS_RECURSIVE is not set +# CONFIG_FEATURE_LS_WIDTH is not set +# CONFIG_FEATURE_LS_SORTFILES is not set +# CONFIG_FEATURE_LS_TIMESTAMPS is not set +# CONFIG_FEATURE_LS_USERNAME is not set +# CONFIG_FEATURE_LS_COLOR is not set +# CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set +# CONFIG_MD5SUM is not set +# CONFIG_SHA1SUM is not set +# CONFIG_SHA256SUM is not set +# CONFIG_SHA512SUM is not set +# CONFIG_SHA3SUM is not set +# CONFIG_FEATURE_MD5_SHA1_SUM_CHECK is not set +# CONFIG_MKDIR is not set +# CONFIG_MKFIFO is not set +# CONFIG_MKNOD is not set +# CONFIG_MKTEMP is not set +# CONFIG_MV is not set +# CONFIG_NICE is not set +# CONFIG_NL is not set +# CONFIG_NOHUP is not set +# CONFIG_NPROC is not set +# CONFIG_OD is not set +# CONFIG_PASTE is not set +# CONFIG_PRINTENV is not set +# CONFIG_PRINTF is not set +# CONFIG_PWD is not set +# CONFIG_READLINK is not set +# CONFIG_FEATURE_READLINK_FOLLOW is not set +# CONFIG_REALPATH is not set +# CONFIG_RM is not set +# CONFIG_RMDIR is not set +# CONFIG_SEQ is not set +# CONFIG_SHRED is not set +# CONFIG_SHUF is not set +# CONFIG_SLEEP is not set +# CONFIG_FEATURE_FANCY_SLEEP is not set +# CONFIG_SORT is not set +# CONFIG_FEATURE_SORT_BIG is not set +# CONFIG_FEATURE_SORT_OPTIMIZE_MEMORY is not set +# CONFIG_SPLIT is not set +# CONFIG_FEATURE_SPLIT_FANCY is not set +# CONFIG_STAT is not set +# CONFIG_FEATURE_STAT_FORMAT is not set +# CONFIG_FEATURE_STAT_FILESYSTEM is not set +# CONFIG_STTY is not set +# CONFIG_SUM is not set +# CONFIG_SYNC is not set +# CONFIG_FEATURE_SYNC_FANCY is not set +# CONFIG_FSYNC is not set +# CONFIG_TAC is not set +# CONFIG_TAIL is not set +# CONFIG_FEATURE_FANCY_TAIL is not set +# CONFIG_TEE is not set +# CONFIG_FEATURE_TEE_USE_BLOCK_IO is not set +# CONFIG_TEST is not set +# CONFIG_TEST1 is not set +# CONFIG_TEST2 is not set +CONFIG_FEATURE_TEST_64=y +# CONFIG_TIMEOUT is not set +# CONFIG_TOUCH is not set +# CONFIG_FEATURE_TOUCH_NODEREF is not set +# CONFIG_FEATURE_TOUCH_SUSV3 is not set +# CONFIG_TR is not set +# CONFIG_FEATURE_TR_CLASSES is not set +# CONFIG_FEATURE_TR_EQUIV is not set +# CONFIG_TRUE is not set +# CONFIG_TRUNCATE is not set +# CONFIG_TTY is not set +# CONFIG_UNAME is not set +CONFIG_UNAME_OSNAME="" +# CONFIG_BB_ARCH is not set +# CONFIG_UNIQ is not set +# CONFIG_UNLINK is not set +# CONFIG_USLEEP is not set +# CONFIG_UUDECODE is not set +# CONFIG_BASE64 is not set +# CONFIG_UUENCODE is not set +# CONFIG_WC is not set +# CONFIG_FEATURE_WC_LARGE is not set +# CONFIG_WHOAMI is not set +# CONFIG_WHO is not set +# CONFIG_W is not set +# CONFIG_USERS is not set +# CONFIG_YES is not set + +# +# Common options +# +# CONFIG_FEATURE_VERBOSE is not set +# CONFIG_FEATURE_PRESERVE_HARDLINKS is not set +# CONFIG_FEATURE_HUMAN_READABLE is not set + +# +# Console Utilities +# +# CONFIG_CHVT is not set +# CONFIG_CLEAR is not set +# CONFIG_DEALLOCVT is not set +# CONFIG_DUMPKMAP is not set +# CONFIG_FGCONSOLE is not set +# CONFIG_KBD_MODE is not set +# CONFIG_LOADFONT is not set +# CONFIG_SETFONT is not set +# CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set +CONFIG_DEFAULT_SETFONT_DIR="" +# CONFIG_FEATURE_LOADFONT_PSF2 is not set +# CONFIG_FEATURE_LOADFONT_RAW is not set +# CONFIG_LOADKMAP is not set +# CONFIG_OPENVT is not set +# CONFIG_RESET is not set +# CONFIG_RESIZE is not set +# CONFIG_FEATURE_RESIZE_PRINT is not set +# CONFIG_SETCONSOLE is not set +# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set +# CONFIG_SETKEYCODES is not set +# CONFIG_SETLOGCONS is not set +# CONFIG_SHOWKEY is not set + +# +# Debian Utilities +# +# CONFIG_PIPE_PROGRESS is not set +# CONFIG_RUN_PARTS is not set +# CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set +# CONFIG_FEATURE_RUN_PARTS_FANCY is not set +# CONFIG_START_STOP_DAEMON is not set +# CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set +# CONFIG_FEATURE_START_STOP_DAEMON_FANCY is not set +# CONFIG_WHICH is not set + +# +# klibc-utils +# +# CONFIG_MINIPS is not set +# CONFIG_NUKE is not set +# CONFIG_RESUME is not set +# CONFIG_RUN_INIT is not set + +# +# Editors +# +# CONFIG_AWK is not set +# CONFIG_FEATURE_AWK_LIBM is not set +# CONFIG_FEATURE_AWK_GNU_EXTENSIONS is not set +# CONFIG_CMP is not set +# CONFIG_DIFF is not set +# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set +# CONFIG_FEATURE_DIFF_DIR is not set +# CONFIG_ED is not set +# CONFIG_PATCH is not set +# CONFIG_SED is not set +# CONFIG_VI is not set +CONFIG_FEATURE_VI_MAX_LEN=0 +# CONFIG_FEATURE_VI_8BIT is not set +# CONFIG_FEATURE_VI_COLON is not set +# CONFIG_FEATURE_VI_YANKMARK is not set +# CONFIG_FEATURE_VI_SEARCH is not set +# CONFIG_FEATURE_VI_REGEX_SEARCH is not set +# CONFIG_FEATURE_VI_USE_SIGNALS is not set +# CONFIG_FEATURE_VI_DOT_CMD is not set +# CONFIG_FEATURE_VI_READONLY is not set +# CONFIG_FEATURE_VI_SETOPTS is not set +# CONFIG_FEATURE_VI_SET is not set +# CONFIG_FEATURE_VI_WIN_RESIZE is not set +# CONFIG_FEATURE_VI_ASK_TERMINAL is not set +# CONFIG_FEATURE_VI_UNDO is not set +# CONFIG_FEATURE_VI_UNDO_QUEUE is not set +CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=0 +# CONFIG_FEATURE_ALLOW_EXEC is not set + +# +# Finding Utilities +# +# CONFIG_FIND is not set +# CONFIG_FEATURE_FIND_PRINT0 is not set +# CONFIG_FEATURE_FIND_MTIME is not set +# CONFIG_FEATURE_FIND_MMIN is not set +# CONFIG_FEATURE_FIND_PERM is not set +# CONFIG_FEATURE_FIND_TYPE is not set +# CONFIG_FEATURE_FIND_EXECUTABLE is not set +# CONFIG_FEATURE_FIND_XDEV is not set +# CONFIG_FEATURE_FIND_MAXDEPTH is not set +# CONFIG_FEATURE_FIND_NEWER is not set +# CONFIG_FEATURE_FIND_INUM is not set +# CONFIG_FEATURE_FIND_EXEC is not set +# CONFIG_FEATURE_FIND_EXEC_PLUS is not set +# CONFIG_FEATURE_FIND_USER is not set +# CONFIG_FEATURE_FIND_GROUP is not set +# CONFIG_FEATURE_FIND_NOT is not set +# CONFIG_FEATURE_FIND_DEPTH is not set +# CONFIG_FEATURE_FIND_PAREN is not set +# CONFIG_FEATURE_FIND_SIZE is not set +# CONFIG_FEATURE_FIND_PRUNE is not set +# CONFIG_FEATURE_FIND_QUIT is not set +# CONFIG_FEATURE_FIND_DELETE is not set +# CONFIG_FEATURE_FIND_EMPTY is not set +# CONFIG_FEATURE_FIND_PATH is not set +# CONFIG_FEATURE_FIND_REGEX is not set +# CONFIG_FEATURE_FIND_CONTEXT is not set +# CONFIG_FEATURE_FIND_LINKS is not set +# CONFIG_GREP is not set +# CONFIG_EGREP is not set +# CONFIG_FGREP is not set +# CONFIG_FEATURE_GREP_CONTEXT is not set +# CONFIG_XARGS is not set +# CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION is not set +# CONFIG_FEATURE_XARGS_SUPPORT_QUOTES is not set +# CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM is not set +# CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR is not set +# CONFIG_FEATURE_XARGS_SUPPORT_PARALLEL is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ARGS_FILE is not set + +# +# Init Utilities +# +# CONFIG_BOOTCHARTD is not set +# CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set +# CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set +# CONFIG_HALT is not set +# CONFIG_POWEROFF is not set +# CONFIG_REBOOT is not set +# CONFIG_FEATURE_WAIT_FOR_INIT is not set +# CONFIG_FEATURE_CALL_TELINIT is not set +CONFIG_TELINIT_PATH="" +# CONFIG_INIT is not set +# CONFIG_LINUXRC is not set +# CONFIG_FEATURE_USE_INITTAB is not set +# CONFIG_FEATURE_KILL_REMOVED is not set +CONFIG_FEATURE_KILL_DELAY=0 +# CONFIG_FEATURE_INIT_SCTTY is not set +# CONFIG_FEATURE_INIT_SYSLOG is not set +# CONFIG_FEATURE_INIT_QUIET is not set +# CONFIG_FEATURE_INIT_COREDUMPS is not set +CONFIG_INIT_TERMINAL_TYPE="" +# CONFIG_FEATURE_INIT_MODIFY_CMDLINE is not set + +# +# Login/Password Management Utilities +# +# CONFIG_FEATURE_SHADOWPASSWDS is not set +# CONFIG_USE_BB_PWD_GRP is not set +# CONFIG_USE_BB_SHADOW is not set +# CONFIG_USE_BB_CRYPT is not set +# CONFIG_USE_BB_CRYPT_SHA is not set +# CONFIG_ADDGROUP is not set +# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set +# CONFIG_ADD_SHELL is not set +# CONFIG_REMOVE_SHELL is not set +# CONFIG_ADDUSER is not set +# CONFIG_FEATURE_CHECK_NAMES is not set +CONFIG_LAST_ID=0 +CONFIG_FIRST_SYSTEM_ID=0 +CONFIG_LAST_SYSTEM_ID=0 +# CONFIG_CHPASSWD is not set +CONFIG_FEATURE_DEFAULT_PASSWD_ALGO="" +# CONFIG_CRYPTPW is not set +# CONFIG_MKPASSWD is not set +# CONFIG_DELUSER is not set +# CONFIG_DELGROUP is not set +# CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set +# CONFIG_GETTY is not set +# CONFIG_LOGIN is not set +# CONFIG_LOGIN_SESSION_AS_CHILD is not set +# CONFIG_LOGIN_SCRIPTS is not set +# CONFIG_FEATURE_NOLOGIN is not set +# CONFIG_FEATURE_SECURETTY is not set +# CONFIG_PASSWD is not set +# CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set +# CONFIG_SU is not set +# CONFIG_FEATURE_SU_SYSLOG is not set +# CONFIG_FEATURE_SU_CHECKS_SHELLS is not set +# CONFIG_FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY is not set +# CONFIG_SULOGIN is not set +# CONFIG_VLOCK is not set + +# +# Linux Ext2 FS Progs +# +# CONFIG_CHATTR is not set +# CONFIG_FSCK is not set +# CONFIG_LSATTR is not set +# CONFIG_TUNE2FS is not set + +# +# Linux Module Utilities +# +# CONFIG_MODPROBE_SMALL is not set +# CONFIG_DEPMOD is not set +# CONFIG_INSMOD is not set +# CONFIG_LSMOD is not set +# CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set +# CONFIG_MODINFO is not set +# CONFIG_MODPROBE is not set +# CONFIG_FEATURE_MODPROBE_BLACKLIST is not set +# CONFIG_RMMOD is not set + +# +# Options common to multiple modutils +# +# CONFIG_FEATURE_CMDLINE_MODULE_OPTIONS is not set +# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set +# CONFIG_FEATURE_2_4_MODULES is not set +# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set +# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set +# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set +# CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set +# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set +# CONFIG_FEATURE_MODUTILS_ALIAS is not set +# CONFIG_FEATURE_MODUTILS_SYMBOLS is not set +CONFIG_DEFAULT_MODULES_DIR="" +CONFIG_DEFAULT_DEPMOD_FILE="" + +# +# Linux System Utilities +# +# CONFIG_ACPID is not set +# CONFIG_FEATURE_ACPID_COMPAT is not set +# CONFIG_BLKDISCARD is not set +# CONFIG_BLKID is not set +# CONFIG_FEATURE_BLKID_TYPE is not set +# CONFIG_BLOCKDEV is not set +# CONFIG_CAL is not set +# CONFIG_CHRT is not set +# CONFIG_DMESG is not set +# CONFIG_FEATURE_DMESG_PRETTY is not set +# CONFIG_EJECT is not set +# CONFIG_FEATURE_EJECT_SCSI is not set +# CONFIG_FALLOCATE is not set +# CONFIG_FATATTR is not set +# CONFIG_FBSET is not set +# CONFIG_FEATURE_FBSET_FANCY is not set +# CONFIG_FEATURE_FBSET_READMODE is not set +# CONFIG_FDFORMAT is not set +# CONFIG_FDISK is not set +# CONFIG_FDISK_SUPPORT_LARGE_DISKS is not set +# CONFIG_FEATURE_FDISK_WRITABLE is not set +# CONFIG_FEATURE_AIX_LABEL is not set +# CONFIG_FEATURE_SGI_LABEL is not set +# CONFIG_FEATURE_SUN_LABEL is not set +# CONFIG_FEATURE_OSF_LABEL is not set +# CONFIG_FEATURE_GPT_LABEL is not set +# CONFIG_FEATURE_FDISK_ADVANCED is not set +# CONFIG_FINDFS is not set +# CONFIG_FLOCK is not set +# CONFIG_FDFLUSH is not set +# CONFIG_FREERAMDISK is not set +# CONFIG_FSCK_MINIX is not set +# CONFIG_FSFREEZE is not set +# CONFIG_FSTRIM is not set +# CONFIG_GETOPT is not set +# CONFIG_FEATURE_GETOPT_LONG is not set +# CONFIG_HEXDUMP is not set +# CONFIG_FEATURE_HEXDUMP_REVERSE is not set +# CONFIG_HD is not set +# CONFIG_XXD is not set +# CONFIG_HWCLOCK is not set +# CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set +# CONFIG_IONICE is not set +# CONFIG_IPCRM is not set +# CONFIG_IPCS is not set +# CONFIG_LAST is not set +# CONFIG_FEATURE_LAST_FANCY is not set +# CONFIG_LOSETUP is not set +# CONFIG_LSPCI is not set +# CONFIG_LSUSB is not set +# CONFIG_MDEV is not set +# CONFIG_FEATURE_MDEV_CONF is not set +# CONFIG_FEATURE_MDEV_RENAME is not set +# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set +# CONFIG_FEATURE_MDEV_EXEC is not set +# CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set +# CONFIG_FEATURE_MDEV_DAEMON is not set +# CONFIG_MESG is not set +# CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP is not set +# CONFIG_MKE2FS is not set +# CONFIG_MKFS_EXT2 is not set +# CONFIG_MKFS_MINIX is not set +# CONFIG_FEATURE_MINIX2 is not set +# CONFIG_MKFS_REISER is not set +# CONFIG_MKDOSFS is not set +# CONFIG_MKFS_VFAT is not set +# CONFIG_MKSWAP is not set +# CONFIG_FEATURE_MKSWAP_UUID is not set +# CONFIG_MORE is not set +# CONFIG_MOUNT is not set +# CONFIG_FEATURE_MOUNT_FAKE is not set +# CONFIG_FEATURE_MOUNT_VERBOSE is not set +# CONFIG_FEATURE_MOUNT_HELPERS is not set +# CONFIG_FEATURE_MOUNT_LABEL is not set +# CONFIG_FEATURE_MOUNT_NFS is not set +# CONFIG_FEATURE_MOUNT_CIFS is not set +# CONFIG_FEATURE_MOUNT_FLAGS is not set +# CONFIG_FEATURE_MOUNT_FSTAB is not set +# CONFIG_FEATURE_MOUNT_OTHERTAB is not set +# CONFIG_MOUNTPOINT is not set +# CONFIG_NOLOGIN is not set +# CONFIG_NOLOGIN_DEPENDENCIES is not set +# CONFIG_NSENTER is not set +# CONFIG_PIVOT_ROOT is not set +# CONFIG_RDATE is not set +# CONFIG_RDEV is not set +# CONFIG_READPROFILE is not set +# CONFIG_RENICE is not set +# CONFIG_REV is not set +# CONFIG_RTCWAKE is not set +# CONFIG_SCRIPT is not set +# CONFIG_SCRIPTREPLAY is not set +# CONFIG_SETARCH is not set +# CONFIG_LINUX32 is not set +# CONFIG_LINUX64 is not set +# CONFIG_SETPRIV is not set +# CONFIG_FEATURE_SETPRIV_DUMP is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITIES is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITY_NAMES is not set +# CONFIG_SETSID is not set +# CONFIG_SWAPON is not set +# CONFIG_FEATURE_SWAPON_DISCARD is not set +# CONFIG_FEATURE_SWAPON_PRI is not set +# CONFIG_SWAPOFF is not set +# CONFIG_FEATURE_SWAPONOFF_LABEL is not set +# CONFIG_SWITCH_ROOT is not set +# CONFIG_TASKSET is not set +# CONFIG_FEATURE_TASKSET_FANCY is not set +# CONFIG_FEATURE_TASKSET_CPULIST is not set +# CONFIG_UEVENT is not set +# CONFIG_UMOUNT is not set +# CONFIG_FEATURE_UMOUNT_ALL is not set +# CONFIG_UNSHARE is not set +# CONFIG_WALL is not set +# CONFIG_FEATURE_MOUNT_LOOP is not set +# CONFIG_FEATURE_MOUNT_LOOP_CREATE is not set +# CONFIG_FEATURE_MTAB_SUPPORT is not set +# CONFIG_VOLUMEID is not set +# CONFIG_FEATURE_VOLUMEID_BCACHE is not set +# CONFIG_FEATURE_VOLUMEID_BTRFS is not set +# CONFIG_FEATURE_VOLUMEID_CRAMFS is not set +# CONFIG_FEATURE_VOLUMEID_EXFAT is not set +# CONFIG_FEATURE_VOLUMEID_EXT is not set +# CONFIG_FEATURE_VOLUMEID_F2FS is not set +# CONFIG_FEATURE_VOLUMEID_FAT is not set +# CONFIG_FEATURE_VOLUMEID_HFS is not set +# CONFIG_FEATURE_VOLUMEID_ISO9660 is not set +# CONFIG_FEATURE_VOLUMEID_JFS is not set +# CONFIG_FEATURE_VOLUMEID_LFS is not set +# CONFIG_FEATURE_VOLUMEID_LINUXRAID is not set +# CONFIG_FEATURE_VOLUMEID_LINUXSWAP is not set +# CONFIG_FEATURE_VOLUMEID_LUKS is not set +# CONFIG_FEATURE_VOLUMEID_MINIX is not set +# CONFIG_FEATURE_VOLUMEID_NILFS is not set +# CONFIG_FEATURE_VOLUMEID_NTFS is not set +# CONFIG_FEATURE_VOLUMEID_OCFS2 is not set +# CONFIG_FEATURE_VOLUMEID_REISERFS is not set +# CONFIG_FEATURE_VOLUMEID_ROMFS is not set +# CONFIG_FEATURE_VOLUMEID_SQUASHFS is not set +# CONFIG_FEATURE_VOLUMEID_SYSV is not set +# CONFIG_FEATURE_VOLUMEID_UBIFS is not set +# CONFIG_FEATURE_VOLUMEID_UDF is not set +# CONFIG_FEATURE_VOLUMEID_XFS is not set + +# +# Miscellaneous Utilities +# +# CONFIG_ADJTIMEX is not set +# CONFIG_BBCONFIG is not set +# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set +# CONFIG_BC is not set +# CONFIG_DC is not set +# CONFIG_FEATURE_DC_BIG is not set +# CONFIG_FEATURE_DC_LIBM is not set +# CONFIG_FEATURE_BC_INTERACTIVE is not set +# CONFIG_FEATURE_BC_LONG_OPTIONS is not set +# CONFIG_BEEP is not set +CONFIG_FEATURE_BEEP_FREQ=0 +CONFIG_FEATURE_BEEP_LENGTH_MS=0 +# CONFIG_CHAT is not set +# CONFIG_FEATURE_CHAT_NOFAIL is not set +# CONFIG_FEATURE_CHAT_TTY_HIFI is not set +# CONFIG_FEATURE_CHAT_IMPLICIT_CR is not set +# CONFIG_FEATURE_CHAT_SWALLOW_OPTS is not set +# CONFIG_FEATURE_CHAT_SEND_ESCAPES is not set +# CONFIG_FEATURE_CHAT_VAR_ABORT_LEN is not set +# CONFIG_FEATURE_CHAT_CLR_ABORT is not set +# CONFIG_CONSPY is not set +# CONFIG_CROND is not set +# CONFIG_FEATURE_CROND_D is not set +# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set +# CONFIG_FEATURE_CROND_SPECIAL_TIMES is not set +CONFIG_FEATURE_CROND_DIR="" +# CONFIG_CRONTAB is not set +# CONFIG_DEVFSD is not set +# CONFIG_DEVFSD_MODLOAD is not set +# CONFIG_DEVFSD_FG_NP is not set +# CONFIG_DEVFSD_VERBOSE is not set +# CONFIG_FEATURE_DEVFS is not set +# CONFIG_DEVMEM is not set +# CONFIG_FBSPLASH is not set +# CONFIG_FLASHCP is not set +# CONFIG_FLASH_ERASEALL is not set +# CONFIG_FLASH_LOCK is not set +# CONFIG_FLASH_UNLOCK is not set +# CONFIG_HDPARM is not set +# CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set +# CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set +# CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set +# CONFIG_HEXEDIT is not set +# CONFIG_I2CGET is not set +# CONFIG_I2CSET is not set +# CONFIG_I2CDUMP is not set +# CONFIG_I2CDETECT is not set +# CONFIG_I2CTRANSFER is not set +# CONFIG_INOTIFYD is not set +# CONFIG_LESS is not set +CONFIG_FEATURE_LESS_MAXLINES=0 +# CONFIG_FEATURE_LESS_BRACKETS is not set +# CONFIG_FEATURE_LESS_FLAGS is not set +# CONFIG_FEATURE_LESS_TRUNCATE is not set +# CONFIG_FEATURE_LESS_MARKS is not set +# CONFIG_FEATURE_LESS_REGEXP is not set +# CONFIG_FEATURE_LESS_WINCH is not set +# CONFIG_FEATURE_LESS_ASK_TERMINAL is not set +# CONFIG_FEATURE_LESS_DASHCMD is not set +# CONFIG_FEATURE_LESS_LINENUMS is not set +# CONFIG_FEATURE_LESS_RAW is not set +# CONFIG_FEATURE_LESS_ENV is not set +# CONFIG_LSSCSI is not set +# CONFIG_MAKEDEVS is not set +# CONFIG_FEATURE_MAKEDEVS_LEAF is not set +# CONFIG_FEATURE_MAKEDEVS_TABLE is not set +# CONFIG_MAN is not set +# CONFIG_MICROCOM is not set +# CONFIG_MIM is not set +# CONFIG_MT is not set +# CONFIG_NANDWRITE is not set +# CONFIG_NANDDUMP is not set +# CONFIG_PARTPROBE is not set +# CONFIG_RAIDAUTORUN is not set +# CONFIG_READAHEAD is not set +# CONFIG_RFKILL is not set +# CONFIG_RUNLEVEL is not set +# CONFIG_RX is not set +# CONFIG_SETFATTR is not set +# CONFIG_SETSERIAL is not set +# CONFIG_STRINGS is not set +# CONFIG_TIME is not set +# CONFIG_TS is not set +# CONFIG_TTYSIZE is not set +# CONFIG_UBIRENAME is not set +# CONFIG_UBIATTACH is not set +# CONFIG_UBIDETACH is not set +# CONFIG_UBIMKVOL is not set +# CONFIG_UBIRMVOL is not set +# CONFIG_UBIRSVOL is not set +# CONFIG_UBIUPDATEVOL is not set +# CONFIG_VOLNAME is not set +# CONFIG_WATCHDOG is not set + +# +# Networking Utilities +# +# CONFIG_FEATURE_IPV6 is not set +# CONFIG_FEATURE_UNIX_LOCAL is not set +# CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set +# CONFIG_VERBOSE_RESOLUTION_ERRORS is not set +# CONFIG_FEATURE_TLS_SHA1 is not set +# CONFIG_ARP is not set +# CONFIG_ARPING is not set +# CONFIG_BRCTL is not set +# CONFIG_FEATURE_BRCTL_FANCY is not set +# CONFIG_FEATURE_BRCTL_SHOW is not set +# CONFIG_DNSD is not set +# CONFIG_ETHER_WAKE is not set +# CONFIG_FTPD is not set +# CONFIG_FEATURE_FTPD_WRITE is not set +# CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST is not set +# CONFIG_FEATURE_FTPD_AUTHENTICATION is not set +# CONFIG_FTPGET is not set +# CONFIG_FTPPUT is not set +# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set +# CONFIG_HOSTNAME is not set +# CONFIG_DNSDOMAINNAME is not set +# CONFIG_HTTPD is not set +# CONFIG_FEATURE_HTTPD_RANGES is not set +# CONFIG_FEATURE_HTTPD_SETUID is not set +# CONFIG_FEATURE_HTTPD_BASIC_AUTH is not set +# CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set +# CONFIG_FEATURE_HTTPD_CGI is not set +# CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set +# CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set +# CONFIG_FEATURE_HTTPD_ENCODE_URL_STR is not set +# CONFIG_FEATURE_HTTPD_ERROR_PAGES is not set +# CONFIG_FEATURE_HTTPD_PROXY is not set +# CONFIG_FEATURE_HTTPD_GZIP is not set +# CONFIG_IFCONFIG is not set +# CONFIG_FEATURE_IFCONFIG_STATUS is not set +# CONFIG_FEATURE_IFCONFIG_SLIP is not set +# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set +# CONFIG_FEATURE_IFCONFIG_HW is not set +# CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set +# CONFIG_IFENSLAVE is not set +# CONFIG_IFPLUGD is not set +# CONFIG_IFUP is not set +# CONFIG_IFDOWN is not set +CONFIG_IFUPDOWN_IFSTATE_PATH="" +# CONFIG_FEATURE_IFUPDOWN_IP is not set +# CONFIG_FEATURE_IFUPDOWN_IPV4 is not set +# CONFIG_FEATURE_IFUPDOWN_IPV6 is not set +# CONFIG_FEATURE_IFUPDOWN_MAPPING is not set +# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set +# CONFIG_INETD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set +# CONFIG_FEATURE_INETD_RPC is not set +# CONFIG_IP is not set +# CONFIG_IPADDR is not set +# CONFIG_IPLINK is not set +# CONFIG_IPROUTE is not set +# CONFIG_IPTUNNEL is not set +# CONFIG_IPRULE is not set +# CONFIG_IPNEIGH is not set +# CONFIG_FEATURE_IP_ADDRESS is not set +# CONFIG_FEATURE_IP_LINK is not set +# CONFIG_FEATURE_IP_ROUTE is not set +CONFIG_FEATURE_IP_ROUTE_DIR="" +# CONFIG_FEATURE_IP_TUNNEL is not set +# CONFIG_FEATURE_IP_RULE is not set +# CONFIG_FEATURE_IP_NEIGH is not set +# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set +# CONFIG_IPCALC is not set +# CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set +# CONFIG_FEATURE_IPCALC_FANCY is not set +# CONFIG_FAKEIDENTD is not set +# CONFIG_NAMEIF is not set +# CONFIG_FEATURE_NAMEIF_EXTENDED is not set +# CONFIG_NBDCLIENT is not set +# CONFIG_NC is not set +# CONFIG_NETCAT is not set +# CONFIG_NC_SERVER is not set +# CONFIG_NC_EXTRA is not set +# CONFIG_NC_110_COMPAT is not set +# CONFIG_NETSTAT is not set +# CONFIG_FEATURE_NETSTAT_WIDE is not set +# CONFIG_FEATURE_NETSTAT_PRG is not set +# CONFIG_NSLOOKUP is not set +# CONFIG_FEATURE_NSLOOKUP_BIG is not set +# CONFIG_FEATURE_NSLOOKUP_LONG_OPTIONS is not set +# CONFIG_NTPD is not set +# CONFIG_FEATURE_NTPD_SERVER is not set +# CONFIG_FEATURE_NTPD_CONF is not set +# CONFIG_FEATURE_NTP_AUTH is not set +# CONFIG_PING is not set +# CONFIG_PING6 is not set +# CONFIG_FEATURE_FANCY_PING is not set +# CONFIG_PSCAN is not set +# CONFIG_ROUTE is not set +# CONFIG_SLATTACH is not set +# CONFIG_SSL_CLIENT is not set +# CONFIG_TC is not set +# CONFIG_FEATURE_TC_INGRESS is not set +# CONFIG_TCPSVD is not set +# CONFIG_UDPSVD is not set +# CONFIG_TELNET is not set +# CONFIG_FEATURE_TELNET_TTYPE is not set +# CONFIG_FEATURE_TELNET_AUTOLOGIN is not set +# CONFIG_FEATURE_TELNET_WIDTH is not set +# CONFIG_TELNETD is not set +# CONFIG_FEATURE_TELNETD_STANDALONE is not set +# CONFIG_FEATURE_TELNETD_INETD_WAIT is not set +# CONFIG_TFTP is not set +# CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set +# CONFIG_FEATURE_TFTP_HPA_COMPAT is not set +# CONFIG_TFTPD is not set +# CONFIG_FEATURE_TFTP_GET is not set +# CONFIG_FEATURE_TFTP_PUT is not set +# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set +# CONFIG_TFTP_DEBUG is not set +# CONFIG_TLS is not set +# CONFIG_TRACEROUTE is not set +# CONFIG_TRACEROUTE6 is not set +# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set +# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set +# CONFIG_TUNCTL is not set +# CONFIG_FEATURE_TUNCTL_UG is not set +# CONFIG_VCONFIG is not set +# CONFIG_WGET is not set +# CONFIG_FEATURE_WGET_LONG_OPTIONS is not set +# CONFIG_FEATURE_WGET_STATUSBAR is not set +# CONFIG_FEATURE_WGET_AUTHENTICATION is not set +# CONFIG_FEATURE_WGET_TIMEOUT is not set +# CONFIG_FEATURE_WGET_HTTPS is not set +# CONFIG_FEATURE_WGET_OPENSSL is not set +# CONFIG_WHOIS is not set +# CONFIG_ZCIP is not set +# CONFIG_UDHCPD is not set +# CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC is not set +# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set +CONFIG_DHCPD_LEASES_FILE="" +# CONFIG_DUMPLEASES is not set +# CONFIG_DHCPRELAY is not set +# CONFIG_UDHCPC is not set +# CONFIG_FEATURE_UDHCPC_ARPING is not set +# CONFIG_FEATURE_UDHCPC_SANITIZEOPT is not set +CONFIG_UDHCPC_DEFAULT_SCRIPT="" +# CONFIG_UDHCPC6 is not set +# CONFIG_FEATURE_UDHCPC6_RFC3646 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4704 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4833 is not set +# CONFIG_FEATURE_UDHCPC6_RFC5970 is not set +# CONFIG_FEATURE_UDHCP_PORT is not set +CONFIG_UDHCP_DEBUG=0 +CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=0 +# CONFIG_FEATURE_UDHCP_RFC3397 is not set +# CONFIG_FEATURE_UDHCP_8021Q is not set +CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="" + +# +# Print Utilities +# +# CONFIG_LPD is not set +# CONFIG_LPR is not set +# CONFIG_LPQ is not set + +# +# Mail Utilities +# +# CONFIG_MAKEMIME is not set +# CONFIG_POPMAILDIR is not set +# CONFIG_FEATURE_POPMAILDIR_DELIVERY is not set +# CONFIG_REFORMIME is not set +# CONFIG_FEATURE_REFORMIME_COMPAT is not set +# CONFIG_SENDMAIL is not set +CONFIG_FEATURE_MIME_CHARSET="" + +# +# Process Utilities +# +# CONFIG_FREE is not set +# CONFIG_FUSER is not set +# CONFIG_IOSTAT is not set +# CONFIG_KILL is not set +# CONFIG_KILLALL is not set +# CONFIG_KILLALL5 is not set +# CONFIG_LSOF is not set +# CONFIG_MPSTAT is not set +# CONFIG_NMETER is not set +# CONFIG_PGREP is not set +# CONFIG_PKILL is not set +# CONFIG_PIDOF is not set +# CONFIG_FEATURE_PIDOF_SINGLE is not set +# CONFIG_FEATURE_PIDOF_OMIT is not set +# CONFIG_PMAP is not set +# CONFIG_POWERTOP is not set +# CONFIG_FEATURE_POWERTOP_INTERACTIVE is not set +# CONFIG_PS is not set +# CONFIG_FEATURE_PS_WIDE is not set +# CONFIG_FEATURE_PS_LONG is not set +# CONFIG_FEATURE_PS_TIME is not set +# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set +# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set +# CONFIG_PSTREE is not set +# CONFIG_PWDX is not set +# CONFIG_SMEMCAP is not set +# CONFIG_BB_SYSCTL is not set +# CONFIG_TOP is not set +# CONFIG_FEATURE_TOP_INTERACTIVE is not set +# CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE is not set +# CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS is not set +# CONFIG_FEATURE_TOP_SMP_CPU is not set +# CONFIG_FEATURE_TOP_DECIMALS is not set +# CONFIG_FEATURE_TOP_SMP_PROCESS is not set +# CONFIG_FEATURE_TOPMEM is not set +# CONFIG_UPTIME is not set +# CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set +# CONFIG_WATCH is not set +# CONFIG_FEATURE_SHOW_THREADS is not set + +# +# Runit Utilities +# +# CONFIG_CHPST is not set +# CONFIG_SETUIDGID is not set +# CONFIG_ENVUIDGID is not set +# CONFIG_ENVDIR is not set +# CONFIG_SOFTLIMIT is not set +# CONFIG_RUNSV is not set +# CONFIG_RUNSVDIR is not set +# CONFIG_FEATURE_RUNSVDIR_LOG is not set +# CONFIG_SV is not set +CONFIG_SV_DEFAULT_SERVICE_DIR="" +# CONFIG_SVC is not set +# CONFIG_SVOK is not set +# CONFIG_SVLOGD is not set +# CONFIG_CHCON is not set +# CONFIG_GETENFORCE is not set +# CONFIG_GETSEBOOL is not set +# CONFIG_LOAD_POLICY is not set +# CONFIG_MATCHPATHCON is not set +# CONFIG_RUNCON is not set +# CONFIG_SELINUXENABLED is not set +# CONFIG_SESTATUS is not set +# CONFIG_SETENFORCE is not set +# CONFIG_SETFILES is not set +# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set +# CONFIG_RESTORECON is not set +# CONFIG_SETSEBOOL is not set + +# +# Shells +# +CONFIG_SH_IS_ASH=y +# CONFIG_SH_IS_HUSH is not set +# CONFIG_SH_IS_NONE is not set +# CONFIG_BASH_IS_ASH is not set +# CONFIG_BASH_IS_HUSH is not set +CONFIG_BASH_IS_NONE=y +CONFIG_SHELL_ASH=y +CONFIG_ASH=y +CONFIG_ASH_OPTIMIZE_FOR_SIZE=y +CONFIG_ASH_INTERNAL_GLOB=y +CONFIG_ASH_BASH_COMPAT=y +CONFIG_ASH_BASH_SOURCE_CURDIR=y +CONFIG_ASH_BASH_NOT_FOUND_HOOK=y +CONFIG_ASH_JOB_CONTROL=y +CONFIG_ASH_ALIAS=y +CONFIG_ASH_RANDOM_SUPPORT=y +CONFIG_ASH_EXPAND_PRMT=y +CONFIG_ASH_IDLE_TIMEOUT=y +CONFIG_ASH_MAIL=y +CONFIG_ASH_ECHO=y +CONFIG_ASH_PRINTF=y +CONFIG_ASH_TEST=y +CONFIG_ASH_HELP=y +CONFIG_ASH_GETOPTS=y +CONFIG_ASH_CMDCMD=y +CONFIG_CTTYHACK=y +CONFIG_HUSH=y +CONFIG_SHELL_HUSH=y +CONFIG_HUSH_BASH_COMPAT=y +CONFIG_HUSH_BRACE_EXPANSION=y +CONFIG_HUSH_LINENO_VAR=y +CONFIG_HUSH_BASH_SOURCE_CURDIR=y +CONFIG_HUSH_INTERACTIVE=y +# CONFIG_HUSH_SAVEHISTORY is not set +CONFIG_HUSH_JOB=y +CONFIG_HUSH_TICK=y +CONFIG_HUSH_IF=y +CONFIG_HUSH_LOOPS=y +CONFIG_HUSH_CASE=y +CONFIG_HUSH_FUNCTIONS=y +CONFIG_HUSH_LOCAL=y +CONFIG_HUSH_RANDOM_SUPPORT=y +CONFIG_HUSH_MODE_X=y +CONFIG_HUSH_ECHO=y +CONFIG_HUSH_PRINTF=y +CONFIG_HUSH_TEST=y +CONFIG_HUSH_HELP=y +CONFIG_HUSH_EXPORT=y +CONFIG_HUSH_EXPORT_N=y +CONFIG_HUSH_READONLY=y +CONFIG_HUSH_KILL=y +CONFIG_HUSH_WAIT=y +CONFIG_HUSH_COMMAND=y +CONFIG_HUSH_TRAP=y +CONFIG_HUSH_TYPE=y +CONFIG_HUSH_TIMES=y +CONFIG_HUSH_READ=y +CONFIG_HUSH_SET=y +CONFIG_HUSH_UNSET=y +CONFIG_HUSH_ULIMIT=y +CONFIG_HUSH_UMASK=y +CONFIG_HUSH_GETOPTS=y +# CONFIG_HUSH_MEMLEAK is not set + +# +# Options common to all shells +# +CONFIG_FEATURE_SH_MATH=y +CONFIG_FEATURE_SH_MATH_64=y +CONFIG_FEATURE_SH_MATH_BASE=y +CONFIG_FEATURE_SH_EXTRA_QUIET=y +CONFIG_FEATURE_SH_STANDALONE=y +CONFIG_FEATURE_SH_NOFORK=y +# CONFIG_FEATURE_SH_READ_FRAC is not set +# CONFIG_FEATURE_SH_HISTFILESIZE is not set +# CONFIG_FEATURE_SH_EMBEDDED_SCRIPTS is not set + +# +# System Logging Utilities +# +# CONFIG_KLOGD is not set +# CONFIG_FEATURE_KLOGD_KLOGCTL is not set +# CONFIG_LOGGER is not set +# CONFIG_LOGREAD is not set +# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set +# CONFIG_SYSLOGD is not set +# CONFIG_FEATURE_ROTATE_LOGFILE is not set +# CONFIG_FEATURE_REMOTE_LOG is not set +# CONFIG_FEATURE_SYSLOGD_DUP is not set +# CONFIG_FEATURE_SYSLOGD_CFG is not set +# CONFIG_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS is not set +CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0 +# CONFIG_FEATURE_IPC_SYSLOG is not set +CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 +# CONFIG_FEATURE_KMSG_SYSLOG is not set diff --git a/BUSYBOX/aarch64_hexdump.config b/BUSYBOX/aarch64_hexdump.config new file mode 100644 index 0000000..d13aa42 --- /dev/null +++ b/BUSYBOX/aarch64_hexdump.config @@ -0,0 +1,1166 @@ +# +# Automatically generated make config: don't edit +# Busybox version: 1.32.0 +# Tue Dec 8 03:03:31 2020 +# +CONFIG_HAVE_DOT_CONFIG=y + +# +# Settings +# +# CONFIG_DESKTOP is not set +# CONFIG_EXTRA_COMPAT is not set +# CONFIG_FEDORA_COMPAT is not set +# CONFIG_INCLUDE_SUSv2 is not set +# CONFIG_LONG_OPTS is not set +# CONFIG_SHOW_USAGE is not set +# CONFIG_FEATURE_VERBOSE_USAGE is not set +# CONFIG_FEATURE_COMPRESS_USAGE is not set +# CONFIG_LFS is not set +# CONFIG_PAM is not set +# CONFIG_FEATURE_DEVPTS is not set +# CONFIG_FEATURE_UTMP is not set +# CONFIG_FEATURE_WTMP is not set +# CONFIG_FEATURE_PIDFILE is not set +CONFIG_PID_FILE_PATH="" +# CONFIG_BUSYBOX is not set +# CONFIG_FEATURE_SHOW_SCRIPT is not set +# CONFIG_FEATURE_INSTALLER is not set +# CONFIG_INSTALL_NO_USR is not set +# CONFIG_FEATURE_SUID is not set +# CONFIG_FEATURE_SUID_CONFIG is not set +# CONFIG_FEATURE_SUID_CONFIG_QUIET is not set +# CONFIG_FEATURE_PREFER_APPLETS is not set +CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" +# CONFIG_SELINUX is not set +# CONFIG_FEATURE_CLEAN_UP is not set +# CONFIG_FEATURE_SYSLOG_INFO is not set +# CONFIG_FEATURE_SYSLOG is not set +# CONFIG_PLATFORM_LINUX is not set + +# +# Build Options +# +CONFIG_STATIC=y +# CONFIG_PIE is not set +# CONFIG_NOMMU is not set +# CONFIG_BUILD_LIBBUSYBOX is not set +# CONFIG_FEATURE_LIBBUSYBOX_STATIC is not set +# CONFIG_FEATURE_INDIVIDUAL is not set +# CONFIG_FEATURE_SHARED_BUSYBOX is not set +CONFIG_CROSS_COMPILER_PREFIX="" +CONFIG_SYSROOT="" +CONFIG_EXTRA_CFLAGS="" +CONFIG_EXTRA_LDFLAGS="" +CONFIG_EXTRA_LDLIBS="" +# CONFIG_USE_PORTABLE_CODE is not set +# CONFIG_STACK_OPTIMIZATION_386 is not set + +# +# Installation Options ("make install" behavior) +# +CONFIG_INSTALL_APPLET_SYMLINKS=y +# CONFIG_INSTALL_APPLET_HARDLINKS is not set +# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set +# CONFIG_INSTALL_APPLET_DONT is not set +# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set +# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set +# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set +CONFIG_PREFIX="./_install" + +# +# Debugging Options +# +# CONFIG_DEBUG is not set +# CONFIG_DEBUG_PESSIMIZE is not set +# CONFIG_DEBUG_SANITIZE is not set +# CONFIG_UNIT_TEST is not set +# CONFIG_WERROR is not set +# CONFIG_WARN_SIMPLE_MSG is not set +CONFIG_NO_DEBUG_LIB=y +# CONFIG_DMALLOC is not set +# CONFIG_EFENCE is not set + +# +# Library Tuning +# +# CONFIG_FEATURE_USE_BSS_TAIL is not set +# CONFIG_FLOAT_DURATION is not set +# CONFIG_FEATURE_RTMINMAX is not set +# CONFIG_FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS is not set +CONFIG_FEATURE_BUFFERS_USE_MALLOC=y +# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set +# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set +CONFIG_PASSWORD_MINLEN=6 +CONFIG_MD5_SMALL=1 +CONFIG_SHA3_SMALL=1 +# CONFIG_FEATURE_FAST_TOP is not set +# CONFIG_FEATURE_ETC_NETWORKS is not set +# CONFIG_FEATURE_ETC_SERVICES is not set +# CONFIG_FEATURE_EDITING is not set +CONFIG_FEATURE_EDITING_MAX_LEN=0 +# CONFIG_FEATURE_EDITING_VI is not set +CONFIG_FEATURE_EDITING_HISTORY=0 +# CONFIG_FEATURE_EDITING_SAVEHISTORY is not set +# CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set +# CONFIG_FEATURE_REVERSE_SEARCH is not set +# CONFIG_FEATURE_TAB_COMPLETION is not set +# CONFIG_FEATURE_USERNAME_COMPLETION is not set +# CONFIG_FEATURE_EDITING_FANCY_PROMPT is not set +# CONFIG_FEATURE_EDITING_WINCH is not set +# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set +# CONFIG_LOCALE_SUPPORT is not set +# CONFIG_UNICODE_SUPPORT is not set +# CONFIG_UNICODE_USING_LOCALE is not set +# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set +CONFIG_SUBST_WCHAR=0 +CONFIG_LAST_SUPPORTED_WCHAR=0 +# CONFIG_UNICODE_COMBINING_WCHARS is not set +# CONFIG_UNICODE_WIDE_WCHARS is not set +# CONFIG_UNICODE_BIDI_SUPPORT is not set +# CONFIG_UNICODE_NEUTRAL_TABLE is not set +# CONFIG_UNICODE_PRESERVE_BROKEN is not set +# CONFIG_FEATURE_NON_POSIX_CP is not set +# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set +# CONFIG_FEATURE_USE_SENDFILE is not set +CONFIG_FEATURE_COPYBUF_KB=4 +# CONFIG_FEATURE_SKIP_ROOTFS is not set +# CONFIG_MONOTONIC_SYSCALL is not set +# CONFIG_IOCTL_HEX2STR_ERROR is not set +# CONFIG_FEATURE_HWIB is not set + +# +# Applets +# + +# +# Archival Utilities +# +# CONFIG_FEATURE_SEAMLESS_XZ is not set +# CONFIG_FEATURE_SEAMLESS_LZMA is not set +# CONFIG_FEATURE_SEAMLESS_BZ2 is not set +# CONFIG_FEATURE_SEAMLESS_GZ is not set +# CONFIG_FEATURE_SEAMLESS_Z is not set +# CONFIG_AR is not set +# CONFIG_FEATURE_AR_LONG_FILENAMES is not set +# CONFIG_FEATURE_AR_CREATE is not set +# CONFIG_UNCOMPRESS is not set +# CONFIG_GUNZIP is not set +# CONFIG_ZCAT is not set +# CONFIG_FEATURE_GUNZIP_LONG_OPTIONS is not set +# CONFIG_BUNZIP2 is not set +# CONFIG_BZCAT is not set +# CONFIG_UNLZMA is not set +# CONFIG_LZCAT is not set +# CONFIG_LZMA is not set +# CONFIG_UNXZ is not set +# CONFIG_XZCAT is not set +# CONFIG_XZ is not set +# CONFIG_BZIP2 is not set +CONFIG_BZIP2_SMALL=0 +# CONFIG_FEATURE_BZIP2_DECOMPRESS is not set +# CONFIG_CPIO is not set +# CONFIG_FEATURE_CPIO_O is not set +# CONFIG_FEATURE_CPIO_P is not set +# CONFIG_DPKG is not set +# CONFIG_DPKG_DEB is not set +# CONFIG_GZIP is not set +# CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set +CONFIG_GZIP_FAST=0 +# CONFIG_FEATURE_GZIP_LEVELS is not set +# CONFIG_FEATURE_GZIP_DECOMPRESS is not set +# CONFIG_LZOP is not set +# CONFIG_UNLZOP is not set +# CONFIG_LZOPCAT is not set +# CONFIG_LZOP_COMPR_HIGH is not set +# CONFIG_RPM is not set +# CONFIG_RPM2CPIO is not set +# CONFIG_TAR is not set +# CONFIG_FEATURE_TAR_LONG_OPTIONS is not set +# CONFIG_FEATURE_TAR_CREATE is not set +# CONFIG_FEATURE_TAR_AUTODETECT is not set +# CONFIG_FEATURE_TAR_FROM is not set +# CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_GNU_EXTENSIONS is not set +# CONFIG_FEATURE_TAR_TO_COMMAND is not set +# CONFIG_FEATURE_TAR_UNAME_GNAME is not set +# CONFIG_FEATURE_TAR_NOPRESERVE_TIME is not set +# CONFIG_FEATURE_TAR_SELINUX is not set +# CONFIG_UNZIP is not set +# CONFIG_FEATURE_UNZIP_CDF is not set +# CONFIG_FEATURE_UNZIP_BZIP2 is not set +# CONFIG_FEATURE_UNZIP_LZMA is not set +# CONFIG_FEATURE_UNZIP_XZ is not set +# CONFIG_FEATURE_LZMA_FAST is not set + +# +# Coreutils +# +# CONFIG_BASENAME is not set +# CONFIG_CAT is not set +# CONFIG_FEATURE_CATN is not set +# CONFIG_FEATURE_CATV is not set +# CONFIG_CHGRP is not set +# CONFIG_CHMOD is not set +# CONFIG_CHOWN is not set +# CONFIG_FEATURE_CHOWN_LONG_OPTIONS is not set +# CONFIG_CHROOT is not set +# CONFIG_CKSUM is not set +# CONFIG_COMM is not set +# CONFIG_CP is not set +# CONFIG_FEATURE_CP_LONG_OPTIONS is not set +# CONFIG_FEATURE_CP_REFLINK is not set +# CONFIG_CUT is not set +# CONFIG_DATE is not set +# CONFIG_FEATURE_DATE_ISOFMT is not set +# CONFIG_FEATURE_DATE_NANO is not set +# CONFIG_FEATURE_DATE_COMPAT is not set +# CONFIG_DD is not set +# CONFIG_FEATURE_DD_SIGNAL_HANDLING is not set +# CONFIG_FEATURE_DD_THIRD_STATUS_LINE is not set +# CONFIG_FEATURE_DD_IBS_OBS is not set +# CONFIG_FEATURE_DD_STATUS is not set +# CONFIG_DF is not set +# CONFIG_FEATURE_DF_FANCY is not set +# CONFIG_DIRNAME is not set +# CONFIG_DOS2UNIX is not set +# CONFIG_UNIX2DOS is not set +# CONFIG_DU is not set +# CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K is not set +# CONFIG_ECHO is not set +# CONFIG_FEATURE_FANCY_ECHO is not set +# CONFIG_ENV is not set +# CONFIG_EXPAND is not set +# CONFIG_UNEXPAND is not set +# CONFIG_EXPR is not set +# CONFIG_EXPR_MATH_SUPPORT_64 is not set +# CONFIG_FACTOR is not set +# CONFIG_FALSE is not set +# CONFIG_FOLD is not set +# CONFIG_HEAD is not set +# CONFIG_FEATURE_FANCY_HEAD is not set +# CONFIG_HOSTID is not set +# CONFIG_ID is not set +# CONFIG_GROUPS is not set +# CONFIG_INSTALL is not set +# CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set +# CONFIG_LINK is not set +# CONFIG_LN is not set +# CONFIG_LOGNAME is not set +# CONFIG_LS is not set +# CONFIG_FEATURE_LS_FILETYPES is not set +# CONFIG_FEATURE_LS_FOLLOWLINKS is not set +# CONFIG_FEATURE_LS_RECURSIVE is not set +# CONFIG_FEATURE_LS_WIDTH is not set +# CONFIG_FEATURE_LS_SORTFILES is not set +# CONFIG_FEATURE_LS_TIMESTAMPS is not set +# CONFIG_FEATURE_LS_USERNAME is not set +# CONFIG_FEATURE_LS_COLOR is not set +# CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set +# CONFIG_MD5SUM is not set +# CONFIG_SHA1SUM is not set +# CONFIG_SHA256SUM is not set +# CONFIG_SHA512SUM is not set +# CONFIG_SHA3SUM is not set +# CONFIG_FEATURE_MD5_SHA1_SUM_CHECK is not set +# CONFIG_MKDIR is not set +# CONFIG_MKFIFO is not set +# CONFIG_MKNOD is not set +# CONFIG_MKTEMP is not set +# CONFIG_MV is not set +# CONFIG_NICE is not set +# CONFIG_NL is not set +# CONFIG_NOHUP is not set +# CONFIG_NPROC is not set +# CONFIG_OD is not set +# CONFIG_PASTE is not set +# CONFIG_PRINTENV is not set +# CONFIG_PRINTF is not set +# CONFIG_PWD is not set +# CONFIG_READLINK is not set +# CONFIG_FEATURE_READLINK_FOLLOW is not set +# CONFIG_REALPATH is not set +# CONFIG_RM is not set +# CONFIG_RMDIR is not set +# CONFIG_SEQ is not set +# CONFIG_SHRED is not set +# CONFIG_SHUF is not set +# CONFIG_SLEEP is not set +# CONFIG_FEATURE_FANCY_SLEEP is not set +# CONFIG_SORT is not set +# CONFIG_FEATURE_SORT_BIG is not set +# CONFIG_FEATURE_SORT_OPTIMIZE_MEMORY is not set +# CONFIG_SPLIT is not set +# CONFIG_FEATURE_SPLIT_FANCY is not set +# CONFIG_STAT is not set +# CONFIG_FEATURE_STAT_FORMAT is not set +# CONFIG_FEATURE_STAT_FILESYSTEM is not set +# CONFIG_STTY is not set +# CONFIG_SUM is not set +# CONFIG_SYNC is not set +# CONFIG_FEATURE_SYNC_FANCY is not set +# CONFIG_FSYNC is not set +# CONFIG_TAC is not set +# CONFIG_TAIL is not set +# CONFIG_FEATURE_FANCY_TAIL is not set +# CONFIG_TEE is not set +# CONFIG_FEATURE_TEE_USE_BLOCK_IO is not set +# CONFIG_TEST is not set +# CONFIG_TEST1 is not set +# CONFIG_TEST2 is not set +# CONFIG_FEATURE_TEST_64 is not set +# CONFIG_TIMEOUT is not set +# CONFIG_TOUCH is not set +# CONFIG_FEATURE_TOUCH_NODEREF is not set +# CONFIG_FEATURE_TOUCH_SUSV3 is not set +# CONFIG_TR is not set +# CONFIG_FEATURE_TR_CLASSES is not set +# CONFIG_FEATURE_TR_EQUIV is not set +# CONFIG_TRUE is not set +# CONFIG_TRUNCATE is not set +# CONFIG_TTY is not set +# CONFIG_UNAME is not set +CONFIG_UNAME_OSNAME="" +# CONFIG_BB_ARCH is not set +# CONFIG_UNIQ is not set +# CONFIG_UNLINK is not set +# CONFIG_USLEEP is not set +# CONFIG_UUDECODE is not set +# CONFIG_BASE64 is not set +# CONFIG_UUENCODE is not set +# CONFIG_WC is not set +# CONFIG_FEATURE_WC_LARGE is not set +# CONFIG_WHO is not set +# CONFIG_W is not set +# CONFIG_USERS is not set +# CONFIG_WHOAMI is not set +# CONFIG_YES is not set + +# +# Common options +# +# CONFIG_FEATURE_VERBOSE is not set +# CONFIG_FEATURE_PRESERVE_HARDLINKS is not set +# CONFIG_FEATURE_HUMAN_READABLE is not set + +# +# Console Utilities +# +# CONFIG_CHVT is not set +# CONFIG_CLEAR is not set +# CONFIG_DEALLOCVT is not set +# CONFIG_DUMPKMAP is not set +# CONFIG_FGCONSOLE is not set +# CONFIG_KBD_MODE is not set +# CONFIG_LOADFONT is not set +# CONFIG_SETFONT is not set +# CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set +CONFIG_DEFAULT_SETFONT_DIR="" +# CONFIG_FEATURE_LOADFONT_PSF2 is not set +# CONFIG_FEATURE_LOADFONT_RAW is not set +# CONFIG_LOADKMAP is not set +# CONFIG_OPENVT is not set +# CONFIG_RESET is not set +# CONFIG_RESIZE is not set +# CONFIG_FEATURE_RESIZE_PRINT is not set +# CONFIG_SETCONSOLE is not set +# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set +# CONFIG_SETKEYCODES is not set +# CONFIG_SETLOGCONS is not set +# CONFIG_SHOWKEY is not set + +# +# Debian Utilities +# +# CONFIG_PIPE_PROGRESS is not set +# CONFIG_RUN_PARTS is not set +# CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set +# CONFIG_FEATURE_RUN_PARTS_FANCY is not set +# CONFIG_START_STOP_DAEMON is not set +# CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set +# CONFIG_FEATURE_START_STOP_DAEMON_FANCY is not set +# CONFIG_WHICH is not set + +# +# klibc-utils +# +# CONFIG_MINIPS is not set +# CONFIG_NUKE is not set +# CONFIG_RESUME is not set +# CONFIG_RUN_INIT is not set + +# +# Editors +# +# CONFIG_AWK is not set +# CONFIG_FEATURE_AWK_LIBM is not set +# CONFIG_FEATURE_AWK_GNU_EXTENSIONS is not set +# CONFIG_CMP is not set +# CONFIG_DIFF is not set +# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set +# CONFIG_FEATURE_DIFF_DIR is not set +# CONFIG_ED is not set +# CONFIG_PATCH is not set +# CONFIG_SED is not set +# CONFIG_VI is not set +CONFIG_FEATURE_VI_MAX_LEN=0 +# CONFIG_FEATURE_VI_8BIT is not set +# CONFIG_FEATURE_VI_COLON is not set +# CONFIG_FEATURE_VI_YANKMARK is not set +# CONFIG_FEATURE_VI_SEARCH is not set +# CONFIG_FEATURE_VI_REGEX_SEARCH is not set +# CONFIG_FEATURE_VI_USE_SIGNALS is not set +# CONFIG_FEATURE_VI_DOT_CMD is not set +# CONFIG_FEATURE_VI_READONLY is not set +# CONFIG_FEATURE_VI_SETOPTS is not set +# CONFIG_FEATURE_VI_SET is not set +# CONFIG_FEATURE_VI_WIN_RESIZE is not set +# CONFIG_FEATURE_VI_ASK_TERMINAL is not set +# CONFIG_FEATURE_VI_UNDO is not set +# CONFIG_FEATURE_VI_UNDO_QUEUE is not set +CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=0 +# CONFIG_FEATURE_ALLOW_EXEC is not set + +# +# Finding Utilities +# +# CONFIG_FIND is not set +# CONFIG_FEATURE_FIND_PRINT0 is not set +# CONFIG_FEATURE_FIND_MTIME is not set +# CONFIG_FEATURE_FIND_MMIN is not set +# CONFIG_FEATURE_FIND_PERM is not set +# CONFIG_FEATURE_FIND_TYPE is not set +# CONFIG_FEATURE_FIND_EXECUTABLE is not set +# CONFIG_FEATURE_FIND_XDEV is not set +# CONFIG_FEATURE_FIND_MAXDEPTH is not set +# CONFIG_FEATURE_FIND_NEWER is not set +# CONFIG_FEATURE_FIND_INUM is not set +# CONFIG_FEATURE_FIND_EXEC is not set +# CONFIG_FEATURE_FIND_EXEC_PLUS is not set +# CONFIG_FEATURE_FIND_USER is not set +# CONFIG_FEATURE_FIND_GROUP is not set +# CONFIG_FEATURE_FIND_NOT is not set +# CONFIG_FEATURE_FIND_DEPTH is not set +# CONFIG_FEATURE_FIND_PAREN is not set +# CONFIG_FEATURE_FIND_SIZE is not set +# CONFIG_FEATURE_FIND_PRUNE is not set +# CONFIG_FEATURE_FIND_QUIT is not set +# CONFIG_FEATURE_FIND_DELETE is not set +# CONFIG_FEATURE_FIND_EMPTY is not set +# CONFIG_FEATURE_FIND_PATH is not set +# CONFIG_FEATURE_FIND_REGEX is not set +# CONFIG_FEATURE_FIND_CONTEXT is not set +# CONFIG_FEATURE_FIND_LINKS is not set +# CONFIG_GREP is not set +# CONFIG_EGREP is not set +# CONFIG_FGREP is not set +# CONFIG_FEATURE_GREP_CONTEXT is not set +# CONFIG_XARGS is not set +# CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION is not set +# CONFIG_FEATURE_XARGS_SUPPORT_QUOTES is not set +# CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM is not set +# CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR is not set +# CONFIG_FEATURE_XARGS_SUPPORT_PARALLEL is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ARGS_FILE is not set + +# +# Init Utilities +# +# CONFIG_BOOTCHARTD is not set +# CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set +# CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set +# CONFIG_HALT is not set +# CONFIG_POWEROFF is not set +# CONFIG_REBOOT is not set +# CONFIG_FEATURE_WAIT_FOR_INIT is not set +# CONFIG_FEATURE_CALL_TELINIT is not set +CONFIG_TELINIT_PATH="" +# CONFIG_INIT is not set +# CONFIG_LINUXRC is not set +# CONFIG_FEATURE_USE_INITTAB is not set +# CONFIG_FEATURE_KILL_REMOVED is not set +CONFIG_FEATURE_KILL_DELAY=0 +# CONFIG_FEATURE_INIT_SCTTY is not set +# CONFIG_FEATURE_INIT_SYSLOG is not set +# CONFIG_FEATURE_INIT_QUIET is not set +# CONFIG_FEATURE_INIT_COREDUMPS is not set +CONFIG_INIT_TERMINAL_TYPE="" +# CONFIG_FEATURE_INIT_MODIFY_CMDLINE is not set + +# +# Login/Password Management Utilities +# +# CONFIG_FEATURE_SHADOWPASSWDS is not set +# CONFIG_USE_BB_PWD_GRP is not set +# CONFIG_USE_BB_SHADOW is not set +# CONFIG_USE_BB_CRYPT is not set +# CONFIG_USE_BB_CRYPT_SHA is not set +# CONFIG_ADD_SHELL is not set +# CONFIG_REMOVE_SHELL is not set +# CONFIG_ADDGROUP is not set +# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set +# CONFIG_ADDUSER is not set +# CONFIG_FEATURE_CHECK_NAMES is not set +CONFIG_LAST_ID=0 +CONFIG_FIRST_SYSTEM_ID=0 +CONFIG_LAST_SYSTEM_ID=0 +# CONFIG_CHPASSWD is not set +CONFIG_FEATURE_DEFAULT_PASSWD_ALGO="" +# CONFIG_CRYPTPW is not set +# CONFIG_MKPASSWD is not set +# CONFIG_DELUSER is not set +# CONFIG_DELGROUP is not set +# CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set +# CONFIG_GETTY is not set +# CONFIG_LOGIN is not set +# CONFIG_LOGIN_SESSION_AS_CHILD is not set +# CONFIG_LOGIN_SCRIPTS is not set +# CONFIG_FEATURE_NOLOGIN is not set +# CONFIG_FEATURE_SECURETTY is not set +# CONFIG_PASSWD is not set +# CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set +# CONFIG_SU is not set +# CONFIG_FEATURE_SU_SYSLOG is not set +# CONFIG_FEATURE_SU_CHECKS_SHELLS is not set +# CONFIG_FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY is not set +# CONFIG_SULOGIN is not set +# CONFIG_VLOCK is not set + +# +# Linux Ext2 FS Progs +# +# CONFIG_CHATTR is not set +# CONFIG_FSCK is not set +# CONFIG_LSATTR is not set +# CONFIG_TUNE2FS is not set + +# +# Linux Module Utilities +# +# CONFIG_MODPROBE_SMALL is not set +# CONFIG_DEPMOD is not set +# CONFIG_INSMOD is not set +# CONFIG_LSMOD is not set +# CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set +# CONFIG_MODINFO is not set +# CONFIG_MODPROBE is not set +# CONFIG_FEATURE_MODPROBE_BLACKLIST is not set +# CONFIG_RMMOD is not set + +# +# Options common to multiple modutils +# +# CONFIG_FEATURE_CMDLINE_MODULE_OPTIONS is not set +# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set +# CONFIG_FEATURE_2_4_MODULES is not set +# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set +# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set +# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set +# CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set +# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set +# CONFIG_FEATURE_MODUTILS_ALIAS is not set +# CONFIG_FEATURE_MODUTILS_SYMBOLS is not set +CONFIG_DEFAULT_MODULES_DIR="" +CONFIG_DEFAULT_DEPMOD_FILE="" + +# +# Linux System Utilities +# +# CONFIG_ACPID is not set +# CONFIG_FEATURE_ACPID_COMPAT is not set +# CONFIG_BLKDISCARD is not set +# CONFIG_BLKID is not set +# CONFIG_FEATURE_BLKID_TYPE is not set +# CONFIG_BLOCKDEV is not set +# CONFIG_CAL is not set +# CONFIG_CHRT is not set +# CONFIG_DMESG is not set +# CONFIG_FEATURE_DMESG_PRETTY is not set +# CONFIG_EJECT is not set +# CONFIG_FEATURE_EJECT_SCSI is not set +# CONFIG_FALLOCATE is not set +# CONFIG_FATATTR is not set +# CONFIG_FBSET is not set +# CONFIG_FEATURE_FBSET_FANCY is not set +# CONFIG_FEATURE_FBSET_READMODE is not set +# CONFIG_FDFORMAT is not set +# CONFIG_FDISK is not set +# CONFIG_FDISK_SUPPORT_LARGE_DISKS is not set +# CONFIG_FEATURE_FDISK_WRITABLE is not set +# CONFIG_FEATURE_AIX_LABEL is not set +# CONFIG_FEATURE_SGI_LABEL is not set +# CONFIG_FEATURE_SUN_LABEL is not set +# CONFIG_FEATURE_OSF_LABEL is not set +# CONFIG_FEATURE_GPT_LABEL is not set +# CONFIG_FEATURE_FDISK_ADVANCED is not set +# CONFIG_FINDFS is not set +# CONFIG_FLOCK is not set +# CONFIG_FDFLUSH is not set +# CONFIG_FREERAMDISK is not set +# CONFIG_FSCK_MINIX is not set +# CONFIG_FSFREEZE is not set +# CONFIG_FSTRIM is not set +# CONFIG_GETOPT is not set +# CONFIG_FEATURE_GETOPT_LONG is not set +CONFIG_HEXDUMP=y +CONFIG_FEATURE_HEXDUMP_REVERSE=y +# CONFIG_HD is not set +# CONFIG_XXD is not set +# CONFIG_HWCLOCK is not set +# CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set +# CONFIG_IONICE is not set +# CONFIG_IPCRM is not set +# CONFIG_IPCS is not set +# CONFIG_LAST is not set +# CONFIG_FEATURE_LAST_FANCY is not set +# CONFIG_LOSETUP is not set +# CONFIG_LSPCI is not set +# CONFIG_LSUSB is not set +# CONFIG_MDEV is not set +# CONFIG_FEATURE_MDEV_CONF is not set +# CONFIG_FEATURE_MDEV_RENAME is not set +# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set +# CONFIG_FEATURE_MDEV_EXEC is not set +# CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set +# CONFIG_FEATURE_MDEV_DAEMON is not set +# CONFIG_MESG is not set +# CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP is not set +# CONFIG_MKE2FS is not set +# CONFIG_MKFS_EXT2 is not set +# CONFIG_MKFS_MINIX is not set +# CONFIG_FEATURE_MINIX2 is not set +# CONFIG_MKFS_REISER is not set +# CONFIG_MKDOSFS is not set +# CONFIG_MKFS_VFAT is not set +# CONFIG_MKSWAP is not set +# CONFIG_FEATURE_MKSWAP_UUID is not set +# CONFIG_MORE is not set +# CONFIG_MOUNT is not set +# CONFIG_FEATURE_MOUNT_FAKE is not set +# CONFIG_FEATURE_MOUNT_VERBOSE is not set +# CONFIG_FEATURE_MOUNT_HELPERS is not set +# CONFIG_FEATURE_MOUNT_LABEL is not set +# CONFIG_FEATURE_MOUNT_NFS is not set +# CONFIG_FEATURE_MOUNT_CIFS is not set +# CONFIG_FEATURE_MOUNT_FLAGS is not set +# CONFIG_FEATURE_MOUNT_FSTAB is not set +# CONFIG_FEATURE_MOUNT_OTHERTAB is not set +# CONFIG_MOUNTPOINT is not set +# CONFIG_NOLOGIN is not set +# CONFIG_NOLOGIN_DEPENDENCIES is not set +# CONFIG_NSENTER is not set +# CONFIG_PIVOT_ROOT is not set +# CONFIG_RDATE is not set +# CONFIG_RDEV is not set +# CONFIG_READPROFILE is not set +# CONFIG_RENICE is not set +# CONFIG_REV is not set +# CONFIG_RTCWAKE is not set +# CONFIG_SCRIPT is not set +# CONFIG_SCRIPTREPLAY is not set +# CONFIG_SETARCH is not set +# CONFIG_LINUX32 is not set +# CONFIG_LINUX64 is not set +# CONFIG_SETPRIV is not set +# CONFIG_FEATURE_SETPRIV_DUMP is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITIES is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITY_NAMES is not set +# CONFIG_SETSID is not set +# CONFIG_SWAPON is not set +# CONFIG_FEATURE_SWAPON_DISCARD is not set +# CONFIG_FEATURE_SWAPON_PRI is not set +# CONFIG_SWAPOFF is not set +# CONFIG_FEATURE_SWAPONOFF_LABEL is not set +# CONFIG_SWITCH_ROOT is not set +# CONFIG_TASKSET is not set +# CONFIG_FEATURE_TASKSET_FANCY is not set +# CONFIG_FEATURE_TASKSET_CPULIST is not set +# CONFIG_UEVENT is not set +# CONFIG_UMOUNT is not set +# CONFIG_FEATURE_UMOUNT_ALL is not set +# CONFIG_UNSHARE is not set +# CONFIG_WALL is not set +# CONFIG_FEATURE_MOUNT_LOOP is not set +# CONFIG_FEATURE_MOUNT_LOOP_CREATE is not set +# CONFIG_FEATURE_MTAB_SUPPORT is not set +# CONFIG_VOLUMEID is not set +# CONFIG_FEATURE_VOLUMEID_BCACHE is not set +# CONFIG_FEATURE_VOLUMEID_BTRFS is not set +# CONFIG_FEATURE_VOLUMEID_CRAMFS is not set +# CONFIG_FEATURE_VOLUMEID_EXFAT is not set +# CONFIG_FEATURE_VOLUMEID_EXT is not set +# CONFIG_FEATURE_VOLUMEID_F2FS is not set +# CONFIG_FEATURE_VOLUMEID_FAT is not set +# CONFIG_FEATURE_VOLUMEID_HFS is not set +# CONFIG_FEATURE_VOLUMEID_ISO9660 is not set +# CONFIG_FEATURE_VOLUMEID_JFS is not set +# CONFIG_FEATURE_VOLUMEID_LFS is not set +# CONFIG_FEATURE_VOLUMEID_LINUXRAID is not set +# CONFIG_FEATURE_VOLUMEID_LINUXSWAP is not set +# CONFIG_FEATURE_VOLUMEID_LUKS is not set +# CONFIG_FEATURE_VOLUMEID_MINIX is not set +# CONFIG_FEATURE_VOLUMEID_NILFS is not set +# CONFIG_FEATURE_VOLUMEID_NTFS is not set +# CONFIG_FEATURE_VOLUMEID_OCFS2 is not set +# CONFIG_FEATURE_VOLUMEID_REISERFS is not set +# CONFIG_FEATURE_VOLUMEID_ROMFS is not set +# CONFIG_FEATURE_VOLUMEID_SQUASHFS is not set +# CONFIG_FEATURE_VOLUMEID_SYSV is not set +# CONFIG_FEATURE_VOLUMEID_UBIFS is not set +# CONFIG_FEATURE_VOLUMEID_UDF is not set +# CONFIG_FEATURE_VOLUMEID_XFS is not set + +# +# Miscellaneous Utilities +# +# CONFIG_ADJTIMEX is not set +# CONFIG_BBCONFIG is not set +# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set +# CONFIG_BC is not set +# CONFIG_DC is not set +# CONFIG_FEATURE_DC_BIG is not set +# CONFIG_FEATURE_DC_LIBM is not set +# CONFIG_FEATURE_BC_INTERACTIVE is not set +# CONFIG_FEATURE_BC_LONG_OPTIONS is not set +# CONFIG_BEEP is not set +CONFIG_FEATURE_BEEP_FREQ=0 +CONFIG_FEATURE_BEEP_LENGTH_MS=0 +# CONFIG_CHAT is not set +# CONFIG_FEATURE_CHAT_NOFAIL is not set +# CONFIG_FEATURE_CHAT_TTY_HIFI is not set +# CONFIG_FEATURE_CHAT_IMPLICIT_CR is not set +# CONFIG_FEATURE_CHAT_SWALLOW_OPTS is not set +# CONFIG_FEATURE_CHAT_SEND_ESCAPES is not set +# CONFIG_FEATURE_CHAT_VAR_ABORT_LEN is not set +# CONFIG_FEATURE_CHAT_CLR_ABORT is not set +# CONFIG_CONSPY is not set +# CONFIG_CROND is not set +# CONFIG_FEATURE_CROND_D is not set +# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set +# CONFIG_FEATURE_CROND_SPECIAL_TIMES is not set +CONFIG_FEATURE_CROND_DIR="" +# CONFIG_CRONTAB is not set +# CONFIG_DEVFSD is not set +# CONFIG_DEVFSD_MODLOAD is not set +# CONFIG_DEVFSD_FG_NP is not set +# CONFIG_DEVFSD_VERBOSE is not set +# CONFIG_FEATURE_DEVFS is not set +# CONFIG_DEVMEM is not set +# CONFIG_FBSPLASH is not set +# CONFIG_FLASH_ERASEALL is not set +# CONFIG_FLASH_LOCK is not set +# CONFIG_FLASH_UNLOCK is not set +# CONFIG_FLASHCP is not set +# CONFIG_HDPARM is not set +# CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set +# CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set +# CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set +# CONFIG_HEXEDIT is not set +# CONFIG_I2CGET is not set +# CONFIG_I2CSET is not set +# CONFIG_I2CDUMP is not set +# CONFIG_I2CDETECT is not set +# CONFIG_I2CTRANSFER is not set +# CONFIG_INOTIFYD is not set +# CONFIG_LESS is not set +CONFIG_FEATURE_LESS_MAXLINES=0 +# CONFIG_FEATURE_LESS_BRACKETS is not set +# CONFIG_FEATURE_LESS_FLAGS is not set +# CONFIG_FEATURE_LESS_TRUNCATE is not set +# CONFIG_FEATURE_LESS_MARKS is not set +# CONFIG_FEATURE_LESS_REGEXP is not set +# CONFIG_FEATURE_LESS_WINCH is not set +# CONFIG_FEATURE_LESS_ASK_TERMINAL is not set +# CONFIG_FEATURE_LESS_DASHCMD is not set +# CONFIG_FEATURE_LESS_LINENUMS is not set +# CONFIG_FEATURE_LESS_RAW is not set +# CONFIG_FEATURE_LESS_ENV is not set +# CONFIG_LSSCSI is not set +# CONFIG_MAKEDEVS is not set +# CONFIG_FEATURE_MAKEDEVS_LEAF is not set +# CONFIG_FEATURE_MAKEDEVS_TABLE is not set +# CONFIG_MAN is not set +# CONFIG_MICROCOM is not set +# CONFIG_MIM is not set +# CONFIG_MT is not set +# CONFIG_NANDWRITE is not set +# CONFIG_NANDDUMP is not set +# CONFIG_PARTPROBE is not set +# CONFIG_RAIDAUTORUN is not set +# CONFIG_READAHEAD is not set +# CONFIG_RFKILL is not set +# CONFIG_RUNLEVEL is not set +# CONFIG_RX is not set +# CONFIG_SETFATTR is not set +# CONFIG_SETSERIAL is not set +# CONFIG_STRINGS is not set +# CONFIG_TIME is not set +# CONFIG_TS is not set +# CONFIG_TTYSIZE is not set +# CONFIG_UBIATTACH is not set +# CONFIG_UBIDETACH is not set +# CONFIG_UBIMKVOL is not set +# CONFIG_UBIRMVOL is not set +# CONFIG_UBIRSVOL is not set +# CONFIG_UBIUPDATEVOL is not set +# CONFIG_UBIRENAME is not set +# CONFIG_VOLNAME is not set +# CONFIG_WATCHDOG is not set + +# +# Networking Utilities +# +# CONFIG_FEATURE_IPV6 is not set +# CONFIG_FEATURE_UNIX_LOCAL is not set +# CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set +# CONFIG_VERBOSE_RESOLUTION_ERRORS is not set +# CONFIG_FEATURE_TLS_SHA1 is not set +# CONFIG_ARP is not set +# CONFIG_ARPING is not set +# CONFIG_BRCTL is not set +# CONFIG_FEATURE_BRCTL_FANCY is not set +# CONFIG_FEATURE_BRCTL_SHOW is not set +# CONFIG_DNSD is not set +# CONFIG_ETHER_WAKE is not set +# CONFIG_FTPD is not set +# CONFIG_FEATURE_FTPD_WRITE is not set +# CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST is not set +# CONFIG_FEATURE_FTPD_AUTHENTICATION is not set +# CONFIG_FTPGET is not set +# CONFIG_FTPPUT is not set +# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set +# CONFIG_HOSTNAME is not set +# CONFIG_DNSDOMAINNAME is not set +# CONFIG_HTTPD is not set +# CONFIG_FEATURE_HTTPD_RANGES is not set +# CONFIG_FEATURE_HTTPD_SETUID is not set +# CONFIG_FEATURE_HTTPD_BASIC_AUTH is not set +# CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set +# CONFIG_FEATURE_HTTPD_CGI is not set +# CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set +# CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set +# CONFIG_FEATURE_HTTPD_ENCODE_URL_STR is not set +# CONFIG_FEATURE_HTTPD_ERROR_PAGES is not set +# CONFIG_FEATURE_HTTPD_PROXY is not set +# CONFIG_FEATURE_HTTPD_GZIP is not set +# CONFIG_IFCONFIG is not set +# CONFIG_FEATURE_IFCONFIG_STATUS is not set +# CONFIG_FEATURE_IFCONFIG_SLIP is not set +# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set +# CONFIG_FEATURE_IFCONFIG_HW is not set +# CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set +# CONFIG_IFENSLAVE is not set +# CONFIG_IFPLUGD is not set +# CONFIG_IFUP is not set +# CONFIG_IFDOWN is not set +CONFIG_IFUPDOWN_IFSTATE_PATH="" +# CONFIG_FEATURE_IFUPDOWN_IP is not set +# CONFIG_FEATURE_IFUPDOWN_IPV4 is not set +# CONFIG_FEATURE_IFUPDOWN_IPV6 is not set +# CONFIG_FEATURE_IFUPDOWN_MAPPING is not set +# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set +# CONFIG_INETD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set +# CONFIG_FEATURE_INETD_RPC is not set +# CONFIG_IP is not set +# CONFIG_IPADDR is not set +# CONFIG_IPLINK is not set +# CONFIG_IPROUTE is not set +# CONFIG_IPTUNNEL is not set +# CONFIG_IPRULE is not set +# CONFIG_IPNEIGH is not set +# CONFIG_FEATURE_IP_ADDRESS is not set +# CONFIG_FEATURE_IP_LINK is not set +# CONFIG_FEATURE_IP_ROUTE is not set +CONFIG_FEATURE_IP_ROUTE_DIR="" +# CONFIG_FEATURE_IP_TUNNEL is not set +# CONFIG_FEATURE_IP_RULE is not set +# CONFIG_FEATURE_IP_NEIGH is not set +# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set +# CONFIG_IPCALC is not set +# CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set +# CONFIG_FEATURE_IPCALC_FANCY is not set +# CONFIG_FAKEIDENTD is not set +# CONFIG_NAMEIF is not set +# CONFIG_FEATURE_NAMEIF_EXTENDED is not set +# CONFIG_NBDCLIENT is not set +# CONFIG_NC is not set +# CONFIG_NETCAT is not set +# CONFIG_NC_SERVER is not set +# CONFIG_NC_EXTRA is not set +# CONFIG_NC_110_COMPAT is not set +# CONFIG_NETSTAT is not set +# CONFIG_FEATURE_NETSTAT_WIDE is not set +# CONFIG_FEATURE_NETSTAT_PRG is not set +# CONFIG_NSLOOKUP is not set +# CONFIG_FEATURE_NSLOOKUP_BIG is not set +# CONFIG_FEATURE_NSLOOKUP_LONG_OPTIONS is not set +# CONFIG_NTPD is not set +# CONFIG_FEATURE_NTPD_SERVER is not set +# CONFIG_FEATURE_NTPD_CONF is not set +# CONFIG_FEATURE_NTP_AUTH is not set +# CONFIG_PING is not set +# CONFIG_PING6 is not set +# CONFIG_FEATURE_FANCY_PING is not set +# CONFIG_PSCAN is not set +# CONFIG_ROUTE is not set +# CONFIG_SLATTACH is not set +# CONFIG_SSL_CLIENT is not set +# CONFIG_TC is not set +# CONFIG_FEATURE_TC_INGRESS is not set +# CONFIG_TCPSVD is not set +# CONFIG_UDPSVD is not set +# CONFIG_TELNET is not set +# CONFIG_FEATURE_TELNET_TTYPE is not set +# CONFIG_FEATURE_TELNET_AUTOLOGIN is not set +# CONFIG_FEATURE_TELNET_WIDTH is not set +# CONFIG_TELNETD is not set +# CONFIG_FEATURE_TELNETD_STANDALONE is not set +# CONFIG_FEATURE_TELNETD_INETD_WAIT is not set +# CONFIG_TFTP is not set +# CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set +# CONFIG_FEATURE_TFTP_HPA_COMPAT is not set +# CONFIG_TFTPD is not set +# CONFIG_FEATURE_TFTP_GET is not set +# CONFIG_FEATURE_TFTP_PUT is not set +# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set +# CONFIG_TFTP_DEBUG is not set +# CONFIG_TLS is not set +# CONFIG_TRACEROUTE is not set +# CONFIG_TRACEROUTE6 is not set +# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set +# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set +# CONFIG_TUNCTL is not set +# CONFIG_FEATURE_TUNCTL_UG is not set +# CONFIG_VCONFIG is not set +# CONFIG_WGET is not set +# CONFIG_FEATURE_WGET_LONG_OPTIONS is not set +# CONFIG_FEATURE_WGET_STATUSBAR is not set +# CONFIG_FEATURE_WGET_AUTHENTICATION is not set +# CONFIG_FEATURE_WGET_TIMEOUT is not set +# CONFIG_FEATURE_WGET_HTTPS is not set +# CONFIG_FEATURE_WGET_OPENSSL is not set +# CONFIG_WHOIS is not set +# CONFIG_ZCIP is not set +# CONFIG_UDHCPD is not set +# CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC is not set +# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set +CONFIG_DHCPD_LEASES_FILE="" +# CONFIG_DUMPLEASES is not set +# CONFIG_DHCPRELAY is not set +# CONFIG_UDHCPC is not set +# CONFIG_FEATURE_UDHCPC_ARPING is not set +# CONFIG_FEATURE_UDHCPC_SANITIZEOPT is not set +CONFIG_UDHCPC_DEFAULT_SCRIPT="" +# CONFIG_UDHCPC6 is not set +# CONFIG_FEATURE_UDHCPC6_RFC3646 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4704 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4833 is not set +# CONFIG_FEATURE_UDHCPC6_RFC5970 is not set +# CONFIG_FEATURE_UDHCP_PORT is not set +CONFIG_UDHCP_DEBUG=0 +CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=0 +# CONFIG_FEATURE_UDHCP_RFC3397 is not set +# CONFIG_FEATURE_UDHCP_8021Q is not set +CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="" + +# +# Print Utilities +# +# CONFIG_LPD is not set +# CONFIG_LPR is not set +# CONFIG_LPQ is not set + +# +# Mail Utilities +# +# CONFIG_MAKEMIME is not set +# CONFIG_POPMAILDIR is not set +# CONFIG_FEATURE_POPMAILDIR_DELIVERY is not set +# CONFIG_REFORMIME is not set +# CONFIG_FEATURE_REFORMIME_COMPAT is not set +# CONFIG_SENDMAIL is not set +CONFIG_FEATURE_MIME_CHARSET="" + +# +# Process Utilities +# +# CONFIG_FREE is not set +# CONFIG_FUSER is not set +# CONFIG_IOSTAT is not set +# CONFIG_KILL is not set +# CONFIG_KILLALL is not set +# CONFIG_KILLALL5 is not set +# CONFIG_LSOF is not set +# CONFIG_MPSTAT is not set +# CONFIG_NMETER is not set +# CONFIG_PGREP is not set +# CONFIG_PKILL is not set +# CONFIG_PIDOF is not set +# CONFIG_FEATURE_PIDOF_SINGLE is not set +# CONFIG_FEATURE_PIDOF_OMIT is not set +# CONFIG_PMAP is not set +# CONFIG_POWERTOP is not set +# CONFIG_FEATURE_POWERTOP_INTERACTIVE is not set +# CONFIG_PS is not set +# CONFIG_FEATURE_PS_WIDE is not set +# CONFIG_FEATURE_PS_LONG is not set +# CONFIG_FEATURE_PS_TIME is not set +# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set +# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set +# CONFIG_PSTREE is not set +# CONFIG_PWDX is not set +# CONFIG_SMEMCAP is not set +# CONFIG_BB_SYSCTL is not set +# CONFIG_TOP is not set +# CONFIG_FEATURE_TOP_INTERACTIVE is not set +# CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE is not set +# CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS is not set +# CONFIG_FEATURE_TOP_SMP_CPU is not set +# CONFIG_FEATURE_TOP_DECIMALS is not set +# CONFIG_FEATURE_TOP_SMP_PROCESS is not set +# CONFIG_FEATURE_TOPMEM is not set +# CONFIG_UPTIME is not set +# CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set +# CONFIG_WATCH is not set +# CONFIG_FEATURE_SHOW_THREADS is not set + +# +# Runit Utilities +# +# CONFIG_CHPST is not set +# CONFIG_SETUIDGID is not set +# CONFIG_ENVUIDGID is not set +# CONFIG_ENVDIR is not set +# CONFIG_SOFTLIMIT is not set +# CONFIG_RUNSV is not set +# CONFIG_RUNSVDIR is not set +# CONFIG_FEATURE_RUNSVDIR_LOG is not set +# CONFIG_SV is not set +CONFIG_SV_DEFAULT_SERVICE_DIR="" +# CONFIG_SVC is not set +# CONFIG_SVOK is not set +# CONFIG_SVLOGD is not set +# CONFIG_CHCON is not set +# CONFIG_GETENFORCE is not set +# CONFIG_GETSEBOOL is not set +# CONFIG_LOAD_POLICY is not set +# CONFIG_MATCHPATHCON is not set +# CONFIG_RUNCON is not set +# CONFIG_SELINUXENABLED is not set +# CONFIG_SESTATUS is not set +# CONFIG_SETENFORCE is not set +# CONFIG_SETFILES is not set +# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set +# CONFIG_RESTORECON is not set +# CONFIG_SETSEBOOL is not set + +# +# Shells +# +# CONFIG_SH_IS_ASH is not set +# CONFIG_SH_IS_HUSH is not set +CONFIG_SH_IS_NONE=y +# CONFIG_BASH_IS_ASH is not set +# CONFIG_BASH_IS_HUSH is not set +CONFIG_BASH_IS_NONE=y +# CONFIG_SHELL_ASH is not set +# CONFIG_ASH is not set +# CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set +# CONFIG_ASH_INTERNAL_GLOB is not set +# CONFIG_ASH_BASH_COMPAT is not set +# CONFIG_ASH_BASH_SOURCE_CURDIR is not set +# CONFIG_ASH_BASH_NOT_FOUND_HOOK is not set +# CONFIG_ASH_JOB_CONTROL is not set +# CONFIG_ASH_ALIAS is not set +# CONFIG_ASH_RANDOM_SUPPORT is not set +# CONFIG_ASH_EXPAND_PRMT is not set +# CONFIG_ASH_IDLE_TIMEOUT is not set +# CONFIG_ASH_MAIL is not set +# CONFIG_ASH_ECHO is not set +# CONFIG_ASH_PRINTF is not set +# CONFIG_ASH_TEST is not set +# CONFIG_ASH_HELP is not set +# CONFIG_ASH_GETOPTS is not set +# CONFIG_ASH_CMDCMD is not set +# CONFIG_CTTYHACK is not set +# CONFIG_HUSH is not set +# CONFIG_SHELL_HUSH is not set +# CONFIG_HUSH_BASH_COMPAT is not set +# CONFIG_HUSH_BRACE_EXPANSION is not set +# CONFIG_HUSH_LINENO_VAR is not set +# CONFIG_HUSH_BASH_SOURCE_CURDIR is not set +# CONFIG_HUSH_INTERACTIVE is not set +# CONFIG_HUSH_SAVEHISTORY is not set +# CONFIG_HUSH_JOB is not set +# CONFIG_HUSH_TICK is not set +# CONFIG_HUSH_IF is not set +# CONFIG_HUSH_LOOPS is not set +# CONFIG_HUSH_CASE is not set +# CONFIG_HUSH_FUNCTIONS is not set +# CONFIG_HUSH_LOCAL is not set +# CONFIG_HUSH_RANDOM_SUPPORT is not set +# CONFIG_HUSH_MODE_X is not set +# CONFIG_HUSH_ECHO is not set +# CONFIG_HUSH_PRINTF is not set +# CONFIG_HUSH_TEST is not set +# CONFIG_HUSH_HELP is not set +# CONFIG_HUSH_EXPORT is not set +# CONFIG_HUSH_EXPORT_N is not set +# CONFIG_HUSH_READONLY is not set +# CONFIG_HUSH_KILL is not set +# CONFIG_HUSH_WAIT is not set +# CONFIG_HUSH_COMMAND is not set +# CONFIG_HUSH_TRAP is not set +# CONFIG_HUSH_TYPE is not set +# CONFIG_HUSH_TIMES is not set +# CONFIG_HUSH_READ is not set +# CONFIG_HUSH_SET is not set +# CONFIG_HUSH_UNSET is not set +# CONFIG_HUSH_ULIMIT is not set +# CONFIG_HUSH_UMASK is not set +# CONFIG_HUSH_GETOPTS is not set +# CONFIG_HUSH_MEMLEAK is not set + +# +# Options common to all shells +# +# CONFIG_FEATURE_SH_MATH is not set +# CONFIG_FEATURE_SH_MATH_64 is not set +# CONFIG_FEATURE_SH_MATH_BASE is not set +# CONFIG_FEATURE_SH_EXTRA_QUIET is not set +# CONFIG_FEATURE_SH_STANDALONE is not set +# CONFIG_FEATURE_SH_NOFORK is not set +# CONFIG_FEATURE_SH_READ_FRAC is not set +# CONFIG_FEATURE_SH_HISTFILESIZE is not set +# CONFIG_FEATURE_SH_EMBEDDED_SCRIPTS is not set + +# +# System Logging Utilities +# +# CONFIG_KLOGD is not set +# CONFIG_FEATURE_KLOGD_KLOGCTL is not set +# CONFIG_LOGGER is not set +# CONFIG_LOGREAD is not set +# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set +# CONFIG_SYSLOGD is not set +# CONFIG_FEATURE_ROTATE_LOGFILE is not set +# CONFIG_FEATURE_REMOTE_LOG is not set +# CONFIG_FEATURE_SYSLOGD_DUP is not set +# CONFIG_FEATURE_SYSLOGD_CFG is not set +# CONFIG_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS is not set +CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0 +# CONFIG_FEATURE_IPC_SYSLOG is not set +CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 +# CONFIG_FEATURE_KMSG_SYSLOG is not set diff --git a/BUSYBOX/aarch64_xzcat.config b/BUSYBOX/aarch64_xzcat.config new file mode 100644 index 0000000..cd4361d --- /dev/null +++ b/BUSYBOX/aarch64_xzcat.config @@ -0,0 +1,1166 @@ +# +# Automatically generated make config: don't edit +# Busybox version: 1.32.0 +# Tue Dec 8 11:07:46 2020 +# +CONFIG_HAVE_DOT_CONFIG=y + +# +# Settings +# +# CONFIG_DESKTOP is not set +# CONFIG_EXTRA_COMPAT is not set +# CONFIG_FEDORA_COMPAT is not set +# CONFIG_INCLUDE_SUSv2 is not set +# CONFIG_LONG_OPTS is not set +# CONFIG_SHOW_USAGE is not set +# CONFIG_FEATURE_VERBOSE_USAGE is not set +# CONFIG_FEATURE_COMPRESS_USAGE is not set +# CONFIG_LFS is not set +# CONFIG_PAM is not set +# CONFIG_FEATURE_DEVPTS is not set +# CONFIG_FEATURE_UTMP is not set +# CONFIG_FEATURE_WTMP is not set +# CONFIG_FEATURE_PIDFILE is not set +CONFIG_PID_FILE_PATH="" +# CONFIG_BUSYBOX is not set +# CONFIG_FEATURE_SHOW_SCRIPT is not set +# CONFIG_FEATURE_INSTALLER is not set +# CONFIG_INSTALL_NO_USR is not set +# CONFIG_FEATURE_SUID is not set +# CONFIG_FEATURE_SUID_CONFIG is not set +# CONFIG_FEATURE_SUID_CONFIG_QUIET is not set +# CONFIG_FEATURE_PREFER_APPLETS is not set +CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" +# CONFIG_SELINUX is not set +# CONFIG_FEATURE_CLEAN_UP is not set +# CONFIG_FEATURE_SYSLOG_INFO is not set +# CONFIG_FEATURE_SYSLOG is not set +# CONFIG_PLATFORM_LINUX is not set + +# +# Build Options +# +CONFIG_STATIC=y +# CONFIG_PIE is not set +# CONFIG_NOMMU is not set +# CONFIG_BUILD_LIBBUSYBOX is not set +# CONFIG_FEATURE_LIBBUSYBOX_STATIC is not set +# CONFIG_FEATURE_INDIVIDUAL is not set +# CONFIG_FEATURE_SHARED_BUSYBOX is not set +CONFIG_CROSS_COMPILER_PREFIX="" +CONFIG_SYSROOT="" +CONFIG_EXTRA_CFLAGS="" +CONFIG_EXTRA_LDFLAGS="" +CONFIG_EXTRA_LDLIBS="" +# CONFIG_USE_PORTABLE_CODE is not set +# CONFIG_STACK_OPTIMIZATION_386 is not set + +# +# Installation Options ("make install" behavior) +# +CONFIG_INSTALL_APPLET_SYMLINKS=y +# CONFIG_INSTALL_APPLET_HARDLINKS is not set +# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set +# CONFIG_INSTALL_APPLET_DONT is not set +# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set +# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set +# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set +CONFIG_PREFIX="./_install" + +# +# Debugging Options +# +# CONFIG_DEBUG is not set +# CONFIG_DEBUG_PESSIMIZE is not set +# CONFIG_DEBUG_SANITIZE is not set +# CONFIG_UNIT_TEST is not set +# CONFIG_WERROR is not set +# CONFIG_WARN_SIMPLE_MSG is not set +CONFIG_NO_DEBUG_LIB=y +# CONFIG_DMALLOC is not set +# CONFIG_EFENCE is not set + +# +# Library Tuning +# +# CONFIG_FEATURE_USE_BSS_TAIL is not set +# CONFIG_FLOAT_DURATION is not set +# CONFIG_FEATURE_RTMINMAX is not set +# CONFIG_FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS is not set +CONFIG_FEATURE_BUFFERS_USE_MALLOC=y +# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set +# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set +CONFIG_PASSWORD_MINLEN=6 +CONFIG_MD5_SMALL=1 +CONFIG_SHA3_SMALL=1 +# CONFIG_FEATURE_FAST_TOP is not set +# CONFIG_FEATURE_ETC_NETWORKS is not set +# CONFIG_FEATURE_ETC_SERVICES is not set +# CONFIG_FEATURE_EDITING is not set +CONFIG_FEATURE_EDITING_MAX_LEN=0 +# CONFIG_FEATURE_EDITING_VI is not set +CONFIG_FEATURE_EDITING_HISTORY=0 +# CONFIG_FEATURE_EDITING_SAVEHISTORY is not set +# CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set +# CONFIG_FEATURE_REVERSE_SEARCH is not set +# CONFIG_FEATURE_TAB_COMPLETION is not set +# CONFIG_FEATURE_USERNAME_COMPLETION is not set +# CONFIG_FEATURE_EDITING_FANCY_PROMPT is not set +# CONFIG_FEATURE_EDITING_WINCH is not set +# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set +# CONFIG_LOCALE_SUPPORT is not set +# CONFIG_UNICODE_SUPPORT is not set +# CONFIG_UNICODE_USING_LOCALE is not set +# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set +CONFIG_SUBST_WCHAR=0 +CONFIG_LAST_SUPPORTED_WCHAR=0 +# CONFIG_UNICODE_COMBINING_WCHARS is not set +# CONFIG_UNICODE_WIDE_WCHARS is not set +# CONFIG_UNICODE_BIDI_SUPPORT is not set +# CONFIG_UNICODE_NEUTRAL_TABLE is not set +# CONFIG_UNICODE_PRESERVE_BROKEN is not set +# CONFIG_FEATURE_NON_POSIX_CP is not set +# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set +# CONFIG_FEATURE_USE_SENDFILE is not set +CONFIG_FEATURE_COPYBUF_KB=4 +# CONFIG_FEATURE_SKIP_ROOTFS is not set +# CONFIG_MONOTONIC_SYSCALL is not set +# CONFIG_IOCTL_HEX2STR_ERROR is not set +# CONFIG_FEATURE_HWIB is not set + +# +# Applets +# + +# +# Archival Utilities +# +# CONFIG_FEATURE_SEAMLESS_XZ is not set +# CONFIG_FEATURE_SEAMLESS_LZMA is not set +# CONFIG_FEATURE_SEAMLESS_BZ2 is not set +# CONFIG_FEATURE_SEAMLESS_GZ is not set +# CONFIG_FEATURE_SEAMLESS_Z is not set +# CONFIG_AR is not set +# CONFIG_FEATURE_AR_LONG_FILENAMES is not set +# CONFIG_FEATURE_AR_CREATE is not set +# CONFIG_UNCOMPRESS is not set +# CONFIG_GUNZIP is not set +# CONFIG_ZCAT is not set +# CONFIG_FEATURE_GUNZIP_LONG_OPTIONS is not set +# CONFIG_BUNZIP2 is not set +# CONFIG_BZCAT is not set +# CONFIG_UNLZMA is not set +# CONFIG_LZCAT is not set +# CONFIG_LZMA is not set +# CONFIG_UNXZ is not set +CONFIG_XZCAT=y +# CONFIG_XZ is not set +# CONFIG_BZIP2 is not set +CONFIG_BZIP2_SMALL=0 +# CONFIG_FEATURE_BZIP2_DECOMPRESS is not set +# CONFIG_CPIO is not set +# CONFIG_FEATURE_CPIO_O is not set +# CONFIG_FEATURE_CPIO_P is not set +# CONFIG_DPKG is not set +# CONFIG_DPKG_DEB is not set +# CONFIG_GZIP is not set +# CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set +CONFIG_GZIP_FAST=0 +# CONFIG_FEATURE_GZIP_LEVELS is not set +# CONFIG_FEATURE_GZIP_DECOMPRESS is not set +# CONFIG_LZOP is not set +# CONFIG_UNLZOP is not set +# CONFIG_LZOPCAT is not set +# CONFIG_LZOP_COMPR_HIGH is not set +# CONFIG_RPM is not set +# CONFIG_RPM2CPIO is not set +# CONFIG_TAR is not set +# CONFIG_FEATURE_TAR_LONG_OPTIONS is not set +# CONFIG_FEATURE_TAR_CREATE is not set +# CONFIG_FEATURE_TAR_AUTODETECT is not set +# CONFIG_FEATURE_TAR_FROM is not set +# CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_GNU_EXTENSIONS is not set +# CONFIG_FEATURE_TAR_TO_COMMAND is not set +# CONFIG_FEATURE_TAR_UNAME_GNAME is not set +# CONFIG_FEATURE_TAR_NOPRESERVE_TIME is not set +# CONFIG_FEATURE_TAR_SELINUX is not set +# CONFIG_UNZIP is not set +# CONFIG_FEATURE_UNZIP_CDF is not set +# CONFIG_FEATURE_UNZIP_BZIP2 is not set +# CONFIG_FEATURE_UNZIP_LZMA is not set +# CONFIG_FEATURE_UNZIP_XZ is not set +# CONFIG_FEATURE_LZMA_FAST is not set + +# +# Coreutils +# +# CONFIG_BASENAME is not set +# CONFIG_CAT is not set +# CONFIG_FEATURE_CATN is not set +# CONFIG_FEATURE_CATV is not set +# CONFIG_CHGRP is not set +# CONFIG_CHMOD is not set +# CONFIG_CHOWN is not set +# CONFIG_FEATURE_CHOWN_LONG_OPTIONS is not set +# CONFIG_CHROOT is not set +# CONFIG_CKSUM is not set +# CONFIG_COMM is not set +# CONFIG_CP is not set +# CONFIG_FEATURE_CP_LONG_OPTIONS is not set +# CONFIG_FEATURE_CP_REFLINK is not set +# CONFIG_CUT is not set +# CONFIG_DATE is not set +# CONFIG_FEATURE_DATE_ISOFMT is not set +# CONFIG_FEATURE_DATE_NANO is not set +# CONFIG_FEATURE_DATE_COMPAT is not set +# CONFIG_DD is not set +# CONFIG_FEATURE_DD_SIGNAL_HANDLING is not set +# CONFIG_FEATURE_DD_THIRD_STATUS_LINE is not set +# CONFIG_FEATURE_DD_IBS_OBS is not set +# CONFIG_FEATURE_DD_STATUS is not set +# CONFIG_DF is not set +# CONFIG_FEATURE_DF_FANCY is not set +# CONFIG_DIRNAME is not set +# CONFIG_DOS2UNIX is not set +# CONFIG_UNIX2DOS is not set +# CONFIG_DU is not set +# CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K is not set +# CONFIG_ECHO is not set +# CONFIG_FEATURE_FANCY_ECHO is not set +# CONFIG_ENV is not set +# CONFIG_EXPAND is not set +# CONFIG_UNEXPAND is not set +# CONFIG_EXPR is not set +# CONFIG_EXPR_MATH_SUPPORT_64 is not set +# CONFIG_FACTOR is not set +# CONFIG_FALSE is not set +# CONFIG_FOLD is not set +# CONFIG_HEAD is not set +# CONFIG_FEATURE_FANCY_HEAD is not set +# CONFIG_HOSTID is not set +# CONFIG_ID is not set +# CONFIG_GROUPS is not set +# CONFIG_INSTALL is not set +# CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set +# CONFIG_LINK is not set +# CONFIG_LN is not set +# CONFIG_LOGNAME is not set +# CONFIG_LS is not set +# CONFIG_FEATURE_LS_FILETYPES is not set +# CONFIG_FEATURE_LS_FOLLOWLINKS is not set +# CONFIG_FEATURE_LS_RECURSIVE is not set +# CONFIG_FEATURE_LS_WIDTH is not set +# CONFIG_FEATURE_LS_SORTFILES is not set +# CONFIG_FEATURE_LS_TIMESTAMPS is not set +# CONFIG_FEATURE_LS_USERNAME is not set +# CONFIG_FEATURE_LS_COLOR is not set +# CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set +# CONFIG_MD5SUM is not set +# CONFIG_SHA1SUM is not set +# CONFIG_SHA256SUM is not set +# CONFIG_SHA512SUM is not set +# CONFIG_SHA3SUM is not set +# CONFIG_FEATURE_MD5_SHA1_SUM_CHECK is not set +# CONFIG_MKDIR is not set +# CONFIG_MKFIFO is not set +# CONFIG_MKNOD is not set +# CONFIG_MKTEMP is not set +# CONFIG_MV is not set +# CONFIG_NICE is not set +# CONFIG_NL is not set +# CONFIG_NOHUP is not set +# CONFIG_NPROC is not set +# CONFIG_OD is not set +# CONFIG_PASTE is not set +# CONFIG_PRINTENV is not set +# CONFIG_PRINTF is not set +# CONFIG_PWD is not set +# CONFIG_READLINK is not set +# CONFIG_FEATURE_READLINK_FOLLOW is not set +# CONFIG_REALPATH is not set +# CONFIG_RM is not set +# CONFIG_RMDIR is not set +# CONFIG_SEQ is not set +# CONFIG_SHRED is not set +# CONFIG_SHUF is not set +# CONFIG_SLEEP is not set +# CONFIG_FEATURE_FANCY_SLEEP is not set +# CONFIG_SORT is not set +# CONFIG_FEATURE_SORT_BIG is not set +# CONFIG_FEATURE_SORT_OPTIMIZE_MEMORY is not set +# CONFIG_SPLIT is not set +# CONFIG_FEATURE_SPLIT_FANCY is not set +# CONFIG_STAT is not set +# CONFIG_FEATURE_STAT_FORMAT is not set +# CONFIG_FEATURE_STAT_FILESYSTEM is not set +# CONFIG_STTY is not set +# CONFIG_SUM is not set +# CONFIG_SYNC is not set +# CONFIG_FEATURE_SYNC_FANCY is not set +# CONFIG_FSYNC is not set +# CONFIG_TAC is not set +# CONFIG_TAIL is not set +# CONFIG_FEATURE_FANCY_TAIL is not set +# CONFIG_TEE is not set +# CONFIG_FEATURE_TEE_USE_BLOCK_IO is not set +# CONFIG_TEST is not set +# CONFIG_TEST1 is not set +# CONFIG_TEST2 is not set +# CONFIG_FEATURE_TEST_64 is not set +# CONFIG_TIMEOUT is not set +# CONFIG_TOUCH is not set +# CONFIG_FEATURE_TOUCH_NODEREF is not set +# CONFIG_FEATURE_TOUCH_SUSV3 is not set +# CONFIG_TR is not set +# CONFIG_FEATURE_TR_CLASSES is not set +# CONFIG_FEATURE_TR_EQUIV is not set +# CONFIG_TRUE is not set +# CONFIG_TRUNCATE is not set +# CONFIG_TTY is not set +# CONFIG_UNAME is not set +CONFIG_UNAME_OSNAME="" +# CONFIG_BB_ARCH is not set +# CONFIG_UNIQ is not set +# CONFIG_UNLINK is not set +# CONFIG_USLEEP is not set +# CONFIG_UUDECODE is not set +# CONFIG_BASE64 is not set +# CONFIG_UUENCODE is not set +# CONFIG_WC is not set +# CONFIG_FEATURE_WC_LARGE is not set +# CONFIG_WHOAMI is not set +# CONFIG_WHO is not set +# CONFIG_W is not set +# CONFIG_USERS is not set +# CONFIG_YES is not set + +# +# Common options +# +# CONFIG_FEATURE_VERBOSE is not set +# CONFIG_FEATURE_PRESERVE_HARDLINKS is not set +# CONFIG_FEATURE_HUMAN_READABLE is not set + +# +# Console Utilities +# +# CONFIG_CHVT is not set +# CONFIG_CLEAR is not set +# CONFIG_DEALLOCVT is not set +# CONFIG_DUMPKMAP is not set +# CONFIG_FGCONSOLE is not set +# CONFIG_KBD_MODE is not set +# CONFIG_LOADFONT is not set +# CONFIG_SETFONT is not set +# CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set +CONFIG_DEFAULT_SETFONT_DIR="" +# CONFIG_FEATURE_LOADFONT_PSF2 is not set +# CONFIG_FEATURE_LOADFONT_RAW is not set +# CONFIG_LOADKMAP is not set +# CONFIG_OPENVT is not set +# CONFIG_RESET is not set +# CONFIG_RESIZE is not set +# CONFIG_FEATURE_RESIZE_PRINT is not set +# CONFIG_SETCONSOLE is not set +# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set +# CONFIG_SETKEYCODES is not set +# CONFIG_SETLOGCONS is not set +# CONFIG_SHOWKEY is not set + +# +# Debian Utilities +# +# CONFIG_PIPE_PROGRESS is not set +# CONFIG_RUN_PARTS is not set +# CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set +# CONFIG_FEATURE_RUN_PARTS_FANCY is not set +# CONFIG_START_STOP_DAEMON is not set +# CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set +# CONFIG_FEATURE_START_STOP_DAEMON_FANCY is not set +# CONFIG_WHICH is not set + +# +# klibc-utils +# +# CONFIG_MINIPS is not set +# CONFIG_NUKE is not set +# CONFIG_RESUME is not set +# CONFIG_RUN_INIT is not set + +# +# Editors +# +# CONFIG_AWK is not set +# CONFIG_FEATURE_AWK_LIBM is not set +# CONFIG_FEATURE_AWK_GNU_EXTENSIONS is not set +# CONFIG_CMP is not set +# CONFIG_DIFF is not set +# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set +# CONFIG_FEATURE_DIFF_DIR is not set +# CONFIG_ED is not set +# CONFIG_PATCH is not set +# CONFIG_SED is not set +# CONFIG_VI is not set +CONFIG_FEATURE_VI_MAX_LEN=0 +# CONFIG_FEATURE_VI_8BIT is not set +# CONFIG_FEATURE_VI_COLON is not set +# CONFIG_FEATURE_VI_YANKMARK is not set +# CONFIG_FEATURE_VI_SEARCH is not set +# CONFIG_FEATURE_VI_REGEX_SEARCH is not set +# CONFIG_FEATURE_VI_USE_SIGNALS is not set +# CONFIG_FEATURE_VI_DOT_CMD is not set +# CONFIG_FEATURE_VI_READONLY is not set +# CONFIG_FEATURE_VI_SETOPTS is not set +# CONFIG_FEATURE_VI_SET is not set +# CONFIG_FEATURE_VI_WIN_RESIZE is not set +# CONFIG_FEATURE_VI_ASK_TERMINAL is not set +# CONFIG_FEATURE_VI_UNDO is not set +# CONFIG_FEATURE_VI_UNDO_QUEUE is not set +CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=0 +# CONFIG_FEATURE_ALLOW_EXEC is not set + +# +# Finding Utilities +# +# CONFIG_FIND is not set +# CONFIG_FEATURE_FIND_PRINT0 is not set +# CONFIG_FEATURE_FIND_MTIME is not set +# CONFIG_FEATURE_FIND_MMIN is not set +# CONFIG_FEATURE_FIND_PERM is not set +# CONFIG_FEATURE_FIND_TYPE is not set +# CONFIG_FEATURE_FIND_EXECUTABLE is not set +# CONFIG_FEATURE_FIND_XDEV is not set +# CONFIG_FEATURE_FIND_MAXDEPTH is not set +# CONFIG_FEATURE_FIND_NEWER is not set +# CONFIG_FEATURE_FIND_INUM is not set +# CONFIG_FEATURE_FIND_EXEC is not set +# CONFIG_FEATURE_FIND_EXEC_PLUS is not set +# CONFIG_FEATURE_FIND_USER is not set +# CONFIG_FEATURE_FIND_GROUP is not set +# CONFIG_FEATURE_FIND_NOT is not set +# CONFIG_FEATURE_FIND_DEPTH is not set +# CONFIG_FEATURE_FIND_PAREN is not set +# CONFIG_FEATURE_FIND_SIZE is not set +# CONFIG_FEATURE_FIND_PRUNE is not set +# CONFIG_FEATURE_FIND_QUIT is not set +# CONFIG_FEATURE_FIND_DELETE is not set +# CONFIG_FEATURE_FIND_EMPTY is not set +# CONFIG_FEATURE_FIND_PATH is not set +# CONFIG_FEATURE_FIND_REGEX is not set +# CONFIG_FEATURE_FIND_CONTEXT is not set +# CONFIG_FEATURE_FIND_LINKS is not set +# CONFIG_GREP is not set +# CONFIG_EGREP is not set +# CONFIG_FGREP is not set +# CONFIG_FEATURE_GREP_CONTEXT is not set +# CONFIG_XARGS is not set +# CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION is not set +# CONFIG_FEATURE_XARGS_SUPPORT_QUOTES is not set +# CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM is not set +# CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR is not set +# CONFIG_FEATURE_XARGS_SUPPORT_PARALLEL is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ARGS_FILE is not set + +# +# Init Utilities +# +# CONFIG_BOOTCHARTD is not set +# CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set +# CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set +# CONFIG_HALT is not set +# CONFIG_POWEROFF is not set +# CONFIG_REBOOT is not set +# CONFIG_FEATURE_WAIT_FOR_INIT is not set +# CONFIG_FEATURE_CALL_TELINIT is not set +CONFIG_TELINIT_PATH="" +# CONFIG_INIT is not set +# CONFIG_LINUXRC is not set +# CONFIG_FEATURE_USE_INITTAB is not set +# CONFIG_FEATURE_KILL_REMOVED is not set +CONFIG_FEATURE_KILL_DELAY=0 +# CONFIG_FEATURE_INIT_SCTTY is not set +# CONFIG_FEATURE_INIT_SYSLOG is not set +# CONFIG_FEATURE_INIT_QUIET is not set +# CONFIG_FEATURE_INIT_COREDUMPS is not set +CONFIG_INIT_TERMINAL_TYPE="" +# CONFIG_FEATURE_INIT_MODIFY_CMDLINE is not set + +# +# Login/Password Management Utilities +# +# CONFIG_FEATURE_SHADOWPASSWDS is not set +# CONFIG_USE_BB_PWD_GRP is not set +# CONFIG_USE_BB_SHADOW is not set +# CONFIG_USE_BB_CRYPT is not set +# CONFIG_USE_BB_CRYPT_SHA is not set +# CONFIG_ADDGROUP is not set +# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set +# CONFIG_ADD_SHELL is not set +# CONFIG_REMOVE_SHELL is not set +# CONFIG_ADDUSER is not set +# CONFIG_FEATURE_CHECK_NAMES is not set +CONFIG_LAST_ID=0 +CONFIG_FIRST_SYSTEM_ID=0 +CONFIG_LAST_SYSTEM_ID=0 +# CONFIG_CHPASSWD is not set +CONFIG_FEATURE_DEFAULT_PASSWD_ALGO="" +# CONFIG_CRYPTPW is not set +# CONFIG_MKPASSWD is not set +# CONFIG_DELUSER is not set +# CONFIG_DELGROUP is not set +# CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set +# CONFIG_GETTY is not set +# CONFIG_LOGIN is not set +# CONFIG_LOGIN_SESSION_AS_CHILD is not set +# CONFIG_LOGIN_SCRIPTS is not set +# CONFIG_FEATURE_NOLOGIN is not set +# CONFIG_FEATURE_SECURETTY is not set +# CONFIG_PASSWD is not set +# CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set +# CONFIG_SU is not set +# CONFIG_FEATURE_SU_SYSLOG is not set +# CONFIG_FEATURE_SU_CHECKS_SHELLS is not set +# CONFIG_FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY is not set +# CONFIG_SULOGIN is not set +# CONFIG_VLOCK is not set + +# +# Linux Ext2 FS Progs +# +# CONFIG_CHATTR is not set +# CONFIG_FSCK is not set +# CONFIG_LSATTR is not set +# CONFIG_TUNE2FS is not set + +# +# Linux Module Utilities +# +# CONFIG_MODPROBE_SMALL is not set +# CONFIG_DEPMOD is not set +# CONFIG_INSMOD is not set +# CONFIG_LSMOD is not set +# CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set +# CONFIG_MODINFO is not set +# CONFIG_MODPROBE is not set +# CONFIG_FEATURE_MODPROBE_BLACKLIST is not set +# CONFIG_RMMOD is not set + +# +# Options common to multiple modutils +# +# CONFIG_FEATURE_CMDLINE_MODULE_OPTIONS is not set +# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set +# CONFIG_FEATURE_2_4_MODULES is not set +# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set +# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set +# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set +# CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set +# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set +# CONFIG_FEATURE_MODUTILS_ALIAS is not set +# CONFIG_FEATURE_MODUTILS_SYMBOLS is not set +CONFIG_DEFAULT_MODULES_DIR="" +CONFIG_DEFAULT_DEPMOD_FILE="" + +# +# Linux System Utilities +# +# CONFIG_ACPID is not set +# CONFIG_FEATURE_ACPID_COMPAT is not set +# CONFIG_BLKDISCARD is not set +# CONFIG_BLKID is not set +# CONFIG_FEATURE_BLKID_TYPE is not set +# CONFIG_BLOCKDEV is not set +# CONFIG_CAL is not set +# CONFIG_CHRT is not set +# CONFIG_DMESG is not set +# CONFIG_FEATURE_DMESG_PRETTY is not set +# CONFIG_EJECT is not set +# CONFIG_FEATURE_EJECT_SCSI is not set +# CONFIG_FALLOCATE is not set +# CONFIG_FATATTR is not set +# CONFIG_FBSET is not set +# CONFIG_FEATURE_FBSET_FANCY is not set +# CONFIG_FEATURE_FBSET_READMODE is not set +# CONFIG_FDFORMAT is not set +# CONFIG_FDISK is not set +# CONFIG_FDISK_SUPPORT_LARGE_DISKS is not set +# CONFIG_FEATURE_FDISK_WRITABLE is not set +# CONFIG_FEATURE_AIX_LABEL is not set +# CONFIG_FEATURE_SGI_LABEL is not set +# CONFIG_FEATURE_SUN_LABEL is not set +# CONFIG_FEATURE_OSF_LABEL is not set +# CONFIG_FEATURE_GPT_LABEL is not set +# CONFIG_FEATURE_FDISK_ADVANCED is not set +# CONFIG_FINDFS is not set +# CONFIG_FLOCK is not set +# CONFIG_FDFLUSH is not set +# CONFIG_FREERAMDISK is not set +# CONFIG_FSCK_MINIX is not set +# CONFIG_FSFREEZE is not set +# CONFIG_FSTRIM is not set +# CONFIG_GETOPT is not set +# CONFIG_FEATURE_GETOPT_LONG is not set +# CONFIG_HEXDUMP is not set +# CONFIG_FEATURE_HEXDUMP_REVERSE is not set +# CONFIG_HD is not set +# CONFIG_XXD is not set +# CONFIG_HWCLOCK is not set +# CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set +# CONFIG_IONICE is not set +# CONFIG_IPCRM is not set +# CONFIG_IPCS is not set +# CONFIG_LAST is not set +# CONFIG_FEATURE_LAST_FANCY is not set +# CONFIG_LOSETUP is not set +# CONFIG_LSPCI is not set +# CONFIG_LSUSB is not set +# CONFIG_MDEV is not set +# CONFIG_FEATURE_MDEV_CONF is not set +# CONFIG_FEATURE_MDEV_RENAME is not set +# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set +# CONFIG_FEATURE_MDEV_EXEC is not set +# CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set +# CONFIG_FEATURE_MDEV_DAEMON is not set +# CONFIG_MESG is not set +# CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP is not set +# CONFIG_MKE2FS is not set +# CONFIG_MKFS_EXT2 is not set +# CONFIG_MKFS_MINIX is not set +# CONFIG_FEATURE_MINIX2 is not set +# CONFIG_MKFS_REISER is not set +# CONFIG_MKDOSFS is not set +# CONFIG_MKFS_VFAT is not set +# CONFIG_MKSWAP is not set +# CONFIG_FEATURE_MKSWAP_UUID is not set +# CONFIG_MORE is not set +# CONFIG_MOUNT is not set +# CONFIG_FEATURE_MOUNT_FAKE is not set +# CONFIG_FEATURE_MOUNT_VERBOSE is not set +# CONFIG_FEATURE_MOUNT_HELPERS is not set +# CONFIG_FEATURE_MOUNT_LABEL is not set +# CONFIG_FEATURE_MOUNT_NFS is not set +# CONFIG_FEATURE_MOUNT_CIFS is not set +# CONFIG_FEATURE_MOUNT_FLAGS is not set +# CONFIG_FEATURE_MOUNT_FSTAB is not set +# CONFIG_FEATURE_MOUNT_OTHERTAB is not set +# CONFIG_MOUNTPOINT is not set +# CONFIG_NOLOGIN is not set +# CONFIG_NOLOGIN_DEPENDENCIES is not set +# CONFIG_NSENTER is not set +# CONFIG_PIVOT_ROOT is not set +# CONFIG_RDATE is not set +# CONFIG_RDEV is not set +# CONFIG_READPROFILE is not set +# CONFIG_RENICE is not set +# CONFIG_REV is not set +# CONFIG_RTCWAKE is not set +# CONFIG_SCRIPT is not set +# CONFIG_SCRIPTREPLAY is not set +# CONFIG_SETARCH is not set +# CONFIG_LINUX32 is not set +# CONFIG_LINUX64 is not set +# CONFIG_SETPRIV is not set +# CONFIG_FEATURE_SETPRIV_DUMP is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITIES is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITY_NAMES is not set +# CONFIG_SETSID is not set +# CONFIG_SWAPON is not set +# CONFIG_FEATURE_SWAPON_DISCARD is not set +# CONFIG_FEATURE_SWAPON_PRI is not set +# CONFIG_SWAPOFF is not set +# CONFIG_FEATURE_SWAPONOFF_LABEL is not set +# CONFIG_SWITCH_ROOT is not set +# CONFIG_TASKSET is not set +# CONFIG_FEATURE_TASKSET_FANCY is not set +# CONFIG_FEATURE_TASKSET_CPULIST is not set +# CONFIG_UEVENT is not set +# CONFIG_UMOUNT is not set +# CONFIG_FEATURE_UMOUNT_ALL is not set +# CONFIG_UNSHARE is not set +# CONFIG_WALL is not set +# CONFIG_FEATURE_MOUNT_LOOP is not set +# CONFIG_FEATURE_MOUNT_LOOP_CREATE is not set +# CONFIG_FEATURE_MTAB_SUPPORT is not set +# CONFIG_VOLUMEID is not set +# CONFIG_FEATURE_VOLUMEID_BCACHE is not set +# CONFIG_FEATURE_VOLUMEID_BTRFS is not set +# CONFIG_FEATURE_VOLUMEID_CRAMFS is not set +# CONFIG_FEATURE_VOLUMEID_EXFAT is not set +# CONFIG_FEATURE_VOLUMEID_EXT is not set +# CONFIG_FEATURE_VOLUMEID_F2FS is not set +# CONFIG_FEATURE_VOLUMEID_FAT is not set +# CONFIG_FEATURE_VOLUMEID_HFS is not set +# CONFIG_FEATURE_VOLUMEID_ISO9660 is not set +# CONFIG_FEATURE_VOLUMEID_JFS is not set +# CONFIG_FEATURE_VOLUMEID_LFS is not set +# CONFIG_FEATURE_VOLUMEID_LINUXRAID is not set +# CONFIG_FEATURE_VOLUMEID_LINUXSWAP is not set +# CONFIG_FEATURE_VOLUMEID_LUKS is not set +# CONFIG_FEATURE_VOLUMEID_MINIX is not set +# CONFIG_FEATURE_VOLUMEID_NILFS is not set +# CONFIG_FEATURE_VOLUMEID_NTFS is not set +# CONFIG_FEATURE_VOLUMEID_OCFS2 is not set +# CONFIG_FEATURE_VOLUMEID_REISERFS is not set +# CONFIG_FEATURE_VOLUMEID_ROMFS is not set +# CONFIG_FEATURE_VOLUMEID_SQUASHFS is not set +# CONFIG_FEATURE_VOLUMEID_SYSV is not set +# CONFIG_FEATURE_VOLUMEID_UBIFS is not set +# CONFIG_FEATURE_VOLUMEID_UDF is not set +# CONFIG_FEATURE_VOLUMEID_XFS is not set + +# +# Miscellaneous Utilities +# +# CONFIG_ADJTIMEX is not set +# CONFIG_BBCONFIG is not set +# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set +# CONFIG_BC is not set +# CONFIG_DC is not set +# CONFIG_FEATURE_DC_BIG is not set +# CONFIG_FEATURE_DC_LIBM is not set +# CONFIG_FEATURE_BC_INTERACTIVE is not set +# CONFIG_FEATURE_BC_LONG_OPTIONS is not set +# CONFIG_BEEP is not set +CONFIG_FEATURE_BEEP_FREQ=0 +CONFIG_FEATURE_BEEP_LENGTH_MS=0 +# CONFIG_CHAT is not set +# CONFIG_FEATURE_CHAT_NOFAIL is not set +# CONFIG_FEATURE_CHAT_TTY_HIFI is not set +# CONFIG_FEATURE_CHAT_IMPLICIT_CR is not set +# CONFIG_FEATURE_CHAT_SWALLOW_OPTS is not set +# CONFIG_FEATURE_CHAT_SEND_ESCAPES is not set +# CONFIG_FEATURE_CHAT_VAR_ABORT_LEN is not set +# CONFIG_FEATURE_CHAT_CLR_ABORT is not set +# CONFIG_CONSPY is not set +# CONFIG_CROND is not set +# CONFIG_FEATURE_CROND_D is not set +# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set +# CONFIG_FEATURE_CROND_SPECIAL_TIMES is not set +CONFIG_FEATURE_CROND_DIR="" +# CONFIG_CRONTAB is not set +# CONFIG_DEVFSD is not set +# CONFIG_DEVFSD_MODLOAD is not set +# CONFIG_DEVFSD_FG_NP is not set +# CONFIG_DEVFSD_VERBOSE is not set +# CONFIG_FEATURE_DEVFS is not set +# CONFIG_DEVMEM is not set +# CONFIG_FBSPLASH is not set +# CONFIG_FLASHCP is not set +# CONFIG_FLASH_ERASEALL is not set +# CONFIG_FLASH_LOCK is not set +# CONFIG_FLASH_UNLOCK is not set +# CONFIG_HDPARM is not set +# CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set +# CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set +# CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set +# CONFIG_HEXEDIT is not set +# CONFIG_I2CGET is not set +# CONFIG_I2CSET is not set +# CONFIG_I2CDUMP is not set +# CONFIG_I2CDETECT is not set +# CONFIG_I2CTRANSFER is not set +# CONFIG_INOTIFYD is not set +# CONFIG_LESS is not set +CONFIG_FEATURE_LESS_MAXLINES=0 +# CONFIG_FEATURE_LESS_BRACKETS is not set +# CONFIG_FEATURE_LESS_FLAGS is not set +# CONFIG_FEATURE_LESS_TRUNCATE is not set +# CONFIG_FEATURE_LESS_MARKS is not set +# CONFIG_FEATURE_LESS_REGEXP is not set +# CONFIG_FEATURE_LESS_WINCH is not set +# CONFIG_FEATURE_LESS_ASK_TERMINAL is not set +# CONFIG_FEATURE_LESS_DASHCMD is not set +# CONFIG_FEATURE_LESS_LINENUMS is not set +# CONFIG_FEATURE_LESS_RAW is not set +# CONFIG_FEATURE_LESS_ENV is not set +# CONFIG_LSSCSI is not set +# CONFIG_MAKEDEVS is not set +# CONFIG_FEATURE_MAKEDEVS_LEAF is not set +# CONFIG_FEATURE_MAKEDEVS_TABLE is not set +# CONFIG_MAN is not set +# CONFIG_MICROCOM is not set +# CONFIG_MIM is not set +# CONFIG_MT is not set +# CONFIG_NANDWRITE is not set +# CONFIG_NANDDUMP is not set +# CONFIG_PARTPROBE is not set +# CONFIG_RAIDAUTORUN is not set +# CONFIG_READAHEAD is not set +# CONFIG_RFKILL is not set +# CONFIG_RUNLEVEL is not set +# CONFIG_RX is not set +# CONFIG_SETFATTR is not set +# CONFIG_SETSERIAL is not set +# CONFIG_STRINGS is not set +# CONFIG_TIME is not set +# CONFIG_TS is not set +# CONFIG_TTYSIZE is not set +# CONFIG_UBIRENAME is not set +# CONFIG_UBIATTACH is not set +# CONFIG_UBIDETACH is not set +# CONFIG_UBIMKVOL is not set +# CONFIG_UBIRMVOL is not set +# CONFIG_UBIRSVOL is not set +# CONFIG_UBIUPDATEVOL is not set +# CONFIG_VOLNAME is not set +# CONFIG_WATCHDOG is not set + +# +# Networking Utilities +# +# CONFIG_FEATURE_IPV6 is not set +# CONFIG_FEATURE_UNIX_LOCAL is not set +# CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set +# CONFIG_VERBOSE_RESOLUTION_ERRORS is not set +# CONFIG_FEATURE_TLS_SHA1 is not set +# CONFIG_ARP is not set +# CONFIG_ARPING is not set +# CONFIG_BRCTL is not set +# CONFIG_FEATURE_BRCTL_FANCY is not set +# CONFIG_FEATURE_BRCTL_SHOW is not set +# CONFIG_DNSD is not set +# CONFIG_ETHER_WAKE is not set +# CONFIG_FTPD is not set +# CONFIG_FEATURE_FTPD_WRITE is not set +# CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST is not set +# CONFIG_FEATURE_FTPD_AUTHENTICATION is not set +# CONFIG_FTPGET is not set +# CONFIG_FTPPUT is not set +# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set +# CONFIG_HOSTNAME is not set +# CONFIG_DNSDOMAINNAME is not set +# CONFIG_HTTPD is not set +# CONFIG_FEATURE_HTTPD_RANGES is not set +# CONFIG_FEATURE_HTTPD_SETUID is not set +# CONFIG_FEATURE_HTTPD_BASIC_AUTH is not set +# CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set +# CONFIG_FEATURE_HTTPD_CGI is not set +# CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set +# CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set +# CONFIG_FEATURE_HTTPD_ENCODE_URL_STR is not set +# CONFIG_FEATURE_HTTPD_ERROR_PAGES is not set +# CONFIG_FEATURE_HTTPD_PROXY is not set +# CONFIG_FEATURE_HTTPD_GZIP is not set +# CONFIG_IFCONFIG is not set +# CONFIG_FEATURE_IFCONFIG_STATUS is not set +# CONFIG_FEATURE_IFCONFIG_SLIP is not set +# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set +# CONFIG_FEATURE_IFCONFIG_HW is not set +# CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set +# CONFIG_IFENSLAVE is not set +# CONFIG_IFPLUGD is not set +# CONFIG_IFUP is not set +# CONFIG_IFDOWN is not set +CONFIG_IFUPDOWN_IFSTATE_PATH="" +# CONFIG_FEATURE_IFUPDOWN_IP is not set +# CONFIG_FEATURE_IFUPDOWN_IPV4 is not set +# CONFIG_FEATURE_IFUPDOWN_IPV6 is not set +# CONFIG_FEATURE_IFUPDOWN_MAPPING is not set +# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set +# CONFIG_INETD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set +# CONFIG_FEATURE_INETD_RPC is not set +# CONFIG_IP is not set +# CONFIG_IPADDR is not set +# CONFIG_IPLINK is not set +# CONFIG_IPROUTE is not set +# CONFIG_IPTUNNEL is not set +# CONFIG_IPRULE is not set +# CONFIG_IPNEIGH is not set +# CONFIG_FEATURE_IP_ADDRESS is not set +# CONFIG_FEATURE_IP_LINK is not set +# CONFIG_FEATURE_IP_ROUTE is not set +CONFIG_FEATURE_IP_ROUTE_DIR="" +# CONFIG_FEATURE_IP_TUNNEL is not set +# CONFIG_FEATURE_IP_RULE is not set +# CONFIG_FEATURE_IP_NEIGH is not set +# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set +# CONFIG_IPCALC is not set +# CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set +# CONFIG_FEATURE_IPCALC_FANCY is not set +# CONFIG_FAKEIDENTD is not set +# CONFIG_NAMEIF is not set +# CONFIG_FEATURE_NAMEIF_EXTENDED is not set +# CONFIG_NBDCLIENT is not set +# CONFIG_NC is not set +# CONFIG_NETCAT is not set +# CONFIG_NC_SERVER is not set +# CONFIG_NC_EXTRA is not set +# CONFIG_NC_110_COMPAT is not set +# CONFIG_NETSTAT is not set +# CONFIG_FEATURE_NETSTAT_WIDE is not set +# CONFIG_FEATURE_NETSTAT_PRG is not set +# CONFIG_NSLOOKUP is not set +# CONFIG_FEATURE_NSLOOKUP_BIG is not set +# CONFIG_FEATURE_NSLOOKUP_LONG_OPTIONS is not set +# CONFIG_NTPD is not set +# CONFIG_FEATURE_NTPD_SERVER is not set +# CONFIG_FEATURE_NTPD_CONF is not set +# CONFIG_FEATURE_NTP_AUTH is not set +# CONFIG_PING is not set +# CONFIG_PING6 is not set +# CONFIG_FEATURE_FANCY_PING is not set +# CONFIG_PSCAN is not set +# CONFIG_ROUTE is not set +# CONFIG_SLATTACH is not set +# CONFIG_SSL_CLIENT is not set +# CONFIG_TC is not set +# CONFIG_FEATURE_TC_INGRESS is not set +# CONFIG_TCPSVD is not set +# CONFIG_UDPSVD is not set +# CONFIG_TELNET is not set +# CONFIG_FEATURE_TELNET_TTYPE is not set +# CONFIG_FEATURE_TELNET_AUTOLOGIN is not set +# CONFIG_FEATURE_TELNET_WIDTH is not set +# CONFIG_TELNETD is not set +# CONFIG_FEATURE_TELNETD_STANDALONE is not set +# CONFIG_FEATURE_TELNETD_INETD_WAIT is not set +# CONFIG_TFTP is not set +# CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set +# CONFIG_FEATURE_TFTP_HPA_COMPAT is not set +# CONFIG_TFTPD is not set +# CONFIG_FEATURE_TFTP_GET is not set +# CONFIG_FEATURE_TFTP_PUT is not set +# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set +# CONFIG_TFTP_DEBUG is not set +# CONFIG_TLS is not set +# CONFIG_TRACEROUTE is not set +# CONFIG_TRACEROUTE6 is not set +# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set +# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set +# CONFIG_TUNCTL is not set +# CONFIG_FEATURE_TUNCTL_UG is not set +# CONFIG_VCONFIG is not set +# CONFIG_WGET is not set +# CONFIG_FEATURE_WGET_LONG_OPTIONS is not set +# CONFIG_FEATURE_WGET_STATUSBAR is not set +# CONFIG_FEATURE_WGET_AUTHENTICATION is not set +# CONFIG_FEATURE_WGET_TIMEOUT is not set +# CONFIG_FEATURE_WGET_HTTPS is not set +# CONFIG_FEATURE_WGET_OPENSSL is not set +# CONFIG_WHOIS is not set +# CONFIG_ZCIP is not set +# CONFIG_UDHCPD is not set +# CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC is not set +# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set +CONFIG_DHCPD_LEASES_FILE="" +# CONFIG_DUMPLEASES is not set +# CONFIG_DHCPRELAY is not set +# CONFIG_UDHCPC is not set +# CONFIG_FEATURE_UDHCPC_ARPING is not set +# CONFIG_FEATURE_UDHCPC_SANITIZEOPT is not set +CONFIG_UDHCPC_DEFAULT_SCRIPT="" +# CONFIG_UDHCPC6 is not set +# CONFIG_FEATURE_UDHCPC6_RFC3646 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4704 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4833 is not set +# CONFIG_FEATURE_UDHCPC6_RFC5970 is not set +# CONFIG_FEATURE_UDHCP_PORT is not set +CONFIG_UDHCP_DEBUG=0 +CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=0 +# CONFIG_FEATURE_UDHCP_RFC3397 is not set +# CONFIG_FEATURE_UDHCP_8021Q is not set +CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="" + +# +# Print Utilities +# +# CONFIG_LPD is not set +# CONFIG_LPR is not set +# CONFIG_LPQ is not set + +# +# Mail Utilities +# +# CONFIG_MAKEMIME is not set +# CONFIG_POPMAILDIR is not set +# CONFIG_FEATURE_POPMAILDIR_DELIVERY is not set +# CONFIG_REFORMIME is not set +# CONFIG_FEATURE_REFORMIME_COMPAT is not set +# CONFIG_SENDMAIL is not set +CONFIG_FEATURE_MIME_CHARSET="" + +# +# Process Utilities +# +# CONFIG_FREE is not set +# CONFIG_FUSER is not set +# CONFIG_IOSTAT is not set +# CONFIG_KILL is not set +# CONFIG_KILLALL is not set +# CONFIG_KILLALL5 is not set +# CONFIG_LSOF is not set +# CONFIG_MPSTAT is not set +# CONFIG_NMETER is not set +# CONFIG_PGREP is not set +# CONFIG_PKILL is not set +# CONFIG_PIDOF is not set +# CONFIG_FEATURE_PIDOF_SINGLE is not set +# CONFIG_FEATURE_PIDOF_OMIT is not set +# CONFIG_PMAP is not set +# CONFIG_POWERTOP is not set +# CONFIG_FEATURE_POWERTOP_INTERACTIVE is not set +# CONFIG_PS is not set +# CONFIG_FEATURE_PS_WIDE is not set +# CONFIG_FEATURE_PS_LONG is not set +# CONFIG_FEATURE_PS_TIME is not set +# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set +# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set +# CONFIG_PSTREE is not set +# CONFIG_PWDX is not set +# CONFIG_SMEMCAP is not set +# CONFIG_BB_SYSCTL is not set +# CONFIG_TOP is not set +# CONFIG_FEATURE_TOP_INTERACTIVE is not set +# CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE is not set +# CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS is not set +# CONFIG_FEATURE_TOP_SMP_CPU is not set +# CONFIG_FEATURE_TOP_DECIMALS is not set +# CONFIG_FEATURE_TOP_SMP_PROCESS is not set +# CONFIG_FEATURE_TOPMEM is not set +# CONFIG_UPTIME is not set +# CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set +# CONFIG_WATCH is not set +# CONFIG_FEATURE_SHOW_THREADS is not set + +# +# Runit Utilities +# +# CONFIG_CHPST is not set +# CONFIG_SETUIDGID is not set +# CONFIG_ENVUIDGID is not set +# CONFIG_ENVDIR is not set +# CONFIG_SOFTLIMIT is not set +# CONFIG_RUNSV is not set +# CONFIG_RUNSVDIR is not set +# CONFIG_FEATURE_RUNSVDIR_LOG is not set +# CONFIG_SV is not set +CONFIG_SV_DEFAULT_SERVICE_DIR="" +# CONFIG_SVC is not set +# CONFIG_SVOK is not set +# CONFIG_SVLOGD is not set +# CONFIG_CHCON is not set +# CONFIG_GETENFORCE is not set +# CONFIG_GETSEBOOL is not set +# CONFIG_LOAD_POLICY is not set +# CONFIG_MATCHPATHCON is not set +# CONFIG_RUNCON is not set +# CONFIG_SELINUXENABLED is not set +# CONFIG_SESTATUS is not set +# CONFIG_SETENFORCE is not set +# CONFIG_SETFILES is not set +# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set +# CONFIG_RESTORECON is not set +# CONFIG_SETSEBOOL is not set + +# +# Shells +# +# CONFIG_SH_IS_ASH is not set +# CONFIG_SH_IS_HUSH is not set +CONFIG_SH_IS_NONE=y +# CONFIG_BASH_IS_ASH is not set +# CONFIG_BASH_IS_HUSH is not set +CONFIG_BASH_IS_NONE=y +# CONFIG_SHELL_ASH is not set +# CONFIG_ASH is not set +# CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set +# CONFIG_ASH_INTERNAL_GLOB is not set +# CONFIG_ASH_BASH_COMPAT is not set +# CONFIG_ASH_BASH_SOURCE_CURDIR is not set +# CONFIG_ASH_BASH_NOT_FOUND_HOOK is not set +# CONFIG_ASH_JOB_CONTROL is not set +# CONFIG_ASH_ALIAS is not set +# CONFIG_ASH_RANDOM_SUPPORT is not set +# CONFIG_ASH_EXPAND_PRMT is not set +# CONFIG_ASH_IDLE_TIMEOUT is not set +# CONFIG_ASH_MAIL is not set +# CONFIG_ASH_ECHO is not set +# CONFIG_ASH_PRINTF is not set +# CONFIG_ASH_TEST is not set +# CONFIG_ASH_HELP is not set +# CONFIG_ASH_GETOPTS is not set +# CONFIG_ASH_CMDCMD is not set +# CONFIG_CTTYHACK is not set +# CONFIG_HUSH is not set +# CONFIG_SHELL_HUSH is not set +# CONFIG_HUSH_BASH_COMPAT is not set +# CONFIG_HUSH_BRACE_EXPANSION is not set +# CONFIG_HUSH_LINENO_VAR is not set +# CONFIG_HUSH_BASH_SOURCE_CURDIR is not set +# CONFIG_HUSH_INTERACTIVE is not set +# CONFIG_HUSH_SAVEHISTORY is not set +# CONFIG_HUSH_JOB is not set +# CONFIG_HUSH_TICK is not set +# CONFIG_HUSH_IF is not set +# CONFIG_HUSH_LOOPS is not set +# CONFIG_HUSH_CASE is not set +# CONFIG_HUSH_FUNCTIONS is not set +# CONFIG_HUSH_LOCAL is not set +# CONFIG_HUSH_RANDOM_SUPPORT is not set +# CONFIG_HUSH_MODE_X is not set +# CONFIG_HUSH_ECHO is not set +# CONFIG_HUSH_PRINTF is not set +# CONFIG_HUSH_TEST is not set +# CONFIG_HUSH_HELP is not set +# CONFIG_HUSH_EXPORT is not set +# CONFIG_HUSH_EXPORT_N is not set +# CONFIG_HUSH_READONLY is not set +# CONFIG_HUSH_KILL is not set +# CONFIG_HUSH_WAIT is not set +# CONFIG_HUSH_COMMAND is not set +# CONFIG_HUSH_TRAP is not set +# CONFIG_HUSH_TYPE is not set +# CONFIG_HUSH_TIMES is not set +# CONFIG_HUSH_READ is not set +# CONFIG_HUSH_SET is not set +# CONFIG_HUSH_UNSET is not set +# CONFIG_HUSH_ULIMIT is not set +# CONFIG_HUSH_UMASK is not set +# CONFIG_HUSH_GETOPTS is not set +# CONFIG_HUSH_MEMLEAK is not set + +# +# Options common to all shells +# +# CONFIG_FEATURE_SH_MATH is not set +# CONFIG_FEATURE_SH_MATH_64 is not set +# CONFIG_FEATURE_SH_MATH_BASE is not set +# CONFIG_FEATURE_SH_EXTRA_QUIET is not set +# CONFIG_FEATURE_SH_STANDALONE is not set +# CONFIG_FEATURE_SH_NOFORK is not set +# CONFIG_FEATURE_SH_READ_FRAC is not set +# CONFIG_FEATURE_SH_HISTFILESIZE is not set +# CONFIG_FEATURE_SH_EMBEDDED_SCRIPTS is not set + +# +# System Logging Utilities +# +# CONFIG_KLOGD is not set +# CONFIG_FEATURE_KLOGD_KLOGCTL is not set +# CONFIG_LOGGER is not set +# CONFIG_LOGREAD is not set +# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set +# CONFIG_SYSLOGD is not set +# CONFIG_FEATURE_ROTATE_LOGFILE is not set +# CONFIG_FEATURE_REMOTE_LOG is not set +# CONFIG_FEATURE_SYSLOGD_DUP is not set +# CONFIG_FEATURE_SYSLOGD_CFG is not set +# CONFIG_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS is not set +CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0 +# CONFIG_FEATURE_IPC_SYSLOG is not set +CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 +# CONFIG_FEATURE_KMSG_SYSLOG is not set diff --git a/BUSYBOX/build.txt b/BUSYBOX/build.txt new file mode 100644 index 0000000..7a68be8 --- /dev/null +++ b/BUSYBOX/build.txt @@ -0,0 +1,55 @@ +======== How to build ash/hexdump/xzcat for aarch64 ======== +#How to get ash.config/hexdump.cofig/xzcat.config +#ARCH=arm64 CROSS_COMPILE=aarch64-linux- make allnoconfig +#ARCH=arm64 CROSS_COMPILE=aarch64-linux- make menuconfig +#----> enable static build +#----> enable xzcat +#get aarch64_xzcat.config + +tar xf busybox-1.32.0.tar.bz2 +cd busybox-1.32.0 +copy aarch64_xzcat.config as .config +ARCH=arm64 CROSS_COMPILE=aarch64-linux- make +rename ./busybox to xzcat + + +======== How to build ash/hexdump/xzcat for mips64el ======== +#download mips64el-musl cross toolchain from https://github.com/ventoy/musl-cross-make/releases/download/latest/ +#How to get ash.config/hexdump.cofig/xzcat.config +#ARCH=mips CROSS_COMPILE=mips64el-linux-musl- make allnoconfig "CFLAGS+=-mips64r2 -mabi=64 -Os" "LDFLAGS+=-mips64r2 -mabi=64 -Os" +#ARCH=mips CROSS_COMPILE=mips64el-linux-musl- make menuconfig "CFLAGS+=-mips64r2 -mabi=64 -Os" "LDFLAGS+=-mips64r2 -mabi=64 -Os" +#----> enable static build +#----> enable xzcat +#get mips64el_xzcat.config + +tar xf busybox-1.32.0.tar.bz2 +cd busybox-1.32.0 +copy mips64el_xzcat.config as .config +ARCH=mips CROSS_COMPILE=mips64el-linux-musl- make "CFLAGS+=-mips64r2 -mabi=64 -Os" "LDFLAGS+=-mips64r2 -mabi=64 -Os" +rename ./busybox to xzcat + + +======== How to build full busybox ========= +#make defconfig +#make menuconfig select static build + +======== How to build ash/hexdump/xzcat for x86_64 ========== +#How to get ash.config/hexdump.cofig/xzcat.config +#make allnoconfig +#make menuconfig +#----> enable static build +#----> enable xzcat +#get x86_64_xzcat.config + + +tar xf busybox-1.32.0.tar.bz2 +cd busybox-1.32.0 +copy x86_64_xzcat.config as .config +modify Makefile +CC = gcc -specs "/usr/local/musl/lib/musl-gcc.specs" +MODFLAGS = -DMODULE -specs "/usr/local/musl/lib/musl-gcc.specs" +make +rename ./busybox to xzcat + + + diff --git a/BUSYBOX/chmod/build.sh b/BUSYBOX/chmod/build.sh new file mode 100644 index 0000000..e72bc10 --- /dev/null +++ b/BUSYBOX/chmod/build.sh @@ -0,0 +1,33 @@ +#!/bin/sh + +DSTDIR1=../../IMG/cpio_x86/ventoy/busybox +DSTDIR2=../../IMG/cpio_arm64/ventoy/busybox +DSTDIR3=../../IMG/cpio_mips64/ventoy/busybox + +rm -f vtchmod32 vtchmod64 vtchmod64_musl vtchmodaa64 +rm -f $DSTDIR1/vtchmod32 $DSTDIR1/vtchmod64 $DSTDIR2/vtchmodaa64 $DSTDIR3/vtchmodm64e + +/opt/diet32/bin/diet gcc -Os -m32 vtchmod.c -o vtchmod32 +/opt/diet64/bin/diet gcc -Os vtchmod.c -o vtchmod64 +aarch64-linux-gcc -Os -static vtchmod.c -o vtchmodaa64 +aarch64-linux-strip --strip-all vtchmodaa64 + +mips64el-linux-musl-gcc -mips64r2 -mabi=64 -Os -static vtchmod.c -o vtchmodm64e +mips64el-linux-musl-strip --strip-all vtchmodm64e + + +gcc -specs "/usr/local/musl/lib/musl-gcc.specs" -Os -static vtchmod.c -o vtchmod64_musl +strip --strip-all vtchmod64_musl + +chmod 777 vtchmod32 +chmod 777 vtchmod64 +chmod 777 vtchmodaa64 +chmod 777 vtchmod64_musl +chmod 777 vtchmodm64e + +cp -a vtchmod32 $DSTDIR1/ +cp -a vtchmod64 $DSTDIR1/ +cp -a vtchmod64_musl $DSTDIR1/ +cp -a vtchmodaa64 $DSTDIR2/ +cp -a vtchmodm64e $DSTDIR3/ + diff --git a/BUSYBOX/chmod/vtchmod.c b/BUSYBOX/chmod/vtchmod.c new file mode 100644 index 0000000..ad10d0e --- /dev/null +++ b/BUSYBOX/chmod/vtchmod.c @@ -0,0 +1,34 @@ +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + if (argc != 2) + { + return 1; + } + + if (argv[1][0] == '-' && argv[1][1] == '6') + { + struct utsname buf; + if (0 == uname(&buf)) + { + if (strstr(buf.machine, "amd64")) + { + return 0; + } + + if (strstr(buf.machine, "x86_64")) + { + return 0; + } + } + return 1; + } + + return chmod(argv[1], 0777); +} + diff --git a/BUSYBOX/chmod/vtchmod32 b/BUSYBOX/chmod/vtchmod32 new file mode 100644 index 0000000..2647afb Binary files /dev/null and b/BUSYBOX/chmod/vtchmod32 differ diff --git a/BUSYBOX/chmod/vtchmod64 b/BUSYBOX/chmod/vtchmod64 new file mode 100644 index 0000000..4d27c57 Binary files /dev/null and b/BUSYBOX/chmod/vtchmod64 differ diff --git a/BUSYBOX/chmod/vtchmod64_musl b/BUSYBOX/chmod/vtchmod64_musl new file mode 100644 index 0000000..01c80f2 Binary files /dev/null and b/BUSYBOX/chmod/vtchmod64_musl differ diff --git a/BUSYBOX/chmod/vtchmodaa64 b/BUSYBOX/chmod/vtchmodaa64 new file mode 100644 index 0000000..6c3811a Binary files /dev/null and b/BUSYBOX/chmod/vtchmodaa64 differ diff --git a/BUSYBOX/chmod/vtchmodm64e b/BUSYBOX/chmod/vtchmodm64e new file mode 100644 index 0000000..dc623d5 Binary files /dev/null and b/BUSYBOX/chmod/vtchmodm64e differ diff --git a/BUSYBOX/config b/BUSYBOX/config new file mode 100644 index 0000000..d650073 --- /dev/null +++ b/BUSYBOX/config @@ -0,0 +1,1181 @@ +# +# Automatically generated make config: don't edit +# Busybox version: 1.30.0 +# Sun Dec 30 19:34:09 2018 +# +CONFIG_HAVE_DOT_CONFIG=y + +# +# Settings +# +CONFIG_DESKTOP=y +CONFIG_EXTRA_COMPAT=y +# CONFIG_FEDORA_COMPAT is not set +CONFIG_INCLUDE_SUSv2=y +CONFIG_LONG_OPTS=y +CONFIG_SHOW_USAGE=y +CONFIG_FEATURE_VERBOSE_USAGE=y +CONFIG_FEATURE_COMPRESS_USAGE=y +CONFIG_LFS=y +# CONFIG_PAM is not set +CONFIG_FEATURE_DEVPTS=y +CONFIG_FEATURE_UTMP=y +CONFIG_FEATURE_WTMP=y +CONFIG_FEATURE_PIDFILE=y +CONFIG_PID_FILE_PATH="/var/run" +CONFIG_BUSYBOX=y +CONFIG_FEATURE_SHOW_SCRIPT=y +CONFIG_FEATURE_INSTALLER=y +# CONFIG_INSTALL_NO_USR is not set +CONFIG_FEATURE_SUID=y +CONFIG_FEATURE_SUID_CONFIG=y +CONFIG_FEATURE_SUID_CONFIG_QUIET=y +# CONFIG_FEATURE_PREFER_APPLETS is not set +CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" +# CONFIG_SELINUX is not set +# CONFIG_FEATURE_CLEAN_UP is not set +CONFIG_FEATURE_SYSLOG=y +CONFIG_PLATFORM_LINUX=y + +# +# Build Options +# +CONFIG_STATIC=y +# CONFIG_PIE is not set +# CONFIG_NOMMU is not set +# CONFIG_BUILD_LIBBUSYBOX is not set +# CONFIG_FEATURE_LIBBUSYBOX_STATIC is not set +# CONFIG_FEATURE_INDIVIDUAL is not set +# CONFIG_FEATURE_SHARED_BUSYBOX is not set +CONFIG_CROSS_COMPILER_PREFIX="i486-linux-uclibc-" +CONFIG_SYSROOT="" +CONFIG_EXTRA_CFLAGS="" +CONFIG_EXTRA_LDFLAGS="" +CONFIG_EXTRA_LDLIBS="" +# CONFIG_USE_PORTABLE_CODE is not set +CONFIG_STACK_OPTIMIZATION_386=y + +# +# Installation Options ("make install" behavior) +# +CONFIG_INSTALL_APPLET_SYMLINKS=y +# CONFIG_INSTALL_APPLET_HARDLINKS is not set +# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set +# CONFIG_INSTALL_APPLET_DONT is not set +# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set +# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set +# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set +CONFIG_PREFIX="./_install" + +# +# Debugging Options +# +# CONFIG_DEBUG is not set +# CONFIG_DEBUG_PESSIMIZE is not set +# CONFIG_DEBUG_SANITIZE is not set +# CONFIG_UNIT_TEST is not set +CONFIG_WERROR=y +CONFIG_NO_DEBUG_LIB=y +# CONFIG_DMALLOC is not set +# CONFIG_EFENCE is not set + +# +# Library Tuning +# +CONFIG_FEATURE_USE_BSS_TAIL=y +CONFIG_FLOAT_DURATION=y +CONFIG_FEATURE_RTMINMAX=y +CONFIG_FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS=y +CONFIG_FEATURE_BUFFERS_USE_MALLOC=y +# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set +# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set +CONFIG_PASSWORD_MINLEN=6 +CONFIG_MD5_SMALL=1 +CONFIG_SHA3_SMALL=1 +CONFIG_FEATURE_FAST_TOP=y +# CONFIG_FEATURE_ETC_NETWORKS is not set +# CONFIG_FEATURE_ETC_SERVICES is not set +CONFIG_FEATURE_EDITING=y +CONFIG_FEATURE_EDITING_MAX_LEN=1024 +CONFIG_FEATURE_EDITING_VI=y +CONFIG_FEATURE_EDITING_HISTORY=15 +CONFIG_FEATURE_EDITING_SAVEHISTORY=y +# CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set +CONFIG_FEATURE_REVERSE_SEARCH=y +CONFIG_FEATURE_TAB_COMPLETION=y +CONFIG_FEATURE_USERNAME_COMPLETION=y +CONFIG_FEATURE_EDITING_FANCY_PROMPT=y +CONFIG_FEATURE_EDITING_WINCH=y +CONFIG_FEATURE_EDITING_ASK_TERMINAL=y +# CONFIG_LOCALE_SUPPORT is not set +CONFIG_UNICODE_SUPPORT=y +# CONFIG_UNICODE_USING_LOCALE is not set +CONFIG_FEATURE_CHECK_UNICODE_IN_ENV=y +CONFIG_SUBST_WCHAR=63 +CONFIG_LAST_SUPPORTED_WCHAR=4351 +CONFIG_UNICODE_COMBINING_WCHARS=y +# CONFIG_UNICODE_WIDE_WCHARS is not set +CONFIG_UNICODE_BIDI_SUPPORT=y +# CONFIG_UNICODE_NEUTRAL_TABLE is not set +CONFIG_UNICODE_PRESERVE_BROKEN=y +CONFIG_FEATURE_NON_POSIX_CP=y +# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set +CONFIG_FEATURE_USE_SENDFILE=y +CONFIG_FEATURE_COPYBUF_KB=64 +CONFIG_FEATURE_SKIP_ROOTFS=y +CONFIG_MONOTONIC_SYSCALL=y +# CONFIG_IOCTL_HEX2STR_ERROR is not set +CONFIG_FEATURE_HWIB=y + +# +# Applets +# + +# +# Archival Utilities +# +CONFIG_FEATURE_SEAMLESS_XZ=y +CONFIG_FEATURE_SEAMLESS_LZMA=y +CONFIG_FEATURE_SEAMLESS_BZ2=y +CONFIG_FEATURE_SEAMLESS_GZ=y +CONFIG_FEATURE_SEAMLESS_Z=y +CONFIG_AR=y +CONFIG_FEATURE_AR_LONG_FILENAMES=y +CONFIG_FEATURE_AR_CREATE=y +CONFIG_UNCOMPRESS=y +CONFIG_GUNZIP=y +CONFIG_ZCAT=y +CONFIG_FEATURE_GUNZIP_LONG_OPTIONS=y +CONFIG_BUNZIP2=y +CONFIG_BZCAT=y +CONFIG_UNLZMA=y +CONFIG_LZCAT=y +CONFIG_LZMA=y +CONFIG_UNXZ=y +CONFIG_XZCAT=y +CONFIG_XZ=y +CONFIG_BZIP2=y +CONFIG_BZIP2_SMALL=8 +CONFIG_FEATURE_BZIP2_DECOMPRESS=y +CONFIG_CPIO=y +CONFIG_FEATURE_CPIO_O=y +CONFIG_FEATURE_CPIO_P=y +CONFIG_DPKG=y +CONFIG_DPKG_DEB=y +CONFIG_GZIP=y +CONFIG_FEATURE_GZIP_LONG_OPTIONS=y +CONFIG_GZIP_FAST=2 +# CONFIG_FEATURE_GZIP_LEVELS is not set +CONFIG_FEATURE_GZIP_DECOMPRESS=y +CONFIG_LZOP=y +CONFIG_UNLZOP=y +CONFIG_LZOPCAT=y +# CONFIG_LZOP_COMPR_HIGH is not set +CONFIG_RPM=y +CONFIG_RPM2CPIO=y +CONFIG_TAR=y +CONFIG_FEATURE_TAR_LONG_OPTIONS=y +CONFIG_FEATURE_TAR_CREATE=y +CONFIG_FEATURE_TAR_AUTODETECT=y +CONFIG_FEATURE_TAR_FROM=y +CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY=y +CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY=y +CONFIG_FEATURE_TAR_GNU_EXTENSIONS=y +CONFIG_FEATURE_TAR_TO_COMMAND=y +CONFIG_FEATURE_TAR_UNAME_GNAME=y +CONFIG_FEATURE_TAR_NOPRESERVE_TIME=y +# CONFIG_FEATURE_TAR_SELINUX is not set +CONFIG_UNZIP=y +CONFIG_FEATURE_UNZIP_CDF=y +CONFIG_FEATURE_UNZIP_BZIP2=y +CONFIG_FEATURE_UNZIP_LZMA=y +CONFIG_FEATURE_UNZIP_XZ=y +CONFIG_FEATURE_LZMA_FAST=y + +# +# Coreutils +# +CONFIG_BASENAME=y +CONFIG_CAT=y +CONFIG_FEATURE_CATN=y +CONFIG_FEATURE_CATV=y +CONFIG_CHGRP=y +CONFIG_CHMOD=y +CONFIG_CHOWN=y +CONFIG_FEATURE_CHOWN_LONG_OPTIONS=y +CONFIG_CHROOT=y +CONFIG_CKSUM=y +CONFIG_COMM=y +CONFIG_CP=y +CONFIG_FEATURE_CP_LONG_OPTIONS=y +CONFIG_FEATURE_CP_REFLINK=y +CONFIG_CUT=y +CONFIG_DATE=y +CONFIG_FEATURE_DATE_ISOFMT=y +CONFIG_FEATURE_DATE_NANO=y +# CONFIG_FEATURE_DATE_COMPAT is not set +CONFIG_DD=y +CONFIG_FEATURE_DD_SIGNAL_HANDLING=y +CONFIG_FEATURE_DD_THIRD_STATUS_LINE=y +CONFIG_FEATURE_DD_IBS_OBS=y +CONFIG_FEATURE_DD_STATUS=y +CONFIG_DF=y +CONFIG_FEATURE_DF_FANCY=y +CONFIG_DIRNAME=y +CONFIG_DOS2UNIX=y +CONFIG_UNIX2DOS=y +CONFIG_DU=y +CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K=y +CONFIG_ECHO=y +CONFIG_FEATURE_FANCY_ECHO=y +CONFIG_ENV=y +CONFIG_EXPAND=y +CONFIG_UNEXPAND=y +CONFIG_EXPR=y +CONFIG_EXPR_MATH_SUPPORT_64=y +CONFIG_FACTOR=y +CONFIG_FALSE=y +CONFIG_FOLD=y +CONFIG_FSYNC=y +CONFIG_HEAD=y +CONFIG_FEATURE_FANCY_HEAD=y +CONFIG_HOSTID=y +CONFIG_ID=y +CONFIG_GROUPS=y +CONFIG_INSTALL=y +CONFIG_FEATURE_INSTALL_LONG_OPTIONS=y +CONFIG_LINK=y +CONFIG_LN=y +CONFIG_LOGNAME=y +CONFIG_LS=y +CONFIG_FEATURE_LS_FILETYPES=y +CONFIG_FEATURE_LS_FOLLOWLINKS=y +CONFIG_FEATURE_LS_RECURSIVE=y +CONFIG_FEATURE_LS_WIDTH=y +CONFIG_FEATURE_LS_SORTFILES=y +CONFIG_FEATURE_LS_TIMESTAMPS=y +CONFIG_FEATURE_LS_USERNAME=y +CONFIG_FEATURE_LS_COLOR=y +CONFIG_FEATURE_LS_COLOR_IS_DEFAULT=y +CONFIG_MD5SUM=y +CONFIG_SHA1SUM=y +CONFIG_SHA256SUM=y +CONFIG_SHA512SUM=y +CONFIG_SHA3SUM=y + +# +# Common options for md5sum, sha1sum, sha256sum, sha512sum, sha3sum +# +CONFIG_FEATURE_MD5_SHA1_SUM_CHECK=y +CONFIG_MKDIR=y +CONFIG_MKFIFO=y +CONFIG_MKNOD=y +CONFIG_MKTEMP=y +CONFIG_MV=y +CONFIG_NICE=y +CONFIG_NL=y +CONFIG_NOHUP=y +CONFIG_NPROC=y +CONFIG_OD=y +CONFIG_PASTE=y +CONFIG_PRINTENV=y +CONFIG_PRINTF=y +CONFIG_PWD=y +CONFIG_READLINK=y +CONFIG_FEATURE_READLINK_FOLLOW=y +CONFIG_REALPATH=y +CONFIG_RM=y +CONFIG_RMDIR=y +CONFIG_SEQ=y +CONFIG_SHRED=y +CONFIG_SHUF=y +CONFIG_SLEEP=y +CONFIG_FEATURE_FANCY_SLEEP=y +CONFIG_SORT=y +CONFIG_FEATURE_SORT_BIG=y +# CONFIG_FEATURE_SORT_OPTIMIZE_MEMORY is not set +CONFIG_SPLIT=y +CONFIG_FEATURE_SPLIT_FANCY=y +CONFIG_STAT=y +CONFIG_FEATURE_STAT_FORMAT=y +CONFIG_FEATURE_STAT_FILESYSTEM=y +CONFIG_STTY=y +CONFIG_SUM=y +CONFIG_SYNC=y +# CONFIG_FEATURE_SYNC_FANCY is not set +CONFIG_TAC=y +CONFIG_TAIL=y +CONFIG_FEATURE_FANCY_TAIL=y +CONFIG_TEE=y +CONFIG_FEATURE_TEE_USE_BLOCK_IO=y +CONFIG_TEST=y +CONFIG_TEST1=y +CONFIG_TEST2=y +CONFIG_FEATURE_TEST_64=y +CONFIG_TIMEOUT=y +CONFIG_TOUCH=y +CONFIG_FEATURE_TOUCH_NODEREF=y +CONFIG_FEATURE_TOUCH_SUSV3=y +CONFIG_TR=y +CONFIG_FEATURE_TR_CLASSES=y +CONFIG_FEATURE_TR_EQUIV=y +CONFIG_TRUE=y +CONFIG_TRUNCATE=y +CONFIG_TTY=y +CONFIG_UNAME=y +CONFIG_UNAME_OSNAME="GNU/Linux" +CONFIG_BB_ARCH=y +CONFIG_UNIQ=y +CONFIG_UNLINK=y +CONFIG_USLEEP=y +CONFIG_UUDECODE=y +CONFIG_BASE64=y +CONFIG_UUENCODE=y +CONFIG_WC=y +CONFIG_FEATURE_WC_LARGE=y +CONFIG_WHOAMI=y +CONFIG_WHO=y +CONFIG_W=y +CONFIG_USERS=y +CONFIG_YES=y + +# +# Common options +# +CONFIG_FEATURE_VERBOSE=y + +# +# Common options for cp and mv +# +CONFIG_FEATURE_PRESERVE_HARDLINKS=y + +# +# Common options for df, du, ls +# +CONFIG_FEATURE_HUMAN_READABLE=y + +# +# Console Utilities +# +CONFIG_CHVT=y +CONFIG_CLEAR=y +CONFIG_DEALLOCVT=y +CONFIG_DUMPKMAP=y +CONFIG_FGCONSOLE=y +CONFIG_KBD_MODE=y +CONFIG_LOADFONT=y +CONFIG_SETFONT=y +CONFIG_FEATURE_SETFONT_TEXTUAL_MAP=y +CONFIG_DEFAULT_SETFONT_DIR="" + +# +# Common options for loadfont and setfont +# +CONFIG_FEATURE_LOADFONT_PSF2=y +CONFIG_FEATURE_LOADFONT_RAW=y +CONFIG_LOADKMAP=y +CONFIG_OPENVT=y +CONFIG_RESET=y +CONFIG_RESIZE=y +CONFIG_FEATURE_RESIZE_PRINT=y +CONFIG_SETCONSOLE=y +CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS=y +CONFIG_SETKEYCODES=y +CONFIG_SETLOGCONS=y +CONFIG_SHOWKEY=y + +# +# Debian Utilities +# +CONFIG_PIPE_PROGRESS=y +CONFIG_RUN_PARTS=y +CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS=y +CONFIG_FEATURE_RUN_PARTS_FANCY=y +CONFIG_START_STOP_DAEMON=y +CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS=y +CONFIG_FEATURE_START_STOP_DAEMON_FANCY=y +CONFIG_WHICH=y + +# +# klibc-utils +# +# CONFIG_MINIPS is not set +CONFIG_NUKE=y +CONFIG_RESUME=y +CONFIG_RUN_INIT=y + +# +# Editors +# +CONFIG_AWK=y +# CONFIG_FEATURE_AWK_LIBM is not set +CONFIG_FEATURE_AWK_GNU_EXTENSIONS=y +CONFIG_CMP=y +CONFIG_DIFF=y +CONFIG_FEATURE_DIFF_LONG_OPTIONS=y +CONFIG_FEATURE_DIFF_DIR=y +CONFIG_ED=y +CONFIG_PATCH=y +CONFIG_SED=y +CONFIG_VI=y +CONFIG_FEATURE_VI_MAX_LEN=1024 +# CONFIG_FEATURE_VI_8BIT is not set +CONFIG_FEATURE_VI_COLON=y +CONFIG_FEATURE_VI_YANKMARK=y +CONFIG_FEATURE_VI_SEARCH=y +CONFIG_FEATURE_VI_REGEX_SEARCH=y +CONFIG_FEATURE_VI_USE_SIGNALS=y +CONFIG_FEATURE_VI_DOT_CMD=y +CONFIG_FEATURE_VI_READONLY=y +CONFIG_FEATURE_VI_SETOPTS=y +CONFIG_FEATURE_VI_SET=y +CONFIG_FEATURE_VI_WIN_RESIZE=y +# CONFIG_FEATURE_VI_ASK_TERMINAL is not set +CONFIG_FEATURE_VI_UNDO=y +CONFIG_FEATURE_VI_UNDO_QUEUE=y +CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=256 +CONFIG_FEATURE_ALLOW_EXEC=y + +# +# Finding Utilities +# +CONFIG_FIND=y +CONFIG_FEATURE_FIND_PRINT0=y +CONFIG_FEATURE_FIND_MTIME=y +CONFIG_FEATURE_FIND_MMIN=y +CONFIG_FEATURE_FIND_PERM=y +CONFIG_FEATURE_FIND_TYPE=y +CONFIG_FEATURE_FIND_EXECUTABLE=y +CONFIG_FEATURE_FIND_XDEV=y +CONFIG_FEATURE_FIND_MAXDEPTH=y +CONFIG_FEATURE_FIND_NEWER=y +CONFIG_FEATURE_FIND_INUM=y +CONFIG_FEATURE_FIND_EXEC=y +CONFIG_FEATURE_FIND_EXEC_PLUS=y +CONFIG_FEATURE_FIND_USER=y +CONFIG_FEATURE_FIND_GROUP=y +CONFIG_FEATURE_FIND_NOT=y +CONFIG_FEATURE_FIND_DEPTH=y +CONFIG_FEATURE_FIND_PAREN=y +CONFIG_FEATURE_FIND_SIZE=y +CONFIG_FEATURE_FIND_PRUNE=y +CONFIG_FEATURE_FIND_QUIT=y +CONFIG_FEATURE_FIND_DELETE=y +CONFIG_FEATURE_FIND_PATH=y +CONFIG_FEATURE_FIND_REGEX=y +# CONFIG_FEATURE_FIND_CONTEXT is not set +CONFIG_FEATURE_FIND_LINKS=y +CONFIG_GREP=y +CONFIG_EGREP=y +CONFIG_FGREP=y +CONFIG_FEATURE_GREP_CONTEXT=y +CONFIG_XARGS=y +CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION=y +CONFIG_FEATURE_XARGS_SUPPORT_QUOTES=y +CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT=y +CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM=y +CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR=y +CONFIG_FEATURE_XARGS_SUPPORT_PARALLEL=y +CONFIG_FEATURE_XARGS_SUPPORT_ARGS_FILE=y + +# +# Init Utilities +# +CONFIG_BOOTCHARTD=y +CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER=y +CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE=y +CONFIG_HALT=y +CONFIG_POWEROFF=y +CONFIG_REBOOT=y +CONFIG_FEATURE_WAIT_FOR_INIT=y +# CONFIG_FEATURE_CALL_TELINIT is not set +CONFIG_TELINIT_PATH="" +CONFIG_INIT=y +CONFIG_LINUXRC=y +CONFIG_FEATURE_USE_INITTAB=y +CONFIG_FEATURE_KILL_REMOVED=y +CONFIG_FEATURE_KILL_DELAY=0 +# CONFIG_FEATURE_INIT_SCTTY is not set +CONFIG_FEATURE_INIT_SYSLOG=y +CONFIG_FEATURE_INIT_QUIET=y +# CONFIG_FEATURE_INIT_COREDUMPS is not set +CONFIG_INIT_TERMINAL_TYPE="linux" +CONFIG_FEATURE_INIT_MODIFY_CMDLINE=y + +# +# Login/Password Management Utilities +# +CONFIG_FEATURE_SHADOWPASSWDS=y +CONFIG_USE_BB_PWD_GRP=y +CONFIG_USE_BB_SHADOW=y +CONFIG_USE_BB_CRYPT=y +CONFIG_USE_BB_CRYPT_SHA=y +CONFIG_ADDGROUP=y +CONFIG_FEATURE_ADDUSER_TO_GROUP=y +CONFIG_ADD_SHELL=y +CONFIG_REMOVE_SHELL=y +CONFIG_ADDUSER=y +CONFIG_FEATURE_CHECK_NAMES=y +CONFIG_LAST_ID=60000 +CONFIG_FIRST_SYSTEM_ID=100 +CONFIG_LAST_SYSTEM_ID=999 +CONFIG_CHPASSWD=y +CONFIG_FEATURE_DEFAULT_PASSWD_ALGO="des" +CONFIG_CRYPTPW=y +CONFIG_MKPASSWD=y +CONFIG_DELUSER=y +CONFIG_DELGROUP=y +CONFIG_FEATURE_DEL_USER_FROM_GROUP=y +CONFIG_GETTY=y +CONFIG_LOGIN=y +# CONFIG_LOGIN_SESSION_AS_CHILD is not set +CONFIG_LOGIN_SCRIPTS=y +# CONFIG_FEATURE_NOLOGIN is not set +CONFIG_FEATURE_SECURETTY=y +CONFIG_PASSWD=y +CONFIG_FEATURE_PASSWD_WEAK_CHECK=y +CONFIG_SU=y +CONFIG_FEATURE_SU_SYSLOG=y +CONFIG_FEATURE_SU_CHECKS_SHELLS=y +# CONFIG_FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY is not set +CONFIG_SULOGIN=y +CONFIG_VLOCK=y + +# +# Linux Ext2 FS Progs +# +CONFIG_CHATTR=y +CONFIG_FSCK=y +CONFIG_LSATTR=y +CONFIG_TUNE2FS=y + +# +# Linux Module Utilities +# +# CONFIG_MODPROBE_SMALL is not set +CONFIG_DEPMOD=y +CONFIG_INSMOD=y +CONFIG_LSMOD=y +CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT=y +CONFIG_MODINFO=y +CONFIG_MODPROBE=y +CONFIG_FEATURE_MODPROBE_BLACKLIST=y +CONFIG_RMMOD=y + +# +# Options common to multiple modutils +# +CONFIG_FEATURE_CMDLINE_MODULE_OPTIONS=y +# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set +# CONFIG_FEATURE_2_4_MODULES is not set +# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set +# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set +# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set +CONFIG_FEATURE_CHECK_TAINTED_MODULE=y +# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set +CONFIG_FEATURE_MODUTILS_ALIAS=y +CONFIG_FEATURE_MODUTILS_SYMBOLS=y +CONFIG_DEFAULT_MODULES_DIR="/lib/modules" +CONFIG_DEFAULT_DEPMOD_FILE="modules.dep" + +# +# Linux System Utilities +# +CONFIG_ACPID=y +CONFIG_FEATURE_ACPID_COMPAT=y +CONFIG_BLKDISCARD=y +CONFIG_BLKID=y +CONFIG_FEATURE_BLKID_TYPE=y +CONFIG_BLOCKDEV=y +CONFIG_CAL=y +CONFIG_CHRT=y +CONFIG_DMESG=y +CONFIG_FEATURE_DMESG_PRETTY=y +CONFIG_EJECT=y +CONFIG_FEATURE_EJECT_SCSI=y +# CONFIG_FALLOCATE is not set +CONFIG_FATATTR=y +CONFIG_FBSET=y +CONFIG_FEATURE_FBSET_FANCY=y +CONFIG_FEATURE_FBSET_READMODE=y +CONFIG_FDFORMAT=y +CONFIG_FDISK=y +# CONFIG_FDISK_SUPPORT_LARGE_DISKS is not set +CONFIG_FEATURE_FDISK_WRITABLE=y +# CONFIG_FEATURE_AIX_LABEL is not set +# CONFIG_FEATURE_SGI_LABEL is not set +# CONFIG_FEATURE_SUN_LABEL is not set +# CONFIG_FEATURE_OSF_LABEL is not set +# CONFIG_FEATURE_GPT_LABEL is not set +CONFIG_FEATURE_FDISK_ADVANCED=y +CONFIG_FINDFS=y +CONFIG_FLOCK=y +CONFIG_FDFLUSH=y +CONFIG_FREERAMDISK=y +CONFIG_FSCK_MINIX=y +CONFIG_FSFREEZE=y +CONFIG_FSTRIM=y +CONFIG_GETOPT=y +CONFIG_FEATURE_GETOPT_LONG=y +CONFIG_HEXDUMP=y +CONFIG_FEATURE_HEXDUMP_REVERSE=y +CONFIG_HD=y +CONFIG_XXD=y +CONFIG_HWCLOCK=y +CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS=y +CONFIG_IONICE=y +CONFIG_IPCRM=y +CONFIG_IPCS=y +CONFIG_LAST=y +CONFIG_FEATURE_LAST_FANCY=y +CONFIG_LOSETUP=y +CONFIG_LSPCI=y +CONFIG_LSUSB=y +CONFIG_MDEV=y +CONFIG_FEATURE_MDEV_CONF=y +CONFIG_FEATURE_MDEV_RENAME=y +CONFIG_FEATURE_MDEV_RENAME_REGEXP=y +CONFIG_FEATURE_MDEV_EXEC=y +CONFIG_FEATURE_MDEV_LOAD_FIRMWARE=y +CONFIG_MESG=y +CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP=y +CONFIG_MKE2FS=y +CONFIG_MKFS_EXT2=y +CONFIG_MKFS_MINIX=y +CONFIG_FEATURE_MINIX2=y +# CONFIG_MKFS_REISER is not set +CONFIG_MKDOSFS=y +CONFIG_MKFS_VFAT=y +CONFIG_MKSWAP=y +CONFIG_FEATURE_MKSWAP_UUID=y +CONFIG_MORE=y +CONFIG_MOUNT=y +CONFIG_FEATURE_MOUNT_FAKE=y +CONFIG_FEATURE_MOUNT_VERBOSE=y +CONFIG_FEATURE_MOUNT_HELPERS=y +CONFIG_FEATURE_MOUNT_LABEL=y +CONFIG_FEATURE_MOUNT_NFS=y +CONFIG_FEATURE_MOUNT_CIFS=y +CONFIG_FEATURE_MOUNT_FLAGS=y +CONFIG_FEATURE_MOUNT_FSTAB=y +CONFIG_FEATURE_MOUNT_OTHERTAB=y +CONFIG_MOUNTPOINT=y +CONFIG_NOLOGIN=y +# CONFIG_NOLOGIN_DEPENDENCIES is not set +# CONFIG_NSENTER is not set +CONFIG_PIVOT_ROOT=y +CONFIG_RDATE=y +CONFIG_RDEV=y +CONFIG_READPROFILE=y +CONFIG_RENICE=y +CONFIG_REV=y +CONFIG_RTCWAKE=y +CONFIG_SCRIPT=y +CONFIG_SCRIPTREPLAY=y +CONFIG_SETARCH=y +CONFIG_LINUX32=y +CONFIG_LINUX64=y +CONFIG_SETPRIV=y +CONFIG_FEATURE_SETPRIV_DUMP=y +CONFIG_FEATURE_SETPRIV_CAPABILITIES=y +CONFIG_FEATURE_SETPRIV_CAPABILITY_NAMES=y +CONFIG_SETSID=y +CONFIG_SWAPON=y +CONFIG_FEATURE_SWAPON_DISCARD=y +CONFIG_FEATURE_SWAPON_PRI=y +CONFIG_SWAPOFF=y +CONFIG_FEATURE_SWAPONOFF_LABEL=y +CONFIG_SWITCH_ROOT=y +CONFIG_TASKSET=y +CONFIG_FEATURE_TASKSET_FANCY=y +CONFIG_UEVENT=y +CONFIG_UMOUNT=y +CONFIG_FEATURE_UMOUNT_ALL=y +# CONFIG_UNSHARE is not set +CONFIG_WALL=y + +# +# Common options for mount/umount +# +CONFIG_FEATURE_MOUNT_LOOP=y +# CONFIG_FEATURE_MOUNT_LOOP_CREATE is not set +# CONFIG_FEATURE_MTAB_SUPPORT is not set +CONFIG_VOLUMEID=y + +# +# Filesystem/Volume identification +# +CONFIG_FEATURE_VOLUMEID_BCACHE=y +CONFIG_FEATURE_VOLUMEID_BTRFS=y +CONFIG_FEATURE_VOLUMEID_CRAMFS=y +CONFIG_FEATURE_VOLUMEID_EXFAT=y +CONFIG_FEATURE_VOLUMEID_EXT=y +CONFIG_FEATURE_VOLUMEID_F2FS=y +CONFIG_FEATURE_VOLUMEID_FAT=y +CONFIG_FEATURE_VOLUMEID_HFS=y +CONFIG_FEATURE_VOLUMEID_ISO9660=y +CONFIG_FEATURE_VOLUMEID_JFS=y +CONFIG_FEATURE_VOLUMEID_LFS=y +CONFIG_FEATURE_VOLUMEID_LINUXRAID=y +CONFIG_FEATURE_VOLUMEID_LINUXSWAP=y +CONFIG_FEATURE_VOLUMEID_LUKS=y +CONFIG_FEATURE_VOLUMEID_MINIX=y +CONFIG_FEATURE_VOLUMEID_NILFS=y +CONFIG_FEATURE_VOLUMEID_NTFS=y +CONFIG_FEATURE_VOLUMEID_OCFS2=y +CONFIG_FEATURE_VOLUMEID_REISERFS=y +CONFIG_FEATURE_VOLUMEID_ROMFS=y +CONFIG_FEATURE_VOLUMEID_SQUASHFS=y +CONFIG_FEATURE_VOLUMEID_SYSV=y +CONFIG_FEATURE_VOLUMEID_UBIFS=y +CONFIG_FEATURE_VOLUMEID_UDF=y +CONFIG_FEATURE_VOLUMEID_XFS=y + +# +# Miscellaneous Utilities +# +CONFIG_ADJTIMEX=y +# CONFIG_BBCONFIG is not set +# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set +CONFIG_BC=y +CONFIG_DC=y +CONFIG_FEATURE_DC_BIG=y +# CONFIG_FEATURE_DC_LIBM is not set +CONFIG_FEATURE_BC_INTERACTIVE=y +CONFIG_FEATURE_BC_LONG_OPTIONS=y +# CONFIG_BEEP is not set +CONFIG_FEATURE_BEEP_FREQ=0 +CONFIG_FEATURE_BEEP_LENGTH_MS=0 +CONFIG_CHAT=y +CONFIG_FEATURE_CHAT_NOFAIL=y +CONFIG_FEATURE_CHAT_TTY_HIFI=y +CONFIG_FEATURE_CHAT_IMPLICIT_CR=y +CONFIG_FEATURE_CHAT_SWALLOW_OPTS=y +CONFIG_FEATURE_CHAT_SEND_ESCAPES=y +CONFIG_FEATURE_CHAT_VAR_ABORT_LEN=y +CONFIG_FEATURE_CHAT_CLR_ABORT=y +CONFIG_CONSPY=y +CONFIG_CROND=y +CONFIG_FEATURE_CROND_D=y +CONFIG_FEATURE_CROND_CALL_SENDMAIL=y +CONFIG_FEATURE_CROND_SPECIAL_TIMES=y +CONFIG_FEATURE_CROND_DIR="/var/spool/cron" +CONFIG_CRONTAB=y +# CONFIG_DEVFSD is not set +# CONFIG_DEVFSD_MODLOAD is not set +# CONFIG_DEVFSD_FG_NP is not set +# CONFIG_DEVFSD_VERBOSE is not set +# CONFIG_FEATURE_DEVFS is not set +CONFIG_DEVMEM=y +CONFIG_FBSPLASH=y +CONFIG_FLASHCP=y +CONFIG_FLASH_ERASEALL=y +CONFIG_FLASH_LOCK=y +CONFIG_FLASH_UNLOCK=y +CONFIG_HDPARM=y +CONFIG_FEATURE_HDPARM_GET_IDENTITY=y +CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF=y +CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF=y +CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET=y +CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF=y +CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA=y +CONFIG_HEXEDIT=y +CONFIG_I2CGET=y +CONFIG_I2CSET=y +CONFIG_I2CDUMP=y +CONFIG_I2CDETECT=y +CONFIG_INOTIFYD=y +CONFIG_LESS=y +CONFIG_FEATURE_LESS_MAXLINES=9999999 +CONFIG_FEATURE_LESS_BRACKETS=y +CONFIG_FEATURE_LESS_FLAGS=y +CONFIG_FEATURE_LESS_TRUNCATE=y +CONFIG_FEATURE_LESS_MARKS=y +CONFIG_FEATURE_LESS_REGEXP=y +CONFIG_FEATURE_LESS_WINCH=y +CONFIG_FEATURE_LESS_ASK_TERMINAL=y +CONFIG_FEATURE_LESS_DASHCMD=y +CONFIG_FEATURE_LESS_LINENUMS=y +CONFIG_FEATURE_LESS_RAW=y +CONFIG_FEATURE_LESS_ENV=y +CONFIG_LSSCSI=y +CONFIG_MAKEDEVS=y +# CONFIG_FEATURE_MAKEDEVS_LEAF is not set +CONFIG_FEATURE_MAKEDEVS_TABLE=y +CONFIG_MAN=y +CONFIG_MICROCOM=y +CONFIG_MT=y +# CONFIG_NANDWRITE is not set +# CONFIG_NANDDUMP is not set +CONFIG_PARTPROBE=y +CONFIG_RAIDAUTORUN=y +# CONFIG_READAHEAD is not set +# CONFIG_RFKILL is not set +CONFIG_RUNLEVEL=y +CONFIG_RX=y +CONFIG_SETFATTR=y +CONFIG_SETSERIAL=y +CONFIG_STRINGS=y +CONFIG_TIME=y +CONFIG_TTYSIZE=y +CONFIG_UBIRENAME=y +CONFIG_UBIATTACH=y +CONFIG_UBIDETACH=y +CONFIG_UBIMKVOL=y +CONFIG_UBIRMVOL=y +CONFIG_UBIRSVOL=y +CONFIG_UBIUPDATEVOL=y +CONFIG_VOLNAME=y +CONFIG_WATCHDOG=y + +# +# Networking Utilities +# +CONFIG_FEATURE_IPV6=y +# CONFIG_FEATURE_UNIX_LOCAL is not set +CONFIG_FEATURE_PREFER_IPV4_ADDRESS=y +CONFIG_VERBOSE_RESOLUTION_ERRORS=y +CONFIG_FEATURE_TLS_SHA1=y +CONFIG_ARP=y +CONFIG_ARPING=y +CONFIG_BRCTL=y +CONFIG_FEATURE_BRCTL_FANCY=y +CONFIG_FEATURE_BRCTL_SHOW=y +CONFIG_DNSD=y +# CONFIG_ETHER_WAKE is not set +CONFIG_FTPD=y +CONFIG_FEATURE_FTPD_WRITE=y +CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST=y +CONFIG_FEATURE_FTPD_AUTHENTICATION=y +CONFIG_FTPGET=y +CONFIG_FTPPUT=y +CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS=y +CONFIG_HOSTNAME=y +CONFIG_DNSDOMAINNAME=y +CONFIG_HTTPD=y +CONFIG_FEATURE_HTTPD_RANGES=y +CONFIG_FEATURE_HTTPD_SETUID=y +CONFIG_FEATURE_HTTPD_BASIC_AUTH=y +CONFIG_FEATURE_HTTPD_AUTH_MD5=y +CONFIG_FEATURE_HTTPD_CGI=y +CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR=y +CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV=y +CONFIG_FEATURE_HTTPD_ENCODE_URL_STR=y +CONFIG_FEATURE_HTTPD_ERROR_PAGES=y +CONFIG_FEATURE_HTTPD_PROXY=y +CONFIG_FEATURE_HTTPD_GZIP=y +CONFIG_IFCONFIG=y +CONFIG_FEATURE_IFCONFIG_STATUS=y +CONFIG_FEATURE_IFCONFIG_SLIP=y +CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ=y +CONFIG_FEATURE_IFCONFIG_HW=y +CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS=y +CONFIG_IFENSLAVE=y +CONFIG_IFPLUGD=y +# CONFIG_IFUP is not set +# CONFIG_IFDOWN is not set +CONFIG_IFUPDOWN_IFSTATE_PATH="" +# CONFIG_FEATURE_IFUPDOWN_IP is not set +# CONFIG_FEATURE_IFUPDOWN_IPV4 is not set +# CONFIG_FEATURE_IFUPDOWN_IPV6 is not set +# CONFIG_FEATURE_IFUPDOWN_MAPPING is not set +# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set +CONFIG_INETD=y +CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO=y +CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD=y +CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME=y +CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME=y +CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN=y +CONFIG_FEATURE_INETD_RPC=y +CONFIG_IP=y +CONFIG_IPADDR=y +CONFIG_IPLINK=y +CONFIG_IPROUTE=y +CONFIG_IPTUNNEL=y +CONFIG_IPRULE=y +CONFIG_IPNEIGH=y +CONFIG_FEATURE_IP_ADDRESS=y +CONFIG_FEATURE_IP_LINK=y +CONFIG_FEATURE_IP_ROUTE=y +CONFIG_FEATURE_IP_ROUTE_DIR="/etc/iproute2" +CONFIG_FEATURE_IP_TUNNEL=y +CONFIG_FEATURE_IP_RULE=y +CONFIG_FEATURE_IP_NEIGH=y +CONFIG_FEATURE_IP_RARE_PROTOCOLS=y +CONFIG_IPCALC=y +CONFIG_FEATURE_IPCALC_LONG_OPTIONS=y +CONFIG_FEATURE_IPCALC_FANCY=y +CONFIG_FAKEIDENTD=y +CONFIG_NAMEIF=y +CONFIG_FEATURE_NAMEIF_EXTENDED=y +CONFIG_NBDCLIENT=y +CONFIG_NC=y +# CONFIG_NETCAT is not set +CONFIG_NC_SERVER=y +CONFIG_NC_EXTRA=y +CONFIG_NC_110_COMPAT=y +CONFIG_NETSTAT=y +CONFIG_FEATURE_NETSTAT_WIDE=y +CONFIG_FEATURE_NETSTAT_PRG=y +# CONFIG_NSLOOKUP is not set +# CONFIG_FEATURE_NSLOOKUP_BIG is not set +# CONFIG_FEATURE_NSLOOKUP_LONG_OPTIONS is not set +CONFIG_NTPD=y +CONFIG_FEATURE_NTPD_SERVER=y +# CONFIG_FEATURE_NTPD_CONF is not set +CONFIG_FEATURE_NTP_AUTH=y +CONFIG_PING=y +CONFIG_PING6=y +CONFIG_FEATURE_FANCY_PING=y +CONFIG_PSCAN=y +CONFIG_ROUTE=y +CONFIG_SLATTACH=y +CONFIG_SSL_CLIENT=y +CONFIG_TC=y +CONFIG_FEATURE_TC_INGRESS=y +CONFIG_TCPSVD=y +CONFIG_UDPSVD=y +CONFIG_TELNET=y +CONFIG_FEATURE_TELNET_TTYPE=y +CONFIG_FEATURE_TELNET_AUTOLOGIN=y +CONFIG_FEATURE_TELNET_WIDTH=y +CONFIG_TELNETD=y +CONFIG_FEATURE_TELNETD_STANDALONE=y +CONFIG_FEATURE_TELNETD_INETD_WAIT=y +CONFIG_TFTP=y +CONFIG_FEATURE_TFTP_PROGRESS_BAR=y +CONFIG_TFTPD=y +CONFIG_FEATURE_TFTP_GET=y +CONFIG_FEATURE_TFTP_PUT=y +CONFIG_FEATURE_TFTP_BLOCKSIZE=y +# CONFIG_TFTP_DEBUG is not set +CONFIG_TLS=y +CONFIG_TRACEROUTE=y +CONFIG_TRACEROUTE6=y +CONFIG_FEATURE_TRACEROUTE_VERBOSE=y +CONFIG_FEATURE_TRACEROUTE_USE_ICMP=y +CONFIG_TUNCTL=y +CONFIG_FEATURE_TUNCTL_UG=y +CONFIG_VCONFIG=y +CONFIG_WGET=y +CONFIG_FEATURE_WGET_LONG_OPTIONS=y +CONFIG_FEATURE_WGET_STATUSBAR=y +CONFIG_FEATURE_WGET_AUTHENTICATION=y +CONFIG_FEATURE_WGET_TIMEOUT=y +CONFIG_FEATURE_WGET_HTTPS=y +CONFIG_FEATURE_WGET_OPENSSL=y +CONFIG_WHOIS=y +CONFIG_ZCIP=y +CONFIG_UDHCPD=y +# CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC is not set +CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY=y +CONFIG_DHCPD_LEASES_FILE="/var/lib/misc/udhcpd.leases" +CONFIG_DUMPLEASES=y +CONFIG_DHCPRELAY=y +CONFIG_UDHCPC=y +CONFIG_FEATURE_UDHCPC_ARPING=y +CONFIG_FEATURE_UDHCPC_SANITIZEOPT=y +CONFIG_UDHCPC_DEFAULT_SCRIPT="/usr/share/udhcpc/default.script" +# CONFIG_UDHCPC6 is not set +# CONFIG_FEATURE_UDHCPC6_RFC3646 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4704 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4833 is not set +# CONFIG_FEATURE_UDHCPC6_RFC5970 is not set + +# +# Common options for DHCP applets +# +# CONFIG_FEATURE_UDHCP_PORT is not set +CONFIG_UDHCP_DEBUG=9 +CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=80 +CONFIG_FEATURE_UDHCP_RFC3397=y +CONFIG_FEATURE_UDHCP_8021Q=y +CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="" + +# +# Print Utilities +# +CONFIG_LPD=y +CONFIG_LPR=y +CONFIG_LPQ=y + +# +# Mail Utilities +# +CONFIG_MAKEMIME=y +CONFIG_POPMAILDIR=y +CONFIG_FEATURE_POPMAILDIR_DELIVERY=y +CONFIG_REFORMIME=y +CONFIG_FEATURE_REFORMIME_COMPAT=y +CONFIG_SENDMAIL=y +CONFIG_FEATURE_MIME_CHARSET="us-ascii" + +# +# Process Utilities +# +CONFIG_FREE=y +CONFIG_FUSER=y +CONFIG_IOSTAT=y +CONFIG_KILL=y +CONFIG_KILLALL=y +CONFIG_KILLALL5=y +CONFIG_LSOF=y +CONFIG_MPSTAT=y +CONFIG_NMETER=y +CONFIG_PGREP=y +CONFIG_PKILL=y +CONFIG_PIDOF=y +CONFIG_FEATURE_PIDOF_SINGLE=y +CONFIG_FEATURE_PIDOF_OMIT=y +CONFIG_PMAP=y +CONFIG_POWERTOP=y +CONFIG_FEATURE_POWERTOP_INTERACTIVE=y +CONFIG_PS=y +# CONFIG_FEATURE_PS_WIDE is not set +# CONFIG_FEATURE_PS_LONG is not set +CONFIG_FEATURE_PS_TIME=y +# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set +CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS=y +CONFIG_PSTREE=y +CONFIG_PWDX=y +CONFIG_SMEMCAP=y +CONFIG_BB_SYSCTL=y +CONFIG_TOP=y +CONFIG_FEATURE_TOP_INTERACTIVE=y +CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE=y +CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS=y +CONFIG_FEATURE_TOP_SMP_CPU=y +# CONFIG_FEATURE_TOP_DECIMALS is not set +CONFIG_FEATURE_TOP_SMP_PROCESS=y +CONFIG_FEATURE_TOPMEM=y +CONFIG_UPTIME=y +CONFIG_FEATURE_UPTIME_UTMP_SUPPORT=y +CONFIG_WATCH=y +CONFIG_FEATURE_SHOW_THREADS=y + +# +# Runit Utilities +# +CONFIG_CHPST=y +CONFIG_SETUIDGID=y +CONFIG_ENVUIDGID=y +CONFIG_ENVDIR=y +CONFIG_SOFTLIMIT=y +CONFIG_RUNSV=y +CONFIG_RUNSVDIR=y +# CONFIG_FEATURE_RUNSVDIR_LOG is not set +CONFIG_SV=y +CONFIG_SV_DEFAULT_SERVICE_DIR="/var/service" +CONFIG_SVC=y +CONFIG_SVOK=y +CONFIG_SVLOGD=y +# CONFIG_CHCON is not set +# CONFIG_GETENFORCE is not set +# CONFIG_GETSEBOOL is not set +# CONFIG_LOAD_POLICY is not set +# CONFIG_MATCHPATHCON is not set +# CONFIG_RUNCON is not set +# CONFIG_SELINUXENABLED is not set +# CONFIG_SESTATUS is not set +# CONFIG_SETENFORCE is not set +# CONFIG_SETFILES is not set +# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set +# CONFIG_RESTORECON is not set +# CONFIG_SETSEBOOL is not set + +# +# Shells +# +CONFIG_SH_IS_ASH=y +# CONFIG_SH_IS_HUSH is not set +# CONFIG_SH_IS_NONE is not set +# CONFIG_BASH_IS_ASH is not set +# CONFIG_BASH_IS_HUSH is not set +CONFIG_BASH_IS_NONE=y +CONFIG_ASH=y +CONFIG_ASH_OPTIMIZE_FOR_SIZE=y +CONFIG_ASH_INTERNAL_GLOB=y +CONFIG_ASH_BASH_COMPAT=y +# CONFIG_ASH_BASH_SOURCE_CURDIR is not set +CONFIG_ASH_BASH_NOT_FOUND_HOOK=y +CONFIG_ASH_JOB_CONTROL=y +CONFIG_ASH_ALIAS=y +CONFIG_ASH_RANDOM_SUPPORT=y +CONFIG_ASH_EXPAND_PRMT=y +CONFIG_ASH_IDLE_TIMEOUT=y +CONFIG_ASH_MAIL=y +CONFIG_ASH_ECHO=y +CONFIG_ASH_PRINTF=y +CONFIG_ASH_TEST=y +CONFIG_ASH_HELP=y +CONFIG_ASH_GETOPTS=y +CONFIG_ASH_CMDCMD=y +CONFIG_CTTYHACK=y +CONFIG_HUSH=y +CONFIG_HUSH_BASH_COMPAT=y +CONFIG_HUSH_BRACE_EXPANSION=y +CONFIG_HUSH_LINENO_VAR=y +# CONFIG_HUSH_BASH_SOURCE_CURDIR is not set +CONFIG_HUSH_INTERACTIVE=y +CONFIG_HUSH_SAVEHISTORY=y +CONFIG_HUSH_JOB=y +CONFIG_HUSH_TICK=y +CONFIG_HUSH_IF=y +CONFIG_HUSH_LOOPS=y +CONFIG_HUSH_CASE=y +CONFIG_HUSH_FUNCTIONS=y +CONFIG_HUSH_LOCAL=y +CONFIG_HUSH_RANDOM_SUPPORT=y +CONFIG_HUSH_MODE_X=y +CONFIG_HUSH_ECHO=y +CONFIG_HUSH_PRINTF=y +CONFIG_HUSH_TEST=y +CONFIG_HUSH_HELP=y +CONFIG_HUSH_EXPORT=y +CONFIG_HUSH_EXPORT_N=y +CONFIG_HUSH_READONLY=y +CONFIG_HUSH_KILL=y +CONFIG_HUSH_WAIT=y +CONFIG_HUSH_COMMAND=y +CONFIG_HUSH_TRAP=y +CONFIG_HUSH_TYPE=y +CONFIG_HUSH_TIMES=y +CONFIG_HUSH_READ=y +CONFIG_HUSH_SET=y +CONFIG_HUSH_UNSET=y +CONFIG_HUSH_ULIMIT=y +CONFIG_HUSH_UMASK=y +CONFIG_HUSH_GETOPTS=y +# CONFIG_HUSH_MEMLEAK is not set + +# +# Options common to all shells +# +CONFIG_FEATURE_SH_MATH=y +CONFIG_FEATURE_SH_MATH_64=y +CONFIG_FEATURE_SH_EXTRA_QUIET=y +# CONFIG_FEATURE_SH_STANDALONE is not set +# CONFIG_FEATURE_SH_NOFORK is not set +CONFIG_FEATURE_SH_READ_FRAC=y +# CONFIG_FEATURE_SH_HISTFILESIZE is not set +CONFIG_FEATURE_SH_EMBEDDED_SCRIPTS=y + +# +# System Logging Utilities +# +CONFIG_KLOGD=y +CONFIG_FEATURE_KLOGD_KLOGCTL=y +CONFIG_LOGGER=y +# CONFIG_LOGREAD is not set +# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set +CONFIG_SYSLOGD=y +CONFIG_FEATURE_ROTATE_LOGFILE=y +CONFIG_FEATURE_REMOTE_LOG=y +CONFIG_FEATURE_SYSLOGD_DUP=y +CONFIG_FEATURE_SYSLOGD_CFG=y +CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=256 +# CONFIG_FEATURE_IPC_SYSLOG is not set +CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 +# CONFIG_FEATURE_KMSG_SYSLOG is not set diff --git a/BUSYBOX/mips64el_ash.config b/BUSYBOX/mips64el_ash.config new file mode 100644 index 0000000..8354db8 --- /dev/null +++ b/BUSYBOX/mips64el_ash.config @@ -0,0 +1,1166 @@ +# +# Automatically generated make config: don't edit +# Busybox version: 1.32.0 +# Thu Mar 4 12:59:59 2021 +# +CONFIG_HAVE_DOT_CONFIG=y + +# +# Settings +# +# CONFIG_DESKTOP is not set +# CONFIG_EXTRA_COMPAT is not set +# CONFIG_FEDORA_COMPAT is not set +# CONFIG_INCLUDE_SUSv2 is not set +# CONFIG_LONG_OPTS is not set +# CONFIG_SHOW_USAGE is not set +# CONFIG_FEATURE_VERBOSE_USAGE is not set +# CONFIG_FEATURE_COMPRESS_USAGE is not set +# CONFIG_LFS is not set +# CONFIG_PAM is not set +# CONFIG_FEATURE_DEVPTS is not set +# CONFIG_FEATURE_UTMP is not set +# CONFIG_FEATURE_WTMP is not set +# CONFIG_FEATURE_PIDFILE is not set +CONFIG_PID_FILE_PATH="" +# CONFIG_BUSYBOX is not set +# CONFIG_FEATURE_SHOW_SCRIPT is not set +# CONFIG_FEATURE_INSTALLER is not set +# CONFIG_INSTALL_NO_USR is not set +# CONFIG_FEATURE_SUID is not set +# CONFIG_FEATURE_SUID_CONFIG is not set +# CONFIG_FEATURE_SUID_CONFIG_QUIET is not set +# CONFIG_FEATURE_PREFER_APPLETS is not set +CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" +# CONFIG_SELINUX is not set +# CONFIG_FEATURE_CLEAN_UP is not set +# CONFIG_FEATURE_SYSLOG_INFO is not set +# CONFIG_FEATURE_SYSLOG is not set +# CONFIG_PLATFORM_LINUX is not set + +# +# Build Options +# +CONFIG_STATIC=y +# CONFIG_PIE is not set +# CONFIG_NOMMU is not set +# CONFIG_BUILD_LIBBUSYBOX is not set +# CONFIG_FEATURE_LIBBUSYBOX_STATIC is not set +# CONFIG_FEATURE_INDIVIDUAL is not set +# CONFIG_FEATURE_SHARED_BUSYBOX is not set +CONFIG_CROSS_COMPILER_PREFIX="" +CONFIG_SYSROOT="" +CONFIG_EXTRA_CFLAGS="" +CONFIG_EXTRA_LDFLAGS="" +CONFIG_EXTRA_LDLIBS="" +# CONFIG_USE_PORTABLE_CODE is not set +# CONFIG_STACK_OPTIMIZATION_386 is not set + +# +# Installation Options ("make install" behavior) +# +CONFIG_INSTALL_APPLET_SYMLINKS=y +# CONFIG_INSTALL_APPLET_HARDLINKS is not set +# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set +# CONFIG_INSTALL_APPLET_DONT is not set +# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set +# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set +# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set +CONFIG_PREFIX="./_install" + +# +# Debugging Options +# +# CONFIG_DEBUG is not set +# CONFIG_DEBUG_PESSIMIZE is not set +# CONFIG_DEBUG_SANITIZE is not set +# CONFIG_UNIT_TEST is not set +# CONFIG_WERROR is not set +# CONFIG_WARN_SIMPLE_MSG is not set +CONFIG_NO_DEBUG_LIB=y +# CONFIG_DMALLOC is not set +# CONFIG_EFENCE is not set + +# +# Library Tuning +# +# CONFIG_FEATURE_USE_BSS_TAIL is not set +# CONFIG_FLOAT_DURATION is not set +# CONFIG_FEATURE_RTMINMAX is not set +# CONFIG_FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS is not set +CONFIG_FEATURE_BUFFERS_USE_MALLOC=y +# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set +# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set +CONFIG_PASSWORD_MINLEN=6 +CONFIG_MD5_SMALL=1 +CONFIG_SHA3_SMALL=1 +# CONFIG_FEATURE_FAST_TOP is not set +# CONFIG_FEATURE_ETC_NETWORKS is not set +# CONFIG_FEATURE_ETC_SERVICES is not set +# CONFIG_FEATURE_EDITING is not set +CONFIG_FEATURE_EDITING_MAX_LEN=0 +# CONFIG_FEATURE_EDITING_VI is not set +CONFIG_FEATURE_EDITING_HISTORY=0 +# CONFIG_FEATURE_EDITING_SAVEHISTORY is not set +# CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set +# CONFIG_FEATURE_REVERSE_SEARCH is not set +# CONFIG_FEATURE_TAB_COMPLETION is not set +# CONFIG_FEATURE_USERNAME_COMPLETION is not set +# CONFIG_FEATURE_EDITING_FANCY_PROMPT is not set +# CONFIG_FEATURE_EDITING_WINCH is not set +# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set +# CONFIG_LOCALE_SUPPORT is not set +# CONFIG_UNICODE_SUPPORT is not set +# CONFIG_UNICODE_USING_LOCALE is not set +# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set +CONFIG_SUBST_WCHAR=0 +CONFIG_LAST_SUPPORTED_WCHAR=0 +# CONFIG_UNICODE_COMBINING_WCHARS is not set +# CONFIG_UNICODE_WIDE_WCHARS is not set +# CONFIG_UNICODE_BIDI_SUPPORT is not set +# CONFIG_UNICODE_NEUTRAL_TABLE is not set +# CONFIG_UNICODE_PRESERVE_BROKEN is not set +# CONFIG_FEATURE_NON_POSIX_CP is not set +# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set +# CONFIG_FEATURE_USE_SENDFILE is not set +CONFIG_FEATURE_COPYBUF_KB=4 +# CONFIG_FEATURE_SKIP_ROOTFS is not set +# CONFIG_MONOTONIC_SYSCALL is not set +# CONFIG_IOCTL_HEX2STR_ERROR is not set +# CONFIG_FEATURE_HWIB is not set + +# +# Applets +# + +# +# Archival Utilities +# +# CONFIG_FEATURE_SEAMLESS_XZ is not set +# CONFIG_FEATURE_SEAMLESS_LZMA is not set +# CONFIG_FEATURE_SEAMLESS_BZ2 is not set +# CONFIG_FEATURE_SEAMLESS_GZ is not set +# CONFIG_FEATURE_SEAMLESS_Z is not set +# CONFIG_AR is not set +# CONFIG_FEATURE_AR_LONG_FILENAMES is not set +# CONFIG_FEATURE_AR_CREATE is not set +# CONFIG_UNCOMPRESS is not set +# CONFIG_GUNZIP is not set +# CONFIG_ZCAT is not set +# CONFIG_FEATURE_GUNZIP_LONG_OPTIONS is not set +# CONFIG_BUNZIP2 is not set +# CONFIG_BZCAT is not set +# CONFIG_UNLZMA is not set +# CONFIG_LZCAT is not set +# CONFIG_LZMA is not set +# CONFIG_UNXZ is not set +# CONFIG_XZCAT is not set +# CONFIG_XZ is not set +# CONFIG_BZIP2 is not set +CONFIG_BZIP2_SMALL=0 +# CONFIG_FEATURE_BZIP2_DECOMPRESS is not set +# CONFIG_CPIO is not set +# CONFIG_FEATURE_CPIO_O is not set +# CONFIG_FEATURE_CPIO_P is not set +# CONFIG_DPKG is not set +# CONFIG_DPKG_DEB is not set +# CONFIG_GZIP is not set +# CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set +CONFIG_GZIP_FAST=0 +# CONFIG_FEATURE_GZIP_LEVELS is not set +# CONFIG_FEATURE_GZIP_DECOMPRESS is not set +# CONFIG_LZOP is not set +# CONFIG_UNLZOP is not set +# CONFIG_LZOPCAT is not set +# CONFIG_LZOP_COMPR_HIGH is not set +# CONFIG_RPM is not set +# CONFIG_RPM2CPIO is not set +# CONFIG_TAR is not set +# CONFIG_FEATURE_TAR_LONG_OPTIONS is not set +# CONFIG_FEATURE_TAR_CREATE is not set +# CONFIG_FEATURE_TAR_AUTODETECT is not set +# CONFIG_FEATURE_TAR_FROM is not set +# CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_GNU_EXTENSIONS is not set +# CONFIG_FEATURE_TAR_TO_COMMAND is not set +# CONFIG_FEATURE_TAR_UNAME_GNAME is not set +# CONFIG_FEATURE_TAR_NOPRESERVE_TIME is not set +# CONFIG_FEATURE_TAR_SELINUX is not set +# CONFIG_UNZIP is not set +# CONFIG_FEATURE_UNZIP_CDF is not set +# CONFIG_FEATURE_UNZIP_BZIP2 is not set +# CONFIG_FEATURE_UNZIP_LZMA is not set +# CONFIG_FEATURE_UNZIP_XZ is not set +# CONFIG_FEATURE_LZMA_FAST is not set + +# +# Coreutils +# +# CONFIG_BASENAME is not set +# CONFIG_CAT is not set +# CONFIG_FEATURE_CATN is not set +# CONFIG_FEATURE_CATV is not set +# CONFIG_CHGRP is not set +# CONFIG_CHMOD is not set +# CONFIG_CHOWN is not set +# CONFIG_FEATURE_CHOWN_LONG_OPTIONS is not set +# CONFIG_CHROOT is not set +# CONFIG_CKSUM is not set +# CONFIG_COMM is not set +# CONFIG_CP is not set +# CONFIG_FEATURE_CP_LONG_OPTIONS is not set +# CONFIG_FEATURE_CP_REFLINK is not set +# CONFIG_CUT is not set +# CONFIG_DATE is not set +# CONFIG_FEATURE_DATE_ISOFMT is not set +# CONFIG_FEATURE_DATE_NANO is not set +# CONFIG_FEATURE_DATE_COMPAT is not set +# CONFIG_DD is not set +# CONFIG_FEATURE_DD_SIGNAL_HANDLING is not set +# CONFIG_FEATURE_DD_THIRD_STATUS_LINE is not set +# CONFIG_FEATURE_DD_IBS_OBS is not set +# CONFIG_FEATURE_DD_STATUS is not set +# CONFIG_DF is not set +# CONFIG_FEATURE_DF_FANCY is not set +# CONFIG_DIRNAME is not set +# CONFIG_DOS2UNIX is not set +# CONFIG_UNIX2DOS is not set +# CONFIG_DU is not set +# CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K is not set +# CONFIG_ECHO is not set +# CONFIG_FEATURE_FANCY_ECHO is not set +# CONFIG_ENV is not set +# CONFIG_EXPAND is not set +# CONFIG_UNEXPAND is not set +# CONFIG_EXPR is not set +# CONFIG_EXPR_MATH_SUPPORT_64 is not set +# CONFIG_FACTOR is not set +# CONFIG_FALSE is not set +# CONFIG_FOLD is not set +# CONFIG_HEAD is not set +# CONFIG_FEATURE_FANCY_HEAD is not set +# CONFIG_HOSTID is not set +# CONFIG_ID is not set +# CONFIG_GROUPS is not set +# CONFIG_INSTALL is not set +# CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set +# CONFIG_LINK is not set +# CONFIG_LN is not set +# CONFIG_LOGNAME is not set +# CONFIG_LS is not set +# CONFIG_FEATURE_LS_FILETYPES is not set +# CONFIG_FEATURE_LS_FOLLOWLINKS is not set +# CONFIG_FEATURE_LS_RECURSIVE is not set +# CONFIG_FEATURE_LS_WIDTH is not set +# CONFIG_FEATURE_LS_SORTFILES is not set +# CONFIG_FEATURE_LS_TIMESTAMPS is not set +# CONFIG_FEATURE_LS_USERNAME is not set +# CONFIG_FEATURE_LS_COLOR is not set +# CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set +# CONFIG_MD5SUM is not set +# CONFIG_SHA1SUM is not set +# CONFIG_SHA256SUM is not set +# CONFIG_SHA512SUM is not set +# CONFIG_SHA3SUM is not set +# CONFIG_FEATURE_MD5_SHA1_SUM_CHECK is not set +# CONFIG_MKDIR is not set +# CONFIG_MKFIFO is not set +# CONFIG_MKNOD is not set +# CONFIG_MKTEMP is not set +# CONFIG_MV is not set +# CONFIG_NICE is not set +# CONFIG_NL is not set +# CONFIG_NOHUP is not set +# CONFIG_NPROC is not set +# CONFIG_OD is not set +# CONFIG_PASTE is not set +# CONFIG_PRINTENV is not set +# CONFIG_PRINTF is not set +# CONFIG_PWD is not set +# CONFIG_READLINK is not set +# CONFIG_FEATURE_READLINK_FOLLOW is not set +# CONFIG_REALPATH is not set +# CONFIG_RM is not set +# CONFIG_RMDIR is not set +# CONFIG_SEQ is not set +# CONFIG_SHRED is not set +# CONFIG_SHUF is not set +# CONFIG_SLEEP is not set +# CONFIG_FEATURE_FANCY_SLEEP is not set +# CONFIG_SORT is not set +# CONFIG_FEATURE_SORT_BIG is not set +# CONFIG_FEATURE_SORT_OPTIMIZE_MEMORY is not set +# CONFIG_SPLIT is not set +# CONFIG_FEATURE_SPLIT_FANCY is not set +# CONFIG_STAT is not set +# CONFIG_FEATURE_STAT_FORMAT is not set +# CONFIG_FEATURE_STAT_FILESYSTEM is not set +# CONFIG_STTY is not set +# CONFIG_SUM is not set +# CONFIG_SYNC is not set +# CONFIG_FEATURE_SYNC_FANCY is not set +# CONFIG_FSYNC is not set +# CONFIG_TAC is not set +# CONFIG_TAIL is not set +# CONFIG_FEATURE_FANCY_TAIL is not set +# CONFIG_TEE is not set +# CONFIG_FEATURE_TEE_USE_BLOCK_IO is not set +# CONFIG_TEST is not set +# CONFIG_TEST1 is not set +# CONFIG_TEST2 is not set +# CONFIG_FEATURE_TEST_64 is not set +# CONFIG_TIMEOUT is not set +# CONFIG_TOUCH is not set +# CONFIG_FEATURE_TOUCH_NODEREF is not set +# CONFIG_FEATURE_TOUCH_SUSV3 is not set +# CONFIG_TR is not set +# CONFIG_FEATURE_TR_CLASSES is not set +# CONFIG_FEATURE_TR_EQUIV is not set +# CONFIG_TRUE is not set +# CONFIG_TRUNCATE is not set +# CONFIG_TTY is not set +# CONFIG_UNAME is not set +CONFIG_UNAME_OSNAME="" +# CONFIG_BB_ARCH is not set +# CONFIG_UNIQ is not set +# CONFIG_UNLINK is not set +# CONFIG_USLEEP is not set +# CONFIG_UUDECODE is not set +# CONFIG_BASE64 is not set +# CONFIG_UUENCODE is not set +# CONFIG_WC is not set +# CONFIG_FEATURE_WC_LARGE is not set +# CONFIG_WHOAMI is not set +# CONFIG_WHO is not set +# CONFIG_W is not set +# CONFIG_USERS is not set +# CONFIG_YES is not set + +# +# Common options +# +# CONFIG_FEATURE_VERBOSE is not set +# CONFIG_FEATURE_PRESERVE_HARDLINKS is not set +# CONFIG_FEATURE_HUMAN_READABLE is not set + +# +# Console Utilities +# +# CONFIG_CHVT is not set +# CONFIG_CLEAR is not set +# CONFIG_DEALLOCVT is not set +# CONFIG_DUMPKMAP is not set +# CONFIG_FGCONSOLE is not set +# CONFIG_KBD_MODE is not set +# CONFIG_LOADFONT is not set +# CONFIG_SETFONT is not set +# CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set +CONFIG_DEFAULT_SETFONT_DIR="" +# CONFIG_FEATURE_LOADFONT_PSF2 is not set +# CONFIG_FEATURE_LOADFONT_RAW is not set +# CONFIG_LOADKMAP is not set +# CONFIG_OPENVT is not set +# CONFIG_RESET is not set +# CONFIG_RESIZE is not set +# CONFIG_FEATURE_RESIZE_PRINT is not set +# CONFIG_SETCONSOLE is not set +# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set +# CONFIG_SETKEYCODES is not set +# CONFIG_SETLOGCONS is not set +# CONFIG_SHOWKEY is not set + +# +# Debian Utilities +# +# CONFIG_PIPE_PROGRESS is not set +# CONFIG_RUN_PARTS is not set +# CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set +# CONFIG_FEATURE_RUN_PARTS_FANCY is not set +# CONFIG_START_STOP_DAEMON is not set +# CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set +# CONFIG_FEATURE_START_STOP_DAEMON_FANCY is not set +# CONFIG_WHICH is not set + +# +# klibc-utils +# +# CONFIG_MINIPS is not set +# CONFIG_NUKE is not set +# CONFIG_RESUME is not set +# CONFIG_RUN_INIT is not set + +# +# Editors +# +# CONFIG_AWK is not set +# CONFIG_FEATURE_AWK_LIBM is not set +# CONFIG_FEATURE_AWK_GNU_EXTENSIONS is not set +# CONFIG_CMP is not set +# CONFIG_DIFF is not set +# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set +# CONFIG_FEATURE_DIFF_DIR is not set +# CONFIG_ED is not set +# CONFIG_PATCH is not set +# CONFIG_SED is not set +# CONFIG_VI is not set +CONFIG_FEATURE_VI_MAX_LEN=0 +# CONFIG_FEATURE_VI_8BIT is not set +# CONFIG_FEATURE_VI_COLON is not set +# CONFIG_FEATURE_VI_YANKMARK is not set +# CONFIG_FEATURE_VI_SEARCH is not set +# CONFIG_FEATURE_VI_REGEX_SEARCH is not set +# CONFIG_FEATURE_VI_USE_SIGNALS is not set +# CONFIG_FEATURE_VI_DOT_CMD is not set +# CONFIG_FEATURE_VI_READONLY is not set +# CONFIG_FEATURE_VI_SETOPTS is not set +# CONFIG_FEATURE_VI_SET is not set +# CONFIG_FEATURE_VI_WIN_RESIZE is not set +# CONFIG_FEATURE_VI_ASK_TERMINAL is not set +# CONFIG_FEATURE_VI_UNDO is not set +# CONFIG_FEATURE_VI_UNDO_QUEUE is not set +CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=0 +# CONFIG_FEATURE_ALLOW_EXEC is not set + +# +# Finding Utilities +# +# CONFIG_FIND is not set +# CONFIG_FEATURE_FIND_PRINT0 is not set +# CONFIG_FEATURE_FIND_MTIME is not set +# CONFIG_FEATURE_FIND_MMIN is not set +# CONFIG_FEATURE_FIND_PERM is not set +# CONFIG_FEATURE_FIND_TYPE is not set +# CONFIG_FEATURE_FIND_EXECUTABLE is not set +# CONFIG_FEATURE_FIND_XDEV is not set +# CONFIG_FEATURE_FIND_MAXDEPTH is not set +# CONFIG_FEATURE_FIND_NEWER is not set +# CONFIG_FEATURE_FIND_INUM is not set +# CONFIG_FEATURE_FIND_EXEC is not set +# CONFIG_FEATURE_FIND_EXEC_PLUS is not set +# CONFIG_FEATURE_FIND_USER is not set +# CONFIG_FEATURE_FIND_GROUP is not set +# CONFIG_FEATURE_FIND_NOT is not set +# CONFIG_FEATURE_FIND_DEPTH is not set +# CONFIG_FEATURE_FIND_PAREN is not set +# CONFIG_FEATURE_FIND_SIZE is not set +# CONFIG_FEATURE_FIND_PRUNE is not set +# CONFIG_FEATURE_FIND_QUIT is not set +# CONFIG_FEATURE_FIND_DELETE is not set +# CONFIG_FEATURE_FIND_EMPTY is not set +# CONFIG_FEATURE_FIND_PATH is not set +# CONFIG_FEATURE_FIND_REGEX is not set +# CONFIG_FEATURE_FIND_CONTEXT is not set +# CONFIG_FEATURE_FIND_LINKS is not set +# CONFIG_GREP is not set +# CONFIG_EGREP is not set +# CONFIG_FGREP is not set +# CONFIG_FEATURE_GREP_CONTEXT is not set +# CONFIG_XARGS is not set +# CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION is not set +# CONFIG_FEATURE_XARGS_SUPPORT_QUOTES is not set +# CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM is not set +# CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR is not set +# CONFIG_FEATURE_XARGS_SUPPORT_PARALLEL is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ARGS_FILE is not set + +# +# Init Utilities +# +# CONFIG_BOOTCHARTD is not set +# CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set +# CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set +# CONFIG_HALT is not set +# CONFIG_POWEROFF is not set +# CONFIG_REBOOT is not set +# CONFIG_FEATURE_WAIT_FOR_INIT is not set +# CONFIG_FEATURE_CALL_TELINIT is not set +CONFIG_TELINIT_PATH="" +# CONFIG_INIT is not set +# CONFIG_LINUXRC is not set +# CONFIG_FEATURE_USE_INITTAB is not set +# CONFIG_FEATURE_KILL_REMOVED is not set +CONFIG_FEATURE_KILL_DELAY=0 +# CONFIG_FEATURE_INIT_SCTTY is not set +# CONFIG_FEATURE_INIT_SYSLOG is not set +# CONFIG_FEATURE_INIT_QUIET is not set +# CONFIG_FEATURE_INIT_COREDUMPS is not set +CONFIG_INIT_TERMINAL_TYPE="" +# CONFIG_FEATURE_INIT_MODIFY_CMDLINE is not set + +# +# Login/Password Management Utilities +# +# CONFIG_FEATURE_SHADOWPASSWDS is not set +# CONFIG_USE_BB_PWD_GRP is not set +# CONFIG_USE_BB_SHADOW is not set +# CONFIG_USE_BB_CRYPT is not set +# CONFIG_USE_BB_CRYPT_SHA is not set +# CONFIG_ADDGROUP is not set +# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set +# CONFIG_ADD_SHELL is not set +# CONFIG_REMOVE_SHELL is not set +# CONFIG_ADDUSER is not set +# CONFIG_FEATURE_CHECK_NAMES is not set +CONFIG_LAST_ID=0 +CONFIG_FIRST_SYSTEM_ID=0 +CONFIG_LAST_SYSTEM_ID=0 +# CONFIG_CHPASSWD is not set +CONFIG_FEATURE_DEFAULT_PASSWD_ALGO="" +# CONFIG_CRYPTPW is not set +# CONFIG_MKPASSWD is not set +# CONFIG_DELUSER is not set +# CONFIG_DELGROUP is not set +# CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set +# CONFIG_GETTY is not set +# CONFIG_LOGIN is not set +# CONFIG_LOGIN_SESSION_AS_CHILD is not set +# CONFIG_LOGIN_SCRIPTS is not set +# CONFIG_FEATURE_NOLOGIN is not set +# CONFIG_FEATURE_SECURETTY is not set +# CONFIG_PASSWD is not set +# CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set +# CONFIG_SU is not set +# CONFIG_FEATURE_SU_SYSLOG is not set +# CONFIG_FEATURE_SU_CHECKS_SHELLS is not set +# CONFIG_FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY is not set +# CONFIG_SULOGIN is not set +# CONFIG_VLOCK is not set + +# +# Linux Ext2 FS Progs +# +# CONFIG_CHATTR is not set +# CONFIG_FSCK is not set +# CONFIG_LSATTR is not set +# CONFIG_TUNE2FS is not set + +# +# Linux Module Utilities +# +# CONFIG_MODPROBE_SMALL is not set +# CONFIG_DEPMOD is not set +# CONFIG_INSMOD is not set +# CONFIG_LSMOD is not set +# CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set +# CONFIG_MODINFO is not set +# CONFIG_MODPROBE is not set +# CONFIG_FEATURE_MODPROBE_BLACKLIST is not set +# CONFIG_RMMOD is not set + +# +# Options common to multiple modutils +# +# CONFIG_FEATURE_CMDLINE_MODULE_OPTIONS is not set +# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set +# CONFIG_FEATURE_2_4_MODULES is not set +# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set +# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set +# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set +# CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set +# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set +# CONFIG_FEATURE_MODUTILS_ALIAS is not set +# CONFIG_FEATURE_MODUTILS_SYMBOLS is not set +CONFIG_DEFAULT_MODULES_DIR="" +CONFIG_DEFAULT_DEPMOD_FILE="" + +# +# Linux System Utilities +# +# CONFIG_ACPID is not set +# CONFIG_FEATURE_ACPID_COMPAT is not set +# CONFIG_BLKDISCARD is not set +# CONFIG_BLKID is not set +# CONFIG_FEATURE_BLKID_TYPE is not set +# CONFIG_BLOCKDEV is not set +# CONFIG_CAL is not set +# CONFIG_CHRT is not set +# CONFIG_DMESG is not set +# CONFIG_FEATURE_DMESG_PRETTY is not set +# CONFIG_EJECT is not set +# CONFIG_FEATURE_EJECT_SCSI is not set +# CONFIG_FALLOCATE is not set +# CONFIG_FATATTR is not set +# CONFIG_FBSET is not set +# CONFIG_FEATURE_FBSET_FANCY is not set +# CONFIG_FEATURE_FBSET_READMODE is not set +# CONFIG_FDFORMAT is not set +# CONFIG_FDISK is not set +# CONFIG_FDISK_SUPPORT_LARGE_DISKS is not set +# CONFIG_FEATURE_FDISK_WRITABLE is not set +# CONFIG_FEATURE_AIX_LABEL is not set +# CONFIG_FEATURE_SGI_LABEL is not set +# CONFIG_FEATURE_SUN_LABEL is not set +# CONFIG_FEATURE_OSF_LABEL is not set +# CONFIG_FEATURE_GPT_LABEL is not set +# CONFIG_FEATURE_FDISK_ADVANCED is not set +# CONFIG_FINDFS is not set +# CONFIG_FLOCK is not set +# CONFIG_FDFLUSH is not set +# CONFIG_FREERAMDISK is not set +# CONFIG_FSCK_MINIX is not set +# CONFIG_FSFREEZE is not set +# CONFIG_FSTRIM is not set +# CONFIG_GETOPT is not set +# CONFIG_FEATURE_GETOPT_LONG is not set +# CONFIG_HEXDUMP is not set +# CONFIG_FEATURE_HEXDUMP_REVERSE is not set +# CONFIG_HD is not set +# CONFIG_XXD is not set +# CONFIG_HWCLOCK is not set +# CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set +# CONFIG_IONICE is not set +# CONFIG_IPCRM is not set +# CONFIG_IPCS is not set +# CONFIG_LAST is not set +# CONFIG_FEATURE_LAST_FANCY is not set +# CONFIG_LOSETUP is not set +# CONFIG_LSPCI is not set +# CONFIG_LSUSB is not set +# CONFIG_MDEV is not set +# CONFIG_FEATURE_MDEV_CONF is not set +# CONFIG_FEATURE_MDEV_RENAME is not set +# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set +# CONFIG_FEATURE_MDEV_EXEC is not set +# CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set +# CONFIG_FEATURE_MDEV_DAEMON is not set +# CONFIG_MESG is not set +# CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP is not set +# CONFIG_MKE2FS is not set +# CONFIG_MKFS_EXT2 is not set +# CONFIG_MKFS_MINIX is not set +# CONFIG_FEATURE_MINIX2 is not set +# CONFIG_MKFS_REISER is not set +# CONFIG_MKDOSFS is not set +# CONFIG_MKFS_VFAT is not set +# CONFIG_MKSWAP is not set +# CONFIG_FEATURE_MKSWAP_UUID is not set +# CONFIG_MORE is not set +# CONFIG_MOUNT is not set +# CONFIG_FEATURE_MOUNT_FAKE is not set +# CONFIG_FEATURE_MOUNT_VERBOSE is not set +# CONFIG_FEATURE_MOUNT_HELPERS is not set +# CONFIG_FEATURE_MOUNT_LABEL is not set +# CONFIG_FEATURE_MOUNT_NFS is not set +# CONFIG_FEATURE_MOUNT_CIFS is not set +# CONFIG_FEATURE_MOUNT_FLAGS is not set +# CONFIG_FEATURE_MOUNT_FSTAB is not set +# CONFIG_FEATURE_MOUNT_OTHERTAB is not set +# CONFIG_MOUNTPOINT is not set +# CONFIG_NOLOGIN is not set +# CONFIG_NOLOGIN_DEPENDENCIES is not set +# CONFIG_NSENTER is not set +# CONFIG_PIVOT_ROOT is not set +# CONFIG_RDATE is not set +# CONFIG_RDEV is not set +# CONFIG_READPROFILE is not set +# CONFIG_RENICE is not set +# CONFIG_REV is not set +# CONFIG_RTCWAKE is not set +# CONFIG_SCRIPT is not set +# CONFIG_SCRIPTREPLAY is not set +# CONFIG_SETARCH is not set +# CONFIG_LINUX32 is not set +# CONFIG_LINUX64 is not set +# CONFIG_SETPRIV is not set +# CONFIG_FEATURE_SETPRIV_DUMP is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITIES is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITY_NAMES is not set +# CONFIG_SETSID is not set +# CONFIG_SWAPON is not set +# CONFIG_FEATURE_SWAPON_DISCARD is not set +# CONFIG_FEATURE_SWAPON_PRI is not set +# CONFIG_SWAPOFF is not set +# CONFIG_FEATURE_SWAPONOFF_LABEL is not set +# CONFIG_SWITCH_ROOT is not set +# CONFIG_TASKSET is not set +# CONFIG_FEATURE_TASKSET_FANCY is not set +# CONFIG_FEATURE_TASKSET_CPULIST is not set +# CONFIG_UEVENT is not set +# CONFIG_UMOUNT is not set +# CONFIG_FEATURE_UMOUNT_ALL is not set +# CONFIG_UNSHARE is not set +# CONFIG_WALL is not set +# CONFIG_FEATURE_MOUNT_LOOP is not set +# CONFIG_FEATURE_MOUNT_LOOP_CREATE is not set +# CONFIG_FEATURE_MTAB_SUPPORT is not set +# CONFIG_VOLUMEID is not set +# CONFIG_FEATURE_VOLUMEID_BCACHE is not set +# CONFIG_FEATURE_VOLUMEID_BTRFS is not set +# CONFIG_FEATURE_VOLUMEID_CRAMFS is not set +# CONFIG_FEATURE_VOLUMEID_EXFAT is not set +# CONFIG_FEATURE_VOLUMEID_EXT is not set +# CONFIG_FEATURE_VOLUMEID_F2FS is not set +# CONFIG_FEATURE_VOLUMEID_FAT is not set +# CONFIG_FEATURE_VOLUMEID_HFS is not set +# CONFIG_FEATURE_VOLUMEID_ISO9660 is not set +# CONFIG_FEATURE_VOLUMEID_JFS is not set +# CONFIG_FEATURE_VOLUMEID_LFS is not set +# CONFIG_FEATURE_VOLUMEID_LINUXRAID is not set +# CONFIG_FEATURE_VOLUMEID_LINUXSWAP is not set +# CONFIG_FEATURE_VOLUMEID_LUKS is not set +# CONFIG_FEATURE_VOLUMEID_MINIX is not set +# CONFIG_FEATURE_VOLUMEID_NILFS is not set +# CONFIG_FEATURE_VOLUMEID_NTFS is not set +# CONFIG_FEATURE_VOLUMEID_OCFS2 is not set +# CONFIG_FEATURE_VOLUMEID_REISERFS is not set +# CONFIG_FEATURE_VOLUMEID_ROMFS is not set +# CONFIG_FEATURE_VOLUMEID_SQUASHFS is not set +# CONFIG_FEATURE_VOLUMEID_SYSV is not set +# CONFIG_FEATURE_VOLUMEID_UBIFS is not set +# CONFIG_FEATURE_VOLUMEID_UDF is not set +# CONFIG_FEATURE_VOLUMEID_XFS is not set + +# +# Miscellaneous Utilities +# +# CONFIG_ADJTIMEX is not set +# CONFIG_BBCONFIG is not set +# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set +# CONFIG_BC is not set +# CONFIG_DC is not set +# CONFIG_FEATURE_DC_BIG is not set +# CONFIG_FEATURE_DC_LIBM is not set +# CONFIG_FEATURE_BC_INTERACTIVE is not set +# CONFIG_FEATURE_BC_LONG_OPTIONS is not set +# CONFIG_BEEP is not set +CONFIG_FEATURE_BEEP_FREQ=0 +CONFIG_FEATURE_BEEP_LENGTH_MS=0 +# CONFIG_CHAT is not set +# CONFIG_FEATURE_CHAT_NOFAIL is not set +# CONFIG_FEATURE_CHAT_TTY_HIFI is not set +# CONFIG_FEATURE_CHAT_IMPLICIT_CR is not set +# CONFIG_FEATURE_CHAT_SWALLOW_OPTS is not set +# CONFIG_FEATURE_CHAT_SEND_ESCAPES is not set +# CONFIG_FEATURE_CHAT_VAR_ABORT_LEN is not set +# CONFIG_FEATURE_CHAT_CLR_ABORT is not set +# CONFIG_CONSPY is not set +# CONFIG_CROND is not set +# CONFIG_FEATURE_CROND_D is not set +# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set +# CONFIG_FEATURE_CROND_SPECIAL_TIMES is not set +CONFIG_FEATURE_CROND_DIR="" +# CONFIG_CRONTAB is not set +# CONFIG_DEVFSD is not set +# CONFIG_DEVFSD_MODLOAD is not set +# CONFIG_DEVFSD_FG_NP is not set +# CONFIG_DEVFSD_VERBOSE is not set +# CONFIG_FEATURE_DEVFS is not set +# CONFIG_DEVMEM is not set +# CONFIG_FBSPLASH is not set +# CONFIG_FLASHCP is not set +# CONFIG_FLASH_ERASEALL is not set +# CONFIG_FLASH_LOCK is not set +# CONFIG_FLASH_UNLOCK is not set +# CONFIG_HDPARM is not set +# CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set +# CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set +# CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set +# CONFIG_HEXEDIT is not set +# CONFIG_I2CGET is not set +# CONFIG_I2CSET is not set +# CONFIG_I2CDUMP is not set +# CONFIG_I2CDETECT is not set +# CONFIG_I2CTRANSFER is not set +# CONFIG_INOTIFYD is not set +# CONFIG_LESS is not set +CONFIG_FEATURE_LESS_MAXLINES=0 +# CONFIG_FEATURE_LESS_BRACKETS is not set +# CONFIG_FEATURE_LESS_FLAGS is not set +# CONFIG_FEATURE_LESS_TRUNCATE is not set +# CONFIG_FEATURE_LESS_MARKS is not set +# CONFIG_FEATURE_LESS_REGEXP is not set +# CONFIG_FEATURE_LESS_WINCH is not set +# CONFIG_FEATURE_LESS_ASK_TERMINAL is not set +# CONFIG_FEATURE_LESS_DASHCMD is not set +# CONFIG_FEATURE_LESS_LINENUMS is not set +# CONFIG_FEATURE_LESS_RAW is not set +# CONFIG_FEATURE_LESS_ENV is not set +# CONFIG_LSSCSI is not set +# CONFIG_MAKEDEVS is not set +# CONFIG_FEATURE_MAKEDEVS_LEAF is not set +# CONFIG_FEATURE_MAKEDEVS_TABLE is not set +# CONFIG_MAN is not set +# CONFIG_MICROCOM is not set +# CONFIG_MIM is not set +# CONFIG_MT is not set +# CONFIG_NANDWRITE is not set +# CONFIG_NANDDUMP is not set +# CONFIG_PARTPROBE is not set +# CONFIG_RAIDAUTORUN is not set +# CONFIG_READAHEAD is not set +# CONFIG_RFKILL is not set +# CONFIG_RUNLEVEL is not set +# CONFIG_RX is not set +# CONFIG_SETFATTR is not set +# CONFIG_SETSERIAL is not set +# CONFIG_STRINGS is not set +# CONFIG_TIME is not set +# CONFIG_TS is not set +# CONFIG_TTYSIZE is not set +# CONFIG_UBIRENAME is not set +# CONFIG_UBIATTACH is not set +# CONFIG_UBIDETACH is not set +# CONFIG_UBIMKVOL is not set +# CONFIG_UBIRMVOL is not set +# CONFIG_UBIRSVOL is not set +# CONFIG_UBIUPDATEVOL is not set +# CONFIG_VOLNAME is not set +# CONFIG_WATCHDOG is not set + +# +# Networking Utilities +# +# CONFIG_FEATURE_IPV6 is not set +# CONFIG_FEATURE_UNIX_LOCAL is not set +# CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set +# CONFIG_VERBOSE_RESOLUTION_ERRORS is not set +# CONFIG_FEATURE_TLS_SHA1 is not set +# CONFIG_ARP is not set +# CONFIG_ARPING is not set +# CONFIG_BRCTL is not set +# CONFIG_FEATURE_BRCTL_FANCY is not set +# CONFIG_FEATURE_BRCTL_SHOW is not set +# CONFIG_DNSD is not set +# CONFIG_ETHER_WAKE is not set +# CONFIG_FTPD is not set +# CONFIG_FEATURE_FTPD_WRITE is not set +# CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST is not set +# CONFIG_FEATURE_FTPD_AUTHENTICATION is not set +# CONFIG_FTPGET is not set +# CONFIG_FTPPUT is not set +# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set +# CONFIG_HOSTNAME is not set +# CONFIG_DNSDOMAINNAME is not set +# CONFIG_HTTPD is not set +# CONFIG_FEATURE_HTTPD_RANGES is not set +# CONFIG_FEATURE_HTTPD_SETUID is not set +# CONFIG_FEATURE_HTTPD_BASIC_AUTH is not set +# CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set +# CONFIG_FEATURE_HTTPD_CGI is not set +# CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set +# CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set +# CONFIG_FEATURE_HTTPD_ENCODE_URL_STR is not set +# CONFIG_FEATURE_HTTPD_ERROR_PAGES is not set +# CONFIG_FEATURE_HTTPD_PROXY is not set +# CONFIG_FEATURE_HTTPD_GZIP is not set +# CONFIG_IFCONFIG is not set +# CONFIG_FEATURE_IFCONFIG_STATUS is not set +# CONFIG_FEATURE_IFCONFIG_SLIP is not set +# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set +# CONFIG_FEATURE_IFCONFIG_HW is not set +# CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set +# CONFIG_IFENSLAVE is not set +# CONFIG_IFPLUGD is not set +# CONFIG_IFUP is not set +# CONFIG_IFDOWN is not set +CONFIG_IFUPDOWN_IFSTATE_PATH="" +# CONFIG_FEATURE_IFUPDOWN_IP is not set +# CONFIG_FEATURE_IFUPDOWN_IPV4 is not set +# CONFIG_FEATURE_IFUPDOWN_IPV6 is not set +# CONFIG_FEATURE_IFUPDOWN_MAPPING is not set +# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set +# CONFIG_INETD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set +# CONFIG_FEATURE_INETD_RPC is not set +# CONFIG_IP is not set +# CONFIG_IPADDR is not set +# CONFIG_IPLINK is not set +# CONFIG_IPROUTE is not set +# CONFIG_IPTUNNEL is not set +# CONFIG_IPRULE is not set +# CONFIG_IPNEIGH is not set +# CONFIG_FEATURE_IP_ADDRESS is not set +# CONFIG_FEATURE_IP_LINK is not set +# CONFIG_FEATURE_IP_ROUTE is not set +CONFIG_FEATURE_IP_ROUTE_DIR="" +# CONFIG_FEATURE_IP_TUNNEL is not set +# CONFIG_FEATURE_IP_RULE is not set +# CONFIG_FEATURE_IP_NEIGH is not set +# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set +# CONFIG_IPCALC is not set +# CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set +# CONFIG_FEATURE_IPCALC_FANCY is not set +# CONFIG_FAKEIDENTD is not set +# CONFIG_NAMEIF is not set +# CONFIG_FEATURE_NAMEIF_EXTENDED is not set +# CONFIG_NBDCLIENT is not set +# CONFIG_NC is not set +# CONFIG_NETCAT is not set +# CONFIG_NC_SERVER is not set +# CONFIG_NC_EXTRA is not set +# CONFIG_NC_110_COMPAT is not set +# CONFIG_NETSTAT is not set +# CONFIG_FEATURE_NETSTAT_WIDE is not set +# CONFIG_FEATURE_NETSTAT_PRG is not set +# CONFIG_NSLOOKUP is not set +# CONFIG_FEATURE_NSLOOKUP_BIG is not set +# CONFIG_FEATURE_NSLOOKUP_LONG_OPTIONS is not set +# CONFIG_NTPD is not set +# CONFIG_FEATURE_NTPD_SERVER is not set +# CONFIG_FEATURE_NTPD_CONF is not set +# CONFIG_FEATURE_NTP_AUTH is not set +# CONFIG_PING is not set +# CONFIG_PING6 is not set +# CONFIG_FEATURE_FANCY_PING is not set +# CONFIG_PSCAN is not set +# CONFIG_ROUTE is not set +# CONFIG_SLATTACH is not set +# CONFIG_SSL_CLIENT is not set +# CONFIG_TC is not set +# CONFIG_FEATURE_TC_INGRESS is not set +# CONFIG_TCPSVD is not set +# CONFIG_UDPSVD is not set +# CONFIG_TELNET is not set +# CONFIG_FEATURE_TELNET_TTYPE is not set +# CONFIG_FEATURE_TELNET_AUTOLOGIN is not set +# CONFIG_FEATURE_TELNET_WIDTH is not set +# CONFIG_TELNETD is not set +# CONFIG_FEATURE_TELNETD_STANDALONE is not set +# CONFIG_FEATURE_TELNETD_INETD_WAIT is not set +# CONFIG_TFTP is not set +# CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set +# CONFIG_FEATURE_TFTP_HPA_COMPAT is not set +# CONFIG_TFTPD is not set +# CONFIG_FEATURE_TFTP_GET is not set +# CONFIG_FEATURE_TFTP_PUT is not set +# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set +# CONFIG_TFTP_DEBUG is not set +# CONFIG_TLS is not set +# CONFIG_TRACEROUTE is not set +# CONFIG_TRACEROUTE6 is not set +# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set +# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set +# CONFIG_TUNCTL is not set +# CONFIG_FEATURE_TUNCTL_UG is not set +# CONFIG_VCONFIG is not set +# CONFIG_WGET is not set +# CONFIG_FEATURE_WGET_LONG_OPTIONS is not set +# CONFIG_FEATURE_WGET_STATUSBAR is not set +# CONFIG_FEATURE_WGET_AUTHENTICATION is not set +# CONFIG_FEATURE_WGET_TIMEOUT is not set +# CONFIG_FEATURE_WGET_HTTPS is not set +# CONFIG_FEATURE_WGET_OPENSSL is not set +# CONFIG_WHOIS is not set +# CONFIG_ZCIP is not set +# CONFIG_UDHCPD is not set +# CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC is not set +# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set +CONFIG_DHCPD_LEASES_FILE="" +# CONFIG_DUMPLEASES is not set +# CONFIG_DHCPRELAY is not set +# CONFIG_UDHCPC is not set +# CONFIG_FEATURE_UDHCPC_ARPING is not set +# CONFIG_FEATURE_UDHCPC_SANITIZEOPT is not set +CONFIG_UDHCPC_DEFAULT_SCRIPT="" +# CONFIG_UDHCPC6 is not set +# CONFIG_FEATURE_UDHCPC6_RFC3646 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4704 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4833 is not set +# CONFIG_FEATURE_UDHCPC6_RFC5970 is not set +# CONFIG_FEATURE_UDHCP_PORT is not set +CONFIG_UDHCP_DEBUG=0 +CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=0 +# CONFIG_FEATURE_UDHCP_RFC3397 is not set +# CONFIG_FEATURE_UDHCP_8021Q is not set +CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="" + +# +# Print Utilities +# +# CONFIG_LPD is not set +# CONFIG_LPR is not set +# CONFIG_LPQ is not set + +# +# Mail Utilities +# +# CONFIG_MAKEMIME is not set +# CONFIG_POPMAILDIR is not set +# CONFIG_FEATURE_POPMAILDIR_DELIVERY is not set +# CONFIG_REFORMIME is not set +# CONFIG_FEATURE_REFORMIME_COMPAT is not set +# CONFIG_SENDMAIL is not set +CONFIG_FEATURE_MIME_CHARSET="" + +# +# Process Utilities +# +# CONFIG_FREE is not set +# CONFIG_FUSER is not set +# CONFIG_IOSTAT is not set +# CONFIG_KILL is not set +# CONFIG_KILLALL is not set +# CONFIG_KILLALL5 is not set +# CONFIG_LSOF is not set +# CONFIG_MPSTAT is not set +# CONFIG_NMETER is not set +# CONFIG_PGREP is not set +# CONFIG_PKILL is not set +# CONFIG_PIDOF is not set +# CONFIG_FEATURE_PIDOF_SINGLE is not set +# CONFIG_FEATURE_PIDOF_OMIT is not set +# CONFIG_PMAP is not set +# CONFIG_POWERTOP is not set +# CONFIG_FEATURE_POWERTOP_INTERACTIVE is not set +# CONFIG_PS is not set +# CONFIG_FEATURE_PS_WIDE is not set +# CONFIG_FEATURE_PS_LONG is not set +# CONFIG_FEATURE_PS_TIME is not set +# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set +# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set +# CONFIG_PSTREE is not set +# CONFIG_PWDX is not set +# CONFIG_SMEMCAP is not set +# CONFIG_BB_SYSCTL is not set +# CONFIG_TOP is not set +# CONFIG_FEATURE_TOP_INTERACTIVE is not set +# CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE is not set +# CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS is not set +# CONFIG_FEATURE_TOP_SMP_CPU is not set +# CONFIG_FEATURE_TOP_DECIMALS is not set +# CONFIG_FEATURE_TOP_SMP_PROCESS is not set +# CONFIG_FEATURE_TOPMEM is not set +# CONFIG_UPTIME is not set +# CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set +# CONFIG_WATCH is not set +# CONFIG_FEATURE_SHOW_THREADS is not set + +# +# Runit Utilities +# +# CONFIG_CHPST is not set +# CONFIG_SETUIDGID is not set +# CONFIG_ENVUIDGID is not set +# CONFIG_ENVDIR is not set +# CONFIG_SOFTLIMIT is not set +# CONFIG_RUNSV is not set +# CONFIG_RUNSVDIR is not set +# CONFIG_FEATURE_RUNSVDIR_LOG is not set +# CONFIG_SV is not set +CONFIG_SV_DEFAULT_SERVICE_DIR="" +# CONFIG_SVC is not set +# CONFIG_SVOK is not set +# CONFIG_SVLOGD is not set +# CONFIG_CHCON is not set +# CONFIG_GETENFORCE is not set +# CONFIG_GETSEBOOL is not set +# CONFIG_LOAD_POLICY is not set +# CONFIG_MATCHPATHCON is not set +# CONFIG_RUNCON is not set +# CONFIG_SELINUXENABLED is not set +# CONFIG_SESTATUS is not set +# CONFIG_SETENFORCE is not set +# CONFIG_SETFILES is not set +# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set +# CONFIG_RESTORECON is not set +# CONFIG_SETSEBOOL is not set + +# +# Shells +# +CONFIG_SH_IS_ASH=y +# CONFIG_SH_IS_HUSH is not set +# CONFIG_SH_IS_NONE is not set +# CONFIG_BASH_IS_ASH is not set +# CONFIG_BASH_IS_HUSH is not set +CONFIG_BASH_IS_NONE=y +CONFIG_SHELL_ASH=y +CONFIG_ASH=y +# CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set +# CONFIG_ASH_INTERNAL_GLOB is not set +# CONFIG_ASH_BASH_COMPAT is not set +# CONFIG_ASH_BASH_SOURCE_CURDIR is not set +# CONFIG_ASH_BASH_NOT_FOUND_HOOK is not set +# CONFIG_ASH_JOB_CONTROL is not set +# CONFIG_ASH_ALIAS is not set +# CONFIG_ASH_RANDOM_SUPPORT is not set +# CONFIG_ASH_EXPAND_PRMT is not set +# CONFIG_ASH_IDLE_TIMEOUT is not set +# CONFIG_ASH_MAIL is not set +# CONFIG_ASH_ECHO is not set +# CONFIG_ASH_PRINTF is not set +# CONFIG_ASH_TEST is not set +# CONFIG_ASH_HELP is not set +# CONFIG_ASH_GETOPTS is not set +# CONFIG_ASH_CMDCMD is not set +# CONFIG_CTTYHACK is not set +# CONFIG_HUSH is not set +# CONFIG_SHELL_HUSH is not set +# CONFIG_HUSH_BASH_COMPAT is not set +# CONFIG_HUSH_BRACE_EXPANSION is not set +# CONFIG_HUSH_LINENO_VAR is not set +# CONFIG_HUSH_BASH_SOURCE_CURDIR is not set +# CONFIG_HUSH_INTERACTIVE is not set +# CONFIG_HUSH_SAVEHISTORY is not set +# CONFIG_HUSH_JOB is not set +# CONFIG_HUSH_TICK is not set +# CONFIG_HUSH_IF is not set +# CONFIG_HUSH_LOOPS is not set +# CONFIG_HUSH_CASE is not set +# CONFIG_HUSH_FUNCTIONS is not set +# CONFIG_HUSH_LOCAL is not set +# CONFIG_HUSH_RANDOM_SUPPORT is not set +# CONFIG_HUSH_MODE_X is not set +# CONFIG_HUSH_ECHO is not set +# CONFIG_HUSH_PRINTF is not set +# CONFIG_HUSH_TEST is not set +# CONFIG_HUSH_HELP is not set +# CONFIG_HUSH_EXPORT is not set +# CONFIG_HUSH_EXPORT_N is not set +# CONFIG_HUSH_READONLY is not set +# CONFIG_HUSH_KILL is not set +# CONFIG_HUSH_WAIT is not set +# CONFIG_HUSH_COMMAND is not set +# CONFIG_HUSH_TRAP is not set +# CONFIG_HUSH_TYPE is not set +# CONFIG_HUSH_TIMES is not set +# CONFIG_HUSH_READ is not set +# CONFIG_HUSH_SET is not set +# CONFIG_HUSH_UNSET is not set +# CONFIG_HUSH_ULIMIT is not set +# CONFIG_HUSH_UMASK is not set +# CONFIG_HUSH_GETOPTS is not set +# CONFIG_HUSH_MEMLEAK is not set + +# +# Options common to all shells +# +# CONFIG_FEATURE_SH_MATH is not set +# CONFIG_FEATURE_SH_MATH_64 is not set +# CONFIG_FEATURE_SH_MATH_BASE is not set +# CONFIG_FEATURE_SH_EXTRA_QUIET is not set +# CONFIG_FEATURE_SH_STANDALONE is not set +# CONFIG_FEATURE_SH_NOFORK is not set +# CONFIG_FEATURE_SH_READ_FRAC is not set +# CONFIG_FEATURE_SH_HISTFILESIZE is not set +# CONFIG_FEATURE_SH_EMBEDDED_SCRIPTS is not set + +# +# System Logging Utilities +# +# CONFIG_KLOGD is not set +# CONFIG_FEATURE_KLOGD_KLOGCTL is not set +# CONFIG_LOGGER is not set +# CONFIG_LOGREAD is not set +# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set +# CONFIG_SYSLOGD is not set +# CONFIG_FEATURE_ROTATE_LOGFILE is not set +# CONFIG_FEATURE_REMOTE_LOG is not set +# CONFIG_FEATURE_SYSLOGD_DUP is not set +# CONFIG_FEATURE_SYSLOGD_CFG is not set +# CONFIG_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS is not set +CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0 +# CONFIG_FEATURE_IPC_SYSLOG is not set +CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 +# CONFIG_FEATURE_KMSG_SYSLOG is not set diff --git a/BUSYBOX/mips64el_hexdump.config b/BUSYBOX/mips64el_hexdump.config new file mode 100644 index 0000000..70cfa69 --- /dev/null +++ b/BUSYBOX/mips64el_hexdump.config @@ -0,0 +1,1166 @@ +# +# Automatically generated make config: don't edit +# Busybox version: 1.32.0 +# Thu Mar 4 13:08:09 2021 +# +CONFIG_HAVE_DOT_CONFIG=y + +# +# Settings +# +# CONFIG_DESKTOP is not set +# CONFIG_EXTRA_COMPAT is not set +# CONFIG_FEDORA_COMPAT is not set +# CONFIG_INCLUDE_SUSv2 is not set +# CONFIG_LONG_OPTS is not set +# CONFIG_SHOW_USAGE is not set +# CONFIG_FEATURE_VERBOSE_USAGE is not set +# CONFIG_FEATURE_COMPRESS_USAGE is not set +# CONFIG_LFS is not set +# CONFIG_PAM is not set +# CONFIG_FEATURE_DEVPTS is not set +# CONFIG_FEATURE_UTMP is not set +# CONFIG_FEATURE_WTMP is not set +# CONFIG_FEATURE_PIDFILE is not set +CONFIG_PID_FILE_PATH="" +# CONFIG_BUSYBOX is not set +# CONFIG_FEATURE_SHOW_SCRIPT is not set +# CONFIG_FEATURE_INSTALLER is not set +# CONFIG_INSTALL_NO_USR is not set +# CONFIG_FEATURE_SUID is not set +# CONFIG_FEATURE_SUID_CONFIG is not set +# CONFIG_FEATURE_SUID_CONFIG_QUIET is not set +# CONFIG_FEATURE_PREFER_APPLETS is not set +CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" +# CONFIG_SELINUX is not set +# CONFIG_FEATURE_CLEAN_UP is not set +# CONFIG_FEATURE_SYSLOG_INFO is not set +# CONFIG_FEATURE_SYSLOG is not set +# CONFIG_PLATFORM_LINUX is not set + +# +# Build Options +# +CONFIG_STATIC=y +# CONFIG_PIE is not set +# CONFIG_NOMMU is not set +# CONFIG_BUILD_LIBBUSYBOX is not set +# CONFIG_FEATURE_LIBBUSYBOX_STATIC is not set +# CONFIG_FEATURE_INDIVIDUAL is not set +# CONFIG_FEATURE_SHARED_BUSYBOX is not set +CONFIG_CROSS_COMPILER_PREFIX="" +CONFIG_SYSROOT="" +CONFIG_EXTRA_CFLAGS="" +CONFIG_EXTRA_LDFLAGS="" +CONFIG_EXTRA_LDLIBS="" +# CONFIG_USE_PORTABLE_CODE is not set +# CONFIG_STACK_OPTIMIZATION_386 is not set + +# +# Installation Options ("make install" behavior) +# +CONFIG_INSTALL_APPLET_SYMLINKS=y +# CONFIG_INSTALL_APPLET_HARDLINKS is not set +# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set +# CONFIG_INSTALL_APPLET_DONT is not set +# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set +# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set +# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set +CONFIG_PREFIX="./_install" + +# +# Debugging Options +# +# CONFIG_DEBUG is not set +# CONFIG_DEBUG_PESSIMIZE is not set +# CONFIG_DEBUG_SANITIZE is not set +# CONFIG_UNIT_TEST is not set +# CONFIG_WERROR is not set +# CONFIG_WARN_SIMPLE_MSG is not set +CONFIG_NO_DEBUG_LIB=y +# CONFIG_DMALLOC is not set +# CONFIG_EFENCE is not set + +# +# Library Tuning +# +# CONFIG_FEATURE_USE_BSS_TAIL is not set +# CONFIG_FLOAT_DURATION is not set +# CONFIG_FEATURE_RTMINMAX is not set +# CONFIG_FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS is not set +CONFIG_FEATURE_BUFFERS_USE_MALLOC=y +# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set +# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set +CONFIG_PASSWORD_MINLEN=6 +CONFIG_MD5_SMALL=1 +CONFIG_SHA3_SMALL=1 +# CONFIG_FEATURE_FAST_TOP is not set +# CONFIG_FEATURE_ETC_NETWORKS is not set +# CONFIG_FEATURE_ETC_SERVICES is not set +# CONFIG_FEATURE_EDITING is not set +CONFIG_FEATURE_EDITING_MAX_LEN=0 +# CONFIG_FEATURE_EDITING_VI is not set +CONFIG_FEATURE_EDITING_HISTORY=0 +# CONFIG_FEATURE_EDITING_SAVEHISTORY is not set +# CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set +# CONFIG_FEATURE_REVERSE_SEARCH is not set +# CONFIG_FEATURE_TAB_COMPLETION is not set +# CONFIG_FEATURE_USERNAME_COMPLETION is not set +# CONFIG_FEATURE_EDITING_FANCY_PROMPT is not set +# CONFIG_FEATURE_EDITING_WINCH is not set +# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set +# CONFIG_LOCALE_SUPPORT is not set +# CONFIG_UNICODE_SUPPORT is not set +# CONFIG_UNICODE_USING_LOCALE is not set +# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set +CONFIG_SUBST_WCHAR=0 +CONFIG_LAST_SUPPORTED_WCHAR=0 +# CONFIG_UNICODE_COMBINING_WCHARS is not set +# CONFIG_UNICODE_WIDE_WCHARS is not set +# CONFIG_UNICODE_BIDI_SUPPORT is not set +# CONFIG_UNICODE_NEUTRAL_TABLE is not set +# CONFIG_UNICODE_PRESERVE_BROKEN is not set +# CONFIG_FEATURE_NON_POSIX_CP is not set +# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set +# CONFIG_FEATURE_USE_SENDFILE is not set +CONFIG_FEATURE_COPYBUF_KB=4 +# CONFIG_FEATURE_SKIP_ROOTFS is not set +# CONFIG_MONOTONIC_SYSCALL is not set +# CONFIG_IOCTL_HEX2STR_ERROR is not set +# CONFIG_FEATURE_HWIB is not set + +# +# Applets +# + +# +# Archival Utilities +# +# CONFIG_FEATURE_SEAMLESS_XZ is not set +# CONFIG_FEATURE_SEAMLESS_LZMA is not set +# CONFIG_FEATURE_SEAMLESS_BZ2 is not set +# CONFIG_FEATURE_SEAMLESS_GZ is not set +# CONFIG_FEATURE_SEAMLESS_Z is not set +# CONFIG_AR is not set +# CONFIG_FEATURE_AR_LONG_FILENAMES is not set +# CONFIG_FEATURE_AR_CREATE is not set +# CONFIG_UNCOMPRESS is not set +# CONFIG_GUNZIP is not set +# CONFIG_ZCAT is not set +# CONFIG_FEATURE_GUNZIP_LONG_OPTIONS is not set +# CONFIG_BUNZIP2 is not set +# CONFIG_BZCAT is not set +# CONFIG_UNLZMA is not set +# CONFIG_LZCAT is not set +# CONFIG_LZMA is not set +# CONFIG_UNXZ is not set +# CONFIG_XZCAT is not set +# CONFIG_XZ is not set +# CONFIG_BZIP2 is not set +CONFIG_BZIP2_SMALL=0 +# CONFIG_FEATURE_BZIP2_DECOMPRESS is not set +# CONFIG_CPIO is not set +# CONFIG_FEATURE_CPIO_O is not set +# CONFIG_FEATURE_CPIO_P is not set +# CONFIG_DPKG is not set +# CONFIG_DPKG_DEB is not set +# CONFIG_GZIP is not set +# CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set +CONFIG_GZIP_FAST=0 +# CONFIG_FEATURE_GZIP_LEVELS is not set +# CONFIG_FEATURE_GZIP_DECOMPRESS is not set +# CONFIG_LZOP is not set +# CONFIG_UNLZOP is not set +# CONFIG_LZOPCAT is not set +# CONFIG_LZOP_COMPR_HIGH is not set +# CONFIG_RPM is not set +# CONFIG_RPM2CPIO is not set +# CONFIG_TAR is not set +# CONFIG_FEATURE_TAR_LONG_OPTIONS is not set +# CONFIG_FEATURE_TAR_CREATE is not set +# CONFIG_FEATURE_TAR_AUTODETECT is not set +# CONFIG_FEATURE_TAR_FROM is not set +# CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_GNU_EXTENSIONS is not set +# CONFIG_FEATURE_TAR_TO_COMMAND is not set +# CONFIG_FEATURE_TAR_UNAME_GNAME is not set +# CONFIG_FEATURE_TAR_NOPRESERVE_TIME is not set +# CONFIG_FEATURE_TAR_SELINUX is not set +# CONFIG_UNZIP is not set +# CONFIG_FEATURE_UNZIP_CDF is not set +# CONFIG_FEATURE_UNZIP_BZIP2 is not set +# CONFIG_FEATURE_UNZIP_LZMA is not set +# CONFIG_FEATURE_UNZIP_XZ is not set +# CONFIG_FEATURE_LZMA_FAST is not set + +# +# Coreutils +# +# CONFIG_BASENAME is not set +# CONFIG_CAT is not set +# CONFIG_FEATURE_CATN is not set +# CONFIG_FEATURE_CATV is not set +# CONFIG_CHGRP is not set +# CONFIG_CHMOD is not set +# CONFIG_CHOWN is not set +# CONFIG_FEATURE_CHOWN_LONG_OPTIONS is not set +# CONFIG_CHROOT is not set +# CONFIG_CKSUM is not set +# CONFIG_COMM is not set +# CONFIG_CP is not set +# CONFIG_FEATURE_CP_LONG_OPTIONS is not set +# CONFIG_FEATURE_CP_REFLINK is not set +# CONFIG_CUT is not set +# CONFIG_DATE is not set +# CONFIG_FEATURE_DATE_ISOFMT is not set +# CONFIG_FEATURE_DATE_NANO is not set +# CONFIG_FEATURE_DATE_COMPAT is not set +# CONFIG_DD is not set +# CONFIG_FEATURE_DD_SIGNAL_HANDLING is not set +# CONFIG_FEATURE_DD_THIRD_STATUS_LINE is not set +# CONFIG_FEATURE_DD_IBS_OBS is not set +# CONFIG_FEATURE_DD_STATUS is not set +# CONFIG_DF is not set +# CONFIG_FEATURE_DF_FANCY is not set +# CONFIG_DIRNAME is not set +# CONFIG_DOS2UNIX is not set +# CONFIG_UNIX2DOS is not set +# CONFIG_DU is not set +# CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K is not set +# CONFIG_ECHO is not set +# CONFIG_FEATURE_FANCY_ECHO is not set +# CONFIG_ENV is not set +# CONFIG_EXPAND is not set +# CONFIG_UNEXPAND is not set +# CONFIG_EXPR is not set +# CONFIG_EXPR_MATH_SUPPORT_64 is not set +# CONFIG_FACTOR is not set +# CONFIG_FALSE is not set +# CONFIG_FOLD is not set +# CONFIG_HEAD is not set +# CONFIG_FEATURE_FANCY_HEAD is not set +# CONFIG_HOSTID is not set +# CONFIG_ID is not set +# CONFIG_GROUPS is not set +# CONFIG_INSTALL is not set +# CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set +# CONFIG_LINK is not set +# CONFIG_LN is not set +# CONFIG_LOGNAME is not set +# CONFIG_LS is not set +# CONFIG_FEATURE_LS_FILETYPES is not set +# CONFIG_FEATURE_LS_FOLLOWLINKS is not set +# CONFIG_FEATURE_LS_RECURSIVE is not set +# CONFIG_FEATURE_LS_WIDTH is not set +# CONFIG_FEATURE_LS_SORTFILES is not set +# CONFIG_FEATURE_LS_TIMESTAMPS is not set +# CONFIG_FEATURE_LS_USERNAME is not set +# CONFIG_FEATURE_LS_COLOR is not set +# CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set +# CONFIG_MD5SUM is not set +# CONFIG_SHA1SUM is not set +# CONFIG_SHA256SUM is not set +# CONFIG_SHA512SUM is not set +# CONFIG_SHA3SUM is not set +# CONFIG_FEATURE_MD5_SHA1_SUM_CHECK is not set +# CONFIG_MKDIR is not set +# CONFIG_MKFIFO is not set +# CONFIG_MKNOD is not set +# CONFIG_MKTEMP is not set +# CONFIG_MV is not set +# CONFIG_NICE is not set +# CONFIG_NL is not set +# CONFIG_NOHUP is not set +# CONFIG_NPROC is not set +# CONFIG_OD is not set +# CONFIG_PASTE is not set +# CONFIG_PRINTENV is not set +# CONFIG_PRINTF is not set +# CONFIG_PWD is not set +# CONFIG_READLINK is not set +# CONFIG_FEATURE_READLINK_FOLLOW is not set +# CONFIG_REALPATH is not set +# CONFIG_RM is not set +# CONFIG_RMDIR is not set +# CONFIG_SEQ is not set +# CONFIG_SHRED is not set +# CONFIG_SHUF is not set +# CONFIG_SLEEP is not set +# CONFIG_FEATURE_FANCY_SLEEP is not set +# CONFIG_SORT is not set +# CONFIG_FEATURE_SORT_BIG is not set +# CONFIG_FEATURE_SORT_OPTIMIZE_MEMORY is not set +# CONFIG_SPLIT is not set +# CONFIG_FEATURE_SPLIT_FANCY is not set +# CONFIG_STAT is not set +# CONFIG_FEATURE_STAT_FORMAT is not set +# CONFIG_FEATURE_STAT_FILESYSTEM is not set +# CONFIG_STTY is not set +# CONFIG_SUM is not set +# CONFIG_SYNC is not set +# CONFIG_FEATURE_SYNC_FANCY is not set +# CONFIG_FSYNC is not set +# CONFIG_TAC is not set +# CONFIG_TAIL is not set +# CONFIG_FEATURE_FANCY_TAIL is not set +# CONFIG_TEE is not set +# CONFIG_FEATURE_TEE_USE_BLOCK_IO is not set +# CONFIG_TEST is not set +# CONFIG_TEST1 is not set +# CONFIG_TEST2 is not set +# CONFIG_FEATURE_TEST_64 is not set +# CONFIG_TIMEOUT is not set +# CONFIG_TOUCH is not set +# CONFIG_FEATURE_TOUCH_NODEREF is not set +# CONFIG_FEATURE_TOUCH_SUSV3 is not set +# CONFIG_TR is not set +# CONFIG_FEATURE_TR_CLASSES is not set +# CONFIG_FEATURE_TR_EQUIV is not set +# CONFIG_TRUE is not set +# CONFIG_TRUNCATE is not set +# CONFIG_TTY is not set +# CONFIG_UNAME is not set +CONFIG_UNAME_OSNAME="" +# CONFIG_BB_ARCH is not set +# CONFIG_UNIQ is not set +# CONFIG_UNLINK is not set +# CONFIG_USLEEP is not set +# CONFIG_UUDECODE is not set +# CONFIG_BASE64 is not set +# CONFIG_UUENCODE is not set +# CONFIG_WC is not set +# CONFIG_FEATURE_WC_LARGE is not set +# CONFIG_WHOAMI is not set +# CONFIG_WHO is not set +# CONFIG_W is not set +# CONFIG_USERS is not set +# CONFIG_YES is not set + +# +# Common options +# +# CONFIG_FEATURE_VERBOSE is not set +# CONFIG_FEATURE_PRESERVE_HARDLINKS is not set +# CONFIG_FEATURE_HUMAN_READABLE is not set + +# +# Console Utilities +# +# CONFIG_CHVT is not set +# CONFIG_CLEAR is not set +# CONFIG_DEALLOCVT is not set +# CONFIG_DUMPKMAP is not set +# CONFIG_FGCONSOLE is not set +# CONFIG_KBD_MODE is not set +# CONFIG_LOADFONT is not set +# CONFIG_SETFONT is not set +# CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set +CONFIG_DEFAULT_SETFONT_DIR="" +# CONFIG_FEATURE_LOADFONT_PSF2 is not set +# CONFIG_FEATURE_LOADFONT_RAW is not set +# CONFIG_LOADKMAP is not set +# CONFIG_OPENVT is not set +# CONFIG_RESET is not set +# CONFIG_RESIZE is not set +# CONFIG_FEATURE_RESIZE_PRINT is not set +# CONFIG_SETCONSOLE is not set +# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set +# CONFIG_SETKEYCODES is not set +# CONFIG_SETLOGCONS is not set +# CONFIG_SHOWKEY is not set + +# +# Debian Utilities +# +# CONFIG_PIPE_PROGRESS is not set +# CONFIG_RUN_PARTS is not set +# CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set +# CONFIG_FEATURE_RUN_PARTS_FANCY is not set +# CONFIG_START_STOP_DAEMON is not set +# CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set +# CONFIG_FEATURE_START_STOP_DAEMON_FANCY is not set +# CONFIG_WHICH is not set + +# +# klibc-utils +# +# CONFIG_MINIPS is not set +# CONFIG_NUKE is not set +# CONFIG_RESUME is not set +# CONFIG_RUN_INIT is not set + +# +# Editors +# +# CONFIG_AWK is not set +# CONFIG_FEATURE_AWK_LIBM is not set +# CONFIG_FEATURE_AWK_GNU_EXTENSIONS is not set +# CONFIG_CMP is not set +# CONFIG_DIFF is not set +# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set +# CONFIG_FEATURE_DIFF_DIR is not set +# CONFIG_ED is not set +# CONFIG_PATCH is not set +# CONFIG_SED is not set +# CONFIG_VI is not set +CONFIG_FEATURE_VI_MAX_LEN=0 +# CONFIG_FEATURE_VI_8BIT is not set +# CONFIG_FEATURE_VI_COLON is not set +# CONFIG_FEATURE_VI_YANKMARK is not set +# CONFIG_FEATURE_VI_SEARCH is not set +# CONFIG_FEATURE_VI_REGEX_SEARCH is not set +# CONFIG_FEATURE_VI_USE_SIGNALS is not set +# CONFIG_FEATURE_VI_DOT_CMD is not set +# CONFIG_FEATURE_VI_READONLY is not set +# CONFIG_FEATURE_VI_SETOPTS is not set +# CONFIG_FEATURE_VI_SET is not set +# CONFIG_FEATURE_VI_WIN_RESIZE is not set +# CONFIG_FEATURE_VI_ASK_TERMINAL is not set +# CONFIG_FEATURE_VI_UNDO is not set +# CONFIG_FEATURE_VI_UNDO_QUEUE is not set +CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=0 +# CONFIG_FEATURE_ALLOW_EXEC is not set + +# +# Finding Utilities +# +# CONFIG_FIND is not set +# CONFIG_FEATURE_FIND_PRINT0 is not set +# CONFIG_FEATURE_FIND_MTIME is not set +# CONFIG_FEATURE_FIND_MMIN is not set +# CONFIG_FEATURE_FIND_PERM is not set +# CONFIG_FEATURE_FIND_TYPE is not set +# CONFIG_FEATURE_FIND_EXECUTABLE is not set +# CONFIG_FEATURE_FIND_XDEV is not set +# CONFIG_FEATURE_FIND_MAXDEPTH is not set +# CONFIG_FEATURE_FIND_NEWER is not set +# CONFIG_FEATURE_FIND_INUM is not set +# CONFIG_FEATURE_FIND_EXEC is not set +# CONFIG_FEATURE_FIND_EXEC_PLUS is not set +# CONFIG_FEATURE_FIND_USER is not set +# CONFIG_FEATURE_FIND_GROUP is not set +# CONFIG_FEATURE_FIND_NOT is not set +# CONFIG_FEATURE_FIND_DEPTH is not set +# CONFIG_FEATURE_FIND_PAREN is not set +# CONFIG_FEATURE_FIND_SIZE is not set +# CONFIG_FEATURE_FIND_PRUNE is not set +# CONFIG_FEATURE_FIND_QUIT is not set +# CONFIG_FEATURE_FIND_DELETE is not set +# CONFIG_FEATURE_FIND_EMPTY is not set +# CONFIG_FEATURE_FIND_PATH is not set +# CONFIG_FEATURE_FIND_REGEX is not set +# CONFIG_FEATURE_FIND_CONTEXT is not set +# CONFIG_FEATURE_FIND_LINKS is not set +# CONFIG_GREP is not set +# CONFIG_EGREP is not set +# CONFIG_FGREP is not set +# CONFIG_FEATURE_GREP_CONTEXT is not set +# CONFIG_XARGS is not set +# CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION is not set +# CONFIG_FEATURE_XARGS_SUPPORT_QUOTES is not set +# CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM is not set +# CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR is not set +# CONFIG_FEATURE_XARGS_SUPPORT_PARALLEL is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ARGS_FILE is not set + +# +# Init Utilities +# +# CONFIG_BOOTCHARTD is not set +# CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set +# CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set +# CONFIG_HALT is not set +# CONFIG_POWEROFF is not set +# CONFIG_REBOOT is not set +# CONFIG_FEATURE_WAIT_FOR_INIT is not set +# CONFIG_FEATURE_CALL_TELINIT is not set +CONFIG_TELINIT_PATH="" +# CONFIG_INIT is not set +# CONFIG_LINUXRC is not set +# CONFIG_FEATURE_USE_INITTAB is not set +# CONFIG_FEATURE_KILL_REMOVED is not set +CONFIG_FEATURE_KILL_DELAY=0 +# CONFIG_FEATURE_INIT_SCTTY is not set +# CONFIG_FEATURE_INIT_SYSLOG is not set +# CONFIG_FEATURE_INIT_QUIET is not set +# CONFIG_FEATURE_INIT_COREDUMPS is not set +CONFIG_INIT_TERMINAL_TYPE="" +# CONFIG_FEATURE_INIT_MODIFY_CMDLINE is not set + +# +# Login/Password Management Utilities +# +# CONFIG_FEATURE_SHADOWPASSWDS is not set +# CONFIG_USE_BB_PWD_GRP is not set +# CONFIG_USE_BB_SHADOW is not set +# CONFIG_USE_BB_CRYPT is not set +# CONFIG_USE_BB_CRYPT_SHA is not set +# CONFIG_ADDGROUP is not set +# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set +# CONFIG_ADD_SHELL is not set +# CONFIG_REMOVE_SHELL is not set +# CONFIG_ADDUSER is not set +# CONFIG_FEATURE_CHECK_NAMES is not set +CONFIG_LAST_ID=0 +CONFIG_FIRST_SYSTEM_ID=0 +CONFIG_LAST_SYSTEM_ID=0 +# CONFIG_CHPASSWD is not set +CONFIG_FEATURE_DEFAULT_PASSWD_ALGO="" +# CONFIG_CRYPTPW is not set +# CONFIG_MKPASSWD is not set +# CONFIG_DELUSER is not set +# CONFIG_DELGROUP is not set +# CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set +# CONFIG_GETTY is not set +# CONFIG_LOGIN is not set +# CONFIG_LOGIN_SESSION_AS_CHILD is not set +# CONFIG_LOGIN_SCRIPTS is not set +# CONFIG_FEATURE_NOLOGIN is not set +# CONFIG_FEATURE_SECURETTY is not set +# CONFIG_PASSWD is not set +# CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set +# CONFIG_SU is not set +# CONFIG_FEATURE_SU_SYSLOG is not set +# CONFIG_FEATURE_SU_CHECKS_SHELLS is not set +# CONFIG_FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY is not set +# CONFIG_SULOGIN is not set +# CONFIG_VLOCK is not set + +# +# Linux Ext2 FS Progs +# +# CONFIG_CHATTR is not set +# CONFIG_FSCK is not set +# CONFIG_LSATTR is not set +# CONFIG_TUNE2FS is not set + +# +# Linux Module Utilities +# +# CONFIG_MODPROBE_SMALL is not set +# CONFIG_DEPMOD is not set +# CONFIG_INSMOD is not set +# CONFIG_LSMOD is not set +# CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set +# CONFIG_MODINFO is not set +# CONFIG_MODPROBE is not set +# CONFIG_FEATURE_MODPROBE_BLACKLIST is not set +# CONFIG_RMMOD is not set + +# +# Options common to multiple modutils +# +# CONFIG_FEATURE_CMDLINE_MODULE_OPTIONS is not set +# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set +# CONFIG_FEATURE_2_4_MODULES is not set +# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set +# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set +# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set +# CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set +# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set +# CONFIG_FEATURE_MODUTILS_ALIAS is not set +# CONFIG_FEATURE_MODUTILS_SYMBOLS is not set +CONFIG_DEFAULT_MODULES_DIR="" +CONFIG_DEFAULT_DEPMOD_FILE="" + +# +# Linux System Utilities +# +# CONFIG_ACPID is not set +# CONFIG_FEATURE_ACPID_COMPAT is not set +# CONFIG_BLKDISCARD is not set +# CONFIG_BLKID is not set +# CONFIG_FEATURE_BLKID_TYPE is not set +# CONFIG_BLOCKDEV is not set +# CONFIG_CAL is not set +# CONFIG_CHRT is not set +# CONFIG_DMESG is not set +# CONFIG_FEATURE_DMESG_PRETTY is not set +# CONFIG_EJECT is not set +# CONFIG_FEATURE_EJECT_SCSI is not set +# CONFIG_FALLOCATE is not set +# CONFIG_FATATTR is not set +# CONFIG_FBSET is not set +# CONFIG_FEATURE_FBSET_FANCY is not set +# CONFIG_FEATURE_FBSET_READMODE is not set +# CONFIG_FDFORMAT is not set +# CONFIG_FDISK is not set +# CONFIG_FDISK_SUPPORT_LARGE_DISKS is not set +# CONFIG_FEATURE_FDISK_WRITABLE is not set +# CONFIG_FEATURE_AIX_LABEL is not set +# CONFIG_FEATURE_SGI_LABEL is not set +# CONFIG_FEATURE_SUN_LABEL is not set +# CONFIG_FEATURE_OSF_LABEL is not set +# CONFIG_FEATURE_GPT_LABEL is not set +# CONFIG_FEATURE_FDISK_ADVANCED is not set +# CONFIG_FINDFS is not set +# CONFIG_FLOCK is not set +# CONFIG_FDFLUSH is not set +# CONFIG_FREERAMDISK is not set +# CONFIG_FSCK_MINIX is not set +# CONFIG_FSFREEZE is not set +# CONFIG_FSTRIM is not set +# CONFIG_GETOPT is not set +# CONFIG_FEATURE_GETOPT_LONG is not set +CONFIG_HEXDUMP=y +CONFIG_FEATURE_HEXDUMP_REVERSE=y +# CONFIG_HD is not set +# CONFIG_XXD is not set +# CONFIG_HWCLOCK is not set +# CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set +# CONFIG_IONICE is not set +# CONFIG_IPCRM is not set +# CONFIG_IPCS is not set +# CONFIG_LAST is not set +# CONFIG_FEATURE_LAST_FANCY is not set +# CONFIG_LOSETUP is not set +# CONFIG_LSPCI is not set +# CONFIG_LSUSB is not set +# CONFIG_MDEV is not set +# CONFIG_FEATURE_MDEV_CONF is not set +# CONFIG_FEATURE_MDEV_RENAME is not set +# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set +# CONFIG_FEATURE_MDEV_EXEC is not set +# CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set +# CONFIG_FEATURE_MDEV_DAEMON is not set +# CONFIG_MESG is not set +# CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP is not set +# CONFIG_MKE2FS is not set +# CONFIG_MKFS_EXT2 is not set +# CONFIG_MKFS_MINIX is not set +# CONFIG_FEATURE_MINIX2 is not set +# CONFIG_MKFS_REISER is not set +# CONFIG_MKDOSFS is not set +# CONFIG_MKFS_VFAT is not set +# CONFIG_MKSWAP is not set +# CONFIG_FEATURE_MKSWAP_UUID is not set +# CONFIG_MORE is not set +# CONFIG_MOUNT is not set +# CONFIG_FEATURE_MOUNT_FAKE is not set +# CONFIG_FEATURE_MOUNT_VERBOSE is not set +# CONFIG_FEATURE_MOUNT_HELPERS is not set +# CONFIG_FEATURE_MOUNT_LABEL is not set +# CONFIG_FEATURE_MOUNT_NFS is not set +# CONFIG_FEATURE_MOUNT_CIFS is not set +# CONFIG_FEATURE_MOUNT_FLAGS is not set +# CONFIG_FEATURE_MOUNT_FSTAB is not set +# CONFIG_FEATURE_MOUNT_OTHERTAB is not set +# CONFIG_MOUNTPOINT is not set +# CONFIG_NOLOGIN is not set +# CONFIG_NOLOGIN_DEPENDENCIES is not set +# CONFIG_NSENTER is not set +# CONFIG_PIVOT_ROOT is not set +# CONFIG_RDATE is not set +# CONFIG_RDEV is not set +# CONFIG_READPROFILE is not set +# CONFIG_RENICE is not set +# CONFIG_REV is not set +# CONFIG_RTCWAKE is not set +# CONFIG_SCRIPT is not set +# CONFIG_SCRIPTREPLAY is not set +# CONFIG_SETARCH is not set +# CONFIG_LINUX32 is not set +# CONFIG_LINUX64 is not set +# CONFIG_SETPRIV is not set +# CONFIG_FEATURE_SETPRIV_DUMP is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITIES is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITY_NAMES is not set +# CONFIG_SETSID is not set +# CONFIG_SWAPON is not set +# CONFIG_FEATURE_SWAPON_DISCARD is not set +# CONFIG_FEATURE_SWAPON_PRI is not set +# CONFIG_SWAPOFF is not set +# CONFIG_FEATURE_SWAPONOFF_LABEL is not set +# CONFIG_SWITCH_ROOT is not set +# CONFIG_TASKSET is not set +# CONFIG_FEATURE_TASKSET_FANCY is not set +# CONFIG_FEATURE_TASKSET_CPULIST is not set +# CONFIG_UEVENT is not set +# CONFIG_UMOUNT is not set +# CONFIG_FEATURE_UMOUNT_ALL is not set +# CONFIG_UNSHARE is not set +# CONFIG_WALL is not set +# CONFIG_FEATURE_MOUNT_LOOP is not set +# CONFIG_FEATURE_MOUNT_LOOP_CREATE is not set +# CONFIG_FEATURE_MTAB_SUPPORT is not set +# CONFIG_VOLUMEID is not set +# CONFIG_FEATURE_VOLUMEID_BCACHE is not set +# CONFIG_FEATURE_VOLUMEID_BTRFS is not set +# CONFIG_FEATURE_VOLUMEID_CRAMFS is not set +# CONFIG_FEATURE_VOLUMEID_EXFAT is not set +# CONFIG_FEATURE_VOLUMEID_EXT is not set +# CONFIG_FEATURE_VOLUMEID_F2FS is not set +# CONFIG_FEATURE_VOLUMEID_FAT is not set +# CONFIG_FEATURE_VOLUMEID_HFS is not set +# CONFIG_FEATURE_VOLUMEID_ISO9660 is not set +# CONFIG_FEATURE_VOLUMEID_JFS is not set +# CONFIG_FEATURE_VOLUMEID_LFS is not set +# CONFIG_FEATURE_VOLUMEID_LINUXRAID is not set +# CONFIG_FEATURE_VOLUMEID_LINUXSWAP is not set +# CONFIG_FEATURE_VOLUMEID_LUKS is not set +# CONFIG_FEATURE_VOLUMEID_MINIX is not set +# CONFIG_FEATURE_VOLUMEID_NILFS is not set +# CONFIG_FEATURE_VOLUMEID_NTFS is not set +# CONFIG_FEATURE_VOLUMEID_OCFS2 is not set +# CONFIG_FEATURE_VOLUMEID_REISERFS is not set +# CONFIG_FEATURE_VOLUMEID_ROMFS is not set +# CONFIG_FEATURE_VOLUMEID_SQUASHFS is not set +# CONFIG_FEATURE_VOLUMEID_SYSV is not set +# CONFIG_FEATURE_VOLUMEID_UBIFS is not set +# CONFIG_FEATURE_VOLUMEID_UDF is not set +# CONFIG_FEATURE_VOLUMEID_XFS is not set + +# +# Miscellaneous Utilities +# +# CONFIG_ADJTIMEX is not set +# CONFIG_BBCONFIG is not set +# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set +# CONFIG_BC is not set +# CONFIG_DC is not set +# CONFIG_FEATURE_DC_BIG is not set +# CONFIG_FEATURE_DC_LIBM is not set +# CONFIG_FEATURE_BC_INTERACTIVE is not set +# CONFIG_FEATURE_BC_LONG_OPTIONS is not set +# CONFIG_BEEP is not set +CONFIG_FEATURE_BEEP_FREQ=0 +CONFIG_FEATURE_BEEP_LENGTH_MS=0 +# CONFIG_CHAT is not set +# CONFIG_FEATURE_CHAT_NOFAIL is not set +# CONFIG_FEATURE_CHAT_TTY_HIFI is not set +# CONFIG_FEATURE_CHAT_IMPLICIT_CR is not set +# CONFIG_FEATURE_CHAT_SWALLOW_OPTS is not set +# CONFIG_FEATURE_CHAT_SEND_ESCAPES is not set +# CONFIG_FEATURE_CHAT_VAR_ABORT_LEN is not set +# CONFIG_FEATURE_CHAT_CLR_ABORT is not set +# CONFIG_CONSPY is not set +# CONFIG_CROND is not set +# CONFIG_FEATURE_CROND_D is not set +# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set +# CONFIG_FEATURE_CROND_SPECIAL_TIMES is not set +CONFIG_FEATURE_CROND_DIR="" +# CONFIG_CRONTAB is not set +# CONFIG_DEVFSD is not set +# CONFIG_DEVFSD_MODLOAD is not set +# CONFIG_DEVFSD_FG_NP is not set +# CONFIG_DEVFSD_VERBOSE is not set +# CONFIG_FEATURE_DEVFS is not set +# CONFIG_DEVMEM is not set +# CONFIG_FBSPLASH is not set +# CONFIG_FLASHCP is not set +# CONFIG_FLASH_ERASEALL is not set +# CONFIG_FLASH_LOCK is not set +# CONFIG_FLASH_UNLOCK is not set +# CONFIG_HDPARM is not set +# CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set +# CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set +# CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set +# CONFIG_HEXEDIT is not set +# CONFIG_I2CGET is not set +# CONFIG_I2CSET is not set +# CONFIG_I2CDUMP is not set +# CONFIG_I2CDETECT is not set +# CONFIG_I2CTRANSFER is not set +# CONFIG_INOTIFYD is not set +# CONFIG_LESS is not set +CONFIG_FEATURE_LESS_MAXLINES=0 +# CONFIG_FEATURE_LESS_BRACKETS is not set +# CONFIG_FEATURE_LESS_FLAGS is not set +# CONFIG_FEATURE_LESS_TRUNCATE is not set +# CONFIG_FEATURE_LESS_MARKS is not set +# CONFIG_FEATURE_LESS_REGEXP is not set +# CONFIG_FEATURE_LESS_WINCH is not set +# CONFIG_FEATURE_LESS_ASK_TERMINAL is not set +# CONFIG_FEATURE_LESS_DASHCMD is not set +# CONFIG_FEATURE_LESS_LINENUMS is not set +# CONFIG_FEATURE_LESS_RAW is not set +# CONFIG_FEATURE_LESS_ENV is not set +# CONFIG_LSSCSI is not set +# CONFIG_MAKEDEVS is not set +# CONFIG_FEATURE_MAKEDEVS_LEAF is not set +# CONFIG_FEATURE_MAKEDEVS_TABLE is not set +# CONFIG_MAN is not set +# CONFIG_MICROCOM is not set +# CONFIG_MIM is not set +# CONFIG_MT is not set +# CONFIG_NANDWRITE is not set +# CONFIG_NANDDUMP is not set +# CONFIG_PARTPROBE is not set +# CONFIG_RAIDAUTORUN is not set +# CONFIG_READAHEAD is not set +# CONFIG_RFKILL is not set +# CONFIG_RUNLEVEL is not set +# CONFIG_RX is not set +# CONFIG_SETFATTR is not set +# CONFIG_SETSERIAL is not set +# CONFIG_STRINGS is not set +# CONFIG_TIME is not set +# CONFIG_TS is not set +# CONFIG_TTYSIZE is not set +# CONFIG_UBIRENAME is not set +# CONFIG_UBIATTACH is not set +# CONFIG_UBIDETACH is not set +# CONFIG_UBIMKVOL is not set +# CONFIG_UBIRMVOL is not set +# CONFIG_UBIRSVOL is not set +# CONFIG_UBIUPDATEVOL is not set +# CONFIG_VOLNAME is not set +# CONFIG_WATCHDOG is not set + +# +# Networking Utilities +# +# CONFIG_FEATURE_IPV6 is not set +# CONFIG_FEATURE_UNIX_LOCAL is not set +# CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set +# CONFIG_VERBOSE_RESOLUTION_ERRORS is not set +# CONFIG_FEATURE_TLS_SHA1 is not set +# CONFIG_ARP is not set +# CONFIG_ARPING is not set +# CONFIG_BRCTL is not set +# CONFIG_FEATURE_BRCTL_FANCY is not set +# CONFIG_FEATURE_BRCTL_SHOW is not set +# CONFIG_DNSD is not set +# CONFIG_ETHER_WAKE is not set +# CONFIG_FTPD is not set +# CONFIG_FEATURE_FTPD_WRITE is not set +# CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST is not set +# CONFIG_FEATURE_FTPD_AUTHENTICATION is not set +# CONFIG_FTPGET is not set +# CONFIG_FTPPUT is not set +# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set +# CONFIG_HOSTNAME is not set +# CONFIG_DNSDOMAINNAME is not set +# CONFIG_HTTPD is not set +# CONFIG_FEATURE_HTTPD_RANGES is not set +# CONFIG_FEATURE_HTTPD_SETUID is not set +# CONFIG_FEATURE_HTTPD_BASIC_AUTH is not set +# CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set +# CONFIG_FEATURE_HTTPD_CGI is not set +# CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set +# CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set +# CONFIG_FEATURE_HTTPD_ENCODE_URL_STR is not set +# CONFIG_FEATURE_HTTPD_ERROR_PAGES is not set +# CONFIG_FEATURE_HTTPD_PROXY is not set +# CONFIG_FEATURE_HTTPD_GZIP is not set +# CONFIG_IFCONFIG is not set +# CONFIG_FEATURE_IFCONFIG_STATUS is not set +# CONFIG_FEATURE_IFCONFIG_SLIP is not set +# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set +# CONFIG_FEATURE_IFCONFIG_HW is not set +# CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set +# CONFIG_IFENSLAVE is not set +# CONFIG_IFPLUGD is not set +# CONFIG_IFUP is not set +# CONFIG_IFDOWN is not set +CONFIG_IFUPDOWN_IFSTATE_PATH="" +# CONFIG_FEATURE_IFUPDOWN_IP is not set +# CONFIG_FEATURE_IFUPDOWN_IPV4 is not set +# CONFIG_FEATURE_IFUPDOWN_IPV6 is not set +# CONFIG_FEATURE_IFUPDOWN_MAPPING is not set +# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set +# CONFIG_INETD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set +# CONFIG_FEATURE_INETD_RPC is not set +# CONFIG_IP is not set +# CONFIG_IPADDR is not set +# CONFIG_IPLINK is not set +# CONFIG_IPROUTE is not set +# CONFIG_IPTUNNEL is not set +# CONFIG_IPRULE is not set +# CONFIG_IPNEIGH is not set +# CONFIG_FEATURE_IP_ADDRESS is not set +# CONFIG_FEATURE_IP_LINK is not set +# CONFIG_FEATURE_IP_ROUTE is not set +CONFIG_FEATURE_IP_ROUTE_DIR="" +# CONFIG_FEATURE_IP_TUNNEL is not set +# CONFIG_FEATURE_IP_RULE is not set +# CONFIG_FEATURE_IP_NEIGH is not set +# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set +# CONFIG_IPCALC is not set +# CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set +# CONFIG_FEATURE_IPCALC_FANCY is not set +# CONFIG_FAKEIDENTD is not set +# CONFIG_NAMEIF is not set +# CONFIG_FEATURE_NAMEIF_EXTENDED is not set +# CONFIG_NBDCLIENT is not set +# CONFIG_NC is not set +# CONFIG_NETCAT is not set +# CONFIG_NC_SERVER is not set +# CONFIG_NC_EXTRA is not set +# CONFIG_NC_110_COMPAT is not set +# CONFIG_NETSTAT is not set +# CONFIG_FEATURE_NETSTAT_WIDE is not set +# CONFIG_FEATURE_NETSTAT_PRG is not set +# CONFIG_NSLOOKUP is not set +# CONFIG_FEATURE_NSLOOKUP_BIG is not set +# CONFIG_FEATURE_NSLOOKUP_LONG_OPTIONS is not set +# CONFIG_NTPD is not set +# CONFIG_FEATURE_NTPD_SERVER is not set +# CONFIG_FEATURE_NTPD_CONF is not set +# CONFIG_FEATURE_NTP_AUTH is not set +# CONFIG_PING is not set +# CONFIG_PING6 is not set +# CONFIG_FEATURE_FANCY_PING is not set +# CONFIG_PSCAN is not set +# CONFIG_ROUTE is not set +# CONFIG_SLATTACH is not set +# CONFIG_SSL_CLIENT is not set +# CONFIG_TC is not set +# CONFIG_FEATURE_TC_INGRESS is not set +# CONFIG_TCPSVD is not set +# CONFIG_UDPSVD is not set +# CONFIG_TELNET is not set +# CONFIG_FEATURE_TELNET_TTYPE is not set +# CONFIG_FEATURE_TELNET_AUTOLOGIN is not set +# CONFIG_FEATURE_TELNET_WIDTH is not set +# CONFIG_TELNETD is not set +# CONFIG_FEATURE_TELNETD_STANDALONE is not set +# CONFIG_FEATURE_TELNETD_INETD_WAIT is not set +# CONFIG_TFTP is not set +# CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set +# CONFIG_FEATURE_TFTP_HPA_COMPAT is not set +# CONFIG_TFTPD is not set +# CONFIG_FEATURE_TFTP_GET is not set +# CONFIG_FEATURE_TFTP_PUT is not set +# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set +# CONFIG_TFTP_DEBUG is not set +# CONFIG_TLS is not set +# CONFIG_TRACEROUTE is not set +# CONFIG_TRACEROUTE6 is not set +# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set +# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set +# CONFIG_TUNCTL is not set +# CONFIG_FEATURE_TUNCTL_UG is not set +# CONFIG_VCONFIG is not set +# CONFIG_WGET is not set +# CONFIG_FEATURE_WGET_LONG_OPTIONS is not set +# CONFIG_FEATURE_WGET_STATUSBAR is not set +# CONFIG_FEATURE_WGET_AUTHENTICATION is not set +# CONFIG_FEATURE_WGET_TIMEOUT is not set +# CONFIG_FEATURE_WGET_HTTPS is not set +# CONFIG_FEATURE_WGET_OPENSSL is not set +# CONFIG_WHOIS is not set +# CONFIG_ZCIP is not set +# CONFIG_UDHCPD is not set +# CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC is not set +# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set +CONFIG_DHCPD_LEASES_FILE="" +# CONFIG_DUMPLEASES is not set +# CONFIG_DHCPRELAY is not set +# CONFIG_UDHCPC is not set +# CONFIG_FEATURE_UDHCPC_ARPING is not set +# CONFIG_FEATURE_UDHCPC_SANITIZEOPT is not set +CONFIG_UDHCPC_DEFAULT_SCRIPT="" +# CONFIG_UDHCPC6 is not set +# CONFIG_FEATURE_UDHCPC6_RFC3646 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4704 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4833 is not set +# CONFIG_FEATURE_UDHCPC6_RFC5970 is not set +# CONFIG_FEATURE_UDHCP_PORT is not set +CONFIG_UDHCP_DEBUG=0 +CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=0 +# CONFIG_FEATURE_UDHCP_RFC3397 is not set +# CONFIG_FEATURE_UDHCP_8021Q is not set +CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="" + +# +# Print Utilities +# +# CONFIG_LPD is not set +# CONFIG_LPR is not set +# CONFIG_LPQ is not set + +# +# Mail Utilities +# +# CONFIG_MAKEMIME is not set +# CONFIG_POPMAILDIR is not set +# CONFIG_FEATURE_POPMAILDIR_DELIVERY is not set +# CONFIG_REFORMIME is not set +# CONFIG_FEATURE_REFORMIME_COMPAT is not set +# CONFIG_SENDMAIL is not set +CONFIG_FEATURE_MIME_CHARSET="" + +# +# Process Utilities +# +# CONFIG_FREE is not set +# CONFIG_FUSER is not set +# CONFIG_IOSTAT is not set +# CONFIG_KILL is not set +# CONFIG_KILLALL is not set +# CONFIG_KILLALL5 is not set +# CONFIG_LSOF is not set +# CONFIG_MPSTAT is not set +# CONFIG_NMETER is not set +# CONFIG_PGREP is not set +# CONFIG_PKILL is not set +# CONFIG_PIDOF is not set +# CONFIG_FEATURE_PIDOF_SINGLE is not set +# CONFIG_FEATURE_PIDOF_OMIT is not set +# CONFIG_PMAP is not set +# CONFIG_POWERTOP is not set +# CONFIG_FEATURE_POWERTOP_INTERACTIVE is not set +# CONFIG_PS is not set +# CONFIG_FEATURE_PS_WIDE is not set +# CONFIG_FEATURE_PS_LONG is not set +# CONFIG_FEATURE_PS_TIME is not set +# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set +# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set +# CONFIG_PSTREE is not set +# CONFIG_PWDX is not set +# CONFIG_SMEMCAP is not set +# CONFIG_BB_SYSCTL is not set +# CONFIG_TOP is not set +# CONFIG_FEATURE_TOP_INTERACTIVE is not set +# CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE is not set +# CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS is not set +# CONFIG_FEATURE_TOP_SMP_CPU is not set +# CONFIG_FEATURE_TOP_DECIMALS is not set +# CONFIG_FEATURE_TOP_SMP_PROCESS is not set +# CONFIG_FEATURE_TOPMEM is not set +# CONFIG_UPTIME is not set +# CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set +# CONFIG_WATCH is not set +# CONFIG_FEATURE_SHOW_THREADS is not set + +# +# Runit Utilities +# +# CONFIG_CHPST is not set +# CONFIG_SETUIDGID is not set +# CONFIG_ENVUIDGID is not set +# CONFIG_ENVDIR is not set +# CONFIG_SOFTLIMIT is not set +# CONFIG_RUNSV is not set +# CONFIG_RUNSVDIR is not set +# CONFIG_FEATURE_RUNSVDIR_LOG is not set +# CONFIG_SV is not set +CONFIG_SV_DEFAULT_SERVICE_DIR="" +# CONFIG_SVC is not set +# CONFIG_SVOK is not set +# CONFIG_SVLOGD is not set +# CONFIG_CHCON is not set +# CONFIG_GETENFORCE is not set +# CONFIG_GETSEBOOL is not set +# CONFIG_LOAD_POLICY is not set +# CONFIG_MATCHPATHCON is not set +# CONFIG_RUNCON is not set +# CONFIG_SELINUXENABLED is not set +# CONFIG_SESTATUS is not set +# CONFIG_SETENFORCE is not set +# CONFIG_SETFILES is not set +# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set +# CONFIG_RESTORECON is not set +# CONFIG_SETSEBOOL is not set + +# +# Shells +# +CONFIG_SH_IS_ASH=y +# CONFIG_SH_IS_HUSH is not set +# CONFIG_SH_IS_NONE is not set +# CONFIG_BASH_IS_ASH is not set +# CONFIG_BASH_IS_HUSH is not set +CONFIG_BASH_IS_NONE=y +CONFIG_SHELL_ASH=y +# CONFIG_ASH is not set +# CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set +# CONFIG_ASH_INTERNAL_GLOB is not set +# CONFIG_ASH_BASH_COMPAT is not set +# CONFIG_ASH_BASH_SOURCE_CURDIR is not set +# CONFIG_ASH_BASH_NOT_FOUND_HOOK is not set +# CONFIG_ASH_JOB_CONTROL is not set +# CONFIG_ASH_ALIAS is not set +# CONFIG_ASH_RANDOM_SUPPORT is not set +# CONFIG_ASH_EXPAND_PRMT is not set +# CONFIG_ASH_IDLE_TIMEOUT is not set +# CONFIG_ASH_MAIL is not set +# CONFIG_ASH_ECHO is not set +# CONFIG_ASH_PRINTF is not set +# CONFIG_ASH_TEST is not set +# CONFIG_ASH_HELP is not set +# CONFIG_ASH_GETOPTS is not set +# CONFIG_ASH_CMDCMD is not set +# CONFIG_CTTYHACK is not set +# CONFIG_HUSH is not set +# CONFIG_SHELL_HUSH is not set +# CONFIG_HUSH_BASH_COMPAT is not set +# CONFIG_HUSH_BRACE_EXPANSION is not set +# CONFIG_HUSH_LINENO_VAR is not set +# CONFIG_HUSH_BASH_SOURCE_CURDIR is not set +# CONFIG_HUSH_INTERACTIVE is not set +# CONFIG_HUSH_SAVEHISTORY is not set +# CONFIG_HUSH_JOB is not set +# CONFIG_HUSH_TICK is not set +# CONFIG_HUSH_IF is not set +# CONFIG_HUSH_LOOPS is not set +# CONFIG_HUSH_CASE is not set +# CONFIG_HUSH_FUNCTIONS is not set +# CONFIG_HUSH_LOCAL is not set +# CONFIG_HUSH_RANDOM_SUPPORT is not set +# CONFIG_HUSH_MODE_X is not set +# CONFIG_HUSH_ECHO is not set +# CONFIG_HUSH_PRINTF is not set +# CONFIG_HUSH_TEST is not set +# CONFIG_HUSH_HELP is not set +# CONFIG_HUSH_EXPORT is not set +# CONFIG_HUSH_EXPORT_N is not set +# CONFIG_HUSH_READONLY is not set +# CONFIG_HUSH_KILL is not set +# CONFIG_HUSH_WAIT is not set +# CONFIG_HUSH_COMMAND is not set +# CONFIG_HUSH_TRAP is not set +# CONFIG_HUSH_TYPE is not set +# CONFIG_HUSH_TIMES is not set +# CONFIG_HUSH_READ is not set +# CONFIG_HUSH_SET is not set +# CONFIG_HUSH_UNSET is not set +# CONFIG_HUSH_ULIMIT is not set +# CONFIG_HUSH_UMASK is not set +# CONFIG_HUSH_GETOPTS is not set +# CONFIG_HUSH_MEMLEAK is not set + +# +# Options common to all shells +# +# CONFIG_FEATURE_SH_MATH is not set +# CONFIG_FEATURE_SH_MATH_64 is not set +# CONFIG_FEATURE_SH_MATH_BASE is not set +# CONFIG_FEATURE_SH_EXTRA_QUIET is not set +# CONFIG_FEATURE_SH_STANDALONE is not set +# CONFIG_FEATURE_SH_NOFORK is not set +# CONFIG_FEATURE_SH_READ_FRAC is not set +# CONFIG_FEATURE_SH_HISTFILESIZE is not set +# CONFIG_FEATURE_SH_EMBEDDED_SCRIPTS is not set + +# +# System Logging Utilities +# +# CONFIG_KLOGD is not set +# CONFIG_FEATURE_KLOGD_KLOGCTL is not set +# CONFIG_LOGGER is not set +# CONFIG_LOGREAD is not set +# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set +# CONFIG_SYSLOGD is not set +# CONFIG_FEATURE_ROTATE_LOGFILE is not set +# CONFIG_FEATURE_REMOTE_LOG is not set +# CONFIG_FEATURE_SYSLOGD_DUP is not set +# CONFIG_FEATURE_SYSLOGD_CFG is not set +# CONFIG_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS is not set +CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0 +# CONFIG_FEATURE_IPC_SYSLOG is not set +CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 +# CONFIG_FEATURE_KMSG_SYSLOG is not set diff --git a/BUSYBOX/mips64el_xzcat.config b/BUSYBOX/mips64el_xzcat.config new file mode 100644 index 0000000..8a192d3 --- /dev/null +++ b/BUSYBOX/mips64el_xzcat.config @@ -0,0 +1,1166 @@ +# +# Automatically generated make config: don't edit +# Busybox version: 1.32.0 +# Thu Mar 4 13:03:19 2021 +# +CONFIG_HAVE_DOT_CONFIG=y + +# +# Settings +# +# CONFIG_DESKTOP is not set +# CONFIG_EXTRA_COMPAT is not set +# CONFIG_FEDORA_COMPAT is not set +# CONFIG_INCLUDE_SUSv2 is not set +# CONFIG_LONG_OPTS is not set +# CONFIG_SHOW_USAGE is not set +# CONFIG_FEATURE_VERBOSE_USAGE is not set +# CONFIG_FEATURE_COMPRESS_USAGE is not set +# CONFIG_LFS is not set +# CONFIG_PAM is not set +# CONFIG_FEATURE_DEVPTS is not set +# CONFIG_FEATURE_UTMP is not set +# CONFIG_FEATURE_WTMP is not set +# CONFIG_FEATURE_PIDFILE is not set +CONFIG_PID_FILE_PATH="" +# CONFIG_BUSYBOX is not set +# CONFIG_FEATURE_SHOW_SCRIPT is not set +# CONFIG_FEATURE_INSTALLER is not set +# CONFIG_INSTALL_NO_USR is not set +# CONFIG_FEATURE_SUID is not set +# CONFIG_FEATURE_SUID_CONFIG is not set +# CONFIG_FEATURE_SUID_CONFIG_QUIET is not set +# CONFIG_FEATURE_PREFER_APPLETS is not set +CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" +# CONFIG_SELINUX is not set +# CONFIG_FEATURE_CLEAN_UP is not set +# CONFIG_FEATURE_SYSLOG_INFO is not set +# CONFIG_FEATURE_SYSLOG is not set +# CONFIG_PLATFORM_LINUX is not set + +# +# Build Options +# +CONFIG_STATIC=y +# CONFIG_PIE is not set +# CONFIG_NOMMU is not set +# CONFIG_BUILD_LIBBUSYBOX is not set +# CONFIG_FEATURE_LIBBUSYBOX_STATIC is not set +# CONFIG_FEATURE_INDIVIDUAL is not set +# CONFIG_FEATURE_SHARED_BUSYBOX is not set +CONFIG_CROSS_COMPILER_PREFIX="" +CONFIG_SYSROOT="" +CONFIG_EXTRA_CFLAGS="" +CONFIG_EXTRA_LDFLAGS="" +CONFIG_EXTRA_LDLIBS="" +# CONFIG_USE_PORTABLE_CODE is not set +# CONFIG_STACK_OPTIMIZATION_386 is not set + +# +# Installation Options ("make install" behavior) +# +CONFIG_INSTALL_APPLET_SYMLINKS=y +# CONFIG_INSTALL_APPLET_HARDLINKS is not set +# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set +# CONFIG_INSTALL_APPLET_DONT is not set +# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set +# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set +# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set +CONFIG_PREFIX="./_install" + +# +# Debugging Options +# +# CONFIG_DEBUG is not set +# CONFIG_DEBUG_PESSIMIZE is not set +# CONFIG_DEBUG_SANITIZE is not set +# CONFIG_UNIT_TEST is not set +# CONFIG_WERROR is not set +# CONFIG_WARN_SIMPLE_MSG is not set +CONFIG_NO_DEBUG_LIB=y +# CONFIG_DMALLOC is not set +# CONFIG_EFENCE is not set + +# +# Library Tuning +# +# CONFIG_FEATURE_USE_BSS_TAIL is not set +# CONFIG_FLOAT_DURATION is not set +# CONFIG_FEATURE_RTMINMAX is not set +# CONFIG_FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS is not set +CONFIG_FEATURE_BUFFERS_USE_MALLOC=y +# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set +# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set +CONFIG_PASSWORD_MINLEN=6 +CONFIG_MD5_SMALL=1 +CONFIG_SHA3_SMALL=1 +# CONFIG_FEATURE_FAST_TOP is not set +# CONFIG_FEATURE_ETC_NETWORKS is not set +# CONFIG_FEATURE_ETC_SERVICES is not set +# CONFIG_FEATURE_EDITING is not set +CONFIG_FEATURE_EDITING_MAX_LEN=0 +# CONFIG_FEATURE_EDITING_VI is not set +CONFIG_FEATURE_EDITING_HISTORY=0 +# CONFIG_FEATURE_EDITING_SAVEHISTORY is not set +# CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set +# CONFIG_FEATURE_REVERSE_SEARCH is not set +# CONFIG_FEATURE_TAB_COMPLETION is not set +# CONFIG_FEATURE_USERNAME_COMPLETION is not set +# CONFIG_FEATURE_EDITING_FANCY_PROMPT is not set +# CONFIG_FEATURE_EDITING_WINCH is not set +# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set +# CONFIG_LOCALE_SUPPORT is not set +# CONFIG_UNICODE_SUPPORT is not set +# CONFIG_UNICODE_USING_LOCALE is not set +# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set +CONFIG_SUBST_WCHAR=0 +CONFIG_LAST_SUPPORTED_WCHAR=0 +# CONFIG_UNICODE_COMBINING_WCHARS is not set +# CONFIG_UNICODE_WIDE_WCHARS is not set +# CONFIG_UNICODE_BIDI_SUPPORT is not set +# CONFIG_UNICODE_NEUTRAL_TABLE is not set +# CONFIG_UNICODE_PRESERVE_BROKEN is not set +# CONFIG_FEATURE_NON_POSIX_CP is not set +# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set +# CONFIG_FEATURE_USE_SENDFILE is not set +CONFIG_FEATURE_COPYBUF_KB=4 +# CONFIG_FEATURE_SKIP_ROOTFS is not set +# CONFIG_MONOTONIC_SYSCALL is not set +# CONFIG_IOCTL_HEX2STR_ERROR is not set +# CONFIG_FEATURE_HWIB is not set + +# +# Applets +# + +# +# Archival Utilities +# +# CONFIG_FEATURE_SEAMLESS_XZ is not set +# CONFIG_FEATURE_SEAMLESS_LZMA is not set +# CONFIG_FEATURE_SEAMLESS_BZ2 is not set +# CONFIG_FEATURE_SEAMLESS_GZ is not set +# CONFIG_FEATURE_SEAMLESS_Z is not set +# CONFIG_AR is not set +# CONFIG_FEATURE_AR_LONG_FILENAMES is not set +# CONFIG_FEATURE_AR_CREATE is not set +# CONFIG_UNCOMPRESS is not set +# CONFIG_GUNZIP is not set +# CONFIG_ZCAT is not set +# CONFIG_FEATURE_GUNZIP_LONG_OPTIONS is not set +# CONFIG_BUNZIP2 is not set +# CONFIG_BZCAT is not set +# CONFIG_UNLZMA is not set +# CONFIG_LZCAT is not set +# CONFIG_LZMA is not set +# CONFIG_UNXZ is not set +CONFIG_XZCAT=y +# CONFIG_XZ is not set +# CONFIG_BZIP2 is not set +CONFIG_BZIP2_SMALL=0 +# CONFIG_FEATURE_BZIP2_DECOMPRESS is not set +# CONFIG_CPIO is not set +# CONFIG_FEATURE_CPIO_O is not set +# CONFIG_FEATURE_CPIO_P is not set +# CONFIG_DPKG is not set +# CONFIG_DPKG_DEB is not set +# CONFIG_GZIP is not set +# CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set +CONFIG_GZIP_FAST=0 +# CONFIG_FEATURE_GZIP_LEVELS is not set +# CONFIG_FEATURE_GZIP_DECOMPRESS is not set +# CONFIG_LZOP is not set +# CONFIG_UNLZOP is not set +# CONFIG_LZOPCAT is not set +# CONFIG_LZOP_COMPR_HIGH is not set +# CONFIG_RPM is not set +# CONFIG_RPM2CPIO is not set +# CONFIG_TAR is not set +# CONFIG_FEATURE_TAR_LONG_OPTIONS is not set +# CONFIG_FEATURE_TAR_CREATE is not set +# CONFIG_FEATURE_TAR_AUTODETECT is not set +# CONFIG_FEATURE_TAR_FROM is not set +# CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_GNU_EXTENSIONS is not set +# CONFIG_FEATURE_TAR_TO_COMMAND is not set +# CONFIG_FEATURE_TAR_UNAME_GNAME is not set +# CONFIG_FEATURE_TAR_NOPRESERVE_TIME is not set +# CONFIG_FEATURE_TAR_SELINUX is not set +# CONFIG_UNZIP is not set +# CONFIG_FEATURE_UNZIP_CDF is not set +# CONFIG_FEATURE_UNZIP_BZIP2 is not set +# CONFIG_FEATURE_UNZIP_LZMA is not set +# CONFIG_FEATURE_UNZIP_XZ is not set +# CONFIG_FEATURE_LZMA_FAST is not set + +# +# Coreutils +# +# CONFIG_BASENAME is not set +# CONFIG_CAT is not set +# CONFIG_FEATURE_CATN is not set +# CONFIG_FEATURE_CATV is not set +# CONFIG_CHGRP is not set +# CONFIG_CHMOD is not set +# CONFIG_CHOWN is not set +# CONFIG_FEATURE_CHOWN_LONG_OPTIONS is not set +# CONFIG_CHROOT is not set +# CONFIG_CKSUM is not set +# CONFIG_COMM is not set +# CONFIG_CP is not set +# CONFIG_FEATURE_CP_LONG_OPTIONS is not set +# CONFIG_FEATURE_CP_REFLINK is not set +# CONFIG_CUT is not set +# CONFIG_DATE is not set +# CONFIG_FEATURE_DATE_ISOFMT is not set +# CONFIG_FEATURE_DATE_NANO is not set +# CONFIG_FEATURE_DATE_COMPAT is not set +# CONFIG_DD is not set +# CONFIG_FEATURE_DD_SIGNAL_HANDLING is not set +# CONFIG_FEATURE_DD_THIRD_STATUS_LINE is not set +# CONFIG_FEATURE_DD_IBS_OBS is not set +# CONFIG_FEATURE_DD_STATUS is not set +# CONFIG_DF is not set +# CONFIG_FEATURE_DF_FANCY is not set +# CONFIG_DIRNAME is not set +# CONFIG_DOS2UNIX is not set +# CONFIG_UNIX2DOS is not set +# CONFIG_DU is not set +# CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K is not set +# CONFIG_ECHO is not set +# CONFIG_FEATURE_FANCY_ECHO is not set +# CONFIG_ENV is not set +# CONFIG_EXPAND is not set +# CONFIG_UNEXPAND is not set +# CONFIG_EXPR is not set +# CONFIG_EXPR_MATH_SUPPORT_64 is not set +# CONFIG_FACTOR is not set +# CONFIG_FALSE is not set +# CONFIG_FOLD is not set +# CONFIG_HEAD is not set +# CONFIG_FEATURE_FANCY_HEAD is not set +# CONFIG_HOSTID is not set +# CONFIG_ID is not set +# CONFIG_GROUPS is not set +# CONFIG_INSTALL is not set +# CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set +# CONFIG_LINK is not set +# CONFIG_LN is not set +# CONFIG_LOGNAME is not set +# CONFIG_LS is not set +# CONFIG_FEATURE_LS_FILETYPES is not set +# CONFIG_FEATURE_LS_FOLLOWLINKS is not set +# CONFIG_FEATURE_LS_RECURSIVE is not set +# CONFIG_FEATURE_LS_WIDTH is not set +# CONFIG_FEATURE_LS_SORTFILES is not set +# CONFIG_FEATURE_LS_TIMESTAMPS is not set +# CONFIG_FEATURE_LS_USERNAME is not set +# CONFIG_FEATURE_LS_COLOR is not set +# CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set +# CONFIG_MD5SUM is not set +# CONFIG_SHA1SUM is not set +# CONFIG_SHA256SUM is not set +# CONFIG_SHA512SUM is not set +# CONFIG_SHA3SUM is not set +# CONFIG_FEATURE_MD5_SHA1_SUM_CHECK is not set +# CONFIG_MKDIR is not set +# CONFIG_MKFIFO is not set +# CONFIG_MKNOD is not set +# CONFIG_MKTEMP is not set +# CONFIG_MV is not set +# CONFIG_NICE is not set +# CONFIG_NL is not set +# CONFIG_NOHUP is not set +# CONFIG_NPROC is not set +# CONFIG_OD is not set +# CONFIG_PASTE is not set +# CONFIG_PRINTENV is not set +# CONFIG_PRINTF is not set +# CONFIG_PWD is not set +# CONFIG_READLINK is not set +# CONFIG_FEATURE_READLINK_FOLLOW is not set +# CONFIG_REALPATH is not set +# CONFIG_RM is not set +# CONFIG_RMDIR is not set +# CONFIG_SEQ is not set +# CONFIG_SHRED is not set +# CONFIG_SHUF is not set +# CONFIG_SLEEP is not set +# CONFIG_FEATURE_FANCY_SLEEP is not set +# CONFIG_SORT is not set +# CONFIG_FEATURE_SORT_BIG is not set +# CONFIG_FEATURE_SORT_OPTIMIZE_MEMORY is not set +# CONFIG_SPLIT is not set +# CONFIG_FEATURE_SPLIT_FANCY is not set +# CONFIG_STAT is not set +# CONFIG_FEATURE_STAT_FORMAT is not set +# CONFIG_FEATURE_STAT_FILESYSTEM is not set +# CONFIG_STTY is not set +# CONFIG_SUM is not set +# CONFIG_SYNC is not set +# CONFIG_FEATURE_SYNC_FANCY is not set +# CONFIG_FSYNC is not set +# CONFIG_TAC is not set +# CONFIG_TAIL is not set +# CONFIG_FEATURE_FANCY_TAIL is not set +# CONFIG_TEE is not set +# CONFIG_FEATURE_TEE_USE_BLOCK_IO is not set +# CONFIG_TEST is not set +# CONFIG_TEST1 is not set +# CONFIG_TEST2 is not set +# CONFIG_FEATURE_TEST_64 is not set +# CONFIG_TIMEOUT is not set +# CONFIG_TOUCH is not set +# CONFIG_FEATURE_TOUCH_NODEREF is not set +# CONFIG_FEATURE_TOUCH_SUSV3 is not set +# CONFIG_TR is not set +# CONFIG_FEATURE_TR_CLASSES is not set +# CONFIG_FEATURE_TR_EQUIV is not set +# CONFIG_TRUE is not set +# CONFIG_TRUNCATE is not set +# CONFIG_TTY is not set +# CONFIG_UNAME is not set +CONFIG_UNAME_OSNAME="" +# CONFIG_BB_ARCH is not set +# CONFIG_UNIQ is not set +# CONFIG_UNLINK is not set +# CONFIG_USLEEP is not set +# CONFIG_UUDECODE is not set +# CONFIG_BASE64 is not set +# CONFIG_UUENCODE is not set +# CONFIG_WC is not set +# CONFIG_FEATURE_WC_LARGE is not set +# CONFIG_WHOAMI is not set +# CONFIG_WHO is not set +# CONFIG_W is not set +# CONFIG_USERS is not set +# CONFIG_YES is not set + +# +# Common options +# +# CONFIG_FEATURE_VERBOSE is not set +# CONFIG_FEATURE_PRESERVE_HARDLINKS is not set +# CONFIG_FEATURE_HUMAN_READABLE is not set + +# +# Console Utilities +# +# CONFIG_CHVT is not set +# CONFIG_CLEAR is not set +# CONFIG_DEALLOCVT is not set +# CONFIG_DUMPKMAP is not set +# CONFIG_FGCONSOLE is not set +# CONFIG_KBD_MODE is not set +# CONFIG_LOADFONT is not set +# CONFIG_SETFONT is not set +# CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set +CONFIG_DEFAULT_SETFONT_DIR="" +# CONFIG_FEATURE_LOADFONT_PSF2 is not set +# CONFIG_FEATURE_LOADFONT_RAW is not set +# CONFIG_LOADKMAP is not set +# CONFIG_OPENVT is not set +# CONFIG_RESET is not set +# CONFIG_RESIZE is not set +# CONFIG_FEATURE_RESIZE_PRINT is not set +# CONFIG_SETCONSOLE is not set +# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set +# CONFIG_SETKEYCODES is not set +# CONFIG_SETLOGCONS is not set +# CONFIG_SHOWKEY is not set + +# +# Debian Utilities +# +# CONFIG_PIPE_PROGRESS is not set +# CONFIG_RUN_PARTS is not set +# CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set +# CONFIG_FEATURE_RUN_PARTS_FANCY is not set +# CONFIG_START_STOP_DAEMON is not set +# CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set +# CONFIG_FEATURE_START_STOP_DAEMON_FANCY is not set +# CONFIG_WHICH is not set + +# +# klibc-utils +# +# CONFIG_MINIPS is not set +# CONFIG_NUKE is not set +# CONFIG_RESUME is not set +# CONFIG_RUN_INIT is not set + +# +# Editors +# +# CONFIG_AWK is not set +# CONFIG_FEATURE_AWK_LIBM is not set +# CONFIG_FEATURE_AWK_GNU_EXTENSIONS is not set +# CONFIG_CMP is not set +# CONFIG_DIFF is not set +# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set +# CONFIG_FEATURE_DIFF_DIR is not set +# CONFIG_ED is not set +# CONFIG_PATCH is not set +# CONFIG_SED is not set +# CONFIG_VI is not set +CONFIG_FEATURE_VI_MAX_LEN=0 +# CONFIG_FEATURE_VI_8BIT is not set +# CONFIG_FEATURE_VI_COLON is not set +# CONFIG_FEATURE_VI_YANKMARK is not set +# CONFIG_FEATURE_VI_SEARCH is not set +# CONFIG_FEATURE_VI_REGEX_SEARCH is not set +# CONFIG_FEATURE_VI_USE_SIGNALS is not set +# CONFIG_FEATURE_VI_DOT_CMD is not set +# CONFIG_FEATURE_VI_READONLY is not set +# CONFIG_FEATURE_VI_SETOPTS is not set +# CONFIG_FEATURE_VI_SET is not set +# CONFIG_FEATURE_VI_WIN_RESIZE is not set +# CONFIG_FEATURE_VI_ASK_TERMINAL is not set +# CONFIG_FEATURE_VI_UNDO is not set +# CONFIG_FEATURE_VI_UNDO_QUEUE is not set +CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=0 +# CONFIG_FEATURE_ALLOW_EXEC is not set + +# +# Finding Utilities +# +# CONFIG_FIND is not set +# CONFIG_FEATURE_FIND_PRINT0 is not set +# CONFIG_FEATURE_FIND_MTIME is not set +# CONFIG_FEATURE_FIND_MMIN is not set +# CONFIG_FEATURE_FIND_PERM is not set +# CONFIG_FEATURE_FIND_TYPE is not set +# CONFIG_FEATURE_FIND_EXECUTABLE is not set +# CONFIG_FEATURE_FIND_XDEV is not set +# CONFIG_FEATURE_FIND_MAXDEPTH is not set +# CONFIG_FEATURE_FIND_NEWER is not set +# CONFIG_FEATURE_FIND_INUM is not set +# CONFIG_FEATURE_FIND_EXEC is not set +# CONFIG_FEATURE_FIND_EXEC_PLUS is not set +# CONFIG_FEATURE_FIND_USER is not set +# CONFIG_FEATURE_FIND_GROUP is not set +# CONFIG_FEATURE_FIND_NOT is not set +# CONFIG_FEATURE_FIND_DEPTH is not set +# CONFIG_FEATURE_FIND_PAREN is not set +# CONFIG_FEATURE_FIND_SIZE is not set +# CONFIG_FEATURE_FIND_PRUNE is not set +# CONFIG_FEATURE_FIND_QUIT is not set +# CONFIG_FEATURE_FIND_DELETE is not set +# CONFIG_FEATURE_FIND_EMPTY is not set +# CONFIG_FEATURE_FIND_PATH is not set +# CONFIG_FEATURE_FIND_REGEX is not set +# CONFIG_FEATURE_FIND_CONTEXT is not set +# CONFIG_FEATURE_FIND_LINKS is not set +# CONFIG_GREP is not set +# CONFIG_EGREP is not set +# CONFIG_FGREP is not set +# CONFIG_FEATURE_GREP_CONTEXT is not set +# CONFIG_XARGS is not set +# CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION is not set +# CONFIG_FEATURE_XARGS_SUPPORT_QUOTES is not set +# CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM is not set +# CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR is not set +# CONFIG_FEATURE_XARGS_SUPPORT_PARALLEL is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ARGS_FILE is not set + +# +# Init Utilities +# +# CONFIG_BOOTCHARTD is not set +# CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set +# CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set +# CONFIG_HALT is not set +# CONFIG_POWEROFF is not set +# CONFIG_REBOOT is not set +# CONFIG_FEATURE_WAIT_FOR_INIT is not set +# CONFIG_FEATURE_CALL_TELINIT is not set +CONFIG_TELINIT_PATH="" +# CONFIG_INIT is not set +# CONFIG_LINUXRC is not set +# CONFIG_FEATURE_USE_INITTAB is not set +# CONFIG_FEATURE_KILL_REMOVED is not set +CONFIG_FEATURE_KILL_DELAY=0 +# CONFIG_FEATURE_INIT_SCTTY is not set +# CONFIG_FEATURE_INIT_SYSLOG is not set +# CONFIG_FEATURE_INIT_QUIET is not set +# CONFIG_FEATURE_INIT_COREDUMPS is not set +CONFIG_INIT_TERMINAL_TYPE="" +# CONFIG_FEATURE_INIT_MODIFY_CMDLINE is not set + +# +# Login/Password Management Utilities +# +# CONFIG_FEATURE_SHADOWPASSWDS is not set +# CONFIG_USE_BB_PWD_GRP is not set +# CONFIG_USE_BB_SHADOW is not set +# CONFIG_USE_BB_CRYPT is not set +# CONFIG_USE_BB_CRYPT_SHA is not set +# CONFIG_ADDGROUP is not set +# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set +# CONFIG_ADD_SHELL is not set +# CONFIG_REMOVE_SHELL is not set +# CONFIG_ADDUSER is not set +# CONFIG_FEATURE_CHECK_NAMES is not set +CONFIG_LAST_ID=0 +CONFIG_FIRST_SYSTEM_ID=0 +CONFIG_LAST_SYSTEM_ID=0 +# CONFIG_CHPASSWD is not set +CONFIG_FEATURE_DEFAULT_PASSWD_ALGO="" +# CONFIG_CRYPTPW is not set +# CONFIG_MKPASSWD is not set +# CONFIG_DELUSER is not set +# CONFIG_DELGROUP is not set +# CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set +# CONFIG_GETTY is not set +# CONFIG_LOGIN is not set +# CONFIG_LOGIN_SESSION_AS_CHILD is not set +# CONFIG_LOGIN_SCRIPTS is not set +# CONFIG_FEATURE_NOLOGIN is not set +# CONFIG_FEATURE_SECURETTY is not set +# CONFIG_PASSWD is not set +# CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set +# CONFIG_SU is not set +# CONFIG_FEATURE_SU_SYSLOG is not set +# CONFIG_FEATURE_SU_CHECKS_SHELLS is not set +# CONFIG_FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY is not set +# CONFIG_SULOGIN is not set +# CONFIG_VLOCK is not set + +# +# Linux Ext2 FS Progs +# +# CONFIG_CHATTR is not set +# CONFIG_FSCK is not set +# CONFIG_LSATTR is not set +# CONFIG_TUNE2FS is not set + +# +# Linux Module Utilities +# +# CONFIG_MODPROBE_SMALL is not set +# CONFIG_DEPMOD is not set +# CONFIG_INSMOD is not set +# CONFIG_LSMOD is not set +# CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set +# CONFIG_MODINFO is not set +# CONFIG_MODPROBE is not set +# CONFIG_FEATURE_MODPROBE_BLACKLIST is not set +# CONFIG_RMMOD is not set + +# +# Options common to multiple modutils +# +# CONFIG_FEATURE_CMDLINE_MODULE_OPTIONS is not set +# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set +# CONFIG_FEATURE_2_4_MODULES is not set +# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set +# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set +# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set +# CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set +# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set +# CONFIG_FEATURE_MODUTILS_ALIAS is not set +# CONFIG_FEATURE_MODUTILS_SYMBOLS is not set +CONFIG_DEFAULT_MODULES_DIR="" +CONFIG_DEFAULT_DEPMOD_FILE="" + +# +# Linux System Utilities +# +# CONFIG_ACPID is not set +# CONFIG_FEATURE_ACPID_COMPAT is not set +# CONFIG_BLKDISCARD is not set +# CONFIG_BLKID is not set +# CONFIG_FEATURE_BLKID_TYPE is not set +# CONFIG_BLOCKDEV is not set +# CONFIG_CAL is not set +# CONFIG_CHRT is not set +# CONFIG_DMESG is not set +# CONFIG_FEATURE_DMESG_PRETTY is not set +# CONFIG_EJECT is not set +# CONFIG_FEATURE_EJECT_SCSI is not set +# CONFIG_FALLOCATE is not set +# CONFIG_FATATTR is not set +# CONFIG_FBSET is not set +# CONFIG_FEATURE_FBSET_FANCY is not set +# CONFIG_FEATURE_FBSET_READMODE is not set +# CONFIG_FDFORMAT is not set +# CONFIG_FDISK is not set +# CONFIG_FDISK_SUPPORT_LARGE_DISKS is not set +# CONFIG_FEATURE_FDISK_WRITABLE is not set +# CONFIG_FEATURE_AIX_LABEL is not set +# CONFIG_FEATURE_SGI_LABEL is not set +# CONFIG_FEATURE_SUN_LABEL is not set +# CONFIG_FEATURE_OSF_LABEL is not set +# CONFIG_FEATURE_GPT_LABEL is not set +# CONFIG_FEATURE_FDISK_ADVANCED is not set +# CONFIG_FINDFS is not set +# CONFIG_FLOCK is not set +# CONFIG_FDFLUSH is not set +# CONFIG_FREERAMDISK is not set +# CONFIG_FSCK_MINIX is not set +# CONFIG_FSFREEZE is not set +# CONFIG_FSTRIM is not set +# CONFIG_GETOPT is not set +# CONFIG_FEATURE_GETOPT_LONG is not set +# CONFIG_HEXDUMP is not set +# CONFIG_FEATURE_HEXDUMP_REVERSE is not set +# CONFIG_HD is not set +# CONFIG_XXD is not set +# CONFIG_HWCLOCK is not set +# CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set +# CONFIG_IONICE is not set +# CONFIG_IPCRM is not set +# CONFIG_IPCS is not set +# CONFIG_LAST is not set +# CONFIG_FEATURE_LAST_FANCY is not set +# CONFIG_LOSETUP is not set +# CONFIG_LSPCI is not set +# CONFIG_LSUSB is not set +# CONFIG_MDEV is not set +# CONFIG_FEATURE_MDEV_CONF is not set +# CONFIG_FEATURE_MDEV_RENAME is not set +# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set +# CONFIG_FEATURE_MDEV_EXEC is not set +# CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set +# CONFIG_FEATURE_MDEV_DAEMON is not set +# CONFIG_MESG is not set +# CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP is not set +# CONFIG_MKE2FS is not set +# CONFIG_MKFS_EXT2 is not set +# CONFIG_MKFS_MINIX is not set +# CONFIG_FEATURE_MINIX2 is not set +# CONFIG_MKFS_REISER is not set +# CONFIG_MKDOSFS is not set +# CONFIG_MKFS_VFAT is not set +# CONFIG_MKSWAP is not set +# CONFIG_FEATURE_MKSWAP_UUID is not set +# CONFIG_MORE is not set +# CONFIG_MOUNT is not set +# CONFIG_FEATURE_MOUNT_FAKE is not set +# CONFIG_FEATURE_MOUNT_VERBOSE is not set +# CONFIG_FEATURE_MOUNT_HELPERS is not set +# CONFIG_FEATURE_MOUNT_LABEL is not set +# CONFIG_FEATURE_MOUNT_NFS is not set +# CONFIG_FEATURE_MOUNT_CIFS is not set +# CONFIG_FEATURE_MOUNT_FLAGS is not set +# CONFIG_FEATURE_MOUNT_FSTAB is not set +# CONFIG_FEATURE_MOUNT_OTHERTAB is not set +# CONFIG_MOUNTPOINT is not set +# CONFIG_NOLOGIN is not set +# CONFIG_NOLOGIN_DEPENDENCIES is not set +# CONFIG_NSENTER is not set +# CONFIG_PIVOT_ROOT is not set +# CONFIG_RDATE is not set +# CONFIG_RDEV is not set +# CONFIG_READPROFILE is not set +# CONFIG_RENICE is not set +# CONFIG_REV is not set +# CONFIG_RTCWAKE is not set +# CONFIG_SCRIPT is not set +# CONFIG_SCRIPTREPLAY is not set +# CONFIG_SETARCH is not set +# CONFIG_LINUX32 is not set +# CONFIG_LINUX64 is not set +# CONFIG_SETPRIV is not set +# CONFIG_FEATURE_SETPRIV_DUMP is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITIES is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITY_NAMES is not set +# CONFIG_SETSID is not set +# CONFIG_SWAPON is not set +# CONFIG_FEATURE_SWAPON_DISCARD is not set +# CONFIG_FEATURE_SWAPON_PRI is not set +# CONFIG_SWAPOFF is not set +# CONFIG_FEATURE_SWAPONOFF_LABEL is not set +# CONFIG_SWITCH_ROOT is not set +# CONFIG_TASKSET is not set +# CONFIG_FEATURE_TASKSET_FANCY is not set +# CONFIG_FEATURE_TASKSET_CPULIST is not set +# CONFIG_UEVENT is not set +# CONFIG_UMOUNT is not set +# CONFIG_FEATURE_UMOUNT_ALL is not set +# CONFIG_UNSHARE is not set +# CONFIG_WALL is not set +# CONFIG_FEATURE_MOUNT_LOOP is not set +# CONFIG_FEATURE_MOUNT_LOOP_CREATE is not set +# CONFIG_FEATURE_MTAB_SUPPORT is not set +# CONFIG_VOLUMEID is not set +# CONFIG_FEATURE_VOLUMEID_BCACHE is not set +# CONFIG_FEATURE_VOLUMEID_BTRFS is not set +# CONFIG_FEATURE_VOLUMEID_CRAMFS is not set +# CONFIG_FEATURE_VOLUMEID_EXFAT is not set +# CONFIG_FEATURE_VOLUMEID_EXT is not set +# CONFIG_FEATURE_VOLUMEID_F2FS is not set +# CONFIG_FEATURE_VOLUMEID_FAT is not set +# CONFIG_FEATURE_VOLUMEID_HFS is not set +# CONFIG_FEATURE_VOLUMEID_ISO9660 is not set +# CONFIG_FEATURE_VOLUMEID_JFS is not set +# CONFIG_FEATURE_VOLUMEID_LFS is not set +# CONFIG_FEATURE_VOLUMEID_LINUXRAID is not set +# CONFIG_FEATURE_VOLUMEID_LINUXSWAP is not set +# CONFIG_FEATURE_VOLUMEID_LUKS is not set +# CONFIG_FEATURE_VOLUMEID_MINIX is not set +# CONFIG_FEATURE_VOLUMEID_NILFS is not set +# CONFIG_FEATURE_VOLUMEID_NTFS is not set +# CONFIG_FEATURE_VOLUMEID_OCFS2 is not set +# CONFIG_FEATURE_VOLUMEID_REISERFS is not set +# CONFIG_FEATURE_VOLUMEID_ROMFS is not set +# CONFIG_FEATURE_VOLUMEID_SQUASHFS is not set +# CONFIG_FEATURE_VOLUMEID_SYSV is not set +# CONFIG_FEATURE_VOLUMEID_UBIFS is not set +# CONFIG_FEATURE_VOLUMEID_UDF is not set +# CONFIG_FEATURE_VOLUMEID_XFS is not set + +# +# Miscellaneous Utilities +# +# CONFIG_ADJTIMEX is not set +# CONFIG_BBCONFIG is not set +# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set +# CONFIG_BC is not set +# CONFIG_DC is not set +# CONFIG_FEATURE_DC_BIG is not set +# CONFIG_FEATURE_DC_LIBM is not set +# CONFIG_FEATURE_BC_INTERACTIVE is not set +# CONFIG_FEATURE_BC_LONG_OPTIONS is not set +# CONFIG_BEEP is not set +CONFIG_FEATURE_BEEP_FREQ=0 +CONFIG_FEATURE_BEEP_LENGTH_MS=0 +# CONFIG_CHAT is not set +# CONFIG_FEATURE_CHAT_NOFAIL is not set +# CONFIG_FEATURE_CHAT_TTY_HIFI is not set +# CONFIG_FEATURE_CHAT_IMPLICIT_CR is not set +# CONFIG_FEATURE_CHAT_SWALLOW_OPTS is not set +# CONFIG_FEATURE_CHAT_SEND_ESCAPES is not set +# CONFIG_FEATURE_CHAT_VAR_ABORT_LEN is not set +# CONFIG_FEATURE_CHAT_CLR_ABORT is not set +# CONFIG_CONSPY is not set +# CONFIG_CROND is not set +# CONFIG_FEATURE_CROND_D is not set +# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set +# CONFIG_FEATURE_CROND_SPECIAL_TIMES is not set +CONFIG_FEATURE_CROND_DIR="" +# CONFIG_CRONTAB is not set +# CONFIG_DEVFSD is not set +# CONFIG_DEVFSD_MODLOAD is not set +# CONFIG_DEVFSD_FG_NP is not set +# CONFIG_DEVFSD_VERBOSE is not set +# CONFIG_FEATURE_DEVFS is not set +# CONFIG_DEVMEM is not set +# CONFIG_FBSPLASH is not set +# CONFIG_FLASHCP is not set +# CONFIG_FLASH_ERASEALL is not set +# CONFIG_FLASH_LOCK is not set +# CONFIG_FLASH_UNLOCK is not set +# CONFIG_HDPARM is not set +# CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set +# CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set +# CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set +# CONFIG_HEXEDIT is not set +# CONFIG_I2CGET is not set +# CONFIG_I2CSET is not set +# CONFIG_I2CDUMP is not set +# CONFIG_I2CDETECT is not set +# CONFIG_I2CTRANSFER is not set +# CONFIG_INOTIFYD is not set +# CONFIG_LESS is not set +CONFIG_FEATURE_LESS_MAXLINES=0 +# CONFIG_FEATURE_LESS_BRACKETS is not set +# CONFIG_FEATURE_LESS_FLAGS is not set +# CONFIG_FEATURE_LESS_TRUNCATE is not set +# CONFIG_FEATURE_LESS_MARKS is not set +# CONFIG_FEATURE_LESS_REGEXP is not set +# CONFIG_FEATURE_LESS_WINCH is not set +# CONFIG_FEATURE_LESS_ASK_TERMINAL is not set +# CONFIG_FEATURE_LESS_DASHCMD is not set +# CONFIG_FEATURE_LESS_LINENUMS is not set +# CONFIG_FEATURE_LESS_RAW is not set +# CONFIG_FEATURE_LESS_ENV is not set +# CONFIG_LSSCSI is not set +# CONFIG_MAKEDEVS is not set +# CONFIG_FEATURE_MAKEDEVS_LEAF is not set +# CONFIG_FEATURE_MAKEDEVS_TABLE is not set +# CONFIG_MAN is not set +# CONFIG_MICROCOM is not set +# CONFIG_MIM is not set +# CONFIG_MT is not set +# CONFIG_NANDWRITE is not set +# CONFIG_NANDDUMP is not set +# CONFIG_PARTPROBE is not set +# CONFIG_RAIDAUTORUN is not set +# CONFIG_READAHEAD is not set +# CONFIG_RFKILL is not set +# CONFIG_RUNLEVEL is not set +# CONFIG_RX is not set +# CONFIG_SETFATTR is not set +# CONFIG_SETSERIAL is not set +# CONFIG_STRINGS is not set +# CONFIG_TIME is not set +# CONFIG_TS is not set +# CONFIG_TTYSIZE is not set +# CONFIG_UBIRENAME is not set +# CONFIG_UBIATTACH is not set +# CONFIG_UBIDETACH is not set +# CONFIG_UBIMKVOL is not set +# CONFIG_UBIRMVOL is not set +# CONFIG_UBIRSVOL is not set +# CONFIG_UBIUPDATEVOL is not set +# CONFIG_VOLNAME is not set +# CONFIG_WATCHDOG is not set + +# +# Networking Utilities +# +# CONFIG_FEATURE_IPV6 is not set +# CONFIG_FEATURE_UNIX_LOCAL is not set +# CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set +# CONFIG_VERBOSE_RESOLUTION_ERRORS is not set +# CONFIG_FEATURE_TLS_SHA1 is not set +# CONFIG_ARP is not set +# CONFIG_ARPING is not set +# CONFIG_BRCTL is not set +# CONFIG_FEATURE_BRCTL_FANCY is not set +# CONFIG_FEATURE_BRCTL_SHOW is not set +# CONFIG_DNSD is not set +# CONFIG_ETHER_WAKE is not set +# CONFIG_FTPD is not set +# CONFIG_FEATURE_FTPD_WRITE is not set +# CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST is not set +# CONFIG_FEATURE_FTPD_AUTHENTICATION is not set +# CONFIG_FTPGET is not set +# CONFIG_FTPPUT is not set +# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set +# CONFIG_HOSTNAME is not set +# CONFIG_DNSDOMAINNAME is not set +# CONFIG_HTTPD is not set +# CONFIG_FEATURE_HTTPD_RANGES is not set +# CONFIG_FEATURE_HTTPD_SETUID is not set +# CONFIG_FEATURE_HTTPD_BASIC_AUTH is not set +# CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set +# CONFIG_FEATURE_HTTPD_CGI is not set +# CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set +# CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set +# CONFIG_FEATURE_HTTPD_ENCODE_URL_STR is not set +# CONFIG_FEATURE_HTTPD_ERROR_PAGES is not set +# CONFIG_FEATURE_HTTPD_PROXY is not set +# CONFIG_FEATURE_HTTPD_GZIP is not set +# CONFIG_IFCONFIG is not set +# CONFIG_FEATURE_IFCONFIG_STATUS is not set +# CONFIG_FEATURE_IFCONFIG_SLIP is not set +# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set +# CONFIG_FEATURE_IFCONFIG_HW is not set +# CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set +# CONFIG_IFENSLAVE is not set +# CONFIG_IFPLUGD is not set +# CONFIG_IFUP is not set +# CONFIG_IFDOWN is not set +CONFIG_IFUPDOWN_IFSTATE_PATH="" +# CONFIG_FEATURE_IFUPDOWN_IP is not set +# CONFIG_FEATURE_IFUPDOWN_IPV4 is not set +# CONFIG_FEATURE_IFUPDOWN_IPV6 is not set +# CONFIG_FEATURE_IFUPDOWN_MAPPING is not set +# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set +# CONFIG_INETD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set +# CONFIG_FEATURE_INETD_RPC is not set +# CONFIG_IP is not set +# CONFIG_IPADDR is not set +# CONFIG_IPLINK is not set +# CONFIG_IPROUTE is not set +# CONFIG_IPTUNNEL is not set +# CONFIG_IPRULE is not set +# CONFIG_IPNEIGH is not set +# CONFIG_FEATURE_IP_ADDRESS is not set +# CONFIG_FEATURE_IP_LINK is not set +# CONFIG_FEATURE_IP_ROUTE is not set +CONFIG_FEATURE_IP_ROUTE_DIR="" +# CONFIG_FEATURE_IP_TUNNEL is not set +# CONFIG_FEATURE_IP_RULE is not set +# CONFIG_FEATURE_IP_NEIGH is not set +# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set +# CONFIG_IPCALC is not set +# CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set +# CONFIG_FEATURE_IPCALC_FANCY is not set +# CONFIG_FAKEIDENTD is not set +# CONFIG_NAMEIF is not set +# CONFIG_FEATURE_NAMEIF_EXTENDED is not set +# CONFIG_NBDCLIENT is not set +# CONFIG_NC is not set +# CONFIG_NETCAT is not set +# CONFIG_NC_SERVER is not set +# CONFIG_NC_EXTRA is not set +# CONFIG_NC_110_COMPAT is not set +# CONFIG_NETSTAT is not set +# CONFIG_FEATURE_NETSTAT_WIDE is not set +# CONFIG_FEATURE_NETSTAT_PRG is not set +# CONFIG_NSLOOKUP is not set +# CONFIG_FEATURE_NSLOOKUP_BIG is not set +# CONFIG_FEATURE_NSLOOKUP_LONG_OPTIONS is not set +# CONFIG_NTPD is not set +# CONFIG_FEATURE_NTPD_SERVER is not set +# CONFIG_FEATURE_NTPD_CONF is not set +# CONFIG_FEATURE_NTP_AUTH is not set +# CONFIG_PING is not set +# CONFIG_PING6 is not set +# CONFIG_FEATURE_FANCY_PING is not set +# CONFIG_PSCAN is not set +# CONFIG_ROUTE is not set +# CONFIG_SLATTACH is not set +# CONFIG_SSL_CLIENT is not set +# CONFIG_TC is not set +# CONFIG_FEATURE_TC_INGRESS is not set +# CONFIG_TCPSVD is not set +# CONFIG_UDPSVD is not set +# CONFIG_TELNET is not set +# CONFIG_FEATURE_TELNET_TTYPE is not set +# CONFIG_FEATURE_TELNET_AUTOLOGIN is not set +# CONFIG_FEATURE_TELNET_WIDTH is not set +# CONFIG_TELNETD is not set +# CONFIG_FEATURE_TELNETD_STANDALONE is not set +# CONFIG_FEATURE_TELNETD_INETD_WAIT is not set +# CONFIG_TFTP is not set +# CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set +# CONFIG_FEATURE_TFTP_HPA_COMPAT is not set +# CONFIG_TFTPD is not set +# CONFIG_FEATURE_TFTP_GET is not set +# CONFIG_FEATURE_TFTP_PUT is not set +# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set +# CONFIG_TFTP_DEBUG is not set +# CONFIG_TLS is not set +# CONFIG_TRACEROUTE is not set +# CONFIG_TRACEROUTE6 is not set +# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set +# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set +# CONFIG_TUNCTL is not set +# CONFIG_FEATURE_TUNCTL_UG is not set +# CONFIG_VCONFIG is not set +# CONFIG_WGET is not set +# CONFIG_FEATURE_WGET_LONG_OPTIONS is not set +# CONFIG_FEATURE_WGET_STATUSBAR is not set +# CONFIG_FEATURE_WGET_AUTHENTICATION is not set +# CONFIG_FEATURE_WGET_TIMEOUT is not set +# CONFIG_FEATURE_WGET_HTTPS is not set +# CONFIG_FEATURE_WGET_OPENSSL is not set +# CONFIG_WHOIS is not set +# CONFIG_ZCIP is not set +# CONFIG_UDHCPD is not set +# CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC is not set +# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set +CONFIG_DHCPD_LEASES_FILE="" +# CONFIG_DUMPLEASES is not set +# CONFIG_DHCPRELAY is not set +# CONFIG_UDHCPC is not set +# CONFIG_FEATURE_UDHCPC_ARPING is not set +# CONFIG_FEATURE_UDHCPC_SANITIZEOPT is not set +CONFIG_UDHCPC_DEFAULT_SCRIPT="" +# CONFIG_UDHCPC6 is not set +# CONFIG_FEATURE_UDHCPC6_RFC3646 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4704 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4833 is not set +# CONFIG_FEATURE_UDHCPC6_RFC5970 is not set +# CONFIG_FEATURE_UDHCP_PORT is not set +CONFIG_UDHCP_DEBUG=0 +CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=0 +# CONFIG_FEATURE_UDHCP_RFC3397 is not set +# CONFIG_FEATURE_UDHCP_8021Q is not set +CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="" + +# +# Print Utilities +# +# CONFIG_LPD is not set +# CONFIG_LPR is not set +# CONFIG_LPQ is not set + +# +# Mail Utilities +# +# CONFIG_MAKEMIME is not set +# CONFIG_POPMAILDIR is not set +# CONFIG_FEATURE_POPMAILDIR_DELIVERY is not set +# CONFIG_REFORMIME is not set +# CONFIG_FEATURE_REFORMIME_COMPAT is not set +# CONFIG_SENDMAIL is not set +CONFIG_FEATURE_MIME_CHARSET="" + +# +# Process Utilities +# +# CONFIG_FREE is not set +# CONFIG_FUSER is not set +# CONFIG_IOSTAT is not set +# CONFIG_KILL is not set +# CONFIG_KILLALL is not set +# CONFIG_KILLALL5 is not set +# CONFIG_LSOF is not set +# CONFIG_MPSTAT is not set +# CONFIG_NMETER is not set +# CONFIG_PGREP is not set +# CONFIG_PKILL is not set +# CONFIG_PIDOF is not set +# CONFIG_FEATURE_PIDOF_SINGLE is not set +# CONFIG_FEATURE_PIDOF_OMIT is not set +# CONFIG_PMAP is not set +# CONFIG_POWERTOP is not set +# CONFIG_FEATURE_POWERTOP_INTERACTIVE is not set +# CONFIG_PS is not set +# CONFIG_FEATURE_PS_WIDE is not set +# CONFIG_FEATURE_PS_LONG is not set +# CONFIG_FEATURE_PS_TIME is not set +# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set +# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set +# CONFIG_PSTREE is not set +# CONFIG_PWDX is not set +# CONFIG_SMEMCAP is not set +# CONFIG_BB_SYSCTL is not set +# CONFIG_TOP is not set +# CONFIG_FEATURE_TOP_INTERACTIVE is not set +# CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE is not set +# CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS is not set +# CONFIG_FEATURE_TOP_SMP_CPU is not set +# CONFIG_FEATURE_TOP_DECIMALS is not set +# CONFIG_FEATURE_TOP_SMP_PROCESS is not set +# CONFIG_FEATURE_TOPMEM is not set +# CONFIG_UPTIME is not set +# CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set +# CONFIG_WATCH is not set +# CONFIG_FEATURE_SHOW_THREADS is not set + +# +# Runit Utilities +# +# CONFIG_CHPST is not set +# CONFIG_SETUIDGID is not set +# CONFIG_ENVUIDGID is not set +# CONFIG_ENVDIR is not set +# CONFIG_SOFTLIMIT is not set +# CONFIG_RUNSV is not set +# CONFIG_RUNSVDIR is not set +# CONFIG_FEATURE_RUNSVDIR_LOG is not set +# CONFIG_SV is not set +CONFIG_SV_DEFAULT_SERVICE_DIR="" +# CONFIG_SVC is not set +# CONFIG_SVOK is not set +# CONFIG_SVLOGD is not set +# CONFIG_CHCON is not set +# CONFIG_GETENFORCE is not set +# CONFIG_GETSEBOOL is not set +# CONFIG_LOAD_POLICY is not set +# CONFIG_MATCHPATHCON is not set +# CONFIG_RUNCON is not set +# CONFIG_SELINUXENABLED is not set +# CONFIG_SESTATUS is not set +# CONFIG_SETENFORCE is not set +# CONFIG_SETFILES is not set +# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set +# CONFIG_RESTORECON is not set +# CONFIG_SETSEBOOL is not set + +# +# Shells +# +CONFIG_SH_IS_ASH=y +# CONFIG_SH_IS_HUSH is not set +# CONFIG_SH_IS_NONE is not set +# CONFIG_BASH_IS_ASH is not set +# CONFIG_BASH_IS_HUSH is not set +CONFIG_BASH_IS_NONE=y +CONFIG_SHELL_ASH=y +# CONFIG_ASH is not set +# CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set +# CONFIG_ASH_INTERNAL_GLOB is not set +# CONFIG_ASH_BASH_COMPAT is not set +# CONFIG_ASH_BASH_SOURCE_CURDIR is not set +# CONFIG_ASH_BASH_NOT_FOUND_HOOK is not set +# CONFIG_ASH_JOB_CONTROL is not set +# CONFIG_ASH_ALIAS is not set +# CONFIG_ASH_RANDOM_SUPPORT is not set +# CONFIG_ASH_EXPAND_PRMT is not set +# CONFIG_ASH_IDLE_TIMEOUT is not set +# CONFIG_ASH_MAIL is not set +# CONFIG_ASH_ECHO is not set +# CONFIG_ASH_PRINTF is not set +# CONFIG_ASH_TEST is not set +# CONFIG_ASH_HELP is not set +# CONFIG_ASH_GETOPTS is not set +# CONFIG_ASH_CMDCMD is not set +# CONFIG_CTTYHACK is not set +# CONFIG_HUSH is not set +# CONFIG_SHELL_HUSH is not set +# CONFIG_HUSH_BASH_COMPAT is not set +# CONFIG_HUSH_BRACE_EXPANSION is not set +# CONFIG_HUSH_LINENO_VAR is not set +# CONFIG_HUSH_BASH_SOURCE_CURDIR is not set +# CONFIG_HUSH_INTERACTIVE is not set +# CONFIG_HUSH_SAVEHISTORY is not set +# CONFIG_HUSH_JOB is not set +# CONFIG_HUSH_TICK is not set +# CONFIG_HUSH_IF is not set +# CONFIG_HUSH_LOOPS is not set +# CONFIG_HUSH_CASE is not set +# CONFIG_HUSH_FUNCTIONS is not set +# CONFIG_HUSH_LOCAL is not set +# CONFIG_HUSH_RANDOM_SUPPORT is not set +# CONFIG_HUSH_MODE_X is not set +# CONFIG_HUSH_ECHO is not set +# CONFIG_HUSH_PRINTF is not set +# CONFIG_HUSH_TEST is not set +# CONFIG_HUSH_HELP is not set +# CONFIG_HUSH_EXPORT is not set +# CONFIG_HUSH_EXPORT_N is not set +# CONFIG_HUSH_READONLY is not set +# CONFIG_HUSH_KILL is not set +# CONFIG_HUSH_WAIT is not set +# CONFIG_HUSH_COMMAND is not set +# CONFIG_HUSH_TRAP is not set +# CONFIG_HUSH_TYPE is not set +# CONFIG_HUSH_TIMES is not set +# CONFIG_HUSH_READ is not set +# CONFIG_HUSH_SET is not set +# CONFIG_HUSH_UNSET is not set +# CONFIG_HUSH_ULIMIT is not set +# CONFIG_HUSH_UMASK is not set +# CONFIG_HUSH_GETOPTS is not set +# CONFIG_HUSH_MEMLEAK is not set + +# +# Options common to all shells +# +# CONFIG_FEATURE_SH_MATH is not set +# CONFIG_FEATURE_SH_MATH_64 is not set +# CONFIG_FEATURE_SH_MATH_BASE is not set +# CONFIG_FEATURE_SH_EXTRA_QUIET is not set +# CONFIG_FEATURE_SH_STANDALONE is not set +# CONFIG_FEATURE_SH_NOFORK is not set +# CONFIG_FEATURE_SH_READ_FRAC is not set +# CONFIG_FEATURE_SH_HISTFILESIZE is not set +# CONFIG_FEATURE_SH_EMBEDDED_SCRIPTS is not set + +# +# System Logging Utilities +# +# CONFIG_KLOGD is not set +# CONFIG_FEATURE_KLOGD_KLOGCTL is not set +# CONFIG_LOGGER is not set +# CONFIG_LOGREAD is not set +# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set +# CONFIG_SYSLOGD is not set +# CONFIG_FEATURE_ROTATE_LOGFILE is not set +# CONFIG_FEATURE_REMOTE_LOG is not set +# CONFIG_FEATURE_SYSLOGD_DUP is not set +# CONFIG_FEATURE_SYSLOGD_CFG is not set +# CONFIG_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS is not set +CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0 +# CONFIG_FEATURE_IPC_SYSLOG is not set +CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 +# CONFIG_FEATURE_KMSG_SYSLOG is not set diff --git a/BUSYBOX/x86_64_ash.config b/BUSYBOX/x86_64_ash.config new file mode 100644 index 0000000..3285477 --- /dev/null +++ b/BUSYBOX/x86_64_ash.config @@ -0,0 +1,1166 @@ +# +# Automatically generated make config: don't edit +# Busybox version: 1.32.0 +# Fri Aug 7 05:44:56 2020 +# +CONFIG_HAVE_DOT_CONFIG=y + +# +# Settings +# +# CONFIG_DESKTOP is not set +# CONFIG_EXTRA_COMPAT is not set +# CONFIG_FEDORA_COMPAT is not set +# CONFIG_INCLUDE_SUSv2 is not set +# CONFIG_LONG_OPTS is not set +# CONFIG_SHOW_USAGE is not set +# CONFIG_FEATURE_VERBOSE_USAGE is not set +# CONFIG_FEATURE_COMPRESS_USAGE is not set +# CONFIG_LFS is not set +# CONFIG_PAM is not set +# CONFIG_FEATURE_DEVPTS is not set +# CONFIG_FEATURE_UTMP is not set +# CONFIG_FEATURE_WTMP is not set +# CONFIG_FEATURE_PIDFILE is not set +CONFIG_PID_FILE_PATH="" +# CONFIG_BUSYBOX is not set +# CONFIG_FEATURE_SHOW_SCRIPT is not set +# CONFIG_FEATURE_INSTALLER is not set +# CONFIG_INSTALL_NO_USR is not set +# CONFIG_FEATURE_SUID is not set +# CONFIG_FEATURE_SUID_CONFIG is not set +# CONFIG_FEATURE_SUID_CONFIG_QUIET is not set +# CONFIG_FEATURE_PREFER_APPLETS is not set +CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" +# CONFIG_SELINUX is not set +# CONFIG_FEATURE_CLEAN_UP is not set +# CONFIG_FEATURE_SYSLOG_INFO is not set +# CONFIG_FEATURE_SYSLOG is not set +# CONFIG_PLATFORM_LINUX is not set + +# +# Build Options +# +CONFIG_STATIC=y +# CONFIG_PIE is not set +# CONFIG_NOMMU is not set +# CONFIG_BUILD_LIBBUSYBOX is not set +# CONFIG_FEATURE_LIBBUSYBOX_STATIC is not set +# CONFIG_FEATURE_INDIVIDUAL is not set +# CONFIG_FEATURE_SHARED_BUSYBOX is not set +CONFIG_CROSS_COMPILER_PREFIX="" +CONFIG_SYSROOT="" +CONFIG_EXTRA_CFLAGS="" +CONFIG_EXTRA_LDFLAGS="" +CONFIG_EXTRA_LDLIBS="" +# CONFIG_USE_PORTABLE_CODE is not set +# CONFIG_STACK_OPTIMIZATION_386 is not set + +# +# Installation Options ("make install" behavior) +# +CONFIG_INSTALL_APPLET_SYMLINKS=y +# CONFIG_INSTALL_APPLET_HARDLINKS is not set +# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set +# CONFIG_INSTALL_APPLET_DONT is not set +# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set +# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set +# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set +CONFIG_PREFIX="./_install" + +# +# Debugging Options +# +# CONFIG_DEBUG is not set +# CONFIG_DEBUG_PESSIMIZE is not set +# CONFIG_DEBUG_SANITIZE is not set +# CONFIG_UNIT_TEST is not set +# CONFIG_WERROR is not set +# CONFIG_WARN_SIMPLE_MSG is not set +CONFIG_NO_DEBUG_LIB=y +# CONFIG_DMALLOC is not set +# CONFIG_EFENCE is not set + +# +# Library Tuning +# +# CONFIG_FEATURE_USE_BSS_TAIL is not set +# CONFIG_FLOAT_DURATION is not set +# CONFIG_FEATURE_RTMINMAX is not set +# CONFIG_FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS is not set +CONFIG_FEATURE_BUFFERS_USE_MALLOC=y +# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set +# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set +CONFIG_PASSWORD_MINLEN=6 +CONFIG_MD5_SMALL=1 +CONFIG_SHA3_SMALL=1 +# CONFIG_FEATURE_FAST_TOP is not set +# CONFIG_FEATURE_ETC_NETWORKS is not set +# CONFIG_FEATURE_ETC_SERVICES is not set +# CONFIG_FEATURE_EDITING is not set +CONFIG_FEATURE_EDITING_MAX_LEN=0 +# CONFIG_FEATURE_EDITING_VI is not set +CONFIG_FEATURE_EDITING_HISTORY=0 +# CONFIG_FEATURE_EDITING_SAVEHISTORY is not set +# CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set +# CONFIG_FEATURE_REVERSE_SEARCH is not set +# CONFIG_FEATURE_TAB_COMPLETION is not set +# CONFIG_FEATURE_USERNAME_COMPLETION is not set +# CONFIG_FEATURE_EDITING_FANCY_PROMPT is not set +# CONFIG_FEATURE_EDITING_WINCH is not set +# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set +# CONFIG_LOCALE_SUPPORT is not set +# CONFIG_UNICODE_SUPPORT is not set +# CONFIG_UNICODE_USING_LOCALE is not set +# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set +CONFIG_SUBST_WCHAR=0 +CONFIG_LAST_SUPPORTED_WCHAR=0 +# CONFIG_UNICODE_COMBINING_WCHARS is not set +# CONFIG_UNICODE_WIDE_WCHARS is not set +# CONFIG_UNICODE_BIDI_SUPPORT is not set +# CONFIG_UNICODE_NEUTRAL_TABLE is not set +# CONFIG_UNICODE_PRESERVE_BROKEN is not set +# CONFIG_FEATURE_NON_POSIX_CP is not set +# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set +# CONFIG_FEATURE_USE_SENDFILE is not set +CONFIG_FEATURE_COPYBUF_KB=4 +# CONFIG_FEATURE_SKIP_ROOTFS is not set +# CONFIG_MONOTONIC_SYSCALL is not set +# CONFIG_IOCTL_HEX2STR_ERROR is not set +# CONFIG_FEATURE_HWIB is not set + +# +# Applets +# + +# +# Archival Utilities +# +# CONFIG_FEATURE_SEAMLESS_XZ is not set +# CONFIG_FEATURE_SEAMLESS_LZMA is not set +# CONFIG_FEATURE_SEAMLESS_BZ2 is not set +# CONFIG_FEATURE_SEAMLESS_GZ is not set +# CONFIG_FEATURE_SEAMLESS_Z is not set +# CONFIG_AR is not set +# CONFIG_FEATURE_AR_LONG_FILENAMES is not set +# CONFIG_FEATURE_AR_CREATE is not set +# CONFIG_UNCOMPRESS is not set +# CONFIG_GUNZIP is not set +# CONFIG_ZCAT is not set +# CONFIG_FEATURE_GUNZIP_LONG_OPTIONS is not set +# CONFIG_BUNZIP2 is not set +# CONFIG_BZCAT is not set +# CONFIG_UNLZMA is not set +# CONFIG_LZCAT is not set +# CONFIG_LZMA is not set +# CONFIG_UNXZ is not set +# CONFIG_XZCAT is not set +# CONFIG_XZ is not set +# CONFIG_BZIP2 is not set +CONFIG_BZIP2_SMALL=0 +# CONFIG_FEATURE_BZIP2_DECOMPRESS is not set +# CONFIG_CPIO is not set +# CONFIG_FEATURE_CPIO_O is not set +# CONFIG_FEATURE_CPIO_P is not set +# CONFIG_DPKG is not set +# CONFIG_DPKG_DEB is not set +# CONFIG_GZIP is not set +# CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set +CONFIG_GZIP_FAST=0 +# CONFIG_FEATURE_GZIP_LEVELS is not set +# CONFIG_FEATURE_GZIP_DECOMPRESS is not set +# CONFIG_LZOP is not set +# CONFIG_UNLZOP is not set +# CONFIG_LZOPCAT is not set +# CONFIG_LZOP_COMPR_HIGH is not set +# CONFIG_RPM is not set +# CONFIG_RPM2CPIO is not set +# CONFIG_TAR is not set +# CONFIG_FEATURE_TAR_LONG_OPTIONS is not set +# CONFIG_FEATURE_TAR_CREATE is not set +# CONFIG_FEATURE_TAR_AUTODETECT is not set +# CONFIG_FEATURE_TAR_FROM is not set +# CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_GNU_EXTENSIONS is not set +# CONFIG_FEATURE_TAR_TO_COMMAND is not set +# CONFIG_FEATURE_TAR_UNAME_GNAME is not set +# CONFIG_FEATURE_TAR_NOPRESERVE_TIME is not set +# CONFIG_FEATURE_TAR_SELINUX is not set +# CONFIG_UNZIP is not set +# CONFIG_FEATURE_UNZIP_CDF is not set +# CONFIG_FEATURE_UNZIP_BZIP2 is not set +# CONFIG_FEATURE_UNZIP_LZMA is not set +# CONFIG_FEATURE_UNZIP_XZ is not set +# CONFIG_FEATURE_LZMA_FAST is not set + +# +# Coreutils +# +# CONFIG_BASENAME is not set +# CONFIG_CAT is not set +# CONFIG_FEATURE_CATN is not set +# CONFIG_FEATURE_CATV is not set +# CONFIG_CHGRP is not set +# CONFIG_CHMOD is not set +# CONFIG_CHOWN is not set +# CONFIG_FEATURE_CHOWN_LONG_OPTIONS is not set +# CONFIG_CHROOT is not set +# CONFIG_CKSUM is not set +# CONFIG_COMM is not set +# CONFIG_CP is not set +# CONFIG_FEATURE_CP_LONG_OPTIONS is not set +# CONFIG_FEATURE_CP_REFLINK is not set +# CONFIG_CUT is not set +# CONFIG_DATE is not set +# CONFIG_FEATURE_DATE_ISOFMT is not set +# CONFIG_FEATURE_DATE_NANO is not set +# CONFIG_FEATURE_DATE_COMPAT is not set +# CONFIG_DD is not set +# CONFIG_FEATURE_DD_SIGNAL_HANDLING is not set +# CONFIG_FEATURE_DD_THIRD_STATUS_LINE is not set +# CONFIG_FEATURE_DD_IBS_OBS is not set +# CONFIG_FEATURE_DD_STATUS is not set +# CONFIG_DF is not set +# CONFIG_FEATURE_DF_FANCY is not set +# CONFIG_DIRNAME is not set +# CONFIG_DOS2UNIX is not set +# CONFIG_UNIX2DOS is not set +# CONFIG_DU is not set +# CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K is not set +# CONFIG_ECHO is not set +CONFIG_FEATURE_FANCY_ECHO=y +# CONFIG_ENV is not set +# CONFIG_EXPAND is not set +# CONFIG_UNEXPAND is not set +# CONFIG_EXPR is not set +# CONFIG_EXPR_MATH_SUPPORT_64 is not set +# CONFIG_FACTOR is not set +# CONFIG_FALSE is not set +# CONFIG_FOLD is not set +# CONFIG_HEAD is not set +# CONFIG_FEATURE_FANCY_HEAD is not set +# CONFIG_HOSTID is not set +# CONFIG_ID is not set +# CONFIG_GROUPS is not set +# CONFIG_INSTALL is not set +# CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set +# CONFIG_LINK is not set +# CONFIG_LN is not set +# CONFIG_LOGNAME is not set +# CONFIG_LS is not set +# CONFIG_FEATURE_LS_FILETYPES is not set +# CONFIG_FEATURE_LS_FOLLOWLINKS is not set +# CONFIG_FEATURE_LS_RECURSIVE is not set +# CONFIG_FEATURE_LS_WIDTH is not set +# CONFIG_FEATURE_LS_SORTFILES is not set +# CONFIG_FEATURE_LS_TIMESTAMPS is not set +# CONFIG_FEATURE_LS_USERNAME is not set +# CONFIG_FEATURE_LS_COLOR is not set +# CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set +# CONFIG_MD5SUM is not set +# CONFIG_SHA1SUM is not set +# CONFIG_SHA256SUM is not set +# CONFIG_SHA512SUM is not set +# CONFIG_SHA3SUM is not set +# CONFIG_FEATURE_MD5_SHA1_SUM_CHECK is not set +# CONFIG_MKDIR is not set +# CONFIG_MKFIFO is not set +# CONFIG_MKNOD is not set +# CONFIG_MKTEMP is not set +# CONFIG_MV is not set +# CONFIG_NICE is not set +# CONFIG_NL is not set +# CONFIG_NOHUP is not set +# CONFIG_NPROC is not set +# CONFIG_OD is not set +# CONFIG_PASTE is not set +# CONFIG_PRINTENV is not set +# CONFIG_PRINTF is not set +# CONFIG_PWD is not set +# CONFIG_READLINK is not set +# CONFIG_FEATURE_READLINK_FOLLOW is not set +# CONFIG_REALPATH is not set +# CONFIG_RM is not set +# CONFIG_RMDIR is not set +# CONFIG_SEQ is not set +# CONFIG_SHRED is not set +# CONFIG_SHUF is not set +# CONFIG_SLEEP is not set +# CONFIG_FEATURE_FANCY_SLEEP is not set +# CONFIG_SORT is not set +# CONFIG_FEATURE_SORT_BIG is not set +# CONFIG_FEATURE_SORT_OPTIMIZE_MEMORY is not set +# CONFIG_SPLIT is not set +# CONFIG_FEATURE_SPLIT_FANCY is not set +# CONFIG_STAT is not set +# CONFIG_FEATURE_STAT_FORMAT is not set +# CONFIG_FEATURE_STAT_FILESYSTEM is not set +# CONFIG_STTY is not set +# CONFIG_SUM is not set +# CONFIG_SYNC is not set +# CONFIG_FEATURE_SYNC_FANCY is not set +# CONFIG_FSYNC is not set +# CONFIG_TAC is not set +# CONFIG_TAIL is not set +# CONFIG_FEATURE_FANCY_TAIL is not set +# CONFIG_TEE is not set +# CONFIG_FEATURE_TEE_USE_BLOCK_IO is not set +# CONFIG_TEST is not set +# CONFIG_TEST1 is not set +# CONFIG_TEST2 is not set +CONFIG_FEATURE_TEST_64=y +# CONFIG_TIMEOUT is not set +# CONFIG_TOUCH is not set +# CONFIG_FEATURE_TOUCH_NODEREF is not set +# CONFIG_FEATURE_TOUCH_SUSV3 is not set +# CONFIG_TR is not set +# CONFIG_FEATURE_TR_CLASSES is not set +# CONFIG_FEATURE_TR_EQUIV is not set +# CONFIG_TRUE is not set +# CONFIG_TRUNCATE is not set +# CONFIG_TTY is not set +# CONFIG_UNAME is not set +CONFIG_UNAME_OSNAME="" +# CONFIG_BB_ARCH is not set +# CONFIG_UNIQ is not set +# CONFIG_UNLINK is not set +# CONFIG_USLEEP is not set +# CONFIG_UUDECODE is not set +# CONFIG_BASE64 is not set +# CONFIG_UUENCODE is not set +# CONFIG_WC is not set +# CONFIG_FEATURE_WC_LARGE is not set +# CONFIG_WHOAMI is not set +# CONFIG_WHO is not set +# CONFIG_W is not set +# CONFIG_USERS is not set +# CONFIG_YES is not set + +# +# Common options +# +# CONFIG_FEATURE_VERBOSE is not set +# CONFIG_FEATURE_PRESERVE_HARDLINKS is not set +# CONFIG_FEATURE_HUMAN_READABLE is not set + +# +# Console Utilities +# +# CONFIG_CHVT is not set +# CONFIG_CLEAR is not set +# CONFIG_DEALLOCVT is not set +# CONFIG_DUMPKMAP is not set +# CONFIG_FGCONSOLE is not set +# CONFIG_KBD_MODE is not set +# CONFIG_LOADFONT is not set +# CONFIG_SETFONT is not set +# CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set +CONFIG_DEFAULT_SETFONT_DIR="" +# CONFIG_FEATURE_LOADFONT_PSF2 is not set +# CONFIG_FEATURE_LOADFONT_RAW is not set +# CONFIG_LOADKMAP is not set +# CONFIG_OPENVT is not set +# CONFIG_RESET is not set +# CONFIG_RESIZE is not set +# CONFIG_FEATURE_RESIZE_PRINT is not set +# CONFIG_SETCONSOLE is not set +# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set +# CONFIG_SETKEYCODES is not set +# CONFIG_SETLOGCONS is not set +# CONFIG_SHOWKEY is not set + +# +# Debian Utilities +# +# CONFIG_PIPE_PROGRESS is not set +# CONFIG_RUN_PARTS is not set +# CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set +# CONFIG_FEATURE_RUN_PARTS_FANCY is not set +# CONFIG_START_STOP_DAEMON is not set +# CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set +# CONFIG_FEATURE_START_STOP_DAEMON_FANCY is not set +# CONFIG_WHICH is not set + +# +# klibc-utils +# +# CONFIG_MINIPS is not set +# CONFIG_NUKE is not set +# CONFIG_RESUME is not set +# CONFIG_RUN_INIT is not set + +# +# Editors +# +# CONFIG_AWK is not set +# CONFIG_FEATURE_AWK_LIBM is not set +# CONFIG_FEATURE_AWK_GNU_EXTENSIONS is not set +# CONFIG_CMP is not set +# CONFIG_DIFF is not set +# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set +# CONFIG_FEATURE_DIFF_DIR is not set +# CONFIG_ED is not set +# CONFIG_PATCH is not set +# CONFIG_SED is not set +# CONFIG_VI is not set +CONFIG_FEATURE_VI_MAX_LEN=0 +# CONFIG_FEATURE_VI_8BIT is not set +# CONFIG_FEATURE_VI_COLON is not set +# CONFIG_FEATURE_VI_YANKMARK is not set +# CONFIG_FEATURE_VI_SEARCH is not set +# CONFIG_FEATURE_VI_REGEX_SEARCH is not set +# CONFIG_FEATURE_VI_USE_SIGNALS is not set +# CONFIG_FEATURE_VI_DOT_CMD is not set +# CONFIG_FEATURE_VI_READONLY is not set +# CONFIG_FEATURE_VI_SETOPTS is not set +# CONFIG_FEATURE_VI_SET is not set +# CONFIG_FEATURE_VI_WIN_RESIZE is not set +# CONFIG_FEATURE_VI_ASK_TERMINAL is not set +# CONFIG_FEATURE_VI_UNDO is not set +# CONFIG_FEATURE_VI_UNDO_QUEUE is not set +CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=0 +# CONFIG_FEATURE_ALLOW_EXEC is not set + +# +# Finding Utilities +# +# CONFIG_FIND is not set +# CONFIG_FEATURE_FIND_PRINT0 is not set +# CONFIG_FEATURE_FIND_MTIME is not set +# CONFIG_FEATURE_FIND_MMIN is not set +# CONFIG_FEATURE_FIND_PERM is not set +# CONFIG_FEATURE_FIND_TYPE is not set +# CONFIG_FEATURE_FIND_EXECUTABLE is not set +# CONFIG_FEATURE_FIND_XDEV is not set +# CONFIG_FEATURE_FIND_MAXDEPTH is not set +# CONFIG_FEATURE_FIND_NEWER is not set +# CONFIG_FEATURE_FIND_INUM is not set +# CONFIG_FEATURE_FIND_EXEC is not set +# CONFIG_FEATURE_FIND_EXEC_PLUS is not set +# CONFIG_FEATURE_FIND_USER is not set +# CONFIG_FEATURE_FIND_GROUP is not set +# CONFIG_FEATURE_FIND_NOT is not set +# CONFIG_FEATURE_FIND_DEPTH is not set +# CONFIG_FEATURE_FIND_PAREN is not set +# CONFIG_FEATURE_FIND_SIZE is not set +# CONFIG_FEATURE_FIND_PRUNE is not set +# CONFIG_FEATURE_FIND_QUIT is not set +# CONFIG_FEATURE_FIND_DELETE is not set +# CONFIG_FEATURE_FIND_EMPTY is not set +# CONFIG_FEATURE_FIND_PATH is not set +# CONFIG_FEATURE_FIND_REGEX is not set +# CONFIG_FEATURE_FIND_CONTEXT is not set +# CONFIG_FEATURE_FIND_LINKS is not set +# CONFIG_GREP is not set +# CONFIG_EGREP is not set +# CONFIG_FGREP is not set +# CONFIG_FEATURE_GREP_CONTEXT is not set +# CONFIG_XARGS is not set +# CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION is not set +# CONFIG_FEATURE_XARGS_SUPPORT_QUOTES is not set +# CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM is not set +# CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR is not set +# CONFIG_FEATURE_XARGS_SUPPORT_PARALLEL is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ARGS_FILE is not set + +# +# Init Utilities +# +# CONFIG_BOOTCHARTD is not set +# CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set +# CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set +# CONFIG_HALT is not set +# CONFIG_POWEROFF is not set +# CONFIG_REBOOT is not set +# CONFIG_FEATURE_WAIT_FOR_INIT is not set +# CONFIG_FEATURE_CALL_TELINIT is not set +CONFIG_TELINIT_PATH="" +# CONFIG_INIT is not set +# CONFIG_LINUXRC is not set +# CONFIG_FEATURE_USE_INITTAB is not set +# CONFIG_FEATURE_KILL_REMOVED is not set +CONFIG_FEATURE_KILL_DELAY=0 +# CONFIG_FEATURE_INIT_SCTTY is not set +# CONFIG_FEATURE_INIT_SYSLOG is not set +# CONFIG_FEATURE_INIT_QUIET is not set +# CONFIG_FEATURE_INIT_COREDUMPS is not set +CONFIG_INIT_TERMINAL_TYPE="" +# CONFIG_FEATURE_INIT_MODIFY_CMDLINE is not set + +# +# Login/Password Management Utilities +# +# CONFIG_FEATURE_SHADOWPASSWDS is not set +# CONFIG_USE_BB_PWD_GRP is not set +# CONFIG_USE_BB_SHADOW is not set +# CONFIG_USE_BB_CRYPT is not set +# CONFIG_USE_BB_CRYPT_SHA is not set +# CONFIG_ADDGROUP is not set +# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set +# CONFIG_ADD_SHELL is not set +# CONFIG_REMOVE_SHELL is not set +# CONFIG_ADDUSER is not set +# CONFIG_FEATURE_CHECK_NAMES is not set +CONFIG_LAST_ID=0 +CONFIG_FIRST_SYSTEM_ID=0 +CONFIG_LAST_SYSTEM_ID=0 +# CONFIG_CHPASSWD is not set +CONFIG_FEATURE_DEFAULT_PASSWD_ALGO="" +# CONFIG_CRYPTPW is not set +# CONFIG_MKPASSWD is not set +# CONFIG_DELUSER is not set +# CONFIG_DELGROUP is not set +# CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set +# CONFIG_GETTY is not set +# CONFIG_LOGIN is not set +# CONFIG_LOGIN_SESSION_AS_CHILD is not set +# CONFIG_LOGIN_SCRIPTS is not set +# CONFIG_FEATURE_NOLOGIN is not set +# CONFIG_FEATURE_SECURETTY is not set +# CONFIG_PASSWD is not set +# CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set +# CONFIG_SU is not set +# CONFIG_FEATURE_SU_SYSLOG is not set +# CONFIG_FEATURE_SU_CHECKS_SHELLS is not set +# CONFIG_FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY is not set +# CONFIG_SULOGIN is not set +# CONFIG_VLOCK is not set + +# +# Linux Ext2 FS Progs +# +# CONFIG_CHATTR is not set +# CONFIG_FSCK is not set +# CONFIG_LSATTR is not set +# CONFIG_TUNE2FS is not set + +# +# Linux Module Utilities +# +# CONFIG_MODPROBE_SMALL is not set +# CONFIG_DEPMOD is not set +# CONFIG_INSMOD is not set +# CONFIG_LSMOD is not set +# CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set +# CONFIG_MODINFO is not set +# CONFIG_MODPROBE is not set +# CONFIG_FEATURE_MODPROBE_BLACKLIST is not set +# CONFIG_RMMOD is not set + +# +# Options common to multiple modutils +# +# CONFIG_FEATURE_CMDLINE_MODULE_OPTIONS is not set +# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set +# CONFIG_FEATURE_2_4_MODULES is not set +# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set +# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set +# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set +# CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set +# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set +# CONFIG_FEATURE_MODUTILS_ALIAS is not set +# CONFIG_FEATURE_MODUTILS_SYMBOLS is not set +CONFIG_DEFAULT_MODULES_DIR="" +CONFIG_DEFAULT_DEPMOD_FILE="" + +# +# Linux System Utilities +# +# CONFIG_ACPID is not set +# CONFIG_FEATURE_ACPID_COMPAT is not set +# CONFIG_BLKDISCARD is not set +# CONFIG_BLKID is not set +# CONFIG_FEATURE_BLKID_TYPE is not set +# CONFIG_BLOCKDEV is not set +# CONFIG_CAL is not set +# CONFIG_CHRT is not set +# CONFIG_DMESG is not set +# CONFIG_FEATURE_DMESG_PRETTY is not set +# CONFIG_EJECT is not set +# CONFIG_FEATURE_EJECT_SCSI is not set +# CONFIG_FALLOCATE is not set +# CONFIG_FATATTR is not set +# CONFIG_FBSET is not set +# CONFIG_FEATURE_FBSET_FANCY is not set +# CONFIG_FEATURE_FBSET_READMODE is not set +# CONFIG_FDFORMAT is not set +# CONFIG_FDISK is not set +# CONFIG_FDISK_SUPPORT_LARGE_DISKS is not set +# CONFIG_FEATURE_FDISK_WRITABLE is not set +# CONFIG_FEATURE_AIX_LABEL is not set +# CONFIG_FEATURE_SGI_LABEL is not set +# CONFIG_FEATURE_SUN_LABEL is not set +# CONFIG_FEATURE_OSF_LABEL is not set +# CONFIG_FEATURE_GPT_LABEL is not set +# CONFIG_FEATURE_FDISK_ADVANCED is not set +# CONFIG_FINDFS is not set +# CONFIG_FLOCK is not set +# CONFIG_FDFLUSH is not set +# CONFIG_FREERAMDISK is not set +# CONFIG_FSCK_MINIX is not set +# CONFIG_FSFREEZE is not set +# CONFIG_FSTRIM is not set +# CONFIG_GETOPT is not set +# CONFIG_FEATURE_GETOPT_LONG is not set +# CONFIG_HEXDUMP is not set +# CONFIG_FEATURE_HEXDUMP_REVERSE is not set +# CONFIG_HD is not set +# CONFIG_XXD is not set +# CONFIG_HWCLOCK is not set +# CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set +# CONFIG_IONICE is not set +# CONFIG_IPCRM is not set +# CONFIG_IPCS is not set +# CONFIG_LAST is not set +# CONFIG_FEATURE_LAST_FANCY is not set +# CONFIG_LOSETUP is not set +# CONFIG_LSPCI is not set +# CONFIG_LSUSB is not set +# CONFIG_MDEV is not set +# CONFIG_FEATURE_MDEV_CONF is not set +# CONFIG_FEATURE_MDEV_RENAME is not set +# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set +# CONFIG_FEATURE_MDEV_EXEC is not set +# CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set +# CONFIG_FEATURE_MDEV_DAEMON is not set +# CONFIG_MESG is not set +# CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP is not set +# CONFIG_MKE2FS is not set +# CONFIG_MKFS_EXT2 is not set +# CONFIG_MKFS_MINIX is not set +# CONFIG_FEATURE_MINIX2 is not set +# CONFIG_MKFS_REISER is not set +# CONFIG_MKDOSFS is not set +# CONFIG_MKFS_VFAT is not set +# CONFIG_MKSWAP is not set +# CONFIG_FEATURE_MKSWAP_UUID is not set +# CONFIG_MORE is not set +# CONFIG_MOUNT is not set +# CONFIG_FEATURE_MOUNT_FAKE is not set +# CONFIG_FEATURE_MOUNT_VERBOSE is not set +# CONFIG_FEATURE_MOUNT_HELPERS is not set +# CONFIG_FEATURE_MOUNT_LABEL is not set +# CONFIG_FEATURE_MOUNT_NFS is not set +# CONFIG_FEATURE_MOUNT_CIFS is not set +# CONFIG_FEATURE_MOUNT_FLAGS is not set +# CONFIG_FEATURE_MOUNT_FSTAB is not set +# CONFIG_FEATURE_MOUNT_OTHERTAB is not set +# CONFIG_MOUNTPOINT is not set +# CONFIG_NOLOGIN is not set +# CONFIG_NOLOGIN_DEPENDENCIES is not set +# CONFIG_NSENTER is not set +# CONFIG_PIVOT_ROOT is not set +# CONFIG_RDATE is not set +# CONFIG_RDEV is not set +# CONFIG_READPROFILE is not set +# CONFIG_RENICE is not set +# CONFIG_REV is not set +# CONFIG_RTCWAKE is not set +# CONFIG_SCRIPT is not set +# CONFIG_SCRIPTREPLAY is not set +# CONFIG_SETARCH is not set +# CONFIG_LINUX32 is not set +# CONFIG_LINUX64 is not set +# CONFIG_SETPRIV is not set +# CONFIG_FEATURE_SETPRIV_DUMP is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITIES is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITY_NAMES is not set +# CONFIG_SETSID is not set +# CONFIG_SWAPON is not set +# CONFIG_FEATURE_SWAPON_DISCARD is not set +# CONFIG_FEATURE_SWAPON_PRI is not set +# CONFIG_SWAPOFF is not set +# CONFIG_FEATURE_SWAPONOFF_LABEL is not set +# CONFIG_SWITCH_ROOT is not set +# CONFIG_TASKSET is not set +# CONFIG_FEATURE_TASKSET_FANCY is not set +# CONFIG_FEATURE_TASKSET_CPULIST is not set +# CONFIG_UEVENT is not set +# CONFIG_UMOUNT is not set +# CONFIG_FEATURE_UMOUNT_ALL is not set +# CONFIG_UNSHARE is not set +# CONFIG_WALL is not set +# CONFIG_FEATURE_MOUNT_LOOP is not set +# CONFIG_FEATURE_MOUNT_LOOP_CREATE is not set +# CONFIG_FEATURE_MTAB_SUPPORT is not set +# CONFIG_VOLUMEID is not set +# CONFIG_FEATURE_VOLUMEID_BCACHE is not set +# CONFIG_FEATURE_VOLUMEID_BTRFS is not set +# CONFIG_FEATURE_VOLUMEID_CRAMFS is not set +# CONFIG_FEATURE_VOLUMEID_EXFAT is not set +# CONFIG_FEATURE_VOLUMEID_EXT is not set +# CONFIG_FEATURE_VOLUMEID_F2FS is not set +# CONFIG_FEATURE_VOLUMEID_FAT is not set +# CONFIG_FEATURE_VOLUMEID_HFS is not set +# CONFIG_FEATURE_VOLUMEID_ISO9660 is not set +# CONFIG_FEATURE_VOLUMEID_JFS is not set +# CONFIG_FEATURE_VOLUMEID_LFS is not set +# CONFIG_FEATURE_VOLUMEID_LINUXRAID is not set +# CONFIG_FEATURE_VOLUMEID_LINUXSWAP is not set +# CONFIG_FEATURE_VOLUMEID_LUKS is not set +# CONFIG_FEATURE_VOLUMEID_MINIX is not set +# CONFIG_FEATURE_VOLUMEID_NILFS is not set +# CONFIG_FEATURE_VOLUMEID_NTFS is not set +# CONFIG_FEATURE_VOLUMEID_OCFS2 is not set +# CONFIG_FEATURE_VOLUMEID_REISERFS is not set +# CONFIG_FEATURE_VOLUMEID_ROMFS is not set +# CONFIG_FEATURE_VOLUMEID_SQUASHFS is not set +# CONFIG_FEATURE_VOLUMEID_SYSV is not set +# CONFIG_FEATURE_VOLUMEID_UBIFS is not set +# CONFIG_FEATURE_VOLUMEID_UDF is not set +# CONFIG_FEATURE_VOLUMEID_XFS is not set + +# +# Miscellaneous Utilities +# +# CONFIG_ADJTIMEX is not set +# CONFIG_BBCONFIG is not set +# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set +# CONFIG_BC is not set +# CONFIG_DC is not set +# CONFIG_FEATURE_DC_BIG is not set +# CONFIG_FEATURE_DC_LIBM is not set +# CONFIG_FEATURE_BC_INTERACTIVE is not set +# CONFIG_FEATURE_BC_LONG_OPTIONS is not set +# CONFIG_BEEP is not set +CONFIG_FEATURE_BEEP_FREQ=0 +CONFIG_FEATURE_BEEP_LENGTH_MS=0 +# CONFIG_CHAT is not set +# CONFIG_FEATURE_CHAT_NOFAIL is not set +# CONFIG_FEATURE_CHAT_TTY_HIFI is not set +# CONFIG_FEATURE_CHAT_IMPLICIT_CR is not set +# CONFIG_FEATURE_CHAT_SWALLOW_OPTS is not set +# CONFIG_FEATURE_CHAT_SEND_ESCAPES is not set +# CONFIG_FEATURE_CHAT_VAR_ABORT_LEN is not set +# CONFIG_FEATURE_CHAT_CLR_ABORT is not set +# CONFIG_CONSPY is not set +# CONFIG_CROND is not set +# CONFIG_FEATURE_CROND_D is not set +# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set +# CONFIG_FEATURE_CROND_SPECIAL_TIMES is not set +CONFIG_FEATURE_CROND_DIR="" +# CONFIG_CRONTAB is not set +# CONFIG_DEVFSD is not set +# CONFIG_DEVFSD_MODLOAD is not set +# CONFIG_DEVFSD_FG_NP is not set +# CONFIG_DEVFSD_VERBOSE is not set +# CONFIG_FEATURE_DEVFS is not set +# CONFIG_DEVMEM is not set +# CONFIG_FBSPLASH is not set +# CONFIG_FLASHCP is not set +# CONFIG_FLASH_ERASEALL is not set +# CONFIG_FLASH_LOCK is not set +# CONFIG_FLASH_UNLOCK is not set +# CONFIG_HDPARM is not set +# CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set +# CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set +# CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set +# CONFIG_HEXEDIT is not set +# CONFIG_I2CGET is not set +# CONFIG_I2CSET is not set +# CONFIG_I2CDUMP is not set +# CONFIG_I2CDETECT is not set +# CONFIG_I2CTRANSFER is not set +# CONFIG_INOTIFYD is not set +# CONFIG_LESS is not set +CONFIG_FEATURE_LESS_MAXLINES=0 +# CONFIG_FEATURE_LESS_BRACKETS is not set +# CONFIG_FEATURE_LESS_FLAGS is not set +# CONFIG_FEATURE_LESS_TRUNCATE is not set +# CONFIG_FEATURE_LESS_MARKS is not set +# CONFIG_FEATURE_LESS_REGEXP is not set +# CONFIG_FEATURE_LESS_WINCH is not set +# CONFIG_FEATURE_LESS_ASK_TERMINAL is not set +# CONFIG_FEATURE_LESS_DASHCMD is not set +# CONFIG_FEATURE_LESS_LINENUMS is not set +# CONFIG_FEATURE_LESS_RAW is not set +# CONFIG_FEATURE_LESS_ENV is not set +# CONFIG_LSSCSI is not set +# CONFIG_MAKEDEVS is not set +# CONFIG_FEATURE_MAKEDEVS_LEAF is not set +# CONFIG_FEATURE_MAKEDEVS_TABLE is not set +# CONFIG_MAN is not set +# CONFIG_MICROCOM is not set +# CONFIG_MIM is not set +# CONFIG_MT is not set +# CONFIG_NANDWRITE is not set +# CONFIG_NANDDUMP is not set +# CONFIG_PARTPROBE is not set +# CONFIG_RAIDAUTORUN is not set +# CONFIG_READAHEAD is not set +# CONFIG_RFKILL is not set +# CONFIG_RUNLEVEL is not set +# CONFIG_RX is not set +# CONFIG_SETFATTR is not set +# CONFIG_SETSERIAL is not set +# CONFIG_STRINGS is not set +# CONFIG_TIME is not set +# CONFIG_TS is not set +# CONFIG_TTYSIZE is not set +# CONFIG_UBIRENAME is not set +# CONFIG_UBIATTACH is not set +# CONFIG_UBIDETACH is not set +# CONFIG_UBIMKVOL is not set +# CONFIG_UBIRMVOL is not set +# CONFIG_UBIRSVOL is not set +# CONFIG_UBIUPDATEVOL is not set +# CONFIG_VOLNAME is not set +# CONFIG_WATCHDOG is not set + +# +# Networking Utilities +# +# CONFIG_FEATURE_IPV6 is not set +# CONFIG_FEATURE_UNIX_LOCAL is not set +# CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set +# CONFIG_VERBOSE_RESOLUTION_ERRORS is not set +# CONFIG_FEATURE_TLS_SHA1 is not set +# CONFIG_ARP is not set +# CONFIG_ARPING is not set +# CONFIG_BRCTL is not set +# CONFIG_FEATURE_BRCTL_FANCY is not set +# CONFIG_FEATURE_BRCTL_SHOW is not set +# CONFIG_DNSD is not set +# CONFIG_ETHER_WAKE is not set +# CONFIG_FTPD is not set +# CONFIG_FEATURE_FTPD_WRITE is not set +# CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST is not set +# CONFIG_FEATURE_FTPD_AUTHENTICATION is not set +# CONFIG_FTPGET is not set +# CONFIG_FTPPUT is not set +# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set +# CONFIG_HOSTNAME is not set +# CONFIG_DNSDOMAINNAME is not set +# CONFIG_HTTPD is not set +# CONFIG_FEATURE_HTTPD_RANGES is not set +# CONFIG_FEATURE_HTTPD_SETUID is not set +# CONFIG_FEATURE_HTTPD_BASIC_AUTH is not set +# CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set +# CONFIG_FEATURE_HTTPD_CGI is not set +# CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set +# CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set +# CONFIG_FEATURE_HTTPD_ENCODE_URL_STR is not set +# CONFIG_FEATURE_HTTPD_ERROR_PAGES is not set +# CONFIG_FEATURE_HTTPD_PROXY is not set +# CONFIG_FEATURE_HTTPD_GZIP is not set +# CONFIG_IFCONFIG is not set +# CONFIG_FEATURE_IFCONFIG_STATUS is not set +# CONFIG_FEATURE_IFCONFIG_SLIP is not set +# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set +# CONFIG_FEATURE_IFCONFIG_HW is not set +# CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set +# CONFIG_IFENSLAVE is not set +# CONFIG_IFPLUGD is not set +# CONFIG_IFUP is not set +# CONFIG_IFDOWN is not set +CONFIG_IFUPDOWN_IFSTATE_PATH="" +# CONFIG_FEATURE_IFUPDOWN_IP is not set +# CONFIG_FEATURE_IFUPDOWN_IPV4 is not set +# CONFIG_FEATURE_IFUPDOWN_IPV6 is not set +# CONFIG_FEATURE_IFUPDOWN_MAPPING is not set +# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set +# CONFIG_INETD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set +# CONFIG_FEATURE_INETD_RPC is not set +# CONFIG_IP is not set +# CONFIG_IPADDR is not set +# CONFIG_IPLINK is not set +# CONFIG_IPROUTE is not set +# CONFIG_IPTUNNEL is not set +# CONFIG_IPRULE is not set +# CONFIG_IPNEIGH is not set +# CONFIG_FEATURE_IP_ADDRESS is not set +# CONFIG_FEATURE_IP_LINK is not set +# CONFIG_FEATURE_IP_ROUTE is not set +CONFIG_FEATURE_IP_ROUTE_DIR="" +# CONFIG_FEATURE_IP_TUNNEL is not set +# CONFIG_FEATURE_IP_RULE is not set +# CONFIG_FEATURE_IP_NEIGH is not set +# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set +# CONFIG_IPCALC is not set +# CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set +# CONFIG_FEATURE_IPCALC_FANCY is not set +# CONFIG_FAKEIDENTD is not set +# CONFIG_NAMEIF is not set +# CONFIG_FEATURE_NAMEIF_EXTENDED is not set +# CONFIG_NBDCLIENT is not set +# CONFIG_NC is not set +# CONFIG_NETCAT is not set +# CONFIG_NC_SERVER is not set +# CONFIG_NC_EXTRA is not set +# CONFIG_NC_110_COMPAT is not set +# CONFIG_NETSTAT is not set +# CONFIG_FEATURE_NETSTAT_WIDE is not set +# CONFIG_FEATURE_NETSTAT_PRG is not set +# CONFIG_NSLOOKUP is not set +# CONFIG_FEATURE_NSLOOKUP_BIG is not set +# CONFIG_FEATURE_NSLOOKUP_LONG_OPTIONS is not set +# CONFIG_NTPD is not set +# CONFIG_FEATURE_NTPD_SERVER is not set +# CONFIG_FEATURE_NTPD_CONF is not set +# CONFIG_FEATURE_NTP_AUTH is not set +# CONFIG_PING is not set +# CONFIG_PING6 is not set +# CONFIG_FEATURE_FANCY_PING is not set +# CONFIG_PSCAN is not set +# CONFIG_ROUTE is not set +# CONFIG_SLATTACH is not set +# CONFIG_SSL_CLIENT is not set +# CONFIG_TC is not set +# CONFIG_FEATURE_TC_INGRESS is not set +# CONFIG_TCPSVD is not set +# CONFIG_UDPSVD is not set +# CONFIG_TELNET is not set +# CONFIG_FEATURE_TELNET_TTYPE is not set +# CONFIG_FEATURE_TELNET_AUTOLOGIN is not set +# CONFIG_FEATURE_TELNET_WIDTH is not set +# CONFIG_TELNETD is not set +# CONFIG_FEATURE_TELNETD_STANDALONE is not set +# CONFIG_FEATURE_TELNETD_INETD_WAIT is not set +# CONFIG_TFTP is not set +# CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set +# CONFIG_FEATURE_TFTP_HPA_COMPAT is not set +# CONFIG_TFTPD is not set +# CONFIG_FEATURE_TFTP_GET is not set +# CONFIG_FEATURE_TFTP_PUT is not set +# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set +# CONFIG_TFTP_DEBUG is not set +# CONFIG_TLS is not set +# CONFIG_TRACEROUTE is not set +# CONFIG_TRACEROUTE6 is not set +# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set +# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set +# CONFIG_TUNCTL is not set +# CONFIG_FEATURE_TUNCTL_UG is not set +# CONFIG_VCONFIG is not set +# CONFIG_WGET is not set +# CONFIG_FEATURE_WGET_LONG_OPTIONS is not set +# CONFIG_FEATURE_WGET_STATUSBAR is not set +# CONFIG_FEATURE_WGET_AUTHENTICATION is not set +# CONFIG_FEATURE_WGET_TIMEOUT is not set +# CONFIG_FEATURE_WGET_HTTPS is not set +# CONFIG_FEATURE_WGET_OPENSSL is not set +# CONFIG_WHOIS is not set +# CONFIG_ZCIP is not set +# CONFIG_UDHCPD is not set +# CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC is not set +# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set +CONFIG_DHCPD_LEASES_FILE="" +# CONFIG_DUMPLEASES is not set +# CONFIG_DHCPRELAY is not set +# CONFIG_UDHCPC is not set +# CONFIG_FEATURE_UDHCPC_ARPING is not set +# CONFIG_FEATURE_UDHCPC_SANITIZEOPT is not set +CONFIG_UDHCPC_DEFAULT_SCRIPT="" +# CONFIG_UDHCPC6 is not set +# CONFIG_FEATURE_UDHCPC6_RFC3646 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4704 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4833 is not set +# CONFIG_FEATURE_UDHCPC6_RFC5970 is not set +# CONFIG_FEATURE_UDHCP_PORT is not set +CONFIG_UDHCP_DEBUG=0 +CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=0 +# CONFIG_FEATURE_UDHCP_RFC3397 is not set +# CONFIG_FEATURE_UDHCP_8021Q is not set +CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="" + +# +# Print Utilities +# +# CONFIG_LPD is not set +# CONFIG_LPR is not set +# CONFIG_LPQ is not set + +# +# Mail Utilities +# +# CONFIG_MAKEMIME is not set +# CONFIG_POPMAILDIR is not set +# CONFIG_FEATURE_POPMAILDIR_DELIVERY is not set +# CONFIG_REFORMIME is not set +# CONFIG_FEATURE_REFORMIME_COMPAT is not set +# CONFIG_SENDMAIL is not set +CONFIG_FEATURE_MIME_CHARSET="" + +# +# Process Utilities +# +# CONFIG_FREE is not set +# CONFIG_FUSER is not set +# CONFIG_IOSTAT is not set +# CONFIG_KILL is not set +# CONFIG_KILLALL is not set +# CONFIG_KILLALL5 is not set +# CONFIG_LSOF is not set +# CONFIG_MPSTAT is not set +# CONFIG_NMETER is not set +# CONFIG_PGREP is not set +# CONFIG_PKILL is not set +# CONFIG_PIDOF is not set +# CONFIG_FEATURE_PIDOF_SINGLE is not set +# CONFIG_FEATURE_PIDOF_OMIT is not set +# CONFIG_PMAP is not set +# CONFIG_POWERTOP is not set +# CONFIG_FEATURE_POWERTOP_INTERACTIVE is not set +# CONFIG_PS is not set +# CONFIG_FEATURE_PS_WIDE is not set +# CONFIG_FEATURE_PS_LONG is not set +# CONFIG_FEATURE_PS_TIME is not set +# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set +# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set +# CONFIG_PSTREE is not set +# CONFIG_PWDX is not set +# CONFIG_SMEMCAP is not set +# CONFIG_BB_SYSCTL is not set +# CONFIG_TOP is not set +# CONFIG_FEATURE_TOP_INTERACTIVE is not set +# CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE is not set +# CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS is not set +# CONFIG_FEATURE_TOP_SMP_CPU is not set +# CONFIG_FEATURE_TOP_DECIMALS is not set +# CONFIG_FEATURE_TOP_SMP_PROCESS is not set +# CONFIG_FEATURE_TOPMEM is not set +# CONFIG_UPTIME is not set +# CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set +# CONFIG_WATCH is not set +# CONFIG_FEATURE_SHOW_THREADS is not set + +# +# Runit Utilities +# +# CONFIG_CHPST is not set +# CONFIG_SETUIDGID is not set +# CONFIG_ENVUIDGID is not set +# CONFIG_ENVDIR is not set +# CONFIG_SOFTLIMIT is not set +# CONFIG_RUNSV is not set +# CONFIG_RUNSVDIR is not set +# CONFIG_FEATURE_RUNSVDIR_LOG is not set +# CONFIG_SV is not set +CONFIG_SV_DEFAULT_SERVICE_DIR="" +# CONFIG_SVC is not set +# CONFIG_SVOK is not set +# CONFIG_SVLOGD is not set +# CONFIG_CHCON is not set +# CONFIG_GETENFORCE is not set +# CONFIG_GETSEBOOL is not set +# CONFIG_LOAD_POLICY is not set +# CONFIG_MATCHPATHCON is not set +# CONFIG_RUNCON is not set +# CONFIG_SELINUXENABLED is not set +# CONFIG_SESTATUS is not set +# CONFIG_SETENFORCE is not set +# CONFIG_SETFILES is not set +# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set +# CONFIG_RESTORECON is not set +# CONFIG_SETSEBOOL is not set + +# +# Shells +# +CONFIG_SH_IS_ASH=y +# CONFIG_SH_IS_HUSH is not set +# CONFIG_SH_IS_NONE is not set +# CONFIG_BASH_IS_ASH is not set +# CONFIG_BASH_IS_HUSH is not set +CONFIG_BASH_IS_NONE=y +CONFIG_SHELL_ASH=y +CONFIG_ASH=y +CONFIG_ASH_OPTIMIZE_FOR_SIZE=y +CONFIG_ASH_INTERNAL_GLOB=y +CONFIG_ASH_BASH_COMPAT=y +CONFIG_ASH_BASH_SOURCE_CURDIR=y +CONFIG_ASH_BASH_NOT_FOUND_HOOK=y +CONFIG_ASH_JOB_CONTROL=y +CONFIG_ASH_ALIAS=y +CONFIG_ASH_RANDOM_SUPPORT=y +CONFIG_ASH_EXPAND_PRMT=y +CONFIG_ASH_IDLE_TIMEOUT=y +CONFIG_ASH_MAIL=y +CONFIG_ASH_ECHO=y +CONFIG_ASH_PRINTF=y +CONFIG_ASH_TEST=y +CONFIG_ASH_HELP=y +CONFIG_ASH_GETOPTS=y +CONFIG_ASH_CMDCMD=y +CONFIG_CTTYHACK=y +CONFIG_HUSH=y +CONFIG_SHELL_HUSH=y +CONFIG_HUSH_BASH_COMPAT=y +CONFIG_HUSH_BRACE_EXPANSION=y +CONFIG_HUSH_LINENO_VAR=y +CONFIG_HUSH_BASH_SOURCE_CURDIR=y +CONFIG_HUSH_INTERACTIVE=y +# CONFIG_HUSH_SAVEHISTORY is not set +CONFIG_HUSH_JOB=y +CONFIG_HUSH_TICK=y +CONFIG_HUSH_IF=y +CONFIG_HUSH_LOOPS=y +CONFIG_HUSH_CASE=y +CONFIG_HUSH_FUNCTIONS=y +CONFIG_HUSH_LOCAL=y +CONFIG_HUSH_RANDOM_SUPPORT=y +CONFIG_HUSH_MODE_X=y +CONFIG_HUSH_ECHO=y +CONFIG_HUSH_PRINTF=y +CONFIG_HUSH_TEST=y +CONFIG_HUSH_HELP=y +CONFIG_HUSH_EXPORT=y +CONFIG_HUSH_EXPORT_N=y +CONFIG_HUSH_READONLY=y +CONFIG_HUSH_KILL=y +CONFIG_HUSH_WAIT=y +CONFIG_HUSH_COMMAND=y +CONFIG_HUSH_TRAP=y +CONFIG_HUSH_TYPE=y +CONFIG_HUSH_TIMES=y +CONFIG_HUSH_READ=y +CONFIG_HUSH_SET=y +CONFIG_HUSH_UNSET=y +CONFIG_HUSH_ULIMIT=y +CONFIG_HUSH_UMASK=y +CONFIG_HUSH_GETOPTS=y +# CONFIG_HUSH_MEMLEAK is not set + +# +# Options common to all shells +# +CONFIG_FEATURE_SH_MATH=y +CONFIG_FEATURE_SH_MATH_64=y +CONFIG_FEATURE_SH_MATH_BASE=y +CONFIG_FEATURE_SH_EXTRA_QUIET=y +CONFIG_FEATURE_SH_STANDALONE=y +CONFIG_FEATURE_SH_NOFORK=y +# CONFIG_FEATURE_SH_READ_FRAC is not set +# CONFIG_FEATURE_SH_HISTFILESIZE is not set +# CONFIG_FEATURE_SH_EMBEDDED_SCRIPTS is not set + +# +# System Logging Utilities +# +# CONFIG_KLOGD is not set +# CONFIG_FEATURE_KLOGD_KLOGCTL is not set +# CONFIG_LOGGER is not set +# CONFIG_LOGREAD is not set +# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set +# CONFIG_SYSLOGD is not set +# CONFIG_FEATURE_ROTATE_LOGFILE is not set +# CONFIG_FEATURE_REMOTE_LOG is not set +# CONFIG_FEATURE_SYSLOGD_DUP is not set +# CONFIG_FEATURE_SYSLOGD_CFG is not set +# CONFIG_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS is not set +CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0 +# CONFIG_FEATURE_IPC_SYSLOG is not set +CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 +# CONFIG_FEATURE_KMSG_SYSLOG is not set diff --git a/BUSYBOX/x86_64_hexdump.config b/BUSYBOX/x86_64_hexdump.config new file mode 100644 index 0000000..d13aa42 --- /dev/null +++ b/BUSYBOX/x86_64_hexdump.config @@ -0,0 +1,1166 @@ +# +# Automatically generated make config: don't edit +# Busybox version: 1.32.0 +# Tue Dec 8 03:03:31 2020 +# +CONFIG_HAVE_DOT_CONFIG=y + +# +# Settings +# +# CONFIG_DESKTOP is not set +# CONFIG_EXTRA_COMPAT is not set +# CONFIG_FEDORA_COMPAT is not set +# CONFIG_INCLUDE_SUSv2 is not set +# CONFIG_LONG_OPTS is not set +# CONFIG_SHOW_USAGE is not set +# CONFIG_FEATURE_VERBOSE_USAGE is not set +# CONFIG_FEATURE_COMPRESS_USAGE is not set +# CONFIG_LFS is not set +# CONFIG_PAM is not set +# CONFIG_FEATURE_DEVPTS is not set +# CONFIG_FEATURE_UTMP is not set +# CONFIG_FEATURE_WTMP is not set +# CONFIG_FEATURE_PIDFILE is not set +CONFIG_PID_FILE_PATH="" +# CONFIG_BUSYBOX is not set +# CONFIG_FEATURE_SHOW_SCRIPT is not set +# CONFIG_FEATURE_INSTALLER is not set +# CONFIG_INSTALL_NO_USR is not set +# CONFIG_FEATURE_SUID is not set +# CONFIG_FEATURE_SUID_CONFIG is not set +# CONFIG_FEATURE_SUID_CONFIG_QUIET is not set +# CONFIG_FEATURE_PREFER_APPLETS is not set +CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" +# CONFIG_SELINUX is not set +# CONFIG_FEATURE_CLEAN_UP is not set +# CONFIG_FEATURE_SYSLOG_INFO is not set +# CONFIG_FEATURE_SYSLOG is not set +# CONFIG_PLATFORM_LINUX is not set + +# +# Build Options +# +CONFIG_STATIC=y +# CONFIG_PIE is not set +# CONFIG_NOMMU is not set +# CONFIG_BUILD_LIBBUSYBOX is not set +# CONFIG_FEATURE_LIBBUSYBOX_STATIC is not set +# CONFIG_FEATURE_INDIVIDUAL is not set +# CONFIG_FEATURE_SHARED_BUSYBOX is not set +CONFIG_CROSS_COMPILER_PREFIX="" +CONFIG_SYSROOT="" +CONFIG_EXTRA_CFLAGS="" +CONFIG_EXTRA_LDFLAGS="" +CONFIG_EXTRA_LDLIBS="" +# CONFIG_USE_PORTABLE_CODE is not set +# CONFIG_STACK_OPTIMIZATION_386 is not set + +# +# Installation Options ("make install" behavior) +# +CONFIG_INSTALL_APPLET_SYMLINKS=y +# CONFIG_INSTALL_APPLET_HARDLINKS is not set +# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set +# CONFIG_INSTALL_APPLET_DONT is not set +# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set +# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set +# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set +CONFIG_PREFIX="./_install" + +# +# Debugging Options +# +# CONFIG_DEBUG is not set +# CONFIG_DEBUG_PESSIMIZE is not set +# CONFIG_DEBUG_SANITIZE is not set +# CONFIG_UNIT_TEST is not set +# CONFIG_WERROR is not set +# CONFIG_WARN_SIMPLE_MSG is not set +CONFIG_NO_DEBUG_LIB=y +# CONFIG_DMALLOC is not set +# CONFIG_EFENCE is not set + +# +# Library Tuning +# +# CONFIG_FEATURE_USE_BSS_TAIL is not set +# CONFIG_FLOAT_DURATION is not set +# CONFIG_FEATURE_RTMINMAX is not set +# CONFIG_FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS is not set +CONFIG_FEATURE_BUFFERS_USE_MALLOC=y +# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set +# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set +CONFIG_PASSWORD_MINLEN=6 +CONFIG_MD5_SMALL=1 +CONFIG_SHA3_SMALL=1 +# CONFIG_FEATURE_FAST_TOP is not set +# CONFIG_FEATURE_ETC_NETWORKS is not set +# CONFIG_FEATURE_ETC_SERVICES is not set +# CONFIG_FEATURE_EDITING is not set +CONFIG_FEATURE_EDITING_MAX_LEN=0 +# CONFIG_FEATURE_EDITING_VI is not set +CONFIG_FEATURE_EDITING_HISTORY=0 +# CONFIG_FEATURE_EDITING_SAVEHISTORY is not set +# CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set +# CONFIG_FEATURE_REVERSE_SEARCH is not set +# CONFIG_FEATURE_TAB_COMPLETION is not set +# CONFIG_FEATURE_USERNAME_COMPLETION is not set +# CONFIG_FEATURE_EDITING_FANCY_PROMPT is not set +# CONFIG_FEATURE_EDITING_WINCH is not set +# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set +# CONFIG_LOCALE_SUPPORT is not set +# CONFIG_UNICODE_SUPPORT is not set +# CONFIG_UNICODE_USING_LOCALE is not set +# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set +CONFIG_SUBST_WCHAR=0 +CONFIG_LAST_SUPPORTED_WCHAR=0 +# CONFIG_UNICODE_COMBINING_WCHARS is not set +# CONFIG_UNICODE_WIDE_WCHARS is not set +# CONFIG_UNICODE_BIDI_SUPPORT is not set +# CONFIG_UNICODE_NEUTRAL_TABLE is not set +# CONFIG_UNICODE_PRESERVE_BROKEN is not set +# CONFIG_FEATURE_NON_POSIX_CP is not set +# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set +# CONFIG_FEATURE_USE_SENDFILE is not set +CONFIG_FEATURE_COPYBUF_KB=4 +# CONFIG_FEATURE_SKIP_ROOTFS is not set +# CONFIG_MONOTONIC_SYSCALL is not set +# CONFIG_IOCTL_HEX2STR_ERROR is not set +# CONFIG_FEATURE_HWIB is not set + +# +# Applets +# + +# +# Archival Utilities +# +# CONFIG_FEATURE_SEAMLESS_XZ is not set +# CONFIG_FEATURE_SEAMLESS_LZMA is not set +# CONFIG_FEATURE_SEAMLESS_BZ2 is not set +# CONFIG_FEATURE_SEAMLESS_GZ is not set +# CONFIG_FEATURE_SEAMLESS_Z is not set +# CONFIG_AR is not set +# CONFIG_FEATURE_AR_LONG_FILENAMES is not set +# CONFIG_FEATURE_AR_CREATE is not set +# CONFIG_UNCOMPRESS is not set +# CONFIG_GUNZIP is not set +# CONFIG_ZCAT is not set +# CONFIG_FEATURE_GUNZIP_LONG_OPTIONS is not set +# CONFIG_BUNZIP2 is not set +# CONFIG_BZCAT is not set +# CONFIG_UNLZMA is not set +# CONFIG_LZCAT is not set +# CONFIG_LZMA is not set +# CONFIG_UNXZ is not set +# CONFIG_XZCAT is not set +# CONFIG_XZ is not set +# CONFIG_BZIP2 is not set +CONFIG_BZIP2_SMALL=0 +# CONFIG_FEATURE_BZIP2_DECOMPRESS is not set +# CONFIG_CPIO is not set +# CONFIG_FEATURE_CPIO_O is not set +# CONFIG_FEATURE_CPIO_P is not set +# CONFIG_DPKG is not set +# CONFIG_DPKG_DEB is not set +# CONFIG_GZIP is not set +# CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set +CONFIG_GZIP_FAST=0 +# CONFIG_FEATURE_GZIP_LEVELS is not set +# CONFIG_FEATURE_GZIP_DECOMPRESS is not set +# CONFIG_LZOP is not set +# CONFIG_UNLZOP is not set +# CONFIG_LZOPCAT is not set +# CONFIG_LZOP_COMPR_HIGH is not set +# CONFIG_RPM is not set +# CONFIG_RPM2CPIO is not set +# CONFIG_TAR is not set +# CONFIG_FEATURE_TAR_LONG_OPTIONS is not set +# CONFIG_FEATURE_TAR_CREATE is not set +# CONFIG_FEATURE_TAR_AUTODETECT is not set +# CONFIG_FEATURE_TAR_FROM is not set +# CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_GNU_EXTENSIONS is not set +# CONFIG_FEATURE_TAR_TO_COMMAND is not set +# CONFIG_FEATURE_TAR_UNAME_GNAME is not set +# CONFIG_FEATURE_TAR_NOPRESERVE_TIME is not set +# CONFIG_FEATURE_TAR_SELINUX is not set +# CONFIG_UNZIP is not set +# CONFIG_FEATURE_UNZIP_CDF is not set +# CONFIG_FEATURE_UNZIP_BZIP2 is not set +# CONFIG_FEATURE_UNZIP_LZMA is not set +# CONFIG_FEATURE_UNZIP_XZ is not set +# CONFIG_FEATURE_LZMA_FAST is not set + +# +# Coreutils +# +# CONFIG_BASENAME is not set +# CONFIG_CAT is not set +# CONFIG_FEATURE_CATN is not set +# CONFIG_FEATURE_CATV is not set +# CONFIG_CHGRP is not set +# CONFIG_CHMOD is not set +# CONFIG_CHOWN is not set +# CONFIG_FEATURE_CHOWN_LONG_OPTIONS is not set +# CONFIG_CHROOT is not set +# CONFIG_CKSUM is not set +# CONFIG_COMM is not set +# CONFIG_CP is not set +# CONFIG_FEATURE_CP_LONG_OPTIONS is not set +# CONFIG_FEATURE_CP_REFLINK is not set +# CONFIG_CUT is not set +# CONFIG_DATE is not set +# CONFIG_FEATURE_DATE_ISOFMT is not set +# CONFIG_FEATURE_DATE_NANO is not set +# CONFIG_FEATURE_DATE_COMPAT is not set +# CONFIG_DD is not set +# CONFIG_FEATURE_DD_SIGNAL_HANDLING is not set +# CONFIG_FEATURE_DD_THIRD_STATUS_LINE is not set +# CONFIG_FEATURE_DD_IBS_OBS is not set +# CONFIG_FEATURE_DD_STATUS is not set +# CONFIG_DF is not set +# CONFIG_FEATURE_DF_FANCY is not set +# CONFIG_DIRNAME is not set +# CONFIG_DOS2UNIX is not set +# CONFIG_UNIX2DOS is not set +# CONFIG_DU is not set +# CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K is not set +# CONFIG_ECHO is not set +# CONFIG_FEATURE_FANCY_ECHO is not set +# CONFIG_ENV is not set +# CONFIG_EXPAND is not set +# CONFIG_UNEXPAND is not set +# CONFIG_EXPR is not set +# CONFIG_EXPR_MATH_SUPPORT_64 is not set +# CONFIG_FACTOR is not set +# CONFIG_FALSE is not set +# CONFIG_FOLD is not set +# CONFIG_HEAD is not set +# CONFIG_FEATURE_FANCY_HEAD is not set +# CONFIG_HOSTID is not set +# CONFIG_ID is not set +# CONFIG_GROUPS is not set +# CONFIG_INSTALL is not set +# CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set +# CONFIG_LINK is not set +# CONFIG_LN is not set +# CONFIG_LOGNAME is not set +# CONFIG_LS is not set +# CONFIG_FEATURE_LS_FILETYPES is not set +# CONFIG_FEATURE_LS_FOLLOWLINKS is not set +# CONFIG_FEATURE_LS_RECURSIVE is not set +# CONFIG_FEATURE_LS_WIDTH is not set +# CONFIG_FEATURE_LS_SORTFILES is not set +# CONFIG_FEATURE_LS_TIMESTAMPS is not set +# CONFIG_FEATURE_LS_USERNAME is not set +# CONFIG_FEATURE_LS_COLOR is not set +# CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set +# CONFIG_MD5SUM is not set +# CONFIG_SHA1SUM is not set +# CONFIG_SHA256SUM is not set +# CONFIG_SHA512SUM is not set +# CONFIG_SHA3SUM is not set +# CONFIG_FEATURE_MD5_SHA1_SUM_CHECK is not set +# CONFIG_MKDIR is not set +# CONFIG_MKFIFO is not set +# CONFIG_MKNOD is not set +# CONFIG_MKTEMP is not set +# CONFIG_MV is not set +# CONFIG_NICE is not set +# CONFIG_NL is not set +# CONFIG_NOHUP is not set +# CONFIG_NPROC is not set +# CONFIG_OD is not set +# CONFIG_PASTE is not set +# CONFIG_PRINTENV is not set +# CONFIG_PRINTF is not set +# CONFIG_PWD is not set +# CONFIG_READLINK is not set +# CONFIG_FEATURE_READLINK_FOLLOW is not set +# CONFIG_REALPATH is not set +# CONFIG_RM is not set +# CONFIG_RMDIR is not set +# CONFIG_SEQ is not set +# CONFIG_SHRED is not set +# CONFIG_SHUF is not set +# CONFIG_SLEEP is not set +# CONFIG_FEATURE_FANCY_SLEEP is not set +# CONFIG_SORT is not set +# CONFIG_FEATURE_SORT_BIG is not set +# CONFIG_FEATURE_SORT_OPTIMIZE_MEMORY is not set +# CONFIG_SPLIT is not set +# CONFIG_FEATURE_SPLIT_FANCY is not set +# CONFIG_STAT is not set +# CONFIG_FEATURE_STAT_FORMAT is not set +# CONFIG_FEATURE_STAT_FILESYSTEM is not set +# CONFIG_STTY is not set +# CONFIG_SUM is not set +# CONFIG_SYNC is not set +# CONFIG_FEATURE_SYNC_FANCY is not set +# CONFIG_FSYNC is not set +# CONFIG_TAC is not set +# CONFIG_TAIL is not set +# CONFIG_FEATURE_FANCY_TAIL is not set +# CONFIG_TEE is not set +# CONFIG_FEATURE_TEE_USE_BLOCK_IO is not set +# CONFIG_TEST is not set +# CONFIG_TEST1 is not set +# CONFIG_TEST2 is not set +# CONFIG_FEATURE_TEST_64 is not set +# CONFIG_TIMEOUT is not set +# CONFIG_TOUCH is not set +# CONFIG_FEATURE_TOUCH_NODEREF is not set +# CONFIG_FEATURE_TOUCH_SUSV3 is not set +# CONFIG_TR is not set +# CONFIG_FEATURE_TR_CLASSES is not set +# CONFIG_FEATURE_TR_EQUIV is not set +# CONFIG_TRUE is not set +# CONFIG_TRUNCATE is not set +# CONFIG_TTY is not set +# CONFIG_UNAME is not set +CONFIG_UNAME_OSNAME="" +# CONFIG_BB_ARCH is not set +# CONFIG_UNIQ is not set +# CONFIG_UNLINK is not set +# CONFIG_USLEEP is not set +# CONFIG_UUDECODE is not set +# CONFIG_BASE64 is not set +# CONFIG_UUENCODE is not set +# CONFIG_WC is not set +# CONFIG_FEATURE_WC_LARGE is not set +# CONFIG_WHO is not set +# CONFIG_W is not set +# CONFIG_USERS is not set +# CONFIG_WHOAMI is not set +# CONFIG_YES is not set + +# +# Common options +# +# CONFIG_FEATURE_VERBOSE is not set +# CONFIG_FEATURE_PRESERVE_HARDLINKS is not set +# CONFIG_FEATURE_HUMAN_READABLE is not set + +# +# Console Utilities +# +# CONFIG_CHVT is not set +# CONFIG_CLEAR is not set +# CONFIG_DEALLOCVT is not set +# CONFIG_DUMPKMAP is not set +# CONFIG_FGCONSOLE is not set +# CONFIG_KBD_MODE is not set +# CONFIG_LOADFONT is not set +# CONFIG_SETFONT is not set +# CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set +CONFIG_DEFAULT_SETFONT_DIR="" +# CONFIG_FEATURE_LOADFONT_PSF2 is not set +# CONFIG_FEATURE_LOADFONT_RAW is not set +# CONFIG_LOADKMAP is not set +# CONFIG_OPENVT is not set +# CONFIG_RESET is not set +# CONFIG_RESIZE is not set +# CONFIG_FEATURE_RESIZE_PRINT is not set +# CONFIG_SETCONSOLE is not set +# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set +# CONFIG_SETKEYCODES is not set +# CONFIG_SETLOGCONS is not set +# CONFIG_SHOWKEY is not set + +# +# Debian Utilities +# +# CONFIG_PIPE_PROGRESS is not set +# CONFIG_RUN_PARTS is not set +# CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set +# CONFIG_FEATURE_RUN_PARTS_FANCY is not set +# CONFIG_START_STOP_DAEMON is not set +# CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set +# CONFIG_FEATURE_START_STOP_DAEMON_FANCY is not set +# CONFIG_WHICH is not set + +# +# klibc-utils +# +# CONFIG_MINIPS is not set +# CONFIG_NUKE is not set +# CONFIG_RESUME is not set +# CONFIG_RUN_INIT is not set + +# +# Editors +# +# CONFIG_AWK is not set +# CONFIG_FEATURE_AWK_LIBM is not set +# CONFIG_FEATURE_AWK_GNU_EXTENSIONS is not set +# CONFIG_CMP is not set +# CONFIG_DIFF is not set +# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set +# CONFIG_FEATURE_DIFF_DIR is not set +# CONFIG_ED is not set +# CONFIG_PATCH is not set +# CONFIG_SED is not set +# CONFIG_VI is not set +CONFIG_FEATURE_VI_MAX_LEN=0 +# CONFIG_FEATURE_VI_8BIT is not set +# CONFIG_FEATURE_VI_COLON is not set +# CONFIG_FEATURE_VI_YANKMARK is not set +# CONFIG_FEATURE_VI_SEARCH is not set +# CONFIG_FEATURE_VI_REGEX_SEARCH is not set +# CONFIG_FEATURE_VI_USE_SIGNALS is not set +# CONFIG_FEATURE_VI_DOT_CMD is not set +# CONFIG_FEATURE_VI_READONLY is not set +# CONFIG_FEATURE_VI_SETOPTS is not set +# CONFIG_FEATURE_VI_SET is not set +# CONFIG_FEATURE_VI_WIN_RESIZE is not set +# CONFIG_FEATURE_VI_ASK_TERMINAL is not set +# CONFIG_FEATURE_VI_UNDO is not set +# CONFIG_FEATURE_VI_UNDO_QUEUE is not set +CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=0 +# CONFIG_FEATURE_ALLOW_EXEC is not set + +# +# Finding Utilities +# +# CONFIG_FIND is not set +# CONFIG_FEATURE_FIND_PRINT0 is not set +# CONFIG_FEATURE_FIND_MTIME is not set +# CONFIG_FEATURE_FIND_MMIN is not set +# CONFIG_FEATURE_FIND_PERM is not set +# CONFIG_FEATURE_FIND_TYPE is not set +# CONFIG_FEATURE_FIND_EXECUTABLE is not set +# CONFIG_FEATURE_FIND_XDEV is not set +# CONFIG_FEATURE_FIND_MAXDEPTH is not set +# CONFIG_FEATURE_FIND_NEWER is not set +# CONFIG_FEATURE_FIND_INUM is not set +# CONFIG_FEATURE_FIND_EXEC is not set +# CONFIG_FEATURE_FIND_EXEC_PLUS is not set +# CONFIG_FEATURE_FIND_USER is not set +# CONFIG_FEATURE_FIND_GROUP is not set +# CONFIG_FEATURE_FIND_NOT is not set +# CONFIG_FEATURE_FIND_DEPTH is not set +# CONFIG_FEATURE_FIND_PAREN is not set +# CONFIG_FEATURE_FIND_SIZE is not set +# CONFIG_FEATURE_FIND_PRUNE is not set +# CONFIG_FEATURE_FIND_QUIT is not set +# CONFIG_FEATURE_FIND_DELETE is not set +# CONFIG_FEATURE_FIND_EMPTY is not set +# CONFIG_FEATURE_FIND_PATH is not set +# CONFIG_FEATURE_FIND_REGEX is not set +# CONFIG_FEATURE_FIND_CONTEXT is not set +# CONFIG_FEATURE_FIND_LINKS is not set +# CONFIG_GREP is not set +# CONFIG_EGREP is not set +# CONFIG_FGREP is not set +# CONFIG_FEATURE_GREP_CONTEXT is not set +# CONFIG_XARGS is not set +# CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION is not set +# CONFIG_FEATURE_XARGS_SUPPORT_QUOTES is not set +# CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM is not set +# CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR is not set +# CONFIG_FEATURE_XARGS_SUPPORT_PARALLEL is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ARGS_FILE is not set + +# +# Init Utilities +# +# CONFIG_BOOTCHARTD is not set +# CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set +# CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set +# CONFIG_HALT is not set +# CONFIG_POWEROFF is not set +# CONFIG_REBOOT is not set +# CONFIG_FEATURE_WAIT_FOR_INIT is not set +# CONFIG_FEATURE_CALL_TELINIT is not set +CONFIG_TELINIT_PATH="" +# CONFIG_INIT is not set +# CONFIG_LINUXRC is not set +# CONFIG_FEATURE_USE_INITTAB is not set +# CONFIG_FEATURE_KILL_REMOVED is not set +CONFIG_FEATURE_KILL_DELAY=0 +# CONFIG_FEATURE_INIT_SCTTY is not set +# CONFIG_FEATURE_INIT_SYSLOG is not set +# CONFIG_FEATURE_INIT_QUIET is not set +# CONFIG_FEATURE_INIT_COREDUMPS is not set +CONFIG_INIT_TERMINAL_TYPE="" +# CONFIG_FEATURE_INIT_MODIFY_CMDLINE is not set + +# +# Login/Password Management Utilities +# +# CONFIG_FEATURE_SHADOWPASSWDS is not set +# CONFIG_USE_BB_PWD_GRP is not set +# CONFIG_USE_BB_SHADOW is not set +# CONFIG_USE_BB_CRYPT is not set +# CONFIG_USE_BB_CRYPT_SHA is not set +# CONFIG_ADD_SHELL is not set +# CONFIG_REMOVE_SHELL is not set +# CONFIG_ADDGROUP is not set +# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set +# CONFIG_ADDUSER is not set +# CONFIG_FEATURE_CHECK_NAMES is not set +CONFIG_LAST_ID=0 +CONFIG_FIRST_SYSTEM_ID=0 +CONFIG_LAST_SYSTEM_ID=0 +# CONFIG_CHPASSWD is not set +CONFIG_FEATURE_DEFAULT_PASSWD_ALGO="" +# CONFIG_CRYPTPW is not set +# CONFIG_MKPASSWD is not set +# CONFIG_DELUSER is not set +# CONFIG_DELGROUP is not set +# CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set +# CONFIG_GETTY is not set +# CONFIG_LOGIN is not set +# CONFIG_LOGIN_SESSION_AS_CHILD is not set +# CONFIG_LOGIN_SCRIPTS is not set +# CONFIG_FEATURE_NOLOGIN is not set +# CONFIG_FEATURE_SECURETTY is not set +# CONFIG_PASSWD is not set +# CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set +# CONFIG_SU is not set +# CONFIG_FEATURE_SU_SYSLOG is not set +# CONFIG_FEATURE_SU_CHECKS_SHELLS is not set +# CONFIG_FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY is not set +# CONFIG_SULOGIN is not set +# CONFIG_VLOCK is not set + +# +# Linux Ext2 FS Progs +# +# CONFIG_CHATTR is not set +# CONFIG_FSCK is not set +# CONFIG_LSATTR is not set +# CONFIG_TUNE2FS is not set + +# +# Linux Module Utilities +# +# CONFIG_MODPROBE_SMALL is not set +# CONFIG_DEPMOD is not set +# CONFIG_INSMOD is not set +# CONFIG_LSMOD is not set +# CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set +# CONFIG_MODINFO is not set +# CONFIG_MODPROBE is not set +# CONFIG_FEATURE_MODPROBE_BLACKLIST is not set +# CONFIG_RMMOD is not set + +# +# Options common to multiple modutils +# +# CONFIG_FEATURE_CMDLINE_MODULE_OPTIONS is not set +# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set +# CONFIG_FEATURE_2_4_MODULES is not set +# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set +# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set +# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set +# CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set +# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set +# CONFIG_FEATURE_MODUTILS_ALIAS is not set +# CONFIG_FEATURE_MODUTILS_SYMBOLS is not set +CONFIG_DEFAULT_MODULES_DIR="" +CONFIG_DEFAULT_DEPMOD_FILE="" + +# +# Linux System Utilities +# +# CONFIG_ACPID is not set +# CONFIG_FEATURE_ACPID_COMPAT is not set +# CONFIG_BLKDISCARD is not set +# CONFIG_BLKID is not set +# CONFIG_FEATURE_BLKID_TYPE is not set +# CONFIG_BLOCKDEV is not set +# CONFIG_CAL is not set +# CONFIG_CHRT is not set +# CONFIG_DMESG is not set +# CONFIG_FEATURE_DMESG_PRETTY is not set +# CONFIG_EJECT is not set +# CONFIG_FEATURE_EJECT_SCSI is not set +# CONFIG_FALLOCATE is not set +# CONFIG_FATATTR is not set +# CONFIG_FBSET is not set +# CONFIG_FEATURE_FBSET_FANCY is not set +# CONFIG_FEATURE_FBSET_READMODE is not set +# CONFIG_FDFORMAT is not set +# CONFIG_FDISK is not set +# CONFIG_FDISK_SUPPORT_LARGE_DISKS is not set +# CONFIG_FEATURE_FDISK_WRITABLE is not set +# CONFIG_FEATURE_AIX_LABEL is not set +# CONFIG_FEATURE_SGI_LABEL is not set +# CONFIG_FEATURE_SUN_LABEL is not set +# CONFIG_FEATURE_OSF_LABEL is not set +# CONFIG_FEATURE_GPT_LABEL is not set +# CONFIG_FEATURE_FDISK_ADVANCED is not set +# CONFIG_FINDFS is not set +# CONFIG_FLOCK is not set +# CONFIG_FDFLUSH is not set +# CONFIG_FREERAMDISK is not set +# CONFIG_FSCK_MINIX is not set +# CONFIG_FSFREEZE is not set +# CONFIG_FSTRIM is not set +# CONFIG_GETOPT is not set +# CONFIG_FEATURE_GETOPT_LONG is not set +CONFIG_HEXDUMP=y +CONFIG_FEATURE_HEXDUMP_REVERSE=y +# CONFIG_HD is not set +# CONFIG_XXD is not set +# CONFIG_HWCLOCK is not set +# CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set +# CONFIG_IONICE is not set +# CONFIG_IPCRM is not set +# CONFIG_IPCS is not set +# CONFIG_LAST is not set +# CONFIG_FEATURE_LAST_FANCY is not set +# CONFIG_LOSETUP is not set +# CONFIG_LSPCI is not set +# CONFIG_LSUSB is not set +# CONFIG_MDEV is not set +# CONFIG_FEATURE_MDEV_CONF is not set +# CONFIG_FEATURE_MDEV_RENAME is not set +# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set +# CONFIG_FEATURE_MDEV_EXEC is not set +# CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set +# CONFIG_FEATURE_MDEV_DAEMON is not set +# CONFIG_MESG is not set +# CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP is not set +# CONFIG_MKE2FS is not set +# CONFIG_MKFS_EXT2 is not set +# CONFIG_MKFS_MINIX is not set +# CONFIG_FEATURE_MINIX2 is not set +# CONFIG_MKFS_REISER is not set +# CONFIG_MKDOSFS is not set +# CONFIG_MKFS_VFAT is not set +# CONFIG_MKSWAP is not set +# CONFIG_FEATURE_MKSWAP_UUID is not set +# CONFIG_MORE is not set +# CONFIG_MOUNT is not set +# CONFIG_FEATURE_MOUNT_FAKE is not set +# CONFIG_FEATURE_MOUNT_VERBOSE is not set +# CONFIG_FEATURE_MOUNT_HELPERS is not set +# CONFIG_FEATURE_MOUNT_LABEL is not set +# CONFIG_FEATURE_MOUNT_NFS is not set +# CONFIG_FEATURE_MOUNT_CIFS is not set +# CONFIG_FEATURE_MOUNT_FLAGS is not set +# CONFIG_FEATURE_MOUNT_FSTAB is not set +# CONFIG_FEATURE_MOUNT_OTHERTAB is not set +# CONFIG_MOUNTPOINT is not set +# CONFIG_NOLOGIN is not set +# CONFIG_NOLOGIN_DEPENDENCIES is not set +# CONFIG_NSENTER is not set +# CONFIG_PIVOT_ROOT is not set +# CONFIG_RDATE is not set +# CONFIG_RDEV is not set +# CONFIG_READPROFILE is not set +# CONFIG_RENICE is not set +# CONFIG_REV is not set +# CONFIG_RTCWAKE is not set +# CONFIG_SCRIPT is not set +# CONFIG_SCRIPTREPLAY is not set +# CONFIG_SETARCH is not set +# CONFIG_LINUX32 is not set +# CONFIG_LINUX64 is not set +# CONFIG_SETPRIV is not set +# CONFIG_FEATURE_SETPRIV_DUMP is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITIES is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITY_NAMES is not set +# CONFIG_SETSID is not set +# CONFIG_SWAPON is not set +# CONFIG_FEATURE_SWAPON_DISCARD is not set +# CONFIG_FEATURE_SWAPON_PRI is not set +# CONFIG_SWAPOFF is not set +# CONFIG_FEATURE_SWAPONOFF_LABEL is not set +# CONFIG_SWITCH_ROOT is not set +# CONFIG_TASKSET is not set +# CONFIG_FEATURE_TASKSET_FANCY is not set +# CONFIG_FEATURE_TASKSET_CPULIST is not set +# CONFIG_UEVENT is not set +# CONFIG_UMOUNT is not set +# CONFIG_FEATURE_UMOUNT_ALL is not set +# CONFIG_UNSHARE is not set +# CONFIG_WALL is not set +# CONFIG_FEATURE_MOUNT_LOOP is not set +# CONFIG_FEATURE_MOUNT_LOOP_CREATE is not set +# CONFIG_FEATURE_MTAB_SUPPORT is not set +# CONFIG_VOLUMEID is not set +# CONFIG_FEATURE_VOLUMEID_BCACHE is not set +# CONFIG_FEATURE_VOLUMEID_BTRFS is not set +# CONFIG_FEATURE_VOLUMEID_CRAMFS is not set +# CONFIG_FEATURE_VOLUMEID_EXFAT is not set +# CONFIG_FEATURE_VOLUMEID_EXT is not set +# CONFIG_FEATURE_VOLUMEID_F2FS is not set +# CONFIG_FEATURE_VOLUMEID_FAT is not set +# CONFIG_FEATURE_VOLUMEID_HFS is not set +# CONFIG_FEATURE_VOLUMEID_ISO9660 is not set +# CONFIG_FEATURE_VOLUMEID_JFS is not set +# CONFIG_FEATURE_VOLUMEID_LFS is not set +# CONFIG_FEATURE_VOLUMEID_LINUXRAID is not set +# CONFIG_FEATURE_VOLUMEID_LINUXSWAP is not set +# CONFIG_FEATURE_VOLUMEID_LUKS is not set +# CONFIG_FEATURE_VOLUMEID_MINIX is not set +# CONFIG_FEATURE_VOLUMEID_NILFS is not set +# CONFIG_FEATURE_VOLUMEID_NTFS is not set +# CONFIG_FEATURE_VOLUMEID_OCFS2 is not set +# CONFIG_FEATURE_VOLUMEID_REISERFS is not set +# CONFIG_FEATURE_VOLUMEID_ROMFS is not set +# CONFIG_FEATURE_VOLUMEID_SQUASHFS is not set +# CONFIG_FEATURE_VOLUMEID_SYSV is not set +# CONFIG_FEATURE_VOLUMEID_UBIFS is not set +# CONFIG_FEATURE_VOLUMEID_UDF is not set +# CONFIG_FEATURE_VOLUMEID_XFS is not set + +# +# Miscellaneous Utilities +# +# CONFIG_ADJTIMEX is not set +# CONFIG_BBCONFIG is not set +# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set +# CONFIG_BC is not set +# CONFIG_DC is not set +# CONFIG_FEATURE_DC_BIG is not set +# CONFIG_FEATURE_DC_LIBM is not set +# CONFIG_FEATURE_BC_INTERACTIVE is not set +# CONFIG_FEATURE_BC_LONG_OPTIONS is not set +# CONFIG_BEEP is not set +CONFIG_FEATURE_BEEP_FREQ=0 +CONFIG_FEATURE_BEEP_LENGTH_MS=0 +# CONFIG_CHAT is not set +# CONFIG_FEATURE_CHAT_NOFAIL is not set +# CONFIG_FEATURE_CHAT_TTY_HIFI is not set +# CONFIG_FEATURE_CHAT_IMPLICIT_CR is not set +# CONFIG_FEATURE_CHAT_SWALLOW_OPTS is not set +# CONFIG_FEATURE_CHAT_SEND_ESCAPES is not set +# CONFIG_FEATURE_CHAT_VAR_ABORT_LEN is not set +# CONFIG_FEATURE_CHAT_CLR_ABORT is not set +# CONFIG_CONSPY is not set +# CONFIG_CROND is not set +# CONFIG_FEATURE_CROND_D is not set +# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set +# CONFIG_FEATURE_CROND_SPECIAL_TIMES is not set +CONFIG_FEATURE_CROND_DIR="" +# CONFIG_CRONTAB is not set +# CONFIG_DEVFSD is not set +# CONFIG_DEVFSD_MODLOAD is not set +# CONFIG_DEVFSD_FG_NP is not set +# CONFIG_DEVFSD_VERBOSE is not set +# CONFIG_FEATURE_DEVFS is not set +# CONFIG_DEVMEM is not set +# CONFIG_FBSPLASH is not set +# CONFIG_FLASH_ERASEALL is not set +# CONFIG_FLASH_LOCK is not set +# CONFIG_FLASH_UNLOCK is not set +# CONFIG_FLASHCP is not set +# CONFIG_HDPARM is not set +# CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set +# CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set +# CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set +# CONFIG_HEXEDIT is not set +# CONFIG_I2CGET is not set +# CONFIG_I2CSET is not set +# CONFIG_I2CDUMP is not set +# CONFIG_I2CDETECT is not set +# CONFIG_I2CTRANSFER is not set +# CONFIG_INOTIFYD is not set +# CONFIG_LESS is not set +CONFIG_FEATURE_LESS_MAXLINES=0 +# CONFIG_FEATURE_LESS_BRACKETS is not set +# CONFIG_FEATURE_LESS_FLAGS is not set +# CONFIG_FEATURE_LESS_TRUNCATE is not set +# CONFIG_FEATURE_LESS_MARKS is not set +# CONFIG_FEATURE_LESS_REGEXP is not set +# CONFIG_FEATURE_LESS_WINCH is not set +# CONFIG_FEATURE_LESS_ASK_TERMINAL is not set +# CONFIG_FEATURE_LESS_DASHCMD is not set +# CONFIG_FEATURE_LESS_LINENUMS is not set +# CONFIG_FEATURE_LESS_RAW is not set +# CONFIG_FEATURE_LESS_ENV is not set +# CONFIG_LSSCSI is not set +# CONFIG_MAKEDEVS is not set +# CONFIG_FEATURE_MAKEDEVS_LEAF is not set +# CONFIG_FEATURE_MAKEDEVS_TABLE is not set +# CONFIG_MAN is not set +# CONFIG_MICROCOM is not set +# CONFIG_MIM is not set +# CONFIG_MT is not set +# CONFIG_NANDWRITE is not set +# CONFIG_NANDDUMP is not set +# CONFIG_PARTPROBE is not set +# CONFIG_RAIDAUTORUN is not set +# CONFIG_READAHEAD is not set +# CONFIG_RFKILL is not set +# CONFIG_RUNLEVEL is not set +# CONFIG_RX is not set +# CONFIG_SETFATTR is not set +# CONFIG_SETSERIAL is not set +# CONFIG_STRINGS is not set +# CONFIG_TIME is not set +# CONFIG_TS is not set +# CONFIG_TTYSIZE is not set +# CONFIG_UBIATTACH is not set +# CONFIG_UBIDETACH is not set +# CONFIG_UBIMKVOL is not set +# CONFIG_UBIRMVOL is not set +# CONFIG_UBIRSVOL is not set +# CONFIG_UBIUPDATEVOL is not set +# CONFIG_UBIRENAME is not set +# CONFIG_VOLNAME is not set +# CONFIG_WATCHDOG is not set + +# +# Networking Utilities +# +# CONFIG_FEATURE_IPV6 is not set +# CONFIG_FEATURE_UNIX_LOCAL is not set +# CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set +# CONFIG_VERBOSE_RESOLUTION_ERRORS is not set +# CONFIG_FEATURE_TLS_SHA1 is not set +# CONFIG_ARP is not set +# CONFIG_ARPING is not set +# CONFIG_BRCTL is not set +# CONFIG_FEATURE_BRCTL_FANCY is not set +# CONFIG_FEATURE_BRCTL_SHOW is not set +# CONFIG_DNSD is not set +# CONFIG_ETHER_WAKE is not set +# CONFIG_FTPD is not set +# CONFIG_FEATURE_FTPD_WRITE is not set +# CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST is not set +# CONFIG_FEATURE_FTPD_AUTHENTICATION is not set +# CONFIG_FTPGET is not set +# CONFIG_FTPPUT is not set +# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set +# CONFIG_HOSTNAME is not set +# CONFIG_DNSDOMAINNAME is not set +# CONFIG_HTTPD is not set +# CONFIG_FEATURE_HTTPD_RANGES is not set +# CONFIG_FEATURE_HTTPD_SETUID is not set +# CONFIG_FEATURE_HTTPD_BASIC_AUTH is not set +# CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set +# CONFIG_FEATURE_HTTPD_CGI is not set +# CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set +# CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set +# CONFIG_FEATURE_HTTPD_ENCODE_URL_STR is not set +# CONFIG_FEATURE_HTTPD_ERROR_PAGES is not set +# CONFIG_FEATURE_HTTPD_PROXY is not set +# CONFIG_FEATURE_HTTPD_GZIP is not set +# CONFIG_IFCONFIG is not set +# CONFIG_FEATURE_IFCONFIG_STATUS is not set +# CONFIG_FEATURE_IFCONFIG_SLIP is not set +# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set +# CONFIG_FEATURE_IFCONFIG_HW is not set +# CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set +# CONFIG_IFENSLAVE is not set +# CONFIG_IFPLUGD is not set +# CONFIG_IFUP is not set +# CONFIG_IFDOWN is not set +CONFIG_IFUPDOWN_IFSTATE_PATH="" +# CONFIG_FEATURE_IFUPDOWN_IP is not set +# CONFIG_FEATURE_IFUPDOWN_IPV4 is not set +# CONFIG_FEATURE_IFUPDOWN_IPV6 is not set +# CONFIG_FEATURE_IFUPDOWN_MAPPING is not set +# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set +# CONFIG_INETD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set +# CONFIG_FEATURE_INETD_RPC is not set +# CONFIG_IP is not set +# CONFIG_IPADDR is not set +# CONFIG_IPLINK is not set +# CONFIG_IPROUTE is not set +# CONFIG_IPTUNNEL is not set +# CONFIG_IPRULE is not set +# CONFIG_IPNEIGH is not set +# CONFIG_FEATURE_IP_ADDRESS is not set +# CONFIG_FEATURE_IP_LINK is not set +# CONFIG_FEATURE_IP_ROUTE is not set +CONFIG_FEATURE_IP_ROUTE_DIR="" +# CONFIG_FEATURE_IP_TUNNEL is not set +# CONFIG_FEATURE_IP_RULE is not set +# CONFIG_FEATURE_IP_NEIGH is not set +# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set +# CONFIG_IPCALC is not set +# CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set +# CONFIG_FEATURE_IPCALC_FANCY is not set +# CONFIG_FAKEIDENTD is not set +# CONFIG_NAMEIF is not set +# CONFIG_FEATURE_NAMEIF_EXTENDED is not set +# CONFIG_NBDCLIENT is not set +# CONFIG_NC is not set +# CONFIG_NETCAT is not set +# CONFIG_NC_SERVER is not set +# CONFIG_NC_EXTRA is not set +# CONFIG_NC_110_COMPAT is not set +# CONFIG_NETSTAT is not set +# CONFIG_FEATURE_NETSTAT_WIDE is not set +# CONFIG_FEATURE_NETSTAT_PRG is not set +# CONFIG_NSLOOKUP is not set +# CONFIG_FEATURE_NSLOOKUP_BIG is not set +# CONFIG_FEATURE_NSLOOKUP_LONG_OPTIONS is not set +# CONFIG_NTPD is not set +# CONFIG_FEATURE_NTPD_SERVER is not set +# CONFIG_FEATURE_NTPD_CONF is not set +# CONFIG_FEATURE_NTP_AUTH is not set +# CONFIG_PING is not set +# CONFIG_PING6 is not set +# CONFIG_FEATURE_FANCY_PING is not set +# CONFIG_PSCAN is not set +# CONFIG_ROUTE is not set +# CONFIG_SLATTACH is not set +# CONFIG_SSL_CLIENT is not set +# CONFIG_TC is not set +# CONFIG_FEATURE_TC_INGRESS is not set +# CONFIG_TCPSVD is not set +# CONFIG_UDPSVD is not set +# CONFIG_TELNET is not set +# CONFIG_FEATURE_TELNET_TTYPE is not set +# CONFIG_FEATURE_TELNET_AUTOLOGIN is not set +# CONFIG_FEATURE_TELNET_WIDTH is not set +# CONFIG_TELNETD is not set +# CONFIG_FEATURE_TELNETD_STANDALONE is not set +# CONFIG_FEATURE_TELNETD_INETD_WAIT is not set +# CONFIG_TFTP is not set +# CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set +# CONFIG_FEATURE_TFTP_HPA_COMPAT is not set +# CONFIG_TFTPD is not set +# CONFIG_FEATURE_TFTP_GET is not set +# CONFIG_FEATURE_TFTP_PUT is not set +# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set +# CONFIG_TFTP_DEBUG is not set +# CONFIG_TLS is not set +# CONFIG_TRACEROUTE is not set +# CONFIG_TRACEROUTE6 is not set +# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set +# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set +# CONFIG_TUNCTL is not set +# CONFIG_FEATURE_TUNCTL_UG is not set +# CONFIG_VCONFIG is not set +# CONFIG_WGET is not set +# CONFIG_FEATURE_WGET_LONG_OPTIONS is not set +# CONFIG_FEATURE_WGET_STATUSBAR is not set +# CONFIG_FEATURE_WGET_AUTHENTICATION is not set +# CONFIG_FEATURE_WGET_TIMEOUT is not set +# CONFIG_FEATURE_WGET_HTTPS is not set +# CONFIG_FEATURE_WGET_OPENSSL is not set +# CONFIG_WHOIS is not set +# CONFIG_ZCIP is not set +# CONFIG_UDHCPD is not set +# CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC is not set +# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set +CONFIG_DHCPD_LEASES_FILE="" +# CONFIG_DUMPLEASES is not set +# CONFIG_DHCPRELAY is not set +# CONFIG_UDHCPC is not set +# CONFIG_FEATURE_UDHCPC_ARPING is not set +# CONFIG_FEATURE_UDHCPC_SANITIZEOPT is not set +CONFIG_UDHCPC_DEFAULT_SCRIPT="" +# CONFIG_UDHCPC6 is not set +# CONFIG_FEATURE_UDHCPC6_RFC3646 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4704 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4833 is not set +# CONFIG_FEATURE_UDHCPC6_RFC5970 is not set +# CONFIG_FEATURE_UDHCP_PORT is not set +CONFIG_UDHCP_DEBUG=0 +CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=0 +# CONFIG_FEATURE_UDHCP_RFC3397 is not set +# CONFIG_FEATURE_UDHCP_8021Q is not set +CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="" + +# +# Print Utilities +# +# CONFIG_LPD is not set +# CONFIG_LPR is not set +# CONFIG_LPQ is not set + +# +# Mail Utilities +# +# CONFIG_MAKEMIME is not set +# CONFIG_POPMAILDIR is not set +# CONFIG_FEATURE_POPMAILDIR_DELIVERY is not set +# CONFIG_REFORMIME is not set +# CONFIG_FEATURE_REFORMIME_COMPAT is not set +# CONFIG_SENDMAIL is not set +CONFIG_FEATURE_MIME_CHARSET="" + +# +# Process Utilities +# +# CONFIG_FREE is not set +# CONFIG_FUSER is not set +# CONFIG_IOSTAT is not set +# CONFIG_KILL is not set +# CONFIG_KILLALL is not set +# CONFIG_KILLALL5 is not set +# CONFIG_LSOF is not set +# CONFIG_MPSTAT is not set +# CONFIG_NMETER is not set +# CONFIG_PGREP is not set +# CONFIG_PKILL is not set +# CONFIG_PIDOF is not set +# CONFIG_FEATURE_PIDOF_SINGLE is not set +# CONFIG_FEATURE_PIDOF_OMIT is not set +# CONFIG_PMAP is not set +# CONFIG_POWERTOP is not set +# CONFIG_FEATURE_POWERTOP_INTERACTIVE is not set +# CONFIG_PS is not set +# CONFIG_FEATURE_PS_WIDE is not set +# CONFIG_FEATURE_PS_LONG is not set +# CONFIG_FEATURE_PS_TIME is not set +# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set +# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set +# CONFIG_PSTREE is not set +# CONFIG_PWDX is not set +# CONFIG_SMEMCAP is not set +# CONFIG_BB_SYSCTL is not set +# CONFIG_TOP is not set +# CONFIG_FEATURE_TOP_INTERACTIVE is not set +# CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE is not set +# CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS is not set +# CONFIG_FEATURE_TOP_SMP_CPU is not set +# CONFIG_FEATURE_TOP_DECIMALS is not set +# CONFIG_FEATURE_TOP_SMP_PROCESS is not set +# CONFIG_FEATURE_TOPMEM is not set +# CONFIG_UPTIME is not set +# CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set +# CONFIG_WATCH is not set +# CONFIG_FEATURE_SHOW_THREADS is not set + +# +# Runit Utilities +# +# CONFIG_CHPST is not set +# CONFIG_SETUIDGID is not set +# CONFIG_ENVUIDGID is not set +# CONFIG_ENVDIR is not set +# CONFIG_SOFTLIMIT is not set +# CONFIG_RUNSV is not set +# CONFIG_RUNSVDIR is not set +# CONFIG_FEATURE_RUNSVDIR_LOG is not set +# CONFIG_SV is not set +CONFIG_SV_DEFAULT_SERVICE_DIR="" +# CONFIG_SVC is not set +# CONFIG_SVOK is not set +# CONFIG_SVLOGD is not set +# CONFIG_CHCON is not set +# CONFIG_GETENFORCE is not set +# CONFIG_GETSEBOOL is not set +# CONFIG_LOAD_POLICY is not set +# CONFIG_MATCHPATHCON is not set +# CONFIG_RUNCON is not set +# CONFIG_SELINUXENABLED is not set +# CONFIG_SESTATUS is not set +# CONFIG_SETENFORCE is not set +# CONFIG_SETFILES is not set +# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set +# CONFIG_RESTORECON is not set +# CONFIG_SETSEBOOL is not set + +# +# Shells +# +# CONFIG_SH_IS_ASH is not set +# CONFIG_SH_IS_HUSH is not set +CONFIG_SH_IS_NONE=y +# CONFIG_BASH_IS_ASH is not set +# CONFIG_BASH_IS_HUSH is not set +CONFIG_BASH_IS_NONE=y +# CONFIG_SHELL_ASH is not set +# CONFIG_ASH is not set +# CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set +# CONFIG_ASH_INTERNAL_GLOB is not set +# CONFIG_ASH_BASH_COMPAT is not set +# CONFIG_ASH_BASH_SOURCE_CURDIR is not set +# CONFIG_ASH_BASH_NOT_FOUND_HOOK is not set +# CONFIG_ASH_JOB_CONTROL is not set +# CONFIG_ASH_ALIAS is not set +# CONFIG_ASH_RANDOM_SUPPORT is not set +# CONFIG_ASH_EXPAND_PRMT is not set +# CONFIG_ASH_IDLE_TIMEOUT is not set +# CONFIG_ASH_MAIL is not set +# CONFIG_ASH_ECHO is not set +# CONFIG_ASH_PRINTF is not set +# CONFIG_ASH_TEST is not set +# CONFIG_ASH_HELP is not set +# CONFIG_ASH_GETOPTS is not set +# CONFIG_ASH_CMDCMD is not set +# CONFIG_CTTYHACK is not set +# CONFIG_HUSH is not set +# CONFIG_SHELL_HUSH is not set +# CONFIG_HUSH_BASH_COMPAT is not set +# CONFIG_HUSH_BRACE_EXPANSION is not set +# CONFIG_HUSH_LINENO_VAR is not set +# CONFIG_HUSH_BASH_SOURCE_CURDIR is not set +# CONFIG_HUSH_INTERACTIVE is not set +# CONFIG_HUSH_SAVEHISTORY is not set +# CONFIG_HUSH_JOB is not set +# CONFIG_HUSH_TICK is not set +# CONFIG_HUSH_IF is not set +# CONFIG_HUSH_LOOPS is not set +# CONFIG_HUSH_CASE is not set +# CONFIG_HUSH_FUNCTIONS is not set +# CONFIG_HUSH_LOCAL is not set +# CONFIG_HUSH_RANDOM_SUPPORT is not set +# CONFIG_HUSH_MODE_X is not set +# CONFIG_HUSH_ECHO is not set +# CONFIG_HUSH_PRINTF is not set +# CONFIG_HUSH_TEST is not set +# CONFIG_HUSH_HELP is not set +# CONFIG_HUSH_EXPORT is not set +# CONFIG_HUSH_EXPORT_N is not set +# CONFIG_HUSH_READONLY is not set +# CONFIG_HUSH_KILL is not set +# CONFIG_HUSH_WAIT is not set +# CONFIG_HUSH_COMMAND is not set +# CONFIG_HUSH_TRAP is not set +# CONFIG_HUSH_TYPE is not set +# CONFIG_HUSH_TIMES is not set +# CONFIG_HUSH_READ is not set +# CONFIG_HUSH_SET is not set +# CONFIG_HUSH_UNSET is not set +# CONFIG_HUSH_ULIMIT is not set +# CONFIG_HUSH_UMASK is not set +# CONFIG_HUSH_GETOPTS is not set +# CONFIG_HUSH_MEMLEAK is not set + +# +# Options common to all shells +# +# CONFIG_FEATURE_SH_MATH is not set +# CONFIG_FEATURE_SH_MATH_64 is not set +# CONFIG_FEATURE_SH_MATH_BASE is not set +# CONFIG_FEATURE_SH_EXTRA_QUIET is not set +# CONFIG_FEATURE_SH_STANDALONE is not set +# CONFIG_FEATURE_SH_NOFORK is not set +# CONFIG_FEATURE_SH_READ_FRAC is not set +# CONFIG_FEATURE_SH_HISTFILESIZE is not set +# CONFIG_FEATURE_SH_EMBEDDED_SCRIPTS is not set + +# +# System Logging Utilities +# +# CONFIG_KLOGD is not set +# CONFIG_FEATURE_KLOGD_KLOGCTL is not set +# CONFIG_LOGGER is not set +# CONFIG_LOGREAD is not set +# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set +# CONFIG_SYSLOGD is not set +# CONFIG_FEATURE_ROTATE_LOGFILE is not set +# CONFIG_FEATURE_REMOTE_LOG is not set +# CONFIG_FEATURE_SYSLOGD_DUP is not set +# CONFIG_FEATURE_SYSLOGD_CFG is not set +# CONFIG_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS is not set +CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0 +# CONFIG_FEATURE_IPC_SYSLOG is not set +CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 +# CONFIG_FEATURE_KMSG_SYSLOG is not set diff --git a/BUSYBOX/x86_64_xzcat.config b/BUSYBOX/x86_64_xzcat.config new file mode 100644 index 0000000..cd4361d --- /dev/null +++ b/BUSYBOX/x86_64_xzcat.config @@ -0,0 +1,1166 @@ +# +# Automatically generated make config: don't edit +# Busybox version: 1.32.0 +# Tue Dec 8 11:07:46 2020 +# +CONFIG_HAVE_DOT_CONFIG=y + +# +# Settings +# +# CONFIG_DESKTOP is not set +# CONFIG_EXTRA_COMPAT is not set +# CONFIG_FEDORA_COMPAT is not set +# CONFIG_INCLUDE_SUSv2 is not set +# CONFIG_LONG_OPTS is not set +# CONFIG_SHOW_USAGE is not set +# CONFIG_FEATURE_VERBOSE_USAGE is not set +# CONFIG_FEATURE_COMPRESS_USAGE is not set +# CONFIG_LFS is not set +# CONFIG_PAM is not set +# CONFIG_FEATURE_DEVPTS is not set +# CONFIG_FEATURE_UTMP is not set +# CONFIG_FEATURE_WTMP is not set +# CONFIG_FEATURE_PIDFILE is not set +CONFIG_PID_FILE_PATH="" +# CONFIG_BUSYBOX is not set +# CONFIG_FEATURE_SHOW_SCRIPT is not set +# CONFIG_FEATURE_INSTALLER is not set +# CONFIG_INSTALL_NO_USR is not set +# CONFIG_FEATURE_SUID is not set +# CONFIG_FEATURE_SUID_CONFIG is not set +# CONFIG_FEATURE_SUID_CONFIG_QUIET is not set +# CONFIG_FEATURE_PREFER_APPLETS is not set +CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" +# CONFIG_SELINUX is not set +# CONFIG_FEATURE_CLEAN_UP is not set +# CONFIG_FEATURE_SYSLOG_INFO is not set +# CONFIG_FEATURE_SYSLOG is not set +# CONFIG_PLATFORM_LINUX is not set + +# +# Build Options +# +CONFIG_STATIC=y +# CONFIG_PIE is not set +# CONFIG_NOMMU is not set +# CONFIG_BUILD_LIBBUSYBOX is not set +# CONFIG_FEATURE_LIBBUSYBOX_STATIC is not set +# CONFIG_FEATURE_INDIVIDUAL is not set +# CONFIG_FEATURE_SHARED_BUSYBOX is not set +CONFIG_CROSS_COMPILER_PREFIX="" +CONFIG_SYSROOT="" +CONFIG_EXTRA_CFLAGS="" +CONFIG_EXTRA_LDFLAGS="" +CONFIG_EXTRA_LDLIBS="" +# CONFIG_USE_PORTABLE_CODE is not set +# CONFIG_STACK_OPTIMIZATION_386 is not set + +# +# Installation Options ("make install" behavior) +# +CONFIG_INSTALL_APPLET_SYMLINKS=y +# CONFIG_INSTALL_APPLET_HARDLINKS is not set +# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set +# CONFIG_INSTALL_APPLET_DONT is not set +# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set +# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set +# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set +CONFIG_PREFIX="./_install" + +# +# Debugging Options +# +# CONFIG_DEBUG is not set +# CONFIG_DEBUG_PESSIMIZE is not set +# CONFIG_DEBUG_SANITIZE is not set +# CONFIG_UNIT_TEST is not set +# CONFIG_WERROR is not set +# CONFIG_WARN_SIMPLE_MSG is not set +CONFIG_NO_DEBUG_LIB=y +# CONFIG_DMALLOC is not set +# CONFIG_EFENCE is not set + +# +# Library Tuning +# +# CONFIG_FEATURE_USE_BSS_TAIL is not set +# CONFIG_FLOAT_DURATION is not set +# CONFIG_FEATURE_RTMINMAX is not set +# CONFIG_FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS is not set +CONFIG_FEATURE_BUFFERS_USE_MALLOC=y +# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set +# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set +CONFIG_PASSWORD_MINLEN=6 +CONFIG_MD5_SMALL=1 +CONFIG_SHA3_SMALL=1 +# CONFIG_FEATURE_FAST_TOP is not set +# CONFIG_FEATURE_ETC_NETWORKS is not set +# CONFIG_FEATURE_ETC_SERVICES is not set +# CONFIG_FEATURE_EDITING is not set +CONFIG_FEATURE_EDITING_MAX_LEN=0 +# CONFIG_FEATURE_EDITING_VI is not set +CONFIG_FEATURE_EDITING_HISTORY=0 +# CONFIG_FEATURE_EDITING_SAVEHISTORY is not set +# CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set +# CONFIG_FEATURE_REVERSE_SEARCH is not set +# CONFIG_FEATURE_TAB_COMPLETION is not set +# CONFIG_FEATURE_USERNAME_COMPLETION is not set +# CONFIG_FEATURE_EDITING_FANCY_PROMPT is not set +# CONFIG_FEATURE_EDITING_WINCH is not set +# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set +# CONFIG_LOCALE_SUPPORT is not set +# CONFIG_UNICODE_SUPPORT is not set +# CONFIG_UNICODE_USING_LOCALE is not set +# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set +CONFIG_SUBST_WCHAR=0 +CONFIG_LAST_SUPPORTED_WCHAR=0 +# CONFIG_UNICODE_COMBINING_WCHARS is not set +# CONFIG_UNICODE_WIDE_WCHARS is not set +# CONFIG_UNICODE_BIDI_SUPPORT is not set +# CONFIG_UNICODE_NEUTRAL_TABLE is not set +# CONFIG_UNICODE_PRESERVE_BROKEN is not set +# CONFIG_FEATURE_NON_POSIX_CP is not set +# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set +# CONFIG_FEATURE_USE_SENDFILE is not set +CONFIG_FEATURE_COPYBUF_KB=4 +# CONFIG_FEATURE_SKIP_ROOTFS is not set +# CONFIG_MONOTONIC_SYSCALL is not set +# CONFIG_IOCTL_HEX2STR_ERROR is not set +# CONFIG_FEATURE_HWIB is not set + +# +# Applets +# + +# +# Archival Utilities +# +# CONFIG_FEATURE_SEAMLESS_XZ is not set +# CONFIG_FEATURE_SEAMLESS_LZMA is not set +# CONFIG_FEATURE_SEAMLESS_BZ2 is not set +# CONFIG_FEATURE_SEAMLESS_GZ is not set +# CONFIG_FEATURE_SEAMLESS_Z is not set +# CONFIG_AR is not set +# CONFIG_FEATURE_AR_LONG_FILENAMES is not set +# CONFIG_FEATURE_AR_CREATE is not set +# CONFIG_UNCOMPRESS is not set +# CONFIG_GUNZIP is not set +# CONFIG_ZCAT is not set +# CONFIG_FEATURE_GUNZIP_LONG_OPTIONS is not set +# CONFIG_BUNZIP2 is not set +# CONFIG_BZCAT is not set +# CONFIG_UNLZMA is not set +# CONFIG_LZCAT is not set +# CONFIG_LZMA is not set +# CONFIG_UNXZ is not set +CONFIG_XZCAT=y +# CONFIG_XZ is not set +# CONFIG_BZIP2 is not set +CONFIG_BZIP2_SMALL=0 +# CONFIG_FEATURE_BZIP2_DECOMPRESS is not set +# CONFIG_CPIO is not set +# CONFIG_FEATURE_CPIO_O is not set +# CONFIG_FEATURE_CPIO_P is not set +# CONFIG_DPKG is not set +# CONFIG_DPKG_DEB is not set +# CONFIG_GZIP is not set +# CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set +CONFIG_GZIP_FAST=0 +# CONFIG_FEATURE_GZIP_LEVELS is not set +# CONFIG_FEATURE_GZIP_DECOMPRESS is not set +# CONFIG_LZOP is not set +# CONFIG_UNLZOP is not set +# CONFIG_LZOPCAT is not set +# CONFIG_LZOP_COMPR_HIGH is not set +# CONFIG_RPM is not set +# CONFIG_RPM2CPIO is not set +# CONFIG_TAR is not set +# CONFIG_FEATURE_TAR_LONG_OPTIONS is not set +# CONFIG_FEATURE_TAR_CREATE is not set +# CONFIG_FEATURE_TAR_AUTODETECT is not set +# CONFIG_FEATURE_TAR_FROM is not set +# CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_GNU_EXTENSIONS is not set +# CONFIG_FEATURE_TAR_TO_COMMAND is not set +# CONFIG_FEATURE_TAR_UNAME_GNAME is not set +# CONFIG_FEATURE_TAR_NOPRESERVE_TIME is not set +# CONFIG_FEATURE_TAR_SELINUX is not set +# CONFIG_UNZIP is not set +# CONFIG_FEATURE_UNZIP_CDF is not set +# CONFIG_FEATURE_UNZIP_BZIP2 is not set +# CONFIG_FEATURE_UNZIP_LZMA is not set +# CONFIG_FEATURE_UNZIP_XZ is not set +# CONFIG_FEATURE_LZMA_FAST is not set + +# +# Coreutils +# +# CONFIG_BASENAME is not set +# CONFIG_CAT is not set +# CONFIG_FEATURE_CATN is not set +# CONFIG_FEATURE_CATV is not set +# CONFIG_CHGRP is not set +# CONFIG_CHMOD is not set +# CONFIG_CHOWN is not set +# CONFIG_FEATURE_CHOWN_LONG_OPTIONS is not set +# CONFIG_CHROOT is not set +# CONFIG_CKSUM is not set +# CONFIG_COMM is not set +# CONFIG_CP is not set +# CONFIG_FEATURE_CP_LONG_OPTIONS is not set +# CONFIG_FEATURE_CP_REFLINK is not set +# CONFIG_CUT is not set +# CONFIG_DATE is not set +# CONFIG_FEATURE_DATE_ISOFMT is not set +# CONFIG_FEATURE_DATE_NANO is not set +# CONFIG_FEATURE_DATE_COMPAT is not set +# CONFIG_DD is not set +# CONFIG_FEATURE_DD_SIGNAL_HANDLING is not set +# CONFIG_FEATURE_DD_THIRD_STATUS_LINE is not set +# CONFIG_FEATURE_DD_IBS_OBS is not set +# CONFIG_FEATURE_DD_STATUS is not set +# CONFIG_DF is not set +# CONFIG_FEATURE_DF_FANCY is not set +# CONFIG_DIRNAME is not set +# CONFIG_DOS2UNIX is not set +# CONFIG_UNIX2DOS is not set +# CONFIG_DU is not set +# CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K is not set +# CONFIG_ECHO is not set +# CONFIG_FEATURE_FANCY_ECHO is not set +# CONFIG_ENV is not set +# CONFIG_EXPAND is not set +# CONFIG_UNEXPAND is not set +# CONFIG_EXPR is not set +# CONFIG_EXPR_MATH_SUPPORT_64 is not set +# CONFIG_FACTOR is not set +# CONFIG_FALSE is not set +# CONFIG_FOLD is not set +# CONFIG_HEAD is not set +# CONFIG_FEATURE_FANCY_HEAD is not set +# CONFIG_HOSTID is not set +# CONFIG_ID is not set +# CONFIG_GROUPS is not set +# CONFIG_INSTALL is not set +# CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set +# CONFIG_LINK is not set +# CONFIG_LN is not set +# CONFIG_LOGNAME is not set +# CONFIG_LS is not set +# CONFIG_FEATURE_LS_FILETYPES is not set +# CONFIG_FEATURE_LS_FOLLOWLINKS is not set +# CONFIG_FEATURE_LS_RECURSIVE is not set +# CONFIG_FEATURE_LS_WIDTH is not set +# CONFIG_FEATURE_LS_SORTFILES is not set +# CONFIG_FEATURE_LS_TIMESTAMPS is not set +# CONFIG_FEATURE_LS_USERNAME is not set +# CONFIG_FEATURE_LS_COLOR is not set +# CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set +# CONFIG_MD5SUM is not set +# CONFIG_SHA1SUM is not set +# CONFIG_SHA256SUM is not set +# CONFIG_SHA512SUM is not set +# CONFIG_SHA3SUM is not set +# CONFIG_FEATURE_MD5_SHA1_SUM_CHECK is not set +# CONFIG_MKDIR is not set +# CONFIG_MKFIFO is not set +# CONFIG_MKNOD is not set +# CONFIG_MKTEMP is not set +# CONFIG_MV is not set +# CONFIG_NICE is not set +# CONFIG_NL is not set +# CONFIG_NOHUP is not set +# CONFIG_NPROC is not set +# CONFIG_OD is not set +# CONFIG_PASTE is not set +# CONFIG_PRINTENV is not set +# CONFIG_PRINTF is not set +# CONFIG_PWD is not set +# CONFIG_READLINK is not set +# CONFIG_FEATURE_READLINK_FOLLOW is not set +# CONFIG_REALPATH is not set +# CONFIG_RM is not set +# CONFIG_RMDIR is not set +# CONFIG_SEQ is not set +# CONFIG_SHRED is not set +# CONFIG_SHUF is not set +# CONFIG_SLEEP is not set +# CONFIG_FEATURE_FANCY_SLEEP is not set +# CONFIG_SORT is not set +# CONFIG_FEATURE_SORT_BIG is not set +# CONFIG_FEATURE_SORT_OPTIMIZE_MEMORY is not set +# CONFIG_SPLIT is not set +# CONFIG_FEATURE_SPLIT_FANCY is not set +# CONFIG_STAT is not set +# CONFIG_FEATURE_STAT_FORMAT is not set +# CONFIG_FEATURE_STAT_FILESYSTEM is not set +# CONFIG_STTY is not set +# CONFIG_SUM is not set +# CONFIG_SYNC is not set +# CONFIG_FEATURE_SYNC_FANCY is not set +# CONFIG_FSYNC is not set +# CONFIG_TAC is not set +# CONFIG_TAIL is not set +# CONFIG_FEATURE_FANCY_TAIL is not set +# CONFIG_TEE is not set +# CONFIG_FEATURE_TEE_USE_BLOCK_IO is not set +# CONFIG_TEST is not set +# CONFIG_TEST1 is not set +# CONFIG_TEST2 is not set +# CONFIG_FEATURE_TEST_64 is not set +# CONFIG_TIMEOUT is not set +# CONFIG_TOUCH is not set +# CONFIG_FEATURE_TOUCH_NODEREF is not set +# CONFIG_FEATURE_TOUCH_SUSV3 is not set +# CONFIG_TR is not set +# CONFIG_FEATURE_TR_CLASSES is not set +# CONFIG_FEATURE_TR_EQUIV is not set +# CONFIG_TRUE is not set +# CONFIG_TRUNCATE is not set +# CONFIG_TTY is not set +# CONFIG_UNAME is not set +CONFIG_UNAME_OSNAME="" +# CONFIG_BB_ARCH is not set +# CONFIG_UNIQ is not set +# CONFIG_UNLINK is not set +# CONFIG_USLEEP is not set +# CONFIG_UUDECODE is not set +# CONFIG_BASE64 is not set +# CONFIG_UUENCODE is not set +# CONFIG_WC is not set +# CONFIG_FEATURE_WC_LARGE is not set +# CONFIG_WHOAMI is not set +# CONFIG_WHO is not set +# CONFIG_W is not set +# CONFIG_USERS is not set +# CONFIG_YES is not set + +# +# Common options +# +# CONFIG_FEATURE_VERBOSE is not set +# CONFIG_FEATURE_PRESERVE_HARDLINKS is not set +# CONFIG_FEATURE_HUMAN_READABLE is not set + +# +# Console Utilities +# +# CONFIG_CHVT is not set +# CONFIG_CLEAR is not set +# CONFIG_DEALLOCVT is not set +# CONFIG_DUMPKMAP is not set +# CONFIG_FGCONSOLE is not set +# CONFIG_KBD_MODE is not set +# CONFIG_LOADFONT is not set +# CONFIG_SETFONT is not set +# CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set +CONFIG_DEFAULT_SETFONT_DIR="" +# CONFIG_FEATURE_LOADFONT_PSF2 is not set +# CONFIG_FEATURE_LOADFONT_RAW is not set +# CONFIG_LOADKMAP is not set +# CONFIG_OPENVT is not set +# CONFIG_RESET is not set +# CONFIG_RESIZE is not set +# CONFIG_FEATURE_RESIZE_PRINT is not set +# CONFIG_SETCONSOLE is not set +# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set +# CONFIG_SETKEYCODES is not set +# CONFIG_SETLOGCONS is not set +# CONFIG_SHOWKEY is not set + +# +# Debian Utilities +# +# CONFIG_PIPE_PROGRESS is not set +# CONFIG_RUN_PARTS is not set +# CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set +# CONFIG_FEATURE_RUN_PARTS_FANCY is not set +# CONFIG_START_STOP_DAEMON is not set +# CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set +# CONFIG_FEATURE_START_STOP_DAEMON_FANCY is not set +# CONFIG_WHICH is not set + +# +# klibc-utils +# +# CONFIG_MINIPS is not set +# CONFIG_NUKE is not set +# CONFIG_RESUME is not set +# CONFIG_RUN_INIT is not set + +# +# Editors +# +# CONFIG_AWK is not set +# CONFIG_FEATURE_AWK_LIBM is not set +# CONFIG_FEATURE_AWK_GNU_EXTENSIONS is not set +# CONFIG_CMP is not set +# CONFIG_DIFF is not set +# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set +# CONFIG_FEATURE_DIFF_DIR is not set +# CONFIG_ED is not set +# CONFIG_PATCH is not set +# CONFIG_SED is not set +# CONFIG_VI is not set +CONFIG_FEATURE_VI_MAX_LEN=0 +# CONFIG_FEATURE_VI_8BIT is not set +# CONFIG_FEATURE_VI_COLON is not set +# CONFIG_FEATURE_VI_YANKMARK is not set +# CONFIG_FEATURE_VI_SEARCH is not set +# CONFIG_FEATURE_VI_REGEX_SEARCH is not set +# CONFIG_FEATURE_VI_USE_SIGNALS is not set +# CONFIG_FEATURE_VI_DOT_CMD is not set +# CONFIG_FEATURE_VI_READONLY is not set +# CONFIG_FEATURE_VI_SETOPTS is not set +# CONFIG_FEATURE_VI_SET is not set +# CONFIG_FEATURE_VI_WIN_RESIZE is not set +# CONFIG_FEATURE_VI_ASK_TERMINAL is not set +# CONFIG_FEATURE_VI_UNDO is not set +# CONFIG_FEATURE_VI_UNDO_QUEUE is not set +CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=0 +# CONFIG_FEATURE_ALLOW_EXEC is not set + +# +# Finding Utilities +# +# CONFIG_FIND is not set +# CONFIG_FEATURE_FIND_PRINT0 is not set +# CONFIG_FEATURE_FIND_MTIME is not set +# CONFIG_FEATURE_FIND_MMIN is not set +# CONFIG_FEATURE_FIND_PERM is not set +# CONFIG_FEATURE_FIND_TYPE is not set +# CONFIG_FEATURE_FIND_EXECUTABLE is not set +# CONFIG_FEATURE_FIND_XDEV is not set +# CONFIG_FEATURE_FIND_MAXDEPTH is not set +# CONFIG_FEATURE_FIND_NEWER is not set +# CONFIG_FEATURE_FIND_INUM is not set +# CONFIG_FEATURE_FIND_EXEC is not set +# CONFIG_FEATURE_FIND_EXEC_PLUS is not set +# CONFIG_FEATURE_FIND_USER is not set +# CONFIG_FEATURE_FIND_GROUP is not set +# CONFIG_FEATURE_FIND_NOT is not set +# CONFIG_FEATURE_FIND_DEPTH is not set +# CONFIG_FEATURE_FIND_PAREN is not set +# CONFIG_FEATURE_FIND_SIZE is not set +# CONFIG_FEATURE_FIND_PRUNE is not set +# CONFIG_FEATURE_FIND_QUIT is not set +# CONFIG_FEATURE_FIND_DELETE is not set +# CONFIG_FEATURE_FIND_EMPTY is not set +# CONFIG_FEATURE_FIND_PATH is not set +# CONFIG_FEATURE_FIND_REGEX is not set +# CONFIG_FEATURE_FIND_CONTEXT is not set +# CONFIG_FEATURE_FIND_LINKS is not set +# CONFIG_GREP is not set +# CONFIG_EGREP is not set +# CONFIG_FGREP is not set +# CONFIG_FEATURE_GREP_CONTEXT is not set +# CONFIG_XARGS is not set +# CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION is not set +# CONFIG_FEATURE_XARGS_SUPPORT_QUOTES is not set +# CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM is not set +# CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR is not set +# CONFIG_FEATURE_XARGS_SUPPORT_PARALLEL is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ARGS_FILE is not set + +# +# Init Utilities +# +# CONFIG_BOOTCHARTD is not set +# CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set +# CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set +# CONFIG_HALT is not set +# CONFIG_POWEROFF is not set +# CONFIG_REBOOT is not set +# CONFIG_FEATURE_WAIT_FOR_INIT is not set +# CONFIG_FEATURE_CALL_TELINIT is not set +CONFIG_TELINIT_PATH="" +# CONFIG_INIT is not set +# CONFIG_LINUXRC is not set +# CONFIG_FEATURE_USE_INITTAB is not set +# CONFIG_FEATURE_KILL_REMOVED is not set +CONFIG_FEATURE_KILL_DELAY=0 +# CONFIG_FEATURE_INIT_SCTTY is not set +# CONFIG_FEATURE_INIT_SYSLOG is not set +# CONFIG_FEATURE_INIT_QUIET is not set +# CONFIG_FEATURE_INIT_COREDUMPS is not set +CONFIG_INIT_TERMINAL_TYPE="" +# CONFIG_FEATURE_INIT_MODIFY_CMDLINE is not set + +# +# Login/Password Management Utilities +# +# CONFIG_FEATURE_SHADOWPASSWDS is not set +# CONFIG_USE_BB_PWD_GRP is not set +# CONFIG_USE_BB_SHADOW is not set +# CONFIG_USE_BB_CRYPT is not set +# CONFIG_USE_BB_CRYPT_SHA is not set +# CONFIG_ADDGROUP is not set +# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set +# CONFIG_ADD_SHELL is not set +# CONFIG_REMOVE_SHELL is not set +# CONFIG_ADDUSER is not set +# CONFIG_FEATURE_CHECK_NAMES is not set +CONFIG_LAST_ID=0 +CONFIG_FIRST_SYSTEM_ID=0 +CONFIG_LAST_SYSTEM_ID=0 +# CONFIG_CHPASSWD is not set +CONFIG_FEATURE_DEFAULT_PASSWD_ALGO="" +# CONFIG_CRYPTPW is not set +# CONFIG_MKPASSWD is not set +# CONFIG_DELUSER is not set +# CONFIG_DELGROUP is not set +# CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set +# CONFIG_GETTY is not set +# CONFIG_LOGIN is not set +# CONFIG_LOGIN_SESSION_AS_CHILD is not set +# CONFIG_LOGIN_SCRIPTS is not set +# CONFIG_FEATURE_NOLOGIN is not set +# CONFIG_FEATURE_SECURETTY is not set +# CONFIG_PASSWD is not set +# CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set +# CONFIG_SU is not set +# CONFIG_FEATURE_SU_SYSLOG is not set +# CONFIG_FEATURE_SU_CHECKS_SHELLS is not set +# CONFIG_FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY is not set +# CONFIG_SULOGIN is not set +# CONFIG_VLOCK is not set + +# +# Linux Ext2 FS Progs +# +# CONFIG_CHATTR is not set +# CONFIG_FSCK is not set +# CONFIG_LSATTR is not set +# CONFIG_TUNE2FS is not set + +# +# Linux Module Utilities +# +# CONFIG_MODPROBE_SMALL is not set +# CONFIG_DEPMOD is not set +# CONFIG_INSMOD is not set +# CONFIG_LSMOD is not set +# CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set +# CONFIG_MODINFO is not set +# CONFIG_MODPROBE is not set +# CONFIG_FEATURE_MODPROBE_BLACKLIST is not set +# CONFIG_RMMOD is not set + +# +# Options common to multiple modutils +# +# CONFIG_FEATURE_CMDLINE_MODULE_OPTIONS is not set +# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set +# CONFIG_FEATURE_2_4_MODULES is not set +# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set +# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set +# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set +# CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set +# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set +# CONFIG_FEATURE_MODUTILS_ALIAS is not set +# CONFIG_FEATURE_MODUTILS_SYMBOLS is not set +CONFIG_DEFAULT_MODULES_DIR="" +CONFIG_DEFAULT_DEPMOD_FILE="" + +# +# Linux System Utilities +# +# CONFIG_ACPID is not set +# CONFIG_FEATURE_ACPID_COMPAT is not set +# CONFIG_BLKDISCARD is not set +# CONFIG_BLKID is not set +# CONFIG_FEATURE_BLKID_TYPE is not set +# CONFIG_BLOCKDEV is not set +# CONFIG_CAL is not set +# CONFIG_CHRT is not set +# CONFIG_DMESG is not set +# CONFIG_FEATURE_DMESG_PRETTY is not set +# CONFIG_EJECT is not set +# CONFIG_FEATURE_EJECT_SCSI is not set +# CONFIG_FALLOCATE is not set +# CONFIG_FATATTR is not set +# CONFIG_FBSET is not set +# CONFIG_FEATURE_FBSET_FANCY is not set +# CONFIG_FEATURE_FBSET_READMODE is not set +# CONFIG_FDFORMAT is not set +# CONFIG_FDISK is not set +# CONFIG_FDISK_SUPPORT_LARGE_DISKS is not set +# CONFIG_FEATURE_FDISK_WRITABLE is not set +# CONFIG_FEATURE_AIX_LABEL is not set +# CONFIG_FEATURE_SGI_LABEL is not set +# CONFIG_FEATURE_SUN_LABEL is not set +# CONFIG_FEATURE_OSF_LABEL is not set +# CONFIG_FEATURE_GPT_LABEL is not set +# CONFIG_FEATURE_FDISK_ADVANCED is not set +# CONFIG_FINDFS is not set +# CONFIG_FLOCK is not set +# CONFIG_FDFLUSH is not set +# CONFIG_FREERAMDISK is not set +# CONFIG_FSCK_MINIX is not set +# CONFIG_FSFREEZE is not set +# CONFIG_FSTRIM is not set +# CONFIG_GETOPT is not set +# CONFIG_FEATURE_GETOPT_LONG is not set +# CONFIG_HEXDUMP is not set +# CONFIG_FEATURE_HEXDUMP_REVERSE is not set +# CONFIG_HD is not set +# CONFIG_XXD is not set +# CONFIG_HWCLOCK is not set +# CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set +# CONFIG_IONICE is not set +# CONFIG_IPCRM is not set +# CONFIG_IPCS is not set +# CONFIG_LAST is not set +# CONFIG_FEATURE_LAST_FANCY is not set +# CONFIG_LOSETUP is not set +# CONFIG_LSPCI is not set +# CONFIG_LSUSB is not set +# CONFIG_MDEV is not set +# CONFIG_FEATURE_MDEV_CONF is not set +# CONFIG_FEATURE_MDEV_RENAME is not set +# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set +# CONFIG_FEATURE_MDEV_EXEC is not set +# CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set +# CONFIG_FEATURE_MDEV_DAEMON is not set +# CONFIG_MESG is not set +# CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP is not set +# CONFIG_MKE2FS is not set +# CONFIG_MKFS_EXT2 is not set +# CONFIG_MKFS_MINIX is not set +# CONFIG_FEATURE_MINIX2 is not set +# CONFIG_MKFS_REISER is not set +# CONFIG_MKDOSFS is not set +# CONFIG_MKFS_VFAT is not set +# CONFIG_MKSWAP is not set +# CONFIG_FEATURE_MKSWAP_UUID is not set +# CONFIG_MORE is not set +# CONFIG_MOUNT is not set +# CONFIG_FEATURE_MOUNT_FAKE is not set +# CONFIG_FEATURE_MOUNT_VERBOSE is not set +# CONFIG_FEATURE_MOUNT_HELPERS is not set +# CONFIG_FEATURE_MOUNT_LABEL is not set +# CONFIG_FEATURE_MOUNT_NFS is not set +# CONFIG_FEATURE_MOUNT_CIFS is not set +# CONFIG_FEATURE_MOUNT_FLAGS is not set +# CONFIG_FEATURE_MOUNT_FSTAB is not set +# CONFIG_FEATURE_MOUNT_OTHERTAB is not set +# CONFIG_MOUNTPOINT is not set +# CONFIG_NOLOGIN is not set +# CONFIG_NOLOGIN_DEPENDENCIES is not set +# CONFIG_NSENTER is not set +# CONFIG_PIVOT_ROOT is not set +# CONFIG_RDATE is not set +# CONFIG_RDEV is not set +# CONFIG_READPROFILE is not set +# CONFIG_RENICE is not set +# CONFIG_REV is not set +# CONFIG_RTCWAKE is not set +# CONFIG_SCRIPT is not set +# CONFIG_SCRIPTREPLAY is not set +# CONFIG_SETARCH is not set +# CONFIG_LINUX32 is not set +# CONFIG_LINUX64 is not set +# CONFIG_SETPRIV is not set +# CONFIG_FEATURE_SETPRIV_DUMP is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITIES is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITY_NAMES is not set +# CONFIG_SETSID is not set +# CONFIG_SWAPON is not set +# CONFIG_FEATURE_SWAPON_DISCARD is not set +# CONFIG_FEATURE_SWAPON_PRI is not set +# CONFIG_SWAPOFF is not set +# CONFIG_FEATURE_SWAPONOFF_LABEL is not set +# CONFIG_SWITCH_ROOT is not set +# CONFIG_TASKSET is not set +# CONFIG_FEATURE_TASKSET_FANCY is not set +# CONFIG_FEATURE_TASKSET_CPULIST is not set +# CONFIG_UEVENT is not set +# CONFIG_UMOUNT is not set +# CONFIG_FEATURE_UMOUNT_ALL is not set +# CONFIG_UNSHARE is not set +# CONFIG_WALL is not set +# CONFIG_FEATURE_MOUNT_LOOP is not set +# CONFIG_FEATURE_MOUNT_LOOP_CREATE is not set +# CONFIG_FEATURE_MTAB_SUPPORT is not set +# CONFIG_VOLUMEID is not set +# CONFIG_FEATURE_VOLUMEID_BCACHE is not set +# CONFIG_FEATURE_VOLUMEID_BTRFS is not set +# CONFIG_FEATURE_VOLUMEID_CRAMFS is not set +# CONFIG_FEATURE_VOLUMEID_EXFAT is not set +# CONFIG_FEATURE_VOLUMEID_EXT is not set +# CONFIG_FEATURE_VOLUMEID_F2FS is not set +# CONFIG_FEATURE_VOLUMEID_FAT is not set +# CONFIG_FEATURE_VOLUMEID_HFS is not set +# CONFIG_FEATURE_VOLUMEID_ISO9660 is not set +# CONFIG_FEATURE_VOLUMEID_JFS is not set +# CONFIG_FEATURE_VOLUMEID_LFS is not set +# CONFIG_FEATURE_VOLUMEID_LINUXRAID is not set +# CONFIG_FEATURE_VOLUMEID_LINUXSWAP is not set +# CONFIG_FEATURE_VOLUMEID_LUKS is not set +# CONFIG_FEATURE_VOLUMEID_MINIX is not set +# CONFIG_FEATURE_VOLUMEID_NILFS is not set +# CONFIG_FEATURE_VOLUMEID_NTFS is not set +# CONFIG_FEATURE_VOLUMEID_OCFS2 is not set +# CONFIG_FEATURE_VOLUMEID_REISERFS is not set +# CONFIG_FEATURE_VOLUMEID_ROMFS is not set +# CONFIG_FEATURE_VOLUMEID_SQUASHFS is not set +# CONFIG_FEATURE_VOLUMEID_SYSV is not set +# CONFIG_FEATURE_VOLUMEID_UBIFS is not set +# CONFIG_FEATURE_VOLUMEID_UDF is not set +# CONFIG_FEATURE_VOLUMEID_XFS is not set + +# +# Miscellaneous Utilities +# +# CONFIG_ADJTIMEX is not set +# CONFIG_BBCONFIG is not set +# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set +# CONFIG_BC is not set +# CONFIG_DC is not set +# CONFIG_FEATURE_DC_BIG is not set +# CONFIG_FEATURE_DC_LIBM is not set +# CONFIG_FEATURE_BC_INTERACTIVE is not set +# CONFIG_FEATURE_BC_LONG_OPTIONS is not set +# CONFIG_BEEP is not set +CONFIG_FEATURE_BEEP_FREQ=0 +CONFIG_FEATURE_BEEP_LENGTH_MS=0 +# CONFIG_CHAT is not set +# CONFIG_FEATURE_CHAT_NOFAIL is not set +# CONFIG_FEATURE_CHAT_TTY_HIFI is not set +# CONFIG_FEATURE_CHAT_IMPLICIT_CR is not set +# CONFIG_FEATURE_CHAT_SWALLOW_OPTS is not set +# CONFIG_FEATURE_CHAT_SEND_ESCAPES is not set +# CONFIG_FEATURE_CHAT_VAR_ABORT_LEN is not set +# CONFIG_FEATURE_CHAT_CLR_ABORT is not set +# CONFIG_CONSPY is not set +# CONFIG_CROND is not set +# CONFIG_FEATURE_CROND_D is not set +# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set +# CONFIG_FEATURE_CROND_SPECIAL_TIMES is not set +CONFIG_FEATURE_CROND_DIR="" +# CONFIG_CRONTAB is not set +# CONFIG_DEVFSD is not set +# CONFIG_DEVFSD_MODLOAD is not set +# CONFIG_DEVFSD_FG_NP is not set +# CONFIG_DEVFSD_VERBOSE is not set +# CONFIG_FEATURE_DEVFS is not set +# CONFIG_DEVMEM is not set +# CONFIG_FBSPLASH is not set +# CONFIG_FLASHCP is not set +# CONFIG_FLASH_ERASEALL is not set +# CONFIG_FLASH_LOCK is not set +# CONFIG_FLASH_UNLOCK is not set +# CONFIG_HDPARM is not set +# CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set +# CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set +# CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set +# CONFIG_HEXEDIT is not set +# CONFIG_I2CGET is not set +# CONFIG_I2CSET is not set +# CONFIG_I2CDUMP is not set +# CONFIG_I2CDETECT is not set +# CONFIG_I2CTRANSFER is not set +# CONFIG_INOTIFYD is not set +# CONFIG_LESS is not set +CONFIG_FEATURE_LESS_MAXLINES=0 +# CONFIG_FEATURE_LESS_BRACKETS is not set +# CONFIG_FEATURE_LESS_FLAGS is not set +# CONFIG_FEATURE_LESS_TRUNCATE is not set +# CONFIG_FEATURE_LESS_MARKS is not set +# CONFIG_FEATURE_LESS_REGEXP is not set +# CONFIG_FEATURE_LESS_WINCH is not set +# CONFIG_FEATURE_LESS_ASK_TERMINAL is not set +# CONFIG_FEATURE_LESS_DASHCMD is not set +# CONFIG_FEATURE_LESS_LINENUMS is not set +# CONFIG_FEATURE_LESS_RAW is not set +# CONFIG_FEATURE_LESS_ENV is not set +# CONFIG_LSSCSI is not set +# CONFIG_MAKEDEVS is not set +# CONFIG_FEATURE_MAKEDEVS_LEAF is not set +# CONFIG_FEATURE_MAKEDEVS_TABLE is not set +# CONFIG_MAN is not set +# CONFIG_MICROCOM is not set +# CONFIG_MIM is not set +# CONFIG_MT is not set +# CONFIG_NANDWRITE is not set +# CONFIG_NANDDUMP is not set +# CONFIG_PARTPROBE is not set +# CONFIG_RAIDAUTORUN is not set +# CONFIG_READAHEAD is not set +# CONFIG_RFKILL is not set +# CONFIG_RUNLEVEL is not set +# CONFIG_RX is not set +# CONFIG_SETFATTR is not set +# CONFIG_SETSERIAL is not set +# CONFIG_STRINGS is not set +# CONFIG_TIME is not set +# CONFIG_TS is not set +# CONFIG_TTYSIZE is not set +# CONFIG_UBIRENAME is not set +# CONFIG_UBIATTACH is not set +# CONFIG_UBIDETACH is not set +# CONFIG_UBIMKVOL is not set +# CONFIG_UBIRMVOL is not set +# CONFIG_UBIRSVOL is not set +# CONFIG_UBIUPDATEVOL is not set +# CONFIG_VOLNAME is not set +# CONFIG_WATCHDOG is not set + +# +# Networking Utilities +# +# CONFIG_FEATURE_IPV6 is not set +# CONFIG_FEATURE_UNIX_LOCAL is not set +# CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set +# CONFIG_VERBOSE_RESOLUTION_ERRORS is not set +# CONFIG_FEATURE_TLS_SHA1 is not set +# CONFIG_ARP is not set +# CONFIG_ARPING is not set +# CONFIG_BRCTL is not set +# CONFIG_FEATURE_BRCTL_FANCY is not set +# CONFIG_FEATURE_BRCTL_SHOW is not set +# CONFIG_DNSD is not set +# CONFIG_ETHER_WAKE is not set +# CONFIG_FTPD is not set +# CONFIG_FEATURE_FTPD_WRITE is not set +# CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST is not set +# CONFIG_FEATURE_FTPD_AUTHENTICATION is not set +# CONFIG_FTPGET is not set +# CONFIG_FTPPUT is not set +# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set +# CONFIG_HOSTNAME is not set +# CONFIG_DNSDOMAINNAME is not set +# CONFIG_HTTPD is not set +# CONFIG_FEATURE_HTTPD_RANGES is not set +# CONFIG_FEATURE_HTTPD_SETUID is not set +# CONFIG_FEATURE_HTTPD_BASIC_AUTH is not set +# CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set +# CONFIG_FEATURE_HTTPD_CGI is not set +# CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set +# CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set +# CONFIG_FEATURE_HTTPD_ENCODE_URL_STR is not set +# CONFIG_FEATURE_HTTPD_ERROR_PAGES is not set +# CONFIG_FEATURE_HTTPD_PROXY is not set +# CONFIG_FEATURE_HTTPD_GZIP is not set +# CONFIG_IFCONFIG is not set +# CONFIG_FEATURE_IFCONFIG_STATUS is not set +# CONFIG_FEATURE_IFCONFIG_SLIP is not set +# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set +# CONFIG_FEATURE_IFCONFIG_HW is not set +# CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set +# CONFIG_IFENSLAVE is not set +# CONFIG_IFPLUGD is not set +# CONFIG_IFUP is not set +# CONFIG_IFDOWN is not set +CONFIG_IFUPDOWN_IFSTATE_PATH="" +# CONFIG_FEATURE_IFUPDOWN_IP is not set +# CONFIG_FEATURE_IFUPDOWN_IPV4 is not set +# CONFIG_FEATURE_IFUPDOWN_IPV6 is not set +# CONFIG_FEATURE_IFUPDOWN_MAPPING is not set +# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set +# CONFIG_INETD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set +# CONFIG_FEATURE_INETD_RPC is not set +# CONFIG_IP is not set +# CONFIG_IPADDR is not set +# CONFIG_IPLINK is not set +# CONFIG_IPROUTE is not set +# CONFIG_IPTUNNEL is not set +# CONFIG_IPRULE is not set +# CONFIG_IPNEIGH is not set +# CONFIG_FEATURE_IP_ADDRESS is not set +# CONFIG_FEATURE_IP_LINK is not set +# CONFIG_FEATURE_IP_ROUTE is not set +CONFIG_FEATURE_IP_ROUTE_DIR="" +# CONFIG_FEATURE_IP_TUNNEL is not set +# CONFIG_FEATURE_IP_RULE is not set +# CONFIG_FEATURE_IP_NEIGH is not set +# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set +# CONFIG_IPCALC is not set +# CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set +# CONFIG_FEATURE_IPCALC_FANCY is not set +# CONFIG_FAKEIDENTD is not set +# CONFIG_NAMEIF is not set +# CONFIG_FEATURE_NAMEIF_EXTENDED is not set +# CONFIG_NBDCLIENT is not set +# CONFIG_NC is not set +# CONFIG_NETCAT is not set +# CONFIG_NC_SERVER is not set +# CONFIG_NC_EXTRA is not set +# CONFIG_NC_110_COMPAT is not set +# CONFIG_NETSTAT is not set +# CONFIG_FEATURE_NETSTAT_WIDE is not set +# CONFIG_FEATURE_NETSTAT_PRG is not set +# CONFIG_NSLOOKUP is not set +# CONFIG_FEATURE_NSLOOKUP_BIG is not set +# CONFIG_FEATURE_NSLOOKUP_LONG_OPTIONS is not set +# CONFIG_NTPD is not set +# CONFIG_FEATURE_NTPD_SERVER is not set +# CONFIG_FEATURE_NTPD_CONF is not set +# CONFIG_FEATURE_NTP_AUTH is not set +# CONFIG_PING is not set +# CONFIG_PING6 is not set +# CONFIG_FEATURE_FANCY_PING is not set +# CONFIG_PSCAN is not set +# CONFIG_ROUTE is not set +# CONFIG_SLATTACH is not set +# CONFIG_SSL_CLIENT is not set +# CONFIG_TC is not set +# CONFIG_FEATURE_TC_INGRESS is not set +# CONFIG_TCPSVD is not set +# CONFIG_UDPSVD is not set +# CONFIG_TELNET is not set +# CONFIG_FEATURE_TELNET_TTYPE is not set +# CONFIG_FEATURE_TELNET_AUTOLOGIN is not set +# CONFIG_FEATURE_TELNET_WIDTH is not set +# CONFIG_TELNETD is not set +# CONFIG_FEATURE_TELNETD_STANDALONE is not set +# CONFIG_FEATURE_TELNETD_INETD_WAIT is not set +# CONFIG_TFTP is not set +# CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set +# CONFIG_FEATURE_TFTP_HPA_COMPAT is not set +# CONFIG_TFTPD is not set +# CONFIG_FEATURE_TFTP_GET is not set +# CONFIG_FEATURE_TFTP_PUT is not set +# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set +# CONFIG_TFTP_DEBUG is not set +# CONFIG_TLS is not set +# CONFIG_TRACEROUTE is not set +# CONFIG_TRACEROUTE6 is not set +# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set +# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set +# CONFIG_TUNCTL is not set +# CONFIG_FEATURE_TUNCTL_UG is not set +# CONFIG_VCONFIG is not set +# CONFIG_WGET is not set +# CONFIG_FEATURE_WGET_LONG_OPTIONS is not set +# CONFIG_FEATURE_WGET_STATUSBAR is not set +# CONFIG_FEATURE_WGET_AUTHENTICATION is not set +# CONFIG_FEATURE_WGET_TIMEOUT is not set +# CONFIG_FEATURE_WGET_HTTPS is not set +# CONFIG_FEATURE_WGET_OPENSSL is not set +# CONFIG_WHOIS is not set +# CONFIG_ZCIP is not set +# CONFIG_UDHCPD is not set +# CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC is not set +# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set +CONFIG_DHCPD_LEASES_FILE="" +# CONFIG_DUMPLEASES is not set +# CONFIG_DHCPRELAY is not set +# CONFIG_UDHCPC is not set +# CONFIG_FEATURE_UDHCPC_ARPING is not set +# CONFIG_FEATURE_UDHCPC_SANITIZEOPT is not set +CONFIG_UDHCPC_DEFAULT_SCRIPT="" +# CONFIG_UDHCPC6 is not set +# CONFIG_FEATURE_UDHCPC6_RFC3646 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4704 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4833 is not set +# CONFIG_FEATURE_UDHCPC6_RFC5970 is not set +# CONFIG_FEATURE_UDHCP_PORT is not set +CONFIG_UDHCP_DEBUG=0 +CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=0 +# CONFIG_FEATURE_UDHCP_RFC3397 is not set +# CONFIG_FEATURE_UDHCP_8021Q is not set +CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="" + +# +# Print Utilities +# +# CONFIG_LPD is not set +# CONFIG_LPR is not set +# CONFIG_LPQ is not set + +# +# Mail Utilities +# +# CONFIG_MAKEMIME is not set +# CONFIG_POPMAILDIR is not set +# CONFIG_FEATURE_POPMAILDIR_DELIVERY is not set +# CONFIG_REFORMIME is not set +# CONFIG_FEATURE_REFORMIME_COMPAT is not set +# CONFIG_SENDMAIL is not set +CONFIG_FEATURE_MIME_CHARSET="" + +# +# Process Utilities +# +# CONFIG_FREE is not set +# CONFIG_FUSER is not set +# CONFIG_IOSTAT is not set +# CONFIG_KILL is not set +# CONFIG_KILLALL is not set +# CONFIG_KILLALL5 is not set +# CONFIG_LSOF is not set +# CONFIG_MPSTAT is not set +# CONFIG_NMETER is not set +# CONFIG_PGREP is not set +# CONFIG_PKILL is not set +# CONFIG_PIDOF is not set +# CONFIG_FEATURE_PIDOF_SINGLE is not set +# CONFIG_FEATURE_PIDOF_OMIT is not set +# CONFIG_PMAP is not set +# CONFIG_POWERTOP is not set +# CONFIG_FEATURE_POWERTOP_INTERACTIVE is not set +# CONFIG_PS is not set +# CONFIG_FEATURE_PS_WIDE is not set +# CONFIG_FEATURE_PS_LONG is not set +# CONFIG_FEATURE_PS_TIME is not set +# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set +# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set +# CONFIG_PSTREE is not set +# CONFIG_PWDX is not set +# CONFIG_SMEMCAP is not set +# CONFIG_BB_SYSCTL is not set +# CONFIG_TOP is not set +# CONFIG_FEATURE_TOP_INTERACTIVE is not set +# CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE is not set +# CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS is not set +# CONFIG_FEATURE_TOP_SMP_CPU is not set +# CONFIG_FEATURE_TOP_DECIMALS is not set +# CONFIG_FEATURE_TOP_SMP_PROCESS is not set +# CONFIG_FEATURE_TOPMEM is not set +# CONFIG_UPTIME is not set +# CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set +# CONFIG_WATCH is not set +# CONFIG_FEATURE_SHOW_THREADS is not set + +# +# Runit Utilities +# +# CONFIG_CHPST is not set +# CONFIG_SETUIDGID is not set +# CONFIG_ENVUIDGID is not set +# CONFIG_ENVDIR is not set +# CONFIG_SOFTLIMIT is not set +# CONFIG_RUNSV is not set +# CONFIG_RUNSVDIR is not set +# CONFIG_FEATURE_RUNSVDIR_LOG is not set +# CONFIG_SV is not set +CONFIG_SV_DEFAULT_SERVICE_DIR="" +# CONFIG_SVC is not set +# CONFIG_SVOK is not set +# CONFIG_SVLOGD is not set +# CONFIG_CHCON is not set +# CONFIG_GETENFORCE is not set +# CONFIG_GETSEBOOL is not set +# CONFIG_LOAD_POLICY is not set +# CONFIG_MATCHPATHCON is not set +# CONFIG_RUNCON is not set +# CONFIG_SELINUXENABLED is not set +# CONFIG_SESTATUS is not set +# CONFIG_SETENFORCE is not set +# CONFIG_SETFILES is not set +# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set +# CONFIG_RESTORECON is not set +# CONFIG_SETSEBOOL is not set + +# +# Shells +# +# CONFIG_SH_IS_ASH is not set +# CONFIG_SH_IS_HUSH is not set +CONFIG_SH_IS_NONE=y +# CONFIG_BASH_IS_ASH is not set +# CONFIG_BASH_IS_HUSH is not set +CONFIG_BASH_IS_NONE=y +# CONFIG_SHELL_ASH is not set +# CONFIG_ASH is not set +# CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set +# CONFIG_ASH_INTERNAL_GLOB is not set +# CONFIG_ASH_BASH_COMPAT is not set +# CONFIG_ASH_BASH_SOURCE_CURDIR is not set +# CONFIG_ASH_BASH_NOT_FOUND_HOOK is not set +# CONFIG_ASH_JOB_CONTROL is not set +# CONFIG_ASH_ALIAS is not set +# CONFIG_ASH_RANDOM_SUPPORT is not set +# CONFIG_ASH_EXPAND_PRMT is not set +# CONFIG_ASH_IDLE_TIMEOUT is not set +# CONFIG_ASH_MAIL is not set +# CONFIG_ASH_ECHO is not set +# CONFIG_ASH_PRINTF is not set +# CONFIG_ASH_TEST is not set +# CONFIG_ASH_HELP is not set +# CONFIG_ASH_GETOPTS is not set +# CONFIG_ASH_CMDCMD is not set +# CONFIG_CTTYHACK is not set +# CONFIG_HUSH is not set +# CONFIG_SHELL_HUSH is not set +# CONFIG_HUSH_BASH_COMPAT is not set +# CONFIG_HUSH_BRACE_EXPANSION is not set +# CONFIG_HUSH_LINENO_VAR is not set +# CONFIG_HUSH_BASH_SOURCE_CURDIR is not set +# CONFIG_HUSH_INTERACTIVE is not set +# CONFIG_HUSH_SAVEHISTORY is not set +# CONFIG_HUSH_JOB is not set +# CONFIG_HUSH_TICK is not set +# CONFIG_HUSH_IF is not set +# CONFIG_HUSH_LOOPS is not set +# CONFIG_HUSH_CASE is not set +# CONFIG_HUSH_FUNCTIONS is not set +# CONFIG_HUSH_LOCAL is not set +# CONFIG_HUSH_RANDOM_SUPPORT is not set +# CONFIG_HUSH_MODE_X is not set +# CONFIG_HUSH_ECHO is not set +# CONFIG_HUSH_PRINTF is not set +# CONFIG_HUSH_TEST is not set +# CONFIG_HUSH_HELP is not set +# CONFIG_HUSH_EXPORT is not set +# CONFIG_HUSH_EXPORT_N is not set +# CONFIG_HUSH_READONLY is not set +# CONFIG_HUSH_KILL is not set +# CONFIG_HUSH_WAIT is not set +# CONFIG_HUSH_COMMAND is not set +# CONFIG_HUSH_TRAP is not set +# CONFIG_HUSH_TYPE is not set +# CONFIG_HUSH_TIMES is not set +# CONFIG_HUSH_READ is not set +# CONFIG_HUSH_SET is not set +# CONFIG_HUSH_UNSET is not set +# CONFIG_HUSH_ULIMIT is not set +# CONFIG_HUSH_UMASK is not set +# CONFIG_HUSH_GETOPTS is not set +# CONFIG_HUSH_MEMLEAK is not set + +# +# Options common to all shells +# +# CONFIG_FEATURE_SH_MATH is not set +# CONFIG_FEATURE_SH_MATH_64 is not set +# CONFIG_FEATURE_SH_MATH_BASE is not set +# CONFIG_FEATURE_SH_EXTRA_QUIET is not set +# CONFIG_FEATURE_SH_STANDALONE is not set +# CONFIG_FEATURE_SH_NOFORK is not set +# CONFIG_FEATURE_SH_READ_FRAC is not set +# CONFIG_FEATURE_SH_HISTFILESIZE is not set +# CONFIG_FEATURE_SH_EMBEDDED_SCRIPTS is not set + +# +# System Logging Utilities +# +# CONFIG_KLOGD is not set +# CONFIG_FEATURE_KLOGD_KLOGCTL is not set +# CONFIG_LOGGER is not set +# CONFIG_LOGREAD is not set +# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set +# CONFIG_SYSLOGD is not set +# CONFIG_FEATURE_ROTATE_LOGFILE is not set +# CONFIG_FEATURE_REMOTE_LOG is not set +# CONFIG_FEATURE_SYSLOGD_DUP is not set +# CONFIG_FEATURE_SYSLOGD_CFG is not set +# CONFIG_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS is not set +CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0 +# CONFIG_FEATURE_IPC_SYSLOG is not set +CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 +# CONFIG_FEATURE_KMSG_SYSLOG is not set diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. 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 +them 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 prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. 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. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey 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; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If 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 convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU 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 that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + 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. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +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. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + 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 +state 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 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program 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, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU 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. But first, please read +. diff --git a/DMSETUP/build.txt b/DMSETUP/build.txt new file mode 100644 index 0000000..36e37a0 --- /dev/null +++ b/DMSETUP/build.txt @@ -0,0 +1,70 @@ +Build a static linked, small dmsetup tool + +======== Source Code ======== +use an old version of dmsetup +http://vault.centos.org/5.3/os/SRPMS/device-mapper-1.02.28-2.el5.src.rpm +https://www.fefe.de/dietlibc/dietlibc-0.34.tar.xz + +======== Build Environment ======== +build for 32bit, static linked with dietlibc +1. install centos 6.10 i386 with CentOS-6.10-i386-bin-DVD1.iso +2. yum install gcc kernel-devel package +3. install dietc libc (just make && make install) +4. export PATH=$PATH:/opt/diet/bin + +======== Build Step ======== +1. extract device mapper source code +2. CC="diet gcc" ./configure --disable-nls --disable-selinux --disable-shared +3. modify include/configure.h file + --- delete the line with "#define malloc rpl_malloc" + --- add 2 defines as follow: + #ifndef UINT32_MAX + #define UINT32_MAX (4294967295U) + #endif + + #ifndef UINT64_C + #define UINT64_C(c) c ## ULL + #endif + +4. make +5. strip dmsetup/dmsetup +6. get dmsetup/dmsetup as the dmsetup32 binary file + + + + + + +======================== Build for 64bit dmsetup ========================= +1. extract device mapper source code +2. ./configure --disable-nls --disable-selinux --disable-shared --enable-static_link CC='gcc -specs /usr/local/musl/lib/musl-gcc.specs' +3. touch include/linux/limits.h include/linux/types.h + echo '#include ' > include/linux/fs.h +4. make +5. strip --strip-all dmsetup/dmsetup.static +6. get dmsetup/dmsetup.static as the dmsetup64 binary file + + +======================== Build for arm64 dmsetup ========================= +1. extract device mapper source code +2. ./configure CC=aarch64-linux-gcc --target=arm --host=x86_64-linux-gnu --disable-nls --disable-selinux --disable-shared --enable-static_link +3. modify include/configure.h file + --- delete the line with "#define malloc rpl_malloc" +4. make +5. aarch64-linux-strip dmsetup/dmsetup.static +6. get dmsetup/dmsetup.static as the dmsetupaa64 binary file + + +======================== Build for mips64 dmsetup ========================= +1. extract device mapper source code +2. ./configure CC="mips64el-linux-musl-gcc -mips64r2 -mabi=64" --target=mips --host=x86_64-linux-gnu --disable-nls --disable-selinux --disable-shared --enable-static_link +3. modify include/configure.h file + --- delete the line with "#define malloc rpl_malloc" +4. make +5. mips64el-linux-musl-strip dmsetup/dmsetup.static +6. get dmsetup/dmsetup.static as the dmsetupm64e binary file + + + + + diff --git a/DMSETUP/dmsetup32 b/DMSETUP/dmsetup32 new file mode 100644 index 0000000..d5347ec Binary files /dev/null and b/DMSETUP/dmsetup32 differ diff --git a/DMSETUP/dmsetup64 b/DMSETUP/dmsetup64 new file mode 100644 index 0000000..4d39074 Binary files /dev/null and b/DMSETUP/dmsetup64 differ diff --git a/DMSETUP/dmsetupaa64 b/DMSETUP/dmsetupaa64 new file mode 100644 index 0000000..3b6b395 Binary files /dev/null and b/DMSETUP/dmsetupaa64 differ diff --git a/DMSETUP/dmsetupm64e b/DMSETUP/dmsetupm64e new file mode 100644 index 0000000..26d522e Binary files /dev/null and b/DMSETUP/dmsetupm64e differ diff --git a/DOC/BuildVentoyFromSource.txt b/DOC/BuildVentoyFromSource.txt new file mode 100644 index 0000000..60b1857 --- /dev/null +++ b/DOC/BuildVentoyFromSource.txt @@ -0,0 +1,277 @@ + +========================================== +1. Compile Environment +========================================== + My build environment is CentOS 7.8 x86_64. So here I first explain how to create the build environment from scratch. + Ventoy is based on many open source projects, so the build environment is important. I suggest you first test it on a virtual machine. + +1.1 Install CentOS 7.8 + I use CentOS-7-x86_64-Everything-2003.iso and select Minimal install + +1.2 Install Packages + yum install \ + libXpm net-tools bzip2 wget vim gcc gcc-c++ samba dos2unix glibc-devel glibc.i686 glibc-devel.i686 \ + mpfr.i686 mpfr-devel.i686 zlib.i686 rsync autogen autoconf automake libtool gettext* bison binutils \ + flex device-mapper-devel SDL libpciaccess libusb freetype freetype-devel gnu-free-* qemu-* virt-* \ + libvirt* vte* NetworkManager-bluetooth brlapi fuse-devel dejavu* gnu-efi* pesign shim \ + iscsi-initiator-utils grub2-tools zip nasm acpica-tools glibc-static zlib-static xorriso + + + +========================================== +2. Download Source Code +========================================== +2.1 Download Ventoy source code from GitHub and decompress it. + Next I assume that you have unzipped the code into the /home directory (check /home/Ventoy-master/README.md file for the directory layout). + +2.2 Download third-party source code and tool + + https://www.fefe.de/dietlibc/dietlibc-0.34.tar.xz ===> /home/Ventoy-master/DOC/dietlibc-0.34.tar.xz + https://musl.libc.org/releases/musl-1.2.1.tar.gz ===> /home/Ventoy-master/DOC/musl-1.2.1.tar.gz + https://ftp.gnu.org/gnu/grub/grub-2.04.tar.xz ===> /home/Ventoy-master/GRUB2/grub-2.04.tar.xz + https://codeload.github.com/tianocore/edk2/zip/edk2-stable201911 ===> /home/Ventoy-master/EDK2/edk2-edk2-stable201911.zip + https://codeload.github.com/relan/exfat/zip/v1.3.0 ===> /home/Ventoy-master/ExFAT/exfat-1.3.0.zip + https://codeload.github.com/libfuse/libfuse/zip/fuse-2.9.9 ===> /home/Ventoy-master/ExFAT/libfuse-fuse-2.9.9.zip + https://releases.linaro.org/components/toolchain/binaries/7.4-2019.02/aarch64-linux-gnu/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz ===> /opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz + https://toolchains.bootlin.com/downloads/releases/toolchains/aarch64/tarballs/aarch64--uclibc--stable-2020.08-1.tar.bz2 ===> /opt/aarch64--uclibc--stable-2020.08-1.tar.bz2 + https://github.com/ventoy/vtoytoolchain/releases/download/1.0/mips-loongson-gcc7.3-2019.06-29-linux-gnu.tar.gz ===> /opt/mips-loongson-gcc7.3-2019.06-29-linux-gnu.tar.gz + https://github.com/ventoy/musl-cross-make/releases/download/latest/output.tar.bz2 ===> /opt/output.tar.bz2 + + + http://www.tinycorelinux.net/11.x/x86_64/release/distribution_files/vmlinuz64 ===> /home/Ventoy-master/LiveCD/ISO/EFI/boot/vmlinuz64 + http://www.tinycorelinux.net/11.x/x86_64/release/distribution_files/corepure64.gz ===> /home/Ventoy-master/LiveCD/ISO/EFI/boot/corepure64.gz + http://www.tinycorelinux.net/11.x/x86_64/release/distribution_files/modules64.gz ===> /home/Ventoy-master/LiveCD/ISO/EFI/boot/modules64.gz + +2.3 Prepare third-party tools + cd /home/Ventoy-master/DOC/ + tar xf musl-1.2.1.tar.gz + cd musl-1.2.1 + ./configure && make install + + tar xf /opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz -C /opt + tar xf /opt/aarch64--uclibc--stable-2020.08-1.tar.bz2 -C /opt + tar xf /opt/output.tar.bz2 -C /opt + mv /opt/output /opt/mips64el-linux-musl-gcc730 + + +2.4 Set PATH environment + export PATH=$PATH:/opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/bin:/opt/aarch64--uclibc--stable-2020.08-1/bin:/opt/mips64el-linux-musl-gcc730/bin + better to add this line to /root/.bashrc and relogin as root + + +========================================== +3. All in one script +========================================== + I have made an all-in-one script `all_in_one.sh`. You can run this script to build and pack ventoy. + If you want to compile a certain part separately, you can continue to refer to the later chapters of this text. + + cd /home/Ventoy-master/INSTALL + sh all_in_one.sh + + It should be noted that: + 1. Only grub2/EDK2/IPXE will be recompiled in all_in_one.sh. Other parts contain binaries and are rarely modified, so will not be recompiled everytime. + You can rebuild these parts separately if you want. + + 2. Some parts of Ventoy have a 32-bit and 64-bit version (like 4.9, 4.10, 4.11 follows) + all_in_one.sh only builds the 64bit version of them. If you want to rebuild the 32bit verison, you should create a 32-bit CentOS environment and build them. + Fortunately these parts are rarely modified, so you only need to build once or you can directly use the binaries I have built. + + Besides, after a full compile and packaging, you can only build the part you modified (for example grub2) and run ventoy_pack.sh to generate the package. + +========================================== +4. Build every part of Ventoy +========================================== +4.1 == Build grub2 == + cd /home/Ventoy-master/GRUB2 + sh buildgrub.sh + +4.2 == Build ipxe.krn == + cd /home/Ventoy-master/IPXE + sh buildipxe.sh + +4.3 == Build Ventoy2Disk.exe == + Ventoy2Disk.exe is the installer in Windows platform. And it must be built in Windows with Microsoft Visual Studio (2013+). + Open /home/Ventoy-master/Ventoy2Disk/Ventoy2Disk.sln with Visual Studio and build it. + +4.4 == Build vtoyjump64.exe/vtoyjump32.exe == + vtoyjump64.exe/vtoyjump32.exe is used to mount iso file in windows PE. You should install Microsoft Visual Studio (2013+) to build it. + Open /home/Ventoy-master/vtoyjump/vtoyjump.sln with Visual Studio and build it (64&32). + +4.5 == Build dmsetup == + Please refer to DMSETUP/build.txt + +4.6 == Build ventoy_x64.efi == + cd /home/Ventoy-master/EDK2 + sh buildedk.sh + +4.7 == Build VtoyTool == + cd /home/Ventoy-master/VtoyTool + sh build.sh + +4.8 == Build vtoycli == + cd /home/Ventoy-master/vtoycli/fat_io_lib + sh buildlib.sh + cd /home/Ventoy-master/vtoycli + sh build.sh + +4.9 == Build exfat-util == + cd /home/Ventoy-master/ExFAT + sh buidlibfuse.sh + sh buidexfat.sh + + After that, copy EXFAT/shared/mkexfatfs ===> /home/Ventoy-master/INSTALL/tool/mkexfatfs_64 + After that, copy EXFAT/shared/mount.exfat-fuse ===> /home/Ventoy-master/INSTALL/tool/mount.exfat-fuse_64 + + Use the same build step to build exfat-util 32-bit in a 32-bit CentOS system and get mkexfatfs_32 and mount.exfat-fuse_32 + +4.10 == Build vtoy_fuse_iso_64/vtoy_fuse_iso_32 == + cd /home/Ventoy-master/FUSEISO + sh build_libfuse.sh + sh build.sh + + Use the same build step to build in a 32-bit CentOS system and get vtoy_fuse_iso_32 + +4.11 == Build unsquashfs_64/unsquashfs_32 == + cd /home/Ventoy-master/SQUASHFS/SRC + sh build_lz4.sh + sh build_lzma.sh + sh build_lzo.sh + sh build_zstd.sh + + cd /home/Ventoy-master/SQUASHFS/squashfs-tools-4.4/squashfs-tools + sh build.sh + + Use the same build step to build in a 32-bit CentOS system and get unsquashfs_32 + +4.12 == Build vblade_64/vblade_32 == + cd /home/Ventoy-master/VBLADE/vblade-master + sh build.sh + +4.13 == Build zstdcat == + Please refer to ZSTD/build.txt + +4.14 == Build vtoy_gen_uuid == + cd /home/Ventoy-master/GenUUID + sh build.sh + +4.15 == Build xzminidec32 == + cd /home/Ventoy-master/Ventoy2Disk/Ventoy2Disk/xz-embedded-20130513/userspace + make -f ventoy_makefile + strip --strip-all xzminidec + +4.16 == Build xzminidec64/xzminidec64_musl == + cd /home/Ventoy-master/Ventoy2Disk/Ventoy2Disk/xz-embedded-20130513/userspace + make -f ventoy_makefile64 or make -f ventoy_makefile64_musl + strip --strip-all xzminidec + +4.17 == Build iso9660_x64.efi/udf_x64.efi/iso9660_ia32.efi/udf_ia32.efi/iso9660_aa64.efi/udf_aa64.efi/ == + This efi driver is from https://github.com/pbatard/efifs + Follow all the build instructions in this project. I modified 3 files (the original and modified source are at /home/Ventoy-master/EDK2/efiffs) + +4.18 IMG/cpio/ventoy/busybox/64h + https://www.uclibc.org/downloads/binaries/0.9.30.1/mini-native-x86_64.tar.bz2 + https://busybox.net/downloads/busybox-1.32.0.tar.bz2 + use BUSYBOX/x86_64_ash.config and uclibc to build busybox-1.32 + +4.19 == Build lunzip32/lunzip64 == + http://mirror.yongbok.net/nongnu/lzip/lunzip/lunzip-1.11.tar.gz + PATH=$PATH:/opt/diet/bin + ./configure --disable-nls CC='diet gcc -nostdinc' + make + strip --strip-all lunzip + + #aarch64 + ./configure --disable-nls CC='aarch64-buildroot-linux-uclibc-gcc -static' + make + aarch64-buildroot-linux-uclibc-strip --strip-all lunzip + +4.17 == Build xzminidecaa64 == + cd /home/Ventoy-master/Ventoy2Disk/Ventoy2Disk/xz-embedded-20130513/userspace + make -f ventoy_makefileaa64 + strip --strip-all xzminidec + +4.18 == Build xzminidecm64e == + cd /home/Ventoy-master/Ventoy2Disk/Ventoy2Disk/xz-embedded-20130513/userspace + make -f ventoy_makefilem64e + strip --strip-all xzminidec + + + +========================================== +5. Binaries +========================================== + There some binaries in Ventoy install package. These files are downloaded from other open source project's website, such as busybox. + Here is the list of the binaries, their SHA-256 and the download urls: + +5.1 IMG/cpio/ventoy/tool/lz4cat + https://create.stephan-brumme.com/smallz4 smallz4cat-x32-v1.4 + SHA-256: 13d293ddeedb469f51da41167f79b2cbdb904e681716f6e6191b233dbb162438 + +5.2 IMG/cpio/ventoy/tool/ar + https://busybox.net/downloads/binaries/1.30.0-i686 busybox_AR + SHA-256: f29b7d81a983c0c85d22496f4a833c18f2528a1b666eb7d47c93084c1ed66ae0 + +5.3 IMG/cpio/ventoy/tool/inotifyd + https://busybox.net/downloads/binaries/1.30.0-i686 busybox_INOTIFYD + SHA-256: 3532162a8695e91a1ed9ddea28b2cb22259a90e93d5d9c4a517b6c36842c686f + +5.4 IMG/cpio/ventoy/busybox/ash + https://busybox.net/downloads/binaries/1.27.1-i686 busybox_ASH + SHA-256: 44a6274bca580c2758ffc173fc76d18bb855b1fe8dcf70efd9ee75cbd57dee97 + +5.5 IMG/cpio/ventoy/busybox/tmpxz + https://busybox.net/downloads/binaries/1.27.1-i686 busybox_XZ + SHA-256: f6cdb6293680424c29b89bde0685ca27f455166c9b302cd6082ef90681456291 + +5.6 INSTALL/tool/i386/xzcat + https://busybox.net/downloads/binaries/1.30.0-i686/ busybox_XZCAT + SHA-256: 7399db642c2beaf52a16ab5264ffc55cfd1ff5699a524f63e5d48edf84e20f44 + +5.7 INSTALL/tool/i386/hexdump + https://busybox.net/downloads/binaries/1.30.0-i686/ busybox_HEXDUMP + SHA-256: cde08b6a2cf5ad914f05203e18e3f7c2ed6060a63604e3d75536f19b55e8e0af + +5.8 imdisk + download http://static.ltr-data.se/files/imdiskinst_2.0.10.exe and extract it by 7zip. + + INSTALL/ventoy/imdisk/64/imdisk.sys --> sys/amd64/imdisk.sys SHA-256: 6702202220268787e361f5a82dae53362c8e6c6dcd240bb01b44dd77ae0788da + INSTALL/ventoy/imdisk/64/imdisk.exe --> cli/amd64/imdisk.exe SHA-256: 9759175380af836869443e5f21ce2e33022125d154bc6b3d1c04dc36b190de04 + INSTALL/ventoy/imdisk/64/imdisk.cpl --> cpl/amd64/imdisk.cpl SHA-256: aea2ebbea2b073c947263744962af8a3eab025ff4c9d825c543e380e738a4c99 + + INSTALL/ventoy/imdisk/32/imdisk.sys --> sys/i386/imdisk.sys SHA-256: a94caec2f71a924d6a914c093ad4b905d7cfdea3f515ed48aaa8c3950b2dc191 + INSTALL/ventoy/imdisk/32/imdisk.exe --> cli/i386/imdisk.exe SHA-256: 33b53858e2139704cf603b115a3e5e1dfd4daeaaed4d3e03c633f2df3b55dbaa + INSTALL/ventoy/imdisk/32/imdisk.cpl --> cpl/i386/imdisk.cpl SHA-256: b781d3e2d286ac8bf548f44e50cbbb3fe78203296e41e4d2e73b407668f88f2d + +5.9 INSTALL/ventoy/memdisk + https://mirrors.edge.kernel.org/pub/linux/utils/boot/syslinux/syslinux-6.03.tar.gz + decompress it and memdisk is at syslinux-6.03/bios/memdisk/memdisk + SHA-256: 3f6cd656b8a14109cd3f906fee2dd2e75418f983a5e1bfdb64f44f7765588cbb + + +5.10 UEFIinSecureBoot + https://github.com/ValdikSS/Super-UEFIinSecureBoot-Disk/releases Super-UEFIinSecureBoot-Disk_minimal_v3.zip + unzip it and get Super-UEFIinSecureBoot-Disk_minimal.img, extract the img by 7zip. + + INSTALL/EFI/BOOT/BOOTX64.EFI --> EFI/BOOT/BOOTX64.EFI SHA-256: 475552c7476ad45e42344eee8b30d44c264d200ac2468428aa86fc8795fb6e34 + INSTALL/EFI/BOOT/grubx64.efi --> EFI/BOOT/grubx64.efi SHA-256: 25d858157349dc52fa70f3cdf5c62fe1e0bae37ddfc3a6b6528af9a3c745775f + INSTALL/EFI/BOOT/MokManager.efi --> EFI/BOOT/MokManager.efi SHA-256: 3bf1f46cee0832355c7dd1dba880dea9bcaa78cc44375a1559d43bc9db18933b + + +5.11 INSTALL/tool/ash + https://busybox.net/downloads/binaries/1.31.0-i686-uclibc/ busybox_ASH + SHA-256: 2943f02f85fee0c9551aec47110a558a73f919c032b3c51e56d6f197b5ec4d7b + +5.12 7za.exe + download from https://www.7-zip.org/a/7z1900-extra.7z + ISNTALL/ventoy/7z/64/7za.exe SHA-256: 8117e40ee7f824f63373a4f5625bb62749f69159d0c449b3ce2f35aad3b83549 + ISNTALL/ventoy/7z/32/7za.exe SHA-256: ea308c76a2f927b160a143d94072b0dce232e04b751f0c6432a94e05164e716d + +5.13 ./Ventoy/Unix/ventoy_unix/DragonFly/sbin/dmsetup + download from https://cdimage.debian.org/mirror/dragonflybsd.org/iso-images/dfly-x86_64-5.8.3_REL.iso.bz2 + extract from the ISO file sbin/dmsetup + dmsetup SHA-256: bedcf26650e87edfe961e33bae20d832bce73efd4b6239f9a6a5785661e4e698 + +5.14 ./LiveCD/ISO/EFI/boot/vmlinuz64 + download from http://www.tinycorelinux.net/11.x/x86_64/archive/11.0/distribution_files/vmlinuz64 + vmlinuz64 SHA-256: 641077fc1f9914af244c248453005f56536ba9e7f54ba3e52402f26709ddb8a5 + diff --git a/DOC/LoopExBuild.txt b/DOC/LoopExBuild.txt new file mode 100644 index 0000000..2f5a39e --- /dev/null +++ b/DOC/LoopExBuild.txt @@ -0,0 +1,29 @@ + +1. LAKKA dm-mod.ko + LaKKa config + https://github.com/libretro/Lakka-LibreELEC/releases download source code + \projects\Generic\linux\linux.x86_64.conf + + Linux Kernel + linux-4.11.12.tar.xz & patch-4.11.12-rt14.patch.xz + patch -p1 < ../patch-4.11.12-rt14 + + make menuconfig + select device mapper as module + make -j 16 + get drivers\md\dm-mod.ko + +2. LibreELEC dm-mod.ko + LibreELEC config + https://github.com/LibreELEC/LibreELEC.tv/releases download source code + \projects\Generic\linux\linux.x86_64.conf + + Linux Kernel + linux-5.1.6.tar.xz + make menuconfig + select device mapper as module + make -j 16 + get drivers\md\dm-mod.ko + + + \ No newline at end of file diff --git a/DOC/installdietlibc.sh b/DOC/installdietlibc.sh new file mode 100644 index 0000000..ac8350b --- /dev/null +++ b/DOC/installdietlibc.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +if ! [ -f ./dietlibc-0.34.tar.xz ]; then + echo "No dietlibc-0.34.tar.xz found ..." + exit 1 +fi + +rm -rf /opt/diet32 +rm -rf /opt/diet64 + +tar -xvf dietlibc-0.34.tar.xz +cd dietlibc-0.34 + +prefix=/opt/diet64 make -j 4 +prefix=/opt/diet64 make install 2>/dev/null + +cd .. +rm -rf dietlibc-0.34 + +tar -xvf dietlibc-0.34.tar.xz +cd dietlibc-0.34 + +sed "s/MYARCH:=.*/MYARCH=i386/" -i Makefile +sed "s/CC=gcc/CC=gcc -m32/" -i Makefile + +prefix=/opt/diet32 make -j 4 +prefix=/opt/diet32 make install 2>/dev/null + +cd .. +rm -rf dietlibc-0.34 + +echo "" +echo " ================ success ===============" +echo "" diff --git a/DOC/prepare_env.sh b/DOC/prepare_env.sh new file mode 100644 index 0000000..4754db3 --- /dev/null +++ b/DOC/prepare_env.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +#[ -d /opt/diet64 ] || sh ./installdietlibc.sh + +[ -d /opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu ] || tar xf /opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz -C /opt + +[ -d /opt/aarch64--uclibc--stable-2020.08-1 ] || tar xf /opt/aarch64--uclibc--stable-2020.08-1.tar.bz2 -C /opt + +[ -d /opt/mips-loongson-gcc7.3-linux-gnu ] || tar xf /opt/mips-loongson-gcc7.3-2019.06-29-linux-gnu.tar.gz -C /opt diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..0813189 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,15 @@ +FROM centos:7 + +RUN sed -i \ + -e 's/^mirrorlist/#mirrorlist/' \ + -e 's/^#baseurl/baseurl/' \ + -e 's/mirror\.centos\.org/vault.centos.org/' \ + /etc/yum.repos.d/*.repo && \ + yum -y -q install \ + libXpm net-tools bzip2 wget vim gcc gcc-c++ samba dos2unix glibc-devel glibc.i686 glibc-devel.i686 \ + mpfr.i686 mpfr-devel.i686 rsync autogen autoconf automake libtool gettext* bison binutils \ + flex device-mapper-devel SDL libpciaccess libusb freetype freetype-devel gnu-free-* qemu-* virt-* \ + libvirt* vte* NetworkManager-bluetooth brlapi fuse-devel dejavu* gnu-efi* pesign shim \ + iscsi-initiator-utils grub2-tools zip nasm acpica-tools glibc-static zlib-static xorriso lz4 squashfs-tools + +CMD cd /ventoy/INSTALL && ls -la && sh docker_ci_build.sh diff --git a/EDK2/build.sh b/EDK2/build.sh new file mode 100644 index 0000000..92244db --- /dev/null +++ b/EDK2/build.sh @@ -0,0 +1,59 @@ +#!/bin/sh + +if [ -z "$1" ]; then + EDKARCH=X64 + postfix=x64 +elif [ "$1" = "ia32" ]; then + EDKARCH=IA32 + postfix=ia32 + shift +elif [ "$1" = "aa64" ]; then + EDKARCH=AARCH64 + postfix=aa64 + shift +fi + +cd edk2-edk2-stable201911 + +rm -rf ./Conf/.cache +rm -f ./Conf/.AutoGenIdFile.txt + +VTEFI_PATH=Build/MdeModule/RELEASE_GCC48/$EDKARCH/MdeModulePkg/Application/Ventoy/Ventoy/OUTPUT/Ventoy.efi +DST_PATH=../../INSTALL/ventoy/ventoy_${postfix}.efi + +VTEFI_PATH2=Build/MdeModule/RELEASE_GCC48/$EDKARCH/MdeModulePkg/Application/VtoyUtil/VtoyUtil/OUTPUT/VtoyUtil.efi +DST_PATH2=../../INSTALL/ventoy/vtoyutil_${postfix}.efi + +VTEFI_PATH3=Build/MdeModule/RELEASE_GCC48/$EDKARCH/MdeModulePkg/Application/VDiskChain/VDiskChain/OUTPUT/VDiskChain.efi +DST_PATH3=../../VDiskChain/Tool/vdiskchain_${postfix}.efi + + +rm -f $VTEFI_PATH +rm -f $DST_PATH +rm -f $VTEFI_PATH2 +rm -f $DST_PATH2 +rm -f $VTEFI_PATH3 +[ -d ../../VDiskChain ] && rm -f $DST_PATH3 + +unset WORKSPACE +source ./edksetup.sh + +if [ "$EDKARCH" = "AARCH64" ]; then + GCC48_AARCH64_PREFIX=aarch64-linux-gnu- \ + build -p MdeModulePkg/MdeModulePkg.dsc -a $EDKARCH -b RELEASE -t GCC48 +else + build -p MdeModulePkg/MdeModulePkg.dsc -a $EDKARCH -b RELEASE -t GCC48 +fi + +if [ -e $VTEFI_PATH ] && [ -e $VTEFI_PATH2 ] && [ -e $VTEFI_PATH3 ]; then + echo -e '\n\n====================== SUCCESS ========================\n\n' + cp -a $VTEFI_PATH $DST_PATH + cp -a $VTEFI_PATH2 $DST_PATH2 + [ -d ../../VDiskChain ] && cp -a $VTEFI_PATH3 $DST_PATH3 + cd .. +else + echo -e '\n\n====================== FAILED ========================\n\n' + cd .. + exit 1 +fi + diff --git a/EDK2/build_shim.sh b/EDK2/build_shim.sh new file mode 100644 index 0000000..19c377e --- /dev/null +++ b/EDK2/build_shim.sh @@ -0,0 +1,113 @@ +#!/bin/sh + +if [ -z "$1" ]; then + EDKARCH=X64 + postfix=x64 +elif [ "$1" = "ia32" ]; then + EDKARCH=IA32 + postfix=ia32 + shift +elif [ "$1" = "aa64" ]; then + EDKARCH=AARCH64 + postfix=aa64 + shift +fi + +cd edk2-edk2-stable201911 + +rm -rf ./Conf/.cache +rm -f ./Conf/.AutoGenIdFile.txt + +VTEFI_PATH=Build/MdeModule/RELEASE_GCC48/$EDKARCH/MdeModulePkg/Application/VtoyShim/VtoyShim/OUTPUT/VtoyShim.efi +DST_PATH=../../INSTALL/EFI/BOOT/fb${postfix}.efi + + +rm -f $VTEFI_PATH +rm -f $DST_PATH + +unset WORKSPACE +source ./edksetup.sh + +if [ "$EDKARCH" = "AARCH64" ]; then + PATH=$PATH:/opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/bin \ + GCC48_AARCH64_PREFIX=aarch64-linux-gnu- \ + build -p MdeModulePkg/MdeModulePkg.dsc -a $EDKARCH -b RELEASE -t GCC48 -m MdeModulePkg/Application/VtoyShim/VtoyShim.inf +else + build -p MdeModulePkg/MdeModulePkg.dsc -a $EDKARCH -b RELEASE -t GCC48 -m MdeModulePkg/Application/VtoyShim/VtoyShim.inf +fi + +if [ -e $VTEFI_PATH ]; then + + objdump -h "$VTEFI_PATH" + echo "" + + objcopy \ + --add-section .sbat="MdeModulePkg/Application/VtoyShim/sbat.csv" \ + --set-section-flags .sbat=alloc,load,readonly,data \ + "$VTEFI_PATH" "$DST_PATH" + + #find the right sbat section VMA + tmpfile=$(mktemp) + + cnt1=$(objdump -h "$DST_PATH" | grep -P '^\s*[0-9][0-9]* \.' | wc -l) + cnt2=$(objdump -h "$DST_PATH" | grep -P 'ALLOC' | wc -l) + + if [ $cnt1 -ne $cnt2 ]; then + echo "Section count mismatch $cnt1 $cnt2" + objdump -h "$DST_PATH" + exit 1 + fi + + objdump -h "$DST_PATH" | grep -P '^\s*[0-9][0-9]* \.' > $tmpfile + sbat_size=$(stat -c '%s' MdeModulePkg/Application/VtoyShim/sbat.csv) + sbat_size_hex=$(printf '0x%08x' $sbat_size) + + lmax='0000000000000000' + lsize='0000000000000000' + while read line; do + echo $line + lbase=$(echo $line | awk '{print $4}') + if expr "$lmax" \< "$lbase" > /dev/null; then + lmax=$lbase + lsize=$(echo $line | awk '{print $3}') + fi + echo "max=$lmax size=$lsize" + done < $tmpfile + rm -f $tmpfile + + + lvma=$((0x${lsize}+0x${lmax})) + lvma_align=`printf '0x%08x' $(( (lvma + 4095) / 4096 * 4096 ))` + echo "sbat section lvma_align=$lvma_align" + + objcopy --adjust-section-vma .sbat=$lvma_align "$DST_PATH" + + img_base=$(objdump -p "$DST_PATH" | grep ImageBase | awk '{print $2}') + size_img=0x$(objdump -p "$DST_PATH" | grep SizeOfImage | awk '{print $2}') + sbat_end=`printf '0x%08x' $(($lvma_align+$sbat_size_hex))` + + if [ "$img_base" != "0000000000000000" ]; then + echo "#### ImageBase is not 0 $img_base" + exit 1 + fi + + echo "size_img=$size_img sbat_size=$sbat_size_hex sbat_range $lvma_align - $sbat_end" + + if expr "$size_img" \< "$sbat_end" > /dev/null; then + echo "SizeOfImage $size_img less than sbat section addr $sbat_end" + exit 1 + else + echo "SizeOfImage $size_img >= $sbat_end is OK" + fi + + objdump -h "$DST_PATH" + + echo -e '\n\n====================== SUCCESS ========================\n\n' + + cd .. +else + echo -e '\n\n====================== FAILED ========================\n\n' + cd .. + exit 1 +fi + diff --git a/EDK2/buildedk.sh b/EDK2/buildedk.sh new file mode 100644 index 0000000..14823c0 --- /dev/null +++ b/EDK2/buildedk.sh @@ -0,0 +1,25 @@ +#!/bin/sh + +rm -rf edk2-edk2-stable201911 + +unzip edk2-edk2-stable201911.zip > /dev/null + +/bin/cp -a ./edk2_mod/edk2-edk2-stable201911 ./ + +cd edk2-edk2-stable201911 +make -j 4 -C BaseTools/ +cd .. + +echo '======== build EDK2 for i386-efi ===============' +sh ./build.sh ia32 || exit 1 + +echo '======== build EDK2 for arm64-efi ===============' +sh ./build.sh aa64 || exit 1 + +echo '======== build EDK2 for x86_64-efi ===============' +sh ./build.sh || exit 1 + + +echo '======== build EDK2 for x86_64-efi ===============' +sh ./build_shim.sh || exit 1 + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VDiskChain/VDiskChain.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VDiskChain/VDiskChain.c new file mode 100644 index 0000000..cc978a1 --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VDiskChain/VDiskChain.c @@ -0,0 +1,472 @@ +/****************************************************************************** + * VDiskChain.c + * + * Copyright (c) 2021, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +BOOLEAN gVDiskDebugPrint = FALSE; +vdisk_block_data gVDiskBlockData; + +/* Boot filename */ +CONST CHAR16 *gEfiBootFileName[] = +{ + L"@", + EFI_REMOVABLE_MEDIA_FILE_NAME, +#if defined (MDE_CPU_IA32) + L"\\EFI\\BOOT\\GRUBIA32.EFI", + L"\\EFI\\BOOT\\BOOTia32.EFI", + L"\\EFI\\BOOT\\bootia32.efi", + L"\\efi\\boot\\bootia32.efi", +#elif defined (MDE_CPU_X64) + L"\\EFI\\BOOT\\GRUBX64.EFI", + L"\\EFI\\BOOT\\BOOTx64.EFI", + L"\\EFI\\BOOT\\bootx64.efi", + L"\\efi\\boot\\bootx64.efi", +#elif defined (MDE_CPU_ARM) + L"\\EFI\\BOOT\\GRUBARM.EFI", + L"\\EFI\\BOOT\\BOOTarm.EFI", + L"\\EFI\\BOOT\\bootarm.efi", + L"\\efi\\boot\\bootarm.efi", +#elif defined (MDE_CPU_AARCH64) + L"\\EFI\\BOOT\\GRUBAA64.EFI", + L"\\EFI\\BOOT\\BOOTaa64.EFI", + L"\\EFI\\BOOT\\bootaa64.efi", + L"\\efi\\boot\\bootaa64.efi", +#endif + +}; + +UINT8 *g_disk_buf_addr = NULL; +UINT64 g_disk_buf_size = 0; + +STATIC EFI_GET_VARIABLE g_org_get_variable = NULL; +STATIC EFI_EXIT_BOOT_SERVICES g_org_exit_boot_service = NULL; + +VOID EFIAPI VDiskDebug(IN CONST CHAR8 *Format, ...) +{ + VA_LIST Marker; + CHAR16 Buffer[512]; + + VA_START (Marker, Format); + UnicodeVSPrintAsciiFormat(Buffer, sizeof(Buffer), Format, Marker); + VA_END (Marker); + + gST->ConOut->OutputString(gST->ConOut, Buffer); +} + +VOID EFIAPI vdisk_clear_input(VOID) +{ + EFI_INPUT_KEY Key; + + gST->ConIn->Reset(gST->ConIn, FALSE); + while (EFI_SUCCESS == gST->ConIn->ReadKeyStroke(gST->ConIn, &Key)) + { + ; + } + gST->ConIn->Reset(gST->ConIn, FALSE); +} + +STATIC EFI_STATUS EFIAPI vdisk_load_image +( + IN EFI_HANDLE ImageHandle, + IN EFI_DEVICE_PATH_PROTOCOL *pDevicePath, + IN CONST CHAR16 *FileName, + IN UINTN FileNameLen, + OUT EFI_HANDLE *Image +) +{ + EFI_STATUS Status = EFI_SUCCESS; + CHAR16 TmpBuf[256] = {0}; + FILEPATH_DEVICE_PATH *pFilePath = NULL; + EFI_DEVICE_PATH_PROTOCOL *pImgPath = NULL; + + pFilePath = (FILEPATH_DEVICE_PATH *)TmpBuf; + pFilePath->Header.Type = MEDIA_DEVICE_PATH; + pFilePath->Header.SubType = MEDIA_FILEPATH_DP; + pFilePath->Header.Length[0] = FileNameLen + sizeof(EFI_DEVICE_PATH_PROTOCOL); + pFilePath->Header.Length[1] = 0; + CopyMem(pFilePath->PathName, FileName, FileNameLen); + + pImgPath = AppendDevicePathNode(pDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)pFilePath); + if (!pImgPath) + { + return EFI_NOT_FOUND; + } + + Status = gBS->LoadImage(FALSE, ImageHandle, pImgPath, NULL, 0, Image); + + debug("Load Image File %r DP: <%s>", Status, ConvertDevicePathToText(pImgPath, FALSE, FALSE)); + + FreePool(pImgPath); + + return Status; +} + +STATIC EFI_STATUS EFIAPI vdisk_decompress_vdisk(IN EFI_LOADED_IMAGE_PROTOCOL *pImageInfo) +{ + UINT32 Size; + UINT32 DestinationSize; + UINT32 ScratchSize; + UINT8 *buf; + VOID *ScratchBuf; + EFI_STATUS Status = EFI_SUCCESS; + + (VOID)pImageInfo; + + vdisk_get_vdisk_raw(&buf, &Size); + UefiDecompressGetInfo(buf + VDISK_MAGIC_LEN, Size - VDISK_MAGIC_LEN, &DestinationSize, &ScratchSize); + debug("vdisk: size:%u realsize:%u", Size, DestinationSize); + + g_disk_buf_size = DestinationSize; + g_disk_buf_addr = AllocatePool(DestinationSize); + ScratchBuf = AllocatePool(ScratchSize); + + Status = UefiDecompress(buf + VDISK_MAGIC_LEN, g_disk_buf_addr, ScratchBuf); + FreePool(ScratchBuf); + + debug("Status:%r %p %u", Status, g_disk_buf_addr, (UINT32)g_disk_buf_size); + + return EFI_SUCCESS; +} + +STATIC EFI_STATUS vdisk_patch_vdisk_path(CHAR16 *pos) +{ + UINTN i; + UINTN j; + CHAR16 *end; + CHAR8 *buf = (char *)g_disk_buf_addr; + + if (*pos == L'\"') + { + pos++; + } + + end = StrStr(pos, L".vtoy"); + end += 5;//string length + + for (i = 0; i < g_disk_buf_size; i++) + { + if (*(UINT32 *)(buf + i) == 0x59595959) + { + for (j = 0; j < 300; j++) + { + if (buf[i + j] != 'Y') + { + break; + } + } + + if (j >= 300) + { + break; + } + } + } + + if (i >= g_disk_buf_size) + { + debug("No need to fill vdisk path"); + return 0; + } + + debug("Fill vdisk path at %d", i); + + while (pos != end) + { + buf[i++] = (CHAR8)(*pos++); + } + + buf[i++] = '\"'; + + while (buf[i] == 'Y' || buf[i] == '\"') + { + buf[i] = ' '; + i++; + } + + return 0; +} + +EFI_STATUS EFIAPI vdisk_get_variable_wrapper +( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + OUT UINT32 *Attributes, OPTIONAL + IN OUT UINTN *DataSize, + OUT VOID *Data OPTIONAL +) +{ + EFI_STATUS Status = EFI_SUCCESS; + + Status = g_org_get_variable(VariableName, VendorGuid, Attributes, DataSize, Data); + if (StrCmp(VariableName, L"SecureBoot") == 0) + { + if ((*DataSize == 1) && Data) + { + *(UINT8 *)Data = 0; + } + } + + return Status; +} + +EFI_STATUS EFIAPI vdisk_exit_boot_service_wrapper +( + IN EFI_HANDLE ImageHandle, + IN UINTN MapKey +) +{ + if (g_org_get_variable) + { + gRT->GetVariable = g_org_get_variable; + g_org_get_variable = NULL; + } + + return g_org_exit_boot_service(ImageHandle, MapKey); +} + +STATIC EFI_STATUS EFIAPI vdisk_disable_secure_boot(IN EFI_HANDLE ImageHandle) +{ + /* step1: wrapper security protocol. */ + /* Do we still need it since we have been loaded ? */ + + + /* step2: fake SecureBoot variable */ + g_org_exit_boot_service = gBS->ExitBootServices; + gBS->ExitBootServices = vdisk_exit_boot_service_wrapper; + + g_org_get_variable = gRT->GetVariable; + gRT->GetVariable = vdisk_get_variable_wrapper; + + return EFI_SUCCESS; +} + +STATIC EFI_STATUS EFIAPI vdisk_parse_cmdline(IN EFI_HANDLE ImageHandle) +{ + CHAR16 *Pos = NULL; + CHAR16 *pCmdLine = NULL; + EFI_STATUS Status = EFI_SUCCESS; + EFI_LOADED_IMAGE_PROTOCOL *pImageInfo = NULL; + + Status = gBS->HandleProtocol(ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&pImageInfo); + if (EFI_ERROR(Status)) + { + VDiskDebug("Failed to handle load image protocol %r\n", Status); + return Status; + } + + pCmdLine = (CHAR16 *)AllocatePool(pImageInfo->LoadOptionsSize + 4); + SetMem(pCmdLine, pImageInfo->LoadOptionsSize + 4, 0); + CopyMem(pCmdLine, pImageInfo->LoadOptions, pImageInfo->LoadOptionsSize); + + if (StrStr(pCmdLine, L"debug")) + { + gVDiskDebugPrint = TRUE; + } + + debug("cmdline:<%s>", pCmdLine); + vdisk_debug_pause(); + + Pos = StrStr(pCmdLine, L"vdisk="); + if (NULL == Pos || NULL == StrStr(pCmdLine, L".vtoy")) + { + VDiskDebug("vdisk parameter not found!\n"); + return EFI_NOT_FOUND; + } + + vdisk_decompress_vdisk(pImageInfo); + + vdisk_patch_vdisk_path(Pos + 6); + + if (StrStr(pCmdLine, L"secureboot=off")) + { + vdisk_disable_secure_boot(ImageHandle); + } + + FreePool(pCmdLine); + return EFI_SUCCESS; +} + +EFI_STATUS EFIAPI vdisk_boot(IN EFI_HANDLE ImageHandle) +{ + UINTN t = 0; + UINTN i = 0; + UINTN j = 0; + UINTN Find = 0; + UINTN Count = 0; + EFI_HANDLE Image = NULL; + EFI_HANDLE *Handles = NULL; + EFI_STATUS Status = EFI_SUCCESS; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pFile = NULL; + EFI_DEVICE_PATH_PROTOCOL *pDevPath = NULL; + + for (t = 0; t < 3; t++) + { + Count = 0; + Handles = NULL; + + Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleFileSystemProtocolGuid, + NULL, &Count, &Handles); + if (EFI_ERROR(Status)) + { + return Status; + } + + debug("vdisk_boot fs count:%u", Count); + + for (i = 0; i < Count; i++) + { + Status = gBS->HandleProtocol(Handles[i], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&pFile); + if (EFI_ERROR(Status)) + { + continue; + } + + debug("FS:%u Protocol:%p OpenVolume:%p", i, pFile, pFile->OpenVolume); + + Status = gBS->OpenProtocol(Handles[i], &gEfiDevicePathProtocolGuid, + (VOID **)&pDevPath, + ImageHandle, + Handles[i], + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (EFI_ERROR(Status)) + { + debug("Failed to open device path protocol %r", Status); + continue; + } + + debug("Handle:%p FS DP: <%s>", Handles[i], ConvertDevicePathToText(pDevPath, FALSE, FALSE)); + if (CompareMem(gVDiskBlockData.Path, pDevPath, gVDiskBlockData.DevicePathCompareLen)) + { + debug("Not ventoy disk file system"); + continue; + } + + for (j = 1; j < ARRAY_SIZE(gEfiBootFileName); j++) + { + Status = vdisk_load_image(ImageHandle, pDevPath, gEfiBootFileName[j], + StrSize(gEfiBootFileName[j]), &Image); + if (EFI_SUCCESS == Status) + { + break; + } + debug("Failed to load image %r <%s>", Status, gEfiBootFileName[j]); + } + + if (j >= ARRAY_SIZE(gEfiBootFileName)) + { + continue; + } + + Find++; + debug("Find boot file, now try to boot ....."); + vdisk_debug_pause(); + + if (gVDiskDebugPrint) + { + gST->ConIn->Reset(gST->ConIn, FALSE); + } + + /* can't add debug print here */ + //ventoy_wrapper_system(); + Status = gBS->StartImage(Image, NULL, NULL); + if (EFI_ERROR(Status)) + { + debug("Failed to start image %r", Status); + sleep(3); + gBS->UnloadImage(Image); + break; + } + } + + FreePool(Handles); + + if (Find == 0) + { + debug("Fs not found, now wait and retry..."); + sleep(2); + } + } + + if (Find == 0) + { + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; +} + +EFI_STATUS EFIAPI VDiskChainEfiMain +( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable +) +{ + EFI_STATUS Status = EFI_SUCCESS; + + gST->ConOut->ClearScreen(gST->ConOut); + vdisk_clear_input(); + + Status = vdisk_parse_cmdline(ImageHandle); + if (EFI_ERROR(Status)) + { + return Status; + } + + vdisk_install_blockio(ImageHandle, g_disk_buf_size); + vdisk_debug_pause(); + + Status = vdisk_boot(ImageHandle); + + gBS->DisconnectController(gVDiskBlockData.Handle, NULL, NULL); + gBS->UninstallMultipleProtocolInterfaces(gVDiskBlockData.Handle, + &gEfiBlockIoProtocolGuid, &gVDiskBlockData.BlockIo, + &gEfiDevicePathProtocolGuid, gVDiskBlockData.Path, + NULL); + + if (EFI_NOT_FOUND == Status) + { + gST->ConOut->OutputString(gST->ConOut, L"No bootfile found for UEFI!\r\n"); + gST->ConOut->OutputString(gST->ConOut, L"Maybe the image does not support " VENTOY_UEFI_DESC L"!\r\n"); + sleep(30); + } + + vdisk_clear_input(); + gST->ConOut->ClearScreen(gST->ConOut); + + return EFI_SUCCESS; +} + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VDiskChain/VDiskChain.h b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VDiskChain/VDiskChain.h new file mode 100644 index 0000000..d4d21d0 --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VDiskChain/VDiskChain.h @@ -0,0 +1,97 @@ +/****************************************************************************** + * VDiskChain.h + * + * Copyright (c) 2021, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#ifndef __VENTOY_H__ +#define __VENTOY_H__ + +#define VDISK_MAGIC_LEN 32 + +#define VDISK_BLOCK_DEVICE_PATH_GUID \ + { 0x6ed2134e, 0xc2ea, 0x4943, { 0x99, 0x54, 0xa7, 0x76, 0xe5, 0x9c, 0x12, 0xc3 }} + +#define VDISK_BLOCK_DEVICE_PATH_NAME L"vdisk" + +#if defined (MDE_CPU_IA32) + #define VENTOY_UEFI_DESC L"IA32 UEFI" +#elif defined (MDE_CPU_X64) + #define VENTOY_UEFI_DESC L"X64 UEFI" +#elif defined (MDE_CPU_EBC) +#elif defined (MDE_CPU_ARM) + #define VENTOY_UEFI_DESC L"ARM UEFI" +#elif defined (MDE_CPU_AARCH64) + #define VENTOY_UEFI_DESC L"ARM64 UEFI" +#else + #error Unknown Processor Type +#endif + +typedef struct vdisk_block_data +{ + EFI_HANDLE Handle; + EFI_BLOCK_IO_MEDIA Media; /* Media descriptor */ + EFI_BLOCK_IO_PROTOCOL BlockIo; /* Block I/O protocol */ + + UINTN DevicePathCompareLen; + EFI_DEVICE_PATH_PROTOCOL *Path; /* Device path protocol */ + + EFI_HANDLE RawBlockIoHandle; + EFI_BLOCK_IO_PROTOCOL *pRawBlockIo; + EFI_DEVICE_PATH_PROTOCOL *pDiskDevPath; + + /* ventoy disk part2 ESP */ + EFI_HANDLE DiskFsHandle; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pDiskFs; + EFI_DEVICE_PATH_PROTOCOL *pDiskFsDevPath; + + EFI_HANDLE IsoDriverImage; +}vdisk_block_data; + + +#define debug(expr, ...) if (gVDiskDebugPrint) VDiskDebug("[VDISK] "expr"\r\n", ##__VA_ARGS__) +#define trace(expr, ...) VDiskDebug("[VDISK] "expr"\r\n", ##__VA_ARGS__) +#define sleep(sec) gBS->Stall(1000000 * (sec)) + +#define vdisk_debug_pause() \ +if (gVDiskDebugPrint) \ +{ \ + UINTN __Index = 0; \ + gST->ConOut->OutputString(gST->ConOut, L"[VDISK] ###### Press Enter to continue... ######\r\n");\ + gST->ConIn->Reset(gST->ConIn, FALSE); \ + gBS->WaitForEvent(1, &gST->ConIn->WaitForKey, &__Index);\ +} + +extern BOOLEAN gVDiskDebugPrint; +VOID EFIAPI VDiskDebug(IN CONST CHAR8 *Format, ...); +EFI_STATUS EFIAPI vdisk_block_io_read +( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + OUT VOID *Buffer +); + +extern UINT8 *g_disk_buf_addr; +extern UINT64 g_disk_buf_size; +extern vdisk_block_data gVDiskBlockData; +EFI_STATUS EFIAPI vdisk_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 ImgSize); +int vdisk_get_vdisk_raw(UINT8 **buf, UINT32 *size); + +#endif + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VDiskChain/VDiskChain.inf b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VDiskChain/VDiskChain.inf new file mode 100644 index 0000000..2f8cfef --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VDiskChain/VDiskChain.inf @@ -0,0 +1,82 @@ +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = VDiskChain + FILE_GUID = 5bce96e3-ba11-4440-833b-299cf5849193 + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + ENTRY_POINT = VDiskChainEfiMain + + +[Sources] + VDiskChain.h + VDiskChain.c + VDiskRawData.c + VDiskChainProtocol.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ShellPkg/ShellPkg.dec + +[LibraryClasses] + UefiApplicationEntryPoint + UefiLib + DebugLib + UefiDecompressLib + +[Guids] + gShellVariableGuid + gEfiVirtualCdGuid + gEfiFileInfoGuid + +[Protocols] + gEfiLoadedImageProtocolGuid + gEfiBlockIoProtocolGuid + gEfiDevicePathProtocolGuid + gEfiSimpleFileSystemProtocolGuid + gEfiRamDiskProtocolGuid + gEfiAbsolutePointerProtocolGuid + gEfiAcpiTableProtocolGuid + gEfiBlockIo2ProtocolGuid + gEfiBusSpecificDriverOverrideProtocolGuid + gEfiComponentNameProtocolGuid + gEfiComponentName2ProtocolGuid + gEfiDriverBindingProtocolGuid + gEfiDiskIoProtocolGuid + gEfiDiskIo2ProtocolGuid + gEfiGraphicsOutputProtocolGuid + gEfiHiiConfigAccessProtocolGuid + gEfiHiiFontProtocolGuid + gEfiLoadFileProtocolGuid + gEfiLoadFile2ProtocolGuid + gEfiLoadedImageProtocolGuid + gEfiLoadedImageDevicePathProtocolGuid + gEfiPciIoProtocolGuid + gEfiSerialIoProtocolGuid + gEfiSimpleTextInProtocolGuid + gEfiSimpleTextInputExProtocolGuid + gEfiSimpleTextOutProtocolGuid + + + + + + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VDiskChain/VDiskChainProtocol.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VDiskChain/VDiskChainProtocol.c new file mode 100644 index 0000000..a6a6ad0 --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VDiskChain/VDiskChainProtocol.c @@ -0,0 +1,264 @@ +/****************************************************************************** + * VDiskChainProtocol.c + * + * Copyright (c) 2021, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* EFI block device vendor device path GUID */ +EFI_GUID gVDiskBlockDevicePathGuid = VDISK_BLOCK_DEVICE_PATH_GUID; + +EFI_STATUS EFIAPI vdisk_block_io_reset +( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN BOOLEAN ExtendedVerification +) +{ + (VOID)This; + (VOID)ExtendedVerification; + return EFI_SUCCESS; +} + +EFI_STATUS EFIAPI vdisk_block_io_flush(IN EFI_BLOCK_IO_PROTOCOL *This) +{ + (VOID)This; + return EFI_SUCCESS; +} + +EFI_STATUS EFIAPI vdisk_block_io_read +( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + OUT VOID *Buffer +) +{ + (VOID)This; + (VOID)MediaId; + + debug("vdisk_block_io_read %lu %lu\n", Lba, BufferSize / 512); + CopyMem(Buffer, g_disk_buf_addr + (Lba * 512), BufferSize); + + return EFI_SUCCESS; +} + +EFI_STATUS EFIAPI vdisk_block_io_write +( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + IN VOID *Buffer +) +{ + (VOID)This; + (VOID)MediaId; + (VOID)Buffer; + + debug("vdisk_block_io_read %lu %lu\n", Lba, BufferSize / 512); + return EFI_WRITE_PROTECTED; +} + +EFI_STATUS EFIAPI vdisk_fill_device_path(VOID) +{ + UINTN NameLen = 0; + UINT8 TmpBuf[128] = {0}; + VENDOR_DEVICE_PATH *venPath = NULL; + + venPath = (VENDOR_DEVICE_PATH *)TmpBuf; + NameLen = StrSize(VDISK_BLOCK_DEVICE_PATH_NAME); + venPath->Header.Type = HARDWARE_DEVICE_PATH; + venPath->Header.SubType = HW_VENDOR_DP; + venPath->Header.Length[0] = sizeof(VENDOR_DEVICE_PATH) + NameLen; + venPath->Header.Length[1] = 0; + CopyMem(&venPath->Guid, &gVDiskBlockDevicePathGuid, sizeof(EFI_GUID)); + CopyMem(venPath + 1, VDISK_BLOCK_DEVICE_PATH_NAME, NameLen); + + gVDiskBlockData.Path = AppendDevicePathNode(NULL, (EFI_DEVICE_PATH_PROTOCOL *)TmpBuf); + gVDiskBlockData.DevicePathCompareLen = sizeof(VENDOR_DEVICE_PATH) + NameLen; + + debug("gVDiskBlockData.Path=<%s>\n", ConvertDevicePathToText(gVDiskBlockData.Path, FALSE, FALSE)); + + return EFI_SUCCESS; +} + +EFI_STATUS EFIAPI vdisk_connect_driver(IN EFI_HANDLE ControllerHandle, IN CONST CHAR16 *DrvName) +{ + UINTN i = 0; + UINTN Count = 0; + CHAR16 *DriverName = NULL; + EFI_HANDLE *Handles = NULL; + EFI_HANDLE DrvHandles[2] = { NULL }; + EFI_STATUS Status = EFI_SUCCESS; + EFI_COMPONENT_NAME_PROTOCOL *NameProtocol = NULL; + EFI_COMPONENT_NAME2_PROTOCOL *Name2Protocol = NULL; + + debug("vdisk_connect_driver <%s>...", DrvName); + + Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiComponentName2ProtocolGuid, + NULL, &Count, &Handles); + if (EFI_ERROR(Status)) + { + return Status; + } + + for (i = 0; i < Count; i++) + { + Status = gBS->HandleProtocol(Handles[i], &gEfiComponentName2ProtocolGuid, (VOID **)&Name2Protocol); + if (EFI_ERROR(Status)) + { + continue; + } + + Status = Name2Protocol->GetDriverName(Name2Protocol, "en", &DriverName); + if (EFI_ERROR(Status) || NULL == DriverName) + { + continue; + } + + if (StrStr(DriverName, DrvName)) + { + debug("Find driver name2:<%s>: <%s>", DriverName, DrvName); + DrvHandles[0] = Handles[i]; + break; + } + } + + if (i < Count) + { + Status = gBS->ConnectController(ControllerHandle, DrvHandles, NULL, TRUE); + debug("vdisk_connect_driver:<%s> <%r>", DrvName, Status); + goto end; + } + + debug("%s NOT found, now try COMPONENT_NAME", DrvName); + + Count = 0; + FreePool(Handles); + Handles = NULL; + + Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiComponentNameProtocolGuid, + NULL, &Count, &Handles); + if (EFI_ERROR(Status)) + { + return Status; + } + + for (i = 0; i < Count; i++) + { + Status = gBS->HandleProtocol(Handles[i], &gEfiComponentNameProtocolGuid, (VOID **)&NameProtocol); + if (EFI_ERROR(Status)) + { + continue; + } + + Status = NameProtocol->GetDriverName(NameProtocol, "en", &DriverName); + if (EFI_ERROR(Status)) + { + continue; + } + + if (StrStr(DriverName, DrvName)) + { + debug("Find driver name:<%s>: <%s>", DriverName, DrvName); + DrvHandles[0] = Handles[i]; + break; + } + } + + if (i < Count) + { + Status = gBS->ConnectController(ControllerHandle, DrvHandles, NULL, TRUE); + debug("vdisk_connect_driver:<%s> <%r>", DrvName, Status); + goto end; + } + + Status = EFI_NOT_FOUND; + +end: + FreePool(Handles); + + return Status; +} + +EFI_STATUS EFIAPI vdisk_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 ImgSize) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_BLOCK_IO_PROTOCOL *pBlockIo = &(gVDiskBlockData.BlockIo); + + vdisk_fill_device_path(); + + debug("install block io protocol %p", ImageHandle); + vdisk_debug_pause(); + + gVDiskBlockData.Media.BlockSize = 512; + gVDiskBlockData.Media.LastBlock = ImgSize / 512 - 1; + gVDiskBlockData.Media.ReadOnly = TRUE; + gVDiskBlockData.Media.MediaPresent = 1; + gVDiskBlockData.Media.LogicalBlocksPerPhysicalBlock = 1; + + pBlockIo->Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3; + pBlockIo->Media = &(gVDiskBlockData.Media); + pBlockIo->Reset = vdisk_block_io_reset; + pBlockIo->ReadBlocks = vdisk_block_io_read; + pBlockIo->WriteBlocks = vdisk_block_io_write; + pBlockIo->FlushBlocks = vdisk_block_io_flush; + + Status = gBS->InstallMultipleProtocolInterfaces(&gVDiskBlockData.Handle, + &gEfiBlockIoProtocolGuid, &gVDiskBlockData.BlockIo, + &gEfiDevicePathProtocolGuid, gVDiskBlockData.Path, + NULL); + debug("Install protocol %r %p", Status, gVDiskBlockData.Handle); + if (EFI_ERROR(Status)) + { + return Status; + } + + Status = vdisk_connect_driver(gVDiskBlockData.Handle, L"Disk I/O Driver"); + debug("Connect disk IO driver %r", Status); + + Status = vdisk_connect_driver(gVDiskBlockData.Handle, L"Partition Driver"); + debug("Connect partition driver %r", Status); + if (EFI_ERROR(Status)) + { + Status = gBS->ConnectController(gVDiskBlockData.Handle, NULL, NULL, TRUE); + debug("Connect all controller %r", Status); + } + + vdisk_debug_pause(); + + return EFI_SUCCESS; +} + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VDiskChain/VDiskRawData.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VDiskChain/VDiskRawData.c new file mode 100644 index 0000000..a0aaaa1 --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VDiskChain/VDiskRawData.c @@ -0,0 +1,2 @@ +#include +int vdisk_get_vdisk_raw(UINT8 **buf, UINT32 *size) { *buf = NULL; *size = 0; return 0; } \ No newline at end of file diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.c new file mode 100644 index 0000000..6534201 --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.c @@ -0,0 +1,1356 @@ +/****************************************************************************** + * Ventoy.c + * + * Copyright (c) 2020, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +BOOLEAN gDebugPrint = FALSE; +BOOLEAN gBootFallBack = FALSE; +BOOLEAN gDotEfiBoot = FALSE; +BOOLEAN gLoadIsoEfi = FALSE; +BOOLEAN gIsoUdf = FALSE; +ventoy_ram_disk g_ramdisk_param; +ventoy_chain_head *g_chain; +void *g_vtoy_img_location_buf; +ventoy_img_chunk *g_chunk; +UINT8 *g_os_param_reserved; +UINT32 g_img_chunk_num; +ventoy_override_chunk *g_override_chunk; +UINT32 g_override_chunk_num; +ventoy_virt_chunk *g_virt_chunk; +UINT32 g_virt_chunk_num; +vtoy_block_data gBlockData; +static grub_env_get_pf grub_env_get = NULL; +static grub_env_set_pf grub_env_set = NULL; + +ventoy_grub_param_file_replace *g_file_replace_list = NULL; +ventoy_efi_file_replace g_efi_file_replace; + +ventoy_grub_param_file_replace *g_img_replace_list = NULL; +ventoy_efi_file_replace g_img_file_replace[VTOY_MAX_CONF_REPLACE]; + +CONST CHAR16 gIso9660EfiDriverPath[] = ISO9660_EFI_DRIVER_PATH; +CONST CHAR16 gUdfEfiDriverPath[] = UDF_EFI_DRIVER_PATH; + +BOOLEAN g_fix_windows_1st_cdrom_issue = FALSE; + +STATIC BOOLEAN g_hook_keyboard = FALSE; + +CHAR16 gFirstTryBootFile[256] = {0}; + +STATIC EFI_GET_VARIABLE g_org_get_variable = NULL; +STATIC EFI_EXIT_BOOT_SERVICES g_org_exit_boot_service = NULL; + +/* Boot filename */ +UINTN gBootFileStartIndex = 1; +CONST CHAR16 *gEfiBootFileName[] = +{ + L"@", + EFI_REMOVABLE_MEDIA_FILE_NAME, +#if defined (MDE_CPU_IA32) + L"\\EFI\\BOOT\\GRUBIA32.EFI", + L"\\EFI\\BOOT\\BOOTia32.EFI", + L"\\EFI\\BOOT\\bootia32.efi", + L"\\efi\\boot\\bootia32.efi", +#elif defined (MDE_CPU_X64) + L"\\EFI\\BOOT\\GRUBX64.EFI", + L"\\EFI\\BOOT\\BOOTx64.EFI", + L"\\EFI\\BOOT\\bootx64.efi", + L"\\efi\\boot\\bootx64.efi", +#elif defined (MDE_CPU_ARM) + L"\\EFI\\BOOT\\GRUBARM.EFI", + L"\\EFI\\BOOT\\BOOTarm.EFI", + L"\\EFI\\BOOT\\bootarm.efi", + L"\\efi\\boot\\bootarm.efi", +#elif defined (MDE_CPU_AARCH64) + L"\\EFI\\BOOT\\GRUBAA64.EFI", + L"\\EFI\\BOOT\\BOOTaa64.EFI", + L"\\EFI\\BOOT\\bootaa64.efi", + L"\\efi\\boot\\bootaa64.efi", +#endif + +}; + +VOID EFIAPI VtoyDebug(IN CONST CHAR8 *Format, ...) +{ + VA_LIST Marker; + CHAR16 Buffer[512]; + + VA_START (Marker, Format); + UnicodeVSPrintAsciiFormat(Buffer, sizeof(Buffer), Format, Marker); + VA_END (Marker); + + gST->ConOut->OutputString(gST->ConOut, Buffer); +} + +VOID EFIAPI ventoy_clear_input(VOID) +{ + EFI_INPUT_KEY Key; + + gST->ConIn->Reset(gST->ConIn, FALSE); + while (EFI_SUCCESS == gST->ConIn->ReadKeyStroke(gST->ConIn, &Key)) + { + ; + } + gST->ConIn->Reset(gST->ConIn, FALSE); +} + +static void EFIAPI ventoy_dump_img_chunk(ventoy_chain_head *chain) +{ + UINT32 i; + int errcnt = 0; + UINT64 img_sec = 0; + ventoy_img_chunk *chunk; + + chunk = (ventoy_img_chunk *)((char *)chain + chain->img_chunk_offset); + + debug("##################### ventoy_dump_img_chunk #######################"); + + for (i = 0; i < chain->img_chunk_num; i++) + { + debug("%2u: [ %u - %u ] <==> [ %llu - %llu ]", + i, chunk[i].img_start_sector, chunk[i].img_end_sector, + chunk[i].disk_start_sector, chunk[i].disk_end_sector); + + if (i > 0 && (chunk[i].img_start_sector != chunk[i - 1].img_end_sector + 1)) + { + errcnt++; + } + + img_sec += chunk[i].img_end_sector - chunk[i].img_start_sector + 1; + } + + if (errcnt == 0 && (img_sec * 2048 == g_chain->real_img_size_in_bytes)) + { + debug("image chunk size check success"); + } + else + { + debug("image chunk size check failed %d", errcnt); + } + + ventoy_debug_pause(); +} + +static void EFIAPI ventoy_dump_override_chunk(ventoy_chain_head *chain) +{ + UINT32 i; + ventoy_override_chunk *chunk; + + chunk = (ventoy_override_chunk *)((char *)chain + chain->override_chunk_offset); + + debug("##################### ventoy_dump_override_chunk #######################"); + + for (i = 0; i < g_override_chunk_num; i++) + { + debug("%2u: [ %llu, %u ]", i, chunk[i].img_offset, chunk[i].override_size); + } + + ventoy_debug_pause(); +} + +static void EFIAPI ventoy_dump_virt_chunk(ventoy_chain_head *chain) +{ + UINT32 i; + ventoy_virt_chunk *node; + + debug("##################### ventoy_dump_virt_chunk #######################"); + debug("virt_chunk_offset=%u", chain->virt_chunk_offset); + debug("virt_chunk_num=%u", chain->virt_chunk_num); + + node = (ventoy_virt_chunk *)((char *)chain + chain->virt_chunk_offset); + for (i = 0; i < chain->virt_chunk_num; i++, node++) + { + debug("%2u: mem:[ %u, %u, %u ] remap:[ %u, %u, %u ]", i, + node->mem_sector_start, + node->mem_sector_end, + node->mem_sector_offset, + node->remap_sector_start, + node->remap_sector_end, + node->org_sector_start); + } + + ventoy_debug_pause(); +} + +static void EFIAPI ventoy_dump_chain(ventoy_chain_head *chain) +{ + UINT32 i = 0; + UINT8 chksum = 0; + UINT8 *guid; + + guid = chain->os_param.vtoy_disk_guid; + for (i = 0; i < sizeof(ventoy_os_param); i++) + { + chksum += *((UINT8 *)(&(chain->os_param)) + i); + } + + debug("##################### ventoy_dump_chain #######################"); + + debug("os_param->chksum=0x%x (%a)", chain->os_param.chksum, chksum ? "FAILED" : "SUCCESS"); + debug("os_param->vtoy_disk_guid=%02x%02x%02x%02x", guid[0], guid[1], guid[2], guid[3]); + debug("os_param->vtoy_disk_size=%llu", chain->os_param.vtoy_disk_size); + debug("os_param->vtoy_disk_part_id=%u", chain->os_param.vtoy_disk_part_id); + debug("os_param->vtoy_disk_part_type=%u", chain->os_param.vtoy_disk_part_type); + debug("os_param->vtoy_img_path=<%a>", chain->os_param.vtoy_img_path); + debug("os_param->vtoy_img_size=<%llu>", chain->os_param.vtoy_img_size); + debug("os_param->vtoy_img_location_addr=<0x%llx>", chain->os_param.vtoy_img_location_addr); + debug("os_param->vtoy_img_location_len=<%u>", chain->os_param.vtoy_img_location_len); + debug("os_param->vtoy_reserved=<%u %u %u %u %u %u %u>", + g_os_param_reserved[0], + g_os_param_reserved[1], + g_os_param_reserved[2], + g_os_param_reserved[3], + g_os_param_reserved[4], + g_os_param_reserved[5], + g_os_param_reserved[6] + ); + + ventoy_debug_pause(); + + debug("chain->disk_drive=0x%x", chain->disk_drive); + debug("chain->disk_sector_size=%u", chain->disk_sector_size); + debug("chain->real_img_size_in_bytes=%llu", chain->real_img_size_in_bytes); + debug("chain->virt_img_size_in_bytes=%llu", chain->virt_img_size_in_bytes); + debug("chain->boot_catalog=%u", chain->boot_catalog); + debug("chain->img_chunk_offset=%u", chain->img_chunk_offset); + debug("chain->img_chunk_num=%u", chain->img_chunk_num); + debug("chain->override_chunk_offset=%u", chain->override_chunk_offset); + debug("chain->override_chunk_num=%u", chain->override_chunk_num); + + ventoy_debug_pause(); + + ventoy_dump_img_chunk(chain); + ventoy_dump_override_chunk(chain); + ventoy_dump_virt_chunk(chain); +} + +static int ventoy_update_image_location(ventoy_os_param *param) +{ + EFI_STATUS Status = EFI_SUCCESS; + UINT8 chksum = 0; + unsigned int i; + unsigned int length; + UINTN address = 0; + void *buffer = NULL; + ventoy_image_location *location = NULL; + ventoy_image_disk_region *region = NULL; + ventoy_img_chunk *chunk = g_chunk; + + length = sizeof(ventoy_image_location) + (g_img_chunk_num - 1) * sizeof(ventoy_image_disk_region); + + Status = gBS->AllocatePool(EfiRuntimeServicesData, length + 4096 * 2, &buffer); + if (EFI_ERROR(Status) || NULL == buffer) + { + debug("Failed to allocate runtime pool %r\n", Status); + return 1; + } + + address = (UINTN)buffer; + g_vtoy_img_location_buf = buffer; + + if (address % 4096) + { + address += 4096 - (address % 4096); + } + + param->chksum = 0; + param->vtoy_img_location_addr = address; + param->vtoy_img_location_len = length; + + /* update check sum */ + for (i = 0; i < sizeof(ventoy_os_param); i++) + { + chksum += *((UINT8 *)param + i); + } + param->chksum = (chksum == 0) ? 0 : (UINT8)(0x100 - chksum); + + location = (ventoy_image_location *)(unsigned long)(param->vtoy_img_location_addr); + if (NULL == location) + { + return 0; + } + + CopyMem(&location->guid, ¶m->guid, sizeof(ventoy_guid)); + location->image_sector_size = gSector512Mode ? 512 : 2048; + location->disk_sector_size = g_chain->disk_sector_size; + location->region_count = g_img_chunk_num; + + region = location->regions; + + if (gSector512Mode) + { + for (i = 0; i < g_img_chunk_num; i++) + { + region->image_sector_count = chunk->disk_end_sector - chunk->disk_start_sector + 1; + region->image_start_sector = chunk->img_start_sector * 4; + region->disk_start_sector = chunk->disk_start_sector; + region++; + chunk++; + } + } + else + { + for (i = 0; i < g_img_chunk_num; i++) + { + region->image_sector_count = chunk->img_end_sector - chunk->img_start_sector + 1; + region->image_start_sector = chunk->img_start_sector; + region->disk_start_sector = chunk->disk_start_sector; + region++; + chunk++; + } + } + + return 0; +} + +EFI_HANDLE EFIAPI ventoy_get_parent_handle(IN EFI_DEVICE_PATH_PROTOCOL *pDevPath) +{ + EFI_HANDLE Handle = NULL; + EFI_STATUS Status = EFI_SUCCESS; + EFI_DEVICE_PATH_PROTOCOL *pLastNode = NULL; + EFI_DEVICE_PATH_PROTOCOL *pCurNode = NULL; + EFI_DEVICE_PATH_PROTOCOL *pTmpDevPath = NULL; + + pTmpDevPath = DuplicateDevicePath(pDevPath); + if (!pTmpDevPath) + { + return NULL; + } + + pCurNode = pTmpDevPath; + while (!IsDevicePathEnd(pCurNode)) + { + pLastNode = pCurNode; + pCurNode = NextDevicePathNode(pCurNode); + } + if (pLastNode) + { + CopyMem(pLastNode, pCurNode, sizeof(EFI_DEVICE_PATH_PROTOCOL)); + } + + pCurNode = pTmpDevPath; + Status = gBS->LocateDevicePath(&gEfiDevicePathProtocolGuid, &pCurNode, &Handle); + debug("Status:%r Parent Handle:%p DP:%s", Status, Handle, ConvertDevicePathToText(pTmpDevPath, FALSE, FALSE)); + + FreePool(pTmpDevPath); + + return Handle; +} + +STATIC ventoy_ram_disk g_backup_ramdisk_param; +STATIC ventoy_os_param g_backup_os_param_var; + + +EFI_STATUS EFIAPI ventoy_save_ramdisk_param(VOID) +{ + UINTN DataSize; + EFI_STATUS Status = EFI_SUCCESS; + EFI_GUID VarGuid = VENTOY_GUID; + + DataSize = sizeof(g_backup_ramdisk_param); + Status = gRT->GetVariable(L"VentoyRamDisk", &VarGuid, NULL, &DataSize, &g_backup_ramdisk_param); + if (!EFI_ERROR(Status)) + { + debug("find previous ramdisk variable <%llu>", g_backup_ramdisk_param.DiskSize); + } + + Status = gRT->SetVariable(L"VentoyRamDisk", &VarGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof(g_ramdisk_param), &(g_ramdisk_param)); + debug("set ramdisk variable %r", Status); + + return Status; +} + +EFI_STATUS EFIAPI ventoy_delete_ramdisk_param(VOID) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_GUID VarGuid = VENTOY_GUID; + + if (g_backup_ramdisk_param.DiskSize > 0 && g_backup_ramdisk_param.PhyAddr > 0) + { + Status = gRT->SetVariable(L"VentoyRamDisk", &VarGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof(g_backup_ramdisk_param), &g_backup_ramdisk_param); + debug("resotre ramdisk variable %r", Status); + } + else + { + Status = gRT->SetVariable(L"VentoyRamDisk", &VarGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + 0, NULL); + debug("delete ramdisk variable %r", Status); + } + + return Status; +} + +EFI_STATUS EFIAPI ventoy_save_variable(VOID) +{ + UINTN DataSize; + EFI_STATUS Status = EFI_SUCCESS; + EFI_GUID VarGuid = VENTOY_GUID; + + DataSize = sizeof(g_backup_os_param_var); + Status = gRT->GetVariable(L"VentoyOsParam", &VarGuid, NULL, &DataSize, &g_backup_os_param_var); + if (!EFI_ERROR(Status)) + { + debug("find previous efi variable <%a>", g_backup_os_param_var.vtoy_img_path); + } + + Status = gRT->SetVariable(L"VentoyOsParam", &VarGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof(g_chain->os_param), &(g_chain->os_param)); + debug("set efi variable %r", Status); + + return Status; +} + +EFI_STATUS EFIAPI ventoy_delete_variable(VOID) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_GUID VarGuid = VENTOY_GUID; + + if (0 == CompareMem(&(g_backup_os_param_var.guid), &VarGuid, sizeof(EFI_GUID))) + { + Status = gRT->SetVariable(L"VentoyOsParam", &VarGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof(g_backup_os_param_var), &(g_backup_os_param_var)); + debug("restore efi variable %r", Status); + } + else + { + Status = gRT->SetVariable(L"VentoyOsParam", &VarGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + 0, NULL); + debug("delete efi variable %r", Status); + } + + return Status; +} + +#if (VENTOY_DEVICE_WARN != 0) +STATIC VOID ventoy_warn_invalid_device(VOID) +{ + STATIC BOOLEAN flag = FALSE; + + if (flag) + { + return; + } + + flag = TRUE; + gST->ConOut->ClearScreen(gST->ConOut); + gST->ConOut->OutputString(gST->ConOut, VTOY_WARNING L"\r\n"); + gST->ConOut->OutputString(gST->ConOut, VTOY_WARNING L"\r\n"); + gST->ConOut->OutputString(gST->ConOut, VTOY_WARNING L"\r\n\r\n\r\n"); + + gST->ConOut->OutputString(gST->ConOut, L"This is NOT a standard Ventoy device and is NOT supported.\r\n\r\n"); + gST->ConOut->OutputString(gST->ConOut, L"You should follow the official instructions in https://www.ventoy.net\r\n"); + + gST->ConOut->OutputString(gST->ConOut, L"\r\n\r\nWill exit after 10 seconds ...... "); + + sleep(10); +} +#else +STATIC VOID ventoy_warn_invalid_device(VOID) +{ + +} +#endif + +STATIC EFI_STATUS EFIAPI ventoy_load_image +( + IN EFI_HANDLE ImageHandle, + IN EFI_DEVICE_PATH_PROTOCOL *pDevicePath, + IN CONST CHAR16 *FileName, + IN UINTN FileNameLen, + OUT EFI_HANDLE *Image +) +{ + EFI_STATUS Status = EFI_SUCCESS; + CHAR16 TmpBuf[256] = {0}; + FILEPATH_DEVICE_PATH *pFilePath = NULL; + EFI_DEVICE_PATH_PROTOCOL *pImgPath = NULL; + + pFilePath = (FILEPATH_DEVICE_PATH *)TmpBuf; + pFilePath->Header.Type = MEDIA_DEVICE_PATH; + pFilePath->Header.SubType = MEDIA_FILEPATH_DP; + pFilePath->Header.Length[0] = FileNameLen + sizeof(EFI_DEVICE_PATH_PROTOCOL); + pFilePath->Header.Length[1] = 0; + CopyMem(pFilePath->PathName, FileName, FileNameLen); + + pImgPath = AppendDevicePathNode(pDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)pFilePath); + if (!pImgPath) + { + return EFI_NOT_FOUND; + } + + Status = gBS->LoadImage(FALSE, ImageHandle, pImgPath, NULL, 0, Image); + + debug("Load Image File %r DP: <%s>", Status, ConvertDevicePathToText(pImgPath, FALSE, FALSE)); + + FreePool(pImgPath); + + return Status; +} + + +STATIC EFI_STATUS EFIAPI ventoy_find_iso_disk(IN EFI_HANDLE ImageHandle) +{ + UINTN i = 0; + UINTN Count = 0; + UINT64 DiskSize = 0; + MBR_HEAD *pMBR = NULL; + UINT8 *pBuffer = NULL; + EFI_HANDLE *Handles; + EFI_STATUS Status = EFI_SUCCESS; + EFI_BLOCK_IO_PROTOCOL *pBlockIo; + + pBuffer = AllocatePool(2048); + if (!pBuffer) + { + return EFI_OUT_OF_RESOURCES; + } + + Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiBlockIoProtocolGuid, + NULL, &Count, &Handles); + if (EFI_ERROR(Status)) + { + FreePool(pBuffer); + return Status; + } + + for (i = 0; i < Count; i++) + { + Status = gBS->HandleProtocol(Handles[i], &gEfiBlockIoProtocolGuid, (VOID **)&pBlockIo); + if (EFI_ERROR(Status)) + { + continue; + } + + DiskSize = (pBlockIo->Media->LastBlock + 1) * pBlockIo->Media->BlockSize; + debug("This Disk size: %llu", DiskSize); + if (g_chain->os_param.vtoy_disk_size != DiskSize) + { + continue; + } + + Status = pBlockIo->ReadBlocks(pBlockIo, pBlockIo->Media->MediaId, 0, 512, pBuffer); + if (EFI_ERROR(Status)) + { + debug("ReadBlocks filed %r", Status); + continue; + } + + if (CompareMem(g_chain->os_param.vtoy_disk_guid, pBuffer + 0x180, 16) == 0 && + CompareMem(g_chain->os_param.vtoy_disk_signature, pBuffer + 0x1b8, 4) == 0) + { + pMBR = (MBR_HEAD *)pBuffer; + if (g_os_param_reserved[6] == 0 && pMBR->PartTbl[0].FsFlag != 0xEE) + { + if (pMBR->PartTbl[0].StartSectorId != 2048 || + pMBR->PartTbl[1].SectorCount != 65536 || + pMBR->PartTbl[1].StartSectorId != pMBR->PartTbl[0].StartSectorId + pMBR->PartTbl[0].SectorCount) + { + debug("Failed to check disk part table"); + ventoy_warn_invalid_device(); + } + } + + gBlockData.RawBlockIoHandle = Handles[i]; + gBlockData.pRawBlockIo = pBlockIo; + gBS->OpenProtocol(Handles[i], &gEfiDevicePathProtocolGuid, + (VOID **)&(gBlockData.pDiskDevPath), + ImageHandle, + Handles[i], + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + + debug("Find Ventoy Disk Sig Handle:%p DP:%s", Handles[i], + ConvertDevicePathToText(gBlockData.pDiskDevPath, FALSE, FALSE)); + break; + } + } + + FreePool(Handles); + + if (i >= Count) + { + return EFI_NOT_FOUND; + } + else + { + return EFI_SUCCESS; + } +} + + +STATIC EFI_STATUS EFIAPI ventoy_find_iso_disk_fs(IN EFI_HANDLE ImageHandle) +{ + UINTN i = 0; + UINTN Count = 0; + EFI_HANDLE Parent = NULL; + EFI_HANDLE *Handles = NULL; + EFI_STATUS Status = EFI_SUCCESS; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pFile = NULL; + EFI_DEVICE_PATH_PROTOCOL *pDevPath = NULL; + + Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleFileSystemProtocolGuid, + NULL, &Count, &Handles); + if (EFI_ERROR(Status)) + { + return Status; + } + + debug("ventoy_find_iso_disk_fs fs count:%u", Count); + + for (i = 0; i < Count; i++) + { + Status = gBS->HandleProtocol(Handles[i], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&pFile); + if (EFI_ERROR(Status)) + { + continue; + } + + Status = gBS->OpenProtocol(Handles[i], &gEfiDevicePathProtocolGuid, + (VOID **)&pDevPath, + ImageHandle, + Handles[i], + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (EFI_ERROR(Status)) + { + debug("Failed to open device path protocol %r", Status); + continue; + } + + debug("Handle:%p FS DP: <%s>", Handles[i], ConvertDevicePathToText(pDevPath, FALSE, FALSE)); + Parent = ventoy_get_parent_handle(pDevPath); + + if (Parent == gBlockData.RawBlockIoHandle) + { + debug("Find ventoy disk fs"); + gBlockData.DiskFsHandle = Handles[i]; + gBlockData.pDiskFs = pFile; + gBlockData.pDiskFsDevPath = pDevPath; + break; + } + } + + FreePool(Handles); + + return EFI_SUCCESS; +} + +STATIC EFI_STATUS EFIAPI ventoy_load_isoefi_driver(IN EFI_HANDLE ImageHandle) +{ + EFI_HANDLE Image = NULL; + EFI_STATUS Status = EFI_SUCCESS; + CHAR16 LogVar[4] = L"5"; + + if (gIsoUdf) + { + Status = ventoy_load_image(ImageHandle, gBlockData.pDiskFsDevPath, + gUdfEfiDriverPath, + sizeof(gUdfEfiDriverPath), + &Image); + debug("load iso UDF efi driver status:%r", Status); + } + else + { + Status = ventoy_load_image(ImageHandle, gBlockData.pDiskFsDevPath, + gIso9660EfiDriverPath, + sizeof(gIso9660EfiDriverPath), + &Image); + debug("load iso 9660 efi driver status:%r", Status); + } + + if (gDebugPrint) + { + gRT->SetVariable(L"FS_LOGGING", &gShellVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof(LogVar), LogVar); + } + + gRT->SetVariable(L"FS_NAME_NOCASE", &gShellVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof(LogVar), LogVar); + + gBlockData.IsoDriverImage = Image; + Status = gBS->StartImage(Image, NULL, NULL); + debug("Start iso efi driver status:%r", Status); + + return EFI_SUCCESS; +} + +STATIC EFI_STATUS ventoy_proc_img_replace_name(ventoy_grub_param_file_replace *replace) +{ + UINT32 i; + char tmp[256]; + + if (replace->magic != GRUB_IMG_REPLACE_MAGIC) + { + return EFI_SUCCESS; + } + + if (replace->old_file_name[0][0] == 0) + { + return EFI_SUCCESS; + } + + AsciiStrCpyS(tmp, sizeof(tmp), replace->old_file_name[0]); + + for (i = 0; i < 256 && tmp[i]; i++) + { + if (tmp[i] == '/') + { + tmp[i] = '\\'; + } + } + + AsciiStrCpyS(replace->old_file_name[0], 256, tmp); + return EFI_SUCCESS; +} + +EFI_STATUS EFIAPI ventoy_get_variable_wrapper +( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + OUT UINT32 *Attributes, OPTIONAL + IN OUT UINTN *DataSize, + OUT VOID *Data OPTIONAL +) +{ + EFI_STATUS Status = EFI_SUCCESS; + + Status = g_org_get_variable(VariableName, VendorGuid, Attributes, DataSize, Data); + if (StrCmp(VariableName, L"SecureBoot") == 0) + { + if ((*DataSize == 1) && Data) + { + *(UINT8 *)Data = 0; + } + } + + return Status; +} + +EFI_STATUS EFIAPI ventoy_exit_boot_service_wrapper +( + IN EFI_HANDLE ImageHandle, + IN UINTN MapKey +) +{ + if (g_org_get_variable) + { + gRT->GetVariable = g_org_get_variable; + g_org_get_variable = NULL; + } + + return g_org_exit_boot_service(ImageHandle, MapKey); +} + +STATIC EFI_STATUS EFIAPI ventoy_disable_secure_boot(IN EFI_HANDLE ImageHandle) +{ + UINT8 Value = 0; + UINTN DataSize = 1; + EFI_STATUS Status = EFI_SUCCESS; + + Status = gRT->GetVariable(L"SecureBoot", &gEfiGlobalVariableGuid, NULL, &DataSize, &Value); + if (!EFI_ERROR(Status)) + { + if (DataSize == 1 && Value == 0) + { + debug("Current secure boot is off, no need to disable"); + return EFI_SUCCESS; + } + } + + debug("ventoy_disable_secure_boot"); + + /* step1: wrapper security protocol. */ + /* Do we still need it since we have been loaded ? */ + + + /* step2: fake SecureBoot variable */ + g_org_exit_boot_service = gBS->ExitBootServices; + gBS->ExitBootServices = ventoy_exit_boot_service_wrapper; + + g_org_get_variable = gRT->GetVariable; + gRT->GetVariable = ventoy_get_variable_wrapper; + + return EFI_SUCCESS; +} + + +STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle) +{ + UINT32 i = 0; + UINT32 old_cnt = 0; + UINTN size = 0; + UINT8 chksum = 0; + const char *pEnv = NULL; + CHAR16 *pPos = NULL; + CHAR16 *pCmdLine = NULL; + EFI_STATUS Status = EFI_SUCCESS; + ventoy_grub_param *pGrubParam = NULL; + EFI_LOADED_IMAGE_PROTOCOL *pImageInfo = NULL; + ventoy_chain_head *chain = NULL; + ventoy_grub_param_file_replace *replace = NULL; + + Status = gBS->HandleProtocol(ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&pImageInfo); + if (EFI_ERROR(Status)) + { + VtoyDebug("Failed to handle load image protocol %r", Status); + return Status; + } + + pCmdLine = (CHAR16 *)AllocatePool(pImageInfo->LoadOptionsSize + 4); + SetMem(pCmdLine, pImageInfo->LoadOptionsSize + 4, 0); + CopyMem(pCmdLine, pImageInfo->LoadOptions, pImageInfo->LoadOptionsSize); + + if (StrStr(pCmdLine, L"debug")) + { + gDebugPrint = TRUE; + } + + if (StrStr(pCmdLine, L"fallback")) + { + gBootFallBack = TRUE; + } + + if (StrStr(pCmdLine, L"dotefi")) + { + gDotEfiBoot = TRUE; + } + + if (StrStr(pCmdLine, L"isoefi=on")) + { + gLoadIsoEfi = TRUE; + } + + if (StrStr(pCmdLine, L"iso_udf")) + { + gIsoUdf = TRUE; + } + + pPos = StrStr(pCmdLine, L"FirstTry=@"); + if (pPos) + { + pPos += StrLen(L"FirstTry="); + for (i = 0; i < ARRAY_SIZE(gFirstTryBootFile); i++, pPos++) + { + if (*pPos != L' ' && *pPos != L'\t' && *pPos) + { + gFirstTryBootFile[i] = (*pPos == '@') ? '\\' : *pPos; + } + else + { + break; + } + } + + gEfiBootFileName[0] = gFirstTryBootFile; + gBootFileStartIndex = 0; + } + + debug("cmdline:<%s>", pCmdLine); + + if (gFirstTryBootFile[0]) + { + debug("First Try:<%s>", gFirstTryBootFile); + } + + pPos = StrStr(pCmdLine, L"env_param="); + if (!pPos) + { + return EFI_INVALID_PARAMETER; + } + + pGrubParam = (ventoy_grub_param *)StrHexToUintn(pPos + StrLen(L"env_param=")); + grub_env_set = pGrubParam->grub_env_set; + grub_env_get = pGrubParam->grub_env_get; + pEnv = grub_env_get("VTOY_CHKDEV_RESULT_STRING"); + if (!pEnv) + { + return EFI_INVALID_PARAMETER; + } + + if (pEnv[0] != '0' || pEnv[1] != 0) + { + ventoy_warn_invalid_device(); + return EFI_INVALID_PARAMETER; + } + + g_file_replace_list = &pGrubParam->file_replace; + old_cnt = g_file_replace_list->old_file_cnt; + debug("file replace: magic:0x%x virtid:%u name count:%u <%a> <%a> <%a> <%a>", + g_file_replace_list->magic, + g_file_replace_list->new_file_virtual_id, + old_cnt, + old_cnt > 0 ? g_file_replace_list->old_file_name[0] : "", + old_cnt > 1 ? g_file_replace_list->old_file_name[1] : "", + old_cnt > 2 ? g_file_replace_list->old_file_name[2] : "", + old_cnt > 3 ? g_file_replace_list->old_file_name[3] : "" + ); + + + for (i = 0; i < VTOY_MAX_CONF_REPLACE; i++) + { + replace = pGrubParam->img_replace + i; + if (replace->magic == GRUB_IMG_REPLACE_MAGIC) + { + ventoy_proc_img_replace_name(replace); + old_cnt = replace->old_file_cnt; + debug("img replace[%d]: magic:0x%x virtid:%u name count:%u <%a> <%a> <%a> <%a>", + i, replace->magic, + replace->new_file_virtual_id, + old_cnt, + old_cnt > 0 ? replace->old_file_name[0] : "", + old_cnt > 1 ? replace->old_file_name[1] : "", + old_cnt > 2 ? replace->old_file_name[2] : "", + old_cnt > 3 ? replace->old_file_name[3] : "" + ); + g_img_replace_list = pGrubParam->img_replace; + } + } + + + pPos = StrStr(pCmdLine, L"mem:"); + chain = (ventoy_chain_head *)StrHexToUintn(pPos + 4); + + pPos = StrStr(pPos, L"size:"); + size = StrDecimalToUintn(pPos + 5); + + debug("memory addr:%p size:%lu", chain, size); + + if (StrStr(pCmdLine, L"sector512")) + { + gSector512Mode = TRUE; + } + + if (StrStr(pCmdLine, L"memdisk")) + { + g_iso_data_buf = (UINT8 *)chain + sizeof(ventoy_chain_head); + g_iso_buf_size = size - sizeof(ventoy_chain_head); + debug("memdisk mode iso_buf_size:%u", g_iso_buf_size); + + g_chain = chain; + g_os_param_reserved = (UINT8 *)(g_chain->os_param.vtoy_reserved); + gMemdiskMode = TRUE; + } + else + { + debug("This is normal mode"); + g_chain = AllocatePool(size); + CopyMem(g_chain, chain, size); + + g_chunk = (ventoy_img_chunk *)((char *)g_chain + g_chain->img_chunk_offset); + g_img_chunk_num = g_chain->img_chunk_num; + g_override_chunk = (ventoy_override_chunk *)((char *)g_chain + g_chain->override_chunk_offset); + g_override_chunk_num = g_chain->override_chunk_num; + g_virt_chunk = (ventoy_virt_chunk *)((char *)g_chain + g_chain->virt_chunk_offset); + g_virt_chunk_num = g_chain->virt_chunk_num; + + g_os_param_reserved = (UINT8 *)(g_chain->os_param.vtoy_reserved); + + /* Workaround for Windows & ISO9660 */ + if (g_os_param_reserved[2] == ventoy_chain_windows && g_os_param_reserved[3] == 0) + { + g_fixup_iso9660_secover_enable = TRUE; + } + + if (g_os_param_reserved[2] == ventoy_chain_windows && g_os_param_reserved[4] != 1) + { + g_hook_keyboard = TRUE; + } + + if (g_os_param_reserved[5] == 1 && g_os_param_reserved[2] == ventoy_chain_linux) + { + ventoy_disable_secure_boot(ImageHandle); + } + + debug("internal param: secover:%u keyboard:%u", g_fixup_iso9660_secover_enable, g_hook_keyboard); + + for (i = 0; i < sizeof(ventoy_os_param); i++) + { + chksum += *((UINT8 *)(&(g_chain->os_param)) + i); + } + + if (gDebugPrint) + { + debug("os param checksum: 0x%x %a", g_chain->os_param.chksum, chksum ? "FAILED" : "SUCCESS"); + } + + ventoy_update_image_location(&(g_chain->os_param)); + + if (gDebugPrint) + { + ventoy_dump_chain(g_chain); + } + } + + g_fix_windows_1st_cdrom_issue = FALSE; + if (ventoy_chain_windows == g_os_param_reserved[2] || + ventoy_chain_wim == g_os_param_reserved[2]) + { + if (ventoy_is_cdrom_dp_exist()) + { + debug("fixup the 1st cdrom influences when boot windows ..."); + g_fix_windows_1st_cdrom_issue = TRUE; + } + } + + ventoy_debug_pause(); + + FreePool(pCmdLine); + return EFI_SUCCESS; +} + +EFI_STATUS EFIAPI ventoy_clean_env(VOID) +{ + FreePool(g_sector_flag); + g_sector_flag_num = 0; + + if (gLoadIsoEfi && gBlockData.IsoDriverImage) + { + gBS->UnloadImage(gBlockData.IsoDriverImage); + } + + gBS->DisconnectController(gBlockData.Handle, NULL, NULL); + + gBS->UninstallMultipleProtocolInterfaces(gBlockData.Handle, + &gEfiBlockIoProtocolGuid, &gBlockData.BlockIo, + &gEfiDevicePathProtocolGuid, gBlockData.Path, + NULL); + + ventoy_delete_variable(); + + if (g_vtoy_img_location_buf) + { + FreePool(g_vtoy_img_location_buf); + } + + if (!gMemdiskMode) + { + FreePool(g_chain); + } + + return EFI_SUCCESS; +} + +STATIC EFI_STATUS ventoy_hook_start(VOID) +{ + /* don't add debug print in this function */ + + if (g_fix_windows_1st_cdrom_issue) + { + ventoy_hook_1st_cdrom_start(); + } + + /* let this the last */ + if (g_hook_keyboard) + { + ventoy_hook_keyboard_start(); + } + + return EFI_SUCCESS; +} + +STATIC EFI_STATUS ventoy_hook_stop(VOID) +{ + /* don't add debug print in this function */ + + if (g_fix_windows_1st_cdrom_issue) + { + ventoy_hook_1st_cdrom_stop(); + } + + /* let this the last */ + if (g_hook_keyboard) + { + ventoy_hook_keyboard_stop(); + } + + return EFI_SUCCESS; +} + +EFI_STATUS EFIAPI ventoy_boot(IN EFI_HANDLE ImageHandle) +{ + UINTN t = 0; + UINTN i = 0; + UINTN j = 0; + UINTN Find = 0; + UINTN Count = 0; + EFI_HANDLE Image = NULL; + EFI_HANDLE *Handles = NULL; + EFI_STATUS Status = EFI_SUCCESS; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pFile = NULL; + EFI_DEVICE_PATH_PROTOCOL *pDevPath = NULL; + + for (t = 0; t < 3; t++) + { + Count = 0; + Handles = NULL; + + Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleFileSystemProtocolGuid, + NULL, &Count, &Handles); + if (EFI_ERROR(Status)) + { + return Status; + } + + debug("ventoy_boot fs count:%u", Count); + + for (i = 0; i < Count; i++) + { + Status = gBS->HandleProtocol(Handles[i], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&pFile); + if (EFI_ERROR(Status)) + { + continue; + } + + debug("FS:%u Protocol:%p OpenVolume:%p", i, pFile, pFile->OpenVolume); + + Status = gBS->OpenProtocol(Handles[i], &gEfiDevicePathProtocolGuid, + (VOID **)&pDevPath, + ImageHandle, + Handles[i], + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (EFI_ERROR(Status)) + { + debug("Failed to open device path protocol %r", Status); + continue; + } + + debug("Handle:%p FS DP: <%s>", Handles[i], ConvertDevicePathToText(pDevPath, FALSE, FALSE)); + if (CompareMem(gBlockData.Path, pDevPath, gBlockData.DevicePathCompareLen)) + { + debug("Not ventoy disk file system"); + continue; + } + + for (j = gBootFileStartIndex; j < ARRAY_SIZE(gEfiBootFileName); j++) + { + Status = ventoy_load_image(ImageHandle, pDevPath, gEfiBootFileName[j], + StrSize(gEfiBootFileName[j]), &Image); + if (EFI_SUCCESS == Status) + { + break; + } + debug("Failed to load image %r <%s>", Status, gEfiBootFileName[j]); + } + + if (j >= ARRAY_SIZE(gEfiBootFileName)) + { + continue; + } + + Find++; + debug("Find boot file, now try to boot ....."); + ventoy_debug_pause(); + + if (gDebugPrint) + { + gST->ConIn->Reset(gST->ConIn, FALSE); + } + + if ((g_file_replace_list && g_file_replace_list->magic == GRUB_FILE_REPLACE_MAGIC) || g_img_replace_list) + { + ventoy_wrapper_push_openvolume(pFile->OpenVolume); + pFile->OpenVolume = ventoy_wrapper_open_volume; + } + + ventoy_hook_start(); + /* can't add debug print here */ + //ventoy_wrapper_system(); + Status = gBS->StartImage(Image, NULL, NULL); + ventoy_hook_stop(); + + if (EFI_ERROR(Status)) + { + debug("Failed to start image %r", Status); + sleep(3); + gBS->UnloadImage(Image); + break; + } + } + + FreePool(Handles); + + if (Find == 0) + { + if (gDotEfiBoot) + { + break; + } + + debug("Fs not found, now wait and retry..."); + sleep(1); + } + } + + if (Find == 0) + { + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; +} + +EFI_STATUS EFIAPI VentoyEfiMain +( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable +) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *Protocol; + + g_sector_flag_num = 512; /* initial value */ + + g_sector_flag = AllocatePool(g_sector_flag_num * sizeof(ventoy_sector_flag)); + if (NULL == g_sector_flag) + { + return EFI_OUT_OF_RESOURCES; + } + + Status = gBS->HandleProtocol(gST->ConsoleInHandle, &gEfiSimpleTextInputExProtocolGuid, (VOID **)&Protocol); + if (EFI_SUCCESS == Status) + { + g_con_simple_input_ex = Protocol; + } + + gST->ConOut->ClearScreen(gST->ConOut); + ventoy_clear_input(); + + Status = ventoy_parse_cmdline(ImageHandle); + if (EFI_ERROR(Status)) + { + return Status; + } + + if (g_os_param_reserved[11]) + { + ventoy_lock_res(g_os_param_reserved[11]); + } + + ventoy_disable_ex_filesystem(); + + if (gMemdiskMode) + { + g_ramdisk_param.PhyAddr = (UINT64)(UINTN)g_iso_data_buf; + g_ramdisk_param.DiskSize = (UINT64)g_iso_buf_size; + + ventoy_save_ramdisk_param(); + + if (gLoadIsoEfi) + { + ventoy_find_iso_disk(ImageHandle); + ventoy_find_iso_disk_fs(ImageHandle); + ventoy_load_isoefi_driver(ImageHandle); + } + + ventoy_install_blockio(ImageHandle, g_iso_buf_size); + ventoy_debug_pause(); + + Status = ventoy_boot(ImageHandle); + + ventoy_delete_ramdisk_param(); + + if (gLoadIsoEfi && gBlockData.IsoDriverImage) + { + gBS->UnloadImage(gBlockData.IsoDriverImage); + } + + gBS->DisconnectController(gBlockData.Handle, NULL, NULL); + gBS->UninstallMultipleProtocolInterfaces(gBlockData.Handle, + &gEfiBlockIoProtocolGuid, &gBlockData.BlockIo, + &gEfiDevicePathProtocolGuid, gBlockData.Path, + NULL); + } + else + { + ventoy_save_variable(); + Status = ventoy_find_iso_disk(ImageHandle); + if (!EFI_ERROR(Status)) + { + if (gLoadIsoEfi) + { + ventoy_find_iso_disk_fs(ImageHandle); + ventoy_load_isoefi_driver(ImageHandle); + } + + ventoy_debug_pause(); + + ventoy_install_blockio(ImageHandle, g_chain->virt_img_size_in_bytes); + + ventoy_debug_pause(); + + Status = ventoy_boot(ImageHandle); + } + + ventoy_clean_env(); + } + + if (FALSE == gDotEfiBoot && FALSE == gBootFallBack) + { + if (EFI_NOT_FOUND == Status) + { + gST->ConOut->OutputString(gST->ConOut, L"No bootfile found for UEFI!\r\n"); + gST->ConOut->OutputString(gST->ConOut, L"Maybe the image does not support " VENTOY_UEFI_DESC L"!\r\n"); + sleep(30); + } + } + + ventoy_clear_input(); + gST->ConOut->ClearScreen(gST->ConOut); + + if (gDotEfiBoot && (EFI_NOT_FOUND == Status)) + { + grub_env_set("vtoy_dotefi_retry", "YES"); + } + + ventoy_enable_ex_filesystem(); + + if (g_os_param_reserved[11]) + { + ventoy_unlock_res(); + } + + return EFI_SUCCESS; +} + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.h b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.h new file mode 100644 index 0000000..35fd5e4 --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.h @@ -0,0 +1,437 @@ +/****************************************************************************** + * Ventoy.h + * + * Copyright (c) 2020, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#ifndef __VENTOY_H__ +#define __VENTOY_H__ + +#define COMPILE_ASSERT(expr) extern char __compile_assert[(expr) ? 1 : -1] + +#define VTOY_SHIM_POLICY_GUID {0x90a29d14, 0x3968, 0x48fe, { 0x85, 0x81, 0x6b, 0x7f, 0x7d, 0xc4, 0x70, 0x55 }}; + +#define VENTOY_GUID { 0x77772020, 0x2e77, 0x6576, { 0x6e, 0x74, 0x6f, 0x79, 0x2e, 0x6e, 0x65, 0x74 }} + +typedef enum ventoy_chain_type +{ + ventoy_chain_linux = 0, /* 0: linux */ + ventoy_chain_windows, /* 1: windows */ + ventoy_chain_wim, /* 2: wim */ + + ventoy_chain_max +}ventoy_chain_type; + +#pragma pack(1) + +typedef struct ventoy_guid +{ + UINT32 data1; + UINT16 data2; + UINT16 data3; + UINT8 data4[8]; +}ventoy_guid; + +typedef struct ventoy_image_disk_region +{ + UINT32 image_sector_count; /* image sectors contained in this region */ + UINT32 image_start_sector; /* image sector start */ + UINT64 disk_start_sector; /* disk sector start */ +}ventoy_image_disk_region; + +typedef struct ventoy_image_location +{ + ventoy_guid guid; + + /* image sector size, currently this value is always 2048 */ + UINT32 image_sector_size; + + /* disk sector size, normally the value is 512 */ + UINT32 disk_sector_size; + + UINT32 region_count; + + /* + * disk region data + * If the image file has more than one fragments in disk, + * there will be more than one region data here. + * + */ + ventoy_image_disk_region regions[1]; + + /* ventoy_image_disk_region regions[2~region_count-1] */ +}ventoy_image_location; + +typedef struct ventoy_os_param +{ + ventoy_guid guid; // VENTOY_GUID + UINT8 chksum; // checksum + + UINT8 vtoy_disk_guid[16]; + UINT64 vtoy_disk_size; // disk size in bytes + UINT16 vtoy_disk_part_id; // begin with 1 + UINT16 vtoy_disk_part_type; // 0:exfat 1:ntfs other: reserved + char vtoy_img_path[384]; // It seems to be enough, utf-8 format + UINT64 vtoy_img_size; // image file size in bytes + + /* + * Ventoy will write a copy of ventoy_image_location data into runtime memory + * this is the physically address and length of that memory. + * Address 0 means no such data exist. + * Address will be aligned by 4KB. + * + */ + UINT64 vtoy_img_location_addr; + UINT32 vtoy_img_location_len; + + UINT64 vtoy_reserved[4]; // Internal use by ventoy + + UINT8 vtoy_disk_signature[4]; + + UINT8 reserved[27]; +}ventoy_os_param; + +#pragma pack() + +// compile assert to check that size of ventoy_os_param must be 512 +COMPILE_ASSERT(sizeof(ventoy_os_param) == 512); + + + +#pragma pack(4) + +typedef struct ventoy_chain_head +{ + ventoy_os_param os_param; + + UINT32 disk_drive; + UINT32 drive_map; + UINT32 disk_sector_size; + + UINT64 real_img_size_in_bytes; + UINT64 virt_img_size_in_bytes; + UINT32 boot_catalog; + UINT8 boot_catalog_sector[2048]; + + UINT32 img_chunk_offset; + UINT32 img_chunk_num; + + UINT32 override_chunk_offset; + UINT32 override_chunk_num; + + UINT32 virt_chunk_offset; + UINT32 virt_chunk_num; +}ventoy_chain_head; + + +typedef struct ventoy_img_chunk +{ + UINT32 img_start_sector; //2KB + UINT32 img_end_sector; + + UINT64 disk_start_sector; // in disk_sector_size + UINT64 disk_end_sector; +}ventoy_img_chunk; + + +typedef struct ventoy_override_chunk +{ + UINT64 img_offset; + UINT32 override_size; + UINT8 override_data[512]; +}ventoy_override_chunk; + +typedef struct ventoy_virt_chunk +{ + UINT32 mem_sector_start; + UINT32 mem_sector_end; + UINT32 mem_sector_offset; + UINT32 remap_sector_start; + UINT32 remap_sector_end; + UINT32 org_sector_start; +}ventoy_virt_chunk; + + +#pragma pack() + + +#define VTOY_BLOCK_DEVICE_PATH_GUID \ + { 0x37b87ac6, 0xc180, 0x4583, { 0xa7, 0x05, 0x41, 0x4d, 0xa8, 0xf7, 0x7e, 0xd2 }} + + + +#if defined (MDE_CPU_IA32) + #define VENTOY_UEFI_DESC L"IA32 UEFI" + #define ISO9660_EFI_DRIVER_PATH L"\\ventoy\\iso9660_ia32.efi" + #define UDF_EFI_DRIVER_PATH L"\\ventoy\\udf_ia32.efi" +#elif defined (MDE_CPU_X64) + #define VENTOY_UEFI_DESC L"X64 UEFI" + #define ISO9660_EFI_DRIVER_PATH L"\\ventoy\\iso9660_x64.efi" + #define UDF_EFI_DRIVER_PATH L"\\ventoy\\udf_x64.efi" +#elif defined (MDE_CPU_EBC) +#elif defined (MDE_CPU_ARM) + #define VENTOY_UEFI_DESC L"ARM UEFI" + #define ISO9660_EFI_DRIVER_PATH L"\\ventoy\\iso9660_arm.efi" + #define UDF_EFI_DRIVER_PATH L"\\ventoy\\udf_arm.efi" +#elif defined (MDE_CPU_AARCH64) + #define VENTOY_UEFI_DESC L"ARM64 UEFI" + #define ISO9660_EFI_DRIVER_PATH L"\\ventoy\\iso9660_aa64.efi" + #define UDF_EFI_DRIVER_PATH L"\\ventoy\\udf_aa64.efi" +#else + #error Unknown Processor Type +#endif + +#define VENTOY_DEVICE_WARN 1 +#define VTOY_WARNING L"!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!" + +typedef struct ventoy_sector_flag +{ + UINT8 flag; // 0:init 1:mem 2:remap + UINT64 remap_lba; +}ventoy_sector_flag; + + +typedef struct vtoy_block_data +{ + EFI_HANDLE Handle; + EFI_BLOCK_IO_MEDIA Media; /* Media descriptor */ + EFI_BLOCK_IO_PROTOCOL BlockIo; /* Block I/O protocol */ + + UINTN DevicePathCompareLen; + EFI_DEVICE_PATH_PROTOCOL *Path; /* Device path protocol */ + + EFI_HANDLE RawBlockIoHandle; + EFI_BLOCK_IO_PROTOCOL *pRawBlockIo; + EFI_DEVICE_PATH_PROTOCOL *pDiskDevPath; + + /* ventoy disk part2 ESP */ + EFI_HANDLE DiskFsHandle; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pDiskFs; + EFI_DEVICE_PATH_PROTOCOL *pDiskFsDevPath; + + EFI_HANDLE IsoDriverImage; +}vtoy_block_data; + + +#define debug(expr, ...) if (gDebugPrint) VtoyDebug("[VTOY] "expr"\r\n", ##__VA_ARGS__) +#define trace(expr, ...) VtoyDebug("[VTOY] "expr"\r\n", ##__VA_ARGS__) +#define sleep(sec) gBS->Stall(1000000 * (sec)) + +#define ventoy_debug_pause() \ +if (gDebugPrint) \ +{ \ + UINTN __Index = 0; \ + gST->ConOut->OutputString(gST->ConOut, L"[VTOY] ###### Press Enter to continue... ######\r\n");\ + gST->ConIn->Reset(gST->ConIn, FALSE); \ + gBS->WaitForEvent(1, &gST->ConIn->WaitForKey, &__Index);\ +} + +typedef int (*grub_env_set_pf)(const char *name, const char *val); +typedef const char * (*grub_env_get_pf)(const char *name); +typedef int (*grub_env_printf_pf)(const char *fmt, ...); + +#pragma pack(1) + +#define VTOY_MAX_CONF_REPLACE 2 +#define GRUB_FILE_REPLACE_MAGIC 0x1258BEEF +#define GRUB_IMG_REPLACE_MAGIC 0x1259BEEF + +typedef struct ventoy_efi_file_replace +{ + UINT64 BlockIoSectorStart; + + UINT64 CurPos; + UINT64 FileSizeBytes; + + EFI_FILE_PROTOCOL WrapperHandle; +}ventoy_efi_file_replace; + +typedef struct ventoy_grub_param_file_replace +{ + UINT32 magic; + char old_file_name[4][256]; + UINT32 old_file_cnt; + UINT32 new_file_virtual_id; +}ventoy_grub_param_file_replace; + +typedef struct ventoy_grub_param +{ + grub_env_get_pf grub_env_get; + grub_env_set_pf grub_env_set; + ventoy_grub_param_file_replace file_replace; + ventoy_grub_param_file_replace img_replace[VTOY_MAX_CONF_REPLACE]; + grub_env_printf_pf grub_env_printf; +}ventoy_grub_param; + +typedef struct ventoy_ram_disk +{ + UINT64 PhyAddr; + UINT64 DiskSize; +}ventoy_ram_disk; + +typedef struct ventoy_iso9660_override +{ + UINT32 first_sector; + UINT32 first_sector_be; + UINT32 size; + UINT32 size_be; +}ventoy_iso9660_override; + +typedef struct PART_TABLE +{ + UINT8 Active; // 0x00 0x80 + + UINT8 StartHead; + UINT16 StartSector : 6; + UINT16 StartCylinder : 10; + + UINT8 FsFlag; + + UINT8 EndHead; + UINT16 EndSector : 6; + UINT16 EndCylinder : 10; + + UINT32 StartSectorId; + UINT32 SectorCount; +}PART_TABLE; + +typedef struct MBR_HEAD +{ + UINT8 BootCode[446]; + PART_TABLE PartTbl[4]; + UINT8 Byte55; + UINT8 ByteAA; +}MBR_HEAD; + +#pragma pack() + + +typedef struct well_known_guid +{ + EFI_GUID *guid; + const char *name; +}well_known_guid; + +typedef struct ventoy_system_wrapper +{ + EFI_LOCATE_PROTOCOL NewLocateProtocol; + EFI_LOCATE_PROTOCOL OriLocateProtocol; + + EFI_HANDLE_PROTOCOL NewHandleProtocol; + EFI_HANDLE_PROTOCOL OriHandleProtocol; + + EFI_OPEN_PROTOCOL NewOpenProtocol; + EFI_OPEN_PROTOCOL OriOpenProtocol; + + EFI_LOCATE_HANDLE_BUFFER NewLocateHandleBuffer; + EFI_LOCATE_HANDLE_BUFFER OriLocateHandleBuffer; + + EFI_PROTOCOLS_PER_HANDLE NewProtocolsPerHandle; + EFI_PROTOCOLS_PER_HANDLE OriProtocolsPerHandle; + + EFI_LOCATE_HANDLE NewLocateHandle; + EFI_LOCATE_HANDLE OriLocateHandle; + + EFI_LOCATE_DEVICE_PATH NewLocateDevicePath; + EFI_LOCATE_DEVICE_PATH OriLocateDevicePath; +} ventoy_system_wrapper; + + +#define MAX_DRIVER_BIND_WRAPPER 64 +typedef struct DriverBindWrapper +{ + EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; + EFI_DRIVER_BINDING_SUPPORTED pfOldSupport; +}DRIVER_BIND_WRAPPER; + +#define ventoy_wrapper(bs, wrapper, func, newfunc) \ +{\ + wrapper.Ori##func = bs->func;\ + wrapper.New##func = newfunc;\ + bs->func = wrapper.New##func;\ +} + + +#define VENTOY_GET_COMPONENT_NAME(Protocol, DriverName) \ +{\ + DriverName = NULL;\ + Status = Protocol->GetDriverName(Protocol, "en", &DriverName);\ + if (EFI_ERROR(Status) || NULL == DriverName) \ + {\ + DriverName = NULL;\ + Status = Protocol->GetDriverName(Protocol, "eng", &DriverName);\ + if (EFI_ERROR(Status) || NULL == DriverName) \ + {\ + continue;\ + }\ + }\ +} + +extern BOOLEAN gDebugPrint; +VOID EFIAPI VtoyDebug(IN CONST CHAR8 *Format, ...); +EFI_STATUS EFIAPI ventoy_wrapper_system(VOID); +EFI_STATUS EFIAPI ventoy_block_io_read +( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + OUT VOID *Buffer +); + + +extern ventoy_chain_head *g_chain; +extern ventoy_img_chunk *g_chunk; +extern UINT32 g_img_chunk_num; +extern ventoy_override_chunk *g_override_chunk; +extern UINT32 g_override_chunk_num; +extern ventoy_virt_chunk *g_virt_chunk; +extern UINT32 g_virt_chunk_num; +extern vtoy_block_data gBlockData; +extern ventoy_efi_file_replace g_efi_file_replace; +extern ventoy_efi_file_replace g_img_file_replace[VTOY_MAX_CONF_REPLACE]; +extern ventoy_sector_flag *g_sector_flag; +extern UINT32 g_sector_flag_num; +extern BOOLEAN gMemdiskMode; +extern BOOLEAN gSector512Mode; +extern UINTN g_iso_buf_size; +extern UINT8 *g_iso_data_buf; +extern ventoy_grub_param_file_replace *g_file_replace_list; +extern ventoy_grub_param_file_replace *g_img_replace_list; +extern BOOLEAN g_fixup_iso9660_secover_enable; +extern EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *g_con_simple_input_ex; +extern BOOLEAN g_fix_windows_1st_cdrom_issue; + +EFI_STATUS EFIAPI ventoy_wrapper_open_volume +( + IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **Root +); +EFI_STATUS EFIAPI ventoy_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 ImgSize); +EFI_STATUS EFIAPI ventoy_wrapper_push_openvolume(IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME OpenVolume); +EFI_STATUS ventoy_hook_keyboard_start(VOID); +EFI_STATUS ventoy_hook_keyboard_stop(VOID); +BOOLEAN ventoy_is_cdrom_dp_exist(VOID); +EFI_STATUS ventoy_hook_1st_cdrom_start(VOID); +EFI_STATUS ventoy_hook_1st_cdrom_stop(VOID); +EFI_STATUS ventoy_disable_ex_filesystem(VOID); +EFI_STATUS ventoy_enable_ex_filesystem(VOID); +EFI_STATUS ventoy_lock_res(UINT8 LockType); +EFI_STATUS ventoy_unlock_res(VOID); + +#endif + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.inf b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.inf new file mode 100644 index 0000000..36ec0ab --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.inf @@ -0,0 +1,86 @@ +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = Ventoy + FILE_GUID = 1c3a0915-09dc-49c2-873d-0aaaa7733299 + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + ENTRY_POINT = VentoyEfiMain + + +[BuildOptions] + # Force standard GNU ld to pack and align ELF segments to 4KB page boundaries + GCC:*_*_*_DLINK_FLAGS = -Wl,-z,common-page-size=0x1000 -Wl,-z,max-page-size=0x1000 + +[Sources] + Ventoy.h + Ventoy.c + VentoyDebug.c + VentoyProtocol.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ShellPkg/ShellPkg.dec + +[LibraryClasses] + UefiApplicationEntryPoint + UefiLib + DebugLib + +[Guids] + gEfiGlobalVariableGuid + gShellVariableGuid + gEfiVirtualCdGuid + gEfiFileInfoGuid + +[Protocols] + gEfiLoadedImageProtocolGuid + gEfiBlockIoProtocolGuid + gEfiDevicePathProtocolGuid + gEfiSimpleFileSystemProtocolGuid + gEfiRamDiskProtocolGuid + gEfiAbsolutePointerProtocolGuid + gEfiAcpiTableProtocolGuid + gEfiBlockIo2ProtocolGuid + gEfiBusSpecificDriverOverrideProtocolGuid + gEfiComponentNameProtocolGuid + gEfiComponentName2ProtocolGuid + gEfiDriverBindingProtocolGuid + gEfiDiskIoProtocolGuid + gEfiDiskIo2ProtocolGuid + gEfiGraphicsOutputProtocolGuid + gEfiHiiConfigAccessProtocolGuid + gEfiHiiFontProtocolGuid + gEfiLoadFileProtocolGuid + gEfiLoadFile2ProtocolGuid + gEfiLoadedImageProtocolGuid + gEfiLoadedImageDevicePathProtocolGuid + gEfiPciIoProtocolGuid + gEfiSerialIoProtocolGuid + gEfiSimpleTextInProtocolGuid + gEfiSimpleTextInputExProtocolGuid + gEfiSimpleTextOutProtocolGuid + + + + + + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyDebug.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyDebug.c new file mode 100644 index 0000000..9bdfaaa --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyDebug.c @@ -0,0 +1,229 @@ +/****************************************************************************** + * Ventoy.c + * + * Copyright (c) 2020, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PROCOTOL_SLEEP_MSECONDS 0 + +#define debug_sleep() if (PROCOTOL_SLEEP_MSECONDS) gBS->Stall(1000 * PROCOTOL_SLEEP_MSECONDS) + +STATIC ventoy_system_wrapper g_system_wrapper; + +static struct well_known_guid g_efi_well_known_guids[] = +{ + { &gEfiAbsolutePointerProtocolGuid, "AbsolutePointer" }, + { &gEfiAcpiTableProtocolGuid, "AcpiTable" }, + { &gEfiBlockIoProtocolGuid, "BlockIo" }, + { &gEfiBlockIo2ProtocolGuid, "BlockIo2" }, + { &gEfiBusSpecificDriverOverrideProtocolGuid, "BusSpecificDriverOverride" }, + { &gEfiComponentNameProtocolGuid, "ComponentName" }, + { &gEfiComponentName2ProtocolGuid, "ComponentName2" }, + { &gEfiDevicePathProtocolGuid, "DevicePath" }, + { &gEfiDriverBindingProtocolGuid, "DriverBinding" }, + { &gEfiDiskIoProtocolGuid, "DiskIo" }, + { &gEfiDiskIo2ProtocolGuid, "DiskIo2" }, + { &gEfiGraphicsOutputProtocolGuid, "GraphicsOutput" }, + { &gEfiHiiConfigAccessProtocolGuid, "HiiConfigAccess" }, + { &gEfiHiiFontProtocolGuid, "HiiFont" }, + { &gEfiLoadFileProtocolGuid, "LoadFile" }, + { &gEfiLoadFile2ProtocolGuid, "LoadFile2" }, + { &gEfiLoadedImageProtocolGuid, "LoadedImage" }, + { &gEfiLoadedImageDevicePathProtocolGuid, "LoadedImageDevicePath"}, + { &gEfiPciIoProtocolGuid, "PciIo" }, + { &gEfiSerialIoProtocolGuid, "SerialIo" }, + { &gEfiSimpleFileSystemProtocolGuid, "SimpleFileSystem" }, + { &gEfiSimpleTextInProtocolGuid, "SimpleTextInput" }, + { &gEfiSimpleTextInputExProtocolGuid, "SimpleTextInputEx" }, + { &gEfiSimpleTextOutProtocolGuid, "SimpleTextOutput" }, +}; + +STATIC CHAR8 gEfiGuidName[128]; + +static const char * ventoy_get_guid_name(EFI_GUID *guid) +{ + UINTN i; + + for (i = 0; i < ARRAY_SIZE(g_efi_well_known_guids); i++) + { + if (CompareGuid(g_efi_well_known_guids[i].guid, guid)) + { + return g_efi_well_known_guids[i].name; + } + } + + AsciiSPrint(gEfiGuidName, sizeof(gEfiGuidName), "%g", guid); + return gEfiGuidName; +} + +STATIC EFI_STATUS EFIAPI ventoy_handle_protocol +( + IN EFI_HANDLE Handle, + IN EFI_GUID *Protocol, + OUT VOID **Interface +) +{ + EFI_STATUS Status = EFI_SUCCESS; + + debug("ventoy_handle_protocol:%a", ventoy_get_guid_name(Protocol)); debug_sleep(); + Status = g_system_wrapper.OriHandleProtocol(Handle, Protocol, Interface); + + if (CompareGuid(Protocol, &gEfiSimpleFileSystemProtocolGuid)) + { + EFI_FILE_PROTOCOL *FileProtocol = NULL; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pFile = *((EFI_SIMPLE_FILE_SYSTEM_PROTOCOL **)(Interface)); + + pFile->OpenVolume(pFile, &FileProtocol); + + trace("Handle FS Protocol: %p OpenVolume:%p, FileProtocol:%p, Open:%p", + pFile, pFile->OpenVolume, FileProtocol, FileProtocol->Open); + + sleep(3); + } + + return Status; +} + +STATIC EFI_STATUS EFIAPI ventoy_open_protocol +( + IN EFI_HANDLE Handle, + IN EFI_GUID *Protocol, + OUT VOID **Interface, OPTIONAL + IN EFI_HANDLE AgentHandle, + IN EFI_HANDLE ControllerHandle, + IN UINT32 Attributes +) +{ + debug("ventoy_open_protocol:<%p> %a", Handle, ventoy_get_guid_name(Protocol)); debug_sleep(); + return g_system_wrapper.OriOpenProtocol(Handle, Protocol, Interface, AgentHandle, ControllerHandle, Attributes); +} + +STATIC EFI_STATUS EFIAPI ventoy_locate_protocol +( + IN EFI_GUID *Protocol, + IN VOID *Registration, OPTIONAL + OUT VOID **Interface +) +{ + debug("ventoy_locate_protocol:%a", ventoy_get_guid_name(Protocol)); debug_sleep(); + return g_system_wrapper.OriLocateProtocol(Protocol, Registration, Interface); +} + +STATIC EFI_STATUS EFIAPI ventoy_locate_handle_buffer +( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol, OPTIONAL + IN VOID *SearchKey, OPTIONAL + IN OUT UINTN *NoHandles, + OUT EFI_HANDLE **Buffer +) +{ + debug("ventoy_locate_handle_buffer:%a", ventoy_get_guid_name(Protocol)); debug_sleep(); + return g_system_wrapper.OriLocateHandleBuffer(SearchType, Protocol, SearchKey, NoHandles, Buffer); +} + +STATIC EFI_STATUS EFIAPI ventoy_protocol_per_handle +( + IN EFI_HANDLE Handle, + OUT EFI_GUID ***ProtocolBuffer, + OUT UINTN *ProtocolBufferCount +) +{ + debug("ventoy_protocol_per_handle:%p", Handle); debug_sleep(); + return g_system_wrapper.OriProtocolsPerHandle(Handle, ProtocolBuffer, ProtocolBufferCount); +} + +EFI_STATUS EFIAPI ventoy_locate_handle +( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol, OPTIONAL + IN VOID *SearchKey, OPTIONAL + IN OUT UINTN *BufferSize, + OUT EFI_HANDLE *Buffer +) +{ + UINTN i; + EFI_HANDLE Handle; + EFI_STATUS Status = EFI_SUCCESS; + + debug("ventoy_locate_handle: %d %a %p", SearchType, ventoy_get_guid_name(Protocol), SearchKey); + Status = g_system_wrapper.OriLocateHandle(SearchType, Protocol, SearchKey, BufferSize, Buffer); + debug("ventoy_locate_handle: %r Handle Count:%u", Status, *BufferSize/sizeof(EFI_HANDLE)); + + if (EFI_SUCCESS == Status) + { + for (i = 0; i < *BufferSize / sizeof(EFI_HANDLE); i++) + { + if (Buffer[i] == gBlockData.Handle) + { + Handle = Buffer[0]; + Buffer[0] = Buffer[i]; + Buffer[i] = Handle; + debug("####### Handle at %u", i); + break; + } + } + } + + debug_sleep(); + + return Status; +} + +STATIC EFI_STATUS EFIAPI ventoy_locate_device_path +( + IN EFI_GUID *Protocol, + IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, + OUT EFI_HANDLE *Device +) +{ + debug("ventoy_locate_device_path:%a", ventoy_get_guid_name(Protocol)); debug_sleep(); + return g_system_wrapper.OriLocateDevicePath(Protocol, DevicePath, Device); +} + +EFI_STATUS EFIAPI ventoy_wrapper_system(VOID) +{ + ventoy_wrapper(gBS, g_system_wrapper, LocateProtocol, ventoy_locate_protocol); + ventoy_wrapper(gBS, g_system_wrapper, HandleProtocol, ventoy_handle_protocol); + ventoy_wrapper(gBS, g_system_wrapper, OpenProtocol, ventoy_open_protocol); + ventoy_wrapper(gBS, g_system_wrapper, LocateHandleBuffer, ventoy_locate_handle_buffer); + ventoy_wrapper(gBS, g_system_wrapper, ProtocolsPerHandle, ventoy_protocol_per_handle); + ventoy_wrapper(gBS, g_system_wrapper, LocateHandle, ventoy_locate_handle); + ventoy_wrapper(gBS, g_system_wrapper, LocateDevicePath, ventoy_locate_device_path); + + return EFI_SUCCESS; +} + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyProtocol.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyProtocol.c new file mode 100644 index 0000000..b4a228d --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyProtocol.c @@ -0,0 +1,1972 @@ +/****************************************************************************** + * Ventoy.c + * + * Copyright (c) 2020, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +UINT8 *g_iso_data_buf = NULL; +UINTN g_iso_buf_size = 0; +BOOLEAN gMemdiskMode = FALSE; +BOOLEAN gSector512Mode = FALSE; + +ventoy_sector_flag *g_sector_flag = NULL; +UINT32 g_sector_flag_num = 0; + +EFI_FILE_OPEN g_original_fopen = NULL; +EFI_FILE_CLOSE g_original_fclose = NULL; +EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME g_original_open_volume = NULL; + +/* EFI block device vendor device path GUID */ +EFI_GUID gVtoyBlockDevicePathGuid = VTOY_BLOCK_DEVICE_PATH_GUID; + +#define VENTOY_ISO9660_SECTOR_OVERFLOW 2097152 + +BOOLEAN g_fixup_iso9660_secover_enable = FALSE; +BOOLEAN g_fixup_iso9660_secover_start = FALSE; +UINT64 g_fixup_iso9660_secover_1st_secs = 0; +UINT64 g_fixup_iso9660_secover_cur_secs = 0; +UINT64 g_fixup_iso9660_secover_tot_secs = 0; + +STATIC UINTN g_keyboard_hook_count = 0; +STATIC BOOLEAN g_blockio_start_record_bcd = FALSE; +STATIC BOOLEAN g_blockio_bcd_read_done = FALSE; + +EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *g_con_simple_input_ex = NULL; +STATIC EFI_INPUT_READ_KEY_EX g_org_read_key_ex = NULL; +STATIC EFI_INPUT_READ_KEY g_org_read_key = NULL; + +STATIC EFI_LOCATE_HANDLE g_org_locate_handle = NULL; + +STATIC UINT8 g_sector_buf[2048]; +STATIC EFI_BLOCK_READ g_sector_2048_read = NULL; +STATIC EFI_BLOCK_WRITE g_sector_2048_write = NULL; + +STATIC UINTN g_DriverBindWrapperCnt = 0; +STATIC DRIVER_BIND_WRAPPER g_DriverBindWrapperList[MAX_DRIVER_BIND_WRAPPER]; + +BOOLEAN ventoy_is_cdrom_dp_exist(VOID) +{ + UINTN i = 0; + UINTN Count = 0; + EFI_HANDLE *Handles = NULL; + EFI_STATUS Status = EFI_SUCCESS; + EFI_DEVICE_PATH_PROTOCOL *DevicePath = NULL; + + Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiDevicePathProtocolGuid, + NULL, &Count, &Handles); + if (EFI_ERROR(Status)) + { + return FALSE; + } + + for (i = 0; i < Count; i++) + { + Status = gBS->HandleProtocol(Handles[i], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath); + if (EFI_ERROR(Status)) + { + continue; + } + + while (!IsDevicePathEnd(DevicePath)) + { + if (MEDIA_DEVICE_PATH == DevicePath->Type && MEDIA_CDROM_DP == DevicePath->SubType) + { + FreePool(Handles); + return TRUE; + } + + DevicePath = NextDevicePathNode(DevicePath); + } + } + + FreePool(Handles); + return FALSE; +} + +#if 0 +/* Block IO procotol */ +#endif + +EFI_STATUS EFIAPI ventoy_block_io_reset +( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN BOOLEAN ExtendedVerification +) +{ + (VOID)This; + (VOID)ExtendedVerification; + return EFI_SUCCESS; +} + +STATIC EFI_STATUS EFIAPI ventoy_read_iso_sector +( + IN UINT64 Sector, + IN UINTN Count, + OUT VOID *Buffer +) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_LBA MapLba = 0; + UINT32 i = 0; + UINTN secLeft = 0; + UINTN secRead = 0; + UINT64 ReadStart = 0; + UINT64 ReadEnd = 0; + UINT64 OverrideStart = 0; + UINT64 OverrideEnd= 0; + UINT8 *pCurBuf = (UINT8 *)Buffer; + ventoy_img_chunk *pchunk = g_chunk; + ventoy_override_chunk *pOverride = g_override_chunk; + EFI_BLOCK_IO_PROTOCOL *pRawBlockIo = gBlockData.pRawBlockIo; + + debug("read iso sector %lu count %u Buffer:%p Align:%u blk:%u", + Sector, Count, Buffer, pRawBlockIo->Media->IoAlign, pRawBlockIo->Media->BlockSize); + + ReadStart = Sector * 2048; + ReadEnd = (Sector + Count) * 2048; + + for (i = 0; Count > 0 && i < g_img_chunk_num; i++, pchunk++) + { + if (Sector >= pchunk->img_start_sector && Sector <= pchunk->img_end_sector) + { + if (g_chain->disk_sector_size == 512) + { + MapLba = (Sector - pchunk->img_start_sector) * 4 + pchunk->disk_start_sector; + } + else if (g_chain->disk_sector_size == 1024) + { + MapLba = (Sector - pchunk->img_start_sector) * 2 + pchunk->disk_start_sector; + } + else if (g_chain->disk_sector_size == 2048) + { + MapLba = (Sector - pchunk->img_start_sector) + pchunk->disk_start_sector; + } + else if (g_chain->disk_sector_size == 4096) + { + MapLba = ((Sector - pchunk->img_start_sector) >> 1) + pchunk->disk_start_sector; + } + + secLeft = pchunk->img_end_sector + 1 - Sector; + secRead = (Count < secLeft) ? Count : secLeft; + + Status = pRawBlockIo->ReadBlocks(pRawBlockIo, pRawBlockIo->Media->MediaId, + MapLba, secRead * 2048, pCurBuf); + if (EFI_ERROR(Status)) + { + debug("Raw disk read block failed %r LBA:%lu Count:%u %p", Status, MapLba, secRead, pCurBuf); + return Status; + } + + Count -= secRead; + Sector += secRead; + pCurBuf += secRead * 2048; + } + } + + if (ReadStart > g_chain->real_img_size_in_bytes) + { + return EFI_SUCCESS; + } + + /* override data */ + pCurBuf = (UINT8 *)Buffer; + for (i = 0; i < g_override_chunk_num; i++, pOverride++) + { + OverrideStart = pOverride->img_offset; + OverrideEnd = pOverride->img_offset + pOverride->override_size; + + if (OverrideStart >= ReadEnd || ReadStart >= OverrideEnd) + { + continue; + } + + if (ReadStart <= OverrideStart) + { + if (ReadEnd <= OverrideEnd) + { + CopyMem(pCurBuf + OverrideStart - ReadStart, pOverride->override_data, ReadEnd - OverrideStart); + } + else + { + CopyMem(pCurBuf + OverrideStart - ReadStart, pOverride->override_data, pOverride->override_size); + } + } + else + { + if (ReadEnd <= OverrideEnd) + { + CopyMem(pCurBuf, pOverride->override_data + ReadStart - OverrideStart, ReadEnd - ReadStart); + } + else + { + CopyMem(pCurBuf, pOverride->override_data + ReadStart - OverrideStart, OverrideEnd - ReadStart); + } + } + + if (g_fixup_iso9660_secover_enable && (!g_fixup_iso9660_secover_start) && + pOverride->override_size == sizeof(ventoy_iso9660_override)) + { + ventoy_iso9660_override *dirent = (ventoy_iso9660_override *)pOverride->override_data; + if (dirent->first_sector >= VENTOY_ISO9660_SECTOR_OVERFLOW) + { + g_fixup_iso9660_secover_start = TRUE; + g_fixup_iso9660_secover_cur_secs = 0; + } + } + } + + if (g_blockio_start_record_bcd && FALSE == g_blockio_bcd_read_done) + { + if (*(UINT32 *)Buffer == 0x66676572) + { + g_blockio_bcd_read_done = TRUE; + } + } + + return EFI_SUCCESS; +} + +STATIC EFI_STATUS EFIAPI ventoy_write_iso_sector +( + IN UINT64 Sector, + IN UINTN Count, + IN VOID *Buffer +) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_LBA MapLba = 0; + UINT32 i = 0; + UINTN secLeft = 0; + UINTN secRead = 0; + UINT64 ReadStart = 0; + UINT64 ReadEnd = 0; + UINT8 *pCurBuf = (UINT8 *)Buffer; + ventoy_img_chunk *pchunk = g_chunk; + EFI_BLOCK_IO_PROTOCOL *pRawBlockIo = gBlockData.pRawBlockIo; + + debug("write iso sector %lu count %u", Sector, Count); + + ReadStart = Sector * 2048; + ReadEnd = (Sector + Count) * 2048; + + for (i = 0; Count > 0 && i < g_img_chunk_num; i++, pchunk++) + { + if (Sector >= pchunk->img_start_sector && Sector <= pchunk->img_end_sector) + { + if (g_chain->disk_sector_size == 512) + { + MapLba = (Sector - pchunk->img_start_sector) * 4 + pchunk->disk_start_sector; + } + else if (g_chain->disk_sector_size == 1024) + { + MapLba = (Sector - pchunk->img_start_sector) * 2 + pchunk->disk_start_sector; + } + else if (g_chain->disk_sector_size == 2048) + { + MapLba = (Sector - pchunk->img_start_sector) + pchunk->disk_start_sector; + } + else if (g_chain->disk_sector_size == 4096) + { + MapLba = ((Sector - pchunk->img_start_sector) >> 1) + pchunk->disk_start_sector; + } + + + secLeft = pchunk->img_end_sector + 1 - Sector; + secRead = (Count < secLeft) ? Count : secLeft; + + Status = pRawBlockIo->WriteBlocks(pRawBlockIo, pRawBlockIo->Media->MediaId, + MapLba, secRead * 2048, pCurBuf); + if (EFI_ERROR(Status)) + { + debug("Raw disk write block failed %r LBA:%lu Count:%u", Status, MapLba, secRead); + return Status; + } + + Count -= secRead; + Sector += secRead; + pCurBuf += secRead * 2048; + } + } + + return EFI_SUCCESS; +} + +EFI_STATUS EFIAPI ventoy_block_io_ramdisk_write +( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + IN VOID *Buffer +) +{ + (VOID)This; + (VOID)MediaId; + (VOID)Lba; + (VOID)BufferSize; + (VOID)Buffer; + + if (!gSector512Mode) + { + return EFI_WRITE_PROTECTED; + } + + CopyMem(g_iso_data_buf + (Lba * 2048), Buffer, BufferSize); + + return EFI_SUCCESS; +} + +EFI_STATUS EFIAPI ventoy_block_io_ramdisk_read +( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + OUT VOID *Buffer +) +{ + //debug("### ventoy_block_io_ramdisk_read sector:%u count:%u", (UINT32)Lba, (UINT32)BufferSize / 2048); + + (VOID)This; + (VOID)MediaId; + + CopyMem(Buffer, g_iso_data_buf + (Lba * 2048), BufferSize); + + if (g_blockio_start_record_bcd && FALSE == g_blockio_bcd_read_done) + { + if (*(UINT32 *)Buffer == 0x66676572) + { + g_blockio_bcd_read_done = TRUE; + } + } + + return EFI_SUCCESS; +} + +EFI_LBA EFIAPI ventoy_fixup_iso9660_sector(IN EFI_LBA Lba, UINT32 secNum) +{ + UINT32 i = 0; + + if (g_fixup_iso9660_secover_cur_secs > 0) + { + Lba += VENTOY_ISO9660_SECTOR_OVERFLOW; + g_fixup_iso9660_secover_cur_secs += secNum; + if (g_fixup_iso9660_secover_cur_secs >= g_fixup_iso9660_secover_tot_secs) + { + g_fixup_iso9660_secover_start = FALSE; + goto end; + } + } + else + { + ventoy_iso9660_override *dirent; + ventoy_override_chunk *pOverride; + + for (i = 0, pOverride = g_override_chunk; i < g_override_chunk_num; i++, pOverride++) + { + dirent = (ventoy_iso9660_override *)pOverride->override_data; + if (Lba == dirent->first_sector) + { + g_fixup_iso9660_secover_start = FALSE; + goto end; + } + } + + if (g_fixup_iso9660_secover_start) + { + for (i = 0, pOverride = g_override_chunk; i < g_override_chunk_num; i++, pOverride++) + { + dirent = (ventoy_iso9660_override *)pOverride->override_data; + if (Lba + VENTOY_ISO9660_SECTOR_OVERFLOW == dirent->first_sector) + { + g_fixup_iso9660_secover_tot_secs = (dirent->size + 2047) / 2048; + g_fixup_iso9660_secover_cur_secs = secNum; + if (g_fixup_iso9660_secover_cur_secs >= g_fixup_iso9660_secover_tot_secs) + { + g_fixup_iso9660_secover_start = FALSE; + } + Lba += VENTOY_ISO9660_SECTOR_OVERFLOW; + goto end; + } + } + } + } + +end: + return Lba; +} + +EFI_STATUS EFIAPI ventoy_block_io_read_real +( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + OUT VOID *Buffer +) +{ + UINT32 i = 0; + UINT32 j = 0; + UINT32 lbacount = 0; + UINT32 secNum = 0; + UINT32 TmpNum = 0; + UINT64 VirtSec = 0; + UINT64 offset = 0; + EFI_LBA curlba = 0; + EFI_LBA lastlba = 0; + UINT8 *lastbuffer; + ventoy_sector_flag *cur_flag; + ventoy_virt_chunk *node; + + debug("### block_io_read_real sector:%u count:%u Buffer:%p", (UINT32)Lba, (UINT32)BufferSize / 2048, Buffer); + + secNum = BufferSize / 2048; + + /* Workaround for SSTR PE loader error */ + if (g_fixup_iso9660_secover_start) + { + Lba = ventoy_fixup_iso9660_sector(Lba, secNum); + } + + offset = Lba * 2048; + + if (offset + BufferSize <= g_chain->real_img_size_in_bytes) + { + return ventoy_read_iso_sector(Lba, secNum, Buffer); + } + else if (offset < g_chain->real_img_size_in_bytes) + { + TmpNum = (g_chain->real_img_size_in_bytes - offset) / 2048; + ventoy_read_iso_sector(Lba, TmpNum, Buffer); + + Lba += TmpNum; + secNum -= TmpNum; + Buffer = (UINT8 *)Buffer + (g_chain->real_img_size_in_bytes - offset); + offset = Lba * 2048; + } + + VirtSec = g_chain->virt_img_size_in_bytes / 2048; + if (Lba >= VirtSec) + { + return EFI_SUCCESS; + } + else if (Lba + secNum > VirtSec) + { + secNum = VirtSec - Lba; + } + + debug("XXX block_io_read_real sector:%u count:%u Buffer:%p", (UINT32)Lba, (UINT32)BufferSize / 2048, Buffer); + + if (secNum > g_sector_flag_num) + { + cur_flag = AllocatePool(secNum * sizeof(ventoy_sector_flag)); + if (NULL == cur_flag) + { + return EFI_OUT_OF_RESOURCES; + } + + FreePool(g_sector_flag); + g_sector_flag = cur_flag; + g_sector_flag_num = secNum; + } + + for (curlba = Lba, cur_flag = g_sector_flag, j = 0; j < secNum; j++, curlba++, cur_flag++) + { + cur_flag->flag = 0; + for (node = g_virt_chunk, i = 0; i < g_virt_chunk_num; i++, node++) + { + if (curlba >= node->mem_sector_start && curlba < node->mem_sector_end) + { + CopyMem((UINT8 *)Buffer + j * 2048, + (char *)g_virt_chunk + node->mem_sector_offset + (curlba - node->mem_sector_start) * 2048, + 2048); + cur_flag->flag = 1; + break; + } + else if (curlba >= node->remap_sector_start && curlba < node->remap_sector_end) + { + cur_flag->remap_lba = node->org_sector_start + curlba - node->remap_sector_start; + cur_flag->flag = 2; + break; + } + } + } + + for (curlba = Lba, cur_flag = g_sector_flag, j = 0; j < secNum; j++, curlba++, cur_flag++) + { + if (cur_flag->flag == 2) + { + if (lastlba == 0) + { + lastbuffer = (UINT8 *)Buffer + j * 2048; + lastlba = cur_flag->remap_lba; + lbacount = 1; + } + else if (lastlba + lbacount == cur_flag->remap_lba) + { + lbacount++; + } + else + { + ventoy_read_iso_sector(lastlba, lbacount, lastbuffer); + lastbuffer = (UINT8 *)Buffer + j * 2048; + lastlba = cur_flag->remap_lba; + lbacount = 1; + } + } + } + + if (lbacount > 0) + { + ventoy_read_iso_sector(lastlba, lbacount, lastbuffer); + } + + return EFI_SUCCESS; +} + +EFI_STATUS EFIAPI ventoy_block_io_read +( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + OUT VOID *Buffer +) +{ + UINT32 IoAlign = 0; + VOID *NewBuf = NULL; + EFI_STATUS Status = EFI_OUT_OF_RESOURCES; + + if (gBlockData.pRawBlockIo && gBlockData.pRawBlockIo->Media) + { + IoAlign = gBlockData.pRawBlockIo->Media->IoAlign; + } + + if ((IoAlign == 0) || (((UINTN) Buffer & (IoAlign - 1)) == 0)) + { + Status = ventoy_block_io_read_real(This, MediaId, Lba, BufferSize, Buffer); + } + else + { + NewBuf = AllocatePages(EFI_SIZE_TO_PAGES(BufferSize + IoAlign)); + if (NewBuf) + { + Status = ventoy_block_io_read_real(This, MediaId, Lba, BufferSize, NewBuf); + CopyMem(Buffer, NewBuf, BufferSize); + FreePages(NewBuf, EFI_SIZE_TO_PAGES(BufferSize + IoAlign)); + } + } + + return Status; +} + +EFI_STATUS EFIAPI ventoy_block_io_write +( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + IN VOID *Buffer +) +{ + UINT32 secNum = 0; + UINT64 offset = 0; + + (VOID)This; + (VOID)MediaId; + + if (!gSector512Mode) + { + return EFI_WRITE_PROTECTED; + } + + secNum = BufferSize / 2048; + offset = Lba * 2048; + + return ventoy_write_iso_sector(Lba, secNum, Buffer); +} + +EFI_STATUS EFIAPI ventoy_block_io_flush(IN EFI_BLOCK_IO_PROTOCOL *This) +{ + (VOID)This; + return EFI_SUCCESS; +} + +STATIC UINTN ventoy_get_current_device_path_id(VOID) +{ + UINTN i = 0; + UINTN Count = 0; + UINTN MaxId = 0; + UINTN CurId = 0; + BOOLEAN Find = FALSE; + EFI_HANDLE *Handles = NULL; + EFI_STATUS Status = EFI_SUCCESS; + EFI_DEVICE_PATH_PROTOCOL *DevicePath = NULL; + VENDOR_DEVICE_PATH *venPath = NULL; + + Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiDevicePathProtocolGuid, + NULL, &Count, &Handles); + if (EFI_ERROR(Status)) + { + return 0; + } + + for (i = 0; i < Count; i++) + { + Status = gBS->HandleProtocol(Handles[i], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath); + if (EFI_ERROR(Status)) + { + continue; + } + + if (DevicePath->Type == HARDWARE_DEVICE_PATH && DevicePath->SubType == HW_VENDOR_DP) + { + venPath = (VENDOR_DEVICE_PATH *)DevicePath; + if (CompareGuid(&venPath->Guid, &gVtoyBlockDevicePathGuid)) + { + CurId = StrDecimalToUintn((CHAR16 *)(venPath + 1) + StrLen(L"ventoy_")); + MaxId = MAX(MaxId, CurId); + Find = TRUE; + } + } + } + + FreePool(Handles); + + return Find ? (MaxId + 1) : 0; +} + +EFI_STATUS EFIAPI ventoy_fill_device_path(VOID) +{ + UINTN CurVtoyDpId = 0; + UINTN NameLen = 0; + UINT8 TmpBuf[128] = {0}; + VENDOR_DEVICE_PATH *venPath = NULL; + CHAR16 VtoyDpName[32]; + + CurVtoyDpId = ventoy_get_current_device_path_id(); + UnicodeSPrintAsciiFormat(VtoyDpName, sizeof(VtoyDpName), "ventoy_%03lu", CurVtoyDpId); + + venPath = (VENDOR_DEVICE_PATH *)TmpBuf; + NameLen = StrSize(VtoyDpName); + venPath->Header.Type = HARDWARE_DEVICE_PATH; + venPath->Header.SubType = HW_VENDOR_DP; + venPath->Header.Length[0] = sizeof(VENDOR_DEVICE_PATH) + NameLen; + venPath->Header.Length[1] = 0; + CopyMem(&venPath->Guid, &gVtoyBlockDevicePathGuid, sizeof(EFI_GUID)); + CopyMem(venPath + 1, VtoyDpName, NameLen); + + gBlockData.Path = AppendDevicePathNode(NULL, (EFI_DEVICE_PATH_PROTOCOL *)TmpBuf); + gBlockData.DevicePathCompareLen = sizeof(VENDOR_DEVICE_PATH) + NameLen; + + debug("gBlockData.Path=<%lu><%s>\n", CurVtoyDpId, ConvertDevicePathToText(gBlockData.Path, FALSE, FALSE)); + + return EFI_SUCCESS; +} + +EFI_STATUS EFIAPI ventoy_connect_driver(IN EFI_HANDLE ControllerHandle, IN CONST CHAR16 *DrvName) +{ + UINTN i = 0; + UINTN Count = 0; + CHAR16 *DriverName = NULL; + EFI_HANDLE *Handles = NULL; + EFI_HANDLE DrvHandles[2] = { NULL }; + EFI_STATUS Status = EFI_SUCCESS; + EFI_COMPONENT_NAME_PROTOCOL *NameProtocol = NULL; + EFI_COMPONENT_NAME2_PROTOCOL *Name2Protocol = NULL; + + debug("ventoy_connect_driver <%s>...", DrvName); + + Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiComponentName2ProtocolGuid, + NULL, &Count, &Handles); + if (EFI_ERROR(Status)) + { + return Status; + } + + for (i = 0; i < Count; i++) + { + Status = gBS->HandleProtocol(Handles[i], &gEfiComponentName2ProtocolGuid, (VOID **)&Name2Protocol); + if (EFI_ERROR(Status)) + { + continue; + } + + VENTOY_GET_COMPONENT_NAME(Name2Protocol, DriverName); + + if (StrStr(DriverName, DrvName)) + { + debug("Find driver name2:<%s>: <%s>", DriverName, DrvName); + DrvHandles[0] = Handles[i]; + break; + } + } + + if (i < Count) + { + Status = gBS->ConnectController(ControllerHandle, DrvHandles, NULL, TRUE); + debug("ventoy_connect_driver:<%s> <%r>", DrvName, Status); + goto end; + } + + debug("%s NOT found, now try COMPONENT_NAME", DrvName); + + Count = 0; + FreePool(Handles); + Handles = NULL; + + Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiComponentNameProtocolGuid, + NULL, &Count, &Handles); + if (EFI_ERROR(Status)) + { + return Status; + } + + for (i = 0; i < Count; i++) + { + Status = gBS->HandleProtocol(Handles[i], &gEfiComponentNameProtocolGuid, (VOID **)&NameProtocol); + if (EFI_ERROR(Status)) + { + continue; + } + + VENTOY_GET_COMPONENT_NAME(NameProtocol, DriverName); + + if (StrStr(DriverName, DrvName)) + { + debug("Find driver name:<%s>: <%s>", DriverName, DrvName); + DrvHandles[0] = Handles[i]; + break; + } + } + + if (i < Count) + { + Status = gBS->ConnectController(ControllerHandle, DrvHandles, NULL, TRUE); + debug("ventoy_connect_driver:<%s> <%r>", DrvName, Status); + goto end; + } + + Status = EFI_NOT_FOUND; + +end: + FreePool(Handles); + + return Status; +} + + +STATIC BOOLEAN ventoy_filesystem_need_wrapper(IN CONST CHAR16 *DrvName) +{ + UINTN i; + CHAR16 UpperDrvName[256]; + + StrCpyS(UpperDrvName, 256, DrvName); + + for (i = 0; i < 256 && UpperDrvName[i]; i++) + { + if (UpperDrvName[i] >= 'a' && UpperDrvName[i] <= 'z') + { + UpperDrvName[i] = 'A' + (UpperDrvName[i] - 'a'); + } + } + + /* + * suppress some file system drivers + * 1. rEFInd File System Driver + * + */ + + if (StrStr(UpperDrvName, L"REFIND") && StrStr(UpperDrvName, L"FILE SYSTEM")) + { + return TRUE; + } + + return FALSE; +} + +STATIC VOID ventoy_add_filesystem_wrapper +( + IN EFI_DRIVER_BINDING_PROTOCOL *DriverBindProtocol, + IN CONST CHAR16 *DriverName +) +{ + UINTN j; + + if (g_DriverBindWrapperCnt >= MAX_DRIVER_BIND_WRAPPER) + { + debug("driver binding wrapper overflow %lu", g_DriverBindWrapperCnt); + return; + } + + if (!ventoy_filesystem_need_wrapper(DriverName)) + { + return; + } + + for (j = 0; j < g_DriverBindWrapperCnt; j++) + { + if (g_DriverBindWrapperList[j].DriverBinding == DriverBindProtocol) + { + debug("Duplicate driverbinding <%s> %p %lu %lu", DriverName, DriverBindProtocol, j, g_DriverBindWrapperCnt); + break; + } + } + + if (j >= g_DriverBindWrapperCnt) + { + g_DriverBindWrapperList[g_DriverBindWrapperCnt].DriverBinding = DriverBindProtocol; + g_DriverBindWrapperList[g_DriverBindWrapperCnt].pfOldSupport = DriverBindProtocol->Supported; + g_DriverBindWrapperCnt++; + debug("Add driverbinding <%s> %p %lu", DriverName, DriverBindProtocol, g_DriverBindWrapperCnt); + } +} + +STATIC EFI_STATUS ventoy_find_filesystem_driverbind(VOID) +{ + UINTN i = 0; + UINTN Count = 0; + CHAR16 *DriverName = NULL; + EFI_HANDLE *Handles = NULL; + EFI_STATUS Status = EFI_SUCCESS; + EFI_COMPONENT_NAME_PROTOCOL *NameProtocol = NULL; + EFI_COMPONENT_NAME2_PROTOCOL *Name2Protocol = NULL; + EFI_DRIVER_BINDING_PROTOCOL *DriverBindProtocol = NULL; + + debug("ventoy_find_filesystem_driverbind..."); + + Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiComponentName2ProtocolGuid, + NULL, &Count, &Handles); + if (EFI_ERROR(Status)) + { + return Status; + } + + for (i = 0; i < Count; i++) + { + Status = gBS->HandleProtocol(Handles[i], &gEfiComponentName2ProtocolGuid, (VOID **)&Name2Protocol); + if (EFI_ERROR(Status)) + { + continue; + } + + VENTOY_GET_COMPONENT_NAME(Name2Protocol, DriverName); + + Status = gBS->HandleProtocol(Handles[i], &gEfiDriverBindingProtocolGuid, (VOID **)&DriverBindProtocol); + if (EFI_ERROR(Status)) + { + debug("### 2 No DriverBind <%s> <%r>", DriverName, Status); + continue; + } + + ventoy_add_filesystem_wrapper(DriverBindProtocol, DriverName); + } + + Count = 0; + FreePool(Handles); + Handles = NULL; + + Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiComponentNameProtocolGuid, + NULL, &Count, &Handles); + if (EFI_ERROR(Status)) + { + return Status; + } + + for (i = 0; i < Count; i++) + { + Status = gBS->HandleProtocol(Handles[i], &gEfiComponentNameProtocolGuid, (VOID **)&NameProtocol); + if (EFI_ERROR(Status)) + { + continue; + } + + VENTOY_GET_COMPONENT_NAME(NameProtocol, DriverName); + + Status = gBS->HandleProtocol(Handles[i], &gEfiDriverBindingProtocolGuid, (VOID **)&DriverBindProtocol); + if (EFI_ERROR(Status)) + { + debug("### 1 No DriverBind <%s> <%r>", DriverName, Status); + continue; + } + + ventoy_add_filesystem_wrapper(DriverBindProtocol, DriverName); + } + + FreePool(Handles); + + return EFI_SUCCESS; +} + +STATIC EFI_STATUS EFIAPI ventoy_wrapper_driver_bind_support +( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL +) +{ + UINTN i; + EFI_STATUS Status = EFI_SUCCESS; + EFI_DEVICE_PATH_PROTOCOL *DevicePath = NULL; + EFI_DRIVER_BINDING_SUPPORTED pfOldSupport = NULL; + + for (i = 0; i < g_DriverBindWrapperCnt; i++) + { + if (g_DriverBindWrapperList[i].DriverBinding == This) + { + pfOldSupport = g_DriverBindWrapperList[i].pfOldSupport; + break; + } + } + + debug("ventoy_wrapper_driver_bind_support %lu %p", i, pfOldSupport); + + if (!pfOldSupport) + { + return EFI_UNSUPPORTED; + } + + Status = gBS->HandleProtocol(ControllerHandle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath); + if (EFI_ERROR(Status)) + { + goto out; + } + + if (0 == CompareMem(gBlockData.Path, DevicePath, gBlockData.DevicePathCompareLen)) + { + debug("return EFI_UNSUPPORTED for ventoy"); + return EFI_UNSUPPORTED; + } + +out: + return pfOldSupport(This, ControllerHandle, RemainingDevicePath); +} + +EFI_STATUS ventoy_disable_ex_filesystem(VOID) +{ + UINTN i; + + ventoy_find_filesystem_driverbind(); + + for (i = 0; i < g_DriverBindWrapperCnt; i++) + { + g_DriverBindWrapperList[i].DriverBinding->Supported = ventoy_wrapper_driver_bind_support; + } + + debug("Wrapper Ex Driver Binding %lu", g_DriverBindWrapperCnt); + ventoy_debug_pause(); + + return EFI_SUCCESS; +} + +EFI_STATUS ventoy_enable_ex_filesystem(VOID) +{ + UINTN i; + + for (i = 0; i < g_DriverBindWrapperCnt; i++) + { + g_DriverBindWrapperList[i].DriverBinding->Supported = g_DriverBindWrapperList[i].pfOldSupport; + } + g_DriverBindWrapperCnt = 0; + + return EFI_SUCCESS; +} + +EFI_STATUS EFIAPI ventoy_block_io_read_512 +( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + OUT VOID *Buffer +) +{ + EFI_LBA Mod; + UINTN ReadSize; + UINT8 *CurBuf = NULL; + EFI_STATUS Status = EFI_SUCCESS; + + debug("ventoy_block_io_read_512 %lu %lu Buffer:%p\n", Lba, BufferSize / 512, Buffer); + + CurBuf = (UINT8 *)Buffer; + + Mod = Lba % 4; + if (Mod > 0) + { + Status |= g_sector_2048_read(This, MediaId, Lba / 4, 2048, g_sector_buf); + + if (BufferSize <= (4 - Mod) * 512) + { + CopyMem(CurBuf, g_sector_buf + Mod * 512, BufferSize); + return EFI_SUCCESS; + } + else + { + ReadSize = (4 - Mod) * 512; + CopyMem(CurBuf, g_sector_buf + Mod * 512, ReadSize); + CurBuf += ReadSize; + Lba += (4 - Mod); + BufferSize -= ReadSize; + } + } + + if (BufferSize >= 2048) + { + ReadSize = BufferSize / 2048 * 2048; + + Status |= g_sector_2048_read(This, MediaId, Lba / 4, ReadSize, CurBuf); + CurBuf += ReadSize; + + Lba += ReadSize / 512; + BufferSize -= ReadSize; + } + + if (BufferSize > 0) + { + Status |= g_sector_2048_read(This, MediaId, Lba / 4, 2048, g_sector_buf); + CopyMem(CurBuf, g_sector_buf, BufferSize); + } + + return Status; +} + +EFI_STATUS EFIAPI ventoy_block_io_write_512 +( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + IN VOID *Buffer +) +{ + EFI_LBA Mod; + UINTN ReadSize; + UINT8 *CurBuf = NULL; + EFI_STATUS Status = EFI_SUCCESS; + + debug("ventoy_block_io_write_512 %lu %lu\n", Lba, BufferSize / 512); + + CurBuf = (UINT8 *)Buffer; + + Mod = Lba % 4; + if (Mod > 0) + { + Status |= g_sector_2048_read(This, MediaId, Lba / 4, 2048, g_sector_buf); + + if (BufferSize <= (4 - Mod) * 512) + { + CopyMem(g_sector_buf + Mod * 512, CurBuf, BufferSize); + return g_sector_2048_write(This, MediaId, Lba / 4, 2048, g_sector_buf); + } + else + { + ReadSize = (4 - Mod) * 512; + CopyMem(g_sector_buf + Mod * 512, CurBuf, ReadSize); + g_sector_2048_write(This, MediaId, Lba / 4, 2048, g_sector_buf); + + CurBuf += ReadSize; + Lba += (4 - Mod); + BufferSize -= ReadSize; + } + } + + if (BufferSize >= 2048) + { + ReadSize = BufferSize / 2048 * 2048; + + Status |= g_sector_2048_write(This, MediaId, Lba / 4, ReadSize, CurBuf); + CurBuf += ReadSize; + + Lba += ReadSize / 512; + BufferSize -= ReadSize; + } + + if (BufferSize > 0) + { + Status |= g_sector_2048_read(This, MediaId, Lba / 4, 2048, g_sector_buf); + + CopyMem(g_sector_buf, CurBuf, BufferSize); + g_sector_2048_write(This, MediaId, Lba / 4, 2048, g_sector_buf); + } + + return Status; +} + +EFI_STATUS EFIAPI ventoy_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 ImgSize) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_BLOCK_IO_PROTOCOL *pBlockIo = &(gBlockData.BlockIo); + + ventoy_fill_device_path(); + + debug("install block io protocol %p", ImageHandle); + ventoy_debug_pause(); + + if (gSector512Mode) + { + gBlockData.Media.BlockSize = 512; + gBlockData.Media.LastBlock = ImgSize / 512 - 1; + gBlockData.Media.ReadOnly = FALSE; + } + else + { + gBlockData.Media.BlockSize = 2048; + gBlockData.Media.LastBlock = ImgSize / 2048 - 1; + gBlockData.Media.ReadOnly = TRUE; + } + + gBlockData.Media.MediaPresent = 1; + gBlockData.Media.LogicalBlocksPerPhysicalBlock = 1; + + pBlockIo->Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3; + pBlockIo->Media = &(gBlockData.Media); + pBlockIo->Reset = ventoy_block_io_reset; + + if (gSector512Mode) + { + g_sector_2048_read = gMemdiskMode ? ventoy_block_io_ramdisk_read : ventoy_block_io_read; + g_sector_2048_write = gMemdiskMode ? ventoy_block_io_ramdisk_write : ventoy_block_io_write; + pBlockIo->ReadBlocks = ventoy_block_io_read_512; + pBlockIo->WriteBlocks = ventoy_block_io_write_512; + } + else + { + pBlockIo->ReadBlocks = gMemdiskMode ? ventoy_block_io_ramdisk_read : ventoy_block_io_read; + pBlockIo->WriteBlocks = ventoy_block_io_write; + } + + pBlockIo->FlushBlocks = ventoy_block_io_flush; + + Status = gBS->InstallMultipleProtocolInterfaces(&gBlockData.Handle, + &gEfiBlockIoProtocolGuid, &gBlockData.BlockIo, + &gEfiDevicePathProtocolGuid, gBlockData.Path, + NULL); + debug("Install protocol %r %p", Status, gBlockData.Handle); + if (EFI_ERROR(Status)) + { + return Status; + } + + Status = ventoy_connect_driver(gBlockData.Handle, L"Disk I/O Driver"); + debug("Connect disk IO driver %r", Status); + + Status = ventoy_connect_driver(gBlockData.Handle, L"Partition Driver"); + debug("Connect partition driver %r", Status); + if (EFI_ERROR(Status)) + { + Status = gBS->ConnectController(gBlockData.Handle, NULL, NULL, TRUE); + debug("Connect all controller %r", Status); + } + + ventoy_debug_pause(); + + return EFI_SUCCESS; +} + +#if 0 +/* For file replace */ +#endif + +STATIC EFI_STATUS EFIAPI +ventoy_wrapper_fs_open(EFI_FILE_HANDLE This, EFI_FILE_HANDLE *New, CHAR16 *Name, UINT64 Mode, UINT64 Attributes) +{ + (VOID)This; + (VOID)New; + (VOID)Name; + (VOID)Mode; + (VOID)Attributes; + return EFI_SUCCESS; +} + +STATIC EFI_STATUS EFIAPI +ventoy_wrapper_file_open_ex(EFI_FILE_HANDLE This, EFI_FILE_HANDLE *New, CHAR16 *Name, UINT64 Mode, UINT64 Attributes, EFI_FILE_IO_TOKEN *Token) +{ + return ventoy_wrapper_fs_open(This, New, Name, Mode, Attributes); +} + +STATIC EFI_STATUS EFIAPI +ventoy_wrapper_file_delete(EFI_FILE_HANDLE This) +{ + (VOID)This; + return EFI_SUCCESS; +} + +STATIC EFI_STATUS EFIAPI +ventoy_wrapper_file_set_info(EFI_FILE_HANDLE This, EFI_GUID *Type, UINTN Len, VOID *Data) +{ + return EFI_SUCCESS; +} + +STATIC EFI_STATUS EFIAPI +ventoy_wrapper_file_flush(EFI_FILE_HANDLE This) +{ + (VOID)This; + return EFI_SUCCESS; +} + +/* Ex version */ +STATIC EFI_STATUS EFIAPI +ventoy_wrapper_file_flush_ex(EFI_FILE_HANDLE This, EFI_FILE_IO_TOKEN *Token) +{ + (VOID)This; + (VOID)Token; + return EFI_SUCCESS; +} + +/* Ex version */ +STATIC EFI_STATUS EFIAPI +ventoy_wrapper_file_flush_ex_img0(EFI_FILE_HANDLE This, EFI_FILE_IO_TOKEN *Token) +{ + (VOID)This; + (VOID)Token; + return EFI_SUCCESS; +} +/* Ex version */ +STATIC EFI_STATUS EFIAPI +ventoy_wrapper_file_flush_ex_img1(EFI_FILE_HANDLE This, EFI_FILE_IO_TOKEN *Token) +{ + (VOID)This; + (VOID)Token; + return EFI_SUCCESS; +} + +#define DEF_WRAP_FUNC(n) \ +STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_flush_ex_img#n(EFI_FILE_HANDLE This, EFI_FILE_IO_TOKEN *Token) \ +{\ + (VOID)This;\ + (VOID)Token;\ + return EFI_SUCCESS;\ +} + +#define ITEM_WRAP_FUNC(n) ventoy_wrapper_file_flush_ex_img#n + +#if (VTOY_MAX_CONF_REPLACE > 2) +DEF_WRAP_FUNC(2); +#endif +#if (VTOY_MAX_CONF_REPLACE > 3) +DEF_WRAP_FUNC(3); +#endif +#if (VTOY_MAX_CONF_REPLACE > 4) +DEF_WRAP_FUNC(4); +#endif +#if (VTOY_MAX_CONF_REPLACE > 5) +DEF_WRAP_FUNC(5); +#endif +#if (VTOY_MAX_CONF_REPLACE > 6) +DEF_WRAP_FUNC(6); +#endif +#if (VTOY_MAX_CONF_REPLACE > 7) +DEF_WRAP_FUNC(7); +#endif +#if (VTOY_MAX_CONF_REPLACE > 8) +#error "VTOY_MAX_CONF_REPLACE overflow" +#endif + +static EFI_FILE_FLUSH_EX g_img_flush_func[VTOY_MAX_CONF_REPLACE] = +{ + ventoy_wrapper_file_flush_ex_img0, + ventoy_wrapper_file_flush_ex_img1, +#if (VTOY_MAX_CONF_REPLACE > 2) + ITEM_WRAP_FUNC(2), +#endif +#if (VTOY_MAX_CONF_REPLACE > 3) + ITEM_WRAP_FUNC(3), +#endif +#if (VTOY_MAX_CONF_REPLACE > 4) + ITEM_WRAP_FUNC(4), +#endif +#if (VTOY_MAX_CONF_REPLACE > 5) + ITEM_WRAP_FUNC(5), +#endif +#if (VTOY_MAX_CONF_REPLACE > 6) + ITEM_WRAP_FUNC(6), +#endif +#if (VTOY_MAX_CONF_REPLACE > 7) + ITEM_WRAP_FUNC(7), +#endif +}; + +STATIC ventoy_efi_file_replace *ventoy_wrapper_get_replace(EFI_FILE_HANDLE This) +{ + UINTN i; + + if (This->FlushEx == ventoy_wrapper_file_flush_ex) + { + return &g_efi_file_replace; + } + + for (i = 0; i < VTOY_MAX_CONF_REPLACE; i++) + { + if (This->FlushEx == g_img_flush_func[i]) + { + return g_img_file_replace + i; + } + } + + return NULL; +} + +STATIC EFI_STATUS EFIAPI +ventoy_wrapper_file_write(EFI_FILE_HANDLE This, UINTN *Len, VOID *Data) +{ + (VOID)This; + (VOID)Len; + (VOID)Data; + + return EFI_WRITE_PROTECTED; +} + +STATIC EFI_STATUS EFIAPI +ventoy_wrapper_file_write_ex(IN EFI_FILE_PROTOCOL *This, IN OUT EFI_FILE_IO_TOKEN *Token) +{ + return ventoy_wrapper_file_write(This, &(Token->BufferSize), Token->Buffer); +} + + +STATIC EFI_STATUS EFIAPI +ventoy_wrapper_file_close(EFI_FILE_HANDLE This) +{ + (VOID)This; + return EFI_SUCCESS; +} + +STATIC EFI_STATUS EFIAPI +ventoy_wrapper_file_set_pos(EFI_FILE_HANDLE This, UINT64 Position) +{ + ventoy_efi_file_replace *replace = NULL; + + replace = ventoy_wrapper_get_replace(This); + + if (Position <= replace->FileSizeBytes) + { + replace->CurPos = Position; + } + else + { + replace->CurPos = replace->FileSizeBytes; + } + + return EFI_SUCCESS; +} + +STATIC EFI_STATUS EFIAPI +ventoy_wrapper_file_get_pos(EFI_FILE_HANDLE This, UINT64 *Position) +{ + ventoy_efi_file_replace *replace = NULL; + + replace = ventoy_wrapper_get_replace(This); + + *Position = replace->CurPos; + + return EFI_SUCCESS; +} + + +STATIC EFI_STATUS EFIAPI +ventoy_wrapper_file_get_info(EFI_FILE_HANDLE This, EFI_GUID *Type, UINTN *Len, VOID *Data) +{ + EFI_FILE_INFO *Info = (EFI_FILE_INFO *) Data; + ventoy_efi_file_replace *replace = NULL; + + replace = ventoy_wrapper_get_replace(This); + + debug("ventoy_wrapper_file_get_info ... %u", *Len); + + if (!CompareGuid(Type, &gEfiFileInfoGuid)) + { + return EFI_INVALID_PARAMETER; + } + + if (*Len == 0) + { + *Len = 384; + return EFI_BUFFER_TOO_SMALL; + } + + ZeroMem(Data, sizeof(EFI_FILE_INFO)); + + Info->Size = sizeof(EFI_FILE_INFO); + Info->FileSize = replace->FileSizeBytes; + Info->PhysicalSize = replace->FileSizeBytes; + Info->Attribute = EFI_FILE_READ_ONLY; + //Info->FileName = EFI_FILE_READ_ONLY; + + *Len = Info->Size; + + return EFI_SUCCESS; +} + +STATIC EFI_STATUS EFIAPI +ventoy_wrapper_file_read(EFI_FILE_HANDLE This, UINTN *Len, VOID *Data) +{ + EFI_LBA Lba; + UINTN ReadLen = *Len; + ventoy_efi_file_replace *replace = NULL; + + replace = ventoy_wrapper_get_replace(This); + + debug("ventoy_wrapper_file_read ... %u", *Len); + + if (replace->CurPos + ReadLen > replace->FileSizeBytes) + { + ReadLen = replace->FileSizeBytes - replace->CurPos; + } + + Lba = replace->CurPos / 2048 + replace->BlockIoSectorStart; + + ventoy_block_io_read(NULL, 0, Lba, ReadLen, Data); + + *Len = ReadLen; + + replace->CurPos += ReadLen; + + return EFI_SUCCESS; +} + +STATIC EFI_STATUS EFIAPI +ventoy_wrapper_file_read_ex(IN EFI_FILE_PROTOCOL *This, IN OUT EFI_FILE_IO_TOKEN *Token) +{ + return ventoy_wrapper_file_read(This, &(Token->BufferSize), Token->Buffer); +} + +STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_procotol(EFI_FILE_PROTOCOL *File, BOOLEAN Img, UINTN Index) +{ + File->Revision = EFI_FILE_PROTOCOL_REVISION2; + File->Open = ventoy_wrapper_fs_open; + File->Close = ventoy_wrapper_file_close; + File->Delete = ventoy_wrapper_file_delete; + File->Read = ventoy_wrapper_file_read; + File->Write = ventoy_wrapper_file_write; + File->GetPosition = ventoy_wrapper_file_get_pos; + File->SetPosition = ventoy_wrapper_file_set_pos; + File->GetInfo = ventoy_wrapper_file_get_info; + File->SetInfo = ventoy_wrapper_file_set_info; + File->Flush = ventoy_wrapper_file_flush; + File->OpenEx = ventoy_wrapper_file_open_ex; + File->ReadEx = ventoy_wrapper_file_read_ex; + File->WriteEx = ventoy_wrapper_file_write_ex; + + if (Img) + { + File->FlushEx = g_img_flush_func[Index]; + } + else + { + File->FlushEx = ventoy_wrapper_file_flush_ex; + } + + return EFI_SUCCESS; +} + +STATIC BOOLEAN EFIAPI ventoy_replace_name_match(CHAR8 *pReplace, CHAR8 *pName) +{ + UINTN Len1, Len2; + + Len1 = AsciiStrLen(pReplace); + Len2 = AsciiStrLen(pName); + + if (Len1 == 0 || Len2 == 0) + { + return FALSE; + } + + if (0 == AsciiStriCmp(pReplace, pName)) + { + return TRUE; + } + + if (Len1 > 2 && Len2 > 2) + { + if ((pReplace[0] != '\\') && (pName[0] == '\\') && (0 == AsciiStriCmp(pReplace, pName + 1))) + { + return TRUE; + } + } + + return FALSE; +} + +STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_open +( + EFI_FILE_HANDLE This, + EFI_FILE_HANDLE *New, + CHAR16 *Name, + UINT64 Mode, + UINT64 Attributes +) +{ + UINT32 i = 0; + UINT32 j = 0; + UINT64 Sectors = 0; + EFI_STATUS Status = EFI_SUCCESS; + CHAR8 TmpName[256]; + CHAR8 OldName[256]; + ventoy_virt_chunk *virt = NULL; + ventoy_grub_param_file_replace *replace = NULL; + + debug("## ventoy_wrapper_file_open <%s> ", Name); + + if ((Mode & EFI_FILE_MODE_WRITE) > 0 && StrCmp(Name, L"\\loader\\random-seed") == 0) + { + if (gDebugPrint) + { + debug("## ventoy_wrapper_file_open return NOT_FOUND for random-seed %lx", Mode); + sleep(3); + } + return EFI_NOT_FOUND; + } + + Status = g_original_fopen(This, New, Name, Mode, Attributes); + if (EFI_ERROR(Status)) + { + return Status; + } + + + if (g_file_replace_list && g_file_replace_list->magic == GRUB_FILE_REPLACE_MAGIC && + g_file_replace_list->new_file_virtual_id < g_virt_chunk_num) + { + AsciiSPrint(TmpName, sizeof(TmpName), "%s", Name); + for (j = 0; j < 4; j++) + { + if (ventoy_replace_name_match(g_file_replace_list[i].old_file_name[j], TmpName)) + { + g_original_fclose(*New); + *New = &g_efi_file_replace.WrapperHandle; + ventoy_wrapper_file_procotol(*New, FALSE, 0); + + virt = g_virt_chunk + g_file_replace_list->new_file_virtual_id; + + Sectors = (virt->mem_sector_end - virt->mem_sector_start) + (virt->remap_sector_end - virt->remap_sector_start); + + g_efi_file_replace.BlockIoSectorStart = virt->mem_sector_start; + g_efi_file_replace.FileSizeBytes = Sectors * 2048; + + if (gDebugPrint) + { + debug("## ventoy_wrapper_file_open <%s> BlockStart:%lu Sectors:%lu Bytes:%lu", Name, + g_efi_file_replace.BlockIoSectorStart, Sectors, Sectors * 2048); + sleep(3); + } + + return Status; + } + } + + if (StrCmp(Name, L"\\EFI\\BOOT") == 0) + { + (*New)->Open = ventoy_wrapper_file_open; + } + } + + for (i = 0; g_img_replace_list && i < VTOY_MAX_CONF_REPLACE; i++) + { + replace = g_img_replace_list + i; + if (replace->magic != GRUB_IMG_REPLACE_MAGIC || replace->new_file_virtual_id >= g_virt_chunk_num) + { + continue; + } + + AsciiSPrint(TmpName, sizeof(TmpName), "%s", Name); + for (j = 0; j < replace->old_file_cnt; j++) + { + AsciiStrCpyS(OldName, sizeof(OldName), replace->old_file_name[j]); + if ((0 == AsciiStrCmp(OldName, TmpName)) || + (AsciiStrnCmp(OldName, "\\loader\\entries\\", 16) == 0 && + AsciiStrCmp(OldName + 16, TmpName) == 0 + ) + ) + { + g_original_fclose(*New); + *New = &(g_img_file_replace[i].WrapperHandle); + ventoy_wrapper_file_procotol(*New, TRUE, i); + + virt = g_virt_chunk + replace->new_file_virtual_id; + + Sectors = (virt->mem_sector_end - virt->mem_sector_start) + (virt->remap_sector_end - virt->remap_sector_start); + + g_img_file_replace[i].BlockIoSectorStart = virt->mem_sector_start; + g_img_file_replace[i].FileSizeBytes = Sectors * 2048; + + if (gDebugPrint) + { + debug("## ventoy_wrapper_file_open2 <%s> BlockStart:%lu Sectors:%lu Bytes:%lu", Name, + g_img_file_replace[i].BlockIoSectorStart, Sectors, Sectors * 2048); + sleep(3); + } + + return Status; + } + } + } + + if (g_img_replace_list && StrCmp(Name, L"\\loader\\entries") == 0) + { + (*New)->Open = ventoy_wrapper_file_open; + } + + return Status; +} + +EFI_STATUS EFIAPI ventoy_wrapper_open_volume +( + IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **Root +) +{ + EFI_STATUS Status = EFI_SUCCESS; + + Status = g_original_open_volume(This, Root); + if (!EFI_ERROR(Status)) + { + g_original_fopen = (*Root)->Open; + g_original_fclose = (*Root)->Close; + (*Root)->Open = ventoy_wrapper_file_open; + } + + return Status; +} + +EFI_STATUS EFIAPI ventoy_wrapper_push_openvolume(IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME OpenVolume) +{ + g_original_open_volume = OpenVolume; + return EFI_SUCCESS; +} + +#if 0 +/* For auto skip Windows 'Press any key to boot from CD or DVD ...' */ +#endif + +STATIC EFI_STATUS EFIAPI ventoy_wrapper_read_key_ex +( + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + OUT EFI_KEY_DATA *KeyData +) +{ + /* only hook once before BCD file read */ + if (g_keyboard_hook_count == 0 && g_blockio_bcd_read_done == FALSE) + { + g_keyboard_hook_count++; + + KeyData->Key.ScanCode = SCAN_DELETE; + KeyData->Key.UnicodeChar = 0; + KeyData->KeyState.KeyShiftState = 0; + KeyData->KeyState.KeyToggleState = 0; + + return EFI_SUCCESS; + } + + return g_org_read_key_ex(This, KeyData); +} + +EFI_STATUS EFIAPI ventoy_wrapper_read_key +( + IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, + OUT EFI_INPUT_KEY *Key +) +{ + /* only hook once before BCD file read */ + if (g_keyboard_hook_count == 0 && g_blockio_bcd_read_done == FALSE) + { + g_keyboard_hook_count++; + + Key->ScanCode = SCAN_DELETE; + Key->UnicodeChar = 0; + return EFI_SUCCESS; + } + + return g_org_read_key(This, Key); +} + +EFI_STATUS ventoy_hook_keyboard_start(VOID) +{ + g_blockio_start_record_bcd = TRUE; + g_blockio_bcd_read_done = FALSE; + g_keyboard_hook_count = 0; + + if (g_con_simple_input_ex) + { + g_org_read_key_ex = g_con_simple_input_ex->ReadKeyStrokeEx; + g_con_simple_input_ex->ReadKeyStrokeEx = ventoy_wrapper_read_key_ex; + } + + g_org_read_key = gST->ConIn->ReadKeyStroke; + gST->ConIn->ReadKeyStroke = ventoy_wrapper_read_key; + + return EFI_SUCCESS; +} + +EFI_STATUS ventoy_hook_keyboard_stop(VOID) +{ + g_blockio_start_record_bcd = FALSE; + g_blockio_bcd_read_done = FALSE; + g_keyboard_hook_count = 0; + + if (g_con_simple_input_ex) + { + g_con_simple_input_ex->ReadKeyStrokeEx = g_org_read_key_ex; + } + + gST->ConIn->ReadKeyStroke = g_org_read_key; + + return EFI_SUCCESS; +} + +#if 0 +/* Fixup the 1st cdrom influnce for Windows boot */ +#endif + +STATIC EFI_STATUS EFIAPI ventoy_wrapper_locate_handle +( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol, OPTIONAL + IN VOID *SearchKey, OPTIONAL + IN OUT UINTN *BufferSize, + OUT EFI_HANDLE *Buffer +) +{ + UINTN i; + EFI_HANDLE Handle = NULL; + EFI_STATUS Status = EFI_SUCCESS; + + Status = g_org_locate_handle(SearchType, Protocol, SearchKey, BufferSize, Buffer); + + if (EFI_SUCCESS == Status && Protocol && CompareGuid(&gEfiBlockIoProtocolGuid, Protocol)) + { + for (i = 0; i < (*BufferSize) / sizeof(EFI_HANDLE); i++) + { + if (Buffer[i] == gBlockData.Handle) + { + Handle = Buffer[0]; + Buffer[0] = Buffer[i]; + Buffer[i] = Handle; + break; + } + } + } + + return Status; +} + +EFI_STATUS ventoy_hook_1st_cdrom_start(VOID) +{ + g_org_locate_handle = gBS->LocateHandle; + gBS->LocateHandle = ventoy_wrapper_locate_handle; + + return EFI_SUCCESS; +} + +EFI_STATUS ventoy_hook_1st_cdrom_stop(VOID) +{ + gBS->LocateHandle = g_org_locate_handle; + g_org_locate_handle = NULL; + + return EFI_SUCCESS; +} + + + +#if 0 +/* For force highest resolution for Windows/WinPE */ +#endif + + +STATIC UINT32 g_org_mode_num = 0; +STATIC EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE g_org_set_mode = NULL; + +STATIC EFI_STATUS EFIAPI ventoy_set_mode +( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN UINT32 ModeNumber +) +{ + (void)This; + (void)ModeNumber; + + /* Force highest resolution */ + return EFI_SUCCESS; +} + +STATIC EFI_STATUS EFIAPI ventoy_set_mode2 +( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN UINT32 ModeNumber +) +{ + UINTN Size; + EFI_STATUS rc; + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info = NULL; + + /* Force >= 1024x768 */ + rc = This->QueryMode(This, ModeNumber, &Size, &info); + if (rc == EFI_SUCCESS) + { + if (info->HorizontalResolution < 1024 || info->VerticalResolution < 768) + { + return EFI_SUCCESS; + } + } + + return g_org_set_mode(This, ModeNumber); +} + +EFI_STATUS ventoy_lock_res(UINT8 LockType) +{ + UINT32 i = 0; + UINT32 x = 0; + UINT32 y = 0; + UINT32 SelMode = 0; + UINT32 CurMode = 0; + UINT32 Highest = 0; + UINT32 M1024_768 = MAX_UINT32; + UINTN Size; + EFI_STATUS rc; + EFI_GRAPHICS_OUTPUT_PROTOCOL *gop = NULL; + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info = NULL; + + /* already hook */ + if (g_org_set_mode) + { + return EFI_SUCCESS; + } + + /* 1: Highest 2: 1024x768 3: >= 1024x768 */ + if (LockType == 0 || LockType > 3) + { + return EFI_SUCCESS; + } + + rc = gBS->LocateProtocol(&gEfiGraphicsOutputProtocolGuid, NULL, (void **)&gop); + if (rc != EFI_SUCCESS) + { + debug("Failed to locate GOP protocol"); + return EFI_SUCCESS; + } + + + if (LockType == 3) + { + g_org_mode_num = MAX_UINT32; + g_org_set_mode = gop->SetMode; + gop->SetMode = ventoy_set_mode2; + return EFI_SUCCESS; + } + + + CurMode = gop->Mode->Mode; + + for (i = 0 ; i < gop->Mode->MaxMode ; i++) + { + /* Get mode information */ + if (gop->QueryMode(gop, i, &Size, &info) == EFI_SUCCESS) + { + if (info->HorizontalResolution == 1024 && info->VerticalResolution == 768) + { + M1024_768 = i; + } + + if (x < info->HorizontalResolution || + (x == info->HorizontalResolution && y < info->VerticalResolution)) + { + Highest = i; + x = info->HorizontalResolution; + y = info->VerticalResolution; + } + } + } + + + if (LockType == 1) + { + SelMode = Highest; + } + else + { + if (M1024_768 == MAX_UINT32) + { + SelMode = Highest; + } + else + { + SelMode = M1024_768; + x = 1024; + y = 768; + } + } + + if (SelMode != CurMode) + { + gop->SetMode(gop, SelMode); + } + debug("Lock resolution to Mode:%d %d x %d", SelMode, x, y); + + + g_org_mode_num = CurMode; + g_org_set_mode = gop->SetMode; + gop->SetMode = ventoy_set_mode; + + return EFI_SUCCESS; +} + +EFI_STATUS ventoy_unlock_res(VOID) +{ + EFI_STATUS rc; + EFI_GRAPHICS_OUTPUT_PROTOCOL *gop = NULL; + + /* not hooked yet */ + if (!g_org_set_mode) + { + return EFI_SUCCESS; + } + + rc = gBS->LocateProtocol(&gEfiGraphicsOutputProtocolGuid, NULL, (void **)&gop); + if (rc != EFI_SUCCESS) + { + debug("Failed to locate GOP protocol"); + return EFI_SUCCESS; + } + + if (g_org_mode_num != MAX_UINT32) + { + g_org_set_mode(gop, g_org_mode_num); + } + + gop->SetMode = g_org_set_mode; + g_org_set_mode = NULL; + return EFI_SUCCESS; +} + + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/VtoyShim.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/VtoyShim.c new file mode 100644 index 0000000..216b5a3 --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/VtoyShim.c @@ -0,0 +1,665 @@ +/****************************************************************************** + * VtoyShim.c + * + * Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: BSD-2-Clause-Patent + * + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CUR_SBAT_VER 1 + +STATIC UINT8 gVtoyGrubSha256Hash[32] __attribute__((aligned(32))) = { + 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, + 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, + 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, + 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26 +}; + +STATIC BOOLEAN gGrubLaunched = FALSE; +STATIC EFI_GUID gShimLockGUID = SHIM_LOCK_GUID; +STATIC EFI_SECURITY_FILE_AUTHENTICATION_STATE gSysSecFileAuth = NULL; +STATIC EFI_SECURITY2_FILE_AUTHENTICATION gSysSec2FileAuth = NULL; +STATIC BOOLEAN gVtoyByPassSB = FALSE; /* must be FALSE by default for revoke */ +STATIC VTOY_SHIM gVtoyShimProtocol; +STATIC EFI_HANDLE gVtoyShimProtHandle; +STATIC SHIM_LOCK gShimLock; + +STATIC EFI_EXIT_BOOT_SERVICES gSysExitBootServices = NULL; +STATIC EFI_GET_VARIABLE gSysGetVariable = NULL; + +STATIC VOID EFIAPI HookSystemService(VOID); +STATIC VOID EFIAPI UnHookSystemService(VOID); + + +STATIC VOID EFIAPI VtoyLog(CONST CHAR16 *Format, ...) +{ + VA_LIST Marker; + CHAR16 Buffer[512]; + UINTN BufLen = 0; + + Buffer[0] = 0; + VA_START(Marker, Format); + BufLen = UnicodeVSPrint(Buffer, sizeof(Buffer), Format, Marker); + VA_END(Marker); + + if (gST->ConOut && gST->ConOut->OutputString) + { + gST->ConOut->OutputString(gST->ConOut, Buffer); + } +} + + +STATIC VOID EFIAPI DumpDevicePath(const EFI_DEVICE_PATH_PROTOCOL *DevicePath) +{ + CHAR16 *DPStr = NULL; + + if (DevicePath) + { + DPStr = ConvertDevicePathToText(DevicePath, TRUE, TRUE); + } + + if (DPStr) + { + vLog(L"%s", DPStr); + FreePool(DPStr); + } + else + { + vLog(L"NULL"); + } +} + +STATIC VOID EFIAPI ShowSBWarning(const EFI_DEVICE_PATH_PROTOCOL *DevicePath) +{ + vLog(L"\r\n======================================================="); + vLog(L"=======================================================\r\n"); + + DumpDevicePath(DevicePath); + + vLog(L"\r\n####### Ventoy Security Boot Violation ##########\r\n"); + + vLog(L"======================================================="); + vLog(L"======================================================="); + + VtoySleep(5); +} + + +STATIC VOID * EFIAPI FindShimFuncAddr(UINT64 FuncOffset) +{ + EFI_STATUS Status; + SHIM_IMAGE_LOADER *ImgLoader = NULL; + EFI_GUID ShimImgLoaderGuid = SHIM_IMAGE_LOADER_GUID; + + Status = gBS->LocateProtocol(&ShimImgLoaderGuid, NULL, (VOID **)&ImgLoader); + if (EFI_ERROR(Status) || !ImgLoader || !ImgLoader->LoadImage) + { + vLog(L"Failed to locate shim image loader protocol %lx %p", Status, ImgLoader); + return NULL; + } + + if (NM_SHIM_LOAD_IMAGE_OFFSET > FuncOffset) + { + return (UINT8 *)ImgLoader->LoadImage - (NM_SHIM_LOAD_IMAGE_OFFSET - FuncOffset); + } + else + { + return (UINT8 *)ImgLoader->LoadImage + (FuncOffset - NM_SHIM_LOAD_IMAGE_OFFSET); + } +} + +EFI_STATUS EFIAPI LaunchRealGrub(EFI_HANDLE ImageHandle, CONST CHAR16 *FileName) +{ + EFI_STATUS Status; + UINTN BufferSize = 0; + CHAR16 *DevDpStr = NULL; + CHAR16 *NewDpStr = NULL; + EFI_HANDLE ChildHandle = NULL; + EFI_LOADED_IMAGE_PROTOCOL *Li = NULL; + EFI_DEVICE_PATH_PROTOCOL *DeviceDP = NULL; + EFI_DEVICE_PATH_PROTOCOL *TargetDp = NULL; + + Status = gBS->HandleProtocol(ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID**)&Li); + if (EFI_ERROR(Status)) + { + vLog(L"Failed to locate loaded image protocol %lx", Status); + return Status; + } + + DeviceDP = DevicePathFromHandle(Li->DeviceHandle); + if (!DeviceDP || !IsDevicePathValid(DeviceDP, 0)) + { + vLog(L"Failed to get device path of device handle %p", Li->DeviceHandle); + Status = EFI_NOT_FOUND; + goto END; + } + + DevDpStr = ConvertDevicePathToText(DeviceDP, FALSE, TRUE); + if (!DevDpStr) + { + vLog(L"Failed to convert device path to text"); + Status = EFI_OUT_OF_RESOURCES; + goto END; + } + + BufferSize = (StrLen(DevDpStr) + 64) * sizeof(CHAR16); + NewDpStr = (CHAR16 *)AllocatePool(BufferSize); + if (!NewDpStr) + { + vLog(L"Failed to alloc new device path string buffer size:%lu", BufferSize); + Status = EFI_OUT_OF_RESOURCES; + goto END; + } + + UnicodeSPrint(NewDpStr, BufferSize, L"%s/EFI/BOOT/%s", DevDpStr, FileName); + + TargetDp = ConvertTextToDevicePath(NewDpStr); + if (!TargetDp) + { + vLog(L"Failed to convert new text <%s> to device path", NewDpStr); + Status = EFI_NOT_FOUND; + goto END; + } + + Status = gBS->LoadImage(FALSE, ImageHandle, TargetDp, NULL, 0, &ChildHandle); + if (EFI_ERROR(Status)) + { + vLog(L"Failed to LoadImage %lx", Status); + goto END; + } + + Status = gBS->StartImage(ChildHandle, NULL, NULL); + if (EFI_ERROR(Status)) + { + vLog(L"Failed to StartImage %lx", Status); + gBS->UnloadImage(ChildHandle); + goto END; + } + +END: + + CheckFreePool(DevDpStr); + CheckFreePool(NewDpStr); + CheckFreePool(TargetDp); + + return Status; +} + + +STATIC EFI_STATUS EFIAPI CheckVtoyGrub +( + VOID *FileBuffer, + UINTN FileSize +) +{ + UINT8 Sha256Hash[64]; + + if (!FileBuffer || FileSize < sizeof(EFI_IMAGE_DOS_HEADER)) + { + vErr(L"Invalid FileBuffer:%p or size:%ld", FileBuffer, FileSize); + return EFI_SECURITY_VIOLATION; + } + + ZeroMem(Sha256Hash, sizeof(Sha256Hash)); + calc_sha256(FileBuffer, (UINT64)FileSize, Sha256Hash); + + if (CompareMem(Sha256Hash, gVtoyGrubSha256Hash, 32) != 0) + { + vErr(L"Ventoy hash check failed."); + gRT->ResetSystem(EfiResetWarm, EFI_SECURITY_VIOLATION, 0, NULL); + return EFI_SECURITY_VIOLATION; + } + + return EFI_SUCCESS; +} + +STATIC EFI_STATUS EFIAPI SecurityPolicyAuth +( + const EFI_SECURITY_ARCH_PROTOCOL *This, + UINT32 AuthenticationStatus, + const EFI_DEVICE_PATH_PROTOCOL *DevicePathConst +) +{ + /* + * Some old UEFI firmware (without Security2 protocol) will hang when run OpenVolume. + * So finally I decide not to support such UEFI firmware. + * It means that for UEFI firmware before 2.5 (about 2015) Ventoy only supports Bypass policy. + * + */ + + (VOID)This; + (VOID)AuthenticationStatus; + (VOID)DevicePathConst; + return EFI_SUCCESS; +} + +STATIC EFI_STATUS EFIAPI Security2PolicyAuth +( + const EFI_SECURITY2_ARCH_PROTOCOL *This, + const EFI_DEVICE_PATH_PROTOCOL *DevicePath, + VOID *FileBuffer, + UINTN FileSize, + BOOLEAN BootPolicy +) +{ + EFI_STATUS Status; + + /* Just return OK if the user choose to bypass SB */ + if (gVtoyByPassSB) + { + return EFI_SUCCESS; + } + + if (!gGrubLaunched) + { + return CheckVtoyGrub(FileBuffer, FileSize); + } + + /* + * Step 1: + * Use original UEFI firmware auth API. + * If it's OK, it may be signed with Microsoft UEFI CA. (e.g. bootmgr/shim/...) + */ + if (gSysSec2FileAuth) + { + Status = gSysSec2FileAuth(This, DevicePath, FileBuffer, FileSize, BootPolicy); + if (!EFI_ERROR(Status)) + { + return EFI_SUCCESS; + } + } + + + /* + * Step 2: + * Use shim verify API. + * If it's OK, it may be signed with a MOK key. (e.g. Ventoy EFI files) + */ + if (gShimLock.Verify) + { + if (FileBuffer && FileSize > 0 && FileSize < 0xFFFFFFFFUL) + { + Status = gShimLock.Verify(FileBuffer, (UINT32)FileSize); + if (!EFI_ERROR(Status)) + { + return EFI_SUCCESS; + } + } + } + + ShowSBWarning(DevicePath); + + return EFI_SECURITY_VIOLATION; +} + + +STATIC EFI_STATUS EFIAPI HookSecurityPolicy(VOID) +{ + EFI_STATUS Status; + EFI_STATUS Status2; + EFI_SECURITY_ARCH_PROTOCOL *Security = NULL; + EFI_SECURITY2_ARCH_PROTOCOL *Security2 = NULL; + + Status = gBS->LocateProtocol(&gEfiSecurityArchProtocolGuid, NULL, (VOID **)&Security); + Status2 = gBS->LocateProtocol(&gEfiSecurity2ArchProtocolGuid, NULL, (VOID **)&Security2); + if (EFI_ERROR(Status) && EFI_ERROR(Status2)) + { + vLog(L"Failed to locate security or security2 protocol. %lx %lx %p %p", + Status, Status2, Security, Security2); + return EFI_NOT_FOUND; + } + + if (Security2) + { + gSysSec2FileAuth = Security2->FileAuthentication; + Security2->FileAuthentication = Security2PolicyAuth; + } + + if (Security) + { + gSysSecFileAuth = Security->FileAuthenticationState; + Security->FileAuthenticationState = SecurityPolicyAuth; + } + + return EFI_SUCCESS; +} + +STATIC VOID EFIAPI UnHookSecurityPolicy(VOID) +{ + EFI_STATUS Status; + EFI_STATUS Status2; + EFI_SECURITY_ARCH_PROTOCOL *Security = NULL; + EFI_SECURITY2_ARCH_PROTOCOL *Security2 = NULL; + + if (!gSysSec2FileAuth && !gSysSecFileAuth) + { + return; + } + + Status = gBS->LocateProtocol(&gEfiSecurityArchProtocolGuid, NULL, (VOID **)&Security); + Status2 = gBS->LocateProtocol(&gEfiSecurity2ArchProtocolGuid, NULL, (VOID **)&Security2); + if (EFI_ERROR(Status) && EFI_ERROR(Status2)) + { + vLog(L"Failed to locate security or security2 protocol. %lx %lx %p %p", + Status, Status2, Security, Security2); + return; + } + + if (Security2 && gSysSec2FileAuth && Security2->FileAuthentication == Security2PolicyAuth) + { + Security2->FileAuthentication = gSysSec2FileAuth; + gSysSec2FileAuth = NULL; + } + + if (Security && gSysSecFileAuth && Security->FileAuthenticationState == SecurityPolicyAuth) + { + Security->FileAuthenticationState = gSysSecFileAuth; + gSysSecFileAuth = NULL; + } +} + +STATIC VOID EFIAPI VtoyByPassSB(VOID) +{ + gVtoyByPassSB = TRUE; +} + +STATIC VOID EFIAPI VtoyCheckSB(VOID) +{ + gVtoyByPassSB = FALSE; +} + +STATIC VOID EFIAPI VtoyLaunched(VOID) +{ + gGrubLaunched = TRUE; +} + +STATIC VOID EFIAPI UnInstallVtoyShimProtocol(VOID) +{ + EFI_GUID Guid = VTOY_SHIM_POLICY_GUID; + + if (gVtoyShimProtHandle) + { + gBS->UninstallProtocolInterface(gVtoyShimProtHandle, &Guid, &gVtoyShimProtocol); + gVtoyShimProtHandle = NULL; + } +} + +STATIC EFI_STATUS EFIAPI InstallVtoyShimProtocol(VOID) +{ + EFI_STATUS Status; + EFI_GUID Guid = VTOY_SHIM_POLICY_GUID; + VTOY_SHIM *Prot = NULL; + + gVtoyShimProtocol.ByPassSB = VtoyByPassSB; + gVtoyShimProtocol.CheckSB = VtoyCheckSB; + gVtoyShimProtocol.Launched = VtoyLaunched; + + Status = gBS->LocateProtocol(&Guid, NULL, (VOID**)&Prot); + if (!EFI_ERROR(Status)) + { + vLog(L"Ventoy shim already loaded, cannot be nested."); + return EFI_ALREADY_STARTED; + } + + Status = gBS->InstallProtocolInterface(&gVtoyShimProtHandle, &Guid, + EFI_NATIVE_INTERFACE, &gVtoyShimProtocol); + if (EFI_ERROR(Status)) + { + vLog(L"Failed to install protocol %lx", Status); + } + + return Status; +} + +STATIC BOOLEAN EFIAPI IsSecureBootEnabled(VOID) +{ + UINT8 SecureBoot = 0; + UINTN DataSize; + EFI_STATUS Status; + + DataSize = sizeof(SecureBoot); + Status = gST->RuntimeServices->GetVariable(L"SecureBoot", &gEfiGlobalVariableGuid, NULL, + &DataSize, &SecureBoot); + if (EFI_ERROR(Status)) + { + return FALSE; + } + + return SecureBoot ? TRUE : FALSE; +} + +STATIC BOOLEAN EFIAPI IsSetupMode(VOID) +{ + UINT8 SetupMode = 0; + UINTN DataSize; + EFI_STATUS Status; + + DataSize = sizeof(SetupMode); + Status = gST->RuntimeServices->GetVariable(L"SetupMode", &gEfiGlobalVariableGuid, NULL, + &DataSize, &SetupMode); + if (EFI_ERROR(Status)) + { + return FALSE; + } + + return SetupMode ? TRUE : FALSE; +} + +STATIC EFI_STATUS EFIAPI ShimEfiMain +( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable +) +{ + EFI_STATUS Status; + SHIM_LOCK *ShimLock = NULL; + shim_void_func_pf Func1 = NULL; + shim_void_func_pf Func2 = NULL; + + /* We must be launched by shim */ + Status = gBS->LocateProtocol(&gShimLockGUID, NULL, (VOID**)&ShimLock); + if (EFI_ERROR(Status) || !ShimLock) + { + vErr(L"Failed to locate SHIM LOCK Protocol %lx", Status); + return Status; + } + + /* Backup shim Lock because we will remove it later */ + gShimLock.Verify = ShimLock->Verify; + gShimLock.Hash = ShimLock->Hash; + gShimLock.Context = ShimLock->Context; + + Status = InstallVtoyShimProtocol(); + if (EFI_ERROR(Status)) + { + vErr(L"Failed to install ventoy shim protocol"); + return Status; + } + + + /* + * IMPORTANT: All recent shim implementations hook the UEFI Boot Services + * (e.g. LoadImage, StartImage) to enforce signature verification. + * + * We must restore the original system service pointers here. If we fail to do this, + * we will be unable to launch Ventoy-signed EFI binaries or any other unsigned + * EFI applications later, even when the user has explicitly opted to disable + * all Secure Boot validation checks. + * + * To the best of my knowledge, there is no official way to remove these hooks. + * This is a tricky hack that relies on shim's internal implementation details. + * It may break in future versions of shim, and a better approach may exist. + * + */ + Func1 = FindShimFuncAddr(NM_UNHOOK_SYSTEM_SERVICES_OFFSET); + Func2 = FindShimFuncAddr(NM_UNINSTALL_SHIM_PROTOCOLS_OFFSET); + if (!Func1 || !Func2) + { + vErr(L"Can not find shim func %p %p", Func1, Func2); + Status = EFI_NOT_FOUND; + goto END; + } + + Func1(); /* call shim unhook_system_services() */ + Func2(); /* call shim uninstall_shim_protocols() */ + + HookSystemService(); + + /* Hook the system security policy */ + Status = HookSecurityPolicy(); + if (EFI_ERROR(Status)) + { + vErr(L"Failed to hook system security policy"); + goto END; + } + + + /* Finally launch Ventoy grub */ + Status = LaunchRealGrub(ImageHandle, REAL_GRUB_FILE); + if (EFI_ERROR(Status)) + { + vErr(L"Failed to finally launch real grub %s", REAL_GRUB_FILE); + goto END; + } + +END: + + /* UnHook system security policy */ + UnHookSecurityPolicy(); + + UnInstallVtoyShimProtocol(); + + UnHookSystemService(); + + return Status; +} + +EFI_STATUS EFIAPI VtoyGetVariable +( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + OUT UINT32 *Attributes, OPTIONAL + IN OUT UINTN *DataSize, + OUT VOID *Data OPTIONAL +) +{ + BOOLEAN bChk = FALSE; + EFI_STATUS Status; + + if (gVtoyByPassSB && VariableName && VendorGuid && DataSize && Data && (*DataSize) > 0) + { + bChk = TRUE; + } + + Status = gSysGetVariable(VariableName, VendorGuid, Attributes, DataSize, Data); + if (bChk && (!EFI_ERROR(Status))) + { + if (CompareMem(&gShimLockGUID, VendorGuid, 16) == 0 && + StrCmp(VariableName, L"MokSBState") == 0) + { + *(UINT8 *)Data = 1; + } + } + + return Status; +} + +STATIC VOID EFIAPI UnHookSystemService(VOID) +{ + if (gSysExitBootServices) + { + gBS->ExitBootServices = gSysExitBootServices; + gSysExitBootServices = NULL; + } + + if (gSysGetVariable) + { + gST->RuntimeServices->GetVariable = gSysGetVariable; + gSysGetVariable = NULL; + } +} + + +STATIC EFI_STATUS EFIAPI VtoyExitBootServices +( + IN EFI_HANDLE ImageHandle, + IN UINTN MapKey +) +{ + EFI_EXIT_BOOT_SERVICES SysExitBS; + + /* UnHookSystemService will set gSysExitBootServices NULL */ + SysExitBS = gSysExitBootServices; + + UnHookSecurityPolicy(); + UnInstallVtoyShimProtocol(); + UnHookSystemService(); + + return SysExitBS(ImageHandle, MapKey); +} + +STATIC VOID EFIAPI HookSystemService(VOID) +{ + gSysExitBootServices = gBS->ExitBootServices; + gBS->ExitBootServices = VtoyExitBootServices; + + gSysGetVariable = gST->RuntimeServices->GetVariable; + gST->RuntimeServices->GetVariable = VtoyGetVariable; +} + +EFI_STATUS EFIAPI VtoyShimEfiMain +( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable +) +{ + BOOLEAN IsSetup = FALSE; + BOOLEAN IsSecureBoot = FALSE; + EFI_STATUS Status; + + IsSetup = IsSetupMode(); + IsSecureBoot = IsSecureBootEnabled(); + + if (!IsSecureBoot || IsSetup) + { + /* If secure boot is not enabled or in SetupMode, nothing needed, just launch Ventoy grub */ + Status = LaunchRealGrub(ImageHandle, REAL_GRUB_FILE); + if (EFI_ERROR(Status)) + { + vErr(L"Failed to launch %s", REAL_GRUB_FILE); + } + } + else + { + Status = ShimEfiMain(ImageHandle, SystemTable); + } + + return Status; +} + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/VtoyShim.h b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/VtoyShim.h new file mode 100644 index 0000000..6f2d62e --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/VtoyShim.h @@ -0,0 +1,116 @@ +/****************************************************************************** + * VtoyShim.h + * + * Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: BSD-2-Clause-Patent + * + */ + +#ifndef __VTOYSHIM_H__ +#define __VTOYSHIM_H__ + +#if defined (MDE_CPU_IA32) +#define REAL_GRUB_FILE L"grubia32_real.efi" +#elif defined (MDE_CPU_X64) +#define REAL_GRUB_FILE L"grubx64_real.efi" +#elif defined (MDE_CPU_AARCH64) +#define REAL_GRUB_FILE L"grubaa64_real.efi" +#else +#error "Not supported now" +#endif + + +/* The following definations are copied from shim source code */ + +#define SHIM_LOCK_GUID {0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } }; + +typedef +EFI_STATUS +(*EFI_SHIM_LOCK_VERIFY) ( + IN VOID *buffer, + IN UINT32 size + ); + +typedef +EFI_STATUS +(*EFI_SHIM_LOCK_HASH) ( + IN char *data, + IN int datasize, + PE_COFF_LOADER_IMAGE_CONTEXT *context, + UINT8 *sha256hash, + UINT8 *sha1hash + ); + +typedef +EFI_STATUS +(*EFI_SHIM_LOCK_CONTEXT) ( + IN VOID *data, + IN unsigned int datasize, + PE_COFF_LOADER_IMAGE_CONTEXT *context + ); + +typedef struct _SHIM_LOCK { + EFI_SHIM_LOCK_VERIFY Verify; + EFI_SHIM_LOCK_HASH Hash; + EFI_SHIM_LOCK_CONTEXT Context; +} SHIM_LOCK; + + + +#define SHIM_IMAGE_LOADER_GUID {0x1f492041, 0xfadb, 0x4e59, {0x9e, 0x57, 0x7c, 0xaf, 0xe7, 0x3a, 0x55, 0xab } } + +typedef struct _SHIM_IMAGE_LOADER { + EFI_IMAGE_LOAD LoadImage; + EFI_IMAGE_START StartImage; + EFI_EXIT Exit; + EFI_IMAGE_UNLOAD UnloadImage; +} SHIM_IMAGE_LOADER; + +typedef VOID (*shim_void_func_pf)(VOID); + + +/* + * The two offset here are extract from the shim file which used in Ventoy. + * nm BOOTX64.EFI | grep shim_load_image + * nm BOOTX64.EFI | grep unhook_system_services + * nm BOOTX64.EFI | grep uninstall_shim_protocols + * + * It means that they must be updated every time Ventoy update the shim file. + * + */ +#define NM_SHIM_LOAD_IMAGE_OFFSET 0x2dc12 +#define NM_UNHOOK_SYSTEM_SERVICES_OFFSET 0x2e278 +#define NM_UNINSTALL_SHIM_PROTOCOLS_OFFSET 0x26264 + + + + +#define VtoySleep(sec) gBS->Stall(1000000 * (sec)) +#define vLog(fmt, ...) VtoyLog(fmt "\r\n", ##__VA_ARGS__) +#define vErr(fmt, ...) VtoyLog(fmt "\r\n", ##__VA_ARGS__); VtoySleep(5) +#define vDbg(fmt, ...) VtoyLog(fmt "\r\n", ##__VA_ARGS__); VtoySleep(2) + +#define CheckFreePool(p) \ +do { \ + if (p) { \ + FreePool(p); \ + (p) = NULL; \ + }\ +} while (0) + + +#define VTOY_SHIM_POLICY_GUID {0x90a29d14, 0x3968, 0x48fe, { 0x85, 0x81, 0x6b, 0x7f, 0x7d, 0xc4, 0x70, 0x55 }}; + +typedef VOID (EFIAPI *VTOY_BYPASS_SB)(VOID); +typedef VOID (EFIAPI *VTOY_CHECK_SB)(VOID); +typedef VOID (EFIAPI *VTOY_LAUNCHED)(VOID); +typedef struct _VTOY_SHIM{ + VTOY_BYPASS_SB ByPassSB; + VTOY_BYPASS_SB CheckSB; + VTOY_LAUNCHED Launched; +} VTOY_SHIM; + +void calc_sha256(const void *data, UINT64 len, void *output); + +#endif + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/VtoyShim.inf b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/VtoyShim.inf new file mode 100644 index 0000000..6cce933 --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/VtoyShim.inf @@ -0,0 +1,84 @@ +#************************************************************************************ +# Copyright (c) 2026, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = VtoyShim + FILE_GUID = 6d7c7406-b32c-461f-8454-ddaa5243d93d + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + ENTRY_POINT = VtoyShimEfiMain + +[BuildOptions] + # Force standard GNU ld to pack and align ELF segments to 4KB page boundaries + GCC:*_*_*_DLINK_FLAGS = -Wl,-z,common-page-size=0x1000 -Wl,-z,max-page-size=0x1000 + +[Sources] + VtoyShim.h + VtoyShim.c + sha256.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ShellPkg/ShellPkg.dec + +[LibraryClasses] + UefiApplicationEntryPoint + UefiLib + DevicePathLib + DebugLib + +[Guids] + gEfiGlobalVariableGuid + gShellVariableGuid + gEfiVirtualCdGuid + gEfiFileInfoGuid + +[Protocols] + gEfiSecurityArchProtocolGuid + gEfiSecurity2ArchProtocolGuid + gEfiLoadedImageProtocolGuid + gEfiBlockIoProtocolGuid + gEfiDevicePathProtocolGuid + gEfiDevicePathToTextProtocolGuid + gEfiDevicePathFromTextProtocolGuid + gEfiSimpleFileSystemProtocolGuid + gEfiRamDiskProtocolGuid + gEfiAbsolutePointerProtocolGuid + gEfiAcpiTableProtocolGuid + gEfiBlockIo2ProtocolGuid + gEfiBusSpecificDriverOverrideProtocolGuid + gEfiComponentNameProtocolGuid + gEfiComponentName2ProtocolGuid + gEfiDriverBindingProtocolGuid + gEfiDiskIoProtocolGuid + gEfiDiskIo2ProtocolGuid + gEfiGraphicsOutputProtocolGuid + gEfiHiiConfigAccessProtocolGuid + gEfiHiiFontProtocolGuid + gEfiLoadFileProtocolGuid + gEfiLoadFile2ProtocolGuid + gEfiLoadedImageProtocolGuid + gEfiLoadedImageDevicePathProtocolGuid + gEfiPciIoProtocolGuid + gEfiSerialIoProtocolGuid + gEfiSimpleTextInProtocolGuid + gEfiSimpleTextInputExProtocolGuid + gEfiSimpleTextOutProtocolGuid + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/sbat.csv b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/sbat.csv new file mode 100644 index 0000000..6f07aa0 --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/sbat.csv @@ -0,0 +1,2 @@ +sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md +ventoy-shim,1,Ventoy,ventoy-shim,1.0,https://www.ventoy.net/ \ No newline at end of file diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/sha256.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/sha256.c new file mode 100644 index 0000000..eb2e2a2 --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/sha256.c @@ -0,0 +1,170 @@ +/****************************************************************************** + * VtoyShim.c + * + * Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: BSD-2-Clause-Patent + * + */ + +#include +#include +#include +#include +#include + + +static const UINT32 sha256_initial_h[8] + = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, + 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 }; + +static const UINT32 sha256_round_k[64] + = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, + 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, + 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, + 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, + 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, + 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 }; + +static void sha256_endian_reverse64(UINT64 input, UINT8 *output) { + output[7] = (input >> 0) & 0xff; + output[6] = (input >> 8) & 0xff; + output[5] = (input >> 16) & 0xff; + output[4] = (input >> 24) & 0xff; + output[3] = (input >> 32) & 0xff; + output[2] = (input >> 40) & 0xff; + output[1] = (input >> 48) & 0xff; + output[0] = (input >> 56) & 0xff; +} + +static UINT32 sha256_endian_read32(UINT8 *input) { + UINT32 output = 0; + output |= (input[0] << 24); + output |= (input[1] << 16); + output |= (input[2] << 8); + output |= (input[3] << 0); + + return output; +} + +static void sha256_endian_reverse32(UINT32 input, UINT8 *output) { + output[3] = (input >> 0) & 0xff; + output[2] = (input >> 8) & 0xff; + output[1] = (input >> 16) & 0xff; + output[0] = (input >> 24) & 0xff; +} + +static UINT32 sha256_ror(UINT32 input, UINT32 by) { + return (input >> by) | (((input & ((1 << by) - 1))) << (32 - by)); +} + +void calc_sha256(const void *data, UINT64 len, void *output) +{ + int i = 0; + int j = 0; + UINT8 padding[80]; + UINT64 current = (len + 1) % 64; + // want to be == 56 % 64. + UINT64 needed = (64 + 56 - current) % 64; + UINT64 extra = needed + 9; + UINT64 total = len + extra; + UINT32 v[8]; + UINT64 cursor = 0; + + for(i = 1; i < 80; i++) + { + padding[i] = 0; + } + padding[0] = 0x80; + + sha256_endian_reverse64(len * 8, padding + total - len - 8); + + for(i = 0; i < 8; i++) + { + v[i] = sha256_initial_h[i]; + } + + for(cursor = 0; cursor * 64 < total; cursor++) + { + UINT32 t[8]; + UINT32 w[64]; + + for(i = 0; i < 8; i++) + { + t[i] = v[i]; + } + + + if(cursor * 64 + 64 <= len) + { + for(j = 0; j < 16; j++) + { + w[j] = sha256_endian_read32((UINT8 *)data + cursor * 64 + j * 4); + } + } + else + { + if(cursor * 64 < len) + { + UINT64 size = len - cursor * 64; + if(size > 0) + { + CopyMem(w, (UINT8 *)data + cursor * 64, size); + } + CopyMem((UINT8 *)w + size, padding, 64 - size); + } + else + { + UINT64 off = (cursor * 64 - len) % 64; + CopyMem((UINT8 *)w, padding + off, 64); + } + + for(j = 0; j < 16; j++) + { + w[j] = sha256_endian_read32((UINT8 *)&w[j]); + } + } + + for(j = 16; j < 64; j++) + { + UINT32 s1 = sha256_ror(w[j - 2], 17) ^ sha256_ror(w[j - 2], 19) ^ (w[j - 2] >> 10); + UINT32 s0 = sha256_ror(w[j - 15], 7) ^ sha256_ror(w[j - 15], 18) ^ (w[j - 15] >> 3); + w[j] = s1 + w[j - 7] + s0 + w[j - 16]; + } + + for(j = 0; j < 64; j++) + { + UINT32 ch = (t[4] & t[5]) ^ (~t[4] & t[6]); + UINT32 maj = (t[0] & t[1]) ^ (t[0] & t[2]) ^ (t[1] & t[2]); + UINT32 S0 = sha256_ror(t[0], 2) ^ sha256_ror(t[0], 13) ^ sha256_ror(t[0], 22); + UINT32 S1 = sha256_ror(t[4], 6) ^ sha256_ror(t[4], 11) ^ sha256_ror(t[4], 25); + UINT32 t1 = t[7] + S1 + ch + sha256_round_k[j] + w[j]; + UINT32 t2 = S0 + maj; + + t[7] = t[6]; + t[6] = t[5]; + t[5] = t[4]; + t[4] = t[3] + t1; + t[3] = t[2]; + t[2] = t[1]; + t[1] = t[0]; + t[0] = t1 + t2; + } + + for(i = 0; i < 8; i++) + { + v[i] += t[i]; + } + } + + for(i = 0; i < 8; i++) + { + sha256_endian_reverse32(v[i], (UINT8 *)output + i * 4); + } +} + + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/Memhole.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/Memhole.c new file mode 100644 index 0000000..715d7bc --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/Memhole.c @@ -0,0 +1,179 @@ +/****************************************************************************** + * Memhole.c + * + * Copyright (c) 2020, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +STATIC BOOLEAN IsMemContiguous +( + IN CONST EFI_MEMORY_DESCRIPTOR *Prev, + IN CONST EFI_MEMORY_DESCRIPTOR *Curr, + IN CONST EFI_MEMORY_DESCRIPTOR *Next +) +{ + UINTN Addr1 = 0; + UINTN Addr2 = 0; + + if (Prev == NULL || Curr == NULL || Next == NULL) + { + return FALSE; + } + + if (Prev->Type == EfiBootServicesData && + Curr->Type == EfiConventionalMemory && + Next->Type == EfiBootServicesData) + { + Addr1 = Prev->PhysicalStart + MultU64x64(SIZE_4KB, Prev->NumberOfPages); + Addr2 = Curr->PhysicalStart + MultU64x64(SIZE_4KB, Curr->NumberOfPages); + + if (Addr1 == Curr->PhysicalStart && Addr2 == Next->PhysicalStart) + { + return TRUE; + } + } + + return FALSE; +} + +STATIC EFI_MEMORY_DESCRIPTOR* GetMemDesc +( + OUT UINTN *pSize, + OUT UINTN *pItemSize, + OUT UINTN *pDescCount +) +{ + UINTN Size = 0; + UINTN MapKey = 0; + UINTN ItemSize = 0; + UINTN DescCount = 0; + UINT32 Version = 0; + EFI_STATUS Status = EFI_SUCCESS; + EFI_MEMORY_DESCRIPTOR *pDesc = NULL; + EFI_MEMORY_DESCRIPTOR *Curr = NULL; + + Status = gBS->GetMemoryMap(&Size, pDesc, &MapKey, &ItemSize, &Version); + if (EFI_BUFFER_TOO_SMALL != Status) + { + debug("GetMemoryMap: %r", Status); + return NULL; + } + + Size += SIZE_1KB; + pDesc = AllocatePool(Size); + if (!pDesc) + { + debug("AllocatePool: %lu failed", Size); + return NULL; + } + + ZeroMem(pDesc, Size); + + Status = gBS->GetMemoryMap(&Size, pDesc, &MapKey, &ItemSize, &Version); + if (EFI_ERROR(Status)) + { + debug("GetMemoryMap: %r", Status); + FreePool(pDesc); + return NULL; + } + + Curr = pDesc; + while (Curr && Curr < (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)pDesc + Size)) + { + DescCount++; + Curr = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)Curr + ItemSize); + } + + *pSize = Size; + *pItemSize = ItemSize; + *pDescCount = DescCount; + + debug("GetMemoryMap: ItemSize:%lu Count:%lu", ItemSize, DescCount); + + return pDesc; +} + +EFI_STATUS FixWindowsMemhole(IN EFI_HANDLE ImageHandle, IN CONST CHAR16 *CmdLine) +{ + UINTN Size = 0; + UINTN ItemSize = 0; + UINTN DescCount = 0; + UINTN TotalMem = 0; + EFI_STATUS Status = EFI_SUCCESS; + EFI_PHYSICAL_ADDRESS AllocAddr = 0; + EFI_MEMORY_DESCRIPTOR *pDescs = NULL; + EFI_MEMORY_DESCRIPTOR *Prev = NULL; + EFI_MEMORY_DESCRIPTOR *Next = NULL; + EFI_MEMORY_DESCRIPTOR *Curr = NULL; + + (VOID)ImageHandle; + (VOID)CmdLine; + + pDescs = GetMemDesc(&Size, &ItemSize, &DescCount); + if (!pDescs) + { + return EFI_NOT_FOUND; + } + + if (DescCount < 500) + { + FreePool(pDescs); + Printf("There is no need to fixup (%lu)\n", DescCount); + return EFI_SUCCESS; + } + + Curr = pDescs; + while ((UINT8 *)Curr < (UINT8 *)pDescs + Size) + { + Next = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)Curr + ItemSize); + + if (IsMemContiguous(Prev, Curr, Next)) + { + AllocAddr = Curr->PhysicalStart; + Status = gBS->AllocatePages(AllocateAddress, EfiBootServicesData, Curr->NumberOfPages, &AllocAddr); + if (EFI_SUCCESS == Status) + { + TotalMem += MultU64x64(SIZE_4KB, Curr->NumberOfPages); + } + } + + Prev = Curr; + Curr = Next; + } + + Printf("Fixup Windows mmap issue OK (%lu)\n", TotalMem); + + return EFI_SUCCESS; +} + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyDrv.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyDrv.c new file mode 100644 index 0000000..7886d66 --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyDrv.c @@ -0,0 +1,140 @@ +/****************************************************************************** + * VtoyDrv.c + * + * Copyright (c) 2020, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +STATIC UINTN g_EfiDriverNameCnt = 0; +STATIC CHAR16 *g_EfiDriverNameList[1024] = { NULL }; + +STATIC EFI_STATUS AddEfiDriverName(IN CHAR16 *DriverName) +{ + UINTN i = 0; + + if (g_EfiDriverNameCnt >= 1024) + { + return EFI_OUT_OF_RESOURCES; + } + + for (i = 0; i < g_EfiDriverNameCnt; i++) + { + if (g_EfiDriverNameList[i] && StrCmp(g_EfiDriverNameList[i], DriverName) == 0) + { + break; + } + } + + if (i >= g_EfiDriverNameCnt) + { + g_EfiDriverNameList[g_EfiDriverNameCnt] = DriverName; + g_EfiDriverNameCnt++; + } + + return EFI_SUCCESS; +} + +EFI_STATUS ShowEfiDrivers(IN EFI_HANDLE ImageHandle, IN CONST CHAR16 *CmdLine) +{ + UINTN i = 0; + UINTN Count = 0; + CHAR16 *DriverName = NULL; + EFI_HANDLE *Handles = NULL; + EFI_STATUS Status = EFI_SUCCESS; + EFI_COMPONENT_NAME_PROTOCOL *NameProtocol = NULL; + EFI_COMPONENT_NAME2_PROTOCOL *Name2Protocol = NULL; + + (VOID)ImageHandle; + (VOID)CmdLine; + + Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiComponentName2ProtocolGuid, + NULL, &Count, &Handles); + if (EFI_ERROR(Status)) + { + return Status; + } + + for (i = 0; i < Count; i++) + { + Status = gBS->HandleProtocol(Handles[i], &gEfiComponentName2ProtocolGuid, (VOID **)&Name2Protocol); + if (EFI_ERROR(Status)) + { + continue; + } + + DriverName = NULL; + Status = VtoyGetComponentName(2, Name2Protocol, &DriverName); + if ((!EFI_ERROR(Status)) && (DriverName)) + { + AddEfiDriverName(DriverName); + } + } + + Count = 0; + FreePool(Handles); + Handles = NULL; + + Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiComponentNameProtocolGuid, + NULL, &Count, &Handles); + if (EFI_ERROR(Status)) + { + return Status; + } + + for (i = 0; i < Count; i++) + { + Status = gBS->HandleProtocol(Handles[i], &gEfiComponentNameProtocolGuid, (VOID **)&NameProtocol); + if (EFI_ERROR(Status)) + { + continue; + } + + DriverName = NULL; + Status = VtoyGetComponentName(1, Name2Protocol, &DriverName); + if ((!EFI_ERROR(Status)) && (DriverName)) + { + AddEfiDriverName(DriverName); + } + } + + FreePool(Handles); + + for (i = 0; i < g_EfiDriverNameCnt; i++) + { + Printf("%2d %s\n", i, g_EfiDriverNameList[i]); + } + + return EFI_SUCCESS; +} + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.c new file mode 100644 index 0000000..9b1b14a --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.c @@ -0,0 +1,178 @@ +/****************************************************************************** + * VtoyUtil.c + * + * Copyright (c) 2020, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +BOOLEAN gVtoyDebugPrint = FALSE; +STATIC CONST CHAR16 *gCurFeature= NULL; +STATIC CHAR16 *gCmdLine = NULL; +STATIC grub_env_printf_pf g_env_printf = NULL; + +STATIC VtoyUtilFeature gFeatureList[] = +{ + { L"fix_windows_mmap", FixWindowsMemhole }, + { L"show_efi_drivers", ShowEfiDrivers }, +}; + +EFI_STATUS VtoyGetComponentName(IN UINTN Ver, IN VOID *Protocol, OUT CHAR16 **DriverName) +{ + EFI_STATUS Status = EFI_SUCCESS; + CHAR16 *DrvName = NULL; + EFI_COMPONENT_NAME_PROTOCOL *NameProtocol = NULL; + EFI_COMPONENT_NAME2_PROTOCOL *Name2Protocol = NULL; + + if (1 == Ver) + { + NameProtocol = (EFI_COMPONENT_NAME_PROTOCOL *)Protocol; + Status = NameProtocol->GetDriverName(Protocol, "en", &DrvName); + if (EFI_ERROR(Status) || NULL == DrvName) + { + Status = NameProtocol->GetDriverName(Protocol, "eng", &DrvName); + } + } + else + { + Name2Protocol = (EFI_COMPONENT_NAME2_PROTOCOL *)Protocol; + Status = Name2Protocol->GetDriverName(Protocol, "en", &DrvName); + if (EFI_ERROR(Status) || NULL == DrvName) + { + Status = Name2Protocol->GetDriverName(Protocol, "eng", &DrvName); + } + } + + *DriverName = DrvName; + return Status; +} + +VOID EFIAPI VtoyUtilDebug(IN CONST CHAR8 *Format, ...) +{ + VA_LIST Marker; + CHAR8 Buffer[512]; + + VA_START (Marker, Format); + AsciiVSPrint(Buffer, sizeof(Buffer), Format, Marker); + VA_END (Marker); + + if (g_env_printf) + { + g_env_printf("%s", Buffer); + } +} + +STATIC EFI_STATUS ParseCmdline(IN EFI_HANDLE ImageHandle) +{ + CHAR16 *pPos = NULL; + CHAR16 *pCmdLine = NULL; + EFI_STATUS Status = EFI_SUCCESS; + ventoy_grub_param *pGrubParam = NULL; + EFI_LOADED_IMAGE_PROTOCOL *pImageInfo = NULL; + + Status = gBS->HandleProtocol(ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&pImageInfo); + if (EFI_ERROR(Status)) + { + return Status; + } + + pCmdLine = (CHAR16 *)AllocatePool(pImageInfo->LoadOptionsSize + 4); + SetMem(pCmdLine, pImageInfo->LoadOptionsSize + 4, 0); + CopyMem(pCmdLine, pImageInfo->LoadOptions, pImageInfo->LoadOptionsSize); + + if (StrStr(pCmdLine, L"vtoyefitest")) + { + gST->ConOut->OutputString(gST->ConOut, L"\r\n##########################"); + gST->ConOut->OutputString(gST->ConOut, L"\r\n######### VTOY #########"); + gST->ConOut->OutputString(gST->ConOut, L"\r\n##########################"); + return EFI_SUCCESS; + } + + if (StrStr(pCmdLine, L"debug")) + { + gVtoyDebugPrint = TRUE; + } + + pPos = StrStr(pCmdLine, L"env_param="); + if (!pPos) + { + return EFI_INVALID_PARAMETER; + } + + pGrubParam = (ventoy_grub_param *)StrHexToUintn(pPos + StrLen(L"env_param=")); + g_env_printf = pGrubParam->grub_env_printf; + + pPos = StrStr(pCmdLine, L"feature="); + if (!pPos) + { + return EFI_INVALID_PARAMETER; + } + + gCurFeature = pPos + StrLen(L"feature="); + + gCmdLine = pCmdLine; + + return EFI_SUCCESS; +} + +EFI_STATUS EFIAPI VtoyUtilEfiMain +( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable +) +{ + UINTN i; + UINTN Len; + + ParseCmdline(ImageHandle); + + for (i = 0; gCurFeature && i < ARRAY_SIZE(gFeatureList); i++) + { + Len = StrLen(gFeatureList[i].Cmd); + if (StrnCmp(gFeatureList[i].Cmd, gCurFeature, Len) == 0) + { + debug("Find main proc <%s>", gFeatureList[i].Cmd); + gFeatureList[i].MainProc(ImageHandle, gCurFeature + Len); + break; + } + } + + if (gCmdLine) + { + FreePool(gCmdLine); + gCmdLine = NULL; + } + + return EFI_SUCCESS; +} + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.h b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.h new file mode 100644 index 0000000..5e228be --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.h @@ -0,0 +1,70 @@ +/****************************************************************************** + * VtoyUtil.h + * + * Copyright (c) 2020, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#ifndef __VTOYUTIL_H__ +#define __VTOYUTIL_H__ + +#define VTOY_SHIM_POLICY_GUID {0x90a29d14, 0x3968, 0x48fe, { 0x85, 0x81, 0x6b, 0x7f, 0x7d, 0xc4, 0x70, 0x55 }}; + +#pragma pack(1) + +typedef EFI_STATUS (*VTOY_UTIL_PROC_PF)(IN EFI_HANDLE ImageHandle, IN CONST CHAR16 *CmdLine); +typedef int (*grub_env_set_pf)(const char *name, const char *val); +typedef const char * (*grub_env_get_pf)(const char *name); +typedef int (*grub_env_printf_pf)(const char *fmt, ...); + +#define VTOY_MAX_CONF_REPLACE 2 + +typedef struct ventoy_grub_param_file_replace +{ + UINT32 magic; + char old_file_name[4][256]; + UINT32 old_file_cnt; + UINT32 new_file_virtual_id; +}ventoy_grub_param_file_replace; + +typedef struct ventoy_grub_param +{ + grub_env_get_pf grub_env_get; + grub_env_set_pf grub_env_set; + ventoy_grub_param_file_replace file_replace; + ventoy_grub_param_file_replace img_replace[VTOY_MAX_CONF_REPLACE]; + grub_env_printf_pf grub_env_printf; +}ventoy_grub_param; +#pragma pack() + + +typedef struct VtoyUtilFeature +{ + CONST CHAR16 *Cmd; + VTOY_UTIL_PROC_PF MainProc; +}VtoyUtilFeature; + +extern BOOLEAN gVtoyDebugPrint; +VOID EFIAPI VtoyUtilDebug(IN CONST CHAR8 *Format, ...); +#define debug(expr, ...) if (gVtoyDebugPrint) VtoyUtilDebug("[VTOY] "expr"\n", ##__VA_ARGS__) +#define Printf VtoyUtilDebug + +EFI_STATUS VtoyGetComponentName(IN UINTN Ver, IN VOID *Protocol, OUT CHAR16 **DriverName); +EFI_STATUS FixWindowsMemhole(IN EFI_HANDLE ImageHandle, IN CONST CHAR16 *CmdLine); +EFI_STATUS ShowEfiDrivers(IN EFI_HANDLE ImageHandle, IN CONST CHAR16 *CmdLine); + +#endif + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.inf b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.inf new file mode 100644 index 0000000..1100c75 --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.inf @@ -0,0 +1,84 @@ +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = VtoyUtil + FILE_GUID = a43466a0-68c6-469d-ba4b-678bbe90bc47 + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + ENTRY_POINT = VtoyUtilEfiMain + +[BuildOptions] + # Force standard GNU ld to pack and align ELF segments to 4KB page boundaries + GCC:*_*_*_DLINK_FLAGS = -Wl,-z,common-page-size=0x1000 -Wl,-z,max-page-size=0x1000 + +[Sources] + VtoyUtil.h + VtoyUtil.c + VtoyDrv.c + Memhole.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ShellPkg/ShellPkg.dec + +[LibraryClasses] + UefiApplicationEntryPoint + UefiLib + DebugLib + +[Guids] + gShellVariableGuid + gEfiVirtualCdGuid + gEfiFileInfoGuid + +[Protocols] + gEfiLoadedImageProtocolGuid + gEfiBlockIoProtocolGuid + gEfiDevicePathProtocolGuid + gEfiSimpleFileSystemProtocolGuid + gEfiRamDiskProtocolGuid + gEfiAbsolutePointerProtocolGuid + gEfiAcpiTableProtocolGuid + gEfiBlockIo2ProtocolGuid + gEfiBusSpecificDriverOverrideProtocolGuid + gEfiComponentNameProtocolGuid + gEfiComponentName2ProtocolGuid + gEfiDriverBindingProtocolGuid + gEfiDiskIoProtocolGuid + gEfiDiskIo2ProtocolGuid + gEfiGraphicsOutputProtocolGuid + gEfiHiiConfigAccessProtocolGuid + gEfiHiiFontProtocolGuid + gEfiLoadFileProtocolGuid + gEfiLoadFile2ProtocolGuid + gEfiLoadedImageProtocolGuid + gEfiLoadedImageDevicePathProtocolGuid + gEfiPciIoProtocolGuid + gEfiSerialIoProtocolGuid + gEfiSimpleTextInProtocolGuid + gEfiSimpleTextInputExProtocolGuid + gEfiSimpleTextOutProtocolGuid + + + + + + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/MdeModulePkg.dsc b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/MdeModulePkg.dsc new file mode 100644 index 0000000..66172f2 --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/MdeModulePkg.dsc @@ -0,0 +1,499 @@ +## @file +# EFI/PI Reference Module Package for All Architectures +# +# (C) Copyright 2014 Hewlett-Packard Development Company, L.P.
+# Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + PLATFORM_NAME = MdeModule + PLATFORM_GUID = 587CE499-6CBE-43cd-94E2-186218569478 + PLATFORM_VERSION = 0.98 + DSC_SPECIFICATION = 0x00010005 + OUTPUT_DIRECTORY = Build/MdeModule + SUPPORTED_ARCHITECTURES = IA32|X64|EBC|ARM|AARCH64 + BUILD_TARGETS = DEBUG|RELEASE|NOOPT + SKUID_IDENTIFIER = DEFAULT + +[LibraryClasses] + # + # Entry point + # + PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf + PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf + DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf + UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf + UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf + # + # Basic + # + BaseLib|MdePkg/Library/BaseLib/BaseLib.inf + BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf + SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf + IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf + PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf + PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf + PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf + CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf + PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf + SortLib|MdeModulePkg/Library/BaseSortLib/BaseSortLib.inf + # + # UEFI & PI + # + UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf + UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf + UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf + UefiLib|MdePkg/Library/UefiLib/UefiLib.inf + UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf + HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf + DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf + PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf + PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf + DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf + DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf + UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf + # + # Generic Modules + # + UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf + UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf + SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf + TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf + SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf + CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf + FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf + # + # Misc + # + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf + DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf + ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf + PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf + DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf + PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf + ResetSystemLib|MdeModulePkg/Library/BaseResetSystemLibNull/BaseResetSystemLibNull.inf + SmbusLib|MdePkg/Library/DxeSmbusLib/DxeSmbusLib.inf + S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf + CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf + PlatformBootManagerLib|MdeModulePkg/Library/PlatformBootManagerLibNull/PlatformBootManagerLibNull.inf + PciHostBridgeLib|MdeModulePkg/Library/PciHostBridgeLibNull/PciHostBridgeLibNull.inf + TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf + AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf + VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf + FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf + NonDiscoverableDeviceRegistrationLib|MdeModulePkg/Library/NonDiscoverableDeviceRegistrationLib/NonDiscoverableDeviceRegistrationLib.inf + + FmpAuthenticationLib|MdeModulePkg/Library/FmpAuthenticationLibNull/FmpAuthenticationLibNull.inf + CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf + BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf + SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf + DisplayUpdateProgressLib|MdeModulePkg/Library/DisplayUpdateProgressLibGraphics/DisplayUpdateProgressLibGraphics.inf + +[LibraryClasses.EBC.PEIM] + IoLib|MdePkg/Library/PeiIoLibCpuIo/PeiIoLibCpuIo.inf + +[LibraryClasses.common.PEI_CORE] + HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf + MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf + +[LibraryClasses.common.PEIM] + HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf + MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf + ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf + LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf + +[LibraryClasses.common.DXE_CORE] + HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf + MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf + ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf + +[LibraryClasses.common.DXE_DRIVER] + HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf + LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf + CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.inf + +[LibraryClasses.common.DXE_RUNTIME_DRIVER] + HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf + LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf + CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf + +[LibraryClasses.common.SMM_CORE] + HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf + MemoryAllocationLib|MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationLib.inf + SmmServicesTableLib|MdeModulePkg/Library/PiSmmCoreSmmServicesTableLib/PiSmmCoreSmmServicesTableLib.inf + SmmCorePlatformHookLib|MdeModulePkg/Library/SmmCorePlatformHookLibNull/SmmCorePlatformHookLibNull.inf + SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf + +[LibraryClasses.common.DXE_SMM_DRIVER] + HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf + MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf + MmServicesTableLib|MdePkg/Library/MmServicesTableLib/MmServicesTableLib.inf + SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf + LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.inf + SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf + +[LibraryClasses.common.UEFI_DRIVER] + HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf + LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf + +[LibraryClasses.common.UEFI_APPLICATION] + HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + DebugLib|MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf + FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf + +[LibraryClasses.common.MM_STANDALONE] + HobLib|MdeModulePkg/Library/BaseHobLibNull/BaseHobLibNull.inf + MemoryAllocationLib|MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.inf + StandaloneMmDriverEntryPoint|MdePkg/Library/StandaloneMmDriverEntryPoint/StandaloneMmDriverEntryPoint.inf + MmServicesTableLib|MdePkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf + +[LibraryClasses.ARM, LibraryClasses.AARCH64] + ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf + ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf + LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf + + # + # It is not possible to prevent ARM compiler calls to generic intrinsic functions. + # This library provides the instrinsic functions generated by a given compiler. + # [LibraryClasses.ARM] and NULL mean link this library into all ARM images. + # + NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf + + # + # Since software stack checking may be heuristically enabled by the compiler + # include BaseStackCheckLib unconditionally. + # + NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf + +[LibraryClasses.EBC] + LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf + +[PcdsFeatureFlag] + gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable|TRUE + gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable|TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdDevicePathSupportDevicePathFromText|FALSE + gEfiMdeModulePkgTokenSpaceGuid.PcdDevicePathSupportDevicePathToText|FALSE + +[PcdsFixedAtBuild] + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0f + gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x06 + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxSizeNonPopulateCapsule|0x0 + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxSizePopulateCapsule|0x0 + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxPeiPerformanceLogEntries|28 + +[PcdsDynamicExDefault] + gEfiMdeModulePkgTokenSpaceGuid.PcdRecoveryFileName|L"FVMAIN.FV" + +[Components] + MdeModulePkg/Application/Ventoy/Ventoy.inf + MdeModulePkg/Application/VtoyUtil/VtoyUtil.inf + MdeModulePkg/Application/VtoyShim/VtoyShim.inf + MdeModulePkg/Application/VDiskChain/VDiskChain.inf + MdeModulePkg/Application/HelloWorld/HelloWorld.inf + MdeModulePkg/Application/DumpDynPcd/DumpDynPcd.inf + MdeModulePkg/Application/MemoryProfileInfo/MemoryProfileInfo.inf + + MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf + MdeModulePkg/Logo/Logo.inf + MdeModulePkg/Logo/LogoDxe.inf + MdeModulePkg/Library/BaseSortLib/BaseSortLib.inf + MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf + MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf + MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf + MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf + MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf + MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf + MdeModulePkg/Library/PciHostBridgeLibNull/PciHostBridgeLibNull.inf + MdeModulePkg/Library/PiSmmCoreSmmServicesTableLib/PiSmmCoreSmmServicesTableLib.inf + MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf + MdeModulePkg/Library/BaseHobLibNull/BaseHobLibNull.inf + MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.inf + + MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf + MdeModulePkg/Bus/Pci/PciSioSerialDxe/PciSioSerialDxe.inf + MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf + MdeModulePkg/Bus/Pci/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupportDxe.inf + MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf + MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.inf + MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.inf + MdeModulePkg/Bus/Pci/SdMmcPciHcPei/SdMmcPciHcPei.inf + MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcBlockIoPei.inf + MdeModulePkg/Bus/Sd/SdBlockIoPei/SdBlockIoPei.inf + MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.inf + MdeModulePkg/Bus/Sd/SdDxe/SdDxe.inf + MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.inf + MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruDxe.inf + MdeModulePkg/Bus/Pci/UfsPciHcPei/UfsPciHcPei.inf + MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.inf + MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf + MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf + MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf + MdeModulePkg/Bus/Pci/UhciPei/UhciPei.inf + MdeModulePkg/Bus/Pci/EhciPei/EhciPei.inf + MdeModulePkg/Bus/Pci/XhciPei/XhciPei.inf + MdeModulePkg/Bus/Pci/IdeBusPei/IdeBusPei.inf + MdeModulePkg/Bus/Usb/UsbBusPei/UsbBusPei.inf + MdeModulePkg/Bus/Usb/UsbBotPei/UsbBotPei.inf + MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf + MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf + MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf + MdeModulePkg/Bus/Ata/AhciPei/AhciPei.inf + MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf + MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf + MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf + MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf + MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf + MdeModulePkg/Bus/Usb/UsbMouseAbsolutePointerDxe/UsbMouseAbsolutePointerDxe.inf + MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf + MdeModulePkg/Bus/I2c/I2cDxe/I2cBusDxe.inf + MdeModulePkg/Bus/I2c/I2cDxe/I2cHostDxe.inf + MdeModulePkg/Bus/I2c/I2cDxe/I2cDxe.inf + MdeModulePkg/Bus/Isa/IsaBusDxe/IsaBusDxe.inf + MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf + MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf + MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceDxe.inf + + MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf + MdeModulePkg/Core/Pei/PeiMain.inf + MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf + + MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf + MdeModulePkg/Library/UefiMemoryAllocationProfileLib/UefiMemoryAllocationProfileLib.inf + MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf + MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationProfileLib.inf + MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf + MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf + MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf + MdeModulePkg/Library/DxeResetSystemLib/DxeResetSystemLib.inf + MdeModulePkg/Library/DxePrintLibPrint2Protocol/DxePrintLibPrint2Protocol.inf + MdeModulePkg/Library/PeiCrc32GuidedSectionExtractLib/PeiCrc32GuidedSectionExtractLib.inf + MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf + MdeModulePkg/Library/PeiResetSystemLib/PeiResetSystemLib.inf + MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf + MdeModulePkg/Library/ResetUtilityLib/ResetUtilityLib.inf + MdeModulePkg/Library/BaseResetSystemLibNull/BaseResetSystemLibNull.inf + MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf + MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf + MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf + MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf + MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib/RuntimeDxeReportStatusCodeLib.inf + MdeModulePkg/Library/RuntimeResetSystemLib/RuntimeResetSystemLib.inf + MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf + MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf + MdeModulePkg/Library/DxeDebugPrintErrorLevelLib/DxeDebugPrintErrorLevelLib.inf + MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf + MdeModulePkg/Library/PeiDebugPrintHobLib/PeiDebugPrintHobLib.inf + MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf + MdeModulePkg/Library/PlatformHookLibSerialPortPpi/PlatformHookLibSerialPortPpi.inf + MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf + MdeModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDxeDebugLibReportStatusCode.inf + MdeModulePkg/Library/PeiDebugLibDebugPpi/PeiDebugLibDebugPpi.inf + MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf + MdeModulePkg/Library/PlatformBootManagerLibNull/PlatformBootManagerLibNull.inf + MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf + MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf + MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf + MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf + MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf + MdeModulePkg/Library/VarCheckPcdLib/VarCheckPcdLib.inf + MdeModulePkg/Library/PlatformVarCleanupLib/PlatformVarCleanupLib.inf + MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf + MdeModulePkg/Library/DxeFileExplorerProtocol/DxeFileExplorerProtocol.inf + MdeModulePkg/Library/BaseIpmiLibNull/BaseIpmiLibNull.inf + MdeModulePkg/Library/DxeIpmiLibIpmiProtocol/DxeIpmiLibIpmiProtocol.inf + MdeModulePkg/Library/PeiIpmiLibIpmiPpi/PeiIpmiLibIpmiPpi.inf + MdeModulePkg/Library/SmmIpmiLibSmmIpmiProtocol/SmmIpmiLibSmmIpmiProtocol.inf + MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf + MdeModulePkg/Library/NonDiscoverableDeviceRegistrationLib/NonDiscoverableDeviceRegistrationLib.inf + MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf + MdeModulePkg/Library/DisplayUpdateProgressLibGraphics/DisplayUpdateProgressLibGraphics.inf + MdeModulePkg/Library/DisplayUpdateProgressLibText/DisplayUpdateProgressLibText.inf + + MdeModulePkg/Universal/BdsDxe/BdsDxe.inf + MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf + MdeModulePkg/Application/UiApp/UiApp.inf{ + + NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf + NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf + NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf + } + MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf + MdeModulePkg/Universal/BootManagerPolicyDxe/BootManagerPolicyDxe.inf + MdeModulePkg/Universal/CapsulePei/CapsulePei.inf + MdeModulePkg/Universal/CapsuleOnDiskLoadPei/CapsuleOnDiskLoadPei.inf + MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf + MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf + MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf + MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf + MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutputDxe.inf + MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf + MdeModulePkg/Universal/DebugPortDxe/DebugPortDxe.inf + MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf + MdeModulePkg/Universal/PrintDxe/PrintDxe.inf + MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf + MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf + MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf + MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf + MdeModulePkg/Universal/Disk/CdExpressPei/CdExpressPei.inf + MdeModulePkg/Universal/DriverSampleDxe/DriverSampleDxe.inf + MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf + MdeModulePkg/Universal/MemoryTest/GenericMemoryTestDxe/GenericMemoryTestDxe.inf + MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf + MdeModulePkg/Universal/Metronome/Metronome.inf + MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf + MdeModulePkg/Universal/ResetSystemPei/ResetSystemPei.inf { + + ResetSystemLib|MdeModulePkg/Library/BaseResetSystemLibNull/BaseResetSystemLibNull.inf + } + MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf { + + ResetSystemLib|MdeModulePkg/Library/BaseResetSystemLibNull/BaseResetSystemLibNull.inf + } + MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf + MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.inf + + MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PcatSingleSegmentPciCfg2Pei.inf + MdeModulePkg/Universal/PCD/Dxe/Pcd.inf + MdeModulePkg/Universal/PCD/Pei/Pcd.inf + MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverrideDxe.inf + + MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf + MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf + + MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf + MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf + MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf + MdeModulePkg/Application/VariableInfo/VariableInfo.inf + MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf + MdeModulePkg/Universal/Variable/Pei/VariablePei.inf + MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf + MdeModulePkg/Universal/TimestampDxe/TimestampDxe.inf + MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf + + MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf + MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf + MdeModulePkg/Universal/HiiResourcesSampleDxe/HiiResourcesSampleDxe.inf + MdeModulePkg/Universal/LegacyRegion2Dxe/LegacyRegion2Dxe.inf + + MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf + MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf + + MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTablePei/FirmwarePerformancePei.inf { + + LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf + } + MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.inf + MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf + MdeModulePkg/Universal/SectionExtractionDxe/SectionExtractionDxe.inf { + + NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf + } + MdeModulePkg/Universal/SectionExtractionPei/SectionExtractionPei.inf { + + NULL|MdeModulePkg/Library/PeiCrc32GuidedSectionExtractLib/PeiCrc32GuidedSectionExtractLib.inf + } + + MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemDxe.inf + MdeModulePkg/Universal/EsrtDxe/EsrtDxe.inf + MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmpDxe.inf + + MdeModulePkg/Universal/FileExplorerDxe/FileExplorerDxe.inf { + + FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf + } + + MdeModulePkg/Universal/SerialDxe/SerialDxe.inf + MdeModulePkg/Universal/LoadFileOnFv2/LoadFileOnFv2.inf + + MdeModulePkg/Universal/DebugServicePei/DebugServicePei.inf + + MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf + MdeModulePkg/Library/FmpAuthenticationLibNull/FmpAuthenticationLibNull.inf + MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.inf + MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf + +[Components.IA32, Components.X64, Components.AARCH64] + MdeModulePkg/Universal/EbcDxe/EbcDxe.inf + MdeModulePkg/Universal/EbcDxe/EbcDebugger.inf + MdeModulePkg/Universal/EbcDxe/EbcDebuggerConfig.inf + +[Components.IA32, Components.X64, Components.ARM, Components.AARCH64] + MdeModulePkg/Library/BrotliCustomDecompressLib/BrotliCustomDecompressLib.inf + MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf + MdeModulePkg/Core/Dxe/DxeMain.inf { + + NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf + } + +!if $(TOOL_CHAIN_TAG) != "XCODE5" + MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.inf + MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf +!endif + +[Components.IA32, Components.X64] + MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxe.inf + MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.inf + MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf + MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf + MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf { + + NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf + NULL|MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf + NULL|MdeModulePkg/Library/VarCheckPcdLib/VarCheckPcdLib.inf + } + MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf { + + NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf + NULL|MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf + NULL|MdeModulePkg/Library/VarCheckPcdLib/VarCheckPcdLib.inf + } + MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf + MdeModulePkg/Library/SmmReportStatusCodeLib/SmmReportStatusCodeLib.inf + MdeModulePkg/Universal/StatusCodeHandler/Smm/StatusCodeHandlerSmm.inf + MdeModulePkg/Universal/ReportStatusCodeRouter/Smm/ReportStatusCodeRouterSmm.inf + MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf + MdeModulePkg/Library/SmmMemoryAllocationProfileLib/SmmMemoryAllocationProfileLib.inf + MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationProfileLib.inf + MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationLib.inf + MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.inf + MdeModulePkg/Library/SmmPerformanceLib/SmmPerformanceLib.inf + MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf + MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf + MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.inf + MdeModulePkg/Library/SmmCorePlatformHookLibNull/SmmCorePlatformHookLibNull.inf + MdeModulePkg/Library/SmmSmiHandlerProfileLib/SmmSmiHandlerProfileLib.inf + MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaArchCustomDecompressLib.inf + MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf + MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf + MdeModulePkg/Universal/Acpi/SmmS3SaveState/SmmS3SaveState.inf + MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.inf + MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.inf + MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmmDxe.inf + MdeModulePkg/Universal/RegularExpressionDxe/RegularExpressionDxe.inf + MdeModulePkg/Universal/SmmCommunicationBufferDxe/SmmCommunicationBufferDxe.inf + MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf + +[Components.X64] + MdeModulePkg/Universal/CapsulePei/CapsuleX64.inf + +[BuildOptions] + *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES + diff --git a/EDK2/efiffs/mod/grub/grub-core/fs/iso9660.c b/EDK2/efiffs/mod/grub/grub-core/fs/iso9660.c new file mode 100644 index 0000000..bae3f62 --- /dev/null +++ b/EDK2/efiffs/mod/grub/grub-core/fs/iso9660.c @@ -0,0 +1,1141 @@ +/* iso9660.c - iso9660 implementation with extensions: + SUSP, Rock Ridge. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +#define GRUB_ISO9660_FSTYPE_DIR 0040000 +#define GRUB_ISO9660_FSTYPE_REG 0100000 +#define GRUB_ISO9660_FSTYPE_SYMLINK 0120000 +#define GRUB_ISO9660_FSTYPE_MASK 0170000 + +#define GRUB_ISO9660_LOG2_BLKSZ 2 +#define GRUB_ISO9660_BLKSZ 2048 + +#define GRUB_ISO9660_RR_DOT 2 +#define GRUB_ISO9660_RR_DOTDOT 4 + +#define GRUB_ISO9660_VOLDESC_BOOT 0 +#define GRUB_ISO9660_VOLDESC_PRIMARY 1 +#define GRUB_ISO9660_VOLDESC_SUPP 2 +#define GRUB_ISO9660_VOLDESC_PART 3 +#define GRUB_ISO9660_VOLDESC_END 255 + +extern int g_fs_name_nocase; +/* The head of a volume descriptor. */ +PRAGMA_BEGIN_PACKED +struct grub_iso9660_voldesc +{ + grub_uint8_t type; + grub_uint8_t magic[5]; + grub_uint8_t version; +} GRUB_PACKED; + +struct grub_iso9660_date2 +{ + grub_uint8_t year; + grub_uint8_t month; + grub_uint8_t day; + grub_uint8_t hour; + grub_uint8_t minute; + grub_uint8_t second; + grub_uint8_t offset; +} GRUB_PACKED; + +/* A directory entry. */ +struct grub_iso9660_dir +{ + grub_uint8_t len; + grub_uint8_t ext_sectors; + grub_uint32_t first_sector; + grub_uint32_t first_sector_be; + grub_uint32_t size; + grub_uint32_t size_be; + struct grub_iso9660_date2 mtime; + grub_uint8_t flags; + grub_uint8_t unused2[6]; +#define MAX_NAMELEN 255 + grub_uint8_t namelen; +} GRUB_PACKED; + +struct grub_iso9660_date +{ + grub_uint8_t year[4]; + grub_uint8_t month[2]; + grub_uint8_t day[2]; + grub_uint8_t hour[2]; + grub_uint8_t minute[2]; + grub_uint8_t second[2]; + grub_uint8_t hundredth[2]; + grub_uint8_t offset; +} GRUB_PACKED; + +/* The primary volume descriptor. Only little endian is used. */ +struct grub_iso9660_primary_voldesc +{ + struct grub_iso9660_voldesc voldesc; + grub_uint8_t unused1[33]; + grub_uint8_t volname[32]; + grub_uint8_t unused2[16]; + grub_uint8_t escape[32]; + grub_uint8_t unused3[12]; + grub_uint32_t path_table_size; + grub_uint8_t unused4[4]; + grub_uint32_t path_table; + grub_uint8_t unused5[12]; + struct grub_iso9660_dir rootdir; + grub_uint8_t unused6[624]; + struct grub_iso9660_date created; + struct grub_iso9660_date modified; +} GRUB_PACKED; + +/* A single entry in the path table. */ +struct grub_iso9660_path +{ + grub_uint8_t len; + grub_uint8_t sectors; + grub_uint32_t first_sector; + grub_uint16_t parentdir; + grub_uint8_t name[0]; +} GRUB_PACKED; + +/* An entry in the System Usage area of the directory entry. */ +struct grub_iso9660_susp_entry +{ + grub_uint8_t sig[2]; + grub_uint8_t len; +/*! MSVC compilers cannot handle a zero sized array in the middle + of a struct, and grub_iso9660_susp_entry is reused within + grub_iso9660_susp_ce. Therefore, instead of defining: + grub_uint8_t version; + grub_uint8_t data[]; + we leverage the fact that these attributes are the same size + and use an union. The only gotcha is that the actual + payload of u.data[] starts at 1, not 0. */ + union { + grub_uint8_t version; + grub_uint8_t data[1]; + } u; +} GRUB_PACKED; + +/* The CE entry. This is used to describe the next block where data + can be found. */ +struct grub_iso9660_susp_ce +{ + struct grub_iso9660_susp_entry entry; + grub_uint32_t blk; + grub_uint32_t blk_be; + grub_uint32_t off; + grub_uint32_t off_be; + grub_uint32_t len; + grub_uint32_t len_be; +} GRUB_PACKED; +PRAGMA_END_PACKED + +struct grub_iso9660_data +{ + struct grub_iso9660_primary_voldesc voldesc; + grub_disk_t disk; + int rockridge; + int susp_skip; + int joliet; + struct grub_fshelp_node *node; +}; + +struct grub_fshelp_node +{ + struct grub_iso9660_data *data; + grub_size_t have_dirents, alloc_dirents; + int have_symlink; + struct grub_iso9660_dir dirents[8]; + char symlink[0]; +}; + +enum + { + FLAG_TYPE_PLAIN = 0, + FLAG_TYPE_DIR = 2, + FLAG_TYPE = 3, + FLAG_MORE_EXTENTS = 0x80 + }; + +static grub_dl_t my_mod; + + +static grub_err_t +iso9660_to_unixtime (const struct grub_iso9660_date *i, grub_int32_t *nix) +{ + struct grub_datetime datetime; + + if (! i->year[0] && ! i->year[1] + && ! i->year[2] && ! i->year[3] + && ! i->month[0] && ! i->month[1] + && ! i->day[0] && ! i->day[1] + && ! i->hour[0] && ! i->hour[1] + && ! i->minute[0] && ! i->minute[1] + && ! i->second[0] && ! i->second[1] + && ! i->hundredth[0] && ! i->hundredth[1]) + return grub_error (GRUB_ERR_BAD_NUMBER, "empty date"); + datetime.year = (i->year[0] - '0') * 1000 + (i->year[1] - '0') * 100 + + (i->year[2] - '0') * 10 + (i->year[3] - '0'); + datetime.month = (i->month[0] - '0') * 10 + (i->month[1] - '0'); + datetime.day = (i->day[0] - '0') * 10 + (i->day[1] - '0'); + datetime.hour = (i->hour[0] - '0') * 10 + (i->hour[1] - '0'); + datetime.minute = (i->minute[0] - '0') * 10 + (i->minute[1] - '0'); + datetime.second = (i->second[0] - '0') * 10 + (i->second[1] - '0'); + + if (!grub_datetime2unixtime (&datetime, nix)) + return grub_error (GRUB_ERR_BAD_NUMBER, "incorrect date"); + *nix -= i->offset * 60 * 15; + return GRUB_ERR_NONE; +} + +static int +iso9660_to_unixtime2 (const struct grub_iso9660_date2 *i, grub_int32_t *nix) +{ + struct grub_datetime datetime; + + datetime.year = i->year + 1900; + datetime.month = i->month; + datetime.day = i->day; + datetime.hour = i->hour; + datetime.minute = i->minute; + datetime.second = i->second; + + if (!grub_datetime2unixtime (&datetime, nix)) + return 0; + *nix -= i->offset * 60 * 15; + return 1; +} + +static grub_err_t +read_node (grub_fshelp_node_t node, grub_off_t off, grub_size_t len, char *buf) +{ + grub_size_t i = 0; + + while (len > 0) + { + grub_size_t toread; + grub_err_t err; + while (i < node->have_dirents + && off >= grub_le_to_cpu32 (node->dirents[i].size)) + { + off -= grub_le_to_cpu32 (node->dirents[i].size); + i++; + } + if (i == node->have_dirents) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "read out of range"); + toread = grub_le_to_cpu32 (node->dirents[i].size); + if (toread > len) + toread = len; + err = grub_disk_read (node->data->disk, + ((grub_disk_addr_t) grub_le_to_cpu32 (node->dirents[i].first_sector)) << GRUB_ISO9660_LOG2_BLKSZ, + off, toread, buf); + if (err) + return err; + len -= toread; + off += toread; + buf += toread; + } + return GRUB_ERR_NONE; +} + +/* Iterate over the susp entries, starting with block SUA_BLOCK on the + offset SUA_POS with a size of SUA_SIZE bytes. Hook is called for + every entry. */ +static grub_err_t +grub_iso9660_susp_iterate (grub_fshelp_node_t node, grub_off_t off, + grub_ssize_t sua_size, + grub_err_t (*hook) + (struct grub_iso9660_susp_entry *entry, void *hook_arg), + void *hook_arg) +{ + char *sua; + struct grub_iso9660_susp_entry *entry; + grub_err_t err; + + if (sua_size <= 0) + return GRUB_ERR_NONE; + + sua = grub_malloc (sua_size); + if (!sua) + return grub_errno; + + /* Load a part of the System Usage Area. */ + err = read_node (node, off, sua_size, sua); + if (err) + return err; + + for (entry = (struct grub_iso9660_susp_entry *) sua; (char *) entry < (char *) sua + sua_size - 1 && entry->len > 0; + entry = (struct grub_iso9660_susp_entry *) + ((char *) entry + entry->len)) + { + /* The last entry. */ + if (grub_strncmp ((char *) entry->sig, "ST", 2) == 0) + break; + + /* Additional entries are stored elsewhere. */ + if (grub_strncmp ((char *) entry->sig, "CE", 2) == 0) + { + struct grub_iso9660_susp_ce *ce; + grub_disk_addr_t ce_block; + + ce = (struct grub_iso9660_susp_ce *) entry; + sua_size = grub_le_to_cpu32 (ce->len); + off = grub_le_to_cpu32 (ce->off); + ce_block = grub_le_to_cpu32 (ce->blk) << GRUB_ISO9660_LOG2_BLKSZ; + + grub_free (sua); + sua = grub_malloc (sua_size); + if (!sua) + return grub_errno; + + /* Load a part of the System Usage Area. */ + err = grub_disk_read (node->data->disk, ce_block, off, + sua_size, sua); + if (err) + return err; + + entry = (struct grub_iso9660_susp_entry *) sua; + } + + if (hook (entry, hook_arg)) + { + grub_free (sua); + return 0; + } + } + + grub_free (sua); + return 0; +} + +static char * +grub_iso9660_convert_string (grub_uint8_t *us, int len) +{ + char *p; + int i; + grub_uint16_t t[MAX_NAMELEN / 2 + 1]; + + p = grub_malloc (len * GRUB_MAX_UTF8_PER_UTF16 + 1); + if (! p) + return NULL; + + for (i=0; isig, "ER", 2) == 0) + { + data->rockridge = 1; + return 1; + } + return 0; +} + +static grub_err_t +set_rockridge (struct grub_iso9660_data *data) +{ + int sua_pos; + int sua_size; + char *sua; + struct grub_iso9660_dir rootdir; + struct grub_iso9660_susp_entry *entry; + + data->rockridge = 0; + + /* Read the system use area and test it to see if SUSP is + supported. */ + if (grub_disk_read (data->disk, + (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector) + << GRUB_ISO9660_LOG2_BLKSZ), 0, + sizeof (rootdir), (char *) &rootdir)) + return grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem"); + + sua_pos = (sizeof (rootdir) + rootdir.namelen + + (rootdir.namelen % 2) - 1); + sua_size = rootdir.len - sua_pos; + + if (!sua_size) + return GRUB_ERR_NONE; + + sua = grub_malloc (sua_size); + if (! sua) + return grub_errno; + + if (grub_disk_read (data->disk, + (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector) + << GRUB_ISO9660_LOG2_BLKSZ), sua_pos, + sua_size, sua)) + { + grub_free (sua); + return grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem"); + } + + entry = (struct grub_iso9660_susp_entry *) sua; + + /* Test if the SUSP protocol is used on this filesystem. */ + if (grub_strncmp ((char *) entry->sig, "SP", 2) == 0) + { + struct grub_fshelp_node rootnode; + + rootnode.data = data; + rootnode.alloc_dirents = ARRAY_SIZE (rootnode.dirents); + rootnode.have_dirents = 1; + rootnode.have_symlink = 0; + rootnode.dirents[0] = data->voldesc.rootdir; + + /* The 2nd data byte stored how many bytes are skipped every time + to get to the SUA (System Usage Area). */ + data->susp_skip = entry->u.data[1 + 2]; + entry = (struct grub_iso9660_susp_entry *) ((char *) entry + entry->len); + + /* Iterate over the entries in the SUA area to detect + extensions. */ + if (grub_iso9660_susp_iterate (&rootnode, + sua_pos, sua_size, susp_iterate_set_rockridge, + data)) + { + grub_free (sua); + return grub_errno; + } + } + grub_free (sua); + return GRUB_ERR_NONE; +} + +static struct grub_iso9660_data * +grub_iso9660_mount (grub_disk_t disk) +{ + struct grub_iso9660_data *data = 0; + struct grub_iso9660_primary_voldesc voldesc; + int block; + + data = grub_zalloc (sizeof (struct grub_iso9660_data)); + if (! data) + return 0; + + data->disk = disk; + + block = 16; + do + { + int copy_voldesc = 0; + + /* Read the superblock. */ + if (grub_disk_read (disk, block << GRUB_ISO9660_LOG2_BLKSZ, 0, + sizeof (struct grub_iso9660_primary_voldesc), + (char *) &voldesc)) + { + grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem"); + goto fail; + } + + if (grub_strncmp ((char *) voldesc.voldesc.magic, "CD001", 5) != 0) + { + grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem"); + goto fail; + } + + if (voldesc.voldesc.type == GRUB_ISO9660_VOLDESC_PRIMARY) + copy_voldesc = 1; + else if (!data->rockridge + && (voldesc.voldesc.type == GRUB_ISO9660_VOLDESC_SUPP) + && (voldesc.escape[0] == 0x25) && (voldesc.escape[1] == 0x2f) + && + ((voldesc.escape[2] == 0x40) || /* UCS-2 Level 1. */ + (voldesc.escape[2] == 0x43) || /* UCS-2 Level 2. */ + (voldesc.escape[2] == 0x45))) /* UCS-2 Level 3. */ + { + copy_voldesc = 1; + data->joliet = 1; + } + + if (copy_voldesc) + { + grub_memcpy((char *) &data->voldesc, (char *) &voldesc, + sizeof (struct grub_iso9660_primary_voldesc)); + if (set_rockridge (data)) + goto fail; + } + + block++; + } while (voldesc.voldesc.type != GRUB_ISO9660_VOLDESC_END); + + return data; + + fail: + grub_free (data); + return 0; +} + + +static char * +grub_iso9660_read_symlink (grub_fshelp_node_t node) +{ + return node->have_symlink + ? grub_strdup (node->symlink + + (node->have_dirents) * sizeof (node->dirents[0]) + - sizeof (node->dirents)) : grub_strdup (""); +} + +static grub_off_t +get_node_size (grub_fshelp_node_t node) +{ + grub_off_t ret = 0; + grub_size_t i; + + for (i = 0; i < node->have_dirents; i++) + ret += grub_le_to_cpu32 (node->dirents[i].size); + return ret; +} + +struct iterate_dir_ctx +{ + char *filename; + int filename_alloc; + enum grub_fshelp_filetype type; + char *symlink; + int was_continue; +}; + + /* Extend the symlink. */ +static void +add_part (struct iterate_dir_ctx *ctx, + const char *part, + int len2) +{ + int size = ctx->symlink ? grub_strlen (ctx->symlink) : 0; + + ctx->symlink = grub_realloc (ctx->symlink, size + len2 + 1); + if (! ctx->symlink) + return; + + grub_memcpy (ctx->symlink + size, part, len2); + ctx->symlink[size + len2] = 0; +} + +static grub_err_t +susp_iterate_dir (struct grub_iso9660_susp_entry *entry, + void *_ctx) +{ + struct iterate_dir_ctx *ctx = _ctx; + + /* The filename in the rock ridge entry. */ + if (grub_strncmp ("NM", (char *) entry->sig, 2) == 0) + { + /* The flags are stored at the data position 0, here the + filename type is stored. */ + /* FIXME: Fix this slightly improper cast. */ + if (entry->u.data[1 + 0] & GRUB_ISO9660_RR_DOT) + ctx->filename = (char *) "."; + else if (entry->u.data[1 + 0] & GRUB_ISO9660_RR_DOTDOT) + ctx->filename = (char *) ".."; + else if (entry->len >= 5) + { + grub_size_t off = 0, csize = 1; + char *old; + csize = entry->len - 5; + old = ctx->filename; + if (ctx->filename_alloc) + { + off = grub_strlen (ctx->filename); + ctx->filename = grub_realloc (ctx->filename, csize + off + 1); + } + else + { + off = 0; + ctx->filename = grub_zalloc (csize + 1); + } + if (!ctx->filename) + { + ctx->filename = old; + return grub_errno; + } + ctx->filename_alloc = 1; + grub_memcpy (ctx->filename + off, (char *) &entry->u.data[1 + 1], csize); + ctx->filename[off + csize] = '\0'; + } + } + /* The mode information (st_mode). */ + else if (grub_strncmp ((char *) entry->sig, "PX", 2) == 0) + { + /* At position 0 of the PX record the st_mode information is + stored (little-endian). */ + grub_uint32_t mode = ((entry->u.data[1 + 0] + (entry->u.data[1 + 1] << 8)) + & GRUB_ISO9660_FSTYPE_MASK); + + switch (mode) + { + case GRUB_ISO9660_FSTYPE_DIR: + ctx->type = GRUB_FSHELP_DIR; + break; + case GRUB_ISO9660_FSTYPE_REG: + ctx->type = GRUB_FSHELP_REG; + break; + case GRUB_ISO9660_FSTYPE_SYMLINK: + ctx->type = GRUB_FSHELP_SYMLINK; + break; + default: + ctx->type = GRUB_FSHELP_UNKNOWN; + } + } + else if (grub_strncmp ("SL", (char *) entry->sig, 2) == 0) + { + unsigned int pos = 1; + + /* The symlink is not stored as a POSIX symlink, translate it. */ + while (pos + sizeof (*entry) < entry->len) + { + /* The current position is the `Component Flag'. */ + switch (entry->u.data[1 + pos] & 30) + { + case 0: + { + /* The data on pos + 2 is the actual data, pos + 1 + is the length. Both are part of the `Component + Record'. */ + if (ctx->symlink && !ctx->was_continue) + add_part (ctx, "/", 1); + add_part (ctx, (char *) &entry->u.data[1 + pos + 2], + entry->u.data[1 + pos + 1]); + ctx->was_continue = (entry->u.data[1 + pos] & 1); + break; + } + + case 2: + add_part (ctx, "./", 2); + break; + + case 4: + add_part (ctx, "../", 3); + break; + + case 8: + add_part (ctx, "/", 1); + break; + } + /* In pos + 1 the length of the `Component Record' is + stored. */ + pos += entry->u.data[1 + pos + 1] + 2; + } + + /* Check if `grub_realloc' failed. */ + if (grub_errno) + return grub_errno; + } + + return 0; +} + +static int +grub_iso9660_iterate_dir (grub_fshelp_node_t dir, + grub_fshelp_iterate_dir_hook_t hook, void *hook_data) +{ + struct grub_iso9660_dir dirent; + grub_off_t offset = 0; + grub_off_t len; + struct iterate_dir_ctx ctx; + + len = get_node_size (dir); + + for (; offset < len; offset += dirent.len) + { + ctx.symlink = 0; + ctx.was_continue = 0; + + if (read_node (dir, offset, sizeof (dirent), (char *) &dirent)) + return 0; + + /* The end of the block, skip to the next one. */ + if (!dirent.len) + { + offset = (offset / GRUB_ISO9660_BLKSZ + 1) * GRUB_ISO9660_BLKSZ; + continue; + } + + { + char name[MAX_NAMELEN + 1]; + int nameoffset = offset + sizeof (dirent); + struct grub_fshelp_node *node; + int sua_off = (sizeof (dirent) + dirent.namelen + 1 + - (dirent.namelen % 2)); + int sua_size = dirent.len - sua_off; + + sua_off += offset + dir->data->susp_skip; + + ctx.filename = 0; + ctx.filename_alloc = 0; + ctx.type = GRUB_FSHELP_UNKNOWN; + + if (dir->data->rockridge + && grub_iso9660_susp_iterate (dir, sua_off, sua_size, + susp_iterate_dir, &ctx)) + return 0; + + /* Read the name. */ + if (read_node (dir, nameoffset, dirent.namelen, (char *) name)) + return 0; + + node = grub_malloc (sizeof (struct grub_fshelp_node)); + if (!node) + return 0; + + node->alloc_dirents = ARRAY_SIZE (node->dirents); + node->have_dirents = 1; + + /* Setup a new node. */ + node->data = dir->data; + node->have_symlink = 0; + + /* If the filetype was not stored using rockridge, use + whatever is stored in the iso9660 filesystem. */ + if (ctx.type == GRUB_FSHELP_UNKNOWN) + { + if ((dirent.flags & FLAG_TYPE) == FLAG_TYPE_DIR) + ctx.type = GRUB_FSHELP_DIR; + else + ctx.type = GRUB_FSHELP_REG; + } + + /* . and .. */ + if (!ctx.filename && dirent.namelen == 1 && name[0] == 0) + ctx.filename = (char *) "."; + + if (!ctx.filename && dirent.namelen == 1 && name[0] == 1) + ctx.filename = (char *) ".."; + + if (g_fs_name_nocase) + ctx.type |= GRUB_FSHELP_CASE_INSENSITIVE; + + /* The filename was not stored in a rock ridge entry. Read it + from the iso9660 filesystem. */ + if (!dir->data->joliet && !ctx.filename) + { + char *ptr; + name[dirent.namelen] = '\0'; + ctx.filename = grub_strrchr (name, ';'); + if (ctx.filename) + *ctx.filename = '\0'; + /* ISO9660 names are not case-preserving. */ + ctx.type |= GRUB_FSHELP_CASE_INSENSITIVE; + for (ptr = name; *ptr; ptr++) + *ptr = grub_tolower (*ptr); + if (ptr != name && *(ptr - 1) == '.') + *(ptr - 1) = 0; + ctx.filename = name; + } + + if (dir->data->joliet && !ctx.filename) + { + char *semicolon; + + ctx.filename = grub_iso9660_convert_string + ((grub_uint8_t *) name, dirent.namelen >> 1); + + semicolon = grub_strrchr (ctx.filename, ';'); + if (semicolon) + *semicolon = '\0'; + + ctx.filename_alloc = 1; + } + + node->dirents[0] = dirent; + while (dirent.flags & FLAG_MORE_EXTENTS) + { + offset += dirent.len; + if (read_node (dir, offset, sizeof (dirent), (char *) &dirent)) + { + if (ctx.filename_alloc) + grub_free (ctx.filename); + grub_free (node); + return 0; + } + if (node->have_dirents >= node->alloc_dirents) + { + struct grub_fshelp_node *new_node; + node->alloc_dirents *= 2; + new_node = grub_realloc (node, + sizeof (struct grub_fshelp_node) + + ((node->alloc_dirents + - ARRAY_SIZE (node->dirents)) + * sizeof (node->dirents[0]))); + if (!new_node) + { + if (ctx.filename_alloc) + grub_free (ctx.filename); + grub_free (node); + return 0; + } + node = new_node; + } + node->dirents[node->have_dirents++] = dirent; + } + if (ctx.symlink) + { + if ((node->alloc_dirents - node->have_dirents) + * sizeof (node->dirents[0]) < grub_strlen (ctx.symlink) + 1) + { + struct grub_fshelp_node *new_node; + new_node = grub_realloc (node, + sizeof (struct grub_fshelp_node) + + ((node->alloc_dirents + - ARRAY_SIZE (node->dirents)) + * sizeof (node->dirents[0])) + + grub_strlen (ctx.symlink) + 1); + if (!new_node) + { + if (ctx.filename_alloc) + grub_free (ctx.filename); + grub_free (node); + return 0; + } + node = new_node; + } + node->have_symlink = 1; + grub_strcpy (node->symlink + + node->have_dirents * sizeof (node->dirents[0]) + - sizeof (node->dirents), ctx.symlink); + grub_free (ctx.symlink); + ctx.symlink = 0; + ctx.was_continue = 0; + } + if (hook (ctx.filename, ctx.type, node, hook_data)) + { + if (ctx.filename_alloc) + grub_free (ctx.filename); + return 1; + } + if (ctx.filename_alloc) + grub_free (ctx.filename); + } + } + + return 0; +} + + + +/* Context for grub_iso9660_dir. */ +struct grub_iso9660_dir_ctx +{ + grub_fs_dir_hook_t hook; + void *hook_data; +}; + +/* Helper for grub_iso9660_dir. */ +static int +grub_iso9660_dir_iter (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node, void *data) +{ + struct grub_iso9660_dir_ctx *ctx = data; + struct grub_dirhook_info info; + + grub_memset (&info, 0, sizeof (info)); + info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); + info.mtimeset = !!iso9660_to_unixtime2 (&node->dirents[0].mtime, &info.mtime); + + grub_free (node); + return ctx->hook (filename, &info, ctx->hook_data); +} + +static grub_err_t +grub_iso9660_dir (grub_device_t device, const char *path, + grub_fs_dir_hook_t hook, void *hook_data) +{ + struct grub_iso9660_dir_ctx ctx = { hook, hook_data }; + struct grub_iso9660_data *data = 0; + struct grub_fshelp_node rootnode; + struct grub_fshelp_node *foundnode; + + grub_dl_ref (my_mod); + + data = grub_iso9660_mount (device->disk); + if (! data) + goto fail; + + rootnode.data = data; + rootnode.alloc_dirents = 0; + rootnode.have_dirents = 1; + rootnode.have_symlink = 0; + rootnode.dirents[0] = data->voldesc.rootdir; + + /* Use the fshelp function to traverse the path. */ + if (grub_fshelp_find_file (path, &rootnode, + &foundnode, + grub_iso9660_iterate_dir, + grub_iso9660_read_symlink, + GRUB_FSHELP_DIR)) + goto fail; + + /* List the files in the directory. */ + grub_iso9660_iterate_dir (foundnode, grub_iso9660_dir_iter, &ctx); + + if (foundnode != &rootnode) + grub_free (foundnode); + + fail: + grub_free (data); + + grub_dl_unref (my_mod); + + return grub_errno; +} + + +/* Open a file named NAME and initialize FILE. */ +static grub_err_t +grub_iso9660_open (struct grub_file *file, const char *name) +{ + struct grub_iso9660_data *data; + struct grub_fshelp_node rootnode; + struct grub_fshelp_node *foundnode; + + grub_dl_ref (my_mod); + + data = grub_iso9660_mount (file->device->disk); + if (!data) + goto fail; + + rootnode.data = data; + rootnode.alloc_dirents = 0; + rootnode.have_dirents = 1; + rootnode.have_symlink = 0; + rootnode.dirents[0] = data->voldesc.rootdir; + + /* Use the fshelp function to traverse the path. */ + if (grub_fshelp_find_file (name, &rootnode, + &foundnode, + grub_iso9660_iterate_dir, + grub_iso9660_read_symlink, + GRUB_FSHELP_REG)) + goto fail; + + data->node = foundnode; + file->data = data; + file->size = get_node_size (foundnode); + file->offset = 0; + + return 0; + + fail: + grub_dl_unref (my_mod); + + grub_free (data); + + return grub_errno; +} + + +static grub_ssize_t +grub_iso9660_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_iso9660_data *data = + (struct grub_iso9660_data *) file->data; + grub_err_t err; + + /* XXX: The file is stored in as a single extent. */ + data->disk->read_hook = file->read_hook; + data->disk->read_hook_data = file->read_hook_data; + err = read_node (data->node, file->offset, len, buf); + data->disk->read_hook = NULL; + + if (err || grub_errno) + return -1; + + return len; +} + + +static grub_err_t +grub_iso9660_close (grub_file_t file) +{ + struct grub_iso9660_data *data = + (struct grub_iso9660_data *) file->data; + grub_free (data->node); + grub_free (data); + + grub_dl_unref (my_mod); + + return GRUB_ERR_NONE; +} + + +static grub_err_t +grub_iso9660_label (grub_device_t device, char **label) +{ + struct grub_iso9660_data *data; + data = grub_iso9660_mount (device->disk); + + if (data) + { + if (data->joliet) + *label = grub_iso9660_convert_string (data->voldesc.volname, 16); + else + *label = grub_strndup ((char *) data->voldesc.volname, 32); + if (*label) + { + char *ptr; + for (ptr = *label; *ptr;ptr++); + ptr--; + while (ptr >= *label && *ptr == ' ') + *ptr-- = 0; + } + + grub_free (data); + } + else + *label = 0; + + return grub_errno; +} + + +static grub_err_t +grub_iso9660_uuid (grub_device_t device, char **uuid) +{ + struct grub_iso9660_data *data; + grub_disk_t disk = device->disk; + + grub_dl_ref (my_mod); + + data = grub_iso9660_mount (disk); + if (data) + { + if (! data->voldesc.modified.year[0] && ! data->voldesc.modified.year[1] + && ! data->voldesc.modified.year[2] && ! data->voldesc.modified.year[3] + && ! data->voldesc.modified.month[0] && ! data->voldesc.modified.month[1] + && ! data->voldesc.modified.day[0] && ! data->voldesc.modified.day[1] + && ! data->voldesc.modified.hour[0] && ! data->voldesc.modified.hour[1] + && ! data->voldesc.modified.minute[0] && ! data->voldesc.modified.minute[1] + && ! data->voldesc.modified.second[0] && ! data->voldesc.modified.second[1] + && ! data->voldesc.modified.hundredth[0] && ! data->voldesc.modified.hundredth[1]) + { + grub_error (GRUB_ERR_BAD_NUMBER, "no creation date in filesystem to generate UUID"); + *uuid = NULL; + } + else + { + *uuid = grub_xasprintf ("%c%c%c%c-%c%c-%c%c-%c%c-%c%c-%c%c-%c%c", + data->voldesc.modified.year[0], + data->voldesc.modified.year[1], + data->voldesc.modified.year[2], + data->voldesc.modified.year[3], + data->voldesc.modified.month[0], + data->voldesc.modified.month[1], + data->voldesc.modified.day[0], + data->voldesc.modified.day[1], + data->voldesc.modified.hour[0], + data->voldesc.modified.hour[1], + data->voldesc.modified.minute[0], + data->voldesc.modified.minute[1], + data->voldesc.modified.second[0], + data->voldesc.modified.second[1], + data->voldesc.modified.hundredth[0], + data->voldesc.modified.hundredth[1]); + } + } + else + *uuid = NULL; + + grub_dl_unref (my_mod); + + grub_free (data); + + return grub_errno; +} + +/* Get writing time of filesystem. */ +static grub_err_t +grub_iso9660_mtime (grub_device_t device, grub_int32_t *timebuf) +{ + struct grub_iso9660_data *data; + grub_disk_t disk = device->disk; + grub_err_t err; + + grub_dl_ref (my_mod); + + data = grub_iso9660_mount (disk); + if (!data) + { + grub_dl_unref (my_mod); + return grub_errno; + } + err = iso9660_to_unixtime (&data->voldesc.modified, timebuf); + + grub_dl_unref (my_mod); + + grub_free (data); + + return err; +} + + + + +static struct grub_fs grub_iso9660_fs = + { + .name = "iso9660", + .fs_dir = grub_iso9660_dir, + .fs_open = grub_iso9660_open, + .fs_read = grub_iso9660_read, + .fs_close = grub_iso9660_close, + .fs_label = grub_iso9660_label, + .fs_uuid = grub_iso9660_uuid, + .fs_mtime = grub_iso9660_mtime, +#ifdef GRUB_UTIL + .reserved_first_sector = 1, + .blocklist_install = 1, +#endif + .next = 0 + }; + +GRUB_MOD_INIT(iso9660) +{ + grub_fs_register (&grub_iso9660_fs); + my_mod = mod; +} + +GRUB_MOD_FINI(iso9660) +{ + grub_fs_unregister (&grub_iso9660_fs); +} diff --git a/EDK2/efiffs/mod/src/file.c b/EDK2/efiffs/mod/src/file.c new file mode 100644 index 0000000..9c17cc9 --- /dev/null +++ b/EDK2/efiffs/mod/src/file.c @@ -0,0 +1,794 @@ +/* file.c - SimpleFileIo Interface */ +/* + * Copyright © 2014-2017 Pete Batard + * Based on iPXE's efi_driver.c and efi_file.c: + * Copyright © 2011,2013 Michael Brown . + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "driver.h" + +/** + * Get EFI file name (for debugging) + * + * @v file EFI file + * @ret Name Name + */ +static const CHAR16 * +FileName(EFI_GRUB_FILE *File) +{ + EFI_STATUS Status; + static CHAR16 Path[MAX_PATH]; + + Status = Utf8ToUtf16NoAlloc(File->path, Path, sizeof(Path)); + if (EFI_ERROR(Status)) { + PrintStatusError(Status, L"Could not convert filename to UTF16"); + return NULL; + } + + return Path; +} + +/* Simple hook to populate the timestamp and directory flag when opening a file */ +static INT32 +InfoHook(const CHAR8 *name, const GRUB_DIRHOOK_INFO *Info, VOID *Data) +{ + EFI_GRUB_FILE *File = (EFI_GRUB_FILE *) Data; + + /* Look for a specific file */ + if (strcmpa(name, File->basename) != 0) + return 0; + + File->IsDir = (BOOLEAN) (Info->Dir); + if (Info->MtimeSet) + File->Mtime = Info->Mtime; + + return 0; +} + +/** + * Open file + * + * @v This File handle + * @ret new New file handle + * @v Name File name + * @v Mode File mode + * @v Attributes File attributes (for newly-created files) + * @ret Status EFI status code + */ +static EFI_STATUS EFIAPI +FileOpen(EFI_FILE_HANDLE This, EFI_FILE_HANDLE *New, + CHAR16 *Name, UINT64 Mode, UINT64 Attributes) +{ + EFI_STATUS Status; + EFI_GRUB_FILE *File = _CR(This, EFI_GRUB_FILE, EfiFile); + EFI_GRUB_FILE *NewFile; + + // TODO: Use dynamic buffers? + char path[MAX_PATH], clean_path[MAX_PATH], *dirname; + INTN i, len; + BOOLEAN AbsolutePath = (*Name == L'\\'); + + PrintInfo(L"Open(" PERCENT_P L"%s, \"%s\")\n", (UINTN) This, + IS_ROOT(File)?L" ":L"", Name); + + /* Fail unless opening read-only */ + if (Mode != EFI_FILE_MODE_READ) { + PrintWarning(L"File '%s' can only be opened in read-only mode\n", Name); + return EFI_WRITE_PROTECTED; + } + + /* Additional failures */ + if ((StrCmp(Name, L"..") == 0) && IS_ROOT(File)) { + PrintInfo(L"Trying to open 's parent\n"); + return EFI_NOT_FOUND; + } + + /* See if we're trying to reopen current (which the EFI Shell insists on doing) */ + if ((*Name == 0) || (StrCmp(Name, L".") == 0)) { + PrintInfo(L" Reopening %s\n", IS_ROOT(File)?L"":FileName(File)); + File->RefCount++; + *New = This; + PrintInfo(L" RET: " PERCENT_P L"\n", (UINTN) *New); + return EFI_SUCCESS; + } + + /* If we have an absolute path, don't bother completing with the parent */ + if (AbsolutePath) { + len = 0; + } else { + strcpya(path, File->path); + len = strlena(path); + /* Add delimiter if needed */ + if ((len == 0) || (path[len-1] != '/')) + path[len++] = '/'; + } + + /* Copy the rest of the path (converted to UTF-8) */ + Status = Utf16ToUtf8NoAlloc(Name, &path[len], sizeof(path) - len); + if (EFI_ERROR(Status)) { + PrintStatusError(Status, L"Could not convert path to UTF-8"); + return Status; + } + /* Convert the delimiters */ + for (i = strlena(path) - 1 ; i >= len; i--) { + if (path[i] == '\\') + path[i] = '/'; + } + + /* We only want to handle with absolute paths */ + clean_path[0] = '/'; + /* Find out if we're dealing with root by removing the junk */ + CopyPathRelative(&clean_path[1], path, MAX_PATH - 1); + if (clean_path[1] == 0) { + /* We're dealing with the root */ + PrintInfo(L" Reopening \n"); + *New = &File->FileSystem->RootFile->EfiFile; + /* Must make sure that DirIndex is reset too (NB: no concurrent access!) */ + File->FileSystem->RootFile->DirIndex = 0; + PrintInfo(L" RET: " PERCENT_P L"\n", (UINTN) *New); + return EFI_SUCCESS; + } + + // TODO: eventually we should seek for already opened files and increase RefCount + /* Allocate and initialise an instance of a file */ + Status = GrubCreateFile(&NewFile, File->FileSystem); + if (EFI_ERROR(Status)) { + PrintStatusError(Status, L"Could not instantiate file"); + return Status; + } + + NewFile->path = AllocatePool(strlena(clean_path)+1); + if (NewFile->path == NULL) { + GrubDestroyFile(NewFile); + PrintError(L"Could not instantiate path\n"); + return EFI_OUT_OF_RESOURCES; + } + strcpya(NewFile->path, clean_path); + + /* Isolate the basename and dirname */ + for (i = strlena(clean_path) - 1; i >= 0; i--) { + if (clean_path[i] == '/') { + clean_path[i] = 0; + break; + } + } + dirname = (i <= 0) ? "/" : clean_path; + NewFile->basename = &NewFile->path[i+1]; + + /* Find if we're working with a directory and fill the grub timestamp */ + Status = GrubDir(NewFile, dirname, InfoHook, (VOID *) NewFile); + if (EFI_ERROR(Status)) { + if (Status != EFI_NOT_FOUND) + PrintStatusError(Status, L"Could not get file attributes for '%s'", Name); + FreePool(NewFile->path); + GrubDestroyFile(NewFile); + return Status; + } + + /* Finally we can call on GRUB open() if it's a regular file */ + if (!NewFile->IsDir) { + Status = GrubOpen(NewFile); + if (EFI_ERROR(Status)) { + if (Status != EFI_NOT_FOUND) + PrintStatusError(Status, L"Could not open file '%s'", Name); + FreePool(NewFile->path); + GrubDestroyFile(NewFile); + return Status; + } + } + + NewFile->RefCount++; + *New = &NewFile->EfiFile; + + PrintInfo(L" RET: " PERCENT_P L"\n", (UINTN) *New); + return EFI_SUCCESS; +} + +/* Ex version */ +static EFI_STATUS EFIAPI +FileOpenEx(EFI_FILE_HANDLE This, EFI_FILE_HANDLE *New, CHAR16 *Name, + UINT64 Mode, UINT64 Attributes, EFI_FILE_IO_TOKEN *Token) +{ + return FileOpen(This, New, Name, Mode, Attributes); +} + + +/** + * Close file + * + * @v This File handle + * @ret Status EFI status code + */ +static EFI_STATUS EFIAPI +FileClose(EFI_FILE_HANDLE This) +{ + EFI_GRUB_FILE *File = _CR(This, EFI_GRUB_FILE, EfiFile); + + PrintInfo(L"Close(" PERCENT_P L"|'%s') %s\n", (UINTN) This, FileName(File), + IS_ROOT(File)?L"":L""); + + /* Nothing to do it this is the root */ + if (IS_ROOT(File)) + return EFI_SUCCESS; + + if (--File->RefCount == 0) { + /* Close the file if it's a regular one */ + if (!File->IsDir) + GrubClose(File); + /* NB: basename points into File->path and does not need to be freed */ + if (File->path != NULL) + FreePool(File->path); + GrubDestroyFile(File); + } + + return EFI_SUCCESS; +} + +/** + * Close and delete file + * + * @v This File handle + * @ret Status EFI status code + */ +static EFI_STATUS EFIAPI +FileDelete(EFI_FILE_HANDLE This) +{ + EFI_GRUB_FILE *File = _CR(This, EFI_GRUB_FILE, EfiFile); + + PrintError(L"Cannot delete '%s'\n", FileName(File)); + + /* Close file */ + FileClose(This); + + /* Warn of failure to delete */ + return EFI_WARN_DELETE_FAILURE; +} + +/* GRUB uses a callback for each directory entry, whereas EFI uses repeated + * firmware generated calls to FileReadDir() to get the info for each entry, + * so we have to reconcile the twos. For now, we'll re-issue a call to GRUB + * dir(), and run through all the entries (to find the one we + * are interested in) multiple times. Maybe later we'll try to optimize this + * by building a one-off chained list of entries that we can parse... + */ +static INT32 +DirHook(const CHAR8 *name, const GRUB_DIRHOOK_INFO *DirInfo, VOID *Data) +{ + EFI_STATUS Status; + EFI_FILE_INFO *Info = (EFI_FILE_INFO *) Data; + INT64 *Index = (INT64 *) &Info->FileSize; + CHAR8 *filename = (CHAR8 *) (UINTN) Info->PhysicalSize; + EFI_TIME Time = { 1970, 01, 01, 00, 00, 00, 0, 0, 0, 0, 0}; + + // Eliminate '.' or '..' + if ((name[0] == '.') && ((name[1] == 0) || ((name[1] == '.') && (name[2] == 0)))) + return 0; + + /* Ignore any entry that doesn't match our index */ + if ((*Index)-- != 0) + return 0; + + strcpya(filename, name); + + Status = Utf8ToUtf16NoAlloc(filename, Info->FileName, (INTN)(Info->Size - sizeof(EFI_FILE_INFO))); + if (EFI_ERROR(Status)) { + if (Status != EFI_BUFFER_TOO_SMALL) + PrintStatusError(Status, L"Could not convert directory entry to UTF-8"); + return (INT32) Status; + } + /* The Info struct size already accounts for the extra NUL */ + Info->Size = sizeof(*Info) + StrLen(Info->FileName) * sizeof(CHAR16); + + // Oh, and of course GRUB uses a 32 bit signed mtime value (seriously, wtf guys?!?) + if (DirInfo->MtimeSet) + GrubTimeToEfiTime(DirInfo->Mtime, &Time); + CopyMem(&Info->CreateTime, &Time, sizeof(Time)); + CopyMem(&Info->LastAccessTime, &Time, sizeof(Time)); + CopyMem(&Info->ModificationTime, &Time, sizeof(Time)); + + Info->Attribute = EFI_FILE_READ_ONLY; + if (DirInfo->Dir) + Info->Attribute |= EFI_FILE_DIRECTORY; + + return 0; +} + +/** + * Read directory entry + * + * @v file EFI file + * @v Len Length to read + * @v Data Data buffer + * @ret Status EFI status code + */ +static EFI_STATUS +FileReadDir(EFI_GRUB_FILE *File, UINTN *Len, VOID *Data) +{ + EFI_FILE_INFO *Info = (EFI_FILE_INFO *) Data; + EFI_STATUS Status; + /* We temporarily repurpose the FileSize as a *signed* entry index */ + INT64 *Index = (INT64 *) &Info->FileSize; + /* And PhysicalSize as a pointer to our filename */ + CHAR8 **basename = (CHAR8 **) &Info->PhysicalSize; + CHAR8 path[MAX_PATH]; + EFI_GRUB_FILE *TmpFile = NULL; + INTN len; + + /* Unless we can fit our maximum size, forget it */ + if (*Len < sizeof(EFI_FILE_INFO)) { + *Len = MINIMUM_INFO_LENGTH; + return EFI_BUFFER_TOO_SMALL; + } + + /* Populate our Info template */ + ZeroMem(Data, *Len); + Info->Size = *Len; + *Index = File->DirIndex; + strcpya(path, File->path); + len = strlena(path); + if (path[len-1] != '/') + path[len++] = '/'; + *basename = &path[len]; + + /* Invoke GRUB's directory listing */ + Status = GrubDir(File, File->path, DirHook, Data); + if (*Index >= 0) { + /* No more entries */ + *Len = 0; + return EFI_SUCCESS; + } + + if (EFI_ERROR(Status)) { + if (Status == EFI_BUFFER_TOO_SMALL) { + *Len = MINIMUM_INFO_LENGTH; + } else { + PrintStatusError(Status, L"Directory listing failed"); + } + return Status; + } + + /* Our Index/FileSize must be reset */ + Info->FileSize = 0; + Info->PhysicalSize = 0; + + /* For regular files, we still need to fill the size */ + if (!(Info->Attribute & EFI_FILE_DIRECTORY)) { + /* Open the file and read its size */ + Status = GrubCreateFile(&TmpFile, File->FileSystem); + if (EFI_ERROR(Status)) { + PrintStatusError(Status, L"Unable to create temporary file"); + return Status; + } + TmpFile->path = path; + + Status = GrubOpen(TmpFile); + if (EFI_ERROR(Status)) { + // TODO: EFI_NO_MAPPING is returned for links... + PrintStatusError(Status, L"Unable to obtain the size of '%s'", Info->FileName); + /* Non fatal error */ + } else { + Info->FileSize = GrubGetFileSize(TmpFile); + Info->PhysicalSize = GrubGetFileSize(TmpFile); + GrubClose(TmpFile); + } + GrubDestroyFile(TmpFile); + } + + *Len = (UINTN) Info->Size; + /* Advance to the next entry */ + File->DirIndex++; + +// PrintInfo(L" Entry[%d]: '%s' %s\n", File->DirIndex-1, Info->FileName, +// (Info->Attribute&EFI_FILE_DIRECTORY)?L"":L""); + + return EFI_SUCCESS; +} + +/** + * Read from file + * + * @v This File handle + * @v Len Length to read + * @v Data Data buffer + * @ret Status EFI status code + */ +static EFI_STATUS EFIAPI +FileRead(EFI_FILE_HANDLE This, UINTN *Len, VOID *Data) +{ + EFI_GRUB_FILE *File = _CR(This, EFI_GRUB_FILE, EfiFile); + + PrintInfo(L"Read(" PERCENT_P L"|'%s', %d) %s\n", (UINTN) This, FileName(File), + *Len, File->IsDir?L"":L""); + + /* If this is a directory, then fetch the directory entries */ + if (File->IsDir) + return FileReadDir(File, Len, Data); + + return GrubRead(File, Data, Len); +} + +/* Ex version */ +static EFI_STATUS EFIAPI +FileReadEx(IN EFI_FILE_PROTOCOL *This, IN OUT EFI_FILE_IO_TOKEN *Token) +{ + return FileRead(This, &(Token->BufferSize), Token->Buffer); +} + +/** + * Write to file + * + * @v This File handle + * @v Len Length to write + * @v Data Data buffer + * @ret Status EFI status code + */ +static EFI_STATUS EFIAPI +FileWrite(EFI_FILE_HANDLE This, UINTN *Len, VOID *Data) +{ + EFI_GRUB_FILE *File = _CR(This, EFI_GRUB_FILE, EfiFile); + + PrintError(L"Cannot write to '%s'\n", FileName(File)); + return EFI_WRITE_PROTECTED; +} + +/* Ex version */ +static EFI_STATUS EFIAPI +FileWriteEx(IN EFI_FILE_PROTOCOL *This, IN OUT EFI_FILE_IO_TOKEN *Token) +{ + return FileWrite(This, &(Token->BufferSize), Token->Buffer); +} + +/** + * Set file position + * + * @v This File handle + * @v Position New file position + * @ret Status EFI status code + */ +static EFI_STATUS EFIAPI +FileSetPosition(EFI_FILE_HANDLE This, UINT64 Position) +{ + EFI_GRUB_FILE *File = _CR(This, EFI_GRUB_FILE, EfiFile); + UINT64 FileSize; + + PrintInfo(L"SetPosition(" PERCENT_P L"|'%s', %lld) %s\n", (UINTN) This, + FileName(File), Position, (File->IsDir)?L"":L""); + + /* If this is a directory, reset the Index to the start */ + if (File->IsDir) { + if (Position != 0) + return EFI_INVALID_PARAMETER; + File->DirIndex = 0; + return EFI_SUCCESS; + } + + /* Fail if we attempt to seek past the end of the file (since + * we do not support writes). + */ + FileSize = GrubGetFileSize(File); + if (Position > FileSize) { + PrintError(L"'%s': Cannot seek to #%llx of %llx\n", + FileName(File), Position, FileSize); + return EFI_UNSUPPORTED; + } + + /* Set position */ + GrubSetFileOffset(File, Position); + PrintDebug(L"'%s': Position set to %llx\n", + FileName(File), Position); + + return EFI_SUCCESS; +} + +/** + * Get file position + * + * @v This File handle + * @ret Position New file position + * @ret Status EFI status code + */ +static EFI_STATUS EFIAPI +FileGetPosition(EFI_FILE_HANDLE This, UINT64 *Position) +{ + EFI_GRUB_FILE *File = _CR(This, EFI_GRUB_FILE, EfiFile); + + PrintInfo(L"GetPosition(" PERCENT_P L"|'%s', %lld)\n", (UINTN) This, FileName(File)); + + if (File->IsDir) + *Position = File->DirIndex; + else + *Position = GrubGetFileOffset(File); + return EFI_SUCCESS; +} + +/** + * Get file information + * + * @v This File handle + * @v Type Type of information + * @v Len Buffer size + * @v Data Buffer + * @ret Status EFI status code + */ +static EFI_STATUS EFIAPI +FileGetInfo(EFI_FILE_HANDLE This, EFI_GUID *Type, UINTN *Len, VOID *Data) +{ + EFI_STATUS Status; + EFI_GRUB_FILE *File = _CR(This, EFI_GRUB_FILE, EfiFile); + EFI_FILE_SYSTEM_INFO *FSInfo = (EFI_FILE_SYSTEM_INFO *) Data; + EFI_FILE_INFO *Info = (EFI_FILE_INFO *) Data; + EFI_FILE_SYSTEM_VOLUME_LABEL_INFO *VLInfo = (EFI_FILE_SYSTEM_VOLUME_LABEL_INFO *)Data; + EFI_TIME Time; + CHAR8* label; + UINTN tmpLen; + + PrintInfo(L"GetInfo(" PERCENT_P L"|'%s', %d) %s\n", (UINTN) This, + FileName(File), *Len, File->IsDir?L"":L""); + + /* Determine information to return */ + if (CompareMem(Type, &gEfiFileInfoGuid, sizeof(*Type)) == 0) { + + /* Fill file information */ + PrintExtra(L"Get regular file information\n"); + if (*Len < sizeof(EFI_FILE_INFO)) { + *Len = MINIMUM_INFO_LENGTH; + return EFI_BUFFER_TOO_SMALL; + } + + ZeroMem(Data, sizeof(EFI_FILE_INFO)); + + Info->Attribute = EFI_FILE_READ_ONLY; + GrubTimeToEfiTime(File->Mtime, &Time); + CopyMem(&Info->CreateTime, &Time, sizeof(Time)); + CopyMem(&Info->LastAccessTime, &Time, sizeof(Time)); + CopyMem(&Info->ModificationTime, &Time, sizeof(Time)); + + if (File->IsDir) { + Info->Attribute |= EFI_FILE_DIRECTORY; + } else { + Info->FileSize = GrubGetFileSize(File); + Info->PhysicalSize = GrubGetFileSize(File); + } + + tmpLen = (UINTN)(Info->Size - sizeof(EFI_FILE_INFO) - 1); + Status = Utf8ToUtf16NoAllocUpdateLen(File->basename, Info->FileName, &tmpLen); + if (EFI_ERROR(Status)) { + if (Status != EFI_BUFFER_TOO_SMALL) { + PrintStatusError(Status, L"Could not convert basename to UTF-16"); + } else { + *Len = MINIMUM_INFO_LENGTH; + } + return Status; + } + + /* The Info struct size already accounts for the extra NUL */ + Info->Size = sizeof(EFI_FILE_INFO) + tmpLen; + *Len = (INTN)Info->Size; + return EFI_SUCCESS; + + } else if (CompareMem(Type, &gEfiFileSystemInfoGuid, sizeof(*Type)) == 0) { + + /* Get file system information */ + PrintExtra(L"Get file system information\n"); + if (*Len < sizeof(EFI_FILE_SYSTEM_INFO)) { + *Len = MINIMUM_FS_INFO_LENGTH; + return EFI_BUFFER_TOO_SMALL; + } + + ZeroMem(Data, sizeof(EFI_FILE_INFO)); + FSInfo->Size = *Len; + FSInfo->ReadOnly = 1; + /* NB: This should really be cluster size, but we don't have access to that */ + if (File->FileSystem->BlockIo2 != NULL) { + FSInfo->BlockSize = File->FileSystem->BlockIo2->Media->BlockSize; + } else { + FSInfo->BlockSize = File->FileSystem->BlockIo->Media->BlockSize; + } + if (FSInfo->BlockSize == 0) { + PrintWarning(L"Corrected Media BlockSize\n"); + FSInfo->BlockSize = 512; + } + if (File->FileSystem->BlockIo2 != NULL) { + FSInfo->VolumeSize = (File->FileSystem->BlockIo2->Media->LastBlock + 1) * + FSInfo->BlockSize; + } else { + FSInfo->VolumeSize = (File->FileSystem->BlockIo->Media->LastBlock + 1) * + FSInfo->BlockSize; + } + /* No idea if we can easily get this for GRUB, and the device is RO anyway */ + FSInfo->FreeSpace = 0; + + Status = GrubLabel(File, &label); + if (EFI_ERROR(Status)) { + PrintStatusError(Status, L"Could not read disk label"); + FSInfo->VolumeLabel[0] = 0; + *Len = sizeof(EFI_FILE_SYSTEM_INFO); + } else { + tmpLen = (INTN)(FSInfo->Size - sizeof(EFI_FILE_SYSTEM_INFO) - 1); + Status = Utf8ToUtf16NoAllocUpdateLen(label, FSInfo->VolumeLabel, &tmpLen); + if (EFI_ERROR(Status)) { + if (Status != EFI_BUFFER_TOO_SMALL) { + PrintStatusError(Status, L"Could not convert label to UTF-16"); + } else { + *Len = MINIMUM_FS_INFO_LENGTH; + } + return Status; + } + FSInfo->Size = sizeof(EFI_FILE_SYSTEM_INFO) - 1 + tmpLen; + *Len = (INTN)FSInfo->Size; + } + return EFI_SUCCESS; + + } else if (CompareMem(Type, &gEfiFileSystemVolumeLabelInfoIdGuid, sizeof(*Type)) == 0) { + + /* Get the volume label */ + Status = GrubLabel(File, &label); + if (EFI_ERROR(Status)) { + PrintStatusError(Status, L"Could not read disk label"); + } + else { + Status = Utf8ToUtf16NoAllocUpdateLen(label, VLInfo->VolumeLabel, Len); + if (EFI_ERROR(Status)) { + if (Status != EFI_BUFFER_TOO_SMALL) + PrintStatusError(Status, L"Could not convert label to UTF-16"); + return Status; + } + } + return EFI_SUCCESS; + + } else { + + Print(L"'%s': Cannot get information of type ", FileName(File)); + PrintGuid(Type); + Print(L"\n"); + return EFI_UNSUPPORTED; + + } +} + +/** + * Set file information + * + * @v This File handle + * @v Type Type of information + * @v Len Buffer size + * @v Data Buffer + * @ret Status EFI status code + */ +static EFI_STATUS EFIAPI +FileSetInfo(EFI_FILE_HANDLE This, EFI_GUID *Type, UINTN Len, VOID *Data) +{ + EFI_GRUB_FILE *File = _CR(This, EFI_GRUB_FILE, EfiFile); + + Print(L"Cannot set information of type "); + PrintGuid(Type); + Print(L" for file '%s'\n", FileName(File)); + + return EFI_WRITE_PROTECTED; +} + +/** + * Flush file modified data + * + * @v This File handle + * @v Type Type of information + * @v Len Buffer size + * @v Data Buffer + * @ret Status EFI status code + */ +static EFI_STATUS EFIAPI +FileFlush(EFI_FILE_HANDLE This) +{ + EFI_GRUB_FILE *File = _CR(This, EFI_GRUB_FILE, EfiFile); + + PrintInfo(L"Flush(" PERCENT_P L"|'%s')\n", (UINTN) This, FileName(File)); + return EFI_SUCCESS; +} + +/* Ex version */ +static EFI_STATUS EFIAPI +FileFlushEx(EFI_FILE_HANDLE This, EFI_FILE_IO_TOKEN *Token) +{ + return FileFlush(This); +} + +/** + * Open root directory + * + * @v This EFI simple file system + * @ret Root File handle for the root directory + * @ret Status EFI status code + */ +EFI_STATUS EFIAPI +FileOpenVolume(EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, EFI_FILE_HANDLE *Root) +{ + EFI_FS *FSInstance = _CR(This, EFI_FS, FileIoInterface); + + PrintInfo(L"OpenVolume\n"); + *Root = &FSInstance->RootFile->EfiFile; + + return EFI_SUCCESS; +} + +/** + * Install the EFI simple file system protocol + * If successful this call instantiates a new FS#: drive, that is made + * available on the next 'map -r'. Note that all this call does is add + * the FS protocol. OpenVolume won't be called until a process tries + * to access a file or the root directory on the volume. + */ +EFI_STATUS +FSInstall(EFI_FS *This, EFI_HANDLE ControllerHandle) +{ + EFI_STATUS Status; + + /* Check if it's a filesystem we can handle */ + if (!GrubFSProbe(This)) + return EFI_UNSUPPORTED; + + PrintInfo(L"FSInstall: %s\n", This->DevicePathString); + + /* Initialize the root handle */ + Status = GrubCreateFile(&This->RootFile, This); + if (EFI_ERROR(Status)) { + PrintStatusError(Status, L"Could not create root file"); + return Status; + } + + /* Setup the EFI part */ + This->RootFile->EfiFile.Revision = EFI_FILE_PROTOCOL_REVISION2; + This->RootFile->EfiFile.Open = FileOpen; + This->RootFile->EfiFile.Close = FileClose; + This->RootFile->EfiFile.Delete = FileDelete; + This->RootFile->EfiFile.Read = FileRead; + This->RootFile->EfiFile.Write = FileWrite; + This->RootFile->EfiFile.GetPosition = FileGetPosition; + This->RootFile->EfiFile.SetPosition = FileSetPosition; + This->RootFile->EfiFile.GetInfo = FileGetInfo; + This->RootFile->EfiFile.SetInfo = FileSetInfo; + This->RootFile->EfiFile.Flush = FileFlush; + This->RootFile->EfiFile.OpenEx = FileOpenEx; + This->RootFile->EfiFile.ReadEx = FileReadEx; + This->RootFile->EfiFile.WriteEx = FileWriteEx; + This->RootFile->EfiFile.FlushEx = FileFlushEx; + + /* Setup the other attributes */ + This->RootFile->path = "/"; + This->RootFile->basename = &This->RootFile->path[1]; + This->RootFile->IsDir = TRUE; + + /* Install the simple file system protocol. */ + Status = BS->InstallMultipleProtocolInterfaces(&ControllerHandle, + &gEfiSimpleFileSystemProtocolGuid, &This->FileIoInterface, + NULL); + if (EFI_ERROR(Status)) { + PrintStatusError(Status, L"Could not install simple file system protocol"); + return Status; + } + + return EFI_SUCCESS; +} + +/* Uninstall EFI simple file system protocol */ +VOID +FSUninstall(EFI_FS *This, EFI_HANDLE ControllerHandle) +{ + PrintInfo(L"FSUninstall: %s\n", This->DevicePathString); + + BS->UninstallMultipleProtocolInterfaces(ControllerHandle, + &gEfiSimpleFileSystemProtocolGuid, &This->FileIoInterface, + NULL); +} diff --git a/EDK2/efiffs/mod/src/logging.c b/EDK2/efiffs/mod/src/logging.c new file mode 100644 index 0000000..8366134 --- /dev/null +++ b/EDK2/efiffs/mod/src/logging.c @@ -0,0 +1,86 @@ +/* logging.c - EFI logging */ +/* + * Copyright © 2014-2017 Pete Batard + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "driver.h" + +/* Not defined in gnu-efi yet */ +#define SHELL_VARIABLE_GUID { \ + 0x158def5a, 0xf656, 0x419c, { 0xb0, 0x27, 0x7a, 0x31, 0x92, 0xc0, 0x79, 0xd2 } \ +} +extern EFI_GUID gShellVariableGuid; +EFI_GUID ShellVariable = SHELL_VARIABLE_GUID; + +static UINTN PrintNone(IN CONST CHAR16 *fmt, ... ) { return 0; } +Print_t PrintError = PrintNone; +Print_t PrintWarning = PrintNone; +Print_t PrintInfo = PrintNone; +Print_t PrintDebug = PrintNone; +Print_t PrintExtra = PrintNone; +Print_t* PrintTable[] = { &PrintError, &PrintWarning, &PrintInfo, + &PrintDebug, &PrintExtra }; + +/* Global driver verbosity level */ +#if !defined(DEFAULT_LOGLEVEL) +#define DEFAULT_LOGLEVEL FS_LOGLEVEL_NONE +#endif +UINTN LogLevel = DEFAULT_LOGLEVEL; + +/** + * Print status + * + * @v Status EFI status code + */ +VOID +PrintStatus(EFI_STATUS Status) +{ +#if defined(__MAKEWITH_GNUEFI) + CHAR16 StatusString[64]; + StatusToString(StatusString, Status); + // Make sure the Status is unsigned 32 bits + Print(L": [%d] %s\n", (Status & 0x7FFFFFFF), StatusString); +#else + Print(L": [%d]\n", (Status & 0x7FFFFFFF)); +#endif +} + +int g_fs_name_nocase = 0; +/* + * You can control the verbosity of the driver output by setting the shell environment + * variable FS_LOGGING to one of the values defined in the FS_LOGLEVEL constants + */ +VOID +SetLogging(VOID) +{ + EFI_STATUS Status; + CHAR16 LogVar[4]; + UINTN i, LogVarSize = sizeof(LogVar); + + i = LogVarSize; + Status = RT->GetVariable(L"FS_NAME_NOCASE", &ShellVariable, NULL, &i, LogVar); + if (Status == EFI_SUCCESS) + g_fs_name_nocase = 1; + + Status = RT->GetVariable(L"FS_LOGGING", &ShellVariable, NULL, &LogVarSize, LogVar); + if (Status == EFI_SUCCESS) + LogLevel = Atoi(LogVar); + + for (i=0; i. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +#define GRUB_ISO9660_FSTYPE_DIR 0040000 +#define GRUB_ISO9660_FSTYPE_REG 0100000 +#define GRUB_ISO9660_FSTYPE_SYMLINK 0120000 +#define GRUB_ISO9660_FSTYPE_MASK 0170000 + +#define GRUB_ISO9660_LOG2_BLKSZ 2 +#define GRUB_ISO9660_BLKSZ 2048 + +#define GRUB_ISO9660_RR_DOT 2 +#define GRUB_ISO9660_RR_DOTDOT 4 + +#define GRUB_ISO9660_VOLDESC_BOOT 0 +#define GRUB_ISO9660_VOLDESC_PRIMARY 1 +#define GRUB_ISO9660_VOLDESC_SUPP 2 +#define GRUB_ISO9660_VOLDESC_PART 3 +#define GRUB_ISO9660_VOLDESC_END 255 + +/* The head of a volume descriptor. */ +PRAGMA_BEGIN_PACKED +struct grub_iso9660_voldesc +{ + grub_uint8_t type; + grub_uint8_t magic[5]; + grub_uint8_t version; +} GRUB_PACKED; + +struct grub_iso9660_date2 +{ + grub_uint8_t year; + grub_uint8_t month; + grub_uint8_t day; + grub_uint8_t hour; + grub_uint8_t minute; + grub_uint8_t second; + grub_uint8_t offset; +} GRUB_PACKED; + +/* A directory entry. */ +struct grub_iso9660_dir +{ + grub_uint8_t len; + grub_uint8_t ext_sectors; + grub_uint32_t first_sector; + grub_uint32_t first_sector_be; + grub_uint32_t size; + grub_uint32_t size_be; + struct grub_iso9660_date2 mtime; + grub_uint8_t flags; + grub_uint8_t unused2[6]; +#define MAX_NAMELEN 255 + grub_uint8_t namelen; +} GRUB_PACKED; + +struct grub_iso9660_date +{ + grub_uint8_t year[4]; + grub_uint8_t month[2]; + grub_uint8_t day[2]; + grub_uint8_t hour[2]; + grub_uint8_t minute[2]; + grub_uint8_t second[2]; + grub_uint8_t hundredth[2]; + grub_uint8_t offset; +} GRUB_PACKED; + +/* The primary volume descriptor. Only little endian is used. */ +struct grub_iso9660_primary_voldesc +{ + struct grub_iso9660_voldesc voldesc; + grub_uint8_t unused1[33]; + grub_uint8_t volname[32]; + grub_uint8_t unused2[16]; + grub_uint8_t escape[32]; + grub_uint8_t unused3[12]; + grub_uint32_t path_table_size; + grub_uint8_t unused4[4]; + grub_uint32_t path_table; + grub_uint8_t unused5[12]; + struct grub_iso9660_dir rootdir; + grub_uint8_t unused6[624]; + struct grub_iso9660_date created; + struct grub_iso9660_date modified; +} GRUB_PACKED; + +/* A single entry in the path table. */ +struct grub_iso9660_path +{ + grub_uint8_t len; + grub_uint8_t sectors; + grub_uint32_t first_sector; + grub_uint16_t parentdir; + grub_uint8_t name[0]; +} GRUB_PACKED; + +/* An entry in the System Usage area of the directory entry. */ +struct grub_iso9660_susp_entry +{ + grub_uint8_t sig[2]; + grub_uint8_t len; +/*! MSVC compilers cannot handle a zero sized array in the middle + of a struct, and grub_iso9660_susp_entry is reused within + grub_iso9660_susp_ce. Therefore, instead of defining: + grub_uint8_t version; + grub_uint8_t data[]; + we leverage the fact that these attributes are the same size + and use an union. The only gotcha is that the actual + payload of u.data[] starts at 1, not 0. */ + union { + grub_uint8_t version; + grub_uint8_t data[1]; + } u; +} GRUB_PACKED; + +/* The CE entry. This is used to describe the next block where data + can be found. */ +struct grub_iso9660_susp_ce +{ + struct grub_iso9660_susp_entry entry; + grub_uint32_t blk; + grub_uint32_t blk_be; + grub_uint32_t off; + grub_uint32_t off_be; + grub_uint32_t len; + grub_uint32_t len_be; +} GRUB_PACKED; +PRAGMA_END_PACKED + +struct grub_iso9660_data +{ + struct grub_iso9660_primary_voldesc voldesc; + grub_disk_t disk; + int rockridge; + int susp_skip; + int joliet; + struct grub_fshelp_node *node; +}; + +struct grub_fshelp_node +{ + struct grub_iso9660_data *data; + grub_size_t have_dirents, alloc_dirents; + int have_symlink; + struct grub_iso9660_dir dirents[8]; + char symlink[0]; +}; + +enum + { + FLAG_TYPE_PLAIN = 0, + FLAG_TYPE_DIR = 2, + FLAG_TYPE = 3, + FLAG_MORE_EXTENTS = 0x80 + }; + +static grub_dl_t my_mod; + + +static grub_err_t +iso9660_to_unixtime (const struct grub_iso9660_date *i, grub_int32_t *nix) +{ + struct grub_datetime datetime; + + if (! i->year[0] && ! i->year[1] + && ! i->year[2] && ! i->year[3] + && ! i->month[0] && ! i->month[1] + && ! i->day[0] && ! i->day[1] + && ! i->hour[0] && ! i->hour[1] + && ! i->minute[0] && ! i->minute[1] + && ! i->second[0] && ! i->second[1] + && ! i->hundredth[0] && ! i->hundredth[1]) + return grub_error (GRUB_ERR_BAD_NUMBER, "empty date"); + datetime.year = (i->year[0] - '0') * 1000 + (i->year[1] - '0') * 100 + + (i->year[2] - '0') * 10 + (i->year[3] - '0'); + datetime.month = (i->month[0] - '0') * 10 + (i->month[1] - '0'); + datetime.day = (i->day[0] - '0') * 10 + (i->day[1] - '0'); + datetime.hour = (i->hour[0] - '0') * 10 + (i->hour[1] - '0'); + datetime.minute = (i->minute[0] - '0') * 10 + (i->minute[1] - '0'); + datetime.second = (i->second[0] - '0') * 10 + (i->second[1] - '0'); + + if (!grub_datetime2unixtime (&datetime, nix)) + return grub_error (GRUB_ERR_BAD_NUMBER, "incorrect date"); + *nix -= i->offset * 60 * 15; + return GRUB_ERR_NONE; +} + +static int +iso9660_to_unixtime2 (const struct grub_iso9660_date2 *i, grub_int32_t *nix) +{ + struct grub_datetime datetime; + + datetime.year = i->year + 1900; + datetime.month = i->month; + datetime.day = i->day; + datetime.hour = i->hour; + datetime.minute = i->minute; + datetime.second = i->second; + + if (!grub_datetime2unixtime (&datetime, nix)) + return 0; + *nix -= i->offset * 60 * 15; + return 1; +} + +static grub_err_t +read_node (grub_fshelp_node_t node, grub_off_t off, grub_size_t len, char *buf) +{ + grub_size_t i = 0; + + while (len > 0) + { + grub_size_t toread; + grub_err_t err; + while (i < node->have_dirents + && off >= grub_le_to_cpu32 (node->dirents[i].size)) + { + off -= grub_le_to_cpu32 (node->dirents[i].size); + i++; + } + if (i == node->have_dirents) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "read out of range"); + toread = grub_le_to_cpu32 (node->dirents[i].size); + if (toread > len) + toread = len; + err = grub_disk_read (node->data->disk, + ((grub_disk_addr_t) grub_le_to_cpu32 (node->dirents[i].first_sector)) << GRUB_ISO9660_LOG2_BLKSZ, + off, toread, buf); + if (err) + return err; + len -= toread; + off += toread; + buf += toread; + } + return GRUB_ERR_NONE; +} + +/* Iterate over the susp entries, starting with block SUA_BLOCK on the + offset SUA_POS with a size of SUA_SIZE bytes. Hook is called for + every entry. */ +static grub_err_t +grub_iso9660_susp_iterate (grub_fshelp_node_t node, grub_off_t off, + grub_ssize_t sua_size, + grub_err_t (*hook) + (struct grub_iso9660_susp_entry *entry, void *hook_arg), + void *hook_arg) +{ + char *sua; + struct grub_iso9660_susp_entry *entry; + grub_err_t err; + + if (sua_size <= 0) + return GRUB_ERR_NONE; + + sua = grub_malloc (sua_size); + if (!sua) + return grub_errno; + + /* Load a part of the System Usage Area. */ + err = read_node (node, off, sua_size, sua); + if (err) + return err; + + for (entry = (struct grub_iso9660_susp_entry *) sua; (char *) entry < (char *) sua + sua_size - 1 && entry->len > 0; + entry = (struct grub_iso9660_susp_entry *) + ((char *) entry + entry->len)) + { + /* The last entry. */ + if (grub_strncmp ((char *) entry->sig, "ST", 2) == 0) + break; + + /* Additional entries are stored elsewhere. */ + if (grub_strncmp ((char *) entry->sig, "CE", 2) == 0) + { + struct grub_iso9660_susp_ce *ce; + grub_disk_addr_t ce_block; + + ce = (struct grub_iso9660_susp_ce *) entry; + sua_size = grub_le_to_cpu32 (ce->len); + off = grub_le_to_cpu32 (ce->off); + ce_block = grub_le_to_cpu32 (ce->blk) << GRUB_ISO9660_LOG2_BLKSZ; + + grub_free (sua); + sua = grub_malloc (sua_size); + if (!sua) + return grub_errno; + + /* Load a part of the System Usage Area. */ + err = grub_disk_read (node->data->disk, ce_block, off, + sua_size, sua); + if (err) + return err; + + entry = (struct grub_iso9660_susp_entry *) sua; + } + + if (hook (entry, hook_arg)) + { + grub_free (sua); + return 0; + } + } + + grub_free (sua); + return 0; +} + +static char * +grub_iso9660_convert_string (grub_uint8_t *us, int len) +{ + char *p; + int i; + grub_uint16_t t[MAX_NAMELEN / 2 + 1]; + + p = grub_malloc (len * GRUB_MAX_UTF8_PER_UTF16 + 1); + if (! p) + return NULL; + + for (i=0; isig, "ER", 2) == 0) + { + data->rockridge = 1; + return 1; + } + return 0; +} + +static grub_err_t +set_rockridge (struct grub_iso9660_data *data) +{ + int sua_pos; + int sua_size; + char *sua; + struct grub_iso9660_dir rootdir; + struct grub_iso9660_susp_entry *entry; + + data->rockridge = 0; + + /* Read the system use area and test it to see if SUSP is + supported. */ + if (grub_disk_read (data->disk, + (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector) + << GRUB_ISO9660_LOG2_BLKSZ), 0, + sizeof (rootdir), (char *) &rootdir)) + return grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem"); + + sua_pos = (sizeof (rootdir) + rootdir.namelen + + (rootdir.namelen % 2) - 1); + sua_size = rootdir.len - sua_pos; + + if (!sua_size) + return GRUB_ERR_NONE; + + sua = grub_malloc (sua_size); + if (! sua) + return grub_errno; + + if (grub_disk_read (data->disk, + (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector) + << GRUB_ISO9660_LOG2_BLKSZ), sua_pos, + sua_size, sua)) + { + grub_free (sua); + return grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem"); + } + + entry = (struct grub_iso9660_susp_entry *) sua; + + /* Test if the SUSP protocol is used on this filesystem. */ + if (grub_strncmp ((char *) entry->sig, "SP", 2) == 0) + { + struct grub_fshelp_node rootnode; + + rootnode.data = data; + rootnode.alloc_dirents = ARRAY_SIZE (rootnode.dirents); + rootnode.have_dirents = 1; + rootnode.have_symlink = 0; + rootnode.dirents[0] = data->voldesc.rootdir; + + /* The 2nd data byte stored how many bytes are skipped every time + to get to the SUA (System Usage Area). */ + data->susp_skip = entry->u.data[1 + 2]; + entry = (struct grub_iso9660_susp_entry *) ((char *) entry + entry->len); + + /* Iterate over the entries in the SUA area to detect + extensions. */ + if (grub_iso9660_susp_iterate (&rootnode, + sua_pos, sua_size, susp_iterate_set_rockridge, + data)) + { + grub_free (sua); + return grub_errno; + } + } + grub_free (sua); + return GRUB_ERR_NONE; +} + +static struct grub_iso9660_data * +grub_iso9660_mount (grub_disk_t disk) +{ + struct grub_iso9660_data *data = 0; + struct grub_iso9660_primary_voldesc voldesc; + int block; + + data = grub_zalloc (sizeof (struct grub_iso9660_data)); + if (! data) + return 0; + + data->disk = disk; + + block = 16; + do + { + int copy_voldesc = 0; + + /* Read the superblock. */ + if (grub_disk_read (disk, block << GRUB_ISO9660_LOG2_BLKSZ, 0, + sizeof (struct grub_iso9660_primary_voldesc), + (char *) &voldesc)) + { + grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem"); + goto fail; + } + + if (grub_strncmp ((char *) voldesc.voldesc.magic, "CD001", 5) != 0) + { + grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem"); + goto fail; + } + + if (voldesc.voldesc.type == GRUB_ISO9660_VOLDESC_PRIMARY) + copy_voldesc = 1; + else if (!data->rockridge + && (voldesc.voldesc.type == GRUB_ISO9660_VOLDESC_SUPP) + && (voldesc.escape[0] == 0x25) && (voldesc.escape[1] == 0x2f) + && + ((voldesc.escape[2] == 0x40) || /* UCS-2 Level 1. */ + (voldesc.escape[2] == 0x43) || /* UCS-2 Level 2. */ + (voldesc.escape[2] == 0x45))) /* UCS-2 Level 3. */ + { + copy_voldesc = 1; + data->joliet = 1; + } + + if (copy_voldesc) + { + grub_memcpy((char *) &data->voldesc, (char *) &voldesc, + sizeof (struct grub_iso9660_primary_voldesc)); + if (set_rockridge (data)) + goto fail; + } + + block++; + } while (voldesc.voldesc.type != GRUB_ISO9660_VOLDESC_END); + + return data; + + fail: + grub_free (data); + return 0; +} + + +static char * +grub_iso9660_read_symlink (grub_fshelp_node_t node) +{ + return node->have_symlink + ? grub_strdup (node->symlink + + (node->have_dirents) * sizeof (node->dirents[0]) + - sizeof (node->dirents)) : grub_strdup (""); +} + +static grub_off_t +get_node_size (grub_fshelp_node_t node) +{ + grub_off_t ret = 0; + grub_size_t i; + + for (i = 0; i < node->have_dirents; i++) + ret += grub_le_to_cpu32 (node->dirents[i].size); + return ret; +} + +struct iterate_dir_ctx +{ + char *filename; + int filename_alloc; + enum grub_fshelp_filetype type; + char *symlink; + int was_continue; +}; + + /* Extend the symlink. */ +static void +add_part (struct iterate_dir_ctx *ctx, + const char *part, + int len2) +{ + int size = ctx->symlink ? grub_strlen (ctx->symlink) : 0; + + ctx->symlink = grub_realloc (ctx->symlink, size + len2 + 1); + if (! ctx->symlink) + return; + + grub_memcpy (ctx->symlink + size, part, len2); + ctx->symlink[size + len2] = 0; +} + +static grub_err_t +susp_iterate_dir (struct grub_iso9660_susp_entry *entry, + void *_ctx) +{ + struct iterate_dir_ctx *ctx = _ctx; + + /* The filename in the rock ridge entry. */ + if (grub_strncmp ("NM", (char *) entry->sig, 2) == 0) + { + /* The flags are stored at the data position 0, here the + filename type is stored. */ + /* FIXME: Fix this slightly improper cast. */ + if (entry->u.data[1 + 0] & GRUB_ISO9660_RR_DOT) + ctx->filename = (char *) "."; + else if (entry->u.data[1 + 0] & GRUB_ISO9660_RR_DOTDOT) + ctx->filename = (char *) ".."; + else if (entry->len >= 5) + { + grub_size_t off = 0, csize = 1; + char *old; + csize = entry->len - 5; + old = ctx->filename; + if (ctx->filename_alloc) + { + off = grub_strlen (ctx->filename); + ctx->filename = grub_realloc (ctx->filename, csize + off + 1); + } + else + { + off = 0; + ctx->filename = grub_zalloc (csize + 1); + } + if (!ctx->filename) + { + ctx->filename = old; + return grub_errno; + } + ctx->filename_alloc = 1; + grub_memcpy (ctx->filename + off, (char *) &entry->u.data[1 + 1], csize); + ctx->filename[off + csize] = '\0'; + } + } + /* The mode information (st_mode). */ + else if (grub_strncmp ((char *) entry->sig, "PX", 2) == 0) + { + /* At position 0 of the PX record the st_mode information is + stored (little-endian). */ + grub_uint32_t mode = ((entry->u.data[1 + 0] + (entry->u.data[1 + 1] << 8)) + & GRUB_ISO9660_FSTYPE_MASK); + + switch (mode) + { + case GRUB_ISO9660_FSTYPE_DIR: + ctx->type = GRUB_FSHELP_DIR; + break; + case GRUB_ISO9660_FSTYPE_REG: + ctx->type = GRUB_FSHELP_REG; + break; + case GRUB_ISO9660_FSTYPE_SYMLINK: + ctx->type = GRUB_FSHELP_SYMLINK; + break; + default: + ctx->type = GRUB_FSHELP_UNKNOWN; + } + } + else if (grub_strncmp ("SL", (char *) entry->sig, 2) == 0) + { + unsigned int pos = 1; + + /* The symlink is not stored as a POSIX symlink, translate it. */ + while (pos + sizeof (*entry) < entry->len) + { + /* The current position is the `Component Flag'. */ + switch (entry->u.data[1 + pos] & 30) + { + case 0: + { + /* The data on pos + 2 is the actual data, pos + 1 + is the length. Both are part of the `Component + Record'. */ + if (ctx->symlink && !ctx->was_continue) + add_part (ctx, "/", 1); + add_part (ctx, (char *) &entry->u.data[1 + pos + 2], + entry->u.data[1 + pos + 1]); + ctx->was_continue = (entry->u.data[1 + pos] & 1); + break; + } + + case 2: + add_part (ctx, "./", 2); + break; + + case 4: + add_part (ctx, "../", 3); + break; + + case 8: + add_part (ctx, "/", 1); + break; + } + /* In pos + 1 the length of the `Component Record' is + stored. */ + pos += entry->u.data[1 + pos + 1] + 2; + } + + /* Check if `grub_realloc' failed. */ + if (grub_errno) + return grub_errno; + } + + return 0; +} + +static int +grub_iso9660_iterate_dir (grub_fshelp_node_t dir, + grub_fshelp_iterate_dir_hook_t hook, void *hook_data) +{ + struct grub_iso9660_dir dirent; + grub_off_t offset = 0; + grub_off_t len; + struct iterate_dir_ctx ctx; + + len = get_node_size (dir); + + for (; offset < len; offset += dirent.len) + { + ctx.symlink = 0; + ctx.was_continue = 0; + + if (read_node (dir, offset, sizeof (dirent), (char *) &dirent)) + return 0; + + /* The end of the block, skip to the next one. */ + if (!dirent.len) + { + offset = (offset / GRUB_ISO9660_BLKSZ + 1) * GRUB_ISO9660_BLKSZ; + continue; + } + + { + char name[MAX_NAMELEN + 1]; + int nameoffset = offset + sizeof (dirent); + struct grub_fshelp_node *node; + int sua_off = (sizeof (dirent) + dirent.namelen + 1 + - (dirent.namelen % 2)); + int sua_size = dirent.len - sua_off; + + sua_off += offset + dir->data->susp_skip; + + ctx.filename = 0; + ctx.filename_alloc = 0; + ctx.type = GRUB_FSHELP_UNKNOWN; + + if (dir->data->rockridge + && grub_iso9660_susp_iterate (dir, sua_off, sua_size, + susp_iterate_dir, &ctx)) + return 0; + + /* Read the name. */ + if (read_node (dir, nameoffset, dirent.namelen, (char *) name)) + return 0; + + node = grub_malloc (sizeof (struct grub_fshelp_node)); + if (!node) + return 0; + + node->alloc_dirents = ARRAY_SIZE (node->dirents); + node->have_dirents = 1; + + /* Setup a new node. */ + node->data = dir->data; + node->have_symlink = 0; + + /* If the filetype was not stored using rockridge, use + whatever is stored in the iso9660 filesystem. */ + if (ctx.type == GRUB_FSHELP_UNKNOWN) + { + if ((dirent.flags & FLAG_TYPE) == FLAG_TYPE_DIR) + ctx.type = GRUB_FSHELP_DIR; + else + ctx.type = GRUB_FSHELP_REG; + } + + /* . and .. */ + if (!ctx.filename && dirent.namelen == 1 && name[0] == 0) + ctx.filename = (char *) "."; + + if (!ctx.filename && dirent.namelen == 1 && name[0] == 1) + ctx.filename = (char *) ".."; + + /* The filename was not stored in a rock ridge entry. Read it + from the iso9660 filesystem. */ + if (!dir->data->joliet && !ctx.filename) + { + char *ptr; + name[dirent.namelen] = '\0'; + ctx.filename = grub_strrchr (name, ';'); + if (ctx.filename) + *ctx.filename = '\0'; + /* ISO9660 names are not case-preserving. */ + ctx.type |= GRUB_FSHELP_CASE_INSENSITIVE; + for (ptr = name; *ptr; ptr++) + *ptr = grub_tolower (*ptr); + if (ptr != name && *(ptr - 1) == '.') + *(ptr - 1) = 0; + ctx.filename = name; + } + + if (dir->data->joliet && !ctx.filename) + { + char *semicolon; + + ctx.filename = grub_iso9660_convert_string + ((grub_uint8_t *) name, dirent.namelen >> 1); + + semicolon = grub_strrchr (ctx.filename, ';'); + if (semicolon) + *semicolon = '\0'; + + ctx.filename_alloc = 1; + } + + node->dirents[0] = dirent; + while (dirent.flags & FLAG_MORE_EXTENTS) + { + offset += dirent.len; + if (read_node (dir, offset, sizeof (dirent), (char *) &dirent)) + { + if (ctx.filename_alloc) + grub_free (ctx.filename); + grub_free (node); + return 0; + } + if (node->have_dirents >= node->alloc_dirents) + { + struct grub_fshelp_node *new_node; + node->alloc_dirents *= 2; + new_node = grub_realloc (node, + sizeof (struct grub_fshelp_node) + + ((node->alloc_dirents + - ARRAY_SIZE (node->dirents)) + * sizeof (node->dirents[0]))); + if (!new_node) + { + if (ctx.filename_alloc) + grub_free (ctx.filename); + grub_free (node); + return 0; + } + node = new_node; + } + node->dirents[node->have_dirents++] = dirent; + } + if (ctx.symlink) + { + if ((node->alloc_dirents - node->have_dirents) + * sizeof (node->dirents[0]) < grub_strlen (ctx.symlink) + 1) + { + struct grub_fshelp_node *new_node; + new_node = grub_realloc (node, + sizeof (struct grub_fshelp_node) + + ((node->alloc_dirents + - ARRAY_SIZE (node->dirents)) + * sizeof (node->dirents[0])) + + grub_strlen (ctx.symlink) + 1); + if (!new_node) + { + if (ctx.filename_alloc) + grub_free (ctx.filename); + grub_free (node); + return 0; + } + node = new_node; + } + node->have_symlink = 1; + grub_strcpy (node->symlink + + node->have_dirents * sizeof (node->dirents[0]) + - sizeof (node->dirents), ctx.symlink); + grub_free (ctx.symlink); + ctx.symlink = 0; + ctx.was_continue = 0; + } + if (hook (ctx.filename, ctx.type, node, hook_data)) + { + if (ctx.filename_alloc) + grub_free (ctx.filename); + return 1; + } + if (ctx.filename_alloc) + grub_free (ctx.filename); + } + } + + return 0; +} + + + +/* Context for grub_iso9660_dir. */ +struct grub_iso9660_dir_ctx +{ + grub_fs_dir_hook_t hook; + void *hook_data; +}; + +/* Helper for grub_iso9660_dir. */ +static int +grub_iso9660_dir_iter (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node, void *data) +{ + struct grub_iso9660_dir_ctx *ctx = data; + struct grub_dirhook_info info; + + grub_memset (&info, 0, sizeof (info)); + info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); + info.mtimeset = !!iso9660_to_unixtime2 (&node->dirents[0].mtime, &info.mtime); + + grub_free (node); + return ctx->hook (filename, &info, ctx->hook_data); +} + +static grub_err_t +grub_iso9660_dir (grub_device_t device, const char *path, + grub_fs_dir_hook_t hook, void *hook_data) +{ + struct grub_iso9660_dir_ctx ctx = { hook, hook_data }; + struct grub_iso9660_data *data = 0; + struct grub_fshelp_node rootnode; + struct grub_fshelp_node *foundnode; + + grub_dl_ref (my_mod); + + data = grub_iso9660_mount (device->disk); + if (! data) + goto fail; + + rootnode.data = data; + rootnode.alloc_dirents = 0; + rootnode.have_dirents = 1; + rootnode.have_symlink = 0; + rootnode.dirents[0] = data->voldesc.rootdir; + + /* Use the fshelp function to traverse the path. */ + if (grub_fshelp_find_file (path, &rootnode, + &foundnode, + grub_iso9660_iterate_dir, + grub_iso9660_read_symlink, + GRUB_FSHELP_DIR)) + goto fail; + + /* List the files in the directory. */ + grub_iso9660_iterate_dir (foundnode, grub_iso9660_dir_iter, &ctx); + + if (foundnode != &rootnode) + grub_free (foundnode); + + fail: + grub_free (data); + + grub_dl_unref (my_mod); + + return grub_errno; +} + + +/* Open a file named NAME and initialize FILE. */ +static grub_err_t +grub_iso9660_open (struct grub_file *file, const char *name) +{ + struct grub_iso9660_data *data; + struct grub_fshelp_node rootnode; + struct grub_fshelp_node *foundnode; + + grub_dl_ref (my_mod); + + data = grub_iso9660_mount (file->device->disk); + if (!data) + goto fail; + + rootnode.data = data; + rootnode.alloc_dirents = 0; + rootnode.have_dirents = 1; + rootnode.have_symlink = 0; + rootnode.dirents[0] = data->voldesc.rootdir; + + /* Use the fshelp function to traverse the path. */ + if (grub_fshelp_find_file (name, &rootnode, + &foundnode, + grub_iso9660_iterate_dir, + grub_iso9660_read_symlink, + GRUB_FSHELP_REG)) + goto fail; + + data->node = foundnode; + file->data = data; + file->size = get_node_size (foundnode); + file->offset = 0; + + return 0; + + fail: + grub_dl_unref (my_mod); + + grub_free (data); + + return grub_errno; +} + + +static grub_ssize_t +grub_iso9660_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_iso9660_data *data = + (struct grub_iso9660_data *) file->data; + grub_err_t err; + + /* XXX: The file is stored in as a single extent. */ + data->disk->read_hook = file->read_hook; + data->disk->read_hook_data = file->read_hook_data; + err = read_node (data->node, file->offset, len, buf); + data->disk->read_hook = NULL; + + if (err || grub_errno) + return -1; + + return len; +} + + +static grub_err_t +grub_iso9660_close (grub_file_t file) +{ + struct grub_iso9660_data *data = + (struct grub_iso9660_data *) file->data; + grub_free (data->node); + grub_free (data); + + grub_dl_unref (my_mod); + + return GRUB_ERR_NONE; +} + + +static grub_err_t +grub_iso9660_label (grub_device_t device, char **label) +{ + struct grub_iso9660_data *data; + data = grub_iso9660_mount (device->disk); + + if (data) + { + if (data->joliet) + *label = grub_iso9660_convert_string (data->voldesc.volname, 16); + else + *label = grub_strndup ((char *) data->voldesc.volname, 32); + if (*label) + { + char *ptr; + for (ptr = *label; *ptr;ptr++); + ptr--; + while (ptr >= *label && *ptr == ' ') + *ptr-- = 0; + } + + grub_free (data); + } + else + *label = 0; + + return grub_errno; +} + + +static grub_err_t +grub_iso9660_uuid (grub_device_t device, char **uuid) +{ + struct grub_iso9660_data *data; + grub_disk_t disk = device->disk; + + grub_dl_ref (my_mod); + + data = grub_iso9660_mount (disk); + if (data) + { + if (! data->voldesc.modified.year[0] && ! data->voldesc.modified.year[1] + && ! data->voldesc.modified.year[2] && ! data->voldesc.modified.year[3] + && ! data->voldesc.modified.month[0] && ! data->voldesc.modified.month[1] + && ! data->voldesc.modified.day[0] && ! data->voldesc.modified.day[1] + && ! data->voldesc.modified.hour[0] && ! data->voldesc.modified.hour[1] + && ! data->voldesc.modified.minute[0] && ! data->voldesc.modified.minute[1] + && ! data->voldesc.modified.second[0] && ! data->voldesc.modified.second[1] + && ! data->voldesc.modified.hundredth[0] && ! data->voldesc.modified.hundredth[1]) + { + grub_error (GRUB_ERR_BAD_NUMBER, "no creation date in filesystem to generate UUID"); + *uuid = NULL; + } + else + { + *uuid = grub_xasprintf ("%c%c%c%c-%c%c-%c%c-%c%c-%c%c-%c%c-%c%c", + data->voldesc.modified.year[0], + data->voldesc.modified.year[1], + data->voldesc.modified.year[2], + data->voldesc.modified.year[3], + data->voldesc.modified.month[0], + data->voldesc.modified.month[1], + data->voldesc.modified.day[0], + data->voldesc.modified.day[1], + data->voldesc.modified.hour[0], + data->voldesc.modified.hour[1], + data->voldesc.modified.minute[0], + data->voldesc.modified.minute[1], + data->voldesc.modified.second[0], + data->voldesc.modified.second[1], + data->voldesc.modified.hundredth[0], + data->voldesc.modified.hundredth[1]); + } + } + else + *uuid = NULL; + + grub_dl_unref (my_mod); + + grub_free (data); + + return grub_errno; +} + +/* Get writing time of filesystem. */ +static grub_err_t +grub_iso9660_mtime (grub_device_t device, grub_int32_t *timebuf) +{ + struct grub_iso9660_data *data; + grub_disk_t disk = device->disk; + grub_err_t err; + + grub_dl_ref (my_mod); + + data = grub_iso9660_mount (disk); + if (!data) + { + grub_dl_unref (my_mod); + return grub_errno; + } + err = iso9660_to_unixtime (&data->voldesc.modified, timebuf); + + grub_dl_unref (my_mod); + + grub_free (data); + + return err; +} + + + + +static struct grub_fs grub_iso9660_fs = + { + .name = "iso9660", + .fs_dir = grub_iso9660_dir, + .fs_open = grub_iso9660_open, + .fs_read = grub_iso9660_read, + .fs_close = grub_iso9660_close, + .fs_label = grub_iso9660_label, + .fs_uuid = grub_iso9660_uuid, + .fs_mtime = grub_iso9660_mtime, +#ifdef GRUB_UTIL + .reserved_first_sector = 1, + .blocklist_install = 1, +#endif + .next = 0 + }; + +GRUB_MOD_INIT(iso9660) +{ + grub_fs_register (&grub_iso9660_fs); + my_mod = mod; +} + +GRUB_MOD_FINI(iso9660) +{ + grub_fs_unregister (&grub_iso9660_fs); +} diff --git a/EDK2/efiffs/org/src/file.c b/EDK2/efiffs/org/src/file.c new file mode 100644 index 0000000..66b6780 --- /dev/null +++ b/EDK2/efiffs/org/src/file.c @@ -0,0 +1,784 @@ +/* file.c - SimpleFileIo Interface */ +/* + * Copyright © 2014-2017 Pete Batard + * Based on iPXE's efi_driver.c and efi_file.c: + * Copyright © 2011,2013 Michael Brown . + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "driver.h" + +/** + * Get EFI file name (for debugging) + * + * @v file EFI file + * @ret Name Name + */ +static const CHAR16 * +FileName(EFI_GRUB_FILE *File) +{ + EFI_STATUS Status; + static CHAR16 Path[MAX_PATH]; + + Status = Utf8ToUtf16NoAlloc(File->path, Path, sizeof(Path)); + if (EFI_ERROR(Status)) { + PrintStatusError(Status, L"Could not convert filename to UTF16"); + return NULL; + } + + return Path; +} + +/* Simple hook to populate the timestamp and directory flag when opening a file */ +static INT32 +InfoHook(const CHAR8 *name, const GRUB_DIRHOOK_INFO *Info, VOID *Data) +{ + EFI_GRUB_FILE *File = (EFI_GRUB_FILE *) Data; + + /* Look for a specific file */ + if (strcmpa(name, File->basename) != 0) + return 0; + + File->IsDir = (BOOLEAN) (Info->Dir); + if (Info->MtimeSet) + File->Mtime = Info->Mtime; + + return 0; +} + +/** + * Open file + * + * @v This File handle + * @ret new New file handle + * @v Name File name + * @v Mode File mode + * @v Attributes File attributes (for newly-created files) + * @ret Status EFI status code + */ +static EFI_STATUS EFIAPI +FileOpen(EFI_FILE_HANDLE This, EFI_FILE_HANDLE *New, + CHAR16 *Name, UINT64 Mode, UINT64 Attributes) +{ + EFI_STATUS Status; + EFI_GRUB_FILE *File = _CR(This, EFI_GRUB_FILE, EfiFile); + EFI_GRUB_FILE *NewFile; + + // TODO: Use dynamic buffers? + char path[MAX_PATH], clean_path[MAX_PATH], *dirname; + INTN i, len; + BOOLEAN AbsolutePath = (*Name == L'\\'); + + PrintInfo(L"Open(" PERCENT_P L"%s, \"%s\")\n", (UINTN) This, + IS_ROOT(File)?L" ":L"", Name); + + /* Fail unless opening read-only */ + if (Mode != EFI_FILE_MODE_READ) { + PrintWarning(L"File '%s' can only be opened in read-only mode\n", Name); + return EFI_WRITE_PROTECTED; + } + + /* Additional failures */ + if ((StrCmp(Name, L"..") == 0) && IS_ROOT(File)) { + PrintInfo(L"Trying to open 's parent\n"); + return EFI_NOT_FOUND; + } + + /* See if we're trying to reopen current (which the EFI Shell insists on doing) */ + if ((*Name == 0) || (StrCmp(Name, L".") == 0)) { + PrintInfo(L" Reopening %s\n", IS_ROOT(File)?L"":FileName(File)); + File->RefCount++; + *New = This; + PrintInfo(L" RET: " PERCENT_P L"\n", (UINTN) *New); + return EFI_SUCCESS; + } + + /* If we have an absolute path, don't bother completing with the parent */ + if (AbsolutePath) { + len = 0; + } else { + strcpya(path, File->path); + len = strlena(path); + /* Add delimiter if needed */ + if ((len == 0) || (path[len-1] != '/')) + path[len++] = '/'; + } + + /* Copy the rest of the path (converted to UTF-8) */ + Status = Utf16ToUtf8NoAlloc(Name, &path[len], sizeof(path) - len); + if (EFI_ERROR(Status)) { + PrintStatusError(Status, L"Could not convert path to UTF-8"); + return Status; + } + /* Convert the delimiters */ + for (i = strlena(path) - 1 ; i >= len; i--) { + if (path[i] == '\\') + path[i] = '/'; + } + + /* We only want to handle with absolute paths */ + clean_path[0] = '/'; + /* Find out if we're dealing with root by removing the junk */ + CopyPathRelative(&clean_path[1], path, MAX_PATH - 1); + if (clean_path[1] == 0) { + /* We're dealing with the root */ + PrintInfo(L" Reopening \n"); + *New = &File->FileSystem->RootFile->EfiFile; + /* Must make sure that DirIndex is reset too (NB: no concurrent access!) */ + File->FileSystem->RootFile->DirIndex = 0; + PrintInfo(L" RET: " PERCENT_P L"\n", (UINTN) *New); + return EFI_SUCCESS; + } + + // TODO: eventually we should seek for already opened files and increase RefCount + /* Allocate and initialise an instance of a file */ + Status = GrubCreateFile(&NewFile, File->FileSystem); + if (EFI_ERROR(Status)) { + PrintStatusError(Status, L"Could not instantiate file"); + return Status; + } + + NewFile->path = AllocatePool(strlena(clean_path)+1); + if (NewFile->path == NULL) { + GrubDestroyFile(NewFile); + PrintError(L"Could not instantiate path\n"); + return EFI_OUT_OF_RESOURCES; + } + strcpya(NewFile->path, clean_path); + + /* Isolate the basename and dirname */ + for (i = strlena(clean_path) - 1; i >= 0; i--) { + if (clean_path[i] == '/') { + clean_path[i] = 0; + break; + } + } + dirname = (i <= 0) ? "/" : clean_path; + NewFile->basename = &NewFile->path[i+1]; + + /* Find if we're working with a directory and fill the grub timestamp */ + Status = GrubDir(NewFile, dirname, InfoHook, (VOID *) NewFile); + if (EFI_ERROR(Status)) { + if (Status != EFI_NOT_FOUND) + PrintStatusError(Status, L"Could not get file attributes for '%s'", Name); + FreePool(NewFile->path); + GrubDestroyFile(NewFile); + return Status; + } + + /* Finally we can call on GRUB open() if it's a regular file */ + if (!NewFile->IsDir) { + Status = GrubOpen(NewFile); + if (EFI_ERROR(Status)) { + if (Status != EFI_NOT_FOUND) + PrintStatusError(Status, L"Could not open file '%s'", Name); + FreePool(NewFile->path); + GrubDestroyFile(NewFile); + return Status; + } + } + + NewFile->RefCount++; + *New = &NewFile->EfiFile; + + PrintInfo(L" RET: " PERCENT_P L"\n", (UINTN) *New); + return EFI_SUCCESS; +} + +/* Ex version */ +static EFI_STATUS EFIAPI +FileOpenEx(EFI_FILE_HANDLE This, EFI_FILE_HANDLE *New, CHAR16 *Name, + UINT64 Mode, UINT64 Attributes, EFI_FILE_IO_TOKEN *Token) +{ + return FileOpen(This, New, Name, Mode, Attributes); +} + + +/** + * Close file + * + * @v This File handle + * @ret Status EFI status code + */ +static EFI_STATUS EFIAPI +FileClose(EFI_FILE_HANDLE This) +{ + EFI_GRUB_FILE *File = _CR(This, EFI_GRUB_FILE, EfiFile); + + PrintInfo(L"Close(" PERCENT_P L"|'%s') %s\n", (UINTN) This, FileName(File), + IS_ROOT(File)?L"":L""); + + /* Nothing to do it this is the root */ + if (IS_ROOT(File)) + return EFI_SUCCESS; + + if (--File->RefCount == 0) { + /* Close the file if it's a regular one */ + if (!File->IsDir) + GrubClose(File); + /* NB: basename points into File->path and does not need to be freed */ + if (File->path != NULL) + FreePool(File->path); + GrubDestroyFile(File); + } + + return EFI_SUCCESS; +} + +/** + * Close and delete file + * + * @v This File handle + * @ret Status EFI status code + */ +static EFI_STATUS EFIAPI +FileDelete(EFI_FILE_HANDLE This) +{ + EFI_GRUB_FILE *File = _CR(This, EFI_GRUB_FILE, EfiFile); + + PrintError(L"Cannot delete '%s'\n", FileName(File)); + + /* Close file */ + FileClose(This); + + /* Warn of failure to delete */ + return EFI_WARN_DELETE_FAILURE; +} + +/* GRUB uses a callback for each directory entry, whereas EFI uses repeated + * firmware generated calls to FileReadDir() to get the info for each entry, + * so we have to reconcile the twos. For now, we'll re-issue a call to GRUB + * dir(), and run through all the entries (to find the one we + * are interested in) multiple times. Maybe later we'll try to optimize this + * by building a one-off chained list of entries that we can parse... + */ +static INT32 +DirHook(const CHAR8 *name, const GRUB_DIRHOOK_INFO *DirInfo, VOID *Data) +{ + EFI_STATUS Status; + EFI_FILE_INFO *Info = (EFI_FILE_INFO *) Data; + INT64 *Index = (INT64 *) &Info->FileSize; + CHAR8 *filename = (CHAR8 *) (UINTN) Info->PhysicalSize; + EFI_TIME Time = { 1970, 01, 01, 00, 00, 00, 0, 0, 0, 0, 0}; + + // Eliminate '.' or '..' + if ((name[0] == '.') && ((name[1] == 0) || ((name[1] == '.') && (name[2] == 0)))) + return 0; + + /* Ignore any entry that doesn't match our index */ + if ((*Index)-- != 0) + return 0; + + strcpya(filename, name); + + Status = Utf8ToUtf16NoAlloc(filename, Info->FileName, (INTN)(Info->Size - sizeof(EFI_FILE_INFO))); + if (EFI_ERROR(Status)) { + if (Status != EFI_BUFFER_TOO_SMALL) + PrintStatusError(Status, L"Could not convert directory entry to UTF-8"); + return (INT32) Status; + } + /* The Info struct size already accounts for the extra NUL */ + Info->Size = sizeof(*Info) + StrLen(Info->FileName) * sizeof(CHAR16); + + // Oh, and of course GRUB uses a 32 bit signed mtime value (seriously, wtf guys?!?) + if (DirInfo->MtimeSet) + GrubTimeToEfiTime(DirInfo->Mtime, &Time); + CopyMem(&Info->CreateTime, &Time, sizeof(Time)); + CopyMem(&Info->LastAccessTime, &Time, sizeof(Time)); + CopyMem(&Info->ModificationTime, &Time, sizeof(Time)); + + Info->Attribute = EFI_FILE_READ_ONLY; + if (DirInfo->Dir) + Info->Attribute |= EFI_FILE_DIRECTORY; + + return 0; +} + +/** + * Read directory entry + * + * @v file EFI file + * @v Len Length to read + * @v Data Data buffer + * @ret Status EFI status code + */ +static EFI_STATUS +FileReadDir(EFI_GRUB_FILE *File, UINTN *Len, VOID *Data) +{ + EFI_FILE_INFO *Info = (EFI_FILE_INFO *) Data; + EFI_STATUS Status; + /* We temporarily repurpose the FileSize as a *signed* entry index */ + INT64 *Index = (INT64 *) &Info->FileSize; + /* And PhysicalSize as a pointer to our filename */ + CHAR8 **basename = (CHAR8 **) &Info->PhysicalSize; + CHAR8 path[MAX_PATH]; + EFI_GRUB_FILE *TmpFile = NULL; + INTN len; + + /* Unless we can fit our maximum size, forget it */ + if (*Len < MINIMUM_INFO_LENGTH) { + *Len = MINIMUM_INFO_LENGTH; + return EFI_BUFFER_TOO_SMALL; + } + + /* Populate our Info template */ + ZeroMem(Data, *Len); + Info->Size = *Len; + *Index = File->DirIndex; + strcpya(path, File->path); + len = strlena(path); + if (path[len-1] != '/') + path[len++] = '/'; + *basename = &path[len]; + + /* Invoke GRUB's directory listing */ + Status = GrubDir(File, File->path, DirHook, Data); + if (*Index >= 0) { + /* No more entries */ + *Len = 0; + return EFI_SUCCESS; + } + + if (EFI_ERROR(Status)) { + PrintStatusError(Status, L"Directory listing failed"); + return Status; + } + + /* Our Index/FileSize must be reset */ + Info->FileSize = 0; + Info->PhysicalSize = 0; + + /* For regular files, we still need to fill the size */ + if (!(Info->Attribute & EFI_FILE_DIRECTORY)) { + /* Open the file and read its size */ + Status = GrubCreateFile(&TmpFile, File->FileSystem); + if (EFI_ERROR(Status)) { + PrintStatusError(Status, L"Unable to create temporary file"); + return Status; + } + TmpFile->path = path; + + Status = GrubOpen(TmpFile); + if (EFI_ERROR(Status)) { + // TODO: EFI_NO_MAPPING is returned for links... + PrintStatusError(Status, L"Unable to obtain the size of '%s'", Info->FileName); + /* Non fatal error */ + } else { + Info->FileSize = GrubGetFileSize(TmpFile); + Info->PhysicalSize = GrubGetFileSize(TmpFile); + GrubClose(TmpFile); + } + GrubDestroyFile(TmpFile); + } + + *Len = (UINTN) Info->Size; + /* Advance to the next entry */ + File->DirIndex++; + +// PrintInfo(L" Entry[%d]: '%s' %s\n", File->DirIndex-1, Info->FileName, +// (Info->Attribute&EFI_FILE_DIRECTORY)?L"":L""); + + return EFI_SUCCESS; +} + +/** + * Read from file + * + * @v This File handle + * @v Len Length to read + * @v Data Data buffer + * @ret Status EFI status code + */ +static EFI_STATUS EFIAPI +FileRead(EFI_FILE_HANDLE This, UINTN *Len, VOID *Data) +{ + EFI_GRUB_FILE *File = _CR(This, EFI_GRUB_FILE, EfiFile); + + PrintInfo(L"Read(" PERCENT_P L"|'%s', %d) %s\n", (UINTN) This, FileName(File), + *Len, File->IsDir?L"":L""); + + /* If this is a directory, then fetch the directory entries */ + if (File->IsDir) + return FileReadDir(File, Len, Data); + + return GrubRead(File, Data, Len); +} + +/* Ex version */ +static EFI_STATUS EFIAPI +FileReadEx(IN EFI_FILE_PROTOCOL *This, IN OUT EFI_FILE_IO_TOKEN *Token) +{ + return FileRead(This, &(Token->BufferSize), Token->Buffer); +} + +/** + * Write to file + * + * @v This File handle + * @v Len Length to write + * @v Data Data buffer + * @ret Status EFI status code + */ +static EFI_STATUS EFIAPI +FileWrite(EFI_FILE_HANDLE This, UINTN *Len, VOID *Data) +{ + EFI_GRUB_FILE *File = _CR(This, EFI_GRUB_FILE, EfiFile); + + PrintError(L"Cannot write to '%s'\n", FileName(File)); + return EFI_WRITE_PROTECTED; +} + +/* Ex version */ +static EFI_STATUS EFIAPI +FileWriteEx(IN EFI_FILE_PROTOCOL *This, IN OUT EFI_FILE_IO_TOKEN *Token) +{ + return FileWrite(This, &(Token->BufferSize), Token->Buffer); +} + +/** + * Set file position + * + * @v This File handle + * @v Position New file position + * @ret Status EFI status code + */ +static EFI_STATUS EFIAPI +FileSetPosition(EFI_FILE_HANDLE This, UINT64 Position) +{ + EFI_GRUB_FILE *File = _CR(This, EFI_GRUB_FILE, EfiFile); + UINT64 FileSize; + + PrintInfo(L"SetPosition(" PERCENT_P L"|'%s', %lld) %s\n", (UINTN) This, + FileName(File), Position, (File->IsDir)?L"":L""); + + /* If this is a directory, reset the Index to the start */ + if (File->IsDir) { + if (Position != 0) + return EFI_INVALID_PARAMETER; + File->DirIndex = 0; + return EFI_SUCCESS; + } + + /* Fail if we attempt to seek past the end of the file (since + * we do not support writes). + */ + FileSize = GrubGetFileSize(File); + if (Position > FileSize) { + PrintError(L"'%s': Cannot seek to #%llx of %llx\n", + FileName(File), Position, FileSize); + return EFI_UNSUPPORTED; + } + + /* Set position */ + GrubSetFileOffset(File, Position); + PrintDebug(L"'%s': Position set to %llx\n", + FileName(File), Position); + + return EFI_SUCCESS; +} + +/** + * Get file position + * + * @v This File handle + * @ret Position New file position + * @ret Status EFI status code + */ +static EFI_STATUS EFIAPI +FileGetPosition(EFI_FILE_HANDLE This, UINT64 *Position) +{ + EFI_GRUB_FILE *File = _CR(This, EFI_GRUB_FILE, EfiFile); + + PrintInfo(L"GetPosition(" PERCENT_P L"|'%s', %lld)\n", (UINTN) This, FileName(File)); + + if (File->IsDir) + *Position = File->DirIndex; + else + *Position = GrubGetFileOffset(File); + return EFI_SUCCESS; +} + +/** + * Get file information + * + * @v This File handle + * @v Type Type of information + * @v Len Buffer size + * @v Data Buffer + * @ret Status EFI status code + */ +static EFI_STATUS EFIAPI +FileGetInfo(EFI_FILE_HANDLE This, EFI_GUID *Type, UINTN *Len, VOID *Data) +{ + EFI_STATUS Status; + EFI_GRUB_FILE *File = _CR(This, EFI_GRUB_FILE, EfiFile); + EFI_FILE_SYSTEM_INFO *FSInfo = (EFI_FILE_SYSTEM_INFO *) Data; + EFI_FILE_INFO *Info = (EFI_FILE_INFO *) Data; + EFI_FILE_SYSTEM_VOLUME_LABEL_INFO *VLInfo = (EFI_FILE_SYSTEM_VOLUME_LABEL_INFO *)Data; + EFI_TIME Time; + CHAR8* label; + UINTN tmpLen; + + PrintInfo(L"GetInfo(" PERCENT_P L"|'%s', %d) %s\n", (UINTN) This, + FileName(File), *Len, File->IsDir?L"":L""); + + /* Determine information to return */ + if (CompareMem(Type, &gEfiFileInfoGuid, sizeof(*Type)) == 0) { + + /* Fill file information */ + PrintExtra(L"Get regular file information\n"); + if (*Len < MINIMUM_INFO_LENGTH) { + *Len = MINIMUM_INFO_LENGTH; + return EFI_BUFFER_TOO_SMALL; + } + + ZeroMem(Data, sizeof(EFI_FILE_INFO)); + + Info->Attribute = EFI_FILE_READ_ONLY; + GrubTimeToEfiTime(File->Mtime, &Time); + CopyMem(&Info->CreateTime, &Time, sizeof(Time)); + CopyMem(&Info->LastAccessTime, &Time, sizeof(Time)); + CopyMem(&Info->ModificationTime, &Time, sizeof(Time)); + + if (File->IsDir) { + Info->Attribute |= EFI_FILE_DIRECTORY; + } else { + Info->FileSize = GrubGetFileSize(File); + Info->PhysicalSize = GrubGetFileSize(File); + } + + tmpLen = (UINTN)(Info->Size - sizeof(EFI_FILE_INFO) - 1); + Status = Utf8ToUtf16NoAllocUpdateLen(File->basename, Info->FileName, &tmpLen); + if (EFI_ERROR(Status)) { + if (Status != EFI_BUFFER_TOO_SMALL) + PrintStatusError(Status, L"Could not convert basename to UTF-16"); + return Status; + } + + /* The Info struct size already accounts for the extra NUL */ + Info->Size = sizeof(EFI_FILE_INFO) + tmpLen; + *Len = (INTN)Info->Size; + return EFI_SUCCESS; + + } else if (CompareMem(Type, &gEfiFileSystemInfoGuid, sizeof(*Type)) == 0) { + + /* Get file system information */ + PrintExtra(L"Get file system information\n"); + if (*Len < MINIMUM_FS_INFO_LENGTH) { + *Len = MINIMUM_FS_INFO_LENGTH; + return EFI_BUFFER_TOO_SMALL; + } + + ZeroMem(Data, sizeof(EFI_FILE_INFO)); + FSInfo->Size = *Len; + FSInfo->ReadOnly = 1; + /* NB: This should really be cluster size, but we don't have access to that */ + if (File->FileSystem->BlockIo2 != NULL) { + FSInfo->BlockSize = File->FileSystem->BlockIo2->Media->BlockSize; + } else { + FSInfo->BlockSize = File->FileSystem->BlockIo->Media->BlockSize; + } + if (FSInfo->BlockSize == 0) { + PrintWarning(L"Corrected Media BlockSize\n"); + FSInfo->BlockSize = 512; + } + if (File->FileSystem->BlockIo2 != NULL) { + FSInfo->VolumeSize = (File->FileSystem->BlockIo2->Media->LastBlock + 1) * + FSInfo->BlockSize; + } else { + FSInfo->VolumeSize = (File->FileSystem->BlockIo->Media->LastBlock + 1) * + FSInfo->BlockSize; + } + /* No idea if we can easily get this for GRUB, and the device is RO anyway */ + FSInfo->FreeSpace = 0; + + Status = GrubLabel(File, &label); + if (EFI_ERROR(Status)) { + PrintStatusError(Status, L"Could not read disk label"); + FSInfo->VolumeLabel[0] = 0; + *Len = sizeof(EFI_FILE_SYSTEM_INFO); + } else { + tmpLen = (INTN)(FSInfo->Size - sizeof(EFI_FILE_SYSTEM_INFO) - 1); + Status = Utf8ToUtf16NoAllocUpdateLen(label, FSInfo->VolumeLabel, &tmpLen); + if (EFI_ERROR(Status)) { + if (Status != EFI_BUFFER_TOO_SMALL) + PrintStatusError(Status, L"Could not convert label to UTF-16"); + return Status; + } + FSInfo->Size = sizeof(EFI_FILE_SYSTEM_INFO) - 1 + tmpLen; + *Len = (INTN)FSInfo->Size; + } + return EFI_SUCCESS; + + } else if (CompareMem(Type, &gEfiFileSystemVolumeLabelInfoIdGuid, sizeof(*Type)) == 0) { + + /* Get the volume label */ + Status = GrubLabel(File, &label); + if (EFI_ERROR(Status)) { + PrintStatusError(Status, L"Could not read disk label"); + } + else { + Status = Utf8ToUtf16NoAllocUpdateLen(label, VLInfo->VolumeLabel, Len); + if (EFI_ERROR(Status)) { + if (Status != EFI_BUFFER_TOO_SMALL) + PrintStatusError(Status, L"Could not convert label to UTF-16"); + return Status; + } + } + return EFI_SUCCESS; + + } else { + + Print(L"'%s': Cannot get information of type ", FileName(File)); + PrintGuid(Type); + Print(L"\n"); + return EFI_UNSUPPORTED; + + } +} + +/** + * Set file information + * + * @v This File handle + * @v Type Type of information + * @v Len Buffer size + * @v Data Buffer + * @ret Status EFI status code + */ +static EFI_STATUS EFIAPI +FileSetInfo(EFI_FILE_HANDLE This, EFI_GUID *Type, UINTN Len, VOID *Data) +{ + EFI_GRUB_FILE *File = _CR(This, EFI_GRUB_FILE, EfiFile); + + Print(L"Cannot set information of type "); + PrintGuid(Type); + Print(L" for file '%s'\n", FileName(File)); + + return EFI_WRITE_PROTECTED; +} + +/** + * Flush file modified data + * + * @v This File handle + * @v Type Type of information + * @v Len Buffer size + * @v Data Buffer + * @ret Status EFI status code + */ +static EFI_STATUS EFIAPI +FileFlush(EFI_FILE_HANDLE This) +{ + EFI_GRUB_FILE *File = _CR(This, EFI_GRUB_FILE, EfiFile); + + PrintInfo(L"Flush(" PERCENT_P L"|'%s')\n", (UINTN) This, FileName(File)); + return EFI_SUCCESS; +} + +/* Ex version */ +static EFI_STATUS EFIAPI +FileFlushEx(EFI_FILE_HANDLE This, EFI_FILE_IO_TOKEN *Token) +{ + return FileFlush(This); +} + +/** + * Open root directory + * + * @v This EFI simple file system + * @ret Root File handle for the root directory + * @ret Status EFI status code + */ +EFI_STATUS EFIAPI +FileOpenVolume(EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, EFI_FILE_HANDLE *Root) +{ + EFI_FS *FSInstance = _CR(This, EFI_FS, FileIoInterface); + + PrintInfo(L"OpenVolume\n"); + *Root = &FSInstance->RootFile->EfiFile; + + return EFI_SUCCESS; +} + +/** + * Install the EFI simple file system protocol + * If successful this call instantiates a new FS#: drive, that is made + * available on the next 'map -r'. Note that all this call does is add + * the FS protocol. OpenVolume won't be called until a process tries + * to access a file or the root directory on the volume. + */ +EFI_STATUS +FSInstall(EFI_FS *This, EFI_HANDLE ControllerHandle) +{ + EFI_STATUS Status; + + /* Check if it's a filesystem we can handle */ + if (!GrubFSProbe(This)) + return EFI_UNSUPPORTED; + + PrintInfo(L"FSInstall: %s\n", This->DevicePathString); + + /* Initialize the root handle */ + Status = GrubCreateFile(&This->RootFile, This); + if (EFI_ERROR(Status)) { + PrintStatusError(Status, L"Could not create root file"); + return Status; + } + + /* Setup the EFI part */ + This->RootFile->EfiFile.Revision = EFI_FILE_PROTOCOL_REVISION2; + This->RootFile->EfiFile.Open = FileOpen; + This->RootFile->EfiFile.Close = FileClose; + This->RootFile->EfiFile.Delete = FileDelete; + This->RootFile->EfiFile.Read = FileRead; + This->RootFile->EfiFile.Write = FileWrite; + This->RootFile->EfiFile.GetPosition = FileGetPosition; + This->RootFile->EfiFile.SetPosition = FileSetPosition; + This->RootFile->EfiFile.GetInfo = FileGetInfo; + This->RootFile->EfiFile.SetInfo = FileSetInfo; + This->RootFile->EfiFile.Flush = FileFlush; + This->RootFile->EfiFile.OpenEx = FileOpenEx; + This->RootFile->EfiFile.ReadEx = FileReadEx; + This->RootFile->EfiFile.WriteEx = FileWriteEx; + This->RootFile->EfiFile.FlushEx = FileFlushEx; + + /* Setup the other attributes */ + This->RootFile->path = "/"; + This->RootFile->basename = &This->RootFile->path[1]; + This->RootFile->IsDir = TRUE; + + /* Install the simple file system protocol. */ + Status = BS->InstallMultipleProtocolInterfaces(&ControllerHandle, + &gEfiSimpleFileSystemProtocolGuid, &This->FileIoInterface, + NULL); + if (EFI_ERROR(Status)) { + PrintStatusError(Status, L"Could not install simple file system protocol"); + return Status; + } + + return EFI_SUCCESS; +} + +/* Uninstall EFI simple file system protocol */ +VOID +FSUninstall(EFI_FS *This, EFI_HANDLE ControllerHandle) +{ + PrintInfo(L"FSUninstall: %s\n", This->DevicePathString); + + BS->UninstallMultipleProtocolInterfaces(ControllerHandle, + &gEfiSimpleFileSystemProtocolGuid, &This->FileIoInterface, + NULL); +} diff --git a/EDK2/efiffs/org/src/logging.c b/EDK2/efiffs/org/src/logging.c new file mode 100644 index 0000000..34ca653 --- /dev/null +++ b/EDK2/efiffs/org/src/logging.c @@ -0,0 +1,80 @@ +/* logging.c - EFI logging */ +/* + * Copyright © 2014-2017 Pete Batard + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "driver.h" + +/* Not defined in gnu-efi yet */ +#define SHELL_VARIABLE_GUID { \ + 0x158def5a, 0xf656, 0x419c, { 0xb0, 0x27, 0x7a, 0x31, 0x92, 0xc0, 0x79, 0xd2 } \ +} +extern EFI_GUID gShellVariableGuid; +EFI_GUID ShellVariable = SHELL_VARIABLE_GUID; + +static UINTN PrintNone(IN CONST CHAR16 *fmt, ... ) { return 0; } +Print_t PrintError = PrintNone; +Print_t PrintWarning = PrintNone; +Print_t PrintInfo = PrintNone; +Print_t PrintDebug = PrintNone; +Print_t PrintExtra = PrintNone; +Print_t* PrintTable[] = { &PrintError, &PrintWarning, &PrintInfo, + &PrintDebug, &PrintExtra }; + +/* Global driver verbosity level */ +#if !defined(DEFAULT_LOGLEVEL) +#define DEFAULT_LOGLEVEL FS_LOGLEVEL_NONE +#endif +UINTN LogLevel = DEFAULT_LOGLEVEL; + +/** + * Print status + * + * @v Status EFI status code + */ +VOID +PrintStatus(EFI_STATUS Status) +{ +#if defined(__MAKEWITH_GNUEFI) + CHAR16 StatusString[64]; + StatusToString(StatusString, Status); + // Make sure the Status is unsigned 32 bits + Print(L": [%d] %s\n", (Status & 0x7FFFFFFF), StatusString); +#else + Print(L": [%d]\n", (Status & 0x7FFFFFFF)); +#endif +} + +/* + * You can control the verbosity of the driver output by setting the shell environment + * variable FS_LOGGING to one of the values defined in the FS_LOGLEVEL constants + */ +VOID +SetLogging(VOID) +{ + EFI_STATUS Status; + CHAR16 LogVar[4]; + UINTN i, LogVarSize = sizeof(LogVar); + + Status = RT->GetVariable(L"FS_LOGGING", &ShellVariable, NULL, &LogVarSize, LogVar); + if (Status == EFI_SUCCESS) + LogLevel = Atoi(LogVar); + + for (i=0; i= 0) argv[0][0] = '@';" -i exfat-1.3.0/fuse/main.c + +cd exfat-1.3.0 +autoreconf --install +./configure --prefix="$CUR" CFLAGS='-static -O2 -D_FILE_OFFSET_BITS=64' FUSE_CFLAGS="-I$CUR/LIBFUSE/include/" FUSE_LIBS="$CUR/LIBFUSE/lib/libfuse.a -pthread $opt -ldl" +make + +strip --strip-all fuse/mount.exfat-fuse +strip --strip-all mkfs/mkexfatfs + +cp fuse/mount.exfat-fuse ../EXFAT/static/mount.exfat-fuse +cp mkfs/mkexfatfs ../EXFAT/static/mkexfatfs + +cd .. +rm -rf exfat-1.3.0 + +unzip exfat-1.3.0.zip +sed "/printf.*VERSION/a\ if (access(\"/etc/initrd-release\", F_OK) >= 0) argv[0][0] = '@';" -i exfat-1.3.0/fuse/main.c + + +cd exfat-1.3.0 +autoreconf --install +./configure --prefix="$CUR" CFLAGS='-O2 -D_FILE_OFFSET_BITS=64' FUSE_CFLAGS="-I$CUR/LIBFUSE/include/" FUSE_LIBS="$CUR/LIBFUSE/lib/libfuse.a -lpthread -ldl $opt" +make + +strip --strip-all fuse/mount.exfat-fuse +strip --strip-all mkfs/mkexfatfs + +cp fuse/mount.exfat-fuse ../EXFAT/shared/mount.exfat-fuse +cp mkfs/mkexfatfs ../EXFAT/shared/mkexfatfs + +cd .. +rm -rf exfat-1.3.0 + + + + diff --git a/ExFAT/buidexfat_aarch64.sh b/ExFAT/buidexfat_aarch64.sh new file mode 100644 index 0000000..9de4359 --- /dev/null +++ b/ExFAT/buidexfat_aarch64.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +CUR="$PWD" + +if ! [ -e LIBFUSE ]; then + ./buidlibfuse.sh +fi + +rm -f EXFAT/shared/* + + +rm -rf exfat-1.3.0 +unzip exfat-1.3.0.zip +sed "/printf.*VERSION/a\ if (access(\"/etc/initrd-release\", F_OK) >= 0) argv[0][0] = '@';" -i exfat-1.3.0/fuse/main.c + +cd exfat-1.3.0 +autoreconf --install +./configure --prefix="$CUR" CFLAGS='-O2 -D_FILE_OFFSET_BITS=64' FUSE_CFLAGS="-I$CUR/LIBFUSE/include/" FUSE_LIBS="$CUR/LIBFUSE/lib/libfuse.a -lpthread -ldl" +make + +strip --strip-all fuse/mount.exfat-fuse +strip --strip-all mkfs/mkexfatfs + +cp fuse/mount.exfat-fuse ../EXFAT/shared/mount.exfat-fuse +cp mkfs/mkexfatfs ../EXFAT/shared/mkexfatfs + +cd .. +rm -rf exfat-1.3.0 + + + + diff --git a/ExFAT/buidlibfuse.sh b/ExFAT/buidlibfuse.sh new file mode 100644 index 0000000..5421385 --- /dev/null +++ b/ExFAT/buidlibfuse.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +CUR="$PWD" + +rm -rf libfuse +rm -rf LIBFUSE + +if [ -e mirrors-libfuse-fuse-2.9.9.zip ]; then + unzip mirrors-libfuse-fuse-2.9.9.zip + cd libfuse +else + unzip libfuse-fuse-2.9.9.zip + cd libfuse-fuse-2.9.9 +fi + +./makeconf.sh + +./configure --prefix="$CUR/LIBFUSE" +make -j 16 +make install +cd .. +rm -rf libfuse diff --git a/ExFAT/buidlibfuse_aarch64.sh b/ExFAT/buidlibfuse_aarch64.sh new file mode 100644 index 0000000..da1bdd2 --- /dev/null +++ b/ExFAT/buidlibfuse_aarch64.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +CUR="$PWD" + +rm -rf libfuse +rm -rf LIBFUSE + +if [ -e mirrors-libfuse-fuse-2.9.9.zip ]; then + unzip mirrors-libfuse-fuse-2.9.9.zip + cd libfuse +else + unzip libfuse-fuse-2.9.9.zip + cd libfuse-fuse-2.9.9 +fi + +./makeconf.sh + +./configure --prefix="$CUR/LIBFUSE" + +sed '/#define *__u64/d' -i include/fuse_kernel.h +sed '/#define *__s64/d' -i include/fuse_kernel.h + +sed 's/__u64/uint64_t/g' -i include/fuse_kernel.h +sed 's/__s64/int64_t/g' -i include/fuse_kernel.h + +make -j 16 +make install +cd .. +rm -rf libfuse diff --git a/FUSEISO/build.sh b/FUSEISO/build.sh new file mode 100644 index 0000000..45617c2 --- /dev/null +++ b/FUSEISO/build.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +CUR="$PWD" + +LIBFUSE_DIR=$CUR/LIBFUSE + +if uname -a | egrep -q 'x86_64|amd64'; then + name=vtoy_fuse_iso_64 +else + name=vtoy_fuse_iso_32 + opt=-lrt +fi + +# +# use musl-c to build for x86_64 +# + +export C_INCLUDE_PATH=$LIBFUSE_DIR/include + +rm -f $name +gcc -specs "/usr/local/musl/lib/musl-gcc.specs" -static -O2 -D_FILE_OFFSET_BITS=64 vtoy_fuse_iso.c $LIBFUSE_DIR/lib/libfuse.a -o $name + +strip --strip-all $name + +if [ -e $name ]; then + echo -e "\n############### SUCCESS $name ##################\n" +else + echo -e "\n############### FAILED $name ##################\n" +fi + +strip --strip-all $name + diff --git a/FUSEISO/build_aarch64.sh b/FUSEISO/build_aarch64.sh new file mode 100644 index 0000000..59e995e --- /dev/null +++ b/FUSEISO/build_aarch64.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +CUR="$PWD" + +LIBFUSE_DIR=$CUR/LIBFUSE + +name=vtoy_fuse_iso_aa64 + +export C_INCLUDE_PATH=$LIBFUSE_DIR/include + +rm -f $name +aarch64-buildroot-linux-uclibc-gcc -static -O2 -D_FILE_OFFSET_BITS=64 vtoy_fuse_iso.c -o $name $LIBFUSE_DIR/lib/libfuse.a + +if [ -e $name ]; then + echo -e "\n############### SUCCESS $name ##################\n" +else + echo -e "\n############### FAILED $name ##################\n" +fi + +aarch64-buildroot-linux-uclibc-strip --strip-all $name + diff --git a/FUSEISO/build_libfuse.sh b/FUSEISO/build_libfuse.sh new file mode 100644 index 0000000..96086aa --- /dev/null +++ b/FUSEISO/build_libfuse.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +# +# +# Package Dependency: +# gcc automake autoconf gettext gettext-devel libtool unzip +# +# + +# use mini-native-x86_64 UCLIBC to build for x86_64 + + +CUR="$PWD" +LIBFUSE_DIR=$CUR/LIBFUSE + +rm -rf libfuse +rm -rf $LIBFUSE_DIR + +# please download https://codeload.github.com/libfuse/libfuse/zip/fuse-2.9.9 +if [ -e ../ExFAT/mirrors-libfuse-fuse-2.9.9.zip ]; then + rm -rf libfuse + unzip ../ExFAT/mirrors-libfuse-fuse-2.9.9.zip + cd libfuse +elif [ -e ../ExFAT/libfuse-fuse-2.9.9.zip ]; then + rm -rf libfuse-fuse-2.9.9 + unzip ../ExFAT/libfuse-fuse-2.9.9.zip + cd libfuse-fuse-2.9.9 +else + echo "Please download mirrors-libfuse-fuse-2.9.9.zip first" + exit 1 +fi + + +./makeconf.sh + +./configure --prefix="$LIBFUSE_DIR" CFLAGS='-specs /usr/local/musl/lib/musl-gcc.specs' +make -j 16 +make install +cd .. +rm -rf libfuse diff --git a/FUSEISO/build_libfuse_aarch64.sh b/FUSEISO/build_libfuse_aarch64.sh new file mode 100644 index 0000000..691829e --- /dev/null +++ b/FUSEISO/build_libfuse_aarch64.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +# +# +# Package Dependency: +# gcc automake autoconf gettext gettext-devel libtool unzip +# +# + + +CUR="$PWD" +LIBFUSE_DIR=$CUR/LIBFUSE + +rm -rf libfuse +rm -rf $LIBFUSE_DIR + +# please download https://codeload.github.com/libfuse/libfuse/zip/fuse-2.9.9 +if [ -e ../ExFAT/mirrors-libfuse-fuse-2.9.9.zip ]; then + rm -rf libfuse + unzip ../ExFAT/mirrors-libfuse-fuse-2.9.9.zip + cd libfuse +elif [ -e ../ExFAT/libfuse-fuse-2.9.9.zip ]; then + rm -rf libfuse-fuse-2.9.9 + unzip ../ExFAT/libfuse-fuse-2.9.9.zip + cd libfuse-fuse-2.9.9 +else + echo "Please download mirrors-libfuse-fuse-2.9.9.zip first" + exit 1 +fi + + +./makeconf.sh + +sed '/#define *__u64/d' -i include/fuse_kernel.h +sed '/#define *__s64/d' -i include/fuse_kernel.h + +sed 's/__u64/uint64_t/g' -i include/fuse_kernel.h +sed 's/__s64/int64_t/g' -i include/fuse_kernel.h + +./configure --prefix="$LIBFUSE_DIR" --host=aarch64 CC=aarch64-buildroot-linux-uclibc-gcc + + +make -j 16 +make install +cd .. +rm -rf libfuse diff --git a/FUSEISO/vtoy_fuse_iso.c b/FUSEISO/vtoy_fuse_iso.c new file mode 100644 index 0000000..0178c8d --- /dev/null +++ b/FUSEISO/vtoy_fuse_iso.c @@ -0,0 +1,348 @@ +/****************************************************************************** + * vtoy_fuse_iso.c + * + * Copyright (c) 2020, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#define FUSE_USE_VERSION 26 + +#include +#include +#include +#include +#include +#include +#include + +typedef unsigned int uint32_t; + +typedef struct dmtable_entry +{ + uint32_t isoSector; + uint32_t sectorNum; + unsigned long long diskSector; +}dmtable_entry; + +#define MAX_ENTRY_NUM (1024 * 1024 / sizeof(dmtable_entry)) + +static int verbose = 0; +#define debug(fmt, ...) if(verbose) printf(fmt, ##__VA_ARGS__) + +static int g_disk_fd = -1; +static uint64_t g_iso_file_size; +static char g_mnt_point[512]; +static char g_iso_file_name[512]; +static dmtable_entry *g_disk_entry_list = NULL; +static int g_disk_entry_num = 0; + +static int ventoy_iso_getattr(const char *path, struct stat *statinfo) +{ + int ret = -ENOENT; + + if (path && statinfo) + { + memset(statinfo, 0, sizeof(struct stat)); + + if (path[0] == '/' && path[1] == 0) + { + statinfo->st_mode = S_IFDIR | 0755; + statinfo->st_nlink = 2; + ret = 0; + } + else if (strcmp(path, g_iso_file_name) == 0) + { + statinfo->st_mode = S_IFREG | 0444; + statinfo->st_nlink = 1; + statinfo->st_size = g_iso_file_size; + ret = 0; + } + } + + return ret; +} + +static int ventoy_iso_readdir +( + const char *path, + void *buf, + fuse_fill_dir_t filler, + off_t offset, + struct fuse_file_info *file +) +{ + (void)offset; + (void)file; + + if (path[0] != '/' || path[1] != 0) + { + return -ENOENT; + } + + filler(buf, ".", NULL, 0); + filler(buf, "..", NULL, 0); + filler(buf, g_iso_file_name + 1, NULL, 0); + + return 0; +} + +static int ventoy_iso_open(const char *path, struct fuse_file_info *file) +{ + if (strcmp(path, g_iso_file_name) != 0) + { + return -ENOENT; + } + + if ((file->flags & 3) != O_RDONLY) + { + return -EACCES; + } + + return 0; +} + +static int ventoy_read_iso_sector(uint32_t sector, uint32_t num, char *buf) +{ + uint32_t i = 0; + uint32_t leftSec = 0; + uint32_t readSec = 0; + off_t offset = 0; + dmtable_entry *entry = NULL; + + for (i = 0; i < g_disk_entry_num && num > 0; i++) + { + entry = g_disk_entry_list + i; + + if (sector >= entry->isoSector && sector < entry->isoSector + entry->sectorNum) + { + offset = (entry->diskSector + (sector - entry->isoSector)) * 512; + + leftSec = entry->sectorNum - (sector - entry->isoSector); + readSec = (leftSec > num) ? num : leftSec; + + pread(g_disk_fd, buf, readSec * 512, offset); + + sector += readSec; + buf += readSec * 512; + num -= readSec; + } + } + + return 0; +} + +static int ventoy_iso_read +( + const char *path, char *buf, + size_t size, off_t offset, + struct fuse_file_info *file +) +{ + uint32_t mod = 0; + uint32_t align = 0; + uint32_t sector = 0; + uint32_t number = 0; + size_t leftsize = 0; + char secbuf[512]; + + (void)file; + + if(strcmp(path, g_iso_file_name) != 0) + { + return -ENOENT; + } + + if (offset >= g_iso_file_size) + { + return 0; + } + + if (offset + size > g_iso_file_size) + { + size = g_iso_file_size - offset; + } + + leftsize = size; + sector = offset / 512; + + mod = offset % 512; + if (mod > 0) + { + align = 512 - mod; + ventoy_read_iso_sector(sector, 1, secbuf); + + if (leftsize > align) + { + memcpy(buf, secbuf + mod, align); + buf += align; + offset += align; + sector++; + leftsize -= align; + } + else + { + memcpy(buf, secbuf + mod, leftsize); + return size; + } + } + + number = leftsize / 512; + ventoy_read_iso_sector(sector, number, buf); + buf += number * 512; + + mod = leftsize % 512; + if (mod > 0) + { + ventoy_read_iso_sector(sector + number, 1, secbuf); + memcpy(buf, secbuf, mod); + } + + return size; +} + +static struct fuse_operations ventoy_op = +{ + .getattr = ventoy_iso_getattr, + .readdir = ventoy_iso_readdir, + .open = ventoy_iso_open, + .read = ventoy_iso_read, +}; + +static int ventoy_parse_dmtable(const char *filename) +{ + FILE *fp = NULL; + char diskname[128] = {0}; + char line[256] = {0}; + dmtable_entry *entry= g_disk_entry_list; + + fp = fopen(filename, "r"); + if (NULL == fp) + { + printf("Failed to open file %s\n", filename); + return 1; + } + + /* read untill the last line */ + while (fgets(line, sizeof(line), fp) && g_disk_entry_num < MAX_ENTRY_NUM) + { + sscanf(line, "%u %u linear %s %llu", + &entry->isoSector, &entry->sectorNum, + diskname, &entry->diskSector); + + g_iso_file_size += (uint64_t)entry->sectorNum * 512ULL; + g_disk_entry_num++; + entry++; + } + fclose(fp); + + if (g_disk_entry_num >= MAX_ENTRY_NUM) + { + fprintf(stderr, "ISO file has too many fragments ( more than %u )\n", MAX_ENTRY_NUM); + return 1; + } + + debug("iso file size: %llu disk name %s\n", g_iso_file_size, diskname); + + g_disk_fd = open(diskname, O_RDONLY); + if (g_disk_fd < 0) + { + debug("Failed to open %s\n", diskname); + return 1; + } + + return 0; +} + +int main(int argc, char **argv) +{ + int rc; + int ch; + char filename[512] = {0}; + + /* Avoid to be killed by systemd */ + if (access("/etc/initrd-release", F_OK) >= 0) + { + argv[0][0] = '@'; + } + + g_iso_file_name[0] = '/'; + + while ((ch = getopt(argc, argv, "f:s:m:v::t::")) != -1) + { + if (ch == 'f') + { + strncpy(filename, optarg, sizeof(filename) - 1); + } + else if (ch == 'm') + { + strncpy(g_mnt_point, optarg, sizeof(g_mnt_point) - 1); + } + else if (ch == 's') + { + strncpy(g_iso_file_name + 1, optarg, sizeof(g_iso_file_name) - 2); + } + else if (ch == 'v') + { + verbose = 1; + } + else if (ch == 't') // for test + { + return 0; + } + } + + if (filename[0] == 0) + { + fprintf(stderr, "Must input dmsetup table file with -f\n"); + return 1; + } + + if (g_mnt_point[0] == 0) + { + fprintf(stderr, "Must input mount point with -m\n"); + return 1; + } + + if (g_iso_file_name[1] == 0) + { + strncpy(g_iso_file_name + 1, "ventoy.iso", sizeof(g_iso_file_name) - 2); + } + + debug("ventoy fuse iso: %s %s %s\n", filename, g_iso_file_name, g_mnt_point); + + g_disk_entry_list = malloc(MAX_ENTRY_NUM * sizeof(dmtable_entry)); + if (NULL == g_disk_entry_list) + { + return 1; + } + + rc = ventoy_parse_dmtable(filename); + if (rc) + { + free(g_disk_entry_list); + return rc; + } + + argv[1] = g_mnt_point; + argv[2] = NULL; + rc = fuse_main(2, argv, &ventoy_op, NULL); + + close(g_disk_fd); + + free(g_disk_entry_list); + return rc; +} + diff --git a/FUSEISO/vtoy_fuse_iso_32 b/FUSEISO/vtoy_fuse_iso_32 new file mode 100644 index 0000000..ab21929 Binary files /dev/null and b/FUSEISO/vtoy_fuse_iso_32 differ diff --git a/FUSEISO/vtoy_fuse_iso_64 b/FUSEISO/vtoy_fuse_iso_64 new file mode 100644 index 0000000..c5e4b8d Binary files /dev/null and b/FUSEISO/vtoy_fuse_iso_64 differ diff --git a/FUSEISO/vtoy_fuse_iso_aa64 b/FUSEISO/vtoy_fuse_iso_aa64 new file mode 100644 index 0000000..e10dff9 Binary files /dev/null and b/FUSEISO/vtoy_fuse_iso_aa64 differ diff --git a/GRUB2/MOD_SRC/grub-2.04/configure.ac b/GRUB2/MOD_SRC/grub-2.04/configure.ac new file mode 100644 index 0000000..9ad929e --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/configure.ac @@ -0,0 +1,2123 @@ +# -*- autoconf -*- + +# Process this file with autoconf to produce a configure script. + +# Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. +# +# This configure.ac is free software; the author +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +dnl This configure script is complicated, because GRUB needs to deal +dnl with three potentially different types: +dnl +dnl build -- the environment for building GRUB +dnl host -- the environment for running utilities +dnl target -- the environment for running GRUB +dnl +dnl In addition, GRUB needs to deal with a platform specification +dnl which specifies the system running GRUB, such as firmware. +dnl This is necessary because the target type in autoconf does not +dnl describe such a system very well. +dnl +dnl The current strategy is to use variables with no prefix (such as +dnl CC, CFLAGS, etc.) for the host type, variables with prefix "BUILD_" +dnl (such as BUILD_CC, BUILD_CFLAGS, etc.) for the build type and variables +dnl with the prefix "TARGET_" (such as TARGET_CC, TARGET_CFLAGS, etc.) are +dnl used for the target type. See INSTALL for full list of variables. + +AC_INIT([GRUB],[2.04],[bug-grub@gnu.org]) + +AC_CONFIG_AUX_DIR([build-aux]) + +# We don't want -g -O2 by default in CFLAGS +: ${CFLAGS=""} + +# Checks for build, host and target systems. +AC_CANONICAL_BUILD +AC_CANONICAL_HOST +save_program_prefix="${program_prefix}" +AC_CANONICAL_TARGET +program_prefix="${save_program_prefix}" + +AM_INIT_AUTOMAKE([1.11]) +AC_PREREQ(2.63) +AC_CONFIG_SRCDIR([include/grub/dl.h]) +AC_CONFIG_HEADER([config-util.h]) + +# Explicitly check for pkg-config early on, since otherwise conditional +# calls are problematic. +PKG_PROG_PKG_CONFIG + +# Program name transformations +AC_ARG_PROGRAM +grub_TRANSFORM([grub-bios-setup]) +grub_TRANSFORM([grub-editenv]) +grub_TRANSFORM([grub-install]) +grub_TRANSFORM([grub-mkconfig]) +grub_TRANSFORM([grub-mkfont]) +grub_TRANSFORM([grub-mkimage]) +grub_TRANSFORM([grub-glue-efi]) +grub_TRANSFORM([grub-mklayout]) +grub_TRANSFORM([grub-mkpasswd-pbkdf2]) +grub_TRANSFORM([grub-mkrelpath]) +grub_TRANSFORM([grub-mkrescue]) +grub_TRANSFORM([grub-probe]) +grub_TRANSFORM([grub-reboot]) +grub_TRANSFORM([grub-script-check]) +grub_TRANSFORM([grub-set-default]) +grub_TRANSFORM([grub-sparc64-setup]) +grub_TRANSFORM([grub-render-label]) +grub_TRANSFORM([grub-file]) + +# Optimization flag. Allow user to override. +if test "x$TARGET_CFLAGS" = x; then + TARGET_CFLAGS="$TARGET_CFLAGS -Os" +fi + +# Default HOST_CPPFLAGS +HOST_CPPFLAGS="$HOST_CPPFLAGS -Wall -W" +HOST_CPPFLAGS="$HOST_CPPFLAGS -DGRUB_UTIL=1" + +TARGET_CPPFLAGS="$TARGET_CPPFLAGS -Wall -W" + +case "$target_cpu" in + i[[3456]]86) target_cpu=i386 ;; + amd64) target_cpu=x86_64 ;; + sparc) target_cpu=sparc64 ;; + mips64el) + target_cpu=mips64el + machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_CPU_MIPS64EL=1" + ;; + mipsel) + target_cpu=mipsel + machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_CPU_MIPSEL=1" + ;; + mips|mips64) + target_cpu=mips + machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_CPU_MIPS=1" + ;; + arm*) + target_cpu=arm + ;; + aarch64*) + target_cpu=arm64 + ;; + riscv32*) + target_cpu=riscv32 + ;; + riscv64*) + target_cpu=riscv64 + ;; +esac + +# Specify the platform (such as firmware). +AC_ARG_WITH([platform], + AS_HELP_STRING([--with-platform=PLATFORM], + [select the host platform [[guessed]]])) + +# Guess the platform if not specified. +if test "x$with_platform" = x; then + case "$target_cpu"-"$target_vendor" in + i386-apple) platform=efi ;; + i386-*) platform=pc ;; + x86_64-apple) platform=efi ;; + x86_64-*) platform=pc ;; + powerpc-*) platform=ieee1275 ;; + powerpc64-*) platform=ieee1275 ;; + powerpc64le-*) platform=ieee1275 ;; + sparc64-*) platform=ieee1275 ;; + mips64el-*) platform=efi;; + mipsel-*) platform=loongson ;; + mips-*) platform=arc ;; + ia64-*) platform=efi ;; + arm-*) platform=uboot ;; + arm64-*) platform=efi ;; + riscv32-*) platform=efi ;; + riscv64-*) platform=efi ;; + *) + AC_MSG_WARN([unsupported CPU: "$target_cpu" - only building utilities]) + platform=none + ;; + esac +else + platform="$with_platform" +fi + +case "$target_cpu"-"$platform" in + x86_64-efi) ;; + x86_64-emu) ;; + x86_64-xen) ;; + x86_64-none) ;; + x86_64-*) target_cpu=i386 ;; + powerpc64-ieee1275) target_cpu=powerpc ;; + powerpc64le-ieee1275) target_cpu=powerpc ;; +esac + +# Check if the platform is supported, make final adjustments. +case "$target_cpu"-"$platform" in + i386-efi) ;; + x86_64-efi) ;; + i386-xen) ;; + i386-xen_pvh) ;; + x86_64-xen) ;; + i386-pc) ;; + i386-multiboot) ;; + i386-coreboot) ;; + i386-linuxbios) platform=coreboot ;; + i386-ieee1275) ;; + i386-qemu) ;; + powerpc-ieee1275) ;; + sparc64-ieee1275) ;; + ia64-efi) ;; + mips-qemu_mips) ;; + mips-qemu-mips) platform=qemu_mips;; + mips-arc) ;; + mipsel-arc) ;; + mipsel-qemu_mips) ;; + mipsel-qemu-mips) platform=qemu_mips;; + mipsel-yeeloong) platform=loongson ;; + mipsel-fuloong) platform=loongson ;; + mipsel-loongson) ;; + mips64el-efi) ;; + arm-uboot) ;; + arm-coreboot) ;; + arm-efi) ;; + arm64-efi) ;; + riscv32-efi) ;; + riscv64-efi) ;; + *-emu) ;; + *-none) ;; + *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;; +esac + +if test x$platform != xemu ; then + case "$target_cpu" in + i386 | powerpc) target_m32=1 ;; + x86_64 | sparc64) target_m64=1 ;; + esac +fi + +if test x"$target_cpu-$platform" = xsparc64-emu ; then + target_m64=1 +fi + +case "$target_os" in + windows* | mingw32*) target_os=cygwin ;; +esac + +# This normalizes the names, and creates a new variable ("host_kernel") +# while at it, since the mapping is not always 1:1 (e.g. different OSes +# using the same kernel type). +case "$host_os" in + gnu*) host_kernel=hurd ;; + linux*) host_kernel=linux ;; + freebsd* | kfreebsd*-gnu) host_kernel=kfreebsd ;; + netbsd*) host_kernel=netbsd ;; + solaris*) host_kernel=illumos ;; + darwin*) host_kernel=xnu ;; + cygwin | windows* | mingw32*) host_kernel=windows ;; +esac + +case "$host_os" in + cygwin) have_exec=y ;; + windows* | mingw32*) have_exec=n ;; + aros*) have_exec=n ;; + *) have_exec=y;; +esac + +case "$platform" in + coreboot) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_COREBOOT=1" ;; + multiboot) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MULTIBOOT=1" ;; + efi) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_EFI=1" ;; + xen) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_XEN=1" ;; + xen_pvh) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_XEN_PVH=1" ;; + ieee1275) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_IEEE1275=1" ;; + uboot) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_UBOOT=1" ;; + qemu) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_QEMU=1" ;; + pc) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_PCBIOS=1" ;; + emu) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_EMU=1" ;; + loongson) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS_LOONGSON=1" ;; + qemu_mips) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS_QEMU_MIPS=1" ;; + arc) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_ARC=1" ;; +esac +if test x${target_cpu} = xmipsel ; then + machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE=`echo mips_$platform | sed y,abcdefghijklmnopqrstuvwxyz,ABCDEFGHIJKLMNOPQRSTUVWXYZ,`" +else + machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE=`echo ${target_cpu}_$platform | sed y,abcdefghijklmnopqrstuvwxyz,ABCDEFGHIJKLMNOPQRSTUVWXYZ,`" +fi + +case "${target_cpu}-$platform" in + mips-arc) + TARGET_LINK_ADDR=0x88200000 + TARGET_DECOMPRESSOR_LINK_ADDR=0x88100000 + ;; + mipsel-arc) + TARGET_LINK_ADDR=0x80700000 + TARGET_DECOMPRESSOR_LINK_ADDR=0x80600000 + ;; + mips*-qemu_mips | mips*-loongson) + TARGET_DECOMPRESSOR_LINK_ADDR=0x80100000 + ;; +esac + +AC_SUBST(TARGET_LINK_ADDR) +AC_SUBST(TARGET_DECOMPRESSOR_LINK_ADDR) + +TARGET_CPPFLAGS="$TARGET_CPPFLAGS $machine_CPPFLAGS" + +AC_SUBST(host_cpu) +AC_SUBST(host_os) +AC_SUBST(host_kernel) + +AC_SUBST(target_cpu) +AC_SUBST(platform) + +# Define default variables + +have_with_bootdir=n +AC_ARG_WITH([bootdir], + AS_HELP_STRING([--with-bootdir=DIR], + [set the name of /boot directory [[guessed]]]), + [have_with_bootdir=y], + [have_with_bootdir=n]) +if test x$have_with_bootdir = xy; then + bootdirname="$with_bootdir" +else + case "$host_os" in + netbsd* | openbsd*) + # Because /boot is used for the boot block in NetBSD and OpenBSD, + bootdirname='' ;; + *) bootdirname='boot' ;; + esac +fi + +AC_SUBST(bootdirname) +AC_DEFINE_UNQUOTED(GRUB_BOOT_DIR_NAME, "$bootdirname", + [Default boot directory name]) + +AC_ARG_WITH([grubdir], + AS_HELP_STRING([--with-grubdir=DIR], + [set the name of grub directory [[guessed]]]), + [grubdirname="$with_grubdir"], + [grubdirname="$PACKAGE"]) + +AC_SUBST(grubdirname) +AC_DEFINE_UNQUOTED(GRUB_DIR_NAME, "$grubdirname", + [Default grub directory name]) + +# +# Checks for build programs. +# + +# Although cmp is listed in the GNU Coding Standards as a command which +# can used directly, OpenBSD lacks cmp in the default installation. +AC_CHECK_PROGS([CMP], [cmp]) +if test "x$CMP" = x; then + AC_MSG_ERROR([cmp is not found]) +fi + +AC_CHECK_PROGS([YACC], [bison]) +if test "x$YACC" = x; then + AC_MSG_ERROR([bison is not found]) +fi + +AC_PROG_RANLIB +AC_PROG_INSTALL +AC_PROG_AWK +AC_PROG_LEX +AC_PROG_YACC +AC_PROG_MAKE_SET +AC_PROG_MKDIR_P +AC_PROG_LN_S + +if test "x$LEX" = "x:"; then + AC_MSG_ERROR([flex is not found]) +else + version=`$LEX --version | $AWK '{ split($2,x,"."); print x[[1]]*10000+x[[2]]*100+x[[3]]; }'` + if test -n "$version" -a "$version" -ge 20535; then + : + else + AC_MSG_ERROR([flex is too old. GRUB requires 2.5.35 or above]) + fi +fi + +# These are not a "must". +AC_PATH_PROGS(MAKEINFO, makeinfo true) + +# +# Checks for host programs. +# + +AC_PROG_CC +gl_EARLY +AC_PROG_CXX +AM_PROG_CC_C_O +AM_PROG_AS +AM_PATH_PYTHON([2.6]) + +# Must be GCC. +test "x$GCC" = xyes || AC_MSG_ERROR([GCC is required]) + +AC_CHECK_PROG(HAVE_CXX, $CXX, yes, no) + +AC_GNU_SOURCE +AM_GNU_GETTEXT([external]) +AM_GNU_GETTEXT_VERSION([0.18.3]) +AC_SYS_LARGEFILE + +# Identify characteristics of the host architecture. +unset ac_cv_c_bigendian + +if test x"$target_cpu-$platform" = xsparc64-emu ; then + CFLAGS="$CFLAGS -m64" + HOST_CFLAGS="$HOST_CFLAGS -m64" +fi + +CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=64" +HOST_CPPFLAGS="$HOST_CPPFLAGS -D_FILE_OFFSET_BITS=64" + +AC_C_BIGENDIAN +AC_CHECK_SIZEOF(void *) +AC_CHECK_SIZEOF(long) + +case "$host_os" in + cygwin | windows* | mingw32*) + HOST_CPPFLAGS="$HOST_CPPFLAGS -DUNICODE=1 -D_WIN32_WINNT=0x0500" + CPPFLAGS="$CPPFLAGS -DUNICODE=1 -D_WIN32_WINNT=0x0500" + AC_CHECK_SIZEOF(TCHAR,,[#include ]) + ;; +esac + +case "$host_os" in + cygwin | windows* | mingw32* | aros*) + ;; + *) + AC_CHECK_SIZEOF(off_t) + if test x"$ac_cv_sizeof_off_t" != x8 ; then + AC_CHECK_SIZEOF(off64_t) + test x"$ac_cv_sizeof_off64_t" = x8 || AC_MSG_ERROR([Large file support is required]) + fi;; +esac + +if test x$USE_NLS = xno; then + HOST_CFLAGS="$HOST_CFLAGS -fno-builtin-gettext" +fi + +if test "x$cross_compiling" = xyes; then + AC_MSG_WARN([cannot generate manual pages while cross compiling]) +else + AC_PATH_PROG(HELP2MAN, help2man) +fi + +# Check for functions and headers. +AC_CHECK_FUNCS(posix_memalign memalign getextmntent) +AC_CHECK_HEADERS(sys/param.h sys/mount.h sys/mnttab.h limits.h) + +# glibc 2.25 still includes sys/sysmacros.h in sys/types.h but emits deprecation +# warning which causes compilation failure later with -Werror. So use -Werror here +# as well to force proper sys/sysmacros.h detection. +SAVED_CFLAGS="$CFLAGS" +CFLAGS="$HOST_CFLAGS -Werror" +AC_HEADER_MAJOR +CFLAGS="$SAVED_CFLAGS" + +AC_CHECK_MEMBERS([struct statfs.f_fstypename],,,[$ac_includes_default +#include +#include ]) + +AC_CHECK_MEMBERS([struct statfs.f_mntfromname],,,[$ac_includes_default +#include +#include ]) + +# For opendisk() and getrawpartition() on NetBSD. +# Used in util/deviceiter.c and in util/hostdisk.c. +AC_CHECK_HEADER([util.h], [ + AC_CHECK_LIB([util], [opendisk], [ + LIBUTIL="-lutil" + AC_DEFINE(HAVE_OPENDISK, 1, [Define if opendisk() in -lutil can be used]) + ]) + AC_CHECK_LIB([util], [getrawpartition], [ + LIBUTIL="-lutil" + AC_DEFINE(HAVE_GETRAWPARTITION, 1, [Define if getrawpartition() in -lutil can be used]) + ]) +]) +AC_SUBST([LIBUTIL]) + +AC_CACHE_CHECK([whether -Wtrampolines work], [grub_cv_host_cc_wtrampolines], [ + SAVED_CFLAGS="$CFLAGS" + CFLAGS="$HOST_CFLAGS -Wtrampolines -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include +int va_arg_func (int fixed, va_list args);]], [[]])], + [grub_cv_host_cc_wtrampolines=yes], + [grub_cv_host_cc_wtrampolines=no]) + CFLAGS="$SAVED_CFLAGS" +]) + +if test x"$grub_host_cv_cc_wtrampolines" = xyes ; then + HOST_CFLAGS="$HOST_CFLAGS -Wtrampolines" +fi + +# +# Check for host and build compilers. +# +HOST_CC=$CC +AC_CHECK_PROGS(BUILD_CC, [gcc egcs cc]) +test -z "$BUILD_CC" && AC_MSG_ERROR([none of gcc, egcs and cc is found. set BUILD_CC manually.]) +BUILD_CPP="$BUILD_CC -E" + +case "$build_os" in + haiku*) BUILD_LIBM= ;; + *) BUILD_LIBM=-lm ;; +esac + +dnl FIXME proper test seems to require too deep dive into Autoconf internals. +dnl For now just list known platforms that we support. + +case "$build_os" in + cygwin*|mingw32*|mingw64*) BUILD_EXEEXT=.exe ;; + *) BUILD_EXEEXT= ;; +esac +AC_SUBST(BUILD_EXEEXT) + +# In some build environments like termux /bin/sh is not a valid +# shebang. Use $SHELL instead if it's executable and /bin/sh isn't +BUILD_SHEBANG=/bin/sh +for she in /bin/sh "$SHELL"; do + if test -x "$she" ; then + BUILD_SHEBANG="$she" + fi +done +AC_SUBST(BUILD_SHEBANG) + +# For gnulib. +gl_INIT + +WARN_FLAGS="-Wall -W -Wshadow -Wpointer-arith -Wundef -Wchar-subscripts -Wcomment -Wdeprecated-declarations -Wdisabled-optimization -Wdiv-by-zero -Wfloat-equal -Wformat-extra-args -Wformat-security -Wformat-y2k -Wimplicit -Wimplicit-function-declaration -Wimplicit-int -Wmain -Wmissing-braces -Wmissing-format-attribute -Wmultichar -Wparentheses -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -Wswitch -Wtrigraphs -Wunknown-pragmas -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable -Wwrite-strings -Wnested-externs -Wstrict-prototypes" +EXTRA_WARN_FLAGS="-Wextra -Wattributes -Wendif-labels -Winit-self -Wint-to-pointer-cast -Winvalid-pch -Wmissing-field-initializers -Wnonnull -Woverflow -Wvla -Wpointer-to-int-cast -Wstrict-aliasing -Wvariadic-macros -Wvolatile-register-var -Wpointer-sign -Wmissing-include-dirs -Wmissing-prototypes -Wmissing-declarations -Wformat=2" + +HOST_CFLAGS="$HOST_CFLAGS $WARN_FLAGS -Wcast-align" + +AC_CACHE_CHECK([which extra warnings work], [grub_cv_cc_w_extra_flags], [ + SAVED_CFLAGS="$CFLAGS" + grub_cv_cc_w_extra_flags= + for x in $EXTRA_WARN_FLAGS; do + CFLAGS="$HOST_CFLAGS $x -Werror" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [flag=1], [flag=0]) + if test x$flag = x1 ; then + grub_cv_cc_w_extra_flags="$grub_cv_cc_w_extra_flags $x" + fi + done + CFLAGS="$SAVED_CFLAGS" +]) + +HOST_CFLAGS="$HOST_CFLAGS $grub_cv_cc_w_extra_flags" + +# +# Check for target programs. +# + +# Find tools for the target. +if test "x$target_alias" != x && test "x$host_alias" != "x$target_alias"; then + tmp_ac_tool_prefix="$ac_tool_prefix" + ac_tool_prefix=$target_alias- + + AC_CHECK_TOOLS(TARGET_CC, [gcc egcs cc], + [AC_MSG_ERROR([none of gcc, egcs and cc is found. set TARGET_CC manually.])]) + AC_CHECK_TOOL(TARGET_OBJCOPY, objcopy) + AC_CHECK_TOOL(TARGET_STRIP, strip) + AC_CHECK_TOOL(TARGET_NM, nm) + AC_CHECK_TOOL(TARGET_RANLIB, ranlib) + + ac_tool_prefix="$tmp_ac_tool_prefix" +else + if test "x$TARGET_CC" = x; then + TARGET_CC=$CC + fi + AC_CHECK_TOOL(TARGET_OBJCOPY, objcopy) + AC_CHECK_TOOL(TARGET_STRIP, strip) + AC_CHECK_TOOL(TARGET_NM, nm) + AC_CHECK_TOOL(TARGET_RANLIB, ranlib) +fi + +AC_SUBST(HOST_CC) +AC_SUBST(BUILD_CC) +AC_SUBST(BUILD_CFLAGS) +AC_SUBST(BUILD_CPPFLAGS) +AC_SUBST(BUILD_LDFLAGS) +AC_SUBST(TARGET_CC) +AC_SUBST(TARGET_NM) +AC_SUBST(TARGET_RANLIB) +AC_SUBST(TARGET_STRIP) +AC_SUBST(TARGET_OBJCOPY) + +# Test the C compiler for the target environment. +tmp_CC="$CC" +tmp_CFLAGS="$CFLAGS" +tmp_LDFLAGS="$LDFLAGS" +tmp_CPPFLAGS="$CPPFLAGS" +tmp_LIBS="$LIBS" +CC="$TARGET_CC" +CFLAGS="$TARGET_CFLAGS" +CPPFLAGS="$TARGET_CPPFLAGS" +LDFLAGS="$TARGET_LDFLAGS" +LIBS="" + +# debug flags. +TARGET_CFLAGS="$TARGET_CFLAGS $WARN_FLAGS -g -Wredundant-decls -Wmissing-prototypes -Wmissing-declarations" +TARGET_CCASFLAGS="$TARGET_CCASFLAGS -g" + +if test "x$target_cpu" != xi386 && test "x$target_cpu" != xx86_64; then +TARGET_CFLAGS="$TARGET_CFLAGS -Wcast-align" +fi + +TARGET_CC_VERSION="$(LC_ALL=C $TARGET_CC --version | head -n1)" + +AC_CACHE_CHECK([which extra warnings work], [grub_cv_target_cc_w_extra_flags], [ + LDFLAGS="$TARGET_LDFLAGS -nostdlib -static" + + grub_cv_target_cc_w_extra_flags= + for x in $EXTRA_WARN_FLAGS; do + CFLAGS="$TARGET_CFLAGS $x -Werror" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +asm (".globl start; start:"); +void __main (void); +void __main (void) {} +int main (void); +]], [[]])], [flag=1], [flag=0]) + if test x$flag = x1 ; then + grub_cv_target_cc_w_extra_flags="$grub_cv_target_cc_w_extra_flags $x" + fi + done +]) + +TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_w_extra_flags" + +AC_CACHE_CHECK([if compiling with clang], [grub_cv_cc_target_clang], +[ +CFLAGS="$TARGET_CFLAGS" +AC_COMPILE_IFELSE( +[AC_LANG_PROGRAM([], [[ +#ifdef __clang__ +#error "is clang" +#endif +]])], +[grub_cv_cc_target_clang=no], [grub_cv_cc_target_clang=yes])]) + +if test x$target_cpu = xpowerpc -o x$target_cpu = xmips; then + AC_CACHE_CHECK([for options to get big-endian compilation], grub_cv_target_cc_big_endian, [ + grub_cv_target_cc_big_endian=no + for cand in "-target $target_cpu -Wl,-EB" "-target $target_cpu" \ + "-target $target_cpu-linux-gnu -Wl,-EB" "-target $target_cpu-linux-gnu" \ + "-EB" "-mbig-endian"; do + if test x"$grub_cv_target_cc_big_endian" != xno ; then + break + fi + CFLAGS="$TARGET_CFLAGS $cand -Werror" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__ORDER_BIG_ENDIAN__ != __BYTE_ORDER__) +#error still little endian +#endif +asm (".globl start; start:"); +asm (".globl _start; _start:"); +asm (".globl __start; __start:"); +void __main (void); +void __main (void) {} +int main (void); +]], [[]])], + [grub_cv_target_cc_big_endian="$cand"], []) + done + ]) + + if test x"$grub_cv_target_cc_big_endian" = xno ; then + AC_MSG_ERROR([could not force big-endian]) + fi + + skip_linkflags="$(echo "$grub_cv_target_cc_big_endian"|sed 's@-Wl,-EB@@')" + + TARGET_CFLAGS="$TARGET_CFLAGS $skip_linkflags" + TARGET_CPPFLAGS="$TARGET_CPPFLAGS $skip_linkflags" + TARGET_CCASFLAGS="$TARGET_CCASFLAGS $skip_linkflags" + TARGET_LDFLAGS="$TARGET_LDFLAGS $grub_cv_target_cc_big_endian" +elif test x$target_cpu = xmipsel; then + AC_CACHE_CHECK([for options to get little-endian compilation], grub_cv_target_cc_little_endian, [ + grub_cv_target_cc_little_endian=no + for cand in "-target $target_cpu -Wl,-EL" "-target $target_cpu" \ + "-target $target_cpu-linux-gnu -Wl,-EL" "-target $target_cpu-linux-gnu" \ + "-EL"; do + if test x"$grub_cv_target_cc_little_endian" != xno ; then + break + fi + CFLAGS="$TARGET_CFLAGS $cand -Werror" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__ORDER_BIG_ENDIAN__ == __BYTE_ORDER__) +#error still big endian +#endif +asm (".globl start; start:"); +asm (".globl _start; _start:"); +asm (".globl __start; __start:"); +void __main (void); +void __main (void) {} +int main (void); +]], [[]])], + [grub_cv_target_cc_little_endian="$cand"], []) + done + ]) + + if test x"$grub_cv_target_cc_little_endian" = xno ; then + AC_MSG_ERROR([could not force little-endian]) + fi + + skip_linkflags="$(echo "$grub_cv_target_cc_little_endian"|sed 's@-Wl,-EL@@')" + + TARGET_CFLAGS="$TARGET_CFLAGS $skip_linkflags" + TARGET_CPPFLAGS="$TARGET_CPPFLAGS $skip_linkflags" + TARGET_CCASFLAGS="$TARGET_CCASFLAGS $skip_linkflags" + TARGET_LDFLAGS="$TARGET_LDFLAGS $grub_cv_target_cc_little_endian" +fi + +# GRUB code is N32-compliant but it's experimental and we would prefer to +# avoid having too much variety when it doesn't result in any real improvement. +# Moreover N64 isn't supported. +if test "x$target_cpu" = xmips || test "x$target_cpu" = xmipsel ; then + AC_CACHE_CHECK([for options to force MIPS o32 ABI], grub_cv_target_cc_mips_o32_abi, [ + grub_cv_target_cc_mips_o32_abi=no + for arg in "" "-mabi=32" "-target $target_cpu -mabi=32" ; do + if test x"$grub_cv_target_cc_mips_o32_abi" != xno ; then + break + fi + CFLAGS="$TARGET_CFLAGS $arg -Werror" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#if !defined(_ABIO32) || !defined(_MIPS_SIM) || (_MIPS_SIM != _ABIO32) +#error not o32 ABI +#endif +asm (".globl start; start:"); +asm (".globl _start; _start:"); +asm (".globl __start; __start:"); +void __main (void); +void __main (void) {} +int main (void); +]], [[]])], + [grub_cv_target_cc_mips_o32_abi="$arg"], []) + done + ]) + + if test x"$grub_cv_target_cc_mips_o32_abi" = xno ; then + AC_MSG_ERROR([could not force MIPS o32 ABI]) + fi + + TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_mips_o32_abi" + TARGET_CCASFLAGS="$TARGET_CCASFLAGS $grub_cv_target_cc_mips_o32_abi" +fi + +AC_CACHE_CHECK([for options to compile assembly], [grub_cv_cc_target_asm_compile], [ +test_program= +case "x$target_cpu-$platform" in + xmips-* | xmipsel-*) + test_program=mips + ;; + xi386-pc) + test_program=i386-pc + ;; + xi386-* | xx86_64-*) + test_program=i386 + ;; + xpowerpc-* | xsparc64-* | xarm-*) + test_program=$target_cpu + ;; +esac +if test x"$test_program" = x ; then + grub_cv_cc_target_asm_compile= +else + found=no + for arg in "" "-no-integrated-as"; do + cmdline="$TARGET_CC -c -o /dev/null $TARGET_CCASFLAGS $arg $TARGET_CPPFLAGS $srcdir/asm-tests/$test_program.S" + echo "Running $cmdline" >&AS_MESSAGE_LOG_FD + if $cmdline >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD; then + grub_cv_cc_target_asm_compile="$arg" + found=yes + break + fi + done + if test x"$found" = xno ; then + AC_MSG_ERROR([could not compile assembly]) + fi +fi +]) + +TARGET_CCASFLAGS="$TARGET_CCASFLAGS $grub_cv_cc_target_asm_compile" + +if test "x$target_cpu" = xi386 && test "x$platform" != xemu; then + TARGET_CFLAGS="$TARGET_CFLAGS -march=i386" +fi + +if test "x$target_m32" = x1; then + # Force 32-bit mode. + TARGET_CFLAGS="$TARGET_CFLAGS -m32" + TARGET_CCASFLAGS="$TARGET_CCASFLAGS -m32" + TARGET_CPPFLAGS="$TARGET_CPPFLAGS -m32" + TARGET_LDFLAGS="$TARGET_LDFLAGS -m32" + TARGET_MODULE_FORMAT="elf32" +fi + +if test "x$target_m64" = x1; then + # Force 64-bit mode. + TARGET_CFLAGS="$TARGET_CFLAGS -m64" + TARGET_CCASFLAGS="$TARGET_CCASFLAGS -m64" + TARGET_CPPFLAGS="$TARGET_CPPFLAGS -m64" + TARGET_LDFLAGS="$TARGET_LDFLAGS -m64" + TARGET_MODULE_FORMAT="elf64" +fi + +if test "x$grub_cv_cc_target_clang" = xno && test "x$target_cpu" = xi386 && test "x$platform" != xemu && test "x$platform" != xefi; then + TARGET_CFLAGS="$TARGET_CFLAGS -mrtd -mregparm=3" +fi + +# on mips redirect cache flushing function to non-existant one. +if test "x$target_cpu" = xmips || test "x$target_cpu" = xmipsel ; then + AC_CACHE_CHECK([whether -mflush-func=grub_red_herring works], [grub_cv_cc_mflush_func], [ + CFLAGS="$TARGET_CFLAGS -mflush-func=grub_red_herring -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_mflush_func=yes], + [grub_cv_cc_mflush_func=no]) + ]) + + if test "x$grub_cv_cc_mflush_func" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -mflush-func=grub_red_herring" + fi +fi + + +# Force no alignment to save space on i386. +if test "x$target_cpu" = xi386; then + AC_CACHE_CHECK([whether -falign-loops works], [grub_cv_cc_falign_loop], [ + CFLAGS="$TARGET_CFLAGS -falign-loops=1 -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_falign_loop=yes], + [grub_cv_cc_falign_loop=no]) + ]) + + AC_CACHE_CHECK([whether -malign-loops works], [grub_cv_cc_malign_loop], [ + CFLAGS="$TARGET_CFLAGS -malign-loops=1 -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_malign_loop=yes], + [grub_cv_cc_malign_loop=no]) + ]) + + if test "x$grub_cv_cc_falign_loop" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -falign-jumps=1 -falign-loops=1 -falign-functions=1" + elif test "x$grub_cv_cc_malign_loop" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -malign-jumps=1 -malign-loops=1 -malign-functions=1" + fi +fi + +AC_CACHE_CHECK([whether -freg-struct-return works], [grub_cv_cc_freg_struct_return], [ + CFLAGS="$TARGET_CFLAGS -freg-struct-return -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_freg_struct_return=yes], + [grub_cv_cc_freg_struct_return=no]) +]) + +if test "x$grub_cv_cc_freg_struct_return" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -freg-struct-return" +fi + +if ( test "x$target_cpu" = xi386 || test "x$target_cpu" = xx86_64 ) && test "x$platform" != xemu; then + # Some toolchains enable these features by default, but they need + # registers that aren't set up properly in GRUB. + TARGET_CFLAGS="$TARGET_CFLAGS -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow" +fi + +# GRUB doesn't use float or doubles at all. Yet some toolchains may decide +# that floats are a good fit to run instead of what's written in the code. +# Given that floating point unit is disabled (if present to begin with) +# when GRUB is running which may result in various hard crashes. +#if test x"$platform" != xemu ; then +if ( test x"$platform" != xemu && x"$platform" != mips64el-efi ) ; then + AC_CACHE_CHECK([for options to get soft-float], grub_cv_target_cc_soft_float, [ + grub_cv_target_cc_soft_float=no + if test "x$target_cpu" = xarm64; then + CFLAGS="$TARGET_CFLAGS -mgeneral-regs-only -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_target_cc_soft_float="-mgeneral-regs-only"], []) + fi + if test "x$target_cpu" = xriscv32; then + CFLAGS="$TARGET_CFLAGS -march=rv32imac -mabi=ilp32 -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_target_cc_soft_float="-march=rv32imac -mabi=ilp32"], []) + fi + if test "x$target_cpu" = xriscv64; then + CFLAGS="$TARGET_CFLAGS -march=rv64imac -mabi=lp64 -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_target_cc_soft_float="-march=rv64imac -mabi=lp64"], []) + fi + if test "x$target_cpu" = xia64; then + CFLAGS="$TARGET_CFLAGS -mno-inline-float-divide -mno-inline-sqrt -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_target_cc_soft_float="-mno-inline-float-divide -mno-inline-sqrt"], []) + fi + for cand in "-msoft-float -Xclang -msoft-float -Xclang -no-implicit-float" \ + "-Xclang -msoft-float -Xclang -no-implicit-float" \ + "-Xclang -msoft-float" "-msoft-float"; do + if test x"$grub_cv_target_cc_soft_float" != xno ; then + break + fi + CFLAGS="$TARGET_CFLAGS $cand -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_target_cc_soft_float="$cand"], []) + done + ]) + + if test x"$grub_cv_target_cc_soft_float" = xno ; then + AC_MSG_ERROR([could not force soft-float]) + fi + + case x"$grub_cv_target_cc_soft_float" in + x*"-Xclang"*) + # A trick so that clang doesn't see it on link stаge + TARGET_CPPFLAGS="$TARGET_CPPFLAGS $grub_cv_target_cc_soft_float" + ;; + *) + TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_soft_float" + ;; + esac + TARGET_CCASFLAGS="$TARGET_CCASFLAGS $grub_cv_target_cc_soft_float" + +fi + +if test x"$target_cpu" = xsparc64 ; then + AC_CACHE_CHECK([for options to reserve application registers], grub_cv_target_cc_mno_app_regs, [ + grub_cv_target_cc_mno_app_regs=no + for cand in "-mllvm -sparc-reserve-app-registers" \ + "-mno-app-regs"; do + if test x"$grub_cv_target_cc_mno_app_regs" != xno ; then + break + fi + CFLAGS="$TARGET_CFLAGS $cand -Werror" + CPPFLAGS="$TARGET_CPPFLAGS" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_target_cc_mno_app_regs="$cand"], []) + done + ]) + + if test x"$grub_cv_target_cc_mno_app_regs" = xno ; then + AC_MSG_ERROR([could not reserve application registers]) + fi + if test x"$grub_cv_target_cc_mno_app_regs" = x"-mllvm -sparc-reserve-app-registers" ; then + # A trick so that clang doesn't see it on link stаge + TARGET_CPPFLAGS="$TARGET_CPPFLAGS $grub_cv_target_cc_mno_app_regs" + else + TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_mno_app_regs" + fi + + AC_CACHE_CHECK([for no-relax options], grub_cv_target_cc_mno_relax, [ + grub_cv_target_cc_mno_relax=no + for cand in "-mno-relax" "-Wl,--no-relax"; do + if test x"$grub_cv_target_cc_mno_relax" != xno ; then + break + fi + LDFLAGS="$TARGET_LDFLAGS $cand -nostdlib -static" + CFLAGS="$TARGET_CFLAGS -Werror" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + asm (".globl start; start:"); + void __main (void); + void __main (void) {} + int main (void); + ]], [[]])], [grub_cv_target_cc_mno_relax="$cand"], []) + done + ]) + LDFLAGS="$TARGET_LDFLAGS" + CFLAGS="$TARGET_CFLAGS" + + if test x"$grub_cv_target_cc_mno_relax" = xno ; then + AC_MSG_ERROR([could not find no-relax options]) + fi + TARGET_LDFLAGS="$TARGET_LDFLAGS $grub_cv_target_cc_mno_relax" +fi + +# By default, GCC 4.4 generates .eh_frame sections containing unwind +# information in some cases where it previously did not. GRUB doesn't need +# these and they just use up vital space. Restore the old compiler +# behaviour. +AC_CACHE_CHECK([whether -fno-dwarf2-cfi-asm works], [grub_cv_cc_fno_dwarf2_cfi_asm], [ + CFLAGS="$TARGET_CFLAGS -fno-dwarf2-cfi-asm" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_fno_dwarf2_cfi_asm=yes], + [grub_cv_cc_fno_dwarf2_cfi_asm=no]) +]) + +if test "x$grub_cv_cc_fno_dwarf2_cfi_asm" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -fno-dwarf2-cfi-asm" +fi + +if test x"$target_os" = xcygwin; then + AC_CACHE_CHECK([whether option -fno-reorder-functions works], grub_cv_cc_no_reorder_functions, [ + CFLAGS="$TARGET_CFLAGS -fno-reorder-functions" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_no_reorder_functions=yes], + [grub_cv_cc_no_reorder_functions=no]) + ]) +fi + +if test x"$target_os" = xcygwin && test "x$grub_cv_cc_no_reorder_functions" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -fno-reorder-functions" +fi + +AC_CACHE_CHECK([whether -mno-stack-arg-probe works], [grub_cv_cc_mno_stack_arg_probe], [ + CFLAGS="$TARGET_CFLAGS -mno-stack-arg-probe" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_mno_stack_arg_probe=yes], + [grub_cv_cc_mno_stack_arg_probe=no]) +]) + +if test "x$grub_cv_cc_mno_stack_arg_probe" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -mno-stack-arg-probe" +fi + + +# By default, GCC 4.6 generates .eh_frame sections containing unwind +# information in some cases where it previously did not. GRUB doesn't need +# these and they just use up vital space. Restore the old compiler +# behaviour. +AC_CACHE_CHECK([whether -fno-asynchronous-unwind-tables works], [grub_cv_cc_fno_asynchronous_unwind_tables], [ + CFLAGS="$TARGET_CFLAGS -fno-asynchronous-unwind-tables" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_fno_asynchronous_unwind_tables=yes], + [grub_cv_cc_fno_asynchronous_unwind_tables=no]) +]) + +if test "x$grub_cv_cc_fno_asynchronous_unwind_tables" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -fno-asynchronous-unwind-tables" +fi + +AC_CACHE_CHECK([whether -fno-unwind-tables works], [grub_cv_cc_fno_unwind_tables], [ + CFLAGS="$TARGET_CFLAGS -fno-unwind-tables" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_fno_unwind_tables=yes], + [grub_cv_cc_fno_unwind_tables=no]) +]) + +if test "x$grub_cv_cc_fno_unwind_tables" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -fno-unwind-tables" +fi + + +CFLAGS="$TARGET_CFLAGS" + + +if test x"$platform" = xemu ; then + TARGET_OBJ2ELF= + grub_cv_target_cc_link_format= + case "$host_os" in + *darwin* | *mac*) + grub_cv_target_cc_link_format="-arch,${target_cpu}" + TARGET_LDFLAGS="$TARGET_LDFLAGS -Wl,$grub_cv_target_cc_link_format" + ;; + *windows* | *cygwin* | *mingw*) + if test x${target_cpu} = xi386 ; then + grub_cv_target_cc_link_format=-mi386pe + TARGET_OBJ2ELF='./build-grub-pe2elf$(BUILD_EXEEXT)' + fi + if test x${target_cpu} = xx86_64 ; then + grub_cv_target_cc_link_format=-mi386pep + TARGET_OBJ2ELF='./build-grub-pep2elf$(BUILD_EXEEXT)' + fi + TARGET_LDFLAGS="$TARGET_LDFLAGS -Wl,$grub_cv_target_cc_link_format" + ;; + esac +elif test x"$target_cpu" = xi386 || test x"$target_cpu" = xx86_64; then + AC_CACHE_CHECK([for target linking format], [grub_cv_target_cc_link_format], [ + grub_cv_target_cc_link_format=unknown + for format in -melf_${target_cpu} -melf_${target_cpu}_fbsd -melf_${target_cpu}_obsd -melf_${target_cpu}_haiku -mi386pe -mi386pep -arch,${target_cpu}; do + if test x${target_cpu} != xi386 && test x$format = x-mi386pe; then + continue + fi + if test x${target_cpu} != xx86_64 && test x$format = x-mi386pep; then + continue + fi + CFLAGS="$TARGET_CFLAGS" + LDFLAGS="$TARGET_LDFLAGS -Wl,$format -nostdlib -static" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + asm (".globl start; start:"); + asm (".globl _start; _start:"); + asm (".globl __start; __start:"); + void __main (void); + void __main (void) {} + ]], [[]])], [flag=1], [flag=0]) + if test x"$flag" = x1; then + grub_cv_target_cc_link_format="$format" + break + fi + done]) + if test x"$grub_cv_target_cc_link_format" = xunknown; then + AC_MSG_ERROR([no suitable link format found]) + fi + TARGET_LDFLAGS="$TARGET_LDFLAGS -Wl,$grub_cv_target_cc_link_format" + if test x"$grub_cv_target_cc_link_format" = x-mi386pe ; then + TARGET_OBJ2ELF='./build-grub-pe2elf$(BUILD_EXEEXT)' + fi + if test x"$grub_cv_target_cc_link_format" = x-mi386pep ; then + TARGET_OBJ2ELF='./build-grub-pep2elf$(BUILD_EXEEXT)' + fi +fi + +if test x$grub_cv_target_cc_link_format = x-arch,i386 || test x$grub_cv_target_cc_link_format = x-arch,x86_64; then + TARGET_APPLE_LINKER=1 + AC_CHECK_PROG([TARGET_OBJCONV], [objconv], [objconv], []) + if test "x$TARGET_OBJCONV" = x ; then + AC_CHECK_PROG([TARGET_OBJCONV], [objconv], [./objconv], [], [.]) + fi + if test "x$TARGET_OBJCONV" = x ; then + AC_MSG_ERROR([objconv not found which is required when building with apple compiler]) + fi + TARGET_IMG_LDSCRIPT= + TARGET_IMG_CFLAGS="-static" + TARGET_IMG_LDFLAGS='-nostdlib -static -Wl,-preload -Wl,-segalign,20' + TARGET_IMG_LDFLAGS_AC='-nostdlib -static -Wl,-preload -Wl,-segalign,20' + TARGET_IMG_BASE_LDOPT="-Wl,-image_base" + TARGET_LDFLAGS_OLDMAGIC="" +elif test x$grub_cv_target_cc_link_format = x-mi386pe || test x$grub_cv_target_cc_link_format = x-mi386pep ; then + TARGET_APPLE_LINKER=0 + TARGET_LDFLAGS_OLDMAGIC="-Wl,-N" + TARGET_IMG_LDSCRIPT='$(top_srcdir)'"/${grub_coredir}/conf/i386-cygwin-img-ld.sc" + TARGET_IMG_LDFLAGS="-Wl,-T${TARGET_IMG_LDSCRIPT}" + TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/${grub_coredir}/conf/i386-cygwin-img-ld.sc" + TARGET_IMG_BASE_LDOPT="-Wl,-Ttext" + TARGET_IMG_CFLAGS= +else + TARGET_APPLE_LINKER=0 + TARGET_LDFLAGS_OLDMAGIC="-Wl,-N" + TARGET_IMG_LDSCRIPT= + TARGET_IMG_LDFLAGS='-Wl,-N' + TARGET_IMG_LDFLAGS_AC='-Wl,-N' + TARGET_IMG_BASE_LDOPT="-Wl,-Ttext" + TARGET_IMG_CFLAGS= +fi + +CFLAGS="$TARGET_CFLAGS" + +AC_ARG_ENABLE([efiemu], + [AS_HELP_STRING([--enable-efiemu], + [build and install the efiemu runtimes (default=guessed)])]) +if test x"$enable_efiemu" = xno ; then + efiemu_excuse="explicitly disabled" +fi + +if test x"$grub_cv_target_cc_link_format" = x-mi386pe || test x"$grub_cv_target_cc_link_format" = x-mi386pep ; then + efiemu_excuse="not available on cygwin" +fi +if test x"$target_cpu" != xi386 ; then + efiemu_excuse="only available on i386" +fi +if test x"$platform" = xefi ; then + efiemu_excuse="not available on efi" +fi + +if test x"$efiemu_excuse" = x ; then + AC_CACHE_CHECK([whether options required for efiemu work], grub_cv_cc_efiemu, [ + CFLAGS="-m64 -nostdlib -O2 -mcmodel=large -mno-red-zone" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_efiemu=yes], + [grub_cv_cc_efiemu=no]) + ]) + if test x$grub_cv_cc_efiemu = xno; then + efiemu_excuse="cannot compile with -m64 -mcmodel=large -mno-red-zone -nostdlib" + fi +fi +if test x"$efiemu_excuse" = x ; then + AC_CACHE_CHECK([for efiemu64 linking format], [grub_cv_target_cc_efiemu64_link_format], [ + grub_cv_target_cc_efiemu64_link_format=unknown + for format in -melf_x86_64 -melf_x86_64_fbsd -melf_x86_64_obsd -melf_x86_64_haiku -arch,x86_64; do + CFLAGS="-m64 -nostdlib -O2 -mcmodel=large -mno-red-zone" + LDFLAGS="-m64 -Wl,$format -nostdlib -static" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + asm (".globl start; start:"); + asm (".globl _start; _start:"); + asm (".globl __start; __start:"); + void __main (void); + void __main (void) {} + ]], [[]])], [flag=1], [flag=0]) + if test x"$flag" = x1; then + grub_cv_target_cc_efiemu64_link_format="$format" + break + fi + done]) + if test x"$grub_cv_target_cc_efiemu64_link_format" = xunknown; then + efiemu_excuse="no suitable link format for efiemu64 found" + else + EFIEMU64_LINK_FORMAT="-Wl,$grub_cv_target_cc_efiemu64_link_format" + fi +fi +if test x"$enable_efiemu" = xyes && test x"$efiemu_excuse" != x ; then + AC_MSG_ERROR([efiemu runtime was explicitly requested but can't be compiled ($efiemu_excuse)]) +fi +if test x"$efiemu_excuse" = x ; then +enable_efiemu=yes +else +enable_efiemu=no +fi +AC_SUBST([enable_efiemu]) +AC_SUBST([EFIEMU64_LINK_FORMAT]) + +CFLAGS="$TARGET_CFLAGS" + +AC_SUBST(TARGET_LDFLAGS_OLDMAGIC) + + +LDFLAGS="$TARGET_LDFLAGS" + +if test "$target_cpu" = x86_64 || test "$target_cpu" = sparc64 || test "$target_cpu" = riscv64 ; then + # Use large model to support 4G memory + AC_CACHE_CHECK([whether option -mcmodel=large works], grub_cv_cc_mcmodel, [ + CFLAGS="$TARGET_CFLAGS -mcmodel=large" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_mcmodel=yes], + [grub_cv_cc_mcmodel=no]) + ]) + if test "x$grub_cv_cc_mcmodel" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=large" + elif test "$target_cpu" = sparc64 || test "$target_cpu" = riscv64; then + TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=medany" + fi +fi + +if test "$target_cpu"-"$platform" = x86_64-efi; then + # EFI writes to stack below %rsp, we must not use the red zone + AC_CACHE_CHECK([whether option -mno-red-zone works], grub_cv_cc_no_red_zone, [ + CFLAGS="$TARGET_CFLAGS -mno-red-zone" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_no_red_zone=yes], + [grub_cv_cc_no_red_zone=no]) + ]) + if test "x$grub_cv_cc_no_red_zone" = xno; then + AC_MSG_ERROR([-mno-red-zone not supported, upgrade your gcc]) + fi + + TARGET_CFLAGS="$TARGET_CFLAGS -mno-red-zone" +fi + +if test "x$target_cpu" = xarm; then + AC_CACHE_CHECK([for options to disable movt and movw], grub_cv_target_cc_mno_movt, [ + grub_cv_target_cc_mno_movt=no + for cand in "-mno-movt" \ + "-mllvm -arm-use-movt=0"; do + if test x"$grub_cv_target_cc_mno_movt" != xno ; then + break + fi + CFLAGS="$TARGET_CFLAGS $cand -Werror" + CPPFLAGS="$TARGET_CPPFLAGS" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_target_cc_mno_movt="$cand"], []) + done + ]) + + if test x"$grub_cv_target_cc_mno_movt" != xno ; then + # A trick so that clang doesn't see it on link stage + TARGET_CPPFLAGS="$TARGET_CPPFLAGS $grub_cv_target_cc_mno_movt" + fi + AC_CACHE_CHECK([whether option -mthumb-interwork works], grub_cv_cc_mthumb_interwork, [ + CFLAGS="$TARGET_CFLAGS -mthumb-interwork -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_mthumb_interwork=yes], + [grub_cv_cc_mthumb_interwork=no]) + ]) + if test "x$grub_cv_cc_mthumb_interwork" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -mthumb-interwork" + # Clang defaults to thumb interworking + elif test "x$grub_cv_cc_target_clang" = xno ; then + AC_MSG_ERROR([your compiler doesn't support -mthumb-interwork]) + fi +fi + +AC_CACHE_CHECK([whether option -Qn works], grub_cv_target_cc_qn, [ + CFLAGS="$TARGET_CFLAGS -Qn -Qunused-arguments -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_target_cc_qn=yes], + [grub_cv_target_cc_qn=no])]) +if test "x$grub_cv_target_cc_qn" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -Qn -Qunused-arguments" +fi + +# +# Compiler features. +# + +CFLAGS="$TARGET_CFLAGS" + +# Position independent executable. +grub_CHECK_PIE +grub_CHECK_NO_PIE +grub_CHECK_NO_PIE_ONEWORD +grub_CHECK_LINK_PIE +[# Need that, because some distributions ship compilers that include +# `-fPIE' or '-fpie' and '-pie' in the default specs. +if [ x"$pie_possible" = xyes ]; then + TARGET_CFLAGS="$TARGET_CFLAGS -fno-PIE -fno-pie" +fi + +if [ x"$link_nopie_needed" = xyes ] || [ x"$pie_possible" = xyes ]; then + if [ x"$nopie_possible" = xyes ]; then + TARGET_LDFLAGS="$TARGET_LDFLAGS -no-pie" + fi + if [ x"$nopie_oneword_possible" = xyes ]; then + TARGET_LDFLAGS="$TARGET_LDFLAGS -nopie" + fi +fi] + +CFLAGS="$TARGET_CFLAGS" +LDFLAGS="$TARGET_LDFLAGS" + +# Position independent executable. +grub_CHECK_PIC +[# On most platforms we don't want PIC as it only makes relocations harder +# and code less efficient. On mips we want to have one got table per module +# and reload $gp in every function. +# GCC implements it using symbol __gnu_local_gp in non-PIC as well. +# However with clang we need PIC for this reloading to happen. +# With arm64 we need relocations that are in some way representable in +# PE as we need to support arm64-efi. Without -fPIC clang generates +# movk's which aren't representable. +# Since default varies across dictributions use either -fPIC or -fno-PIC +# explicitly. +if ( test x$target_cpu = xmips || test x$target_cpu = xmipsel || test x$target_cpu = xarm64 || test x$target_cpu = xmips64el ) && test "x$grub_cv_cc_target_clang" = xyes ; then + TARGET_CFLAGS="$TARGET_CFLAGS -fPIC" +elif [ x"$pic_possible" = xyes ]; then + TARGET_CFLAGS="$TARGET_CFLAGS -fno-PIC" +fi +# Don't generate SVR4-style position-independent code for MIPS64. +if test x$target_cpu = xmips64el ; then + TARGET_CFLAGS="$TARGET_CFLAGS -mno-abicalls" + TARGET_CCASFLAGS="$TARGET_CCASFLAGS -mno-abicalls" +fi] + +CFLAGS="$TARGET_CFLAGS" + +# Smashing stack protector. +grub_CHECK_STACK_PROTECTOR +# Need that, because some distributions ship compilers that include +# `-fstack-protector' in the default specs. +if test "x$ssp_possible" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -fno-stack-protector" +fi + +CFLAGS="$TARGET_CFLAGS" + +grub_CHECK_STACK_ARG_PROBE +# Cygwin's GCC uses alloca() to probe the stackframe on static +# stack allocations above some threshold. +if test x"$sap_possible" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -mno-stack-arg-probe" +fi + +CFLAGS="$TARGET_CFLAGS" + +# -mno-unaligned-access -mstrict-align +if test "$target_cpu" = arm; then + AC_CACHE_CHECK([for compile options to get strict alignment], [grub_cv_target_cc_strict_align], [ + grub_cv_target_cc_strict_align= + for arg in -mno-unaligned-access "-Xclang -mstrict-align" -mstrict-align; do + CFLAGS="$TARGET_CFLAGS $arg -Werror" + LDFLAGS="$TARGET_LDFLAGS" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [flag=1], [flag=0]) + if test x"$flag" = x1; then + grub_cv_target_cc_strict_align="$arg" + break + fi + done]) + + TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_strict_align" + if test x"$grub_cv_target_cc_strict_align" = x"-Xclang -mstrict-align"; then + TARGET_LDFLAGS="$TARGET_LDFLAGS -Qunused-arguments" + fi + AC_CACHE_CHECK([if compiler generates unaligned accesses], [grub_cv_cc_target_emits_unaligned], + [CFLAGS="$TARGET_CFLAGS" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[ +#ifdef __ARM_FEATURE_UNALIGNED +#error "unaligned" +#endif + ]])], + [grub_cv_cc_target_emits_unaligned=no], [grub_cv_cc_target_emits_unaligned=yes])]) + if test x$grub_cv_cc_target_emits_unaligned = xyes; then + AC_MSG_ERROR([compiler generates unaligned accesses]) + fi +fi + +# Set them to their new values for the tests below. +CC="$TARGET_CC" +if test x"$platform" = xemu ; then +CFLAGS="$TARGET_CFLAGS -Wno-error" +elif test "x$TARGET_APPLE_LINKER" = x1 ; then +CFLAGS="$TARGET_CFLAGS -nostdlib -static -Wno-error" +else +CFLAGS="$TARGET_CFLAGS -nostdlib -Wno-error" +fi +CPPFLAGS="$TARGET_CPPFLAGS" + +grub_ASM_USCORE +if test "x$TARGET_APPLE_LINKER" = x0 && test x"$platform" != xemu; then +if test x$grub_cv_asm_uscore = xyes; then +DEFSYM="-Wl,--defsym,_abort=_main -Wl,--defsym,__main=_main" +else +DEFSYM="-Wl,--defsym,abort=main -Wl,--defsym,_main=main -Wl,--defsym,__main=main" +fi +CFLAGS="$TARGET_CFLAGS -nostdlib $DEFSYM" +fi + +# Check for libgcc symbols +if test x"$platform" = xemu; then +AC_CHECK_FUNCS(__udivsi3 __umodsi3 __divsi3 __modsi3 __divdi3 __moddi3 __udivdi3 __umoddi3 __ctzdi2 __ctzsi2 __aeabi_uidiv __aeabi_uidivmod __aeabi_idiv __aeabi_idivmod __aeabi_ulcmp __muldi3 __aeabi_lmul __aeabi_memcpy __aeabi_memcpy4 __aeabi_memcpy8 __aeabi_memclr __aeabi_memclr4 __aeabi_memclr8 __aeabi_memset __aeabi_lasr __aeabi_llsl __aeabi_llsr _restgpr_14_x __ucmpdi2 __ashldi3 __ashrdi3 __lshrdi3 __bswapsi2 __bswapdi2 __bzero __register_frame_info __deregister_frame_info ___chkstk_ms __chkstk_ms) +fi + +if test "x$TARGET_APPLE_LINKER" = x1 ; then +CFLAGS="$TARGET_CFLAGS -nostdlib -static" +else +CFLAGS="$TARGET_CFLAGS -nostdlib" +fi +LIBS="" + +# Defined in aclocal.m4. +grub_PROG_TARGET_CC +if test "x$TARGET_APPLE_LINKER" != x1 ; then +grub_PROG_OBJCOPY_ABSOLUTE +fi +grub_PROG_LD_BUILD_ID_NONE +if test "x$target_cpu" = xi386; then + if test "$platform" != emu && test "x$TARGET_APPLE_LINKER" != x1 ; then + if test ! -z "$TARGET_IMG_LDSCRIPT"; then + # Check symbols provided by linker script. + CFLAGS="$TARGET_CFLAGS -nostdlib ${TARGET_IMG_LDFLAGS_AC} ${TARGET_IMG_BASE_LDOPT},0x8000" + fi + grub_CHECK_BSS_START_SYMBOL + grub_CHECK_END_SYMBOL + fi + CFLAGS="$TARGET_CFLAGS" +fi + +grub_PROG_NM_WORKS +grub_PROG_NM_MINUS_P +grub_PROG_NM_DEFINED_ONLY +AC_SUBST(TARGET_NMFLAGS_MINUS_P) +AC_SUBST(TARGET_NMFLAGS_DEFINED_ONLY) + +if test "$platform" != emu; then +AC_CACHE_CHECK([whether -nostdinc -isystem works], [grub_cv_cc_isystem], [ + SAVED_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$TARGET_CPPFLAGS -nostdlib -nostdinc -isystem `$TARGET_CC -print-file-name=include`" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include +#include +int va_arg_func (int fixed, va_list args);]], [[]])], + [grub_cv_cc_isystem=yes], + [grub_cv_cc_isystem=no]) + CPPFLAGS="$SAVED_CPPFLAGS" +]) + +if test x"$grub_cv_cc_isystem" = xyes ; then + TARGET_CPPFLAGS="$TARGET_CPPFLAGS -nostdinc -isystem `$TARGET_CC -print-file-name=include`" +fi +fi + +AC_CACHE_CHECK([whether -Wtrampolines work], [grub_cv_cc_wtrampolines], [ + CFLAGS="$TARGET_CFLAGS -Wtrampolines -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include +int va_arg_func (int fixed, va_list args);]], [[]])], + [grub_cv_cc_wtrampolines=yes], + [grub_cv_cc_wtrampolines=no]) +]) + +if test x"$grub_cv_cc_wtrampolines" = xyes ; then + TARGET_CFLAGS="$TARGET_CFLAGS -Wtrampolines" +fi + +# Restore the flags. +CC="$tmp_CC" +CFLAGS="$tmp_CFLAGS" +CPPFLAGS="$tmp_CPPFLAGS" +LDFLAGS="$tmp_LDFLAGS" +LIBS="$tmp_LIBS" + +# +# Check for options. +# + +# Memory manager debugging. +AC_ARG_ENABLE([mm-debug], + AS_HELP_STRING([--enable-mm-debug], + [include memory manager debugging]), + [AC_DEFINE([MM_DEBUG], [1], + [Define to 1 if you enable memory manager debugging.])]) + +AC_ARG_ENABLE([cache-stats], + AS_HELP_STRING([--enable-cache-stats], + [enable disk cache statistics collection])) + +if test x$enable_cache_stats = xyes; then + DISK_CACHE_STATS=1 +else + DISK_CACHE_STATS=0 +fi +AC_SUBST([DISK_CACHE_STATS]) + +AC_ARG_ENABLE([boot-time], + AS_HELP_STRING([--enable-boot-time], + [enable boot time statistics collection])) + +if test x$enable_boot_time = xyes; then + BOOT_TIME_STATS=1 +else + BOOT_TIME_STATS=0 +fi +AC_SUBST([BOOT_TIME_STATS]) + +AC_ARG_ENABLE([grub-emu-sdl], + [AS_HELP_STRING([--enable-grub-emu-sdl], + [build and install the `grub-emu' debugging utility with SDL support (default=guessed)])]) + +AC_ARG_ENABLE([grub-emu-pci], + [AS_HELP_STRING([--enable-grub-emu-pci], + [build and install the `grub-emu' debugging utility with PCI support (potentially dangerous) (default=no)])]) + +if test "$platform" = emu; then + +if test x"$enable_grub_emu_sdl" = xno ; then + grub_emu_sdl_excuse="explicitly disabled" +fi +[if [ x"$grub_emu_sdl_excuse" = x ]; then + # Check for libSDL libraries.] +AC_CHECK_LIB([SDL], [SDL_Init], [LIBSDL="-lSDL"], + [grub_emu_sdl_excuse=["libSDL libraries are required to build \`grub-emu' with SDL support"]]) + AC_SUBST([LIBSDL]) +[fi] + +[if [ x"$grub_emu_sdl_excuse" = x ]; then + # Check for headers.] + AC_CHECK_HEADERS([SDL/SDL.h], [], + [grub_emu_sdl_excuse=["libSDL header file is required to build \`grub-emu' with SDL support"]]) +[fi] + +if test x"enable_grub_emu_sdl" = xyes && test x"$grub_emu_sdl_excuse" != x ; then + AC_MSG_ERROR([SDL support for grub-emu was explicitly requested but can't be compiled ($grub_emu_sdl_excuse)]) +fi +if test x"$grub_emu_sdl_excuse" = x ; then +enable_grub_emu_sdl=yes +else +enable_grub_emu_sdl=no +fi + +if test x"$enable_grub_emu_pci" != xyes ; then + grub_emu_pci_excuse="not enabled" +fi + +[if [ x"$grub_emu_pci_excuse" = x ]; then + # Check for libpci libraries.] + AC_CHECK_LIB([pciaccess], [pci_system_init], [LIBPCIACCESS="-lpciaccess"], + [grub_emu_pci_excuse=["need libpciaccess library"]]) + AC_SUBST([LIBPCIACCESS]) +[fi] +[if [ x"$grub_emu_pci_excuse" = x ]; then + # Check for headers.] + AC_CHECK_HEADERS([pciaccess.h], [], + [grub_emu_pci_excuse=["need libpciaccess headers"]]) +[fi] + +if test x"$grub_emu_pci_excuse" = x ; then +enable_grub_emu_pci=yes +else + +enable_grub_emu_pci=no +fi + +AC_SUBST([enable_grub_emu_sdl]) +AC_SUBST([enable_grub_emu_pci]) + +else + +# Ignore --enable-emu-* if platform is not emu +enable_grub_emu_sdl=no +enable_grub_emu_pci=no +fi + +AC_ARG_ENABLE([grub-mkfont], + [AS_HELP_STRING([--enable-grub-mkfont], + [build and install the `grub-mkfont' utility (default=guessed)])]) +if test x"$enable_grub_mkfont" = xno ; then + grub_mkfont_excuse="explicitly disabled" +fi + +unset ac_cv_header_ft2build_h + +if test x"$grub_mkfont_excuse" = x ; then + # Check for freetype libraries. + PKG_CHECK_MODULES([FREETYPE], [freetype2], [ + SAVED_CPPFLAGS="$CPPFLAGS" + SAVED_LIBS="$LIBS" + CPPFLAGS="$CPPFLAGS $FREETYPE_CFLAGS" + LIBS="$LIBS $FREETYPE_LIBS" + AC_CHECK_HEADERS([ft2build.h], [], + [grub_mkfont_excuse=["need freetype2 headers"]]) + AC_LINK_IFELSE([AC_LANG_CALL([], [FT_Load_Glyph])], [], + [grub_mkfont_excuse=["freetype2 library unusable"]]) + CPPFLAGS="$SAVED_CPPFLAGS" + LIBS="$SAVED_LIBS" + ], [grub_mkfont_excuse=["need freetype2 library"]]) +fi + +if test x"$enable_grub_mkfont" = xyes && test x"$grub_mkfont_excuse" != x ; then + AC_MSG_ERROR([grub-mkfont was explicitly requested but can't be compiled ($grub_mkfont_excuse)]) +fi +if test x"$grub_mkfont_excuse" = x ; then +enable_grub_mkfont=yes +else +enable_grub_mkfont=no +fi +AC_SUBST([enable_grub_mkfont]) + +SAVED_CC="$CC" +SAVED_CPP="$CPP" +SAVED_CFLAGS="$CFLAGS" +SAVED_CPPFLAGS="$CPPFLAGS" +SAVED_LDFLAGS="$LDFLAGS" +CC="$BUILD_CC" +CPP="$BUILD_CPP" +CFLAGS="$BUILD_CFLAGS" +CPPFLAGS="$BUILD_CPPFLAGS" +LDFLAGS="$BUILD_LDFAGS" + +unset ac_cv_c_bigendian +unset ac_cv_header_ft2build_h + +AC_COMPUTE_INT([BUILD_SIZEOF_VOID_P], [sizeof (void *)]) +AC_COMPUTE_INT([BUILD_SIZEOF_LONG], [sizeof (long)]) +AC_C_BIGENDIAN([BUILD_WORDS_BIGENDIAN=1], [BUILD_WORDS_BIGENDIAN=0], [BUILD_WORDS_BIGENDIAN=err], [BUILD_WORDS_BIGENDIAN=err]) + +if test x$BUILD_WORDS_BIGENDIAN = xerr ; then + AC_MSG_ERROR([couldnt determine build endianness]) +fi + +AC_SUBST([BUILD_SIZEOF_LONG]) +AC_SUBST([BUILD_SIZEOF_VOID_P]) +AC_SUBST([BUILD_WORDS_BIGENDIAN]) + +if test x"$grub_build_mkfont_excuse" = x ; then + # Check for freetype libraries. + SAVED_PKG_CONFIG="$PKG_CONFIG" + test -z "$BUILD_PKG_CONFIG" || PKG_CONFIG="$BUILD_PKG_CONFIG" + PKG_CHECK_MODULES([BUILD_FREETYPE], [freetype2], [ + SAVED_CPPFLAGS_2="$CPPFLAGS" + SAVED_LIBS="$LIBS" + CPPFLAGS="$CPPFLAGS $BUILD_FREETYPE_CFLAGS" + LIBS="$LIBS $BUILD_FREETYPE_LIBS" + AC_CHECK_HEADERS([ft2build.h], [], + [grub_build_mkfont_excuse=["need freetype2 headers"]]) + AC_LINK_IFELSE([AC_LANG_CALL([], [FT_Load_Glyph])], [], + [grub_build_mkfont_excuse=["freetype2 library unusable"]]) + LIBS="$SAVED_LIBS" + CPPFLAGS="$SAVED_CPPFLAGS_2" + ], [grub_build_mkfont_excuse=["need freetype2 library"]]) + PKG_CONFIG="$SAVED_PKG_CONFIG" +fi + +if test x"$enable_build_grub_mkfont" = xyes && test x"$grub_build_mkfont_excuse" != x ; then + AC_MSG_ERROR([build-grub-mkfont was explicitly requested but can't be compiled ($grub_build_mkfont_excuse)]) +fi +if test x"$grub_build_mkfont_excuse" = x ; then + enable_build_grub_mkfont=yes +else + enable_build_grub_mkfont=no +fi +if test x"$enable_build_grub_mkfont" = xno && ( test "x$platform" = xqemu || test "x$platform" = xloongson || test "x$platform" = xqemu_mips || test "x$platform" = xcoreboot ); then + if test x"$grub_build_mkfont_excuse" = x ; then + AC_MSG_ERROR([qemu, coreboot and loongson ports need build-time grub-mkfont]) + else + AC_MSG_ERROR([qemu, coreboot and loongson ports need build-time grub-mkfont ($grub_build_mkfont_excuse)]) + fi +fi + +CC="$SAVED_CC" +CPP="$SAVED_CPP" +CFLAGS="$SAVED_CFLAGS" +CPPFLAGS="$SAVED_CPPFLAGS" +LDFLAGS="$SAVED_LDFLAGS" + + +DJVU_FONT_SOURCE= + +starfield_excuse= + +AC_ARG_ENABLE([grub-themes], + [AS_HELP_STRING([--enable-grub-themes], + [build and install GRUB themes (default=guessed)])]) +if test x"$enable_grub_themes" = xno ; then + starfield_excuse="explicitly disabled" +fi + +if test x"$starfield_excuse" = x && test x"$enable_build_grub_mkfont" = xno ; then + starfield_excuse="No build-time grub-mkfont" +fi + +if test x"$starfield_excuse" = x; then + for ext in pcf pcf.gz bdf bdf.gz ttf ttf.gz; do + for dir in . /usr/src /usr/share/fonts/X11/misc /usr/share/fonts/truetype/ttf-dejavu /usr/share/fonts/dejavu /usr/share/fonts/truetype; do + if test -f "$dir/DejaVuSans.$ext"; then + DJVU_FONT_SOURCE="$dir/DejaVuSans.$ext" + break 2 + fi + done + done + + if test "x$DJVU_FONT_SOURCE" = x; then + starfield_excuse="No DejaVu found" + fi +fi + +if test x"$enable_grub_themes" = xyes && test x"$starfield_excuse" != x; then + AC_MSG_ERROR([themes were explicitly requested but requirements are not satisfied ($starfield_excuse)]) +fi + +AC_SUBST([DJVU_FONT_SOURCE]) + +FONT_SOURCE= + +for ext in pcf pcf.gz bdf bdf.gz ttf ttf.gz; do + for dir in . /usr/src /usr/share/fonts/X11/misc /usr/share/fonts/unifont /usr/share/fonts/uni /usr/share/fonts/truetype/unifont /usr/share/fonts/misc; do + if test -f "$dir/unifont.$ext"; then + md5="$(md5sum "$dir/unifont.$ext"|awk '{ print $1; }')" + # PCF and BDF from version 6.3 isn't hanled properly by libfreetype. + if test "$md5" = 0a54834d2788c83886a3e1785a6a1e61 || test "$md5" = 28f2565c7a41d8d407e2551159385edb || test "$md5" = dae5e588461b3b92b87b6ffee734f936 || test "$md5" = 4a3d687aa5bb329ed05f4263a1016791 ; then + continue + fi + FONT_SOURCE="$dir/unifont.$ext" + break 2 + fi + done +done + +if test x"$enable_build_grub_mkfont" = xno ; then + FONT_SOURCE= +fi + +if test "x$FONT_SOURCE" = x && ( test "x$platform" = xqemu || test "x$platform" = xloongson || test "x$platform" = xqemu_mips || test "x$platform" = xcoreboot ); then + if test x"$grub_build_mkfont_excuse" = x ; then + AC_MSG_ERROR([qemu, coreboot and loongson ports need unifont]) + else + AC_MSG_ERROR([qemu, coreboot and loongson ports need unifont ($grub_build_mkfont_excuse)]) + fi +fi + +AC_SUBST([FONT_SOURCE]) + +if test x"$FONT_SOURCE" = x && test x"$DJVU_FONT_SOURCE" = x && test x"$grub_build_mkfont_excuse" = x; then + grub_build_mkfont_excuse="no fonts" +fi + + +AC_ARG_ENABLE([grub-mount], + [AS_HELP_STRING([--enable-grub-mount], + [build and install the `grub-mount' utility (default=guessed)])]) +if test x"$enable_grub_mount" = xno ; then + grub_mount_excuse="explicitly disabled" +fi + +if test x"$grub_mount_excuse" = x ; then + AC_CHECK_LIB([fuse], [fuse_main_real], [], + [grub_mount_excuse="need FUSE library"]) +fi + +if test x"$grub_mount_excuse" = x ; then + # Check for fuse headers. + SAVED_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS -DFUSE_USE_VERSION=26" + AC_CHECK_HEADERS([fuse/fuse.h], [], + [grub_mount_excuse=["need FUSE headers"]]) + CPPFLAGS="$SAVED_CPPFLAGS" +fi + +if test x"$enable_grub_mount" = xyes && test x"$grub_mount_excuse" != x ; then + AC_MSG_ERROR([grub-mount was explicitly requested but can't be compiled ($grub_mount_excuse)]) +fi +if test x"$grub_mount_excuse" = x ; then +enable_grub_mount=yes +else +enable_grub_mount=no +fi +AC_SUBST([enable_grub_mount]) + +AC_ARG_ENABLE([device-mapper], + [AS_HELP_STRING([--enable-device-mapper], + [enable Linux device-mapper support (default=guessed)])]) +if test x"$enable_device_mapper" = xno ; then + device_mapper_excuse="explicitly disabled" +fi + +if test x"$device_mapper_excuse" = x ; then + # Check for device-mapper header. + AC_CHECK_HEADER([libdevmapper.h], [], + [device_mapper_excuse="need libdevmapper header"]) +fi + +if test x"$device_mapper_excuse" = x ; then + # Check for device-mapper library. + AC_CHECK_LIB([devmapper], [dm_task_create], [], + [device_mapper_excuse="need devmapper library"]) +fi + +if test x"$device_mapper_excuse" = x ; then + # Check for device-mapper library. + AC_CHECK_LIB([devmapper], [dm_log_with_errno_init], + [], + [device_mapper_excuse="need devmapper library"]) +fi + +if test x"$device_mapper_excuse" = x ; then + LIBDEVMAPPER="-ldevmapper" + AC_DEFINE([HAVE_DEVICE_MAPPER], [1], + [Define to 1 if you have the devmapper library.]) +fi + +AC_SUBST([LIBDEVMAPPER]) + +LIBGEOM= +if test x$host_kernel = xkfreebsd; then + AC_CHECK_LIB([geom], [geom_gettree], [], + [AC_MSG_ERROR([Your platform requires libgeom])]) + LIBGEOM="-lgeom" +fi + +AC_SUBST([LIBGEOM]) + +AC_ARG_ENABLE([liblzma], + [AS_HELP_STRING([--enable-liblzma], + [enable liblzma integration (default=guessed)])]) +if test x"$enable_liblzma" = xno ; then + liblzma_excuse="explicitly disabled" +fi + +if test x"$liblzma_excuse" = x ; then +AC_CHECK_LIB([lzma], [lzma_code], + [],[liblzma_excuse="need lzma library"]) +fi +if test x"$liblzma_excuse" = x ; then +AC_CHECK_HEADER([lzma.h], [], [liblzma_excuse="need lzma header"]) +fi + +if test x"$enable_liblzma" = xyes && test x"$liblzma_excuse" != x ; then + AC_MSG_ERROR([liblzma support was explicitly requested but requirements are not satisfied ($liblzma_excuse)]) +fi + + +if test x"$liblzma_excuse" = x ; then + LIBLZMA="-llzma" + AC_DEFINE([USE_LIBLZMA], [1], + [Define to 1 if you have the LZMA library.]) +fi + +AC_SUBST([LIBLZMA]) + +AC_ARG_ENABLE([libzfs], + [AS_HELP_STRING([--enable-libzfs], + [enable libzfs integration (default=guessed)])]) +if test x"$enable_libzfs" = xno ; then + libzfs_excuse="explicitly disabled" +fi + +if test x"$libzfs_excuse" = x ; then + # Only check for system headers if libzfs support has not been disabled. + AC_CHECK_HEADERS(libzfs.h libnvpair.h) +fi + +if test x"$libzfs_excuse" = x ; then + AC_CHECK_LIB([zfs], [libzfs_init], + [], + [libzfs_excuse="need zfs library"]) +fi + +if test x"$libzfs_excuse" = x ; then + AC_CHECK_LIB([nvpair], [nvlist_lookup_string], + [], + [libzfs_excuse="need nvpair library"]) +fi + +if test x"$enable_libzfs" = xyes && test x"$libzfs_excuse" != x ; then + AC_MSG_ERROR([libzfs support was explicitly requested but requirements are not satisfied ($libzfs_excuse)]) +fi + +if test x"$libzfs_excuse" = x ; then + # We need both libzfs and libnvpair for a successful build. + LIBZFS="-lzfs" + AC_DEFINE([HAVE_LIBZFS], [1], + [Define to 1 if you have the ZFS library.]) + LIBNVPAIR="-lnvpair" + AC_DEFINE([HAVE_LIBNVPAIR], [1], + [Define to 1 if you have the NVPAIR library.]) +fi + +AC_SUBST([LIBZFS]) +AC_SUBST([LIBNVPAIR]) + +LIBS="" + +AC_SUBST([FONT_SOURCE]) +AS_IF([test x$target_cpu = xi386 -a x$platform = xqemu], + [AC_SUBST([GRUB_BOOT_MACHINE_LINK_ADDR], 0xffe00)]) + +AC_SUBST(HAVE_ASM_USCORE) +AC_SUBST(BSS_START_SYMBOL) +AC_SUBST(END_SYMBOL) +AC_SUBST(PACKAGE) +AC_SUBST(VERSION) + +AC_ARG_ENABLE([werror], + [AS_HELP_STRING([--disable-werror], + [do not use -Werror when building GRUB])]) +if test x"$enable_werror" != xno ; then + TARGET_CFLAGS="$TARGET_CFLAGS -Werror" + HOST_CFLAGS="$HOST_CFLAGS -Werror" +fi + +TARGET_CPP="$TARGET_CC -E" +TARGET_CCAS=$TARGET_CC + +# Includes which include make-time substitutions. They must come last +# as to avoid executing top_builddir in shell. +HOST_CPPFLAGS="$HOST_CPPFLAGS -I\$(top_builddir)/include" +TARGET_CPPFLAGS="$TARGET_CPPFLAGS -I\$(top_srcdir)/include" +TARGET_CPPFLAGS="$TARGET_CPPFLAGS -I\$(top_builddir)/include" + +GRUB_TARGET_CPU="${target_cpu}" +GRUB_PLATFORM="${platform}" + +AC_SUBST(GRUB_TARGET_CPU) +AC_SUBST(GRUB_PLATFORM) + +AC_SUBST(TARGET_OBJCONV) +AC_SUBST(TARGET_CPP) +AC_SUBST(TARGET_CCAS) +AC_SUBST(TARGET_OBJ2ELF) +AC_SUBST(TARGET_MODULE_FORMAT) +AC_SUBST(TARGET_CC_VERSION) + +AC_SUBST(TARGET_CFLAGS) +AC_SUBST(TARGET_LDFLAGS) +AC_SUBST(TARGET_CPPFLAGS) +AC_SUBST(TARGET_CCASFLAGS) + +AC_SUBST(TARGET_IMG_LDFLAGS) +AC_SUBST(TARGET_IMG_CFLAGS) +AC_SUBST(TARGET_IMG_BASE_LDOPT) +AC_SUBST(TARGET_APPLE_LINKER) + +AC_SUBST(HOST_CFLAGS) +AC_SUBST(HOST_LDFLAGS) +AC_SUBST(HOST_CPPFLAGS) +AC_SUBST(HOST_CCASFLAGS) + +AC_SUBST(BUILD_LIBM) + +# +# Automake conditionals +# + +AM_CONDITIONAL([COND_real_platform], [test x$platform != xnone]) +AM_CONDITIONAL([COND_emu], [test x$platform = xemu]) +AM_CONDITIONAL([COND_i386_pc], [test x$target_cpu = xi386 -a x$platform = xpc]) +AM_CONDITIONAL([COND_i386_efi], [test x$target_cpu = xi386 -a x$platform = xefi]) +AM_CONDITIONAL([COND_ia64_efi], [test x$target_cpu = xia64 -a x$platform = xefi]) +AM_CONDITIONAL([COND_i386_qemu], [test x$target_cpu = xi386 -a x$platform = xqemu]) +AM_CONDITIONAL([COND_i386_ieee1275], [test x$target_cpu = xi386 -a x$platform = xieee1275]) +AM_CONDITIONAL([COND_i386_coreboot], [test x$target_cpu = xi386 -a x$platform = xcoreboot]) +AM_CONDITIONAL([COND_i386_multiboot], [test x$target_cpu = xi386 -a x$platform = xmultiboot]) +AM_CONDITIONAL([COND_x86_64_efi], [test x$target_cpu = xx86_64 -a x$platform = xefi]) +AM_CONDITIONAL([COND_i386_xen], [test x$target_cpu = xi386 -a x$platform = xxen]) +AM_CONDITIONAL([COND_i386_xen_pvh], [test x$target_cpu = xi386 -a x$platform = xxen_pvh]) +AM_CONDITIONAL([COND_x86_64_xen], [test x$target_cpu = xx86_64 -a x$platform = xxen]) +AM_CONDITIONAL([COND_mips64_efi], [test x$target_cpu = xmips64el -a x$platform = xefi]) +AM_CONDITIONAL([COND_mips_loongson], [test x$target_cpu = xmipsel -a x$platform = xloongson]) +AM_CONDITIONAL([COND_mips_qemu_mips], [test "(" x$target_cpu = xmips -o x$target_cpu = xmipsel ")" -a x$platform = xqemu_mips]) +AM_CONDITIONAL([COND_mips_arc], [test "(" x$target_cpu = xmips -o x$target_cpu = xmipsel ")" -a x$platform = xarc]) +AM_CONDITIONAL([COND_sparc64_ieee1275], [test x$target_cpu = xsparc64 -a x$platform = xieee1275]) +AM_CONDITIONAL([COND_sparc64_emu], [test x$target_cpu = xsparc64 -a x$platform = xemu]) +AM_CONDITIONAL([COND_powerpc_ieee1275], [test x$target_cpu = xpowerpc -a x$platform = xieee1275]) +AM_CONDITIONAL([COND_mips64el], [test x$target_cpu = xmips64el]) +AM_CONDITIONAL([COND_mips], [test x$target_cpu = xmips -o x$target_cpu = xmipsel]) +AM_CONDITIONAL([COND_mipsel], [test x$target_cpu = xmipsel]) +AM_CONDITIONAL([COND_mipseb], [test x$target_cpu = xmips]) +AM_CONDITIONAL([COND_arm], [test x$target_cpu = xarm ]) +AM_CONDITIONAL([COND_arm_uboot], [test x$target_cpu = xarm -a x$platform = xuboot]) +AM_CONDITIONAL([COND_arm_coreboot], [test x$target_cpu = xarm -a x$platform = xcoreboot]) +AM_CONDITIONAL([COND_arm_efi], [test x$target_cpu = xarm -a x$platform = xefi]) +AM_CONDITIONAL([COND_arm64], [test x$target_cpu = xarm64 ]) +AM_CONDITIONAL([COND_arm64_efi], [test x$target_cpu = xarm64 -a x$platform = xefi]) +AM_CONDITIONAL([COND_riscv32], [test x$target_cpu = xriscv32 ]) +AM_CONDITIONAL([COND_riscv64], [test x$target_cpu = xriscv64 ]) +AM_CONDITIONAL([COND_riscv32_efi], [test x$target_cpu = xriscv32 -a x$platform = xefi]) +AM_CONDITIONAL([COND_riscv64_efi], [test x$target_cpu = xriscv64 -a x$platform = xefi]) + +AM_CONDITIONAL([COND_HOST_HURD], [test x$host_kernel = xhurd]) +AM_CONDITIONAL([COND_HOST_LINUX], [test x$host_kernel = xlinux]) +AM_CONDITIONAL([COND_HOST_NETBSD], [test x$host_kernel = xnetbsd]) +AM_CONDITIONAL([COND_HOST_WINDOWS], [test x$host_kernel = xwindows]) +AM_CONDITIONAL([COND_HOST_KFREEBSD], [test x$host_kernel = xkfreebsd]) +AM_CONDITIONAL([COND_HOST_XNU], [test x$host_kernel = xxnu]) +AM_CONDITIONAL([COND_HOST_ILLUMOS], [test x$host_kernel = xillumos]) + +AM_CONDITIONAL([COND_MAN_PAGES], [test x$cross_compiling = xno -a x$HELP2MAN != x]) +AM_CONDITIONAL([COND_GRUB_EMU_SDL], [test x$enable_grub_emu_sdl = xyes]) +AM_CONDITIONAL([COND_GRUB_EMU_PCI], [test x$enable_grub_emu_pci = xyes]) +AM_CONDITIONAL([COND_GRUB_MKFONT], [test x$enable_grub_mkfont = xyes]) +AM_CONDITIONAL([COND_GRUB_MOUNT], [test x$enable_grub_mount = xyes]) +AM_CONDITIONAL([COND_HAVE_FONT_SOURCE], [test x$FONT_SOURCE != x]) +if test x$FONT_SOURCE != x ; then + HAVE_FONT_SOURCE=1 +else + HAVE_FONT_SOURCE=0 +fi +AC_SUBST(HAVE_FONT_SOURCE) +AM_CONDITIONAL([COND_APPLE_LINKER], [test x$TARGET_APPLE_LINKER = x1]) +AM_CONDITIONAL([COND_ENABLE_EFIEMU], [test x$enable_efiemu = xyes]) +AM_CONDITIONAL([COND_ENABLE_CACHE_STATS], [test x$DISK_CACHE_STATS = x1]) +AM_CONDITIONAL([COND_ENABLE_BOOT_TIME_STATS], [test x$BOOT_TIME_STATS = x1]) + +AM_CONDITIONAL([COND_HAVE_CXX], [test x$HAVE_CXX = xyes]) + +AM_CONDITIONAL([COND_HAVE_ASM_USCORE], [test x$HAVE_ASM_USCORE = x1]) +AM_CONDITIONAL([COND_STARFIELD], [test "x$starfield_excuse" = x]) +AM_CONDITIONAL([COND_HAVE_EXEC], [test "x$have_exec" = xy]) + +test "x$prefix" = xNONE && prefix="$ac_default_prefix" +test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" +datarootdir="$(eval echo "$datarootdir")" +grub_libdir="$(eval echo "$libdir")" +grub_localedir="$(eval echo "$localedir")" +grub_datadir="$(eval echo "$datadir")" +grub_sysconfdir="$(eval echo "$sysconfdir")" +AC_DEFINE_UNQUOTED(LOCALEDIR, "$grub_localedir", [Locale dir]) +AC_DEFINE_UNQUOTED(GRUB_LIBDIR, "$grub_libdir", [Library dir]) +AC_DEFINE_UNQUOTED(GRUB_DATADIR, "$grub_datadir", [Data dir]) +AC_DEFINE_UNQUOTED(GRUB_SYSCONFDIR, "$grub_sysconfdir", [Configuration dir]) + + +# Output files. +if test "$platform" != none; then + cpudir="${target_cpu}" + if test x${cpudir} = xmips64el; then + cpudir=mips64; + elif test x${cpudir} = xmipsel; then + cpudir=mips; + fi + grub_CHECK_LINK_DIR + if test x"$link_dir" = xyes ; then + AC_CONFIG_LINKS([include/grub/cpu:include/grub/$cpudir]) + if test "$platform" != emu ; then + AC_CONFIG_LINKS([include/grub/machine:include/grub/$cpudir/$platform]) + fi + else + mkdir -p include/grub 2>/dev/null + rm -rf include/grub/cpu + cp -rp $srcdir/include/grub/$cpudir include/grub/cpu 2>/dev/null + if test "$platform" != emu ; then + rm -rf include/grub/machine + cp -rp $srcdir/include/grub/$cpudir/$platform include/grub/machine 2>/dev/null + fi + fi +else + # Just enough to stop the compiler failing with -I$(srcdir)/include. + mkdir -p include 2>/dev/null + rm -rf include/grub/cpu include/grub/machine +fi + +AC_CONFIG_FILES([Makefile]) +AC_CONFIG_FILES([grub-core/Makefile]) +AC_CONFIG_FILES([grub-core/lib/gnulib/Makefile]) +AC_CONFIG_FILES([po/Makefile.in]) +AC_CONFIG_FILES([docs/Makefile]) +AC_CONFIG_FILES([util/bash-completion.d/Makefile]) +AC_CONFIG_FILES([stamp-h], [echo timestamp > stamp-h]) +AC_CONFIG_FILES([config.h]) + +AC_OUTPUT +[ +echo "*******************************************************" +echo GRUB2 will be compiled with following components: +echo Platform: "$target_cpu"-"$platform" +if [ x"$platform" = xemu ]; then +if [ x"$grub_emu_sdl_excuse" = x ]; then +echo SDL support for grub-emu: Yes +else +echo SDL support for grub-emu: No "($grub_emu_sdl_excuse)" +fi +if [ x"$grub_emu_pci_excuse" = x ]; then +echo PCI support for grub-emu: Yes +else +echo PCI support for grub-emu: No "($grub_emu_pci_excuse)" +fi +fi +if test x"$device_mapper_excuse" = x ; then +echo With devmapper support: Yes +else +echo With devmapper support: No "($device_mapper_excuse)" +fi +if [ x"$enable_mm_debug" = xyes ]; then +echo With memory debugging: Yes +else +echo With memory debugging: No +fi +if [ x"$enable_cache_stats" = xyes ]; then +echo With disk cache statistics: Yes +else +echo With disk cache statistics: No +fi + +if [ x"$enable_boot_time" = xyes ]; then +echo With boot time statistics: Yes +else +echo With boot time statistics: No +fi + +if [ x"$efiemu_excuse" = x ]; then +echo efiemu runtime: Yes +else +echo efiemu runtime: No "($efiemu_excuse)" +fi +if [ x"$grub_mkfont_excuse" = x ]; then +echo grub-mkfont: Yes +else +echo grub-mkfont: No "($grub_mkfont_excuse)" +fi +if [ x"$grub_mount_excuse" = x ]; then +echo grub-mount: Yes +else +echo grub-mount: No "($grub_mount_excuse)" +fi +if [ x"$starfield_excuse" = x ]; then +echo starfield theme: Yes +echo With DejaVuSans font from $DJVU_FONT_SOURCE +else +echo starfield theme: No "($starfield_excuse)" +fi +if [ x"$libzfs_excuse" = x ]; then +echo With libzfs support: Yes +else +echo With libzfs support: No "($libzfs_excuse)" +fi +if [ x"$grub_build_mkfont_excuse" = x ]; then + echo Build-time grub-mkfont: Yes + if test "x$FONT_SOURCE" = x ; then + echo "Without unifont" + else + echo "With unifont from $FONT_SOURCE" + fi +else + echo Build-time grub-mkfont: No "($grub_build_mkfont_excuse)" + echo "Without unifont (no build-time grub-mkfont)" +fi +if test x"$liblzma_excuse" != x ; then +echo "Without liblzma (no support for XZ-compressed mips images) ($liblzma_excuse)" +else +echo "With liblzma from $LIBLZMA (support for XZ-compressed mips images)" +fi +echo "*******************************************************" +] diff --git a/GRUB2/MOD_SRC/grub-2.04/gentpl.py b/GRUB2/MOD_SRC/grub-2.04/gentpl.py new file mode 100644 index 0000000..fcdb8ad --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/gentpl.py @@ -0,0 +1,909 @@ +#! /usr/bin/python +# GRUB -- GRand Unified Bootloader +# Copyright (C) 2010,2011,2012,2013 Free Software Foundation, Inc. +# +# GRUB is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB 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 GRUB. If not, see . + +from __future__ import print_function + +__metaclass__ = type + +from optparse import OptionParser +import re + +# +# This is the python script used to generate Makefile.*.am +# + +GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot", + "i386_multiboot", "i386_ieee1275", "x86_64_efi", + "i386_xen", "x86_64_xen", "i386_xen_pvh", + "mips_loongson", "mips64_efi", "sparc64_ieee1275", + "powerpc_ieee1275", "mips_arc", "ia64_efi", + "mips_qemu_mips", "arm_uboot", "arm_efi", "arm64_efi", + "arm_coreboot", "riscv32_efi", "riscv64_efi" ] + +GROUPS = {} + +GROUPS["common"] = GRUB_PLATFORMS[:] + +# Groups based on CPU +GROUPS["i386"] = [ "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot", "i386_multiboot", "i386_ieee1275" ] +GROUPS["x86_64"] = [ "x86_64_efi" ] +GROUPS["x86"] = GROUPS["i386"] + GROUPS["x86_64"] +GROUPS["mips"] = [ "mips_loongson", "mips_qemu_mips", "mips_arc" ] +GROUPS["mips64"] = [ "mips64_efi" ] +GROUPS["sparc64"] = [ "sparc64_ieee1275" ] +GROUPS["powerpc"] = [ "powerpc_ieee1275" ] +GROUPS["arm"] = [ "arm_uboot", "arm_efi", "arm_coreboot" ] +GROUPS["arm64"] = [ "arm64_efi" ] +GROUPS["riscv32"] = [ "riscv32_efi" ] +GROUPS["riscv64"] = [ "riscv64_efi" ] + +# Groups based on firmware +GROUPS["efi"] = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi", "arm64_efi", "mips64_efi", + "riscv32_efi", "riscv64_efi" ] +GROUPS["ieee1275"] = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" ] +GROUPS["uboot"] = [ "arm_uboot" ] +GROUPS["xen"] = [ "i386_xen", "x86_64_xen" ] +GROUPS["coreboot"] = [ "i386_coreboot", "arm_coreboot" ] + +# emu is a special case so many core functionality isn't needed on this platform +GROUPS["noemu"] = GRUB_PLATFORMS[:]; GROUPS["noemu"].remove("emu") + +# Groups based on hardware features +GROUPS["cmos"] = GROUPS["x86"][:] + ["mips_loongson", "mips_qemu_mips", + "sparc64_ieee1275", "powerpc_ieee1275"] +GROUPS["cmos"].remove("i386_efi"); GROUPS["cmos"].remove("x86_64_efi"); +GROUPS["pci"] = GROUPS["x86"] + ["mips_loongson"] +GROUPS["usb"] = GROUPS["pci"] + ["arm_coreboot"] + +# If gfxterm is main output console integrate it into kernel +GROUPS["videoinkernel"] = ["mips_loongson", "i386_coreboot", "arm_coreboot" ] +GROUPS["videomodules"] = GRUB_PLATFORMS[:]; +for i in GROUPS["videoinkernel"]: GROUPS["videomodules"].remove(i) + +# Similar for terminfo +GROUPS["terminfoinkernel"] = [ "emu", "mips_loongson", "mips_arc", "mips_qemu_mips", "i386_xen_pvh" ] + GROUPS["xen"] + GROUPS["ieee1275"] + GROUPS["uboot"]; +GROUPS["terminfomodule"] = GRUB_PLATFORMS[:]; +for i in GROUPS["terminfoinkernel"]: GROUPS["terminfomodule"].remove(i) + +# Flattened Device Trees (FDT) +GROUPS["fdt"] = [ "arm64_efi", "arm_uboot", "arm_efi", "riscv32_efi", "riscv64_efi" ] + +# Needs software helpers for division +# Must match GRUB_DIVISION_IN_SOFTWARE in misc.h +GROUPS["softdiv"] = GROUPS["arm"] + ["ia64_efi"] + GROUPS["riscv32"] +GROUPS["no_softdiv"] = GRUB_PLATFORMS[:] +for i in GROUPS["softdiv"]: GROUPS["no_softdiv"].remove(i) + +# Miscellaneous groups scheduled to disappear in future +GROUPS["i386_coreboot_multiboot_qemu"] = ["i386_coreboot", "i386_multiboot", "i386_qemu"] +GROUPS["nopc"] = GRUB_PLATFORMS[:]; GROUPS["nopc"].remove("i386_pc") + +# +# Create platform => groups reverse map, where groups covering that +# platform are ordered by their sizes +# +RMAP = {} +for platform in GRUB_PLATFORMS: + # initialize with platform itself as a group + RMAP[platform] = [ platform ] + + for k in GROUPS.keys(): + v = GROUPS[k] + # skip groups that don't cover this platform + if platform not in v: continue + + bigger = [] + smaller = [] + # partition currently known groups based on their size + for group in RMAP[platform]: + if group in GRUB_PLATFORMS: smaller.append(group) + elif len(GROUPS[group]) < len(v): smaller.append(group) + else: bigger.append(group) + # insert in the middle + RMAP[platform] = smaller + [ k ] + bigger + +# +# Input +# + +# We support a subset of the AutoGen definitions file syntax. Specifically, +# compound names are disallowed; some preprocessing directives are +# disallowed (though #if/#endif are allowed; note that, like AutoGen, #if +# skips everything to the next #endif regardless of the value of the +# conditional); and shell-generated strings, Scheme-generated strings, and +# here strings are disallowed. + +class AutogenToken: + (autogen, definitions, eof, var_name, other_name, string, number, + semicolon, equals, comma, lbrace, rbrace, lbracket, rbracket) = range(14) + +class AutogenState: + (init, need_def, need_tpl, need_semi, need_name, have_name, need_value, + need_idx, need_rbracket, indx_name, have_value, done) = range(12) + +class AutogenParseError(Exception): + def __init__(self, message, path, line): + super(AutogenParseError, self).__init__(message) + self.path = path + self.line = line + + def __str__(self): + return ( + super(AutogenParseError, self).__str__() + + " at file %s line %d" % (self.path, self.line)) + +class AutogenDefinition(list): + def __getitem__(self, key): + try: + return super(AutogenDefinition, self).__getitem__(key) + except TypeError: + for name, value in self: + if name == key: + return value + + def __contains__(self, key): + for name, value in self: + if name == key: + return True + return False + + def get(self, key, default): + for name, value in self: + if name == key: + return value + else: + return default + + def find_all(self, key): + for name, value in self: + if name == key: + yield value + +class AutogenParser: + def __init__(self): + self.definitions = AutogenDefinition() + self.def_stack = [("", self.definitions)] + self.curdef = None + self.new_name = None + self.cur_path = None + self.cur_line = 0 + + @staticmethod + def is_unquotable_char(c): + return (ord(c) in range(ord("!"), ord("~") + 1) and + c not in "#,;<=>[\\]`{}?*'\"()") + + @staticmethod + def is_value_name_char(c): + return c in ":^-_" or c.isalnum() + + def error(self, message): + raise AutogenParseError(message, self.cur_file, self.cur_line) + + def read_tokens(self, f): + data = f.read() + end = len(data) + offset = 0 + while offset < end: + while offset < end and data[offset].isspace(): + if data[offset] == "\n": + self.cur_line += 1 + offset += 1 + if offset >= end: + break + c = data[offset] + if c == "#": + offset += 1 + try: + end_directive = data.index("\n", offset) + directive = data[offset:end_directive] + offset = end_directive + except ValueError: + directive = data[offset:] + offset = end + name, value = directive.split(None, 1) + if name == "if": + try: + end_if = data.index("\n#endif", offset) + new_offset = end_if + len("\n#endif") + self.cur_line += data[offset:new_offset].count("\n") + offset = new_offset + except ValueError: + self.error("#if without matching #endif") + else: + self.error("Unhandled directive '#%s'" % name) + elif c == "{": + yield AutogenToken.lbrace, c + offset += 1 + elif c == "=": + yield AutogenToken.equals, c + offset += 1 + elif c == "}": + yield AutogenToken.rbrace, c + offset += 1 + elif c == "[": + yield AutogenToken.lbracket, c + offset += 1 + elif c == "]": + yield AutogenToken.rbracket, c + offset += 1 + elif c == ";": + yield AutogenToken.semicolon, c + offset += 1 + elif c == ",": + yield AutogenToken.comma, c + offset += 1 + elif c in ("'", '"'): + s = [] + while True: + offset += 1 + if offset >= end: + self.error("EOF in quoted string") + if data[offset] == "\n": + self.cur_line += 1 + if data[offset] == "\\": + offset += 1 + if offset >= end: + self.error("EOF in quoted string") + if data[offset] == "\n": + self.cur_line += 1 + # Proper escaping unimplemented; this can be filled + # out if needed. + s.append("\\") + s.append(data[offset]) + elif data[offset] == c: + offset += 1 + break + else: + s.append(data[offset]) + yield AutogenToken.string, "".join(s) + elif c == "/": + offset += 1 + if data[offset] == "*": + offset += 1 + try: + end_comment = data.index("*/", offset) + new_offset = end_comment + len("*/") + self.cur_line += data[offset:new_offset].count("\n") + offset = new_offset + except ValueError: + self.error("/* without matching */") + elif data[offset] == "/": + try: + offset = data.index("\n", offset) + except ValueError: + pass + elif (c.isdigit() or + (c == "-" and offset < end - 1 and + data[offset + 1].isdigit())): + end_number = offset + 1 + while end_number < end and data[end_number].isdigit(): + end_number += 1 + yield AutogenToken.number, data[offset:end_number] + offset = end_number + elif self.is_unquotable_char(c): + end_name = offset + while (end_name < end and + self.is_value_name_char(data[end_name])): + end_name += 1 + if end_name < end and self.is_unquotable_char(data[end_name]): + while (end_name < end and + self.is_unquotable_char(data[end_name])): + end_name += 1 + yield AutogenToken.other_name, data[offset:end_name] + offset = end_name + else: + s = data[offset:end_name] + if s.lower() == "autogen": + yield AutogenToken.autogen, s + elif s.lower() == "definitions": + yield AutogenToken.definitions, s + else: + yield AutogenToken.var_name, s + offset = end_name + else: + self.error("Invalid input character '%s'" % c) + yield AutogenToken.eof, None + + def do_need_name_end(self, token): + if len(self.def_stack) > 1: + self.error("Definition blocks were left open") + + def do_need_name_var_name(self, token): + self.new_name = token + + def do_end_block(self, token): + if len(self.def_stack) <= 1: + self.error("Too many close braces") + new_name, parent_def = self.def_stack.pop() + parent_def.append((new_name, self.curdef)) + self.curdef = parent_def + + def do_empty_val(self, token): + self.curdef.append((self.new_name, "")) + + def do_str_value(self, token): + self.curdef.append((self.new_name, token)) + + def do_start_block(self, token): + self.def_stack.append((self.new_name, self.curdef)) + self.curdef = AutogenDefinition() + + def do_indexed_name(self, token): + self.new_name = token + + def read_definitions_file(self, f): + self.curdef = self.definitions + self.cur_line = 0 + state = AutogenState.init + + # The following transition table was reduced from the Autogen + # documentation: + # info -f autogen -n 'Full Syntax' + transitions = { + AutogenState.init: { + AutogenToken.autogen: (AutogenState.need_def, None), + }, + AutogenState.need_def: { + AutogenToken.definitions: (AutogenState.need_tpl, None), + }, + AutogenState.need_tpl: { + AutogenToken.var_name: (AutogenState.need_semi, None), + AutogenToken.other_name: (AutogenState.need_semi, None), + AutogenToken.string: (AutogenState.need_semi, None), + }, + AutogenState.need_semi: { + AutogenToken.semicolon: (AutogenState.need_name, None), + }, + AutogenState.need_name: { + AutogenToken.autogen: (AutogenState.need_def, None), + AutogenToken.eof: (AutogenState.done, self.do_need_name_end), + AutogenToken.var_name: ( + AutogenState.have_name, self.do_need_name_var_name), + AutogenToken.rbrace: ( + AutogenState.have_value, self.do_end_block), + }, + AutogenState.have_name: { + AutogenToken.semicolon: ( + AutogenState.need_name, self.do_empty_val), + AutogenToken.equals: (AutogenState.need_value, None), + AutogenToken.lbracket: (AutogenState.need_idx, None), + }, + AutogenState.need_value: { + AutogenToken.var_name: ( + AutogenState.have_value, self.do_str_value), + AutogenToken.other_name: ( + AutogenState.have_value, self.do_str_value), + AutogenToken.string: ( + AutogenState.have_value, self.do_str_value), + AutogenToken.number: ( + AutogenState.have_value, self.do_str_value), + AutogenToken.lbrace: ( + AutogenState.need_name, self.do_start_block), + }, + AutogenState.need_idx: { + AutogenToken.var_name: ( + AutogenState.need_rbracket, self.do_indexed_name), + AutogenToken.number: ( + AutogenState.need_rbracket, self.do_indexed_name), + }, + AutogenState.need_rbracket: { + AutogenToken.rbracket: (AutogenState.indx_name, None), + }, + AutogenState.indx_name: { + AutogenToken.semicolon: ( + AutogenState.need_name, self.do_empty_val), + AutogenToken.equals: (AutogenState.need_value, None), + }, + AutogenState.have_value: { + AutogenToken.semicolon: (AutogenState.need_name, None), + AutogenToken.comma: (AutogenState.need_value, None), + }, + } + + for code, token in self.read_tokens(f): + if code in transitions[state]: + state, handler = transitions[state][code] + if handler is not None: + handler(token) + else: + self.error( + "Parse error in state %s: unexpected token '%s'" % ( + state, token)) + if state == AutogenState.done: + break + + def read_definitions(self, path): + self.cur_file = path + with open(path) as f: + self.read_definitions_file(f) + +defparser = AutogenParser() + +# +# Output +# + +outputs = {} + +def output(s, section=''): + if s == "": + return + outputs.setdefault(section, []) + outputs[section].append(s) + +def write_output(section=''): + for s in outputs.get(section, []): + print(s, end='') + +# +# Global variables +# + +def gvar_add(var, value): + output(var + " += " + value + "\n") + +# +# Per PROGRAM/SCRIPT variables +# + +seen_vars = set() + +def vars_init(defn, *var_list): + name = defn['name'] + + if name not in seen_target and name not in seen_vars: + for var in var_list: + output(var + " = \n", section='decl') + seen_vars.add(name) + +def var_set(var, value): + output(var + " = " + value + "\n") + +def var_add(var, value): + output(var + " += " + value + "\n") + +# +# Variable names and rules +# + +canonical_name_re = re.compile(r'[^0-9A-Za-z@_]') +canonical_name_suffix = "" + +def set_canonical_name_suffix(suffix): + global canonical_name_suffix + canonical_name_suffix = suffix + +def cname(defn): + return canonical_name_re.sub('_', defn['name'] + canonical_name_suffix) + +def rule(target, source, cmd): + if cmd[0] == "\n": + output("\n" + target + ": " + source + cmd.replace("\n", "\n\t") + "\n") + else: + output("\n" + target + ": " + source + "\n\t" + cmd.replace("\n", "\n\t") + "\n") + +# +# Handle keys with platform names as values, for example: +# +# kernel = { +# nostrip = emu; +# ... +# } +# +def platform_tagged(defn, platform, tag): + for value in defn.find_all(tag): + for group in RMAP[platform]: + if value == group: + return True + return False + +def if_platform_tagged(defn, platform, tag, snippet_if, snippet_else=None): + if platform_tagged(defn, platform, tag): + return snippet_if + elif snippet_else is not None: + return snippet_else + +# +# Handle tagged values +# +# module = { +# extra_dist = ... +# extra_dist = ... +# ... +# }; +# +def foreach_value(defn, tag, closure): + r = [] + for value in defn.find_all(tag): + r.append(closure(value)) + return ''.join(r) + +# +# Handle best matched values for a platform, for example: +# +# module = { +# cflags = '-Wall'; +# emu_cflags = '-Wall -DGRUB_EMU=1'; +# ... +# } +# +def foreach_platform_specific_value(defn, platform, suffix, nonetag, closure): + r = [] + for group in RMAP[platform]: + values = list(defn.find_all(group + suffix)) + if values: + for value in values: + r.append(closure(value)) + break + else: + for value in defn.find_all(nonetag): + r.append(closure(value)) + return ''.join(r) + +# +# Handle values from sum of all groups for a platform, for example: +# +# module = { +# common = kern/misc.c; +# emu = kern/emu/misc.c; +# ... +# } +# +def foreach_platform_value(defn, platform, suffix, closure): + r = [] + for group in RMAP[platform]: + for value in defn.find_all(group + suffix): + r.append(closure(value)) + return ''.join(r) + +def platform_conditional(platform, closure): + output("\nif COND_" + platform + "\n") + closure(platform) + output("endif\n") + +# +# Handle guarding with platform-specific "enable" keys, for example: +# +# module = { +# name = pci; +# noemu = bus/pci.c; +# emu = bus/emu/pci.c; +# emu = commands/lspci.c; +# +# enable = emu; +# enable = i386_pc; +# enable = x86_efi; +# enable = i386_ieee1275; +# enable = i386_coreboot; +# }; +# +def foreach_enabled_platform(defn, closure): + if 'enable' in defn: + for platform in GRUB_PLATFORMS: + if platform_tagged(defn, platform, "enable"): + platform_conditional(platform, closure) + else: + for platform in GRUB_PLATFORMS: + platform_conditional(platform, closure) + +# +# Handle guarding with platform-specific automake conditionals, for example: +# +# module = { +# name = usb; +# common = bus/usb/usb.c; +# noemu = bus/usb/usbtrans.c; +# noemu = bus/usb/usbhub.c; +# enable = emu; +# enable = i386; +# enable = mips_loongson; +# emu_condition = COND_GRUB_EMU_SDL; +# }; +# +def under_platform_specific_conditionals(defn, platform, closure): + output(foreach_platform_specific_value(defn, platform, "_condition", "condition", lambda cond: "if " + cond + "\n")) + closure(defn, platform) + output(foreach_platform_specific_value(defn, platform, "_condition", "condition", lambda cond: "endif " + cond + "\n")) + +def platform_specific_values(defn, platform, suffix, nonetag): + return foreach_platform_specific_value(defn, platform, suffix, nonetag, + lambda value: value + " ") + +def platform_values(defn, platform, suffix): + return foreach_platform_value(defn, platform, suffix, lambda value: value + " ") + +def extra_dist(defn): + return foreach_value(defn, "extra_dist", lambda value: value + " ") + +def platform_sources(defn, p): return platform_values(defn, p, "") +def platform_nodist_sources(defn, p): return platform_values(defn, p, "_nodist") + +def platform_startup(defn, p): return platform_specific_values(defn, p, "_startup", "startup") +def platform_ldadd(defn, p): return platform_specific_values(defn, p, "_ldadd", "ldadd") +def platform_dependencies(defn, p): return platform_specific_values(defn, p, "_dependencies", "dependencies") +def platform_cflags(defn, p): return platform_specific_values(defn, p, "_cflags", "cflags") +def platform_ldflags(defn, p): return platform_specific_values(defn, p, "_ldflags", "ldflags") +def platform_cppflags(defn, p): return platform_specific_values(defn, p, "_cppflags", "cppflags") +def platform_ccasflags(defn, p): return platform_specific_values(defn, p, "_ccasflags", "ccasflags") +def platform_stripflags(defn, p): return platform_specific_values(defn, p, "_stripflags", "stripflags") +def platform_objcopyflags(defn, p): return platform_specific_values(defn, p, "_objcopyflags", "objcopyflags") + +# +# Emit snippet only the first time through for the current name. +# +seen_target = set() + +def first_time(defn, snippet): + if defn['name'] not in seen_target: + return snippet + return '' + +def is_platform_independent(defn): + if 'enable' in defn: + return False + for suffix in [ "", "_nodist" ]: + template = platform_values(defn, GRUB_PLATFORMS[0], suffix) + for platform in GRUB_PLATFORMS[1:]: + if template != platform_values(defn, platform, suffix): + return False + + for suffix in [ "startup", "ldadd", "dependencies", "cflags", "ldflags", "cppflags", "ccasflags", "stripflags", "objcopyflags", "condition" ]: + template = platform_specific_values(defn, GRUB_PLATFORMS[0], "_" + suffix, suffix) + for platform in GRUB_PLATFORMS[1:]: + if template != platform_specific_values(defn, platform, "_" + suffix, suffix): + return False + for tag in [ "nostrip" ]: + template = platform_tagged(defn, GRUB_PLATFORMS[0], tag) + for platform in GRUB_PLATFORMS[1:]: + if template != platform_tagged(defn, platform, tag): + return False + + return True + +def module(defn, platform): + name = defn['name'] + set_canonical_name_suffix(".module") + + gvar_add("platform_PROGRAMS", name + ".module") + gvar_add("MODULE_FILES", name + ".module$(EXEEXT)") + + var_set(cname(defn) + "_SOURCES", platform_sources(defn, platform) + " ## platform sources") + var_set("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform) + " ## platform nodist sources") + var_set(cname(defn) + "_LDADD", platform_ldadd(defn, platform)) + var_set(cname(defn) + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_MODULE) " + platform_cflags(defn, platform)) + var_set(cname(defn) + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_MODULE) " + platform_ldflags(defn, platform)) + var_set(cname(defn) + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_MODULE) " + platform_cppflags(defn, platform)) + var_set(cname(defn) + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_MODULE) " + platform_ccasflags(defn, platform)) + var_set(cname(defn) + "_DEPENDENCIES", "$(TARGET_OBJ2ELF) " + platform_dependencies(defn, platform)) + + gvar_add("dist_noinst_DATA", extra_dist(defn)) + gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)") + gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)") + + gvar_add("MOD_FILES", name + ".mod") + gvar_add("MARKER_FILES", name + ".marker") + gvar_add("CLEANFILES", name + ".marker") + output(""" +""" + name + """.marker: $(""" + cname(defn) + """_SOURCES) $(nodist_""" + cname(defn) + """_SOURCES) + $(TARGET_CPP) -DGRUB_LST_GENERATOR $(CPPFLAGS_MARKER) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(""" + cname(defn) + """_CPPFLAGS) $(CPPFLAGS) $^ > $@.new || (rm -f $@; exit 1) + grep 'MARKER' $@.new > $@; rm -f $@.new +""") + +def kernel(defn, platform): + name = defn['name'] + set_canonical_name_suffix(".exec") + gvar_add("platform_PROGRAMS", name + ".exec") + var_set(cname(defn) + "_SOURCES", platform_startup(defn, platform)) + var_add(cname(defn) + "_SOURCES", platform_sources(defn, platform)) + var_set("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform) + " ## platform nodist sources") + var_set(cname(defn) + "_LDADD", platform_ldadd(defn, platform)) + var_set(cname(defn) + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_KERNEL) " + platform_cflags(defn, platform)) + var_set(cname(defn) + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_KERNEL) " + platform_ldflags(defn, platform)) + var_set(cname(defn) + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_KERNEL) " + platform_cppflags(defn, platform)) + var_set(cname(defn) + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_KERNEL) " + platform_ccasflags(defn, platform)) + var_set(cname(defn) + "_STRIPFLAGS", "$(AM_STRIPFLAGS) $(STRIPFLAGS_KERNEL) " + platform_stripflags(defn, platform)) + var_set(cname(defn) + "_DEPENDENCIES", "$(TARGET_OBJ2ELF)") + + gvar_add("dist_noinst_DATA", extra_dist(defn)) + gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)") + gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)") + + gvar_add("platform_DATA", name + ".img") + gvar_add("CLEANFILES", name + ".img") + rule(name + ".img", name + ".exec$(EXEEXT)", + if_platform_tagged(defn, platform, "nostrip", +"""if test x$(TARGET_APPLE_LINKER) = x1; then \ + $(TARGET_OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -ed2022 -wd1106 -nu -nd $< $@; \ + elif test ! -z '$(TARGET_OBJ2ELF)'; then \ + $(TARGET_OBJ2ELF) $< $@ || (rm -f $@; exit 1); \ + else cp $< $@; fi""", +"""if test x$(TARGET_APPLE_LINKER) = x1; then \ + $(TARGET_STRIP) -S -x $(""" + cname(defn) + """) -o $@.bin $<; \ + $(TARGET_OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -ed2022 -ed2016 -wd1106 -nu -nd $@.bin $@; \ + rm -f $@.bin; \ + elif test ! -z '$(TARGET_OBJ2ELF)'; then \ + """ + "$(TARGET_STRIP) $(" + cname(defn) + "_STRIPFLAGS) -o $@.bin $< && \ + $(TARGET_OBJ2ELF) $@.bin $@ || (rm -f $@; rm -f $@.bin; exit 1); \ + rm -f $@.bin; \ +else """ + "$(TARGET_STRIP) $(" + cname(defn) + "_STRIPFLAGS) -o $@ $<; \ +fi""")) + +def image(defn, platform): + name = defn['name'] + set_canonical_name_suffix(".image") + gvar_add("platform_PROGRAMS", name + ".image") + var_set(cname(defn) + "_SOURCES", platform_sources(defn, platform)) + var_set("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform) + "## platform nodist sources") + var_set(cname(defn) + "_LDADD", platform_ldadd(defn, platform)) + var_set(cname(defn) + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_IMAGE) " + platform_cflags(defn, platform)) + var_set(cname(defn) + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_IMAGE) " + platform_ldflags(defn, platform)) + var_set(cname(defn) + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_IMAGE) " + platform_cppflags(defn, platform)) + var_set(cname(defn) + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_IMAGE) " + platform_ccasflags(defn, platform)) + var_set(cname(defn) + "_OBJCOPYFLAGS", "$(OBJCOPYFLAGS_IMAGE) " + platform_objcopyflags(defn, platform)) + # var_set(cname(defn) + "_DEPENDENCIES", platform_dependencies(defn, platform) + " " + platform_ldadd(defn, platform)) + + gvar_add("dist_noinst_DATA", extra_dist(defn)) + gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)") + gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)") + + gvar_add("platform_DATA", name + ".img") + gvar_add("CLEANFILES", name + ".img") + rule(name + ".img", name + ".image$(EXEEXT)", """ +if test x$(TARGET_APPLE_LINKER) = x1; then \ + $(MACHO2IMG) $< $@; \ +else \ + $(TARGET_OBJCOPY) $(""" + cname(defn) + """_OBJCOPYFLAGS) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .MIPS.abiflags -R .reginfo -R .rel.dyn -R .note.gnu.gold-version -R .ARM.exidx $< $@; \ +fi +""") + +def library(defn, platform): + name = defn['name'] + set_canonical_name_suffix("") + + vars_init(defn, + cname(defn) + "_SOURCES", + "nodist_" + cname(defn) + "_SOURCES", + cname(defn) + "_CFLAGS", + cname(defn) + "_CPPFLAGS", + cname(defn) + "_CCASFLAGS") + # cname(defn) + "_DEPENDENCIES") + + if name not in seen_target: + gvar_add("noinst_LIBRARIES", name) + var_add(cname(defn) + "_SOURCES", platform_sources(defn, platform)) + var_add("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform)) + var_add(cname(defn) + "_CFLAGS", first_time(defn, "$(AM_CFLAGS) $(CFLAGS_LIBRARY) ") + platform_cflags(defn, platform)) + var_add(cname(defn) + "_CPPFLAGS", first_time(defn, "$(AM_CPPFLAGS) $(CPPFLAGS_LIBRARY) ") + platform_cppflags(defn, platform)) + var_add(cname(defn) + "_CCASFLAGS", first_time(defn, "$(AM_CCASFLAGS) $(CCASFLAGS_LIBRARY) ") + platform_ccasflags(defn, platform)) + # var_add(cname(defn) + "_DEPENDENCIES", platform_dependencies(defn, platform) + " " + platform_ldadd(defn, platform)) + + gvar_add("dist_noinst_DATA", extra_dist(defn)) + if name not in seen_target: + gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)") + gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)") + +def installdir(defn, default="bin"): + return defn.get('installdir', default) + +def manpage(defn, adddeps): + name = defn['name'] + mansection = defn['mansection'] + + output("if COND_MAN_PAGES\n") + gvar_add("man_MANS", name + "." + mansection) + rule(name + "." + mansection, name + " " + adddeps, """ +chmod a+x """ + name + """ +PATH=$(builddir):$$PATH pkgdatadir=$(builddir) $(HELP2MAN) --section=""" + mansection + """ -i $(top_srcdir)/docs/man/""" + name + """.h2m -o $@ """ + name + """ +""") + gvar_add("CLEANFILES", name + "." + mansection) + output("endif\n") + +def program(defn, platform, test=False): + name = defn['name'] + set_canonical_name_suffix("") + + if 'testcase' in defn: + gvar_add("check_PROGRAMS", name) + gvar_add("TESTS", name) + else: + var_add(installdir(defn) + "_PROGRAMS", name) + if 'mansection' in defn: + manpage(defn, "") + + var_set(cname(defn) + "_SOURCES", platform_sources(defn, platform)) + var_set("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform)) + var_set(cname(defn) + "_LDADD", platform_ldadd(defn, platform)) + var_set(cname(defn) + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_PROGRAM) " + platform_cflags(defn, platform)) + var_set(cname(defn) + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_PROGRAM) " + platform_ldflags(defn, platform)) + var_set(cname(defn) + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_PROGRAM) " + platform_cppflags(defn, platform)) + var_set(cname(defn) + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_PROGRAM) " + platform_ccasflags(defn, platform)) + # var_set(cname(defn) + "_DEPENDENCIES", platform_dependencies(defn, platform) + " " + platform_ldadd(defn, platform)) + + gvar_add("dist_noinst_DATA", extra_dist(defn)) + gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)") + gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)") + +def data(defn, platform): + var_add("dist_" + installdir(defn) + "_DATA", platform_sources(defn, platform)) + gvar_add("dist_noinst_DATA", extra_dist(defn)) + +def transform_data(defn, platform): + name = defn['name'] + + var_add(installdir(defn) + "_DATA", name) + + rule(name, "$(top_builddir)/config.status " + platform_sources(defn, platform) + platform_dependencies(defn, platform), """ +(for x in """ + platform_sources(defn, platform) + """; do cat $(srcdir)/"$$x"; done) | $(top_builddir)/config.status --file=$@:- +chmod a+x """ + name + """ +""") + + gvar_add("CLEANFILES", name) + gvar_add("EXTRA_DIST", extra_dist(defn)) + gvar_add("dist_noinst_DATA", platform_sources(defn, platform)) + +def script(defn, platform): + name = defn['name'] + + if 'testcase' in defn: + gvar_add("check_SCRIPTS", name) + gvar_add ("TESTS", name) + else: + var_add(installdir(defn) + "_SCRIPTS", name) + if 'mansection' in defn: + manpage(defn, "grub-mkconfig_lib") + + rule(name, "$(top_builddir)/config.status " + platform_sources(defn, platform) + platform_dependencies(defn, platform), """ +(for x in """ + platform_sources(defn, platform) + """; do cat $(srcdir)/"$$x"; done) | $(top_builddir)/config.status --file=$@:- +chmod a+x """ + name + """ +""") + + gvar_add("CLEANFILES", name) + gvar_add("EXTRA_DIST", extra_dist(defn)) + gvar_add("dist_noinst_DATA", platform_sources(defn, platform)) + +def rules(target, closure): + seen_target.clear() + seen_vars.clear() + + for defn in defparser.definitions.find_all(target): + if is_platform_independent(defn): + under_platform_specific_conditionals(defn, GRUB_PLATFORMS[0], closure) + else: + foreach_enabled_platform( + defn, + lambda p: under_platform_specific_conditionals(defn, p, closure)) + # Remember that we've seen this target. + seen_target.add(defn['name']) + +parser = OptionParser(usage="%prog DEFINITION-FILES") +_, args = parser.parse_args() + +for arg in args: + defparser.read_definitions(arg) + +rules("module", module) +rules("kernel", kernel) +rules("image", image) +rules("library", library) +rules("program", program) +rules("script", script) +rules("data", data) +rules("transform_data", transform_data) + +write_output(section='decl') +write_output() diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.am b/GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.am new file mode 100644 index 0000000..d84c2ef --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.am @@ -0,0 +1,507 @@ +AUTOMAKE_OPTIONS = subdir-objects -Wno-portability + +DEPDIR=.deps-core + +include $(top_srcdir)/conf/Makefile.common + +CC=$(TARGET_CC) +CPP=$(TARGET_CC) +CCAS=$(TARGET_CC) +RANLIB=$(TARGET_RANLIB) +STRIP=$(TARGET_STRIP) + +MACHO2IMG=$(top_builddir)/grub-macho2img + +AM_CFLAGS = $(TARGET_CFLAGS) +AM_LDFLAGS = $(TARGET_LDFLAGS) +AM_CPPFLAGS = $(TARGET_CPPFLAGS) $(CPPFLAGS_DEFAULT) +AM_CCASFLAGS = $(TARGET_CCASFLAGS) $(CCASFLAGS_DEFAULT) + +CFLAGS_PROGRAM += $(CFLAGS_PLATFORM) +LDFLAGS_PROGRAM += $(LDFLAGS_PLATFORM) +CPPFLAGS_PROGRAM += $(CPPFLAGS_PLATFORM) +CCASFLAGS_PROGRAM += $(CCASFLAGS_PLATFORM) + +CFLAGS_LIBRARY += $(CFLAGS_PLATFORM) -fno-builtin +CPPFLAGS_LIBRARY += $(CPPFLAGS_PLATFORM) +CCASFLAGS_LIBRARY += $(CCASFLAGS_PLATFORM) + +build-grub-pep2elf$(BUILD_EXEEXT): $(top_srcdir)/util/grub-pe2elf.c $(top_srcdir)/grub-core/kern/emu/misc.c $(top_srcdir)/util/misc.c + $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_BUILD=1 -DGRUB_TARGET_WORDSIZE=64 -DGRUB_UTIL=1 -DGRUB_BUILD_PROGRAM_NAME=\"build-grub-pep2elf\" $^ +CLEANFILES += build-grub-pep2elf$(BUILD_EXEEXT) + +build-grub-pe2elf$(BUILD_EXEEXT): $(top_srcdir)/util/grub-pe2elf.c $(top_srcdir)/grub-core/kern/emu/misc.c $(top_srcdir)/util/misc.c + $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_BUILD=1 -DGRUB_TARGET_WORDSIZE=32 -DGRUB_UTIL=1 -DGRUB_BUILD_PROGRAM_NAME=\"build-grub-pe2elf\" $^ +CLEANFILES += build-grub-pe2elf$(BUILD_EXEEXT) + +# gentrigtables +gentrigtables$(BUILD_EXEEXT): gentrigtables.c + $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) $< $(BUILD_LIBM) +CLEANFILES += gentrigtables$(BUILD_EXEEXT) + +build-grub-module-verifier$(BUILD_EXEEXT): $(top_srcdir)/util/grub-module-verifier.c $(top_srcdir)/util/grub-module-verifier32.c $(top_srcdir)/util/grub-module-verifier64.c $(top_srcdir)/grub-core/kern/emu/misc.c $(top_srcdir)/util/misc.c + $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_BUILD=1 -DGRUB_UTIL=1 -DGRUB_BUILD_PROGRAM_NAME=\"build-grub-module-verifier\" $^ +CLEANFILES += build-grub-module-verifier$(BUILD_EXEEXT) + +# trigtables.c +trigtables.c: gentrigtables$(BUILD_EXEEXT) gentrigtables.c $(top_srcdir)/configure.ac + ./gentrigtables$(BUILD_EXEEXT) > $@ +CLEANFILES += trigtables.c + +# XXX Use Automake's LEX & YACC support +grub_script.tab.h: script/parser.y + $(YACC) -d -p grub_script_yy -b grub_script $< +grub_script.tab.c: grub_script.tab.h +CLEANFILES += grub_script.tab.c grub_script.tab.h + +# For the lexer. +grub_script.yy.h: script/yylex.l + $(LEX) -o grub_script.yy.c --header-file=grub_script.yy.h $< +grub_script.yy.c: grub_script.yy.h + +rs_decoder.h: $(srcdir)/lib/reed_solomon.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Os -I$(top_builddir) -S -DSTANDALONE -o $@ $< -g0 -mregparm=3 -ffreestanding + +CLEANFILES += grub_script.yy.c grub_script.yy.h + +include $(srcdir)/Makefile.core.am + +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/cache.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/command.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/device.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/disk.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/dl.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/env.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/env_private.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/err.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/file.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fs.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i18n.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/kernel.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/list.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/misc.h +if COND_emu +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/compiler-rt-emu.h +else +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/compiler-rt.h +endif +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/parser.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/partition.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm_private.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/net.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/memory.h + +if COND_i386_pc +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/pxe.h +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/int.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h +endif + +if COND_i386_xen_pvh +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/int.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/xen.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/xen/hypercall.h +endif + +if COND_i386_efi +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pmtimer.h +endif + +if COND_i386_coreboot +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/coreboot/lbio.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video_fb.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/gfxterm.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/font.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bufio.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h +endif + +if COND_i386_multiboot +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h +endif + +if COND_i386_qemu +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h +endif + +if COND_i386_ieee1275 +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h +endif + +if COND_i386_xen +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/xen.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/xen/hypercall.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h +endif + +if COND_x86_64_xen +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/xen.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/x86_64/xen/hypercall.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h +endif + +if COND_x86_64_efi +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pmtimer.h +endif + +if COND_ia64_efi +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h +endif + +if COND_mips +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/cpu/kernel.h +endif + +if COND_mips_arc +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arc/arc.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h +endif + +if COND_mips_qemu_mips +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/keyboard_layouts.h +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/serial.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h +endif + +if COND_mips_loongson +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/keyboard_layouts.h +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/time.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video_fb.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/gfxterm.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/font.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bufio.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/cs5536.h +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/pci.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/serial.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h +endif + +if COND_mips_qemu_mips +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h +endif + +if COND_mips64_efi +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/loongson.h +endif + +if COND_powerpc_ieee1275 +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h +endif + +if COND_sparc64_ieee1275 +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sparc64/ieee1275/ieee1275.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h +endif + +if COND_arm_uboot +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/uboot/uboot.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/uboot/disk.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/system.h +endif + +if COND_arm_coreboot +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/keyboard_layouts.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/system.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video_fb.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/gfxterm.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/font.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bufio.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fdt.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/dma.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/coreboot/kernel.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fdtbus.h +endif + +if COND_arm_efi +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/system.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h +endif + +if COND_arm64_efi +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h +endif + +if COND_riscv32_efi +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h +endif + +if COND_riscv64_efi +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h +endif + +if COND_emu +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/datetime.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/misc.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/net.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/hostdisk.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/hostfile.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h +if COND_GRUB_EMU_SDL +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sdl.h +endif +if COND_GRUB_EMU_PCI +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libpciaccess.h +endif +endif + +symlist.h: $(top_builddir)/config.h $(KERNEL_HEADER_FILES) + @list='$^'; \ + for p in $$list; do \ + echo "#include <$$p>" >> $@ || (rm -f $@; exit 1); \ + done +CLEANFILES += symlist.h +BUILT_SOURCES += symlist.h + +symlist.c: symlist.h gensymlist.sh + $(TARGET_CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS_KERNEL) $(CPPFLAGS) -DGRUB_SYMBOL_GENERATOR=1 symlist.h > symlist.p || (rm -f symlist.p; exit 1) + cat symlist.p | $(SHELL) $(srcdir)/gensymlist.sh $(top_builddir)/config.h $(KERNEL_HEADER_FILES) >$@ || (rm -f $@; exit 1) + rm -f symlist.p +CLEANFILES += symlist.c +BUILT_SOURCES += symlist.c + +if COND_HAVE_ASM_USCORE +ASM_PREFIX=_ +else +ASM_PREFIX= +endif + +noinst_DATA += kernel_syms.lst + +kernel_syms.lst: $(KERNEL_HEADER_FILES) $(top_builddir)/config.h + $(TARGET_CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS_KERNEL) $(CPPFLAGS) $(CFLAGS) -DGRUB_SYMBOL_GENERATOR=1 $^ >kernel_syms.input + cat kernel_syms.input | grep -v '^#' | sed -n \ + -e '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/defined kernel '"$(ASM_PREFIX)"'\1/;p;}' \ + -e '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/defined kernel '"$(ASM_PREFIX)"'\1/;p;}' \ + | sort -u >$@ + rm -f kernel_syms.input +CLEANFILES += kernel_syms.lst + +if COND_emu +kern/emu/grub_emu-main.$(OBJEXT):grub_emu_init.h +grub_emu-grub_emu_init.$(OBJEXT):grub_emu_init.h +kern/emu/grub_emu_dyn-main.$(OBJEXT):grub_emu_init.h +grub_emu_dyn-grub_emu_init.$(OBJEXT):grub_emu_init.h + +grub_emu_init.h: genemuinitheader.sh $(MODULE_FILES) + rm -f $@; echo $(MODULE_FILES) | sh $(srcdir)/genemuinitheader.sh $(TARGET_NM) > $@ +CLEANFILES += grub_emu_init.h + +grub_emu_init.c: grub_emu_init.h genemuinit.sh $(MODULE_FILES) + rm -f $@; echo $(MODULE_FILES) | sh $(srcdir)/genemuinit.sh $(TARGET_NM) > $@ +CLEANFILES += grub_emu_init.c +endif + +# List files + +fs.lst: $(MARKER_FILES) + (for pp in $^; do \ + b=`basename $$pp .marker`; \ + if grep 'FS_LIST_MARKER' $$pp >/dev/null 2>&1; then \ + echo $$b; \ + fi; \ + done) | sort -u > $@ +platform_DATA += fs.lst +CLEANFILES += fs.lst + +command.lst: $(MARKER_FILES) + (for pp in $^; do \ + b=`basename $$pp .marker`; \ + sed -n \ + -e "/EXTCOMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \ + -e "/P1COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \ + -e "/COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" $$pp; \ + done) | sort -u > $@ +platform_DATA += command.lst +CLEANFILES += command.lst + +partmap.lst: $(MARKER_FILES) + (for pp in $^; do \ + b=`basename $$pp .marker`; \ + if grep 'PARTMAP_LIST_MARKER' $$pp >/dev/null 2>&1; then \ + echo $$b; \ + fi; \ + done) | sort -u > $@ +platform_DATA += partmap.lst +CLEANFILES += partmap.lst + +terminal.lst: $(MARKER_FILES) + (for pp in $^; do \ + b=`basename $$pp .marker`; \ + sed -n \ + -e "/INPUT_TERMINAL_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/i\1: $$b/;p;}" \ + -e "/OUTPUT_TERMINAL_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/o\1: $$b/;p;}" $$pp; \ + done) | sort -u > $@ +platform_DATA += terminal.lst +CLEANFILES += terminal.lst + +fdt.lst: $(MARKER_FILES) + (for pp in $^; do \ + b=`basename $$pp .marker`; \ + sed -n \ + -e "/FDT_DRIVER_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/i\1: $$b/;p;}" \ + -e "/FDT_DRIVER_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/o\1: $$b/;p;}" $$pp; \ + done) | sort -u > $@ +platform_DATA += fdt.lst +CLEANFILES += fdt.lst + +parttool.lst: $(MARKER_FILES) + (for pp in $^; do \ + b=`basename $$pp .marker`; \ + sed -n \ + -e "/PARTTOOL_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" $$pp; \ + done) | sort -u > $@ +platform_DATA += parttool.lst +CLEANFILES += parttool.lst + +video.lst: $(MARKER_FILES) + (for pp in $^; do \ + b=`basename $$pp .marker`; \ + if grep 'VIDEO_LIST_MARKER' $$pp >/dev/null 2>&1; then \ + echo $$b; \ + fi; \ + done) | sort -u > $@ +platform_DATA += video.lst +CLEANFILES += video.lst + +# but, crypto.lst is simply copied +crypto.lst: $(srcdir)/lib/libgcrypt-grub/cipher/crypto.lst + cp $^ $@ +platform_DATA += crypto.lst +CLEANFILES += crypto.lst + +syminfo.lst: gensyminfo.sh kernel_syms.lst $(MODULE_FILES) + cat kernel_syms.lst > $@.new + for m in $(MODULE_FILES); do \ + sh $< $$m >> $@.new || exit 1; \ + done + mv $@.new $@ + +# generate global module dependencies list +moddep.lst: syminfo.lst genmoddep.awk video.lst + cat $< | sort | $(AWK) -f $(srcdir)/genmoddep.awk > $@ || (rm -f $@; exit 1) +platform_DATA += moddep.lst +CLEANFILES += config.log syminfo.lst moddep.lst + +$(MOD_FILES): %.mod : genmod.sh moddep.lst %.module$(EXEEXT) build-grub-module-verifier$(BUILD_EXEEXT) + TARGET_OBJ2ELF=@TARGET_OBJ2ELF@ sh $^ $@ +platform_DATA += $(MOD_FILES) +platform_DATA += modinfo.sh +CLEANFILES += $(MOD_FILES) + +if COND_ENABLE_EFIEMU +efiemu32.o: efiemu/runtime/efiemu.c $(TARGET_OBJ2ELF) + -rm -f $@ + -rm -f $@.bin + $(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_DEFAULT) -m32 -Wall -Werror -nostdlib -static -O2 -c -o $@.bin $< + if test "x$(TARGET_APPLE_LINKER)" = x1; then \ + $(TARGET_OBJCONV) -felf32 -nu -nd $@.bin $@ || exit 1; \ + rm -f $@.bin ; \ + elif test ! -z "$(TARGET_OBJ2ELF)"; then \ + $(TARGET_OBJ2ELF) $@.bin || (rm -f $@.bin; exit 1); \ + mv $@.bin $@ ; \ + else \ + mv $@.bin $@ ; \ + fi + +# Link format -arch,x86_64 means Apple linker +efiemu64_c.o: efiemu/runtime/efiemu.c + $(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_DEFAULT) -m64 -nostdlib -Wall -Werror -O2 -mcmodel=large -mno-red-zone -c -o $@ $< + +efiemu64_s.o: efiemu/runtime/efiemu.S + $(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_DEFAULT) -m64 -Wall -Werror -nostdlib -O2 -mcmodel=large -mno-red-zone -c -o $@ $< + +efiemu64.o: efiemu64_c.o efiemu64_s.o $(TARGET_OBJ2ELEF) + -rm -f $@ + -rm -f $@.bin + $(TARGET_CC) -m64 $(EFIEMU64_LINK_FORMAT) -nostdlib -static -Wl,-r -o $@.bin $^ + if test "x$(EFIEMU64_LINK_FORMAT)" = x-arch,x86_64; then \ + $(TARGET_OBJCONV) -felf64 -nu -nd $@.bin $@ || exit 1; \ + rm -f $@.bin; \ + else \ + mv $@.bin $@ ; \ + fi + +platform_DATA += efiemu32.o efiemu64.o +CLEANFILES += efiemu32.o efiemu64.o efiemu64_c.o efiemu64_s.o +endif + +windowsdir=$(top_builddir)/$(PACKAGE)-$(VERSION)-for-windows +windowsdir: $(PROGRAMS) $(starfield_DATA) $(platform_DATA) + test -d $(windowsdir)/$(target_cpu)-$(platform) || mkdir $(windowsdir)/$(target_cpu)-$(platform) + for x in $(platform_DATA); do \ + cp -fp $$x $(windowsdir)/$(target_cpu)-$(platform)/$$x; \ + done diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.core.def b/GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.core.def new file mode 100644 index 0000000..c76386f --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.core.def @@ -0,0 +1,2586 @@ +AutoGen definitions Makefile.tpl; + +transform_data = { + installdir = noinst; + name = gensyminfo.sh; + common = gensyminfo.sh.in; +}; + +transform_data = { + installdir = noinst; + name = genmod.sh; + common = genmod.sh.in; +}; + +transform_data = { + installdir = noinst; + name = modinfo.sh; + common = modinfo.sh.in; +}; + +transform_data = { + installdir = platform; + name = gmodule.pl; + common = gmodule.pl.in; +}; + +transform_data = { + installdir = platform; + name = gdb_grub; + common = gdb_grub.in; +}; + +transform_data = { + installdir = platform; + name = grub.chrp; + common = boot/powerpc/grub.chrp.in; + enable = powerpc_ieee1275; +}; + +transform_data = { + installdir = platform; + name = bootinfo.txt; + common = boot/powerpc/bootinfo.txt.in; + enable = powerpc_ieee1275; +}; + +kernel = { + name = kernel; + + nostrip = emu; + + emu_ldflags = '-Wl,-r,-d'; + i386_efi_ldflags = '-Wl,-r,-d'; + i386_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version'; + x86_64_efi_ldflags = '-Wl,-r,-d'; + x86_64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version'; + + ia64_efi_cflags = '-fno-builtin -fpic -minline-int-divide-max-throughput'; + ia64_efi_ldflags = '-Wl,-r,-d'; + ia64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version'; + + arm_efi_ldflags = '-Wl,-r,-d'; + arm_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version'; + + arm64_efi_ldflags = '-Wl,-r,-d'; + arm64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version -R .eh_frame'; + + riscv32_efi_ldflags = '-Wl,-r,-d'; + riscv32_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version -R .eh_frame'; + + riscv64_efi_ldflags = '-Wl,-r,-d'; + riscv64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version -R .eh_frame'; + + i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)'; + i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x9000'; + i386_qemu_ldflags = '$(TARGET_IMG_LDFLAGS)'; + i386_qemu_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x9000'; + i386_coreboot_ldflags = '$(TARGET_IMG_LDFLAGS)'; + i386_coreboot_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x9000'; + i386_multiboot_ldflags = '$(TARGET_IMG_LDFLAGS)'; + i386_multiboot_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x9000'; + i386_ieee1275_ldflags = '$(TARGET_IMG_LDFLAGS)'; + i386_ieee1275_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x10000'; + i386_xen_ldflags = '$(TARGET_IMG_LDFLAGS)'; + i386_xen_ldflags = '$(TARGET_IMG_BASE_LDOPT),0'; + x86_64_xen_ldflags = '$(TARGET_IMG_LDFLAGS)'; + x86_64_xen_ldflags = '$(TARGET_IMG_BASE_LDOPT),0'; + i386_xen_pvh_ldflags = '$(TARGET_IMG_LDFLAGS)'; + i386_xen_pvh_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x100000'; + + mips_loongson_ldflags = '-Wl,-Ttext,0x80200000'; + powerpc_ieee1275_ldflags = '-Wl,-Ttext,0x200000'; + sparc64_ieee1275_ldflags = '-Wl,-Ttext,0x4400'; + mips_arc_ldflags = '-Wl,-Ttext,$(TARGET_LINK_ADDR)'; + mips_qemu_mips_ldflags = '-Wl,-Ttext,0x80200000'; + + mips_arc_cppflags = '-DGRUB_DECOMPRESSOR_LINK_ADDR=$(TARGET_DECOMPRESSOR_LINK_ADDR)'; + i386_qemu_cppflags = '-DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)'; + emu_cflags = '$(CFLAGS_GNULIB)'; + emu_cppflags = '$(CPPFLAGS_GNULIB)'; + arm_uboot_ldflags = '-Wl,-r,-d'; + arm_uboot_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version'; + + mips64_efi_ldflags = '-Wl,-r,-d'; + mips64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version -R .eh_frame -R .MIPS.abiflags'; + + arm_coreboot_ldflags = '-Wl,-r,-d'; + arm_coreboot_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version'; + + i386_pc_startup = kern/i386/pc/startup.S; + i386_efi_startup = kern/i386/efi/startup.S; + x86_64_efi_startup = kern/x86_64/efi/startup.S; + i386_xen_startup = kern/i386/xen/startup.S; + x86_64_xen_startup = kern/x86_64/xen/startup.S; + i386_xen_pvh_startup = kern/i386/xen/startup_pvh.S; + i386_qemu_startup = kern/i386/qemu/startup.S; + i386_ieee1275_startup = kern/i386/ieee1275/startup.S; + i386_coreboot_startup = kern/i386/coreboot/startup.S; + i386_multiboot_startup = kern/i386/coreboot/startup.S; + mips_startup = kern/mips/startup.S; + mips64_efi_startup = kern/mips64/efi/startup.S; + sparc64_ieee1275_startup = kern/sparc64/ieee1275/crt0.S; + powerpc_ieee1275_startup = kern/powerpc/ieee1275/startup.S; + arm_uboot_startup = kern/arm/startup.S; + arm_coreboot_startup = kern/arm/startup.S; + arm_efi_startup = kern/arm/efi/startup.S; + arm64_efi_startup = kern/arm64/efi/startup.S; + riscv32_efi_startup = kern/riscv/efi/startup.S; + riscv64_efi_startup = kern/riscv/efi/startup.S; + + common = kern/command.c; + common = kern/corecmd.c; + common = kern/device.c; + common = kern/disk.c; + common = kern/dl.c; + common = kern/env.c; + common = kern/err.c; + common = kern/file.c; + common = kern/fs.c; + common = kern/list.c; + common = kern/main.c; + common = kern/misc.c; + common = kern/parser.c; + common = kern/partition.c; + common = kern/rescue_parser.c; + common = kern/rescue_reader.c; + common = kern/term.c; + + noemu = kern/compiler-rt.c; + noemu = kern/mm.c; + noemu = kern/time.c; + noemu = kern/generic/millisleep.c; + + noemu_nodist = symlist.c; + + mips = kern/generic/rtc_get_time_ms.c; + + ieee1275 = disk/ieee1275/ofdisk.c; + ieee1275 = kern/ieee1275/cmain.c; + ieee1275 = kern/ieee1275/ieee1275.c; + ieee1275 = kern/ieee1275/mmap.c; + ieee1275 = kern/ieee1275/openfw.c; + ieee1275 = term/ieee1275/console.c; + ieee1275 = kern/ieee1275/init.c; + + uboot = disk/uboot/ubootdisk.c; + uboot = kern/uboot/uboot.c; + uboot = kern/uboot/init.c; + uboot = kern/uboot/hw.c; + uboot = term/uboot/console.c; + arm_uboot = kern/arm/uboot/init.c; + arm_uboot = kern/arm/uboot/uboot.S; + + arm_coreboot = kern/arm/coreboot/init.c; + arm_coreboot = kern/arm/coreboot/timer.c; + arm_coreboot = kern/arm/coreboot/coreboot.S; + arm_coreboot = lib/fdt.c; + arm_coreboot = bus/fdt.c; + arm_coreboot = term/ps2.c; + arm_coreboot = term/arm/pl050.c; + arm_coreboot = term/arm/cros.c; + arm_coreboot = term/arm/cros_ec.c; + arm_coreboot = bus/spi/rk3288_spi.c; + arm_coreboot = commands/keylayouts.c; + arm_coreboot = kern/arm/coreboot/dma.c; + + terminfoinkernel = term/terminfo.c; + terminfoinkernel = term/tparm.c; + terminfoinkernel = commands/extcmd.c; + terminfoinkernel = lib/arg.c; + + softdiv = lib/division.c; + + i386 = kern/i386/dl.c; + i386_xen = kern/i386/dl.c; + i386_xen_pvh = kern/i386/dl.c; + + i386_coreboot = kern/i386/coreboot/init.c; + i386_multiboot = kern/i386/coreboot/init.c; + i386_qemu = kern/i386/qemu/init.c; + i386_coreboot_multiboot_qemu = term/i386/pc/vga_text.c; + coreboot = video/coreboot/cbfb.c; + + efi = disk/efi/efidisk.c; + efi = kern/efi/efi.c; + efi = kern/efi/init.c; + efi = kern/efi/mm.c; + efi = term/efi/console.c; + efi = kern/acpi.c; + efi = kern/efi/acpi.c; + i386_coreboot = kern/i386/pc/acpi.c; + i386_multiboot = kern/i386/pc/acpi.c; + i386_coreboot = kern/acpi.c; + i386_multiboot = kern/acpi.c; + + x86 = kern/i386/tsc.c; + x86 = kern/i386/tsc_pit.c; + i386_efi = kern/i386/efi/tsc.c; + x86_64_efi = kern/i386/efi/tsc.c; + i386_efi = kern/i386/tsc_pmtimer.c; + i386_coreboot = kern/i386/tsc_pmtimer.c; + x86_64_efi = kern/i386/tsc_pmtimer.c; + + i386_efi = kern/i386/efi/init.c; + i386_efi = bus/pci.c; + + x86_64 = kern/x86_64/dl.c; + x86_64_xen = kern/x86_64/dl.c; + x86_64_efi = kern/x86_64/efi/callwrap.S; + x86_64_efi = kern/i386/efi/init.c; + x86_64_efi = bus/pci.c; + + xen = kern/i386/tsc.c; + xen = kern/i386/xen/tsc.c; + x86_64_xen = kern/x86_64/xen/hypercall.S; + i386_xen = kern/i386/xen/hypercall.S; + xen = kern/xen/init.c; + xen = term/xen/console.c; + xen = disk/xen/xendisk.c; + xen = commands/boot.c; + + i386_xen_pvh = commands/boot.c; + i386_xen_pvh = disk/xen/xendisk.c; + i386_xen_pvh = kern/i386/tsc.c; + i386_xen_pvh = kern/i386/xen/tsc.c; + i386_xen_pvh = kern/i386/xen/pvh.c; + i386_xen_pvh = kern/xen/init.c; + i386_xen_pvh = term/xen/console.c; + + ia64_efi = kern/ia64/efi/startup.S; + ia64_efi = kern/ia64/efi/init.c; + ia64_efi = kern/ia64/dl.c; + ia64_efi = kern/ia64/dl_helper.c; + ia64_efi = kern/ia64/cache.c; + + arm_efi = kern/arm/efi/init.c; + arm_efi = kern/efi/fdt.c; + + arm64_efi = kern/arm64/efi/init.c; + arm64_efi = kern/efi/fdt.c; + + riscv32_efi = kern/riscv/efi/init.c; + riscv32_efi = kern/efi/fdt.c; + + riscv64_efi = kern/riscv/efi/init.c; + riscv64_efi = kern/efi/fdt.c; + + i386_pc = kern/i386/pc/init.c; + i386_pc = kern/i386/pc/mmap.c; + i386_pc = term/i386/pc/console.c; + + i386_qemu = bus/pci.c; + i386_qemu = kern/vga_init.c; + i386_qemu = kern/i386/qemu/mmap.c; + + coreboot = kern/coreboot/mmap.c; + i386_coreboot = kern/i386/coreboot/cbtable.c; + coreboot = kern/coreboot/cbtable.c; + arm_coreboot = kern/arm/coreboot/cbtable.c; + + i386_multiboot = kern/i386/multiboot_mmap.c; + + mips = kern/mips/cache.S; + mips = kern/mips/dl.c; + mips = kern/mips/init.c; + + mips_qemu_mips = kern/mips/qemu_mips/init.c; + mips_qemu_mips = term/ns8250.c; + mips_qemu_mips = term/serial.c; + mips_qemu_mips = term/at_keyboard.c; + mips_qemu_mips = term/ps2.c; + mips_qemu_mips = commands/boot.c; + mips_qemu_mips = commands/keylayouts.c; + mips_qemu_mips = term/i386/pc/vga_text.c; + mips_qemu_mips = kern/vga_init.c; + + mips_arc = kern/mips/arc/init.c; + mips_arc = term/arc/console.c; + mips_arc = disk/arc/arcdisk.c; + + mips_loongson = term/ns8250.c; + mips_loongson = bus/bonito.c; + mips_loongson = bus/cs5536.c; + mips_loongson = bus/pci.c; + mips_loongson = kern/mips/loongson/init.c; + mips_loongson = term/at_keyboard.c; + mips_loongson = term/ps2.c; + mips_loongson = commands/boot.c; + mips_loongson = term/serial.c; + mips_loongson = video/sm712.c; + mips_loongson = video/sis315pro.c; + mips_loongson = video/radeon_fuloong2e.c; + mips_loongson = video/radeon_yeeloong3a.c; + extra_dist = video/sm712_init.c; + extra_dist = video/sis315_init.c; + mips_loongson = commands/keylayouts.c; + + mips64 = kern/mips64/init.c; + mips64 = kern/mips64/dl.c; + mips64 = kern/mips64/cache.S; + mips64 = kern/generic/rtc_get_time_ms.c; + mips64_efi = kern/mips64/efi/init.c; + mips64_efi = kern/mips64/efi/loongson.c; + mips64_efi = lib/mips64/efi/loongson.c; + mips64_efi = lib/mips64/efi/loongson_asm.S; + + powerpc_ieee1275 = kern/powerpc/cache.S; + powerpc_ieee1275 = kern/powerpc/dl.c; + powerpc_ieee1275 = kern/powerpc/compiler-rt.S; + + sparc64_ieee1275 = kern/sparc64/cache.S; + sparc64_ieee1275 = kern/sparc64/dl.c; + sparc64_ieee1275 = kern/sparc64/ieee1275/ieee1275.c; + sparc64_ieee1275 = disk/ieee1275/obdisk.c; + + arm = kern/arm/dl.c; + arm = kern/arm/dl_helper.c; + arm = kern/arm/cache_armv6.S; + arm = kern/arm/cache_armv7.S; + extra_dist = kern/arm/cache.S; + arm = kern/arm/cache.c; + arm = kern/arm/compiler-rt.S; + + arm64 = kern/arm64/cache.c; + arm64 = kern/arm64/cache_flush.S; + arm64 = kern/arm64/dl.c; + arm64 = kern/arm64/dl_helper.c; + + riscv32 = kern/riscv/cache.c; + riscv32 = kern/riscv/cache_flush.S; + riscv32 = kern/riscv/dl.c; + + riscv64 = kern/riscv/cache.c; + riscv64 = kern/riscv/cache_flush.S; + riscv64 = kern/riscv/dl.c; + + emu = disk/host.c; + emu = kern/emu/cache_s.S; + emu = kern/emu/hostdisk.c; + emu = osdep/unix/hostdisk.c; + emu = osdep/exec.c; + extra_dist = osdep/unix/exec.c; + emu = osdep/devmapper/hostdisk.c; + emu = osdep/hostdisk.c; + emu = kern/emu/hostfs.c; + emu = kern/emu/main.c; + emu = kern/emu/argp_common.c; + emu = kern/emu/misc.c; + emu = kern/emu/mm.c; + emu = kern/emu/time.c; + emu = kern/emu/cache.c; + emu = osdep/emuconsole.c; + extra_dist = osdep/unix/emuconsole.c; + extra_dist = osdep/windows/emuconsole.c; + emu = osdep/dl.c; + extra_dist = osdep/unix/dl.c; + extra_dist = osdep/windows/dl.c; + emu = osdep/sleep.c; + emu = osdep/init.c; + emu = osdep/emunet.c; + extra_dist = osdep/linux/emunet.c; + extra_dist = osdep/basic/emunet.c; + emu = osdep/cputime.c; + extra_dist = osdep/unix/cputime.c; + extra_dist = osdep/windows/cputime.c; + + videoinkernel = term/gfxterm.c; + videoinkernel = font/font.c; + videoinkernel = font/font_cmd.c; + videoinkernel = io/bufio.c; + videoinkernel = video/fb/fbblit.c; + videoinkernel = video/fb/fbfill.c; + videoinkernel = video/fb/fbutil.c; + videoinkernel = video/fb/video_fb.c; + videoinkernel = video/video.c; + + extra_dist = kern/i386/int.S; + extra_dist = kern/i386/realmode.S; + extra_dist = boot/i386/pc/lzma_decode.S; + extra_dist = kern/mips/cache_flush.S; +}; + +program = { + name = grub-emu; + mansection = 1; + + emu = kern/emu/full.c; + emu_nodist = grub_emu_init.c; + + ldadd = 'kernel.exec$(EXEEXT)'; + ldadd = '$(MODULE_FILES)'; + ldadd = 'lib/gnulib/libgnu.a $(LIBINTL) $(LIBUTIL) $(LIBSDL) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; + + enable = emu; +}; + +program = { + name = grub-emu-lite; + + emu = kern/emu/lite.c; + emu_nodist = symlist.c; + + ldadd = 'kernel.exec$(EXEEXT)'; + ldadd = 'lib/gnulib/libgnu.a $(LIBINTL) $(LIBUTIL) $(LIBSDL) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; + + enable = emu; +}; + +image = { + name = boot; + i386_pc = boot/i386/pc/boot.S; + i386_qemu = boot/i386/qemu/boot.S; + sparc64_ieee1275 = boot/sparc64/ieee1275/boot.S; + + i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)'; + i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x7C00'; + + i386_qemu_ldflags = '$(TARGET_IMG_LDFLAGS)'; + i386_qemu_ldflags = '$(TARGET_IMG_BASE_LDOPT),$(GRUB_BOOT_MACHINE_LINK_ADDR)'; + i386_qemu_ccasflags = '-DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)'; + + /* The entry point for a.out binaries on sparc64 starts + at 0x4000. Since we are writing the 32 bytes long a.out + header in the assembly code ourselves, we need to tell + the linker to adjust the start of the text segment to + 0x4000 - 0x20 = 0x3fe0. + */ + sparc64_ieee1275_ldflags = ' -Wl,-Ttext=0x3fe0'; + sparc64_ieee1275_objcopyflags = '-O binary'; + + objcopyflags = '-O binary'; + enable = i386_pc; + enable = i386_qemu; + enable = sparc64_ieee1275; +}; + +image = { + name = boot_hybrid; + i386_pc = boot/i386/pc/boot.S; + + cppflags = '-DHYBRID_BOOT=1'; + + i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)'; + i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x7C00'; + + objcopyflags = '-O binary'; + enable = i386_pc; +}; + +image = { + name = cdboot; + + i386_pc = boot/i386/pc/cdboot.S; + i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)'; + i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x7C00'; + + sparc64_ieee1275 = boot/sparc64/ieee1275/boot.S; + + /* See comment for sparc64_ieee1275_ldflags above. */ + sparc64_ieee1275_ldflags = ' -Wl,-Ttext=0x3fe0'; + sparc64_ieee1275_objcopyflags = '-O binary'; + sparc64_ieee1275_cppflags = '-DCDBOOT=1'; + + objcopyflags = '-O binary'; + + enable = sparc64_ieee1275; + enable = i386_pc; +}; + +image = { + name = pxeboot; + i386_pc = boot/i386/pc/pxeboot.S; + + i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)'; + i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x7C00'; + + objcopyflags = '-O binary'; + enable = i386_pc; +}; + +image = { + name = diskboot; + i386_pc = boot/i386/pc/diskboot.S; + + i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)'; + i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x8000'; + + sparc64_ieee1275 = boot/sparc64/ieee1275/diskboot.S; + sparc64_ieee1275_ldflags = '-Wl,-Ttext=0x4200'; + + objcopyflags = '-O binary'; + + enable = i386_pc; + enable = sparc64_ieee1275; +}; + +image = { + name = lnxboot; + i386_pc = boot/i386/pc/lnxboot.S; + + i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)'; + i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x6000'; + + objcopyflags = '-O binary'; + enable = i386_pc; +}; + +image = { + name = xz_decompress; + mips = boot/mips/startup_raw.S; + common = boot/decompressor/minilib.c; + common = boot/decompressor/xz.c; + common = lib/xzembed/xz_dec_bcj.c; + common = lib/xzembed/xz_dec_lzma2.c; + common = lib/xzembed/xz_dec_stream.c; + common = kern/compiler-rt.c; + + cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed -DGRUB_EMBED_DECOMPRESSOR=1'; + + objcopyflags = '-O binary'; + mips_ldflags = '-Wl,-Ttext,$(TARGET_DECOMPRESSOR_LINK_ADDR)'; + cflags = '-Wno-unreachable-code'; + enable = mips; +}; + +image = { + name = none_decompress; + mips = boot/mips/startup_raw.S; + common = boot/decompressor/none.c; + + cppflags = '-DGRUB_EMBED_DECOMPRESSOR=1'; + + objcopyflags = '-O binary'; + mips_ldflags = '-Wl,-Ttext,$(TARGET_DECOMPRESSOR_LINK_ADDR)'; + enable = mips; +}; + +image = { + name = lzma_decompress; + i386_pc = boot/i386/pc/startup_raw.S; + i386_pc_nodist = rs_decoder.h; + + objcopyflags = '-O binary'; + ldflags = '$(TARGET_IMG_LDFLAGS) $(TARGET_IMG_BASE_LDOPT),0x8200'; + enable = i386_pc; +}; + +image = { + name = fwstart; + mips_loongson = boot/mips/loongson/fwstart.S; + objcopyflags = '-O binary'; + ldflags = '-Wl,-N,-S,-Ttext,0xbfc00000,-Bstatic'; + enable = mips_loongson; +}; + +image = { + name = fwstart_fuloong2f; + mips_loongson = boot/mips/loongson/fuloong2f.S; + objcopyflags = '-O binary'; + ldflags = '-Wl,-N,-S,-Ttext,0xbfc00000,-Bstatic'; + enable = mips_loongson; +}; + +module = { + name = disk; + common = lib/disk.c; + extra_dist = kern/disk_common.c; +}; + +module = { + name = trig; + common_nodist = trigtables.c; + extra_dist = gentrigtables.c; +}; + +module = { + name = cs5536; + x86 = bus/cs5536.c; + enable = x86; +}; + +module = { + name = lsspd; + mips_loongson = commands/mips/loongson/lsspd.c; + enable = mips_loongson; +}; + +module = { + name = usb; + common = bus/usb/usb.c; + common = bus/usb/usbtrans.c; + common = bus/usb/usbhub.c; + enable = usb; +}; + +module = { + name = usbserial_common; + common = bus/usb/serial/common.c; + enable = usb; +}; + +module = { + name = usbserial_pl2303; + common = bus/usb/serial/pl2303.c; + enable = usb; +}; + +module = { + name = usbserial_ftdi; + common = bus/usb/serial/ftdi.c; + enable = usb; +}; + +module = { + name = usbserial_usbdebug; + common = bus/usb/serial/usbdebug_late.c; + enable = usb; +}; + +module = { + name = uhci; + common = bus/usb/uhci.c; + enable = pci; +}; + +module = { + name = ohci; + common = bus/usb/ohci.c; + enable = pci; +}; + +module = { + name = ehci; + common = bus/usb/ehci.c; + arm_coreboot = bus/usb/ehci-fdt.c; + pci = bus/usb/ehci-pci.c; + enable = pci; + enable = arm_coreboot; +}; + +module = { + name = pci; + common = bus/pci.c; + i386_ieee1275 = bus/i386/ieee1275/pci.c; + + enable = i386_pc; + enable = i386_ieee1275; + enable = i386_coreboot; + enable = i386_multiboot; +}; + +module = { + name = nativedisk; + common = commands/nativedisk.c; + + enable = x86; + enable = mips_loongson; + enable = mips_qemu_mips; +}; + +module = { + name = emupci; + common = bus/emu/pci.c; + common = commands/lspci.c; + + enable = emu; + condition = COND_GRUB_EMU_PCI; +}; + +module = { + name = lsdev; + common = commands/arc/lsdev.c; + + enable = mips_arc; +}; + +module = { + name = lsxen; + common = commands/xen/lsxen.c; + + enable = xen; +}; + +module = { + name = cmostest; + common = commands/i386/cmostest.c; + enable = cmos; +}; + +module = { + name = cmosdump; + common = commands/i386/cmosdump.c; + enable = cmos; +}; + +module = { + name = iorw; + common = commands/iorw.c; + enable = x86; +}; + +module = { + name = cbtable; + common = kern/i386/coreboot/cbtable.c; + common = kern/coreboot/cbtable.c; + enable = i386_pc; + enable = i386_efi; + enable = i386_qemu; + enable = i386_multiboot; + enable = i386_ieee1275; + enable = x86_64_efi; +}; + +module = { + name = cbtime; + common = commands/i386/coreboot/cb_timestamps.c; + enable = x86; +}; + +module = { + name = cbls; + common = commands/i386/coreboot/cbls.c; + enable = x86; +}; + +module = { + name = cbmemc; + common = term/i386/coreboot/cbmemc.c; + enable = x86; +}; + +module = { + name = regexp; + common = commands/regexp.c; + common = commands/wildcard.c; + common = lib/gnulib/regex.c; + cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)'; + cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB)'; +}; + +module = { + name = acpi; + + common = commands/acpi.c; + i386_pc = kern/acpi.c; + i386_pc = kern/i386/pc/acpi.c; + + enable = efi; + enable = i386_pc; + enable = i386_coreboot; + enable = i386_multiboot; +}; + +module = { + name = lsacpi; + + common = commands/lsacpi.c; + + enable = efi; + enable = i386_pc; + enable = i386_coreboot; + enable = i386_multiboot; +}; + +module = { + name = lsefisystab; + + common = commands/efi/lsefisystab.c; + + enable = efi; +}; + +module = { + name = lssal; + + common = commands/efi/lssal.c; + + enable = efi; +}; + +module = { + name = lsefimmap; + + common = commands/efi/lsefimmap.c; + + enable = efi; +}; + +module = { + name = lsefi; + common = commands/efi/lsefi.c; + enable = efi; +}; + +module = { + name = efifwsetup; + efi = commands/efi/efifwsetup.c; + enable = efi; +}; + +module = { + name = blocklist; + common = commands/blocklist.c; +}; + +module = { + name = blscfg; + common = commands/blscfg.c; + common = commands/loadenv.h; + enable = powerpc_ieee1275; + enable = efi; + enable = i386_pc; + enable = emu; +}; + +module = { + name = boot; + common = commands/boot.c; + i386_pc = lib/i386/pc/biosnum.c; + enable = x86; + enable = emu; + enable = sparc64_ieee1275; + enable = powerpc_ieee1275; + enable = mips_arc; + enable = mips64_efi; + enable = ia64_efi; + enable = arm_efi; + enable = arm64_efi; + enable = arm_uboot; + enable = arm_coreboot; + enable = riscv32_efi; + enable = riscv64_efi; +}; + +module = { + name = cat; + common = commands/cat.c; +}; + +module = { + name = cmp; + common = commands/cmp.c; +}; + +module = { + name = configfile; + common = commands/configfile.c; +}; + +module = { + name = cpuid; + common = commands/i386/cpuid.c; + enable = x86; + enable = i386_xen_pvh; + enable = i386_xen; + enable = x86_64_xen; +}; + +module = { + name = date; + common = commands/date.c; +}; + +module = { + name = drivemap; + + i386_pc = commands/i386/pc/drivemap.c; + i386_pc = commands/i386/pc/drivemap_int13h.S; + enable = i386_pc; +}; + +module = { + name = echo; + common = commands/echo.c; +}; + +module = { + name = eval; + common = commands/eval.c; +}; + +module = { + name = extcmd; + common = commands/extcmd.c; + common = lib/arg.c; + enable = terminfomodule; +}; + +module = { + name = fixvideo; + common = commands/efi/fixvideo.c; + enable = i386_efi; + enable = x86_64_efi; +}; + +module = { + name = fwload; + efi = commands/efi/fwload.c; + enable = efi; +}; + +module = { + name = gptsync; + common = commands/gptsync.c; +}; + +module = { + name = halt; + nopc = commands/halt.c; + i386_pc = commands/i386/pc/halt.c; + i386_pc = commands/acpihalt.c; + i386_coreboot = commands/acpihalt.c; + i386_multiboot = commands/acpihalt.c; + i386_efi = commands/acpihalt.c; + x86_64_efi = commands/acpihalt.c; + i386_multiboot = lib/i386/halt.c; + i386_coreboot = lib/i386/halt.c; + i386_qemu = lib/i386/halt.c; + xen = lib/xen/halt.c; + i386_xen_pvh = lib/xen/halt.c; + efi = lib/efi/halt.c; + ieee1275 = lib/ieee1275/halt.c; + emu = lib/emu/halt.c; + uboot = lib/dummy/halt.c; + arm_coreboot = lib/dummy/halt.c; +}; + +module = { + name = reboot; + i386 = lib/i386/reboot.c; + i386 = lib/i386/reboot_trampoline.S; + powerpc_ieee1275 = lib/ieee1275/reboot.c; + sparc64_ieee1275 = lib/ieee1275/reboot.c; + mips_arc = lib/mips/arc/reboot.c; + mips_loongson = lib/mips/loongson/reboot.c; + mips_qemu_mips = lib/mips/qemu_mips/reboot.c; + xen = lib/xen/reboot.c; + i386_xen_pvh = lib/xen/reboot.c; + uboot = lib/uboot/reboot.c; + arm_coreboot = lib/dummy/reboot.c; + common = commands/reboot.c; +}; + +module = { + name = hashsum; + common = commands/hashsum.c; +}; + +module = { + name = pgp; + common = commands/pgp.c; + cflags = '$(CFLAGS_POSIX)'; + cppflags = '-I$(srcdir)/lib/posix_wrap'; +}; + +module = { + name = verifiers; + common = commands/verifiers.c; +}; + +module = { + name = shim_lock; + common = commands/efi/shim_lock.c; + enable = x86_64_efi; +}; + +module = { + name = hdparm; + common = commands/hdparm.c; + enable = pci; + enable = mips_qemu_mips; +}; + +module = { + name = help; + common = commands/help.c; +}; + +module = { + name = hexdump; + common = commands/hexdump.c; + common = lib/hexdump.c; +}; + +module = { + name = keystatus; + common = commands/keystatus.c; +}; + +module = { + name = loadbios; + common = commands/efi/loadbios.c; + enable = i386_efi; + enable = x86_64_efi; +}; + +module = { + name = loadenv; + common = commands/loadenv.c; + common = commands/loadenv.h; + common = lib/envblk.c; +}; + +module = { + name = ls; + common = commands/ls.c; +}; + +module = { + name = lsmmap; + common = commands/lsmmap.c; +}; + +module = { + name = lspci; + common = commands/lspci.c; + + enable = pci; +}; + +module = { + name = memrw; + common = commands/memrw.c; +}; + +module = { + name = minicmd; + common = commands/minicmd.c; +}; + +module = { + name = parttool; + common = commands/parttool.c; +}; + +module = { + name = password; + common = commands/password.c; +}; + +module = { + name = password_pbkdf2; + common = commands/password_pbkdf2.c; +}; + +module = { + name = play; + x86 = commands/i386/pc/play.c; + enable = x86; +}; + +module = { + name = spkmodem; + x86 = term/spkmodem.c; + enable = x86; +}; + +module = { + name = morse; + x86 = term/morse.c; + enable = x86; +}; + +module = { + name = probe; + common = commands/probe.c; +}; + +module = { + name = read; + common = commands/read.c; +}; + +module = { + name = search; + common = commands/search_wrap.c; + extra_dist = commands/search.c; +}; + +module = { + name = search_fs_file; + common = commands/search_file.c; +}; + +module = { + name = search_fs_uuid; + common = commands/search_uuid.c; +}; + +module = { + name = search_label; + common = commands/search_label.c; +}; + +module = { + name = setpci; + common = commands/setpci.c; + enable = pci; +}; + +module = { + name = pcidump; + common = commands/pcidump.c; + enable = pci; +}; + +module = { + name = sleep; + common = commands/sleep.c; +}; + +module = { + name = smbios; + + common = commands/smbios.c; + efi = commands/efi/smbios.c; + i386_pc = commands/i386/pc/smbios.c; + i386_coreboot = commands/i386/pc/smbios.c; + i386_multiboot = commands/i386/pc/smbios.c; + + enable = efi; + enable = i386_pc; + enable = i386_coreboot; + enable = i386_multiboot; +}; + +module = { + name = suspend; + ieee1275 = commands/ieee1275/suspend.c; + enable = i386_ieee1275; + enable = powerpc_ieee1275; +}; + +module = { + name = escc; + ieee1275 = term/ieee1275/escc.c; + enable = powerpc_ieee1275; +}; + +module = { + name = terminal; + common = commands/terminal.c; +}; + +module = { + name = test; + common = commands/test.c; +}; + +module = { + name = true; + common = commands/true.c; +}; + +module = { + name = usbtest; + common = commands/usbtest.c; + enable = usb; +}; + +module = { + name = videoinfo; + common = commands/videoinfo.c; +}; + +module = { + name = videotest; + common = commands/videotest.c; +}; + +module = { + name = xnu_uuid; + common = commands/xnu_uuid.c; +}; + +module = { + name = dm_nv; + common = disk/dmraid_nvidia.c; +}; + +module = { + name = loopback; + common = disk/loopback.c; +}; + +module = { + name = cryptodisk; + common = disk/cryptodisk.c; +}; + +module = { + name = luks; + common = disk/luks.c; + common = disk/AFSplitter.c; +}; + +module = { + name = geli; + common = disk/geli.c; +}; + +module = { + name = lvm; + common = disk/lvm.c; +}; + +module = { + name = ldm; + common = disk/ldm.c; +}; + +module = { + name = mdraid09; + common = disk/mdraid_linux.c; +}; + +module = { + name = mdraid09_be; + common = disk/mdraid_linux_be.c; +}; + +module = { + name = mdraid1x; + common = disk/mdraid1x_linux.c; +}; + +module = { + name = diskfilter; + common = disk/diskfilter.c; +}; + +module = { + name = raid5rec; + common = disk/raid5_recover.c; +}; + +module = { + name = raid6rec; + common = disk/raid6_recover.c; +}; + +module = { + name = scsi; + common = disk/scsi.c; +}; + +module = { + name = memdisk; + common = disk/memdisk.c; +}; + +module = { + name = ata; + common = disk/ata.c; + enable = pci; + enable = mips_qemu_mips; +}; + +module = { + name = ahci; + common = disk/ahci.c; + enable = pci; +}; + +module = { + name = pata; + common = disk/pata.c; + enable = pci; + enable = mips_qemu_mips; +}; + +module = { + name = biosdisk; + i386_pc = disk/i386/pc/biosdisk.c; + enable = i386_pc; +}; + +module = { + name = usbms; + common = disk/usbms.c; + enable = usb; +}; + +module = { + name = nand; + ieee1275 = disk/ieee1275/nand.c; + enable = i386_ieee1275; +}; + +module = { + name = efiemu; + common = efiemu/main.c; + common = efiemu/i386/loadcore32.c; + common = efiemu/i386/loadcore64.c; + i386_pc = efiemu/i386/pc/cfgtables.c; + i386_coreboot = efiemu/i386/pc/cfgtables.c; + i386_multiboot = efiemu/i386/pc/cfgtables.c; + i386_ieee1275 = efiemu/i386/nocfgtables.c; + i386_qemu = efiemu/i386/nocfgtables.c; + common = efiemu/mm.c; + common = efiemu/loadcore_common.c; + common = efiemu/symbols.c; + common = efiemu/loadcore32.c; + common = efiemu/loadcore64.c; + common = efiemu/prepare32.c; + common = efiemu/prepare64.c; + common = efiemu/pnvram.c; + common = efiemu/i386/coredetect.c; + + extra_dist = efiemu/prepare.c; + extra_dist = efiemu/loadcore.c; + extra_dist = efiemu/runtime/efiemu.S; + extra_dist = efiemu/runtime/efiemu.c; + + enable = i386_pc; + enable = i386_coreboot; + enable = i386_ieee1275; + enable = i386_multiboot; + enable = i386_qemu; +}; + +module = { + name = font; + common = font/font.c; + common = font/font_cmd.c; + enable = videomodules; +}; + +module = { + name = procfs; + common = fs/proc.c; +}; + +module = { + name = affs; + common = fs/affs.c; +}; + +module = { + name = afs; + common = fs/afs.c; +}; + +module = { + name = bfs; + common = fs/bfs.c; +}; + +module = { + name = zstd; + common = lib/zstd/debug.c; + common = lib/zstd/entropy_common.c; + common = lib/zstd/error_private.c; + common = lib/zstd/fse_decompress.c; + common = lib/zstd/huf_decompress.c; + common = lib/zstd/module.c; + common = lib/zstd/xxhash.c; + common = lib/zstd/zstd_common.c; + common = lib/zstd/zstd_decompress.c; + cflags = '$(CFLAGS_POSIX) -Wno-undef'; + cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/zstd'; +}; + +module = { + name = btrfs; + common = fs/btrfs.c; + common = lib/crc.c; + cflags = '$(CFLAGS_POSIX) -Wno-undef'; + cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/minilzo -I$(srcdir)/lib/zstd -DMINILZO_HAVE_CONFIG_H'; +}; + +module = { + name = archelp; + common = fs/archelp.c; +}; + +module = { + name = cbfs; + common = fs/cbfs.c; +}; + +module = { + name = cpio; + common = fs/cpio.c; +}; + +module = { + name = cpio_be; + common = fs/cpio_be.c; +}; + +module = { + name = newc; + common = fs/newc.c; +}; + +module = { + name = odc; + common = fs/odc.c; +}; + +module = { + name = ext2; + common = fs/ext2.c; +}; + +module = { + name = fat; + common = fs/fat.c; +}; + +module = { + name = exfat; + common = fs/exfat.c; +}; + +module = { + name = f2fs; + common = fs/f2fs.c; +}; + +module = { + name = fshelp; + common = fs/fshelp.c; +}; + +module = { + name = hfs; + common = fs/hfs.c; +}; + +module = { + name = hfsplus; + common = fs/hfsplus.c; +}; + +module = { + name = hfspluscomp; + common = fs/hfspluscomp.c; +}; + +module = { + name = iso9660; + common = fs/iso9660.c; +}; + +module = { + name = jfs; + common = fs/jfs.c; +}; + +module = { + name = minix; + common = fs/minix.c; +}; + +module = { + name = minix2; + common = fs/minix2.c; +}; + +module = { + name = minix3; + common = fs/minix3.c; +}; + +module = { + name = minix_be; + common = fs/minix_be.c; +}; + +module = { + name = minix2_be; + common = fs/minix2_be.c; +}; + +module = { + name = minix3_be; + common = fs/minix3_be.c; +}; + +module = { + name = nilfs2; + common = fs/nilfs2.c; +}; + +module = { + name = ntfs; + common = fs/ntfs.c; +}; + +module = { + name = ntfscomp; + common = fs/ntfscomp.c; +}; + +module = { + name = reiserfs; + common = fs/reiserfs.c; +}; + +module = { + name = romfs; + common = fs/romfs.c; +}; + +module = { + name = sfs; + common = fs/sfs.c; +}; + +module = { + name = squash4; + common = fs/squash4.c; + cflags = '$(CFLAGS_POSIX) -Wno-undef'; + cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed -I$(srcdir)/lib/minilzo -I$(srcdir)/lib/zstd -DMINILZO_HAVE_CONFIG_H'; +}; + +module = { + name = tar; + common = fs/tar.c; +}; + +module = { + name = udf; + common = fs/udf.c; +}; + +module = { + name = ufs1; + common = fs/ufs.c; +}; + +module = { + name = ufs1_be; + common = fs/ufs_be.c; +}; + +module = { + name = ufs2; + common = fs/ufs2.c; +}; + +module = { + name = xfs; + common = fs/xfs.c; +}; + +module = { + name = zfs; + common = fs/zfs/zfs.c; + common = fs/zfs/zfs_lzjb.c; + common = fs/zfs/zfs_lz4.c; + common = fs/zfs/zfs_sha256.c; + common = fs/zfs/zfs_fletcher.c; +}; + +module = { + name = zfscrypt; + common = fs/zfs/zfscrypt.c; +}; + +module = { + name = zfsinfo; + common = fs/zfs/zfsinfo.c; +}; + +module = { + name = macbless; + common = commands/macbless.c; +}; + +module = { + name = pxe; + i386_pc = net/drivers/i386/pc/pxe.c; + enable = i386_pc; +}; + +module = { + name = gettext; + common = gettext/gettext.c; +}; + +module = { + name = gfxmenu; + common = gfxmenu/gfxmenu.c; + common = gfxmenu/view.c; + common = gfxmenu/font.c; + common = gfxmenu/icon_manager.c; + common = gfxmenu/theme_loader.c; + common = gfxmenu/widget-box.c; + common = gfxmenu/gui_canvas.c; + common = gfxmenu/gui_circular_progress.c; + common = gfxmenu/gui_box.c; + common = gfxmenu/gui_label.c; + common = gfxmenu/gui_list.c; + common = gfxmenu/gui_image.c; + common = gfxmenu/gui_progress_bar.c; + common = gfxmenu/gui_util.c; + common = gfxmenu/gui_string_util.c; +}; + +/* Added by longpanda for Ventoy Project */ +module = { + name = ventoy; + common = ventoy/ventoy.c; + common = ventoy/ventoy_cmd.c; + common = ventoy/ventoy_linux.c; + common = ventoy/ventoy_unix.c; + common = ventoy/ventoy_windows.c; + common = ventoy/ventoy_vhd.c; + common = ventoy/ventoy_plugin.c; + common = ventoy/ventoy_json.c; + common = ventoy/ventoy_browser.c; + common = ventoy/lzx.c; + common = ventoy/xpress.c; + common = ventoy/huffman.c; + common = ventoy/miniz.c; +}; + +module = { + name = setkey; + common = term/setkey.c; +}; + +module = { + name = mouse; + efi = term/efi/mouse.c; + enable = efi; +}; + +module = { + name = hello; + common = hello/hello.c; +}; + +module = { + name = gzio; + common = io/gzio.c; +}; + +module = { + name = offsetio; + common = io/offset.c; +}; + +module = { + name = bufio; + common = io/bufio.c; + enable = videomodules; +}; + +module = { + name = elf; + common = kern/elf.c; + + extra_dist = kern/elfXX.c; +}; + +module = { + name = crypto; + common = lib/crypto.c; + + extra_dist = lib/libgcrypt-grub/cipher/crypto.lst; +}; + +module = { + name = pbkdf2; + common = lib/pbkdf2.c; +}; + +module = { + name = relocator; + common = lib/relocator.c; + x86 = lib/i386/relocator16.S; + x86 = lib/i386/relocator32.S; + x86 = lib/i386/relocator64.S; + i386_xen_pvh = lib/i386/relocator16.S; + i386_xen_pvh = lib/i386/relocator32.S; + i386_xen_pvh = lib/i386/relocator64.S; + i386 = lib/i386/relocator_asm.S; + i386_xen_pvh = lib/i386/relocator_asm.S; + x86_64 = lib/x86_64/relocator_asm.S; + i386_xen = lib/i386/relocator_asm.S; + x86_64_xen = lib/x86_64/relocator_asm.S; + x86 = lib/i386/relocator.c; + x86 = lib/i386/relocator_common_c.c; + i386_xen_pvh = lib/i386/relocator.c; + i386_xen_pvh = lib/i386/relocator_common_c.c; + ieee1275 = lib/ieee1275/relocator.c; + efi = lib/efi/relocator.c; + mips = lib/mips/relocator_asm.S; + mips = lib/mips/relocator.c; + mips64 = lib/mips64/relocator_asm.S; + mips64 = lib/mips64/relocator.c; + powerpc = lib/powerpc/relocator_asm.S; + powerpc = lib/powerpc/relocator.c; + xen = lib/xen/relocator.c; + i386_xen = lib/i386/xen/relocator.S; + x86_64_xen = lib/x86_64/xen/relocator.S; + xen = lib/i386/relocator_common_c.c; + x86_64_efi = lib/x86_64/efi/relocator.c; + + extra_dist = lib/i386/relocator_common.S; + extra_dist = kern/powerpc/cache_flush.S; + + enable = mips; + enable = mips64; + enable = powerpc; + enable = x86; + enable = i386_xen_pvh; + enable = xen; +}; + +module = { + name = datetime; + cmos = lib/cmos_datetime.c; + efi = lib/efi/datetime.c; + uboot = lib/dummy/datetime.c; + arm_coreboot = lib/dummy/datetime.c; + sparc64_ieee1275 = lib/ieee1275/datetime.c; + powerpc_ieee1275 = lib/ieee1275/datetime.c; + sparc64_ieee1275 = lib/ieee1275/cmos.c; + powerpc_ieee1275 = lib/ieee1275/cmos.c; + xen = lib/xen/datetime.c; + i386_xen_pvh = lib/xen/datetime.c; + + mips_arc = lib/arc/datetime.c; + enable = noemu; +}; + +module = { + name = setjmp; + common = lib/setjmp.S; + extra_dist = lib/i386/setjmp.S; + extra_dist = lib/mips/setjmp.S; + extra_dist = lib/x86_64/setjmp.S; + extra_dist = lib/sparc64/setjmp.S; + extra_dist = lib/powerpc/setjmp.S; + extra_dist = lib/ia64/setjmp.S; + extra_dist = lib/ia64/longjmp.S; + extra_dist = lib/arm/setjmp.S; + extra_dist = lib/arm64/setjmp.S; + extra_dist = lib/riscv/setjmp.S; +}; + +module = { + name = aout; + common = loader/aout.c; + enable = x86; +}; + +module = { + name = bsd; + x86 = loader/i386/bsd.c; + x86 = loader/i386/bsd32.c; + x86 = loader/i386/bsd64.c; + + extra_dist = loader/i386/bsdXX.c; + extra_dist = loader/i386/bsd_pagetable.c; + + enable = x86; +}; + +module = { + name = plan9; + i386_pc = loader/i386/pc/plan9.c; + enable = i386_pc; +}; + + +module = { + name = linux16; + common = loader/i386/pc/linux.c; + enable = x86; +}; + +module = { + name = ntldr; + i386_pc = loader/i386/pc/ntldr.c; + enable = i386_pc; +}; + + +module = { + name = truecrypt; + i386_pc = loader/i386/pc/truecrypt.c; + enable = i386_pc; +}; + + +module = { + name = freedos; + i386_pc = loader/i386/pc/freedos.c; + enable = i386_pc; +}; + +module = { + name = pxechain; + i386_pc = loader/i386/pc/pxechainloader.c; + enable = i386_pc; +}; + +module = { + name = multiboot2; + cppflags = "-DGRUB_USE_MULTIBOOT2"; + + common = loader/multiboot.c; + common = loader/multiboot_mbi2.c; + enable = x86; + enable = i386_xen_pvh; + enable = mips; +}; + +module = { + name = multiboot; + common = loader/multiboot.c; + x86 = loader/i386/multiboot_mbi.c; + i386_xen_pvh = loader/i386/multiboot_mbi.c; + extra_dist = loader/multiboot_elfxx.c; + enable = x86; + enable = i386_xen_pvh; +}; + +module = { + name = xen_boot; + arm64 = loader/arm64/xen_boot.c; + enable = arm64; +}; + +module = { + name = linux; + x86 = loader/i386/linux.c; + i386_xen_pvh = loader/i386/linux.c; + xen = loader/i386/xen.c; + i386_pc = lib/i386/pc/vesa_modes_table.c; + i386_xen_pvh = lib/i386/pc/vesa_modes_table.c; + mips = loader/mips/linux.c; + mips64 = loader/mips64/linux.c; + powerpc_ieee1275 = loader/powerpc/ieee1275/linux.c; + sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c; + ia64_efi = loader/ia64/efi/linux.c; + arm_coreboot = loader/arm/linux.c; + arm_efi = loader/arm64/linux.c; + arm_uboot = loader/arm/linux.c; + arm64 = loader/arm64/linux.c; + riscv32 = loader/riscv/linux.c; + riscv64 = loader/riscv/linux.c; + common = loader/linux.c; + common = lib/cmdline.c; + enable = noemu; +}; + +module = { + name = fdt; + efi = loader/efi/fdt.c; + common = lib/fdt.c; + enable = fdt; +}; + +module = { + name = xnu; + x86 = loader/xnu_resume.c; + x86 = loader/i386/xnu.c; + x86 = loader/xnu.c; + + /* Code is pretty generic but relies on RNG which + is available only on few platforms. It's not a + big deal as xnu needs ACPI anyway and we have + RNG on all platforms with ACPI. + */ + enable = i386_multiboot; + enable = i386_coreboot; + enable = i386_pc; + enable = i386_efi; + enable = x86_64_efi; +}; + +module = { + name = random; + x86 = lib/i386/random.c; + common = lib/random.c; + + i386_multiboot = kern/i386/tsc_pmtimer.c; + i386_coreboot = kern/i386/tsc_pmtimer.c; + i386_pc = kern/i386/tsc_pmtimer.c; + + enable = i386_multiboot; + enable = i386_coreboot; + enable = i386_pc; + enable = i386_efi; + enable = x86_64_efi; +}; + +module = { + name = macho; + + common = loader/macho.c; + common = loader/macho32.c; + common = loader/macho64.c; + common = loader/lzss.c; + extra_dist = loader/machoXX.c; +}; + +module = { + name = appleldr; + common = loader/efi/appleloader.c; + enable = i386_efi; + enable = x86_64_efi; +}; + +module = { + name = chain; + efi = loader/efi/chainloader.c; + i386_pc = loader/i386/pc/chainloader.c; + i386_coreboot = loader/i386/coreboot/chainloader.c; + i386_coreboot = lib/LzmaDec.c; + enable = i386_pc; + enable = i386_coreboot; + enable = efi; +}; + +module = { + name = mmap; + common = mmap/mmap.c; + x86 = mmap/i386/uppermem.c; + x86 = mmap/i386/mmap.c; + i386_xen_pvh = mmap/i386/uppermem.c; + i386_xen_pvh = mmap/i386/mmap.c; + + i386_pc = mmap/i386/pc/mmap.c; + i386_pc = mmap/i386/pc/mmap_helper.S; + + efi = mmap/efi/mmap.c; + + mips = mmap/mips/uppermem.c; + + enable = x86; + enable = i386_xen_pvh; + enable = ia64_efi; + enable = arm_efi; + enable = arm64_efi; + enable = riscv32_efi; + enable = riscv64_efi; + enable = mips; + enable = mips64_efi; +}; + +module = { + name = normal; + common = normal/main.c; + common = normal/cmdline.c; + common = normal/dyncmd.c; + common = normal/auth.c; + common = normal/autofs.c; + common = normal/color.c; + common = normal/completion.c; + common = normal/datetime.c; + common = normal/menu.c; + common = normal/menu_entry.c; + common = normal/menu_text.c; + common = normal/misc.c; + common = normal/crypto.c; + common = normal/term.c; + common = normal/context.c; + common = normal/charset.c; + common = lib/getline.c; + + common = script/main.c; + common = script/script.c; + common = script/execute.c; + common = script/function.c; + common = script/lexer.c; + common = script/argv.c; + + common = commands/menuentry.c; + + common = unidata.c; + common_nodist = grub_script.tab.c; + common_nodist = grub_script.yy.c; + common_nodist = grub_script.tab.h; + common_nodist = grub_script.yy.h; + + extra_dist = script/yylex.l; + extra_dist = script/parser.y; + + cflags = '$(CFLAGS_POSIX) -Wno-redundant-decls'; + cppflags = '$(CPPFLAGS_POSIX)'; +}; + +module = { + name = part_acorn; + common = partmap/acorn.c; +}; + +module = { + name = part_amiga; + common = partmap/amiga.c; +}; + +module = { + name = part_apple; + common = partmap/apple.c; +}; + +module = { + name = part_gpt; + common = partmap/gpt.c; +}; + +module = { + name = part_msdos; + common = partmap/msdos.c; +}; + +module = { + name = part_sun; + common = partmap/sun.c; +}; + +module = { + name = part_plan; + common = partmap/plan.c; +}; + +module = { + name = part_dvh; + common = partmap/dvh.c; +}; + +module = { + name = part_bsd; + common = partmap/bsdlabel.c; +}; + +module = { + name = part_sunpc; + common = partmap/sunpc.c; +}; + +module = { + name = part_dfly; + common = partmap/dfly.c; +}; + +module = { + name = msdospart; + common = parttool/msdospart.c; +}; + +module = { + name = at_keyboard; + common = term/at_keyboard.c; + common = term/ps2.c; + enable = x86; +}; + +module = { + name = gfxterm; + common = term/gfxterm.c; + enable = videomodules; +}; + +module = { + name = gfxterm_background; + common = term/gfxterm_background.c; +}; + +module = { + name = serial; + common = term/serial.c; + x86 = term/ns8250.c; + ieee1275 = term/ieee1275/serial.c; + mips_arc = term/arc/serial.c; + efi = term/efi/serial.c; + + enable = terminfomodule; + enable = ieee1275; + enable = mips_arc; +}; + +module = { + name = sendkey; + i386_pc = commands/i386/pc/sendkey.c; + enable = i386_pc; +}; + +module = { + name = terminfo; + common = term/terminfo.c; + common = term/tparm.c; + enable = terminfomodule; +}; + +module = { + name = usb_keyboard; + common = term/usb_keyboard.c; + enable = usb; +}; + +module = { + name = vga; + common = video/i386/pc/vga.c; + enable = i386_pc; +}; + +module = { + name = vga_text; + common = term/i386/pc/vga_text.c; + enable = i386_pc; +}; + +module = { + name = mda_text; + common = term/i386/pc/mda_text.c; + enable = i386_pc; + enable = i386_coreboot_multiboot_qemu; +}; + +module = { + name = video_cirrus; + x86 = video/cirrus.c; + enable = x86; +}; + +module = { + name = video_bochs; + x86 = video/bochs.c; + enable = x86; +}; + +module = { + name = functional_test; + common = tests/lib/functional_test.c; + common = tests/lib/test.c; + common = tests/checksums.h; + common = tests/video_checksum.c; + common = tests/fake_input.c; + common = video/capture.c; +}; + +module = { + name = exfctest; + common = tests/example_functional_test.c; +}; + +module = { + name = strtoull_test; + common = tests/strtoull_test.c; +}; + +module = { + name = setjmp_test; + common = tests/setjmp_test.c; +}; + +module = { + name = signature_test; + common = tests/signature_test.c; + common = tests/signatures.h; +}; + +module = { + name = sleep_test; + common = tests/sleep_test.c; +}; + +module = { + name = xnu_uuid_test; + common = tests/xnu_uuid_test.c; +}; + +module = { + name = pbkdf2_test; + common = tests/pbkdf2_test.c; +}; + +module = { + name = legacy_password_test; + common = tests/legacy_password_test.c; + enable = i386_pc; + enable = i386_xen_pvh; + enable = i386_efi; + enable = x86_64_efi; + enable = emu; + enable = xen; +}; + +module = { + name = div; + common = lib/division.c; + enable = no_softdiv; +}; + +module = { + name = div_test; + common = tests/div_test.c; +}; + +module = { + name = mul_test; + common = tests/mul_test.c; +}; + +module = { + name = shift_test; + common = tests/shift_test.c; +}; + +module = { + name = cmp_test; + common = tests/cmp_test.c; +}; + +module = { + name = ctz_test; + common = tests/ctz_test.c; +}; + +module = { + name = bswap_test; + common = tests/bswap_test.c; +}; + +module = { + name = videotest_checksum; + common = tests/videotest_checksum.c; +}; + +module = { + name = gfxterm_menu; + common = tests/gfxterm_menu.c; +}; + +module = { + name = cmdline_cat_test; + common = tests/cmdline_cat_test.c; +}; + +module = { + name = bitmap; + common = video/bitmap.c; +}; + +module = { + name = bitmap_scale; + common = video/bitmap_scale.c; +}; + +module = { + name = efi_gop; + efi = video/efi_gop.c; + enable = efi; +}; + +module = { + name = efi_uga; + efi = video/efi_uga.c; + enable = i386_efi; + enable = x86_64_efi; +}; + +module = { + name = jpeg; + common = video/readers/jpeg.c; +}; + +module = { + name = png; + common = video/readers/png.c; +}; + +module = { + name = tga; + common = video/readers/tga.c; +}; + +module = { + name = vbe; + common = video/i386/pc/vbe.c; + enable = i386_pc; +}; + +module = { + name = video_fb; + common = video/fb/video_fb.c; + common = video/fb/fbblit.c; + common = video/fb/fbfill.c; + common = video/fb/fbutil.c; + enable = videomodules; +}; + +module = { + name = video; + common = video/video.c; + enable = videomodules; +}; + +module = { + name = video_colors; + common = video/colors.c; +}; + +module = { + name = ieee1275_fb; + ieee1275 = video/ieee1275.c; + enable = powerpc_ieee1275; +}; + +module = { + name = sdl; + emu = video/emu/sdl.c; + enable = emu; + condition = COND_GRUB_EMU_SDL; +}; + +module = { + name = datehook; + common = hook/datehook.c; +}; + +module = { + name = net; + common = net/net.c; + common = net/dns.c; + common = net/bootp.c; + common = net/ip.c; + common = net/udp.c; + common = net/tcp.c; + common = net/icmp.c; + common = net/icmp6.c; + common = net/ethernet.c; + common = net/arp.c; + common = net/netbuff.c; +}; + +module = { + name = tftp; + common = net/tftp.c; +}; + +module = { + name = http; + common = net/http.c; +}; + +module = { + name = ofnet; + common = net/drivers/ieee1275/ofnet.c; + enable = ieee1275; +}; + +module = { + name = ubootnet; + common = net/drivers/uboot/ubootnet.c; + enable = uboot; +}; + +module = { + name = efinet; + common = net/drivers/efi/efinet.c; + enable = efi; +}; + +module = { + name = emunet; + emu = net/drivers/emu/emunet.c; + enable = emu; +}; + +module = { + name = legacycfg; + common = commands/legacycfg.c; + common = lib/legacy_parse.c; + emu = lib/i386/pc/vesa_modes_table.c; + i386_efi = lib/i386/pc/vesa_modes_table.c; + x86_64_efi = lib/i386/pc/vesa_modes_table.c; + xen = lib/i386/pc/vesa_modes_table.c; + + enable = i386_pc; + enable = i386_xen_pvh; + enable = i386_efi; + enable = x86_64_efi; + enable = emu; + enable = xen; +}; + +module = { + name = syslinuxcfg; + common = lib/syslinux_parse.c; + common = commands/syslinuxcfg.c; +}; + +module = { + name = test_blockarg; + common = tests/test_blockarg.c; +}; + +module = { + name = xzio; + common = io/xzio.c; + common = lib/xzembed/xz_dec_bcj.c; + common = lib/xzembed/xz_dec_lzma2.c; + common = lib/xzembed/xz_dec_stream.c; + cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed'; + cflags='-Wno-unreachable-code'; +}; + +module = { + name = lzopio; + common = io/lzopio.c; + common = lib/minilzo/minilzo.c; + cflags = '$(CFLAGS_POSIX) -Wno-undef -Wno-redundant-decls -Wno-error'; + cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/minilzo -DMINILZO_HAVE_CONFIG_H'; +}; + +module = { + name = testload; + common = commands/testload.c; +}; + +module = { + name = backtrace; + x86 = lib/i386/backtrace.c; + i386_xen_pvh = lib/i386/backtrace.c; + i386_xen = lib/i386/backtrace.c; + x86_64_xen = lib/i386/backtrace.c; + common = lib/backtrace.c; + enable = x86; + enable = i386_xen_pvh; + enable = i386_xen; + enable = x86_64_xen; +}; + +module = { + name = lsapm; + common = commands/i386/pc/lsapm.c; + enable = i386_pc; +}; + +module = { + name = keylayouts; + common = commands/keylayouts.c; + enable = x86; +}; + +module = { + name = priority_queue; + common = lib/priority_queue.c; +}; + +module = { + name = time; + common = commands/time.c; +}; + +module = { + name = cacheinfo; + common = commands/cacheinfo.c; + condition = COND_ENABLE_CACHE_STATS; +}; + +module = { + name = boottime; + common = commands/boottime.c; + condition = COND_ENABLE_BOOT_TIME_STATS; +}; + +module = { + name = adler32; + common = lib/adler32.c; +}; + +module = { + name = crc64; + common = lib/crc64.c; +}; + +module = { + name = mpi; + common = lib/libgcrypt-grub/mpi/mpiutil.c; + common = lib/libgcrypt-grub/mpi/mpi-bit.c; + common = lib/libgcrypt-grub/mpi/mpi-add.c; + common = lib/libgcrypt-grub/mpi/mpi-mul.c; + common = lib/libgcrypt-grub/mpi/mpi-mod.c; + common = lib/libgcrypt-grub/mpi/mpi-gcd.c; + common = lib/libgcrypt-grub/mpi/mpi-div.c; + common = lib/libgcrypt-grub/mpi/mpi-cmp.c; + common = lib/libgcrypt-grub/mpi/mpi-inv.c; + common = lib/libgcrypt-grub/mpi/mpi-pow.c; + common = lib/libgcrypt-grub/mpi/mpi-mpow.c; + common = lib/libgcrypt-grub/mpi/mpih-lshift.c; + common = lib/libgcrypt-grub/mpi/mpih-mul.c; + common = lib/libgcrypt-grub/mpi/mpih-mul1.c; + common = lib/libgcrypt-grub/mpi/mpih-mul2.c; + common = lib/libgcrypt-grub/mpi/mpih-mul3.c; + common = lib/libgcrypt-grub/mpi/mpih-add1.c; + common = lib/libgcrypt-grub/mpi/mpih-sub1.c; + common = lib/libgcrypt-grub/mpi/mpih-div.c; + common = lib/libgcrypt-grub/mpi/mpicoder.c; + common = lib/libgcrypt-grub/mpi/mpih-rshift.c; + common = lib/libgcrypt-grub/mpi/mpi-inline.c; + common = lib/libgcrypt_wrap/mem.c; + + cflags = '$(CFLAGS_GCRY) -Wno-redundant-decls -Wno-sign-compare'; + cppflags = '$(CPPFLAGS_GCRY)'; +}; + +module = { + name = all_video; + common = lib/fake_module.c; +}; + +module = { + name = gdb; + common = gdb/cstub.c; + common = gdb/gdb.c; + i386 = gdb/i386/idt.c; + i386 = gdb/i386/machdep.S; + i386 = gdb/i386/signal.c; + enable = i386; +}; + +module = { + name = testspeed; + common = commands/testspeed.c; +}; + +module = { + name = tpm; + common = commands/tpm.c; + efi = commands/efi/tpm.c; + enable = x86_64_efi; +}; + +module = { + name = tr; + common = commands/tr.c; +}; + +module = { + name = progress; + common = lib/progress.c; +}; + +module = { + name = file; + common = commands/file.c; + common = commands/file32.c; + common = commands/file64.c; + extra_dist = commands/fileXX.c; + common = loader/i386/xen_file.c; + common = loader/i386/xen_file32.c; + common = loader/i386/xen_file64.c; + extra_dist = loader/i386/xen_fileXX.c; +}; +module = { + name = rdmsr; + common = commands/i386/rdmsr.c; + enable = x86; +}; +module = { + name = wrmsr; + common = commands/i386/wrmsr.c; + enable = x86; +}; diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/boot/i386/pc/boot.S b/GRUB2/MOD_SRC/grub-2.04/grub-core/boot/i386/pc/boot.S new file mode 100644 index 0000000..bc544f7 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/boot/i386/pc/boot.S @@ -0,0 +1,545 @@ +/* -*-Asm-*- */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include + +/* + * defines for the code go here + */ + + /* Print message string */ +#define MSG(x) movw $x, %si; call LOCAL(message) +#define ERR(x) movw $x, %si; jmp LOCAL(error_message) + + .macro floppy +part_start: + +LOCAL(probe_values): + .byte 36, 18, 15, 9, 0 + +LOCAL(floppy_probe): + pushw %dx +/* + * Perform floppy probe. + */ +#ifdef __APPLE__ + LOCAL(probe_values_minus_one) = LOCAL(probe_values) - 1 + movw MACRO_DOLLAR(LOCAL(probe_values_minus_one)), %si +#else + movw MACRO_DOLLAR(LOCAL(probe_values)) - 1, %si +#endif + +LOCAL(probe_loop): + /* reset floppy controller INT 13h AH=0 */ + xorw %ax, %ax + int MACRO_DOLLAR(0x13) + + incw %si + movb (%si), %cl + + /* if number of sectors is 0, display error and die */ + testb %cl, %cl + jnz 1f + +/* + * Floppy disk probe failure. + */ + MSG(fd_probe_error_string) + jmp LOCAL(general_error) + +/* "Floppy" */ +fd_probe_error_string: .asciz "Floppy" + +1: + /* perform read */ + movw MACRO_DOLLAR(GRUB_BOOT_MACHINE_BUFFER_SEG), %bx + movw %bx, %es + xorw %bx, %bx + movw MACRO_DOLLAR(0x201), %ax + movb MACRO_DOLLAR(0), %ch + movb MACRO_DOLLAR(0), %dh + int MACRO_DOLLAR(0x13) + + /* if error, jump to "LOCAL(probe_loop)" */ + jc LOCAL(probe_loop) + + /* %cl is already the correct value! */ + movb MACRO_DOLLAR(1), %dh + movb MACRO_DOLLAR(79), %ch + + jmp LOCAL(final_init) + .endm + + .macro scratch + + /* scratch space */ +mode: + .byte 0 +disk_address_packet: +sectors: + .long 0 +heads: + .long 0 +cylinders: + .word 0 +sector_start: + .byte 0 +head_start: + .byte 0 +cylinder_start: + .word 0 + /* more space... */ + .endm + + .file "boot.S" + + .text + + /* Tell GAS to generate 16-bit instructions so that this code works + in real mode. */ + .code16 + +.globl _start, start; +_start: +start: + /* + * _start is loaded at 0x7c00 and is jumped to with CS:IP 0:0x7c00 + */ + + /* + * Beginning of the sector is compatible with the FAT/HPFS BIOS + * parameter block. + */ + + jmp LOCAL(after_BPB) + nop /* do I care about this ??? */ + +#ifdef HYBRID_BOOT + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + + nop + nop + nop + nop + nop + nop + nop + nop + + nop + nop + jmp LOCAL(after_BPB) +#else + /* + * This space is for the BIOS parameter block!!!! Don't change + * the first jump, nor start the code anywhere but right after + * this area. + */ + + .org GRUB_BOOT_MACHINE_BPB_START + .org 4 +#endif +#ifdef HYBRID_BOOT + floppy +#else + scratch +#endif + + .org GRUB_BOOT_MACHINE_BPB_END + /* + * End of BIOS parameter block. + */ + +LOCAL(kernel_address): + .word GRUB_BOOT_MACHINE_KERNEL_ADDR + +#ifndef HYBRID_BOOT + .org GRUB_BOOT_MACHINE_KERNEL_SECTOR +LOCAL(kernel_sector): + .long 1 +LOCAL(kernel_sector_high): + .long 0 +#endif + + .org GRUB_BOOT_MACHINE_BOOT_DRIVE +boot_drive: + .byte 0xff /* the disk to load kernel from */ + /* 0xff means use the boot drive */ + +LOCAL(after_BPB): + +/* general setup */ + cli /* we're not safe here! */ + + /* + * This is a workaround for buggy BIOSes which don't pass boot + * drive correctly. If GRUB is installed into a HDD, check if + * DL is masked correctly. If not, assume that the BIOS passed + * a bogus value and set DL to 0x80, since this is the only + * possible boot drive. If GRUB is installed into a floppy, + * this does nothing (only jump). + */ + .org GRUB_BOOT_MACHINE_DRIVE_CHECK +boot_drive_check: + jmp 3f /* grub-setup may overwrite this jump */ + testb $0x80, %dl + jz 2f +3: + /* Ignore %dl different from 0-0x0f and 0x80-0x8f. */ + testb $0x70, %dl + jz 1f +2: + movb $0x80, %dl +1: + /* + * ljmp to the next instruction because some bogus BIOSes + * jump to 07C0:0000 instead of 0000:7C00. + */ + ljmp $0, $real_start + +real_start: + + /* set up %ds and %ss as offset from 0 */ + xorw %ax, %ax + movw %ax, %ds + movw %ax, %ss + + /* set up the REAL stack */ + movw $GRUB_BOOT_MACHINE_STACK_SEG, %sp + + sti /* we're safe again */ + + /* + * Check if we have a forced disk reference here + */ + movb boot_drive, %al + cmpb $0xff, %al + je 1f + movb %al, %dl +1: + /* save drive reference first thing! */ + pushw %dx + + /* print a notification message on the screen */ + MSG(notification_string) + + /* set %si to the disk address packet */ + movw $disk_address_packet, %si + + /* check if LBA is supported */ + movb $0x41, %ah + movw $0x55aa, %bx + int $0x13 + + /* + * %dl may have been clobbered by INT 13, AH=41H. + * This happens, for example, with AST BIOS 1.04. + */ + popw %dx + pushw %dx + + /* use CHS if fails */ + jc LOCAL(chs_mode) + cmpw $0xaa55, %bx + jne LOCAL(chs_mode) + + andw $1, %cx + jz LOCAL(chs_mode) + +LOCAL(lba_mode): + xorw %ax, %ax + movw %ax, 4(%si) + + incw %ax + /* set the mode to non-zero */ + movb %al, -1(%si) + + /* the blocks */ + movw %ax, 2(%si) + + /* the size and the reserved byte */ + movw $0x0010, (%si) + + /* the absolute address */ + movl LOCAL(kernel_sector), %ebx + movl %ebx, 8(%si) + movl LOCAL(kernel_sector_high), %ebx + movl %ebx, 12(%si) + + /* the segment of buffer address */ + movw $GRUB_BOOT_MACHINE_BUFFER_SEG, 6(%si) + +/* + * BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory + * Call with %ah = 0x42 + * %dl = drive number + * %ds:%si = segment:offset of disk address packet + * Return: + * %al = 0x0 on success; err code on failure + */ + + movb $0x42, %ah + int $0x13 + + /* LBA read is not supported, so fallback to CHS. */ + jc LOCAL(chs_mode) + + movw $GRUB_BOOT_MACHINE_BUFFER_SEG, %bx + jmp LOCAL(copy_buffer) + +LOCAL(chs_mode): + /* + * Determine the hard disk geometry from the BIOS! + * We do this first, so that LS-120 IDE floppies work correctly. + */ + movb $8, %ah + int $0x13 + jnc LOCAL(final_init) + + popw %dx + /* + * The call failed, so maybe use the floppy probe instead. + */ + testb %dl, %dl + jnb LOCAL(floppy_probe) + + /* Nope, we definitely have a hard disk, and we're screwed. */ + ERR(hd_probe_error_string) + +LOCAL(final_init): + /* set the mode to zero */ + movzbl %dh, %eax + movb %ah, -1(%si) + + /* save number of heads */ + incw %ax + movl %eax, 4(%si) + + movzbw %cl, %dx + shlw $2, %dx + movb %ch, %al + movb %dh, %ah + + /* save number of cylinders */ + incw %ax + movw %ax, 8(%si) + + movzbw %dl, %ax + shrb $2, %al + + /* save number of sectors */ + movl %eax, (%si) + +setup_sectors: + /* load logical sector start (top half) */ + movl LOCAL(kernel_sector_high), %eax + + orl %eax, %eax + jnz LOCAL(geometry_error) + + /* load logical sector start (bottom half) */ + movl LOCAL(kernel_sector), %eax + + /* zero %edx */ + xorl %edx, %edx + + /* divide by number of sectors */ + divl (%si) + + /* save sector start */ + movb %dl, %cl + + xorw %dx, %dx /* zero %edx */ + divl 4(%si) /* divide by number of heads */ + + /* do we need too many cylinders? */ + cmpw 8(%si), %ax + jge LOCAL(geometry_error) + + /* normalize sector start (1-based) */ + incb %cl + + /* low bits of cylinder start */ + movb %al, %ch + + /* high bits of cylinder start */ + xorb %al, %al + shrw $2, %ax + orb %al, %cl + + /* save head start */ + movb %dl, %al + + /* restore %dl */ + popw %dx + + /* head start */ + movb %al, %dh + +/* + * BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory + * Call with %ah = 0x2 + * %al = number of sectors + * %ch = cylinder + * %cl = sector (bits 6-7 are high bits of "cylinder") + * %dh = head + * %dl = drive (0x80 for hard disk, 0x0 for floppy disk) + * %es:%bx = segment:offset of buffer + * Return: + * %al = 0x0 on success; err code on failure + */ + + movw $GRUB_BOOT_MACHINE_BUFFER_SEG, %bx + movw %bx, %es /* load %es segment with disk buffer */ + + xorw %bx, %bx /* %bx = 0, put it at 0 in the segment */ + movw $0x0201, %ax /* function 2 */ + int $0x13 + + jc LOCAL(read_error) + + movw %es, %bx + +LOCAL(copy_buffer): + /* + * We need to save %cx and %si because the startup code in + * kernel uses them without initializing them. + */ + pusha + pushw %ds + + movw $0x100, %cx + movw %bx, %ds + xorw %si, %si + movw $GRUB_BOOT_MACHINE_KERNEL_ADDR, %di + movw %si, %es + + cld + + rep + movsw + + popw %ds + popa + + /* boot kernel */ + jmp *(LOCAL(kernel_address)) + +/* END OF MAIN LOOP */ + +/* + * BIOS Geometry translation error (past the end of the disk geometry!). + */ +LOCAL(geometry_error): + ERR(geometry_error_string) + +/* + * Read error on the disk. + */ +LOCAL(read_error): + movw $read_error_string, %si +LOCAL(error_message): + call LOCAL(message) +LOCAL(general_error): + MSG(general_error_string) + +/* go here when you need to stop the machine hard after an error condition */ + /* tell the BIOS a boot failure, which may result in no effect */ + int $0x18 +LOCAL(stop): + jmp LOCAL(stop) + +ventoy_uuid: .ascii "XXXXXXXXXXXXXXXX" +notification_string: .asciz "VT" +geometry_error_string: .asciz "Ge" +hd_probe_error_string: .asciz "HD" +read_error_string: .asciz "Rd" +general_error_string: .asciz " Er\r\n" + + + +/* + * message: write the string pointed to by %si + * + * WARNING: trashes %si, %ax, and %bx + */ + + /* + * Use BIOS "int 10H Function 0Eh" to write character in teletype mode + * %ah = 0xe %al = character + * %bh = page %bl = foreground color (graphics modes) + */ +1: + movw $0x0001, %bx + movb $0xe, %ah + int $0x10 /* display a byte */ +LOCAL(message): + lodsb + cmpb $0, %al + jne 1b /* if not end of string, jmp to display */ + ret + + /* + * Windows NT breaks compatibility by embedding a magic + * number here. + */ + +#ifdef HYBRID_BOOT + .org 0x1b0 +LOCAL(kernel_sector): + .long 1 +LOCAL(kernel_sector_high): + .long 0 +#endif + .org GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC +nt_magic: + .long 0 + .word 0 + + /* + * This is where an MBR would go if on a hard disk. The code + * here isn't even referenced unless we're on a floppy. Kinda + * sneaky, huh? + */ + + .org GRUB_BOOT_MACHINE_PART_START + +#ifndef HYBRID_BOOT + floppy +#else + scratch +#endif + + .org GRUB_BOOT_MACHINE_PART_END + +/* the last 2 bytes in the sector 0 contain the signature */ + .word GRUB_BOOT_MACHINE_SIGNATURE diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/blocklist.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/blocklist.c new file mode 100644 index 0000000..6256f37 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/blocklist.c @@ -0,0 +1,162 @@ +/* blocklist.c - print the block list of a file */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +/* Context for grub_cmd_blocklist. */ +struct blocklist_ctx +{ + unsigned long start_sector; + unsigned num_sectors; + int num_entries; + grub_disk_addr_t part_start; +}; + +/* Helper for grub_cmd_blocklist. */ +static void +print_blocklist (grub_disk_addr_t sector, unsigned num, + unsigned offset, unsigned length, struct blocklist_ctx *ctx) +{ + if (ctx->num_entries++) + grub_printf (","); + + grub_printf ("%llu", (unsigned long long) (sector - ctx->part_start)); + if (num > 0) + grub_printf ("+%u", num); + if (offset != 0 || length != 0) + grub_printf ("[%u-%u]", offset, offset + length); +} + +/* Helper for grub_cmd_blocklist. */ +static void +read_blocklist (grub_disk_addr_t sector, unsigned offset, unsigned length, + void *data) +{ + struct blocklist_ctx *ctx = data; + + if (ctx->num_sectors > 0) + { + if (ctx->start_sector + ctx->num_sectors == sector + && offset == 0 && length >= GRUB_DISK_SECTOR_SIZE) + { + ctx->num_sectors += length >> GRUB_DISK_SECTOR_BITS; + sector += length >> GRUB_DISK_SECTOR_BITS; + length &= (GRUB_DISK_SECTOR_SIZE - 1); + } + + if (!length) + return; + print_blocklist (ctx->start_sector, ctx->num_sectors, 0, 0, ctx); + ctx->num_sectors = 0; + } + + if (offset) + { + unsigned l = length + offset; + l &= (GRUB_DISK_SECTOR_SIZE - 1); + l -= offset; + print_blocklist (sector, 0, offset, l, ctx); + length -= l; + sector++; + offset = 0; + } + + if (!length) + return; + + if (length & (GRUB_DISK_SECTOR_SIZE - 1)) + { + if (length >> GRUB_DISK_SECTOR_BITS) + { + print_blocklist (sector, length >> GRUB_DISK_SECTOR_BITS, 0, 0, ctx); + sector += length >> GRUB_DISK_SECTOR_BITS; + } + print_blocklist (sector, 0, 0, length & (GRUB_DISK_SECTOR_SIZE - 1), ctx); + } + else + { + ctx->start_sector = sector; + ctx->num_sectors = length >> GRUB_DISK_SECTOR_BITS; + } +} + +static grub_err_t +grub_cmd_blocklist (grub_command_t cmd __attribute__ ((unused)), + int argc, char **args) +{ + grub_file_t file; + char buf[GRUB_DISK_SECTOR_SIZE]; + struct blocklist_ctx ctx = { + .start_sector = 0, + .num_sectors = 0, + .num_entries = 0, + .part_start = 0 + }; + + if (argc < 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + + file = grub_file_open (args[0], GRUB_FILE_TYPE_PRINT_BLOCKLIST + | GRUB_FILE_TYPE_NO_DECOMPRESS); + if (! file) + return grub_errno; + + if (! file->device->disk) + return grub_error (GRUB_ERR_BAD_DEVICE, + "this command is available only for disk devices"); + + ctx.part_start = grub_partition_get_start (file->device->disk->partition); + + file->read_hook = read_blocklist; + file->read_hook_data = &ctx; + + while (grub_file_read (file, buf, sizeof (buf)) > 0) + ; + + if (ctx.num_sectors > 0) + print_blocklist (ctx.start_sector, ctx.num_sectors, 0, 0, &ctx); + + grub_printf("\nentry number:%d \n", ctx.num_entries); + + grub_file_close (file); + + return grub_errno; +} + +static grub_command_t cmd; + +GRUB_MOD_INIT(blocklist) +{ + cmd = grub_register_command ("blocklist", grub_cmd_blocklist, + N_("FILE"), N_("Print a block list.")); +} + +GRUB_MOD_FINI(blocklist) +{ + grub_unregister_command (cmd); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/blscfg.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/blscfg.c new file mode 100644 index 0000000..55ee2be --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/blscfg.c @@ -0,0 +1,1111 @@ +/*-*- Mode: C; c-basic-offset: 2; indent-tabs-mode: t -*-*/ + +/* bls.c - implementation of the boot loader spec */ + +/* + * GRUB -- GRand Unified Bootloader + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +#include "loadenv.h" + +#define GRUB_BLS_CONFIG_PATH "/loader/entries/" +#ifdef GRUB_MACHINE_EMU +#define GRUB_BOOT_DEVICE "/boot" +#else +#define GRUB_BOOT_DEVICE "($root)" +#endif + +struct keyval +{ + const char *key; + char *val; +}; + +static struct bls_entry *entries = NULL; + +#define FOR_BLS_ENTRIES(var) FOR_LIST_ELEMENTS (var, entries) + +static int bls_add_keyval(struct bls_entry *entry, char *key, char *val) +{ + char *k, *v; + struct keyval **kvs, *kv; + int new_n = entry->nkeyvals + 1; + + kvs = grub_realloc (entry->keyvals, new_n * sizeof (struct keyval *)); + if (!kvs) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + "couldn't find space for BLS entry"); + entry->keyvals = kvs; + + kv = grub_malloc (sizeof (struct keyval)); + if (!kv) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + "couldn't find space for BLS entry"); + + k = grub_strdup (key); + if (!k) + { + grub_free (kv); + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + "couldn't find space for BLS entry"); + } + + v = grub_strdup (val); + if (!v) + { + grub_free (k); + grub_free (kv); + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + "couldn't find space for BLS entry"); + } + + kv->key = k; + kv->val = v; + + entry->keyvals[entry->nkeyvals] = kv; + grub_dprintf("blscfg", "new keyval at %p:%s:%s\n", entry->keyvals[entry->nkeyvals], k, v); + entry->nkeyvals = new_n; + + return 0; +} + +/* Find they value of the key named by keyname. If there are allowed to be + * more than one, pass a pointer to an int set to -1 the first time, and pass + * the same pointer through each time after, and it'll return them in sorted + * order as defined in the BLS fragment file */ +static char *bls_get_val(struct bls_entry *entry, const char *keyname, int *last) +{ + int idx, start = 0; + struct keyval *kv = NULL; + + if (last) + start = *last + 1; + + for (idx = start; idx < entry->nkeyvals; idx++) { + kv = entry->keyvals[idx]; + + if (!grub_strcmp (keyname, kv->key)) + break; + } + + if (idx == entry->nkeyvals) { + if (last) + *last = -1; + return NULL; + } + + if (last) + *last = idx; + + return kv->val; +} + +#define goto_return(x) ({ ret = (x); goto finish; }) + +/* compare alpha and numeric segments of two versions */ +/* return 1: a is newer than b */ +/* 0: a and b are the same version */ +/* -1: b is newer than a */ +static int vercmp(const char * a, const char * b) +{ + char oldch1, oldch2; + char *abuf, *bbuf; + char *str1, *str2; + char * one, * two; + int rc; + int isnum; + int ret = 0; + + grub_dprintf("blscfg", "%s comparing %s and %s\n", __func__, a, b); + if (!grub_strcmp(a, b)) + return 0; + + abuf = grub_malloc(grub_strlen(a) + 1); + bbuf = grub_malloc(grub_strlen(b) + 1); + str1 = abuf; + str2 = bbuf; + grub_strcpy(str1, a); + grub_strcpy(str2, b); + + one = str1; + two = str2; + + /* loop through each version segment of str1 and str2 and compare them */ + while (*one || *two) { + while (*one && !grub_isalnum(*one) && *one != '~') one++; + while (*two && !grub_isalnum(*two) && *two != '~') two++; + + /* handle the tilde separator, it sorts before everything else */ + if (*one == '~' || *two == '~') { + if (*one != '~') goto_return (1); + if (*two != '~') goto_return (-1); + one++; + two++; + continue; + } + + /* If we ran to the end of either, we are finished with the loop */ + if (!(*one && *two)) break; + + str1 = one; + str2 = two; + + /* grab first completely alpha or completely numeric segment */ + /* leave one and two pointing to the start of the alpha or numeric */ + /* segment and walk str1 and str2 to end of segment */ + if (grub_isdigit(*str1)) { + while (*str1 && grub_isdigit(*str1)) str1++; + while (*str2 && grub_isdigit(*str2)) str2++; + isnum = 1; + } else { + while (*str1 && grub_isalpha(*str1)) str1++; + while (*str2 && grub_isalpha(*str2)) str2++; + isnum = 0; + } + + /* save character at the end of the alpha or numeric segment */ + /* so that they can be restored after the comparison */ + oldch1 = *str1; + *str1 = '\0'; + oldch2 = *str2; + *str2 = '\0'; + + /* this cannot happen, as we previously tested to make sure that */ + /* the first string has a non-null segment */ + if (one == str1) goto_return(-1); /* arbitrary */ + + /* take care of the case where the two version segments are */ + /* different types: one numeric, the other alpha (i.e. empty) */ + /* numeric segments are always newer than alpha segments */ + /* XXX See patch #60884 (and details) from bugzilla #50977. */ + if (two == str2) goto_return (isnum ? 1 : -1); + + if (isnum) { + grub_size_t onelen, twolen; + /* this used to be done by converting the digit segments */ + /* to ints using atoi() - it's changed because long */ + /* digit segments can overflow an int - this should fix that. */ + + /* throw away any leading zeros - it's a number, right? */ + while (*one == '0') one++; + while (*two == '0') two++; + + /* whichever number has more digits wins */ + onelen = grub_strlen(one); + twolen = grub_strlen(two); + if (onelen > twolen) goto_return (1); + if (twolen > onelen) goto_return (-1); + } + + /* grub_strcmp will return which one is greater - even if the two */ + /* segments are alpha or if they are numeric. don't return */ + /* if they are equal because there might be more segments to */ + /* compare */ + rc = grub_strcmp(one, two); + if (rc) goto_return (rc < 1 ? -1 : 1); + + /* restore character that was replaced by null above */ + *str1 = oldch1; + one = str1; + *str2 = oldch2; + two = str2; + } + + /* this catches the case where all numeric and alpha segments have */ + /* compared identically but the segment sepparating characters were */ + /* different */ + if ((!*one) && (!*two)) goto_return (0); + + /* whichever version still has characters left over wins */ + if (!*one) goto_return (-1); else goto_return (1); + +finish: + grub_free (abuf); + grub_free (bbuf); + return ret; +} + +/* returns name/version/release */ +/* NULL string pointer returned if nothing found */ +static void +split_package_string (char *package_string, char **name, + char **version, char **release) +{ + char *package_version, *package_release; + + /* Release */ + package_release = grub_strrchr (package_string, '-'); + + if (package_release != NULL) + *package_release++ = '\0'; + + *release = package_release; + + if (name == NULL) + { + *version = package_string; + } + else + { + /* Version */ + package_version = grub_strrchr(package_string, '-'); + + if (package_version != NULL) + *package_version++ = '\0'; + + *version = package_version; + /* Name */ + *name = package_string; + } + + /* Bubble up non-null values from release to name */ + if (name != NULL && *name == NULL) + { + *name = (*version == NULL ? *release : *version); + *version = *release; + *release = NULL; + } + if (*version == NULL) + { + *version = *release; + *release = NULL; + } +} + +static int +split_cmp(char *nvr0, char *nvr1, int has_name) +{ + int ret = 0; + char *name0, *version0, *release0; + char *name1, *version1, *release1; + + split_package_string(nvr0, has_name ? &name0 : NULL, &version0, &release0); + split_package_string(nvr1, has_name ? &name1 : NULL, &version1, &release1); + + if (has_name) + { + ret = vercmp(name0 == NULL ? "" : name0, + name1 == NULL ? "" : name1); + if (ret != 0) + return ret; + } + + ret = vercmp(version0 == NULL ? "" : version0, + version1 == NULL ? "" : version1); + if (ret != 0) + return ret; + + ret = vercmp(release0 == NULL ? "" : release0, + release1 == NULL ? "" : release1); + return ret; +} + +/* return 1: e0 is newer than e1 */ +/* 0: e0 and e1 are the same version */ +/* -1: e1 is newer than e0 */ +static int bls_cmp(const struct bls_entry *e0, const struct bls_entry *e1) +{ + char *id0, *id1; + int r; + + id0 = grub_strdup(e0->filename); + id1 = grub_strdup(e1->filename); + + r = split_cmp(id0, id1, 1); + + grub_free(id0); + grub_free(id1); + + return r; +} + +static void list_add_tail(struct bls_entry *head, struct bls_entry *item) +{ + item->next = head; + if (head->prev) + head->prev->next = item; + item->prev = head->prev; + head->prev = item; +} + +static int bls_add_entry(struct bls_entry *entry) +{ + struct bls_entry *e, *last = NULL; + int rc; + + if (!entries) { + grub_dprintf ("blscfg", "Add entry with id \"%s\"\n", entry->filename); + entries = entry; + return 0; + } + + FOR_BLS_ENTRIES(e) { + rc = bls_cmp(entry, e); + + if (!rc) + return GRUB_ERR_BAD_ARGUMENT; + + if (rc == 1) { + grub_dprintf ("blscfg", "Add entry with id \"%s\"\n", entry->filename); + list_add_tail (e, entry); + if (e == entries) { + entries = entry; + entry->prev = NULL; + } + return 0; + } + last = e; + } + + if (last) { + grub_dprintf ("blscfg", "Add entry with id \"%s\"\n", entry->filename); + last->next = entry; + entry->prev = last; + } + + return 0; +} + +struct read_entry_info { + const char *devid; + const char *dirname; + grub_file_t file; +}; + +static int read_entry ( + const char *filename, + const struct grub_dirhook_info *dirhook_info UNUSED, + void *data) +{ + grub_size_t m = 0, n, clip = 0; + int rc = 0; + char *p = NULL; + grub_file_t f = NULL; + struct bls_entry *entry; + struct read_entry_info *info = (struct read_entry_info *)data; + + grub_dprintf ("blscfg", "filename: \"%s\"\n", filename); + + n = grub_strlen (filename); + + if (info->file) + { + f = info->file; + } + else + { + if (filename[0] == '.') + return 0; + + if (n <= 5) + return 0; + + if (grub_strcmp (filename + n - 5, ".conf") != 0) + return 0; + + p = grub_xasprintf ("(%s)%s/%s", info->devid, info->dirname, filename); + + f = grub_file_open (p, GRUB_FILE_TYPE_CONFIG); + if (!f) + goto finish; + } + + entry = grub_zalloc (sizeof (*entry)); + if (!entry) + goto finish; + + if (info->file) + { + char *slash; + + if (n > 5 && !grub_strcmp (filename + n - 5, ".conf") == 0) + clip = 5; + + slash = grub_strrchr (filename, '/'); + if (!slash) + slash = grub_strrchr (filename, '\\'); + + while (*slash == '/' || *slash == '\\') + slash++; + + m = slash ? slash - filename : 0; + } + else + { + m = 0; + clip = 5; + } + n -= m; + + entry->filename = grub_strndup(filename + m, n - clip); + if (!entry->filename) + goto finish; + + entry->filename[n - 5] = '\0'; + + for (;;) + { + char *buf; + char *separator; + + buf = grub_file_getline (f); + if (!buf) + break; + + while (buf && buf[0] && (buf[0] == ' ' || buf[0] == '\t')) + buf++; + if (buf[0] == '#') + continue; + + separator = grub_strchr (buf, ' '); + + if (!separator) + separator = grub_strchr (buf, '\t'); + + if (!separator || separator[1] == '\0') + { + grub_free (buf); + break; + } + + separator[0] = '\0'; + + do { + separator++; + } while (*separator == ' ' || *separator == '\t'); + + rc = bls_add_keyval (entry, buf, separator); + grub_free (buf); + if (rc < 0) + break; + } + + if (!rc) + bls_add_entry(entry); + +finish: + if (p) + grub_free (p); + + if (f) + grub_file_close (f); + + return 0; +} + +static grub_envblk_t saved_env = NULL; + +static int UNUSED +save_var (const char *name, const char *value, void *whitelist UNUSED) +{ + const char *val = grub_env_get (name); + grub_dprintf("blscfg", "saving \"%s\"\n", name); + + if (val) + grub_envblk_set (saved_env, name, value); + + return 0; +} + +static int UNUSED +unset_var (const char *name, const char *value UNUSED, void *whitelist) +{ + grub_dprintf("blscfg", "restoring \"%s\"\n", name); + if (! whitelist) + { + grub_env_unset (name); + return 0; + } + + if (test_whitelist_membership (name, + (const grub_env_whitelist_t *) whitelist)) + grub_env_unset (name); + + return 0; +} + +static char **bls_make_list (struct bls_entry *entry, const char *key, int *num) +{ + int last = -1; + char *val; + + int nlist = 0; + char **list = NULL; + + list = grub_malloc (sizeof (char *)); + if (!list) + return NULL; + list[0] = NULL; + + while (1) + { + char **new; + + val = bls_get_val (entry, key, &last); + if (!val) + break; + + new = grub_realloc (list, (nlist + 2) * sizeof (char *)); + if (!new) + break; + + list = new; + list[nlist++] = val; + list[nlist] = NULL; + } + + if (num) + *num = nlist; + + return list; +} + +static char *field_append(bool is_var, char *buffer, char *start, char *end) +{ + char *temp = grub_strndup(start, end - start + 1); + const char *field = temp; + + if (is_var) { + field = grub_env_get (temp); + if (!field) + return buffer; + } + + if (!buffer) { + buffer = grub_strdup(field); + if (!buffer) + return NULL; + } else { + buffer = grub_realloc (buffer, grub_strlen(buffer) + grub_strlen(field)); + if (!buffer) + return NULL; + + grub_stpcpy (buffer + grub_strlen(buffer), field); + } + + return buffer; +} + +static char *expand_val(char *value) +{ + char *buffer = NULL; + char *start = value; + char *end = value; + bool is_var = false; + + if (!value) + return NULL; + + while (*value) { + if (*value == '$') { + if (start != end) { + buffer = field_append(is_var, buffer, start, end); + if (!buffer) + return NULL; + } + + is_var = true; + start = value + 1; + } else if (is_var) { + if (!grub_isalnum(*value) && *value != '_') { + buffer = field_append(is_var, buffer, start, end); + is_var = false; + start = value; + } + } + + end = value; + value++; + } + + if (start != end) { + buffer = field_append(is_var, buffer, start, end); + if (!buffer) + return NULL; + } + + return buffer; +} + +static char **early_initrd_list (const char *initrd) +{ + int nlist = 0; + char **list = NULL; + char *separator; + + while ((separator = grub_strchr (initrd, ' '))) + { + list = grub_realloc (list, (nlist + 2) * sizeof (char *)); + if (!list) + return NULL; + + list[nlist++] = grub_strndup(initrd, separator - initrd); + list[nlist] = NULL; + initrd = separator + 1; + } + + list = grub_realloc (list, (nlist + 2) * sizeof (char *)); + if (!list) + return NULL; + + list[nlist++] = grub_strndup(initrd, grub_strlen(initrd)); + list[nlist] = NULL; + + return list; +} + +static void create_entry (struct bls_entry *entry) +{ + int argc = 0; + const char **argv = NULL; + + char *title = NULL; + char *clinux = NULL; + char *options = NULL; + char **initrds = NULL; + char *initrd = NULL; + const char *early_initrd = NULL; + char **early_initrds = NULL; + char *initrd_prefix = NULL; + char *id = entry->filename; + char *dotconf = id; + char *hotkey = NULL; + + char *users = NULL; + char **classes = NULL; + + char **args = NULL; + + char *src = NULL; + int bootlen; + const char *bootdev; + int i, index; + + grub_dprintf("blscfg", "%s got here\n", __func__); + clinux = bls_get_val (entry, "linux", NULL); + if (!clinux) + { + grub_dprintf ("blscfg", "Skipping file %s with no 'linux' key.\n", entry->filename); + goto finish; + } + + bootdev = grub_env_get("ventoy_bls_bootdev"); + if (!bootdev) + { + bootdev = GRUB_BOOT_DEVICE; + } + bootlen = grub_strlen(bootdev) + 2;//space and \0 + + /* + * strip the ".conf" off the end before we make it our "id" field. + */ + do + { + dotconf = grub_strstr(dotconf, ".conf"); + } while (dotconf != NULL && dotconf[5] != '\0'); + if (dotconf) + dotconf[0] = '\0'; + + title = bls_get_val (entry, "title", NULL); + options = expand_val (bls_get_val (entry, "options", NULL)); + + if (!options) + options = expand_val ((char *)grub_env_get("default_kernelopts")); + + initrds = bls_make_list (entry, "initrd", NULL); + + hotkey = bls_get_val (entry, "grub_hotkey", NULL); + users = expand_val (bls_get_val (entry, "grub_users", NULL)); + classes = bls_make_list (entry, "grub_class", NULL); + args = bls_make_list (entry, "grub_arg", &argc); + + argc += 1; + argv = grub_malloc ((argc + 1) * sizeof (char *)); + argv[0] = title ? title : clinux; + for (i = 1; i < argc; i++) + argv[i] = args[i-1]; + argv[argc] = NULL; + + early_initrd = grub_env_get("early_initrd"); + + grub_dprintf ("blscfg", "adding menu entry for \"%s\" with id \"%s\"\n", + title, id); + if (early_initrd) + { + early_initrds = early_initrd_list(early_initrd); + if (!early_initrds) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + goto finish; + } + + if (initrds != NULL && initrds[0] != NULL) + { + initrd_prefix = grub_strrchr (initrds[0], '/'); + initrd_prefix = grub_strndup(initrds[0], initrd_prefix - initrds[0] + 1); + } + else + { + initrd_prefix = grub_strrchr (clinux, '/'); + initrd_prefix = grub_strndup(clinux, initrd_prefix - clinux + 1); + } + + if (!initrd_prefix) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + goto finish; + } + } + + if (early_initrds || initrds) + { + int initrd_size = sizeof ("initrd"); + char *tmp; + + for (i = 0; early_initrds != NULL && early_initrds[i] != NULL; i++) + initrd_size += bootlen \ + + grub_strlen(initrd_prefix) \ + + grub_strlen (early_initrds[i]) + 1; + + for (i = 0; initrds != NULL && initrds[i] != NULL; i++) + initrd_size += bootlen \ + + grub_strlen (initrds[i]) + 1; + initrd_size += 1; + + initrd = grub_malloc (initrd_size); + if (!initrd) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + goto finish; + } + + + tmp = grub_stpcpy(initrd, "initrd"); + for (i = 0; early_initrds != NULL && early_initrds[i] != NULL; i++) + { + grub_dprintf ("blscfg", "adding early initrd %s\n", early_initrds[i]); + tmp = grub_stpcpy (tmp, " "); + tmp = grub_stpcpy (tmp, bootdev); + tmp = grub_stpcpy (tmp, initrd_prefix); + tmp = grub_stpcpy (tmp, early_initrds[i]); + grub_free(early_initrds[i]); + } + + for (i = 0; initrds != NULL && initrds[i] != NULL; i++) + { + grub_dprintf ("blscfg", "adding initrd %s\n", initrds[i]); + tmp = grub_stpcpy (tmp, " "); + tmp = grub_stpcpy (tmp, bootdev); + tmp = grub_stpcpy (tmp, initrds[i]); + } + tmp = grub_stpcpy (tmp, "\n"); + } + + src = grub_xasprintf ("load_video\n" + "set gfxpayload=keep\n" + "insmod gzio\n" + "linux %s%s%s%s\n" + "%s", + bootdev, clinux, options ? " " : "", options ? options : "", + initrd ? initrd : ""); + + grub_normal_add_menu_entry (argc, argv, classes, id, users, hotkey, NULL, src, 0, &index, entry); + grub_dprintf ("blscfg", "Added entry %d id:\"%s\"\n", index, id); + +finish: + grub_free (initrd); + grub_free (initrd_prefix); + grub_free (early_initrds); + grub_free (initrds); + grub_free (options); + grub_free (classes); + grub_free (args); + grub_free (argv); + grub_free (src); +} + +struct find_entry_info { + const char *dirname; + const char *devid; + grub_device_t dev; + grub_fs_t fs; +}; + +/* + * info: the filesystem object the file is on. + */ +static int find_entry (struct find_entry_info *info) +{ + struct read_entry_info read_entry_info; + grub_fs_t blsdir_fs = NULL; + grub_device_t blsdir_dev = NULL; + const char *blsdir = info->dirname; + int fallback = 0; + int r = 0; + + if (!blsdir) { + blsdir = grub_env_get ("blsdir"); + if (!blsdir) + blsdir = GRUB_BLS_CONFIG_PATH; + } + + read_entry_info.file = NULL; + read_entry_info.dirname = blsdir; + + grub_dprintf ("blscfg", "scanning blsdir: %s\n", blsdir); + + blsdir_dev = info->dev; + blsdir_fs = info->fs; + read_entry_info.devid = info->devid; + +read_fallback: + r = blsdir_fs->fs_dir (blsdir_dev, read_entry_info.dirname, read_entry, + &read_entry_info); + if (r != 0) { + grub_dprintf ("blscfg", "read_entry returned error\n"); + grub_err_t e; + do + { + e = grub_error_pop(); + } while (e); + } + + if (r && !info->dirname && !fallback) { + read_entry_info.dirname = "/boot" GRUB_BLS_CONFIG_PATH; + grub_dprintf ("blscfg", "Entries weren't found in %s, fallback to %s\n", + blsdir, read_entry_info.dirname); + fallback = 1; + goto read_fallback; + } + + return 0; +} + +static grub_err_t +bls_load_entries (const char *path) +{ + grub_size_t len; + grub_fs_t fs; + grub_device_t dev; + static grub_err_t r; + const char *devid = NULL; + char *blsdir = NULL; + struct find_entry_info info = { + .dev = NULL, + .fs = NULL, + .dirname = NULL, + }; + struct read_entry_info rei = { + .devid = NULL, + .dirname = NULL, + }; + + if (path) { + len = grub_strlen (path); + if (grub_strcmp (path + len - 5, ".conf") == 0) { + rei.file = grub_file_open (path, GRUB_FILE_TYPE_CONFIG); + if (!rei.file) + return grub_errno; + /* + * read_entry() closes the file + */ + return read_entry(path, NULL, &rei); + } else if (path[0] == '(') { + devid = path + 1; + + blsdir = grub_strchr (path, ')'); + if (!blsdir) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Filepath isn't correct")); + + *blsdir = '\0'; + blsdir = blsdir + 1; + } + } + + if (!devid) { +#ifdef GRUB_MACHINE_EMU + devid = "host"; +#elif defined(GRUB_MACHINE_EFI) + devid = grub_env_get ("root"); +#else + devid = grub_env_get ("boot"); + if (!devid) + { + devid = grub_env_get ("root"); + } +#endif + if (!devid) + return grub_error (GRUB_ERR_FILE_NOT_FOUND, + N_("variable `%s' isn't set"), "boot"); + } + + grub_dprintf ("blscfg", "opening %s\n", devid); + dev = grub_device_open (devid); + if (!dev) + return grub_errno; + + grub_dprintf ("blscfg", "probing fs\n"); + fs = grub_fs_probe (dev); + if (!fs) + { + r = grub_errno; + goto finish; + } + + info.dirname = blsdir; + info.devid = devid; + info.dev = dev; + info.fs = fs; + find_entry(&info); + +finish: + if (dev) + grub_device_close (dev); + + return r; +} + +static bool +is_default_entry(const char *def_entry, struct bls_entry *entry, int idx) +{ + const char *title; + int def_idx; + + if (!def_entry) + return false; + + if (grub_strcmp(def_entry, entry->filename) == 0) + return true; + + title = bls_get_val(entry, "title", NULL); + + if (title && grub_strcmp(def_entry, title) == 0) + return true; + + def_idx = (int)grub_strtol(def_entry, NULL, 0); + if (grub_errno == GRUB_ERR_BAD_NUMBER) { + grub_errno = GRUB_ERR_NONE; + return false; + } + + if (def_idx == idx) + return true; + + return false; +} + +static grub_err_t +bls_create_entries (bool show_default, bool show_non_default, char *entry_id) +{ + const char *def_entry = NULL; + struct bls_entry *entry = NULL; + int idx = 0; + + def_entry = grub_env_get("default"); + + grub_dprintf ("blscfg", "%s Creating entries from bls\n", __func__); + FOR_BLS_ENTRIES(entry) { + if (entry->visible) { + idx++; + continue; + } + + if ((show_default && is_default_entry(def_entry, entry, idx)) || + (show_non_default && !is_default_entry(def_entry, entry, idx)) || + (entry_id && grub_strcmp(entry_id, entry->filename) == 0)) { + create_entry(entry); + entry->visible = 1; + } + idx++; + } + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_blscfg (grub_extcmd_context_t ctxt UNUSED, + int argc, char **args) +{ + grub_err_t r; + char *path = NULL; + char *entry_id = NULL; + bool show_default = true; + bool show_non_default = true; + + if (argc == 1) { + if (grub_strcmp (args[0], "default") == 0) { + show_non_default = false; + } else if (grub_strcmp (args[0], "non-default") == 0) { + show_default = false; + } else if (args[0][0] == '(') { + path = args[0]; + } else { + entry_id = args[0]; + show_default = false; + show_non_default = false; + } + } + + r = bls_load_entries(path); + if (r) + return r; + + return bls_create_entries(show_default, show_non_default, entry_id); +} + +static grub_extcmd_t cmd; +static grub_extcmd_t oldcmd; + +GRUB_MOD_INIT(blscfg) +{ + grub_dprintf("blscfg", "%s got here\n", __func__); + cmd = grub_register_extcmd ("blscfg", + grub_cmd_blscfg, + 0, + NULL, + N_("Import Boot Loader Specification snippets."), + NULL); + oldcmd = grub_register_extcmd ("bls_import", + grub_cmd_blscfg, + 0, + NULL, + N_("Import Boot Loader Specification snippets."), + NULL); +} + +GRUB_MOD_FINI(blscfg) +{ + grub_unregister_extcmd (cmd); + grub_unregister_extcmd (oldcmd); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/efi/fwload.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/efi/fwload.c new file mode 100644 index 0000000..6adaf6a --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/efi/fwload.c @@ -0,0 +1,205 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2022 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +static grub_efi_guid_t loaded_image_guid = GRUB_EFI_LOADED_IMAGE_GUID; + +static grub_efi_status_t +grub_efi_connect_all (void) +{ + grub_efi_status_t status; + grub_efi_uintn_t handle_count; + grub_efi_handle_t *handle_buffer; + grub_efi_uintn_t index; + grub_efi_boot_services_t *b; + grub_dprintf ("efi", "Connecting ...\n"); + b = grub_efi_system_table->boot_services; + status = efi_call_5 (b->locate_handle_buffer, + GRUB_EFI_ALL_HANDLES, NULL, NULL, + &handle_count, &handle_buffer); + + if (status != GRUB_EFI_SUCCESS) + return status; + + for (index = 0; index < handle_count; index++) + { + status = efi_call_4 (b->connect_controller, + handle_buffer[index], NULL, NULL, 1); + } + + if (handle_buffer) + { + efi_call_1 (b->free_pool, handle_buffer); + } + return GRUB_EFI_SUCCESS; +} + +static grub_err_t +grub_efi_load_driver (grub_size_t size, void *boot_image, int connect) +{ + grub_efi_status_t status; + grub_efi_handle_t driver_handle; + grub_efi_boot_services_t *b; + grub_efi_loaded_image_t *loaded_image; + + b = grub_efi_system_table->boot_services; + + status = efi_call_6 (b->load_image, 0, grub_efi_image_handle, NULL, + boot_image, size, &driver_handle); + if (status != GRUB_EFI_SUCCESS) + { + if (status == GRUB_EFI_OUT_OF_RESOURCES) + grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of resources"); + else + grub_error (GRUB_ERR_BAD_OS, "cannot load image"); + goto fail; + } + loaded_image = grub_efi_get_loaded_image (driver_handle); + if (! loaded_image) + { + grub_error (GRUB_ERR_BAD_OS, "no loaded image available"); + goto fail; + } + grub_dprintf ("efi", "Registering loaded image\n"); + status = efi_call_3 (b->handle_protocol, driver_handle, + &loaded_image_guid, (void **)&loaded_image); + if (status != GRUB_EFI_SUCCESS) + { + grub_error (GRUB_ERR_BAD_OS, "not a dirver"); + goto fail; + } + grub_dprintf ("efi", "StartImage: %p\n", boot_image); + status = efi_call_3 (b->start_image, driver_handle, NULL, NULL); + if (status != GRUB_EFI_SUCCESS) + { + grub_error (GRUB_ERR_BAD_OS, "StartImage failed"); + goto fail; + } + if (connect) + { + status = grub_efi_connect_all (); + if (status != GRUB_EFI_SUCCESS) + { + grub_error (GRUB_ERR_BAD_OS, "cannot connect controllers\n"); + goto fail; + } + } + grub_dprintf ("efi", "Driver installed\n"); + return 0; +fail: + return grub_errno; +} + +static const struct grub_arg_option options_fwload[] = +{ + {"nc", 'n', 0, N_("Loads the driver, but does not connect the driver."), 0, 0}, + {0, 0, 0, 0, 0, 0} +}; + +static grub_err_t +grub_cmd_fwload (grub_extcmd_context_t ctxt, int argc, char **args) +{ + struct grub_arg_list *state = ctxt->state; + int connect = 1; + grub_file_t file = 0; + grub_efi_boot_services_t *b; + grub_efi_status_t status; + grub_efi_uintn_t pages = 0; + grub_ssize_t size; + grub_efi_physical_address_t address; + void *boot_image = 0; + + b = grub_efi_system_table->boot_services; + if (argc != 1) + goto fail; + + file = grub_file_open (args[0], GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE); + if (! file) + goto fail; + size = grub_file_size (file); + if (!size) + { + grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), args[0]); + goto fail; + } + pages = (((grub_efi_uintn_t) size + ((1 << 12) - 1)) >> 12); + status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ANY_PAGES, + GRUB_EFI_LOADER_CODE, pages, &address); + if (status != GRUB_EFI_SUCCESS) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + goto fail; + } + boot_image = (void *) ((grub_addr_t) address); + if (grub_file_read (file, boot_image, size) != size) + { + if (grub_errno == GRUB_ERR_NONE) + grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), args[0]); + goto fail; + } + grub_file_close (file); + if (state[0].set) + connect = 0; + if (grub_efi_load_driver (size, boot_image, connect)) + goto fail; + return GRUB_ERR_NONE; +fail: + if (file) + grub_file_close (file); + if (address) + efi_call_2 (b->free_pages, address, pages); + return grub_errno; +} + +static grub_err_t +grub_cmd_fwconnect (grub_extcmd_context_t ctxt __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) +{ + grub_efi_connect_all (); + return GRUB_ERR_NONE; +} + +static grub_extcmd_t cmd_fwload, cmd_fwconnect; + +GRUB_MOD_INIT(fwload) +{ + cmd_fwload = grub_register_extcmd ("fwload", grub_cmd_fwload, 0, N_("FILE"), + N_("Install UEFI driver."), options_fwload); + cmd_fwconnect = grub_register_extcmd ("fwconnect", grub_cmd_fwconnect, 0, + NULL, N_("Connect drivers."), 0); +} + +GRUB_MOD_FINI(fwload) +{ + grub_unregister_extcmd (cmd_fwload); + grub_unregister_extcmd (cmd_fwconnect); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/efi/smbios.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/efi/smbios.c new file mode 100644 index 0000000..75202d5 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/efi/smbios.c @@ -0,0 +1,61 @@ +/* smbios.c - get smbios tables. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2019 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include + +struct grub_smbios_eps * +grub_machine_smbios_get_eps (void) +{ + unsigned i; + static grub_efi_packed_guid_t smbios_guid = GRUB_EFI_SMBIOS_TABLE_GUID; + + for (i = 0; i < grub_efi_system_table->num_table_entries; i++) + { + grub_efi_packed_guid_t *guid = + &grub_efi_system_table->configuration_table[i].vendor_guid; + + if (! grub_memcmp (guid, &smbios_guid, sizeof (grub_efi_packed_guid_t))) + return (struct grub_smbios_eps *) + grub_efi_system_table->configuration_table[i].vendor_table; + } + + return 0; +} + +struct grub_smbios_eps3 * +grub_machine_smbios_get_eps3 (void) +{ + unsigned i; + static grub_efi_packed_guid_t smbios3_guid = GRUB_EFI_SMBIOS3_TABLE_GUID; + + for (i = 0; i < grub_efi_system_table->num_table_entries; i++) + { + grub_efi_packed_guid_t *guid = + &grub_efi_system_table->configuration_table[i].vendor_guid; + + if (! grub_memcmp (guid, &smbios3_guid, sizeof (grub_efi_packed_guid_t))) + return (struct grub_smbios_eps3 *) + grub_efi_system_table->configuration_table[i].vendor_table; + } + + return 0; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/hashsum.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/hashsum.c new file mode 100644 index 0000000..f38c18c --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/hashsum.c @@ -0,0 +1,351 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +static const struct grub_arg_option options[] = { + {"hash", 'h', 0, N_("Specify hash to use."), N_("HASH"), ARG_TYPE_STRING}, + {"check", 'c', 0, N_("Check hashes of files with hash list FILE."), + N_("FILE"), ARG_TYPE_STRING}, + {"prefix", 'p', 0, N_("Base directory for hash list."), N_("DIR"), + ARG_TYPE_STRING}, + {"keep-going", 'k', 0, N_("Don't stop after first error."), 0, 0}, + {"uncompress", 'u', 0, N_("Uncompress file before checksumming."), 0, 0}, + {0, 0, 0, 0, 0, 0} +}; + +static struct { const char *name; const char *hashname; } aliases[] = + { + {"sha256sum", "sha256"}, + {"sha512sum", "sha512"}, + {"sha1sum", "sha1"}, + {"md5sum", "md5"}, + {"crc", "crc32"}, + }; + +static inline int +hextoval (char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return -1; +} + +static grub_err_t +hash_file (grub_file_t file, const gcry_md_spec_t *hash, void *result) +{ + int progress = 0; + grub_uint64_t ro = 0; + grub_uint64_t div = 0; + grub_uint64_t total = 0; + void *context; + grub_uint8_t *readbuf; +#define BUF_SIZE 1024 * 1024 + readbuf = grub_malloc (BUF_SIZE); + if (!readbuf) + return grub_errno; + context = grub_zalloc (hash->contextsize); + if (!readbuf || !context) + goto fail; + + if (file->size > 16 * 1024 * 1024) + progress = 1; + + hash->init (context); + while (1) + { + grub_ssize_t r; + r = grub_file_read (file, readbuf, BUF_SIZE); + if (r < 0) + goto fail; + if (r == 0) + break; + hash->write (context, readbuf, r); + if (progress) + { + total += r; + div = grub_divmod64(total * 100, (grub_uint64_t)file->size, &ro); + grub_printf("\rCalculating %s %d%% ", hash->name, (int)div); + grub_refresh(); + } + } + hash->final (context); + grub_memcpy (result, hash->read (context), hash->mdlen); + + grub_free (readbuf); + grub_free (context); + if (progress) + { + grub_printf("\rCalculating %s 100%% \n\r\n", hash->name); + grub_refresh(); + } + return GRUB_ERR_NONE; + + fail: + grub_free (readbuf); + grub_free (context); + return grub_errno; +} + +static grub_err_t +check_list (const gcry_md_spec_t *hash, const char *hashfilename, + const char *prefix, int keep, int uncompress) +{ + grub_file_t hashlist, file; + char *buf = NULL; + grub_uint8_t expected[GRUB_CRYPTO_MAX_MDLEN]; + grub_uint8_t actual[GRUB_CRYPTO_MAX_MDLEN]; + grub_err_t err; + unsigned i; + unsigned unread = 0, mismatch = 0; + + if (hash->mdlen > GRUB_CRYPTO_MAX_MDLEN) + return grub_error (GRUB_ERR_BUG, "mdlen is too long"); + + hashlist = grub_file_open (hashfilename, GRUB_FILE_TYPE_HASHLIST); + if (!hashlist) + return grub_errno; + + while (grub_free (buf), (buf = grub_file_getline (hashlist))) + { + const char *p = buf; + while (grub_isspace (p[0])) + p++; + for (i = 0; i < hash->mdlen; i++) + { + int high, low; + high = hextoval (*p++); + low = hextoval (*p++); + if (high < 0 || low < 0) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list"); + expected[i] = (high << 4) | low; + } + if ((p[0] != ' ' && p[0] != '\t') || (p[1] != ' ' && p[1] != '\t')) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list"); + p += 2; + if (prefix) + { + char *filename; + + filename = grub_xasprintf ("%s/%s", prefix, p); + if (!filename) + return grub_errno; + file = grub_file_open (filename, GRUB_FILE_TYPE_TO_HASH + | (!uncompress ? GRUB_FILE_TYPE_NO_DECOMPRESS + : GRUB_FILE_TYPE_NONE)); + grub_free (filename); + } + else + file = grub_file_open (p, GRUB_FILE_TYPE_TO_HASH + | (!uncompress ? GRUB_FILE_TYPE_NO_DECOMPRESS + : GRUB_FILE_TYPE_NONE)); + if (!file) + { + grub_file_close (hashlist); + grub_free (buf); + return grub_errno; + } + err = hash_file (file, hash, actual); + grub_file_close (file); + if (err) + { + grub_printf_ (N_("%s: READ ERROR\n"), p); + if (!keep) + { + grub_file_close (hashlist); + grub_free (buf); + return err; + } + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + unread++; + continue; + } + if (grub_crypto_memcmp (expected, actual, hash->mdlen) != 0) + { + grub_printf_ (N_("%s: HASH MISMATCH\n"), p); + if (!keep) + { + grub_file_close (hashlist); + grub_free (buf); + return grub_error (GRUB_ERR_TEST_FAILURE, + "hash of '%s' mismatches", p); + } + mismatch++; + continue; + } + grub_printf_ (N_("%s: OK\n"), p); + } + if (mismatch || unread) + return grub_error (GRUB_ERR_TEST_FAILURE, + "%d files couldn't be read and hash " + "of %d files mismatches", unread, mismatch); + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_hashsum (struct grub_extcmd_context *ctxt, + int argc, char **args) +{ + struct grub_arg_list *state = ctxt->state; + const char *hashname = NULL; + const char *prefix = NULL; + const gcry_md_spec_t *hash; + unsigned i; + int keep = state[3].set; + int uncompress = state[4].set; + unsigned unread = 0; + int len = 0; + char hashsum[256]; + + for (i = 0; i < ARRAY_SIZE (aliases); i++) + if (grub_strcmp (ctxt->extcmd->cmd->name, aliases[i].name) == 0) + hashname = aliases[i].hashname; + if (state[0].set) + hashname = state[0].arg; + + if (!hashname) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no hash specified"); + + hash = grub_crypto_lookup_md_by_name (hashname); + if (!hash) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown hash"); + + if (hash->mdlen > GRUB_CRYPTO_MAX_MDLEN) + return grub_error (GRUB_ERR_BUG, "mdlen is too long"); + + if (state[2].set) + prefix = state[2].arg; + + if (state[1].set) + { + if (argc != 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "--check is incompatible with file list"); + return check_list (hash, state[1].arg, prefix, keep, uncompress); + } + + for (i = 0; i < (unsigned) argc; i++) + { + GRUB_PROPERLY_ALIGNED_ARRAY (result, GRUB_CRYPTO_MAX_MDLEN); + grub_file_t file; + grub_err_t err; + unsigned j; + int vlnk = 0; + file = grub_file_open (args[i], GRUB_FILE_TYPE_TO_HASH + | (!uncompress ? GRUB_FILE_TYPE_NO_DECOMPRESS + : GRUB_FILE_TYPE_NONE)); + if (!file) + { + if (!keep) + return grub_errno; + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + unread++; + continue; + } + vlnk = file->vlnk; + err = hash_file (file, hash, result); + grub_file_close (file); + if (err) + { + if (!keep) + return err; + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + unread++; + continue; + } + for (j = 0; j < hash->mdlen; j++) + { + grub_printf ("%02x", ((grub_uint8_t *) result)[j]); + len += grub_snprintf(hashsum + len, sizeof(hashsum) - len, "%02x", ((grub_uint8_t *) result)[j]); + } + grub_printf (" %s\n", vlnk ? grub_file_get_vlnk(args[i], NULL) : args[i]); + grub_env_set("VT_LAST_CHECK_SUM", hashsum); + } + + if (unread) + return grub_error (GRUB_ERR_TEST_FAILURE, "%d files couldn't be read", + unread); + return GRUB_ERR_NONE; +} + +static grub_extcmd_t cmd, cmd_md5, cmd_sha1, cmd_sha256, cmd_sha512, cmd_crc; + +GRUB_MOD_INIT(hashsum) +{ + cmd = grub_register_extcmd ("hashsum", grub_cmd_hashsum, 0, + N_("-h HASH [-c FILE [-p PREFIX]] " + "[FILE1 [FILE2 ...]]"), + /* TRANSLATORS: "hash checksum" is just to + be a bit more precise, you can treat it as + just "hash". */ + N_("Compute or check hash checksum."), + options); + cmd_md5 = grub_register_extcmd ("md5sum", grub_cmd_hashsum, 0, + N_("[-c FILE [-p PREFIX]] " + "[FILE1 [FILE2 ...]]"), + N_("Compute or check hash checksum."), + options); + cmd_sha1 = grub_register_extcmd ("sha1sum", grub_cmd_hashsum, 0, + N_("[-c FILE [-p PREFIX]] " + "[FILE1 [FILE2 ...]]"), + N_("Compute or check hash checksum."), + options); + cmd_sha256 = grub_register_extcmd ("sha256sum", grub_cmd_hashsum, 0, + N_("[-c FILE [-p PREFIX]] " + "[FILE1 [FILE2 ...]]"), + N_("Compute or check hash checksum."), + options); + cmd_sha512 = grub_register_extcmd ("sha512sum", grub_cmd_hashsum, 0, + N_("[-c FILE [-p PREFIX]] " + "[FILE1 [FILE2 ...]]"), + N_("Compute or check hash checksum."), + options); + + cmd_crc = grub_register_extcmd ("crc", grub_cmd_hashsum, 0, + N_("[-c FILE [-p PREFIX]] " + "[FILE1 [FILE2 ...]]"), + N_("Compute or check hash checksum."), + options); +} + +GRUB_MOD_FINI(hashsum) +{ + grub_unregister_extcmd (cmd); + grub_unregister_extcmd (cmd_md5); + grub_unregister_extcmd (cmd_sha1); + grub_unregister_extcmd (cmd_sha256); + grub_unregister_extcmd (cmd_sha512); + grub_unregister_extcmd (cmd_crc); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/i386/pc/smbios.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/i386/pc/smbios.c new file mode 100644 index 0000000..069d663 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/i386/pc/smbios.c @@ -0,0 +1,52 @@ +/* smbios.c - get smbios tables. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2019 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include + +struct grub_smbios_eps * +grub_machine_smbios_get_eps (void) +{ + grub_uint8_t *ptr; + + grub_dprintf ("smbios", "Looking for SMBIOS EPS. Scanning BIOS\n"); + + for (ptr = (grub_uint8_t *) 0xf0000; ptr < (grub_uint8_t *) 0x100000; ptr += 16) + if (grub_memcmp (ptr, "_SM_", 4) == 0 + && grub_byte_checksum (ptr, sizeof (struct grub_smbios_eps)) == 0) + return (struct grub_smbios_eps *) ptr; + + return 0; +} + +struct grub_smbios_eps3 * +grub_machine_smbios_get_eps3 (void) +{ + grub_uint8_t *ptr; + + grub_dprintf ("smbios", "Looking for SMBIOS3 EPS. Scanning BIOS\n"); + + for (ptr = (grub_uint8_t *) 0xf0000; ptr < (grub_uint8_t *) 0x100000; ptr += 16) + if (grub_memcmp (ptr, "_SM3_", 5) == 0 + && grub_byte_checksum (ptr, sizeof (struct grub_smbios_eps3)) == 0) + return (struct grub_smbios_eps3 *) ptr; + + return 0; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/legacycfg.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/legacycfg.c new file mode 100644 index 0000000..891eac5 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/legacycfg.c @@ -0,0 +1,894 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2000, 2001, 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +/* Helper for legacy_file. */ +static grub_err_t +legacy_file_getline (char **line, int cont __attribute__ ((unused)), + void *data __attribute__ ((unused))) +{ + *line = 0; + return GRUB_ERR_NONE; +} + +static grub_err_t +legacy_file (const char *filename) +{ + grub_file_t file; + char *entryname = NULL, *entrysrc = NULL; + grub_menu_t menu; + char *suffix = grub_strdup (""); + + if (!suffix) + return grub_errno; + + file = grub_file_open (filename, GRUB_FILE_TYPE_CONFIG); + if (! file) + { + grub_free (suffix); + return grub_errno; + } + + menu = grub_env_get_menu (); + if (! menu) + { + menu = grub_zalloc (sizeof (*menu)); + if (! menu) + { + grub_free (suffix); + return grub_errno; + } + + grub_env_set_menu (menu); + } + + while (1) + { + char *buf = grub_file_getline (file); + char *parsed = NULL; + + if (!buf && grub_errno) + { + grub_file_close (file); + grub_free (suffix); + return grub_errno; + } + + if (!buf) + break; + + { + char *oldname = NULL; + char *newsuffix; + char *ptr; + + for (ptr = buf; *ptr && grub_isspace (*ptr); ptr++); + + oldname = entryname; + parsed = grub_legacy_parse (ptr, &entryname, &newsuffix); + grub_free (buf); + buf = NULL; + if (newsuffix) + { + char *t; + + t = suffix; + suffix = grub_realloc (suffix, grub_strlen (suffix) + + grub_strlen (newsuffix) + 1); + if (!suffix) + { + grub_free (t); + grub_free (entrysrc); + grub_free (parsed); + grub_free (newsuffix); + grub_free (suffix); + return grub_errno; + } + grub_memcpy (suffix + grub_strlen (suffix), newsuffix, + grub_strlen (newsuffix) + 1); + grub_free (newsuffix); + newsuffix = NULL; + } + if (oldname != entryname && oldname) + { + const char **args = grub_malloc (sizeof (args[0])); + if (!args) + { + grub_file_close (file); + return grub_errno; + } + args[0] = oldname; + grub_normal_add_menu_entry (1, args, NULL, NULL, "legacy", + NULL, NULL, + entrysrc, 0, NULL, NULL); + grub_free (args); + entrysrc[0] = 0; + grub_free (oldname); + } + } + + if (parsed && !entryname) + { + grub_normal_parse_line (parsed, legacy_file_getline, NULL); + grub_print_error (); + grub_free (parsed); + parsed = NULL; + } + else if (parsed) + { + if (!entrysrc) + entrysrc = parsed; + else + { + char *t; + + t = entrysrc; + entrysrc = grub_realloc (entrysrc, grub_strlen (entrysrc) + + grub_strlen (parsed) + 1); + if (!entrysrc) + { + grub_free (t); + grub_free (parsed); + grub_free (suffix); + return grub_errno; + } + grub_memcpy (entrysrc + grub_strlen (entrysrc), parsed, + grub_strlen (parsed) + 1); + grub_free (parsed); + parsed = NULL; + } + } + } + grub_file_close (file); + + if (entryname) + { + const char **args = grub_malloc (sizeof (args[0])); + if (!args) + { + grub_file_close (file); + grub_free (suffix); + grub_free (entrysrc); + return grub_errno; + } + args[0] = entryname; + grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, + NULL, NULL, entrysrc, 0, NULL, + NULL); + grub_free (args); + } + + grub_normal_parse_line (suffix, legacy_file_getline, NULL); + grub_print_error (); + grub_free (suffix); + grub_free (entrysrc); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_legacy_source (struct grub_command *cmd, + int argc, char **args) +{ + int new_env, extractor; + grub_err_t ret; + + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + + extractor = (cmd->name[0] == 'e'); + new_env = (cmd->name[extractor ? (sizeof ("extract_legacy_entries_") - 1) + : (sizeof ("legacy_") - 1)] == 'c'); + + if (new_env) + grub_cls (); + + if (new_env && !extractor) + grub_env_context_open (); + if (extractor) + grub_env_extractor_open (!new_env); + + ret = legacy_file (args[0]); + + if (new_env) + { + grub_menu_t menu; + menu = grub_env_get_menu (); + if (menu && menu->size) + grub_show_menu (menu, 1, 0); + if (!extractor) + grub_env_context_close (); + } + if (extractor) + grub_env_extractor_close (!new_env); + + return ret; +} + +static enum + { + GUESS_IT, LINUX, MULTIBOOT, KFREEBSD, KNETBSD, KOPENBSD + } kernel_type; + +static grub_err_t +grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)), + int argc, char **args) +{ + int i; +#ifdef TODO + int no_mem_option = 0; +#endif + struct grub_command *cmd; + char **cutargs; + int cutargc; + grub_err_t err = GRUB_ERR_NONE; + + for (i = 0; i < 2; i++) + { + /* FIXME: really support this. */ + if (argc >= 1 && grub_strcmp (args[0], "--no-mem-option") == 0) + { +#ifdef TODO + no_mem_option = 1; +#endif + argc--; + args++; + continue; + } + + /* linux16 handles both zImages and bzImages. */ + if (argc >= 1 && (grub_strcmp (args[0], "--type=linux") == 0 + || grub_strcmp (args[0], "--type=biglinux") == 0)) + { + kernel_type = LINUX; + argc--; + args++; + continue; + } + + if (argc >= 1 && grub_strcmp (args[0], "--type=multiboot") == 0) + { + kernel_type = MULTIBOOT; + argc--; + args++; + continue; + } + + if (argc >= 1 && grub_strcmp (args[0], "--type=freebsd") == 0) + { + kernel_type = KFREEBSD; + argc--; + args++; + continue; + } + + if (argc >= 1 && grub_strcmp (args[0], "--type=openbsd") == 0) + { + kernel_type = KOPENBSD; + argc--; + args++; + continue; + } + + if (argc >= 1 && grub_strcmp (args[0], "--type=netbsd") == 0) + { + kernel_type = KNETBSD; + argc--; + args++; + continue; + } + } + + if (argc < 2) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + + cutargs = grub_malloc (sizeof (cutargs[0]) * (argc - 1)); + if (!cutargs) + return grub_errno; + cutargc = argc - 1; + grub_memcpy (cutargs + 1, args + 2, sizeof (cutargs[0]) * (argc - 2)); + cutargs[0] = args[0]; + + do + { + /* First try Linux. */ + if (kernel_type == GUESS_IT || kernel_type == LINUX) + { +#ifdef GRUB_MACHINE_PCBIOS + cmd = grub_command_find ("linux16"); +#else + cmd = grub_command_find ("linux"); +#endif + if (cmd) + { + if (!(cmd->func) (cmd, cutargc, cutargs)) + { + kernel_type = LINUX; + goto out; + } + } + grub_errno = GRUB_ERR_NONE; + } + + /* Then multiboot. */ + if (kernel_type == GUESS_IT || kernel_type == MULTIBOOT) + { + cmd = grub_command_find ("multiboot"); + if (cmd) + { + if (!(cmd->func) (cmd, argc, args)) + { + kernel_type = MULTIBOOT; + goto out; + } + } + grub_errno = GRUB_ERR_NONE; + } + + { + int bsd_device = -1; + int bsd_slice = -1; + int bsd_part = -1; + { + grub_device_t dev; + const char *hdbiasstr; + int hdbias = 0; + hdbiasstr = grub_env_get ("legacy_hdbias"); + if (hdbiasstr) + { + hdbias = grub_strtoul (hdbiasstr, 0, 0); + grub_errno = GRUB_ERR_NONE; + } + dev = grub_device_open (0); + if (dev && dev->disk + && dev->disk->dev->id == GRUB_DISK_DEVICE_BIOSDISK_ID + && dev->disk->id >= 0x80 && dev->disk->id <= 0x90) + { + struct grub_partition *part = dev->disk->partition; + bsd_device = dev->disk->id - 0x80 - hdbias; + if (part && (grub_strcmp (part->partmap->name, "netbsd") == 0 + || grub_strcmp (part->partmap->name, "openbsd") == 0 + || grub_strcmp (part->partmap->name, "bsd") == 0)) + { + bsd_part = part->number; + part = part->parent; + } + if (part && grub_strcmp (part->partmap->name, "msdos") == 0) + bsd_slice = part->number; + } + if (dev) + grub_device_close (dev); + } + + /* k*BSD didn't really work well with grub-legacy. */ + if (kernel_type == GUESS_IT || kernel_type == KFREEBSD) + { + char buf[sizeof("adXXXXXXXXXXXXsXXXXXXXXXXXXYYY")]; + if (bsd_device != -1) + { + if (bsd_slice != -1 && bsd_part != -1) + grub_snprintf(buf, sizeof(buf), "ad%ds%d%c", bsd_device, + bsd_slice, 'a' + bsd_part); + else if (bsd_slice != -1) + grub_snprintf(buf, sizeof(buf), "ad%ds%d", bsd_device, + bsd_slice); + else + grub_snprintf(buf, sizeof(buf), "ad%d", bsd_device); + grub_env_set ("kFreeBSD.vfs.root.mountfrom", buf); + } + else + grub_env_unset ("kFreeBSD.vfs.root.mountfrom"); + cmd = grub_command_find ("kfreebsd"); + if (cmd) + { + if (!(cmd->func) (cmd, cutargc, cutargs)) + { + kernel_type = KFREEBSD; + goto out; + } + } + grub_errno = GRUB_ERR_NONE; + } + { + char **bsdargs; + int bsdargc; + char bsddevname[sizeof ("wdXXXXXXXXXXXXY")]; + int found = 0; + + if (bsd_device == -1) + { + bsdargs = cutargs; + bsdargc = cutargc; + } + else + { + char rbuf[3] = "-r"; + bsdargc = cutargc + 2; + bsdargs = grub_malloc (sizeof (bsdargs[0]) * bsdargc); + if (!bsdargs) + { + err = grub_errno; + goto out; + } + grub_memcpy (bsdargs, args, argc * sizeof (bsdargs[0])); + bsdargs[argc] = rbuf; + bsdargs[argc + 1] = bsddevname; + grub_snprintf (bsddevname, sizeof (bsddevname), + "wd%d%c", bsd_device, + bsd_part != -1 ? bsd_part + 'a' : 'c'); + } + if (kernel_type == GUESS_IT || kernel_type == KNETBSD) + { + cmd = grub_command_find ("knetbsd"); + if (cmd) + { + if (!(cmd->func) (cmd, bsdargc, bsdargs)) + { + kernel_type = KNETBSD; + found = 1; + goto free_bsdargs; + } + } + grub_errno = GRUB_ERR_NONE; + } + if (kernel_type == GUESS_IT || kernel_type == KOPENBSD) + { + cmd = grub_command_find ("kopenbsd"); + if (cmd) + { + if (!(cmd->func) (cmd, bsdargc, bsdargs)) + { + kernel_type = KOPENBSD; + found = 1; + goto free_bsdargs; + } + } + grub_errno = GRUB_ERR_NONE; + } + +free_bsdargs: + if (bsdargs != cutargs) + grub_free (bsdargs); + if (found) + goto out; + } + } + } + while (0); + + err = grub_error (GRUB_ERR_BAD_OS, "couldn't load file %s", + args[0]); +out: + grub_free (cutargs); + return err; +} + +static grub_err_t +grub_cmd_legacy_initrd (struct grub_command *mycmd __attribute__ ((unused)), + int argc, char **args) +{ + struct grub_command *cmd; + + if (kernel_type == LINUX) + { +#ifdef GRUB_MACHINE_PCBIOS + cmd = grub_command_find ("initrd16"); +#else + cmd = grub_command_find ("initrd"); +#endif + if (!cmd) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("can't find command `%s'"), +#ifdef GRUB_MACHINE_PCBIOS + "initrd16" +#else + "initrd" +#endif + ); + + return cmd->func (cmd, argc ? 1 : 0, args); + } + if (kernel_type == MULTIBOOT) + { + cmd = grub_command_find ("module"); + if (!cmd) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("can't find command `%s'"), + "module"); + + return cmd->func (cmd, argc, args); + } + + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("you need to load the kernel first")); +} + +static grub_err_t +grub_cmd_legacy_initrdnounzip (struct grub_command *mycmd __attribute__ ((unused)), + int argc, char **args) +{ + struct grub_command *cmd; + + if (kernel_type == LINUX) + { + cmd = grub_command_find ("initrd16"); + if (!cmd) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("can't find command `%s'"), + "initrd16"); + + return cmd->func (cmd, argc, args); + } + if (kernel_type == MULTIBOOT) + { + char **newargs; + grub_err_t err; + char nounzipbuf[10] = "--nounzip"; + + cmd = grub_command_find ("module"); + if (!cmd) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("can't find command `%s'"), + "module"); + + newargs = grub_malloc ((argc + 1) * sizeof (newargs[0])); + if (!newargs) + return grub_errno; + grub_memcpy (newargs + 1, args, argc * sizeof (newargs[0])); + newargs[0] = nounzipbuf; + + err = cmd->func (cmd, argc + 1, newargs); + grub_free (newargs); + return err; + } + + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("you need to load the kernel first")); +} + +static grub_err_t +check_password_deny (const char *user __attribute__ ((unused)), + const char *entered __attribute__ ((unused)), + void *password __attribute__ ((unused))) +{ + return GRUB_ACCESS_DENIED; +} + +#define MD5_HASHLEN 16 + +struct legacy_md5_password +{ + grub_uint8_t *salt; + int saltlen; + grub_uint8_t hash[MD5_HASHLEN]; +}; + +static int +check_password_md5_real (const char *entered, + struct legacy_md5_password *pw) +{ + grub_size_t enteredlen = grub_strlen (entered); + unsigned char alt_result[MD5_HASHLEN]; + unsigned char *digest; + grub_uint8_t *ctx; + grub_size_t i; + int ret; + + ctx = grub_zalloc (GRUB_MD_MD5->contextsize); + if (!ctx) + return 0; + + GRUB_MD_MD5->init (ctx); + GRUB_MD_MD5->write (ctx, entered, enteredlen); + GRUB_MD_MD5->write (ctx, pw->salt + 3, pw->saltlen - 3); + GRUB_MD_MD5->write (ctx, entered, enteredlen); + digest = GRUB_MD_MD5->read (ctx); + GRUB_MD_MD5->final (ctx); + grub_memcpy (alt_result, digest, MD5_HASHLEN); + + GRUB_MD_MD5->init (ctx); + GRUB_MD_MD5->write (ctx, entered, enteredlen); + GRUB_MD_MD5->write (ctx, pw->salt, pw->saltlen); /* include the $1$ header */ + for (i = enteredlen; i > 16; i -= 16) + GRUB_MD_MD5->write (ctx, alt_result, 16); + GRUB_MD_MD5->write (ctx, alt_result, i); + + for (i = enteredlen; i > 0; i >>= 1) + GRUB_MD_MD5->write (ctx, entered + ((i & 1) ? enteredlen : 0), 1); + digest = GRUB_MD_MD5->read (ctx); + GRUB_MD_MD5->final (ctx); + + for (i = 0; i < 1000; i++) + { + grub_memcpy (alt_result, digest, 16); + + GRUB_MD_MD5->init (ctx); + if ((i & 1) != 0) + GRUB_MD_MD5->write (ctx, entered, enteredlen); + else + GRUB_MD_MD5->write (ctx, alt_result, 16); + + if (i % 3 != 0) + GRUB_MD_MD5->write (ctx, pw->salt + 3, pw->saltlen - 3); + + if (i % 7 != 0) + GRUB_MD_MD5->write (ctx, entered, enteredlen); + + if ((i & 1) != 0) + GRUB_MD_MD5->write (ctx, alt_result, 16); + else + GRUB_MD_MD5->write (ctx, entered, enteredlen); + digest = GRUB_MD_MD5->read (ctx); + GRUB_MD_MD5->final (ctx); + } + + ret = (grub_crypto_memcmp (digest, pw->hash, MD5_HASHLEN) == 0); + grub_free (ctx); + return ret; +} + +static grub_err_t +check_password_md5 (const char *user, + const char *entered, + void *password) +{ + if (!check_password_md5_real (entered, password)) + return GRUB_ACCESS_DENIED; + + grub_auth_authenticate (user); + + return GRUB_ERR_NONE; +} + +static inline int +ib64t (char c) +{ + if (c == '.') + return 0; + if (c == '/') + return 1; + if (c >= '0' && c <= '9') + return c - '0' + 2; + if (c >= 'A' && c <= 'Z') + return c - 'A' + 12; + if (c >= 'a' && c <= 'z') + return c - 'a' + 38; + return -1; +} + +static struct legacy_md5_password * +parse_legacy_md5 (int argc, char **args) +{ + const char *salt, *saltend; + struct legacy_md5_password *pw = NULL; + int i; + const char *p; + + if (grub_memcmp (args[0], "--md5", sizeof ("--md5")) != 0) + goto fail; + if (argc == 1) + goto fail; + if (grub_strlen(args[1]) <= 3) + goto fail; + salt = args[1]; + saltend = grub_strchr (salt + 3, '$'); + if (!saltend) + goto fail; + pw = grub_malloc (sizeof (*pw)); + if (!pw) + goto fail; + + p = saltend + 1; + for (i = 0; i < 5; i++) + { + int n; + grub_uint32_t w = 0; + + for (n = 0; n < 4; n++) + { + int ww = ib64t(*p++); + if (ww == -1) + goto fail; + w |= ww << (n * 6); + } + pw->hash[i == 4 ? 5 : 12+i] = w & 0xff; + pw->hash[6+i] = (w >> 8) & 0xff; + pw->hash[i] = (w >> 16) & 0xff; + } + { + int n; + grub_uint32_t w = 0; + for (n = 0; n < 2; n++) + { + int ww = ib64t(*p++); + if (ww == -1) + goto fail; + w |= ww << (6 * n); + } + if (w >= 0x100) + goto fail; + pw->hash[11] = w; + } + + pw->saltlen = saltend - salt; + pw->salt = (grub_uint8_t *) grub_strndup (salt, pw->saltlen); + if (!pw->salt) + goto fail; + + return pw; + + fail: + grub_free (pw); + return NULL; +} + +static grub_err_t +grub_cmd_legacy_password (struct grub_command *mycmd __attribute__ ((unused)), + int argc, char **args) +{ + struct legacy_md5_password *pw = NULL; + + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); + if (args[0][0] != '-' || args[0][1] != '-') + return grub_normal_set_password ("legacy", args[0]); + + pw = parse_legacy_md5 (argc, args); + + if (pw) + return grub_auth_register_authentication ("legacy", check_password_md5, pw); + else + /* This is to imitate minor difference between grub-legacy in GRUB2. + If 2 password commands are executed in a row and second one fails + on GRUB2 the password of first one is used, whereas in grub-legacy + authenthication is denied. In case of no password command was executed + early both versions deny any access. */ + return grub_auth_register_authentication ("legacy", check_password_deny, + NULL); +} + +int +grub_legacy_check_md5_password (int argc, char **args, + char *entered) +{ + struct legacy_md5_password *pw = NULL; + int ret; + + if (args[0][0] != '-' || args[0][1] != '-') + { + char correct[GRUB_AUTH_MAX_PASSLEN]; + + grub_memset (correct, 0, sizeof (correct)); + grub_strncpy (correct, args[0], sizeof (correct)); + + return grub_crypto_memcmp (entered, correct, GRUB_AUTH_MAX_PASSLEN) == 0; + } + + pw = parse_legacy_md5 (argc, args); + + if (!pw) + return 0; + + ret = check_password_md5_real (entered, pw); + grub_free (pw); + return ret; +} + +static grub_err_t +grub_cmd_legacy_check_password (struct grub_command *mycmd __attribute__ ((unused)), + int argc, char **args) +{ + char entered[GRUB_AUTH_MAX_PASSLEN]; + + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); + grub_puts_ (N_("Enter password: ")); + if (!grub_password_get (entered, GRUB_AUTH_MAX_PASSLEN)) + return GRUB_ACCESS_DENIED; + + if (!grub_legacy_check_md5_password (argc, args, + entered)) + return GRUB_ACCESS_DENIED; + + return GRUB_ERR_NONE; +} + +static grub_command_t cmd_source, cmd_configfile; +static grub_command_t cmd_source_extract, cmd_configfile_extract; +static grub_command_t cmd_kernel, cmd_initrd, cmd_initrdnounzip; +static grub_command_t cmd_password, cmd_check_password; + +GRUB_MOD_INIT(legacycfg) +{ + cmd_source + = grub_register_command ("legacy_source", + grub_cmd_legacy_source, + N_("FILE"), + /* TRANSLATORS: "legacy config" means + "config as used by grub-legacy". */ + N_("Parse legacy config in same context")); + cmd_configfile + = grub_register_command ("legacy_configfile", + grub_cmd_legacy_source, + N_("FILE"), + N_("Parse legacy config in new context")); + cmd_source_extract + = grub_register_command ("extract_legacy_entries_source", + grub_cmd_legacy_source, + N_("FILE"), + N_("Parse legacy config in same context taking only menu entries")); + cmd_configfile_extract + = grub_register_command ("extract_legacy_entries_configfile", + grub_cmd_legacy_source, + N_("FILE"), + N_("Parse legacy config in new context taking only menu entries")); + + cmd_kernel = grub_register_command ("legacy_kernel", + grub_cmd_legacy_kernel, + N_("[--no-mem-option] [--type=TYPE] FILE [ARG ...]"), + N_("Simulate grub-legacy `kernel' command")); + + cmd_initrd = grub_register_command ("legacy_initrd", + grub_cmd_legacy_initrd, + N_("FILE [ARG ...]"), + N_("Simulate grub-legacy `initrd' command")); + cmd_initrdnounzip = grub_register_command ("legacy_initrd_nounzip", + grub_cmd_legacy_initrdnounzip, + N_("FILE [ARG ...]"), + N_("Simulate grub-legacy `modulenounzip' command")); + + cmd_password = grub_register_command ("legacy_password", + grub_cmd_legacy_password, + N_("[--md5] PASSWD [FILE]"), + N_("Simulate grub-legacy `password' command")); + + cmd_check_password = grub_register_command ("legacy_check_password", + grub_cmd_legacy_check_password, + N_("[--md5] PASSWD [FILE]"), + N_("Simulate grub-legacy `password' command in menu entry mode")); + +} + +GRUB_MOD_FINI(legacycfg) +{ + grub_unregister_command (cmd_source); + grub_unregister_command (cmd_configfile); + grub_unregister_command (cmd_source_extract); + grub_unregister_command (cmd_configfile_extract); + + grub_unregister_command (cmd_kernel); + grub_unregister_command (cmd_initrd); + grub_unregister_command (cmd_initrdnounzip); + + grub_unregister_command (cmd_password); + grub_unregister_command (cmd_check_password); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/loadenv.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/loadenv.c new file mode 100644 index 0000000..163b9a0 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/loadenv.c @@ -0,0 +1,397 @@ +/* loadenv.c - command to load/save environment variable. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "loadenv.h" + +GRUB_MOD_LICENSE ("GPLv3+"); + +static const struct grub_arg_option options[] = + { + /* TRANSLATORS: This option is used to override default filename + for loading and storing environment. */ + {"file", 'f', 0, N_("Specify filename."), 0, ARG_TYPE_PATHNAME}, + {"skip-sig", 's', 0, + N_("Skip signature-checking of the environment file."), 0, ARG_TYPE_NONE}, + {0, 0, 0, 0, 0, 0} + }; + +/* Opens 'filename' with compression filters disabled. Optionally disables the + PUBKEY filter (that insists upon properly signed files) as well. PUBKEY + filter is restored before the function returns. */ +static grub_file_t +open_envblk_file (char *filename, + enum grub_file_type type) +{ + grub_file_t file; + char *buf = 0; + + if (! filename) + { + const char *prefix; + int len; + + prefix = grub_env_get ("prefix"); + if (! prefix) + { + grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix"); + return 0; + } + + len = grub_strlen (prefix); + buf = grub_malloc (len + 1 + sizeof (GRUB_ENVBLK_DEFCFG)); + if (! buf) + return 0; + filename = buf; + + grub_strcpy (filename, prefix); + filename[len] = '/'; + grub_strcpy (filename + len + 1, GRUB_ENVBLK_DEFCFG); + } + + file = grub_file_open (filename, type); + + grub_free (buf); + return file; +} + +static grub_err_t +grub_cmd_load_env (grub_extcmd_context_t ctxt, int argc, char **args) +{ + struct grub_arg_list *state = ctxt->state; + grub_file_t file; + grub_envblk_t envblk; + grub_env_whitelist_t whitelist; + + whitelist.len = argc; + whitelist.list = args; + + /* state[0] is the -f flag; state[1] is the --skip-sig flag */ + file = open_envblk_file ((state[0].set) ? state[0].arg : 0, + GRUB_FILE_TYPE_LOADENV + | (state[1].set + ? GRUB_FILE_TYPE_SKIP_SIGNATURE : GRUB_FILE_TYPE_NONE)); + if (! file) + return grub_errno; + + envblk = read_envblk_file (file); + if (! envblk) + goto fail; + + /* argc > 0 indicates caller provided a whitelist of variables to read. */ + grub_envblk_iterate (envblk, argc > 0 ? &whitelist : 0, set_var); + grub_envblk_close (envblk); + + fail: + grub_file_close (file); + return grub_errno; +} + +/* Print all variables in current context. */ +static int +print_var (const char *name, const char *value, + void *hook_data __attribute__ ((unused))) +{ + grub_printf ("%s=%s\n", name, value); + return 0; +} + +static grub_err_t +grub_cmd_list_env (grub_extcmd_context_t ctxt, + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) +{ + struct grub_arg_list *state = ctxt->state; + grub_file_t file; + grub_envblk_t envblk; + + file = open_envblk_file ((state[0].set) ? state[0].arg : 0, + GRUB_FILE_TYPE_LOADENV + | (state[1].set + ? GRUB_FILE_TYPE_SKIP_SIGNATURE : GRUB_FILE_TYPE_NONE)); + if (! file) + return grub_errno; + + envblk = read_envblk_file (file); + if (! envblk) + goto fail; + + grub_envblk_iterate (envblk, NULL, print_var); + grub_envblk_close (envblk); + + fail: + grub_file_close (file); + return grub_errno; +} + +/* Used to maintain a variable length of blocklists internally. */ +struct blocklist +{ + grub_disk_addr_t sector; + unsigned offset; + unsigned length; + struct blocklist *next; +}; + +static void +free_blocklists (struct blocklist *p) +{ + struct blocklist *q; + + for (; p; p = q) + { + q = p->next; + grub_free (p); + } +} + +static grub_err_t +check_blocklists (grub_envblk_t envblk, struct blocklist *blocklists, + grub_file_t file) +{ + grub_size_t total_length; + grub_size_t index; + grub_disk_t disk; + grub_disk_addr_t part_start; + struct blocklist *p; + char *buf; + + /* Sanity checks. */ + total_length = 0; + for (p = blocklists; p; p = p->next) + { + struct blocklist *q; + /* Check if any pair of blocks overlap. */ + for (q = p->next; q; q = q->next) + { + grub_disk_addr_t s1, s2; + grub_disk_addr_t e1, e2; + + s1 = p->sector; + e1 = s1 + ((p->length + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); + + s2 = q->sector; + e2 = s2 + ((q->length + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); + + if (s1 < e2 && s2 < e1) + { + /* This might be actually valid, but it is unbelievable that + any filesystem makes such a silly allocation. */ + return grub_error (GRUB_ERR_BAD_FS, "malformed file"); + } + } + + total_length += p->length; + } + + if (total_length != grub_file_size (file)) + { + /* Maybe sparse, unallocated sectors. No way in GRUB. */ + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "sparse file not allowed"); + } + + /* One more sanity check. Re-read all sectors by blocklists, and compare + those with the data read via a file. */ + disk = file->device->disk; + + part_start = grub_partition_get_start (disk->partition); + + buf = grub_envblk_buffer (envblk); + char *blockbuf = NULL; + grub_size_t blockbuf_len = 0; + for (p = blocklists, index = 0; p; index += p->length, p = p->next) + { + if (p->length > blockbuf_len) + { + grub_free (blockbuf); + blockbuf_len = 2 * p->length; + blockbuf = grub_malloc (blockbuf_len); + if (!blockbuf) + return grub_errno; + } + + if (grub_disk_read (disk, p->sector - part_start, + p->offset, p->length, blockbuf)) + return grub_errno; + + if (grub_memcmp (buf + index, blockbuf, p->length) != 0) + return grub_error (GRUB_ERR_FILE_READ_ERROR, "invalid blocklist"); + } + + return GRUB_ERR_NONE; +} + +static int +write_blocklists (grub_envblk_t envblk, struct blocklist *blocklists, + grub_file_t file) +{ + char *buf; + grub_disk_t disk; + grub_disk_addr_t part_start; + struct blocklist *p; + grub_size_t index; + + buf = grub_envblk_buffer (envblk); + disk = file->device->disk; + part_start = grub_partition_get_start (disk->partition); + + index = 0; + for (p = blocklists; p; index += p->length, p = p->next) + { + if (grub_disk_write (disk, p->sector - part_start, + p->offset, p->length, buf + index)) + return 0; + } + + return 1; +} + +/* Context for grub_cmd_save_env. */ +struct grub_cmd_save_env_ctx +{ + struct blocklist *head, *tail; +}; + +/* Store blocklists in a linked list. */ +static void +save_env_read_hook (grub_disk_addr_t sector, unsigned offset, unsigned length, + void *data) +{ + struct grub_cmd_save_env_ctx *ctx = data; + struct blocklist *block; + + block = grub_malloc (sizeof (*block)); + if (! block) + return; + + block->sector = sector; + block->offset = offset; + block->length = length; + + /* Slightly complicated, because the list should be FIFO. */ + block->next = 0; + if (ctx->tail) + ctx->tail->next = block; + ctx->tail = block; + if (! ctx->head) + ctx->head = block; +} + +static grub_err_t +grub_cmd_save_env (grub_extcmd_context_t ctxt, int argc, char **args) +{ + struct grub_arg_list *state = ctxt->state; + grub_file_t file; + grub_envblk_t envblk; + struct grub_cmd_save_env_ctx ctx = { + .head = 0, + .tail = 0 + }; + + if (! argc) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no variable is specified"); + + file = open_envblk_file ((state[0].set) ? state[0].arg : 0, + GRUB_FILE_TYPE_SAVEENV + | GRUB_FILE_TYPE_SKIP_SIGNATURE); + if (! file) + return grub_errno; + + if (! file->device->disk) + { + grub_file_close (file); + return grub_error (GRUB_ERR_BAD_DEVICE, "disk device required"); + } + + file->read_hook = save_env_read_hook; + file->read_hook_data = &ctx; + envblk = read_envblk_file (file); + file->read_hook = 0; + if (! envblk) + goto fail; + + if (check_blocklists (envblk, ctx.head, file)) + goto fail; + + while (argc) + { + const char *value; + + value = grub_env_get (args[0]); + if (value) + { + if (! grub_envblk_set (envblk, args[0], value)) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "environment block too small"); + goto fail; + } + } + else + grub_envblk_delete (envblk, args[0]); + + argc--; + args++; + } + + write_blocklists (envblk, ctx.head, file); + + fail: + if (envblk) + grub_envblk_close (envblk); + free_blocklists (ctx.head); + grub_file_close (file); + return grub_errno; +} + +static grub_extcmd_t cmd_load, cmd_list, cmd_save; + +GRUB_MOD_INIT(loadenv) +{ + cmd_load = + grub_register_extcmd ("load_env", grub_cmd_load_env, 0, + N_("[-f FILE] [-s|--skip-sig] [variable_name_to_whitelist] [...]"), + N_("Load variables from environment block file."), + options); + cmd_list = + grub_register_extcmd ("list_env", grub_cmd_list_env, 0, N_("[-f FILE]"), + N_("List variables from environment block file."), + options); + cmd_save = + grub_register_extcmd ("save_env", grub_cmd_save_env, 0, + N_("[-f FILE] variable_name [...]"), + N_("Save variables to environment block file."), + options); +} + +GRUB_MOD_FINI(loadenv) +{ + grub_unregister_extcmd (cmd_load); + grub_unregister_extcmd (cmd_list); + grub_unregister_extcmd (cmd_save); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/loadenv.h b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/loadenv.h new file mode 100644 index 0000000..952f461 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/loadenv.h @@ -0,0 +1,93 @@ +/* loadenv.c - command to load/save environment variable. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +static grub_envblk_t UNUSED +read_envblk_file (grub_file_t file) +{ + grub_off_t offset = 0; + char *buf; + grub_size_t size = grub_file_size (file); + grub_envblk_t envblk; + + buf = grub_malloc (size); + if (! buf) + return 0; + + while (size > 0) + { + grub_ssize_t ret; + + ret = grub_file_read (file, buf + offset, size); + if (ret <= 0) + { + grub_free (buf); + return 0; + } + + size -= ret; + offset += ret; + } + + envblk = grub_envblk_open (buf, offset); + if (! envblk) + { + grub_free (buf); + grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid environment block"); + return 0; + } + + return envblk; +} + +struct grub_env_whitelist +{ + grub_size_t len; + char **list; +}; +typedef struct grub_env_whitelist grub_env_whitelist_t; + +static int UNUSED +test_whitelist_membership (const char* name, + const grub_env_whitelist_t* whitelist) +{ + grub_size_t i; + + for (i = 0; i < whitelist->len; i++) + if (grub_strcmp (name, whitelist->list[i]) == 0) + return 1; /* found it */ + + return 0; /* not found */ +} + +/* Helper for grub_cmd_load_env. */ +static int UNUSED +set_var (const char *name, const char *value, void *whitelist) +{ + if (! whitelist) + { + grub_env_set (name, value); + return 0; + } + + if (test_whitelist_membership (name, + (const grub_env_whitelist_t *) whitelist)) + grub_env_set (name, value); + + return 0; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/menuentry.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/menuentry.c new file mode 100644 index 0000000..9faf2be --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/menuentry.c @@ -0,0 +1,349 @@ +/* menuentry.c - menuentry command */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +static const struct grub_arg_option options[] = + { + {"class", 1, GRUB_ARG_OPTION_REPEATABLE, + N_("Menu entry type."), N_("STRING"), ARG_TYPE_STRING}, + {"users", 2, 0, + N_("List of users allowed to boot this entry."), N_("USERNAME[,USERNAME]"), + ARG_TYPE_STRING}, + {"hotkey", 3, 0, + N_("Keyboard key to quickly boot this entry."), N_("KEYBOARD_KEY"), ARG_TYPE_STRING}, + {"source", 4, 0, + N_("Use STRING as menu entry body."), N_("STRING"), ARG_TYPE_STRING}, + {"id", 0, 0, N_("Menu entry identifier."), N_("STRING"), ARG_TYPE_STRING}, + /* TRANSLATORS: menu entry can either be bootable by anyone or only by + handful of users. By default when security is active only superusers can + boot a given menu entry. With --unrestricted (this option) + anyone can boot it. */ + {"unrestricted", 0, 0, N_("This entry can be booted by any user."), + 0, ARG_TYPE_NONE}, + {0, 0, 0, 0, 0, 0} + }; + +static struct +{ + const char *name; + int key; +} hotkey_aliases[] = + { + {"backspace", GRUB_TERM_BACKSPACE}, + {"tab", GRUB_TERM_TAB}, + {"delete", GRUB_TERM_KEY_DC}, + {"insert", GRUB_TERM_KEY_INSERT}, + {"f1", GRUB_TERM_KEY_F1}, + {"f2", GRUB_TERM_KEY_F2}, + {"f3", GRUB_TERM_KEY_F3}, + {"f4", GRUB_TERM_KEY_F4}, + {"f5", GRUB_TERM_KEY_F5}, + {"f6", GRUB_TERM_KEY_F6}, + {"f7", GRUB_TERM_KEY_F7}, + {"f8", GRUB_TERM_KEY_F8}, + {"f9", GRUB_TERM_KEY_F9}, + {"f10", GRUB_TERM_KEY_F10}, + {"f11", GRUB_TERM_KEY_F11}, + {"f12", GRUB_TERM_KEY_F12}, + }; + +/* Add a menu entry to the current menu context (as given by the environment + variable data slot `menu'). As the configuration file is read, the script + parser calls this when a menu entry is to be created. */ +grub_err_t +grub_normal_add_menu_entry (int argc, const char **args, + char **classes, const char *id, + const char *users, const char *hotkey, + const char *prefix, const char *sourcecode, + int submenu, int *index, struct bls_entry *bls) +{ + int menu_hotkey = 0; + char **menu_args = NULL; + char *menu_users = NULL; + char *menu_title = NULL; + char *menu_sourcecode = NULL; + char *menu_id = NULL; + struct grub_menu_entry_class *menu_classes = NULL; + + grub_menu_t menu; + grub_menu_entry_t *last; + + menu = grub_env_get_menu (); + if (! menu) + return grub_error (GRUB_ERR_MENU, "no menu context"); + + last = &menu->entry_list; + + menu_sourcecode = grub_xasprintf ("%s%s", prefix ?: "", sourcecode); + if (! menu_sourcecode) + return grub_errno; + + if (classes && classes[0]) + { + int i; + for (i = 0; classes[i]; i++); /* count # of menuentry classes */ + menu_classes = grub_zalloc (sizeof (struct grub_menu_entry_class) + * (i + 1)); + if (! menu_classes) + goto fail; + + for (i = 0; classes[i]; i++) + { + menu_classes[i].name = grub_strdup (classes[i]); + if (! menu_classes[i].name) + goto fail; + menu_classes[i].next = classes[i + 1] ? &menu_classes[i + 1] : NULL; + } + } + + if (users) + { + menu_users = grub_strdup (users); + if (! menu_users) + goto fail; + } + + if (hotkey) + { + unsigned i; + for (i = 0; i < ARRAY_SIZE (hotkey_aliases); i++) + if (grub_strcmp (hotkey, hotkey_aliases[i].name) == 0) + { + menu_hotkey = hotkey_aliases[i].key; + break; + } + if (i == ARRAY_SIZE (hotkey_aliases)) + menu_hotkey = hotkey[0]; + } + + if (! argc) + { + grub_error (GRUB_ERR_MENU, "menuentry is missing title"); + goto fail; + } + + menu_title = grub_strdup (args[0]); + if (! menu_title) + goto fail; + + grub_dprintf ("menu", "id:\"%s\"\n", id); + grub_dprintf ("menu", "title:\"%s\"\n", menu_title); + menu_id = grub_strdup (id ? : menu_title); + if (! menu_id) + goto fail; + grub_dprintf ("menu", "menu_id:\"%s\"\n", menu_id); + + /* Save argc, args to pass as parameters to block arg later. */ + menu_args = grub_malloc (sizeof (char*) * (argc + 1)); + if (! menu_args) + goto fail; + + { + int i; + for (i = 0; i < argc; i++) + { + menu_args[i] = grub_strdup (args[i]); + if (! menu_args[i]) + goto fail; + } + menu_args[argc] = NULL; + } + + /* Add the menu entry at the end of the list. */ + int ind=0; + while (*last) + { + ind++; + last = &(*last)->next; + } + + *last = grub_zalloc (sizeof (**last)); + if (! *last) + goto fail; + + (*last)->title = menu_title; + (*last)->id = menu_id; + (*last)->hotkey = menu_hotkey; + (*last)->classes = menu_classes; + if (menu_users) + (*last)->restricted = 1; + (*last)->users = menu_users; + (*last)->argc = argc; + (*last)->args = menu_args; + (*last)->sourcecode = menu_sourcecode; + (*last)->submenu = submenu; + (*last)->bls = bls; + + menu->size++; + if (index) + *index = ind; + return GRUB_ERR_NONE; + + fail: + + grub_free (menu_sourcecode); + { + int i; + for (i = 0; menu_classes && menu_classes[i].name; i++) + grub_free (menu_classes[i].name); + grub_free (menu_classes); + } + + { + int i; + for (i = 0; menu_args && menu_args[i]; i++) + grub_free (menu_args[i]); + grub_free (menu_args); + } + + grub_free (menu_users); + grub_free (menu_title); + grub_free (menu_id); + return grub_errno; +} + +static char * +setparams_prefix (int argc, char **args) +{ + int i; + int j; + char *p; + char *result; + grub_size_t len = 10; + + /* Count resulting string length */ + for (i = 0; i < argc; i++) + { + len += 3; /* 3 = 1 space + 2 quotes */ + p = args[i]; + while (*p) + len += (*p++ == '\'' ? 3 : 1); + } + + result = grub_malloc (len + 2); + if (! result) + return 0; + + grub_strcpy (result, "setparams"); + p = result + 9; + + for (j = 0; j < argc; j++) + { + *p++ = ' '; + *p++ = '\''; + p = grub_strchrsub (p, args[j], '\'', "'\\''"); + *p++ = '\''; + } + *p++ = '\n'; + *p = '\0'; + return result; +} + +static grub_err_t +grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args) +{ + char ch; + char *src; + char *prefix; + unsigned len; + grub_err_t r; + const char *users; + + if (! argc) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing arguments"); + + if (ctxt->state[3].set && ctxt->script) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "multiple menuentry definitions"); + + if (! ctxt->state[3].set && ! ctxt->script) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no menuentry definition"); + + if (ctxt->state[1].set) + users = ctxt->state[1].arg; + else if (ctxt->state[5].set) + users = NULL; + else + users = ""; + + if (! ctxt->script) + return grub_normal_add_menu_entry (argc, (const char **) args, + (ctxt->state[0].set ? ctxt->state[0].args + : NULL), + ctxt->state[4].arg, + users, + ctxt->state[2].arg, 0, + ctxt->state[3].arg, + ctxt->extcmd->cmd->name[0] == 's', + NULL, NULL); + + src = args[argc - 1]; + args[argc - 1] = NULL; + + len = grub_strlen(src); + ch = src[len - 1]; + src[len - 1] = '\0'; + + prefix = setparams_prefix (argc - 1, args); + if (! prefix) + return grub_errno; + + r = grub_normal_add_menu_entry (argc - 1, (const char **) args, + ctxt->state[0].args, ctxt->state[4].arg, + users, + ctxt->state[2].arg, prefix, src + 1, + ctxt->extcmd->cmd->name[0] == 's', NULL, + NULL); + + src[len - 1] = ch; + args[argc - 1] = src; + grub_free (prefix); + return r; +} + +static grub_extcmd_t cmd, cmd_sub; + +void +grub_menu_init (void) +{ + cmd = grub_register_extcmd ("menuentry", grub_cmd_menuentry, + GRUB_COMMAND_FLAG_BLOCKS + | GRUB_COMMAND_ACCEPT_DASH + | GRUB_COMMAND_FLAG_EXTRACTOR, + N_("BLOCK"), N_("Define a menu entry."), options); + cmd_sub = grub_register_extcmd ("submenu", grub_cmd_menuentry, + GRUB_COMMAND_FLAG_BLOCKS + | GRUB_COMMAND_ACCEPT_DASH + | GRUB_COMMAND_FLAG_EXTRACTOR, + N_("BLOCK"), N_("Define a submenu."), + options); +} + +void +grub_menu_fini (void) +{ + grub_unregister_extcmd (cmd); + grub_unregister_extcmd (cmd_sub); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/search.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/search.c new file mode 100644 index 0000000..70d0fce --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/search.c @@ -0,0 +1,353 @@ +/* search.c - search devices based on a file or a filesystem label */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +static int g_no_vtoyefi_part = 0; +static char g_vtoyefi_dosname[64]; +static char g_vtoyefi_gptname[64]; + +struct cache_entry +{ + struct cache_entry *next; + char *key; + char *value; +}; + +static struct cache_entry *cache; + +/* Context for FUNC_NAME. */ +struct search_ctx +{ + const char *key; + const char *var; + int no_floppy; + char **hints; + unsigned nhints; + int count; + int is_cache; +}; + +/* Helper for FUNC_NAME. */ +static int +iterate_device (const char *name, void *data) +{ + struct search_ctx *ctx = data; + int found = 0; + + /* Skip floppy drives when requested. */ + if (ctx->no_floppy && + name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9') + return 0; + + if (g_no_vtoyefi_part && (grub_strcmp(name, g_vtoyefi_dosname) == 0 || grub_strcmp(name, g_vtoyefi_gptname) == 0)) { + return 0; + } + +#ifdef DO_SEARCH_FS_UUID +#define compare_fn grub_strcasecmp +#else +#define compare_fn grub_strcmp +#endif + +#ifdef DO_SEARCH_FILE + { + char *buf; + grub_file_t file; + + buf = grub_xasprintf ("(%s)%s", name, ctx->key); + if (! buf) + return 1; + + file = grub_file_open (buf, GRUB_FILE_TYPE_FS_SEARCH + | GRUB_FILE_TYPE_NO_DECOMPRESS); + if (file) + { + found = 1; + grub_file_close (file); + } + grub_free (buf); + } +#else + { + /* SEARCH_FS_UUID or SEARCH_LABEL */ + grub_device_t dev; + grub_fs_t fs; + char *quid; + + dev = grub_device_open (name); + if (dev) + { + fs = grub_fs_probe (dev); + +#ifdef DO_SEARCH_FS_UUID +#define read_fn fs_uuid +#else +#define read_fn fs_label +#endif + + if (fs && fs->read_fn) + { + fs->read_fn (dev, &quid); + + if (grub_errno == GRUB_ERR_NONE && quid) + { + if (compare_fn (quid, ctx->key) == 0) + found = 1; + + grub_free (quid); + } + } + + grub_device_close (dev); + } + } +#endif + + if (!ctx->is_cache && found && ctx->count == 0) + { + struct cache_entry *cache_ent; + cache_ent = grub_malloc (sizeof (*cache_ent)); + if (cache_ent) + { + cache_ent->key = grub_strdup (ctx->key); + cache_ent->value = grub_strdup (name); + if (cache_ent->value && cache_ent->key) + { + cache_ent->next = cache; + cache = cache_ent; + } + else + { + grub_free (cache_ent->value); + grub_free (cache_ent->key); + grub_free (cache_ent); + grub_errno = GRUB_ERR_NONE; + } + } + else + grub_errno = GRUB_ERR_NONE; + } + + if (found) + { + ctx->count++; + if (ctx->var) + grub_env_set (ctx->var, name); + else + grub_printf (" %s", name); + } + + grub_errno = GRUB_ERR_NONE; + return (found && ctx->var); +} + +/* Helper for FUNC_NAME. */ +static int +part_hook (grub_disk_t disk, const grub_partition_t partition, void *data) +{ + struct search_ctx *ctx = data; + char *partition_name, *devname; + int ret; + + partition_name = grub_partition_get_name (partition); + if (! partition_name) + return 1; + + devname = grub_xasprintf ("%s,%s", disk->name, partition_name); + grub_free (partition_name); + if (!devname) + return 1; + ret = iterate_device (devname, ctx); + grub_free (devname); + + return ret; +} + +/* Helper for FUNC_NAME. */ +static void +try (struct search_ctx *ctx) +{ + unsigned i; + struct cache_entry **prev; + struct cache_entry *cache_ent; + + for (prev = &cache, cache_ent = *prev; cache_ent; + prev = &cache_ent->next, cache_ent = *prev) + if (compare_fn (cache_ent->key, ctx->key) == 0) + break; + if (cache_ent) + { + ctx->is_cache = 1; + if (iterate_device (cache_ent->value, ctx)) + { + ctx->is_cache = 0; + return; + } + ctx->is_cache = 0; + /* Cache entry was outdated. Remove it. */ + if (!ctx->count) + { + *prev = cache_ent->next; + grub_free (cache_ent->key); + grub_free (cache_ent->value); + grub_free (cache_ent); + } + } + + for (i = 0; i < ctx->nhints; i++) + { + char *end; + if (!ctx->hints[i][0]) + continue; + end = ctx->hints[i] + grub_strlen (ctx->hints[i]) - 1; + if (*end == ',') + *end = 0; + if (iterate_device (ctx->hints[i], ctx)) + { + if (!*end) + *end = ','; + return; + } + if (!*end) + { + grub_device_t dev; + int ret; + dev = grub_device_open (ctx->hints[i]); + if (!dev) + { + if (!*end) + *end = ','; + continue; + } + if (!dev->disk) + { + grub_device_close (dev); + if (!*end) + *end = ','; + continue; + } + ret = grub_partition_iterate (dev->disk, part_hook, ctx); + if (!*end) + *end = ','; + grub_device_close (dev); + if (ret) + return; + } + } + grub_device_iterate (iterate_device, ctx); +} + +void +FUNC_NAME (const char *key, const char *var, int no_floppy, + char **hints, unsigned nhints) +{ + struct search_ctx ctx = { + .key = key, + .var = var, + .no_floppy = no_floppy, + .hints = hints, + .nhints = nhints, + .count = 0, + .is_cache = 0 + }; + grub_fs_autoload_hook_t saved_autoload; + + g_no_vtoyefi_part = 0; + if (grub_env_get("VTOY_SEARCH_NO_VTOYEFI")) + { + grub_snprintf(g_vtoyefi_dosname, sizeof(g_vtoyefi_dosname), "%s,msdos2", grub_env_get("vtoydev")); + grub_snprintf(g_vtoyefi_gptname, sizeof(g_vtoyefi_gptname), "%s,gpt2", grub_env_get("vtoydev")); + g_no_vtoyefi_part = 1; + } + + /* First try without autoloading if we're setting variable. */ + if (var) + { + saved_autoload = grub_fs_autoload_hook; + grub_fs_autoload_hook = 0; + try (&ctx); + + /* Restore autoload hook. */ + grub_fs_autoload_hook = saved_autoload; + + /* Retry with autoload if nothing found. */ + if (grub_errno == GRUB_ERR_NONE && ctx.count == 0) + try (&ctx); + } + else + try (&ctx); + + if (grub_errno == GRUB_ERR_NONE && ctx.count == 0) + grub_error (GRUB_ERR_FILE_NOT_FOUND, "no such device: %s", key); +} + +static grub_err_t +grub_cmd_do_search (grub_command_t cmd __attribute__ ((unused)), int argc, + char **args) +{ + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); + + FUNC_NAME (args[0], argc == 1 ? 0 : args[1], 0, (args + 2), + argc > 2 ? argc - 2 : 0); + + return grub_errno; +} + +static grub_command_t cmd; + +#ifdef DO_SEARCH_FILE +GRUB_MOD_INIT(search_fs_file) +#elif defined (DO_SEARCH_FS_UUID) +GRUB_MOD_INIT(search_fs_uuid) +#else +GRUB_MOD_INIT(search_label) +#endif +{ + cmd = + grub_register_command (COMMAND_NAME, grub_cmd_do_search, + N_("NAME [VARIABLE] [HINTS]"), + HELP_MESSAGE); +} + +#ifdef DO_SEARCH_FILE +GRUB_MOD_FINI(search_fs_file) +#elif defined (DO_SEARCH_FS_UUID) +GRUB_MOD_FINI(search_fs_uuid) +#else +GRUB_MOD_FINI(search_label) +#endif +{ + grub_unregister_command (cmd); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/smbios.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/smbios.c new file mode 100644 index 0000000..b1a15bc --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/smbios.c @@ -0,0 +1,399 @@ +/* smbios.c - retrieve smbios information. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2019 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +/* Abstract useful values found in either the SMBIOS3 or SMBIOS EPS. */ +static struct { + grub_addr_t start; + grub_addr_t end; + grub_uint16_t structures; +} table_desc; + +static grub_extcmd_t cmd; + +/* Locate the SMBIOS entry point structure depending on the hardware. */ +struct grub_smbios_eps * +grub_smbios_get_eps (void) +{ + static struct grub_smbios_eps *eps = NULL; + + if (eps != NULL) + return eps; + + eps = grub_machine_smbios_get_eps (); + + return eps; +} + +/* Locate the SMBIOS3 entry point structure depending on the hardware. */ +static struct grub_smbios_eps3 * +grub_smbios_get_eps3 (void) +{ + static struct grub_smbios_eps3 *eps = NULL; + + if (eps != NULL) + return eps; + + eps = grub_machine_smbios_get_eps3 (); + + return eps; +} + +static char * +linux_string (const char *value) +{ + char *out = grub_malloc( grub_strlen (value) + 1); + const char *src = value; + char *dst = out; + + for (; *src; src++) + if (*src > ' ' && *src < 127 && *src != ':') + *dst++ = *src; + + *dst = 0; + return out; +} + +/* + * These functions convert values from the various SMBIOS structure field types + * into a string formatted to be returned to the user. They expect that the + * structure and offset were already validated. When the requested data is + * successfully retrieved and formatted, the pointer to the string is returned; + * otherwise, NULL is returned on failure. Don't free the result. + */ + +static const char * +grub_smbios_format_byte (const grub_uint8_t *structure, grub_uint8_t offset) +{ + static char buffer[sizeof ("255")]; + + grub_snprintf (buffer, sizeof (buffer), "%u", structure[offset]); + + return (const char *)buffer; +} + +static const char * +grub_smbios_format_word (const grub_uint8_t *structure, grub_uint8_t offset) +{ + static char buffer[sizeof ("65535")]; + + grub_uint16_t value = grub_get_unaligned16 (structure + offset); + grub_snprintf (buffer, sizeof (buffer), "%u", value); + + return (const char *)buffer; +} + +static const char * +grub_smbios_format_dword (const grub_uint8_t *structure, grub_uint8_t offset) +{ + static char buffer[sizeof ("4294967295")]; + + grub_uint32_t value = grub_get_unaligned32 (structure + offset); + grub_snprintf (buffer, sizeof (buffer), "%" PRIuGRUB_UINT32_T, value); + + return (const char *)buffer; +} + +static const char * +grub_smbios_format_qword (const grub_uint8_t *structure, grub_uint8_t offset) +{ + static char buffer[sizeof ("18446744073709551615")]; + + grub_uint64_t value = grub_get_unaligned64 (structure + offset); + grub_snprintf (buffer, sizeof (buffer), "%" PRIuGRUB_UINT64_T, value); + + return (const char *)buffer; +} + +static const char * +grub_smbios_get_string (const grub_uint8_t *structure, grub_uint8_t offset) +{ + const grub_uint8_t *ptr = structure + structure[1]; + const grub_uint8_t *table_end = (const grub_uint8_t *)table_desc.end; + const grub_uint8_t referenced_string_number = structure[offset]; + grub_uint8_t i; + + /* A string referenced with zero is interpreted as unset. */ + if (referenced_string_number == 0) + return NULL; + + /* Search the string set. */ + for (i = 1; *ptr != 0 && ptr < table_end; i++) + if (i == referenced_string_number) + { + const char *str = (const char *)ptr; + while (*ptr++ != 0) + if (ptr >= table_end) + return NULL; /* The string isn't terminated. */ + return str; + } + else + while (*ptr++ != 0 && ptr < table_end); + + /* The string number is greater than the number of strings in the set. */ + return NULL; +} + +static const char * +grub_smbios_format_uuid (const grub_uint8_t *structure, grub_uint8_t offset) +{ + static char buffer[sizeof ("ffffffff-ffff-ffff-ffff-ffffffffffff")]; + const grub_uint8_t *f = structure + offset; /* little-endian fields */ + const grub_uint8_t *g = f + 8; /* byte-by-byte fields */ + + grub_snprintf (buffer, sizeof (buffer), + "%02x%02x%02x%02x-%02x%02x-%02x%02x-" + "%02x%02x-%02x%02x%02x%02x%02x%02x", + f[3], f[2], f[1], f[0], f[5], f[4], f[7], f[6], + g[0], g[1], g[2], g[3], g[4], g[5], g[6], g[7]); + + return (const char *)buffer; +} + +/* List the field formatting functions and the number of bytes they need. */ +static const struct { + const char *(*format) (const grub_uint8_t *structure, grub_uint8_t offset); + grub_uint8_t field_length; +} field_extractors[] = { + {grub_smbios_format_byte, 1}, + {grub_smbios_format_word, 2}, + {grub_smbios_format_dword, 4}, + {grub_smbios_format_qword, 8}, + {grub_smbios_get_string, 1}, + {grub_smbios_format_uuid, 16} +}; + +/* List command options, with structure field getters ordered as above. */ +#define FIRST_GETTER_OPT (3) +#define SETTER_OPT (FIRST_GETTER_OPT + ARRAY_SIZE(field_extractors)) +#define LINUX_OPT (FIRST_GETTER_OPT + ARRAY_SIZE(field_extractors) + 1) + +static const struct grub_arg_option options[] = { + {"type", 't', 0, N_("Match structures with the given type."), + N_("type"), ARG_TYPE_INT}, + {"handle", 'h', 0, N_("Match structures with the given handle."), + N_("handle"), ARG_TYPE_INT}, + {"match", 'm', 0, N_("Select a structure when several match."), + N_("match"), ARG_TYPE_INT}, + {"get-byte", 'b', 0, N_("Get the byte's value at the given offset."), + N_("offset"), ARG_TYPE_INT}, + {"get-word", 'w', 0, N_("Get two bytes' value at the given offset."), + N_("offset"), ARG_TYPE_INT}, + {"get-dword", 'd', 0, N_("Get four bytes' value at the given offset."), + N_("offset"), ARG_TYPE_INT}, + {"get-qword", 'q', 0, N_("Get eight bytes' value at the given offset."), + N_("offset"), ARG_TYPE_INT}, + {"get-string", 's', 0, N_("Get the string specified at the given offset."), + N_("offset"), ARG_TYPE_INT}, + {"get-uuid", 'u', 0, N_("Get the UUID's value at the given offset."), + N_("offset"), ARG_TYPE_INT}, + {"set", '\0', 0, N_("Store the value in the given variable name."), + N_("variable"), ARG_TYPE_STRING}, + {"linux", '\0', 0, N_("Filter the result like linux does."), + N_("variable"), ARG_TYPE_NONE}, + {0, 0, 0, 0, 0, 0} +}; + +/* + * Return a matching SMBIOS structure. + * + * This method can use up to three criteria for selecting a structure: + * - The "type" field (use -1 to ignore) + * - The "handle" field (use -1 to ignore) + * - Which to return if several match (use 0 to ignore) + * + * The return value is a pointer to the first matching structure. If no + * structures match the given parameters, NULL is returned. + */ +static const grub_uint8_t * +grub_smbios_match_structure (const grub_int16_t type, + const grub_int32_t handle, + const grub_uint16_t match) +{ + const grub_uint8_t *ptr = (const grub_uint8_t *)table_desc.start; + const grub_uint8_t *table_end = (const grub_uint8_t *)table_desc.end; + grub_uint16_t structures = table_desc.structures; + grub_uint16_t structure_count = 0; + grub_uint16_t matches = 0; + + while (ptr < table_end + && ptr[1] >= 4 /* Valid structures include the 4-byte header. */ + && (structure_count++ < structures || structures == 0)) + { + grub_uint16_t structure_handle = grub_get_unaligned16 (ptr + 2); + grub_uint8_t structure_type = ptr[0]; + + if ((handle < 0 || handle == structure_handle) + && (type < 0 || type == structure_type) + && (match == 0 || match == ++matches)) + return ptr; + else + { + ptr += ptr[1]; + while ((*ptr++ != 0 || *ptr++ != 0) && ptr < table_end); + } + + if (structure_type == GRUB_SMBIOS_TYPE_END_OF_TABLE) + break; + } + + return NULL; +} + +static grub_err_t +grub_cmd_smbios (grub_extcmd_context_t ctxt, + int argc __attribute__ ((unused)), + char **argv __attribute__ ((unused))) +{ + struct grub_arg_list *state = ctxt->state; + + grub_int16_t type = -1; + grub_int32_t handle = -1; + grub_uint16_t match = 0; + grub_uint8_t offset = 0; + + const grub_uint8_t *structure; + const char *value; + char *modified_value = NULL; + grub_int32_t option; + grub_int8_t field_type = -1; + grub_uint8_t i; + + if (table_desc.start == 0) + return grub_error (GRUB_ERR_IO, + N_("the SMBIOS entry point structure was not found")); + + /* Read the given filtering options. */ + if (state[0].set) + { + option = grub_strtol (state[0].arg, NULL, 0); + if (option < 0 || option > 255) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("the type must be between 0 and 255")); + type = (grub_int16_t)option; + } + if (state[1].set) + { + option = grub_strtol (state[1].arg, NULL, 0); + if (option < 0 || option > 65535) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("the handle must be between 0 and 65535")); + handle = (grub_int32_t)option; + } + if (state[2].set) + { + option = grub_strtol (state[2].arg, NULL, 0); + if (option <= 0 || option > 65535) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("the match must be a positive integer")); + match = (grub_uint16_t)option; + } + + /* Determine the data type of the structure field to retrieve. */ + for (i = 0; i < ARRAY_SIZE(field_extractors); i++) + if (state[FIRST_GETTER_OPT + i].set) + { + if (field_type >= 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("only one --get option is usable at a time")); + field_type = i; + } + + /* Require a choice of a structure field to return. */ + if (field_type < 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("one of the --get options is required")); + + /* Locate a matching SMBIOS structure. */ + structure = grub_smbios_match_structure (type, handle, match); + if (structure == NULL) + return grub_error (GRUB_ERR_IO, + N_("no structure matched the given options")); + + /* Ensure the requested byte offset is inside the structure. */ + option = grub_strtol (state[FIRST_GETTER_OPT + field_type].arg, NULL, 0); + if (option < 0 || option >= structure[1]) + return grub_error (GRUB_ERR_OUT_OF_RANGE, + N_("the given offset is outside the structure")); + + /* Ensure the requested data type at the offset is inside the structure. */ + offset = (grub_uint8_t)option; + if (offset + field_extractors[field_type].field_length > structure[1]) + return grub_error (GRUB_ERR_OUT_OF_RANGE, + N_("the field ends outside the structure")); + + /* Format the requested structure field into a readable string. */ + value = field_extractors[field_type].format (structure, offset); + if (value == NULL) + return grub_error (GRUB_ERR_IO, + N_("failed to retrieve the structure field")); + + if (state[LINUX_OPT].set) + value = modified_value = linux_string (value); + + /* Store or print the formatted value. */ + if (state[SETTER_OPT].set) + grub_env_set (state[SETTER_OPT].arg, value); + else + grub_printf ("%s\n", value); + + grub_free(modified_value); + + return GRUB_ERR_NONE; +} + +GRUB_MOD_INIT(smbios) +{ + struct grub_smbios_eps3 *eps3; + struct grub_smbios_eps *eps; + + if ((eps3 = grub_smbios_get_eps3 ())) + { + table_desc.start = (grub_addr_t)eps3->table_address; + table_desc.end = table_desc.start + eps3->maximum_table_length; + table_desc.structures = 0; /* SMBIOS3 drops the structure count. */ + } + else if ((eps = grub_smbios_get_eps ())) + { + table_desc.start = (grub_addr_t)eps->intermediate.table_address; + table_desc.end = table_desc.start + eps->intermediate.table_length; + table_desc.structures = eps->intermediate.structures; + } + + cmd = grub_register_extcmd ("smbios", grub_cmd_smbios, 0, + N_("[-t type] [-h handle] [-m match] " + "(-b|-w|-d|-q|-s|-u) offset " + "[--set variable]"), + N_("Retrieve SMBIOS information."), options); +} + +GRUB_MOD_FINI(smbios) +{ + grub_unregister_extcmd (cmd); +} + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/test.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/test.c new file mode 100644 index 0000000..9669a48 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/test.c @@ -0,0 +1,533 @@ +/* test.c -- The test command.. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +static int g_test_case_insensitive = 0; + +/* A simple implementation for signed numbers. */ +static int +grub_strtosl (char *arg, char **end, int base) +{ + if (arg[0] == '-') + return -grub_strtoul (arg + 1, end, base); + return grub_strtoul (arg, end, base); +} + +/* Context for test_parse. */ +struct test_parse_ctx +{ + int invert; + int or, and; + int file_exists; + struct grub_dirhook_info file_info; + char *filename; +}; + +/* Take care of discarding and inverting. */ +static void +update_val (int val, struct test_parse_ctx *ctx) +{ + ctx->and = ctx->and && (ctx->invert ? ! val : val); + ctx->invert = 0; +} + +/* A hook for iterating directories. */ +static int +find_file (const char *cur_filename, const struct grub_dirhook_info *info, + void *data) +{ + int case_insensitive = 0; + struct test_parse_ctx *ctx = data; + + if (g_test_case_insensitive || info->case_insensitive) + case_insensitive = 1; + + if ((case_insensitive ? grub_strcasecmp (cur_filename, ctx->filename) + : grub_strcmp (cur_filename, ctx->filename)) == 0) + { + ctx->file_info = *info; + ctx->file_exists = 1; + return 1; + } + return 0; +} + +/* Check if file exists and fetch its information. */ +static void +get_fileinfo (char *path, struct test_parse_ctx *ctx) +{ + char *pathname; + char *device_name; + grub_fs_t fs; + grub_device_t dev; + + ctx->file_exists = 0; + device_name = grub_file_get_device_name (path); + dev = grub_device_open (device_name); + if (! dev) + { + grub_free (device_name); + return; + } + + fs = grub_fs_probe (dev); + if (! fs) + { + grub_free (device_name); + grub_device_close (dev); + return; + } + + pathname = grub_strchr (path, ')'); + if (! pathname) + pathname = path; + else + pathname++; + + /* Remove trailing '/'. */ + while (*pathname && pathname[grub_strlen (pathname) - 1] == '/') + pathname[grub_strlen (pathname) - 1] = 0; + + /* Split into path and filename. */ + ctx->filename = grub_strrchr (pathname, '/'); + if (! ctx->filename) + { + path = grub_strdup ("/"); + ctx->filename = pathname; + } + else + { + ctx->filename++; + path = grub_strdup (pathname); + path[ctx->filename - pathname] = 0; + } + + /* It's the whole device. */ + if (! *pathname) + { + ctx->file_exists = 1; + grub_memset (&ctx->file_info, 0, sizeof (ctx->file_info)); + /* Root is always a directory. */ + ctx->file_info.dir = 1; + + /* Fetch writing time. */ + ctx->file_info.mtimeset = 0; + if (fs->fs_mtime) + { + if (! fs->fs_mtime (dev, &ctx->file_info.mtime)) + ctx->file_info.mtimeset = 1; + grub_errno = GRUB_ERR_NONE; + } + } + else + (fs->fs_dir) (dev, path, find_file, ctx); + + grub_device_close (dev); + grub_free (path); + grub_free (device_name); +} + +/* Parse a test expression starting from *argn. */ +static int +test_parse (char **args, int *argn, int argc) +{ + struct test_parse_ctx ctx = { + .and = 1, + .or = 0, + .invert = 0 + }; + + /* Here we have the real parsing. */ + while (*argn < argc) + { + /* First try 3 argument tests. */ + if (*argn + 2 < argc) + { + /* String tests. */ + if (grub_strcmp (args[*argn + 1], "=") == 0 + || grub_strcmp (args[*argn + 1], "==") == 0) + { + update_val (grub_strcmp (args[*argn], args[*argn + 2]) == 0, + &ctx); + (*argn) += 3; + continue; + } + + if (grub_strcmp (args[*argn + 1], "!=") == 0) + { + update_val (grub_strcmp (args[*argn], args[*argn + 2]) != 0, + &ctx); + (*argn) += 3; + continue; + } + + /* GRUB extension: lexicographical sorting. */ + if (grub_strcmp (args[*argn + 1], "<") == 0) + { + update_val (grub_strcmp (args[*argn], args[*argn + 2]) < 0, + &ctx); + (*argn) += 3; + continue; + } + + if (grub_strcmp (args[*argn + 1], "<=") == 0) + { + update_val (grub_strcmp (args[*argn], args[*argn + 2]) <= 0, + &ctx); + (*argn) += 3; + continue; + } + + if (grub_strcmp (args[*argn + 1], ">") == 0) + { + update_val (grub_strcmp (args[*argn], args[*argn + 2]) > 0, + &ctx); + (*argn) += 3; + continue; + } + + if (grub_strcmp (args[*argn + 1], ">=") == 0) + { + update_val (grub_strcmp (args[*argn], args[*argn + 2]) >= 0, + &ctx); + (*argn) += 3; + continue; + } + + /* Number tests. */ + if (grub_strcmp (args[*argn + 1], "-eq") == 0) + { + update_val (grub_strtosl (args[*argn], 0, 0) + == grub_strtosl (args[*argn + 2], 0, 0), &ctx); + (*argn) += 3; + continue; + } + if (grub_strcmp (args[*argn + 1], "-EQ") == 0) + { + update_val (grub_strtoull (args[*argn], 0, 0) + == grub_strtoull (args[*argn + 2], 0, 0), &ctx); + (*argn) += 3; + continue; + } + + if (grub_strcmp (args[*argn + 1], "-ge") == 0) + { + update_val (grub_strtosl (args[*argn], 0, 0) + >= grub_strtosl (args[*argn + 2], 0, 0), &ctx); + (*argn) += 3; + continue; + } + if (grub_strcmp (args[*argn + 1], "-GE") == 0) + { + update_val (grub_strtoull (args[*argn], 0, 0) + >= grub_strtoull (args[*argn + 2], 0, 0), &ctx); + (*argn) += 3; + continue; + } + + if (grub_strcmp (args[*argn + 1], "-gt") == 0) + { + update_val (grub_strtosl (args[*argn], 0, 0) + > grub_strtosl (args[*argn + 2], 0, 0), &ctx); + (*argn) += 3; + continue; + } + if (grub_strcmp (args[*argn + 1], "-GT") == 0) + { + update_val (grub_strtoull (args[*argn], 0, 0) + > grub_strtoull (args[*argn + 2], 0, 0), &ctx); + (*argn) += 3; + continue; + } + + if (grub_strcmp (args[*argn + 1], "-le") == 0) + { + update_val (grub_strtosl (args[*argn], 0, 0) + <= grub_strtosl (args[*argn + 2], 0, 0), &ctx); + (*argn) += 3; + continue; + } + if (grub_strcmp (args[*argn + 1], "-LE") == 0) + { + update_val (grub_strtoull (args[*argn], 0, 0) + <= grub_strtoull (args[*argn + 2], 0, 0), &ctx); + (*argn) += 3; + continue; + } + + if (grub_strcmp (args[*argn + 1], "-lt") == 0) + { + update_val (grub_strtosl (args[*argn], 0, 0) + < grub_strtosl (args[*argn + 2], 0, 0), &ctx); + (*argn) += 3; + continue; + } + if (grub_strcmp (args[*argn + 1], "-LT") == 0) + { + update_val (grub_strtoull (args[*argn], 0, 0) + < grub_strtoull (args[*argn + 2], 0, 0), &ctx); + (*argn) += 3; + continue; + } + + if (grub_strcmp (args[*argn + 1], "-ne") == 0) + { + update_val (grub_strtosl (args[*argn], 0, 0) + != grub_strtosl (args[*argn + 2], 0, 0), &ctx); + (*argn) += 3; + continue; + } + if (grub_strcmp (args[*argn + 1], "-NE") == 0) + { + update_val (grub_strtoull (args[*argn], 0, 0) + != grub_strtoull (args[*argn + 2], 0, 0), &ctx); + (*argn) += 3; + continue; + } + + /* GRUB extension: compare numbers skipping prefixes. + Useful for comparing versions. E.g. vmlinuz-2 -plt vmlinuz-11. */ + if (grub_strcmp (args[*argn + 1], "-pgt") == 0 + || grub_strcmp (args[*argn + 1], "-plt") == 0) + { + int i; + /* Skip common prefix. */ + for (i = 0; args[*argn][i] == args[*argn + 2][i] + && args[*argn][i]; i++); + + /* Go the digits back. */ + i--; + while (grub_isdigit (args[*argn][i]) && i > 0) + i--; + i++; + + if (grub_strcmp (args[*argn + 1], "-pgt") == 0) + update_val (grub_strtoul (args[*argn] + i, 0, 0) + > grub_strtoul (args[*argn + 2] + i, 0, 0), &ctx); + else + update_val (grub_strtoul (args[*argn] + i, 0, 0) + < grub_strtoul (args[*argn + 2] + i, 0, 0), &ctx); + (*argn) += 3; + continue; + } + + /* -nt and -ot tests. GRUB extension: when doing -?t bias + will be added to the first mtime. */ + if (grub_memcmp (args[*argn + 1], "-nt", 3) == 0 + || grub_memcmp (args[*argn + 1], "-ot", 3) == 0) + { + struct grub_dirhook_info file1; + int file1exists; + int bias = 0; + + /* Fetch fileinfo. */ + get_fileinfo (args[*argn], &ctx); + file1 = ctx.file_info; + file1exists = ctx.file_exists; + get_fileinfo (args[*argn + 2], &ctx); + + if (args[*argn + 1][3]) + bias = grub_strtosl (args[*argn + 1] + 3, 0, 0); + + if (grub_memcmp (args[*argn + 1], "-nt", 3) == 0) + update_val ((file1exists && ! ctx.file_exists) + || (file1.mtimeset && ctx.file_info.mtimeset + && file1.mtime + bias > ctx.file_info.mtime), + &ctx); + else + update_val ((! file1exists && ctx.file_exists) + || (file1.mtimeset && ctx.file_info.mtimeset + && file1.mtime + bias < ctx.file_info.mtime), + &ctx); + (*argn) += 3; + continue; + } + } + + /* Two-argument tests. */ + if (*argn + 1 < argc) + { + /* File tests. */ + if (grub_strcmp (args[*argn], "-d") == 0) + { + get_fileinfo (args[*argn + 1], &ctx); + update_val (ctx.file_exists && ctx.file_info.dir, &ctx); + (*argn) += 2; + continue; + } + + if (grub_strcmp (args[*argn], "-D") == 0) + { + g_test_case_insensitive = 1; + get_fileinfo (args[*argn + 1], &ctx); + g_test_case_insensitive = 0; + update_val (ctx.file_exists && ctx.file_info.dir, &ctx); + (*argn) += 2; + continue; + } + + if (grub_strcmp (args[*argn], "-e") == 0) + { + get_fileinfo (args[*argn + 1], &ctx); + update_val (ctx.file_exists, &ctx); + (*argn) += 2; + continue; + } + + if (grub_strcmp (args[*argn], "-E") == 0) + { + g_test_case_insensitive = 1; + get_fileinfo (args[*argn + 1], &ctx); + g_test_case_insensitive = 0; + update_val (ctx.file_exists, &ctx); + (*argn) += 2; + continue; + } + + if (grub_strcmp (args[*argn], "-f") == 0) + { + get_fileinfo (args[*argn + 1], &ctx); + /* FIXME: check for other types. */ + update_val (ctx.file_exists && ! ctx.file_info.dir, &ctx); + (*argn) += 2; + continue; + } + if (grub_strcmp (args[*argn], "-F") == 0) + { + g_test_case_insensitive = 1; + get_fileinfo (args[*argn + 1], &ctx); + g_test_case_insensitive = 0; + /* FIXME: check for other types. */ + update_val (ctx.file_exists && ! ctx.file_info.dir, &ctx); + (*argn) += 2; + continue; + } + + if (grub_strcmp (args[*argn], "-s") == 0) + { + grub_file_t file; + file = grub_file_open (args[*argn + 1], GRUB_FILE_TYPE_GET_SIZE + | GRUB_FILE_TYPE_NO_DECOMPRESS); + update_val (file && (grub_file_size (file) != 0), &ctx); + if (file) + grub_file_close (file); + grub_errno = GRUB_ERR_NONE; + (*argn) += 2; + continue; + } + + /* String tests. */ + if (grub_strcmp (args[*argn], "-n") == 0) + { + update_val (args[*argn + 1][0], &ctx); + + (*argn) += 2; + continue; + } + if (grub_strcmp (args[*argn], "-z") == 0) + { + update_val (! args[*argn + 1][0], &ctx); + (*argn) += 2; + continue; + } + } + + /* Special modifiers. */ + + /* End of expression. return to parent. */ + if (grub_strcmp (args[*argn], ")") == 0) + { + (*argn)++; + return ctx.or || ctx.and; + } + /* Recursively invoke if parenthesis. */ + if (grub_strcmp (args[*argn], "(") == 0) + { + (*argn)++; + update_val (test_parse (args, argn, argc), &ctx); + continue; + } + + if (grub_strcmp (args[*argn], "!") == 0) + { + ctx.invert = ! ctx.invert; + (*argn)++; + continue; + } + if (grub_strcmp (args[*argn], "-a") == 0) + { + (*argn)++; + continue; + } + if (grub_strcmp (args[*argn], "-o") == 0) + { + ctx.or = ctx.or || ctx.and; + ctx.and = 1; + (*argn)++; + continue; + } + + /* No test found. Interpret if as just a string. */ + update_val (args[*argn][0], &ctx); + (*argn)++; + } + return ctx.or || ctx.and; +} + +static grub_err_t +grub_cmd_test (grub_command_t cmd __attribute__ ((unused)), + int argc, char **args) +{ + int argn = 0; + + if (argc >= 1 && grub_strcmp (args[argc - 1], "]") == 0) + argc--; + + return test_parse (args, &argn, argc) ? GRUB_ERR_NONE + : grub_error (GRUB_ERR_TEST_FAILURE, N_("false")); +} + +static grub_command_t cmd_1, cmd_2; + +GRUB_MOD_INIT(test) +{ + cmd_1 = grub_register_command ("[", grub_cmd_test, + N_("EXPRESSION ]"), N_("Evaluate an expression.")); + cmd_1->flags |= GRUB_COMMAND_FLAG_EXTRACTOR; + cmd_2 = grub_register_command ("test", grub_cmd_test, + N_("EXPRESSION"), N_("Evaluate an expression.")); + cmd_2->flags |= GRUB_COMMAND_FLAG_EXTRACTOR; +} + +GRUB_MOD_FINI(test) +{ + grub_unregister_command (cmd_1); + grub_unregister_command (cmd_2); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/disk/i386/pc/biosdisk.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/disk/i386/pc/biosdisk.c new file mode 100644 index 0000000..a5146ff --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/disk/i386/pc/biosdisk.c @@ -0,0 +1,764 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +static int cd_drive = 0; +static int grub_biosdisk_rw_int13_extensions (int ah, int drive, void *dap); + +static int grub_biosdisk_get_num_floppies (void) +{ + struct grub_bios_int_registers regs; + int drive; + + /* reset the disk system first */ + regs.eax = 0; + regs.edx = 0; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + + grub_bios_interrupt (0x13, ®s); + + for (drive = 0; drive < 2; drive++) + { + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT | GRUB_CPU_INT_FLAGS_CARRY; + regs.edx = drive; + + /* call GET DISK TYPE */ + regs.eax = 0x1500; + grub_bios_interrupt (0x13, ®s); + if (regs.flags & GRUB_CPU_INT_FLAGS_CARRY) + break; + + /* check if this drive exists */ + if (!(regs.eax & 0x300)) + break; + } + + return drive; +} + +/* + * Call IBM/MS INT13 Extensions (int 13 %ah=AH) for DRIVE. DAP + * is passed for disk address packet. If an error occurs, return + * non-zero, otherwise zero. + */ + +static int +grub_biosdisk_rw_int13_extensions (int ah, int drive, void *dap) +{ + struct grub_bios_int_registers regs; + regs.eax = ah << 8; + /* compute the address of disk_address_packet */ + regs.ds = (((grub_addr_t) dap) & 0xffff0000) >> 4; + regs.esi = (((grub_addr_t) dap) & 0xffff); + regs.edx = drive; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + + grub_bios_interrupt (0x13, ®s); + return (regs.eax >> 8) & 0xff; +} + +/* + * Call standard and old INT13 (int 13 %ah=AH) for DRIVE. Read/write + * NSEC sectors from COFF/HOFF/SOFF into SEGMENT. If an error occurs, + * return non-zero, otherwise zero. + */ +static int +grub_biosdisk_rw_standard (int ah, int drive, int coff, int hoff, + int soff, int nsec, int segment) +{ + int ret, i; + + /* Try 3 times. */ + for (i = 0; i < 3; i++) + { + struct grub_bios_int_registers regs; + + /* set up CHS information */ + /* set %ch to low eight bits of cylinder */ + regs.ecx = (coff << 8) & 0xff00; + /* set bits 6-7 of %cl to high two bits of cylinder */ + regs.ecx |= (coff >> 2) & 0xc0; + /* set bits 0-5 of %cl to sector */ + regs.ecx |= soff & 0x3f; + + /* set %dh to head and %dl to drive */ + regs.edx = (drive & 0xff) | ((hoff << 8) & 0xff00); + /* set %ah to AH */ + regs.eax = (ah << 8) & 0xff00; + /* set %al to NSEC */ + regs.eax |= nsec & 0xff; + + regs.ebx = 0; + regs.es = segment; + + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + + grub_bios_interrupt (0x13, ®s); + /* check if successful */ + if (!(regs.flags & GRUB_CPU_INT_FLAGS_CARRY)) + return 0; + + /* save return value */ + ret = regs.eax >> 8; + + /* if fail, reset the disk system */ + regs.eax = 0; + regs.edx = (drive & 0xff); + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + grub_bios_interrupt (0x13, ®s); + } + return ret; +} + +/* + * Check if LBA is supported for DRIVE. If it is supported, then return + * the major version of extensions, otherwise zero. + */ +static int +grub_biosdisk_check_int13_extensions (int drive) +{ + struct grub_bios_int_registers regs; + + regs.edx = drive & 0xff; + regs.eax = 0x4100; + regs.ebx = 0x55aa; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + grub_bios_interrupt (0x13, ®s); + + if (regs.flags & GRUB_CPU_INT_FLAGS_CARRY) + return 0; + + if ((regs.ebx & 0xffff) != 0xaa55) + return 0; + + /* check if AH=0x42 is supported */ + if (!(regs.ecx & 1)) + return 0; + + return (regs.eax >> 8) & 0xff; +} + +/* + * Return the geometry of DRIVE in CYLINDERS, HEADS and SECTORS. If an + * error occurs, then return non-zero, otherwise zero. + */ +static int +grub_biosdisk_get_diskinfo_standard (int drive, + unsigned long *cylinders, + unsigned long *heads, + unsigned long *sectors) +{ + struct grub_bios_int_registers regs; + + regs.eax = 0x0800; + regs.edx = drive & 0xff; + + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + grub_bios_interrupt (0x13, ®s); + + /* Check if unsuccessful. Ignore return value if carry isn't set to + workaround some buggy BIOSes. */ + if ((regs.flags & GRUB_CPU_INT_FLAGS_CARRY) && ((regs.eax & 0xff00) != 0)) + return (regs.eax & 0xff00) >> 8; + + /* bogus BIOSes may not return an error number */ + /* 0 sectors means no disk */ + if (!(regs.ecx & 0x3f)) + /* XXX 0x60 is one of the unused error numbers */ + return 0x60; + + /* the number of heads is counted from zero */ + *heads = ((regs.edx >> 8) & 0xff) + 1; + *cylinders = (((regs.ecx >> 8) & 0xff) | ((regs.ecx << 2) & 0x0300)) + 1; + *sectors = regs.ecx & 0x3f; + return 0; +} + +static int +grub_biosdisk_get_diskinfo_real (int drive, void *drp, grub_uint16_t ax) +{ + struct grub_bios_int_registers regs; + + regs.eax = ax; + + /* compute the address of drive parameters */ + regs.esi = ((grub_addr_t) drp) & 0xf; + regs.ds = ((grub_addr_t) drp) >> 4; + regs.edx = drive & 0xff; + + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + grub_bios_interrupt (0x13, ®s); + + /* Check if unsuccessful. Ignore return value if carry isn't set to + workaround some buggy BIOSes. */ + if ((regs.flags & GRUB_CPU_INT_FLAGS_CARRY) && ((regs.eax & 0xff00) != 0)) + return (regs.eax & 0xff00) >> 8; + + return 0; +} + +/* + * Return the cdrom information of DRIVE in CDRP. If an error occurs, + * then return non-zero, otherwise zero. + */ +static int +grub_biosdisk_get_cdinfo_int13_extensions (int drive, void *cdrp) +{ + return grub_biosdisk_get_diskinfo_real (drive, cdrp, 0x4b01); +} + +/* + * Return the geometry of DRIVE in a drive parameters, DRP. If an error + * occurs, then return non-zero, otherwise zero. + */ +static int +grub_biosdisk_get_diskinfo_int13_extensions (int drive, void *drp) +{ + return grub_biosdisk_get_diskinfo_real (drive, drp, 0x4800); +} + +static int +grub_biosdisk_get_drive (const char *name) +{ + unsigned long drive; + + if (name[0] == 'c' && name[1] == 'd' && name[2] == 0 && cd_drive) + return cd_drive; + + if ((name[0] != 'f' && name[0] != 'h') || name[1] != 'd') + goto fail; + + drive = grub_strtoul (name + 2, 0, 10); + if (grub_errno != GRUB_ERR_NONE) + goto fail; + + if (name[0] == 'h') + drive += 0x80; + + return (int) drive ; + + fail: + grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a biosdisk"); + return -1; +} + +static int +grub_biosdisk_call_hook (grub_disk_dev_iterate_hook_t hook, void *hook_data, + int drive) +{ + char name[10]; + + if (cd_drive && drive == cd_drive) + return hook ("cd", hook_data); + + grub_snprintf (name, sizeof (name), + (drive & 0x80) ? "hd%d" : "fd%d", drive & (~0x80)); + return hook (name, hook_data); +} + +static int +grub_biosdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, + grub_disk_pull_t pull) +{ + int num_floppies; + int drive; + + /* For hard disks, attempt to read the MBR. */ + switch (pull) + { + case GRUB_DISK_PULL_NONE: + for (drive = 0x80; drive < 0x90; drive++) + { + if (grub_biosdisk_rw_standard (0x02, drive, 0, 0, 1, 1, + GRUB_MEMORY_MACHINE_SCRATCH_SEG) != 0) + { + grub_dprintf ("disk", "Read error when probing drive 0x%2x\n", drive); + break; + } + + if (grub_biosdisk_call_hook (hook, hook_data, drive)) + return 1; + } + return 0; + + case GRUB_DISK_PULL_REMOVABLE: + if (cd_drive) + { + if (grub_biosdisk_call_hook (hook, hook_data, cd_drive)) + return 1; + } + + /* For floppy disks, we can get the number safely. */ + num_floppies = grub_biosdisk_get_num_floppies (); + for (drive = 0; drive < num_floppies; drive++) + if (grub_biosdisk_call_hook (hook, hook_data, drive)) + return 1; + return 0; + default: + return 0; + } + return 0; +} + +#pragma pack(1) +typedef struct ventoy_part_table +{ + grub_uint8_t Active; // 0x00 0x80 + + grub_uint8_t StartHead; + grub_uint16_t StartSector : 6; + grub_uint16_t StartCylinder : 10; + + grub_uint8_t FsFlag; + + grub_uint8_t EndHead; + grub_uint16_t EndSector : 6; + grub_uint16_t EndCylinder : 10; + + grub_uint32_t StartSectorId; + grub_uint32_t SectorCount; +}ventoy_part_table; + +typedef struct ventoy_mbr_head +{ + grub_uint8_t BootCode[446]; + ventoy_part_table PartTbl[4]; + grub_uint8_t Byte55; + grub_uint8_t ByteAA; +}ventoy_mbr_head; +#pragma pack() + +static grub_err_t +grub_biosdisk_rw (int cmd, grub_disk_t disk, + grub_disk_addr_t sector, grub_size_t size, + unsigned segment); + +static int ventoy_is_mbr_match(ventoy_mbr_head *head) +{ + grub_uint32_t PartStartSector; + + if (head->Byte55 != 0x55 || head->ByteAA != 0xAA) { + return 0; + } + + if (head->PartTbl[2].SectorCount > 0 || head->PartTbl[3].SectorCount > 0) { + return 0; + } + + if (head->PartTbl[0].StartSectorId != 2048) { + return 0; + } + + if (head->PartTbl[1].Active != 0x80 || head->PartTbl[1].FsFlag != 0xEF) { + return 0; + } + + PartStartSector = head->PartTbl[0].StartSectorId + head->PartTbl[0].SectorCount; + + if (head->PartTbl[1].StartSectorId != PartStartSector || head->PartTbl[1].SectorCount != 65536) { + return 0; + } + + return 1; +} + +static grub_err_t +grub_biosdisk_open (const char *name, grub_disk_t disk) +{ + grub_uint64_t total_sectors = 0; + int drive; + struct grub_biosdisk_data *data; + + drive = grub_biosdisk_get_drive (name); + if (drive < 0) + return grub_errno; + + disk->id = drive; + + data = (struct grub_biosdisk_data *) grub_zalloc (sizeof (*data)); + if (! data) + return grub_errno; + + data->drive = drive; + + if ((cd_drive) && (drive == cd_drive)) + { + data->flags = GRUB_BIOSDISK_FLAG_LBA | GRUB_BIOSDISK_FLAG_CDROM; + data->sectors = 8; + disk->log_sector_size = 11; + /* TODO: get the correct size. */ + total_sectors = GRUB_DISK_SIZE_UNKNOWN; + } + else + { + /* HDD */ + int version; + + disk->log_sector_size = 9; + + version = grub_biosdisk_check_int13_extensions (drive); + if (version) + { + struct grub_biosdisk_drp *drp + = (struct grub_biosdisk_drp *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + + /* Clear out the DRP. */ + grub_memset (drp, 0, sizeof (*drp)); + drp->size = sizeof (*drp); + if (! grub_biosdisk_get_diskinfo_int13_extensions (drive, drp)) + { + data->flags = GRUB_BIOSDISK_FLAG_LBA; + + if (drp->total_sectors) + total_sectors = drp->total_sectors; + else + /* Some buggy BIOSes doesn't return the total sectors + correctly but returns zero. So if it is zero, compute + it by C/H/S returned by the LBA BIOS call. */ + total_sectors = ((grub_uint64_t) drp->cylinders) + * drp->heads * drp->sectors; + if (drp->bytes_per_sector + && !(drp->bytes_per_sector & (drp->bytes_per_sector - 1)) + && drp->bytes_per_sector >= 512 + && drp->bytes_per_sector <= 16384) + { + for (disk->log_sector_size = 0; + (1 << disk->log_sector_size) < drp->bytes_per_sector; + disk->log_sector_size++); + } + } + } + } + + if (! (data->flags & GRUB_BIOSDISK_FLAG_CDROM)) + { + if (grub_biosdisk_get_diskinfo_standard (drive, + &data->cylinders, + &data->heads, + &data->sectors) != 0) + { + if (total_sectors && (data->flags & GRUB_BIOSDISK_FLAG_LBA)) + { + data->sectors = 63; + data->heads = 255; + data->cylinders + = grub_divmod64 (total_sectors + + data->heads * data->sectors - 1, + data->heads * data->sectors, 0); + } + else + { + grub_free (data); + return grub_error (GRUB_ERR_BAD_DEVICE, "%s cannot get C/H/S values", disk->name); + } + } + + if (data->sectors == 0) + data->sectors = 63; + if (data->heads == 0) + data->heads = 255; + + if (! total_sectors) + total_sectors = ((grub_uint64_t) data->cylinders) + * data->heads * data->sectors; + } + + disk->total_sectors = total_sectors; + /* Limit the max to 0x7f because of Phoenix EDD. */ + disk->max_agglomerate = 0x7f >> GRUB_DISK_CACHE_BITS; + COMPILE_TIME_ASSERT ((0x7f >> GRUB_DISK_CACHE_BITS + << (GRUB_DISK_SECTOR_BITS + GRUB_DISK_CACHE_BITS)) + + sizeof (struct grub_biosdisk_dap) + < GRUB_MEMORY_MACHINE_SCRATCH_SIZE); + + disk->data = data; + + //fixup some buggy bios + if (total_sectors > (16434495 - 2097152) && total_sectors < (16434495 + 2097152) && + (data->flags & GRUB_BIOSDISK_FLAG_LBA) > 0 && (data->flags & GRUB_BIOSDISK_FLAG_CDROM) == 0) { + if (grub_biosdisk_rw(0, disk, 0, 1, GRUB_MEMORY_MACHINE_SCRATCH_SEG) == 0) { + ventoy_mbr_head *mbr = (ventoy_mbr_head *)GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + if (ventoy_is_mbr_match(mbr)) { + total_sectors = mbr->PartTbl[1].StartSectorId + mbr->PartTbl[1].SectorCount + 1; + if (disk->total_sectors < total_sectors) { + disk->total_sectors = total_sectors; + } + } + } + } + + return GRUB_ERR_NONE; +} + +static void +grub_biosdisk_close (grub_disk_t disk) +{ + grub_free (disk->data); +} + +/* For readability. */ +#define GRUB_BIOSDISK_READ 0 +#define GRUB_BIOSDISK_WRITE 1 + +#define GRUB_BIOSDISK_CDROM_RETRY_COUNT 3 + +static grub_err_t +grub_biosdisk_rw (int cmd, grub_disk_t disk, + grub_disk_addr_t sector, grub_size_t size, + unsigned segment) +{ + struct grub_biosdisk_data *data = disk->data; + + /* VirtualBox fails with sectors above 2T on CDs. + Since even BD-ROMS are never that big anyway, return error. */ + if ((data->flags & GRUB_BIOSDISK_FLAG_CDROM) + && (sector >> 32)) + return grub_error (GRUB_ERR_OUT_OF_RANGE, + N_("attempt to read or write outside of disk `%s'"), + disk->name); + + if (data->flags & GRUB_BIOSDISK_FLAG_LBA) + { + struct grub_biosdisk_dap *dap; + + dap = (struct grub_biosdisk_dap *) (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + + (data->sectors + << disk->log_sector_size)); + dap->length = sizeof (*dap); + dap->reserved = 0; + dap->blocks = size; + dap->buffer = segment << 16; /* The format SEGMENT:ADDRESS. */ + dap->block = sector; + + if (data->flags & GRUB_BIOSDISK_FLAG_CDROM) + { + int i; + + if (cmd) + return grub_error (GRUB_ERR_WRITE_ERROR, N_("cannot write to CD-ROM")); + + for (i = 0; i < GRUB_BIOSDISK_CDROM_RETRY_COUNT; i++) + if (! grub_biosdisk_rw_int13_extensions (0x42, data->drive, dap)) + break; + + if (i == GRUB_BIOSDISK_CDROM_RETRY_COUNT) + return grub_error (GRUB_ERR_READ_ERROR, N_("failure reading sector 0x%llx " + "from `%s'"), + (unsigned long long) sector, + disk->name); + } + else + if (grub_biosdisk_rw_int13_extensions (cmd + 0x42, data->drive, dap)) + { + /* Fall back to the CHS mode. */ + data->flags &= ~GRUB_BIOSDISK_FLAG_LBA; + disk->total_sectors = data->cylinders * data->heads * data->sectors; + return grub_biosdisk_rw (cmd, disk, sector, size, segment); + } + } + else + { + unsigned coff, hoff, soff; + unsigned head; + + /* It is impossible to reach over 8064 MiB (a bit less than LBA24) with + the traditional CHS access. */ + if (sector > + 1024 /* cylinders */ * + 256 /* heads */ * + 63 /* spt */) + return grub_error (GRUB_ERR_OUT_OF_RANGE, + N_("attempt to read or write outside of disk `%s'"), + disk->name); + + soff = ((grub_uint32_t) sector) % data->sectors + 1; + head = ((grub_uint32_t) sector) / data->sectors; + hoff = head % data->heads; + coff = head / data->heads; + + if (coff >= data->cylinders) + return grub_error (GRUB_ERR_OUT_OF_RANGE, + N_("attempt to read or write outside of disk `%s'"), + disk->name); + + if (grub_biosdisk_rw_standard (cmd + 0x02, data->drive, + coff, hoff, soff, size, segment)) + { + switch (cmd) + { + case GRUB_BIOSDISK_READ: + return grub_error (GRUB_ERR_READ_ERROR, N_("failure reading sector 0x%llx " + "from `%s'"), + (unsigned long long) sector, + disk->name); + case GRUB_BIOSDISK_WRITE: + return grub_error (GRUB_ERR_WRITE_ERROR, N_("failure writing sector 0x%llx " + "to `%s'"), + (unsigned long long) sector, + disk->name); + } + } + } + + return GRUB_ERR_NONE; +} + +/* Return the number of sectors which can be read safely at a time. */ +static grub_size_t +get_safe_sectors (grub_disk_t disk, grub_disk_addr_t sector) +{ + grub_size_t size; + grub_uint64_t offset; + struct grub_biosdisk_data *data = disk->data; + grub_uint32_t sectors = data->sectors; + + /* OFFSET = SECTOR % SECTORS */ + grub_divmod64 (sector, sectors, &offset); + + size = sectors - offset; + + return size; +} + +static grub_err_t +grub_biosdisk_read (grub_disk_t disk, grub_disk_addr_t sector, + grub_size_t size, char *buf) +{ + while (size) + { + grub_size_t len; + + len = get_safe_sectors (disk, sector); + + if (len > size) + len = size; + + if (grub_biosdisk_rw (GRUB_BIOSDISK_READ, disk, sector, len, + GRUB_MEMORY_MACHINE_SCRATCH_SEG)) + return grub_errno; + + grub_memcpy (buf, (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR, + len << disk->log_sector_size); + + buf += len << disk->log_sector_size; + sector += len; + size -= len; + } + + return grub_errno; +} + +static grub_err_t +grub_biosdisk_write (grub_disk_t disk, grub_disk_addr_t sector, + grub_size_t size, const char *buf) +{ + struct grub_biosdisk_data *data = disk->data; + + if (data->flags & GRUB_BIOSDISK_FLAG_CDROM) + return grub_error (GRUB_ERR_IO, N_("cannot write to CD-ROM")); + + while (size) + { + grub_size_t len; + + len = get_safe_sectors (disk, sector); + if (len > size) + len = size; + + grub_memcpy ((void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR, buf, + len << disk->log_sector_size); + + if (grub_biosdisk_rw (GRUB_BIOSDISK_WRITE, disk, sector, len, + GRUB_MEMORY_MACHINE_SCRATCH_SEG)) + return grub_errno; + + buf += len << disk->log_sector_size; + sector += len; + size -= len; + } + + return grub_errno; +} + +static struct grub_disk_dev grub_biosdisk_dev = + { + .name = "biosdisk", + .id = GRUB_DISK_DEVICE_BIOSDISK_ID, + .disk_iterate = grub_biosdisk_iterate, + .disk_open = grub_biosdisk_open, + .disk_close = grub_biosdisk_close, + .disk_read = grub_biosdisk_read, + .disk_write = grub_biosdisk_write, + .next = 0 + }; + +static void +grub_disk_biosdisk_fini (void) +{ + grub_disk_dev_unregister (&grub_biosdisk_dev); +} + +GRUB_MOD_INIT(biosdisk) +{ + struct grub_biosdisk_cdrp *cdrp + = (struct grub_biosdisk_cdrp *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + grub_uint8_t boot_drive; + + if (grub_disk_firmware_is_tainted) + { + grub_puts_ (N_("Native disk drivers are in use. " + "Refusing to use firmware disk interface.")); + return; + } + grub_disk_firmware_fini = grub_disk_biosdisk_fini; + + grub_memset (cdrp, 0, sizeof (*cdrp)); + cdrp->size = sizeof (*cdrp); + cdrp->media_type = 0xFF; + boot_drive = (grub_boot_device >> 24); + if ((! grub_biosdisk_get_cdinfo_int13_extensions (boot_drive, cdrp)) + && ((cdrp->media_type & GRUB_BIOSDISK_CDTYPE_MASK) + == GRUB_BIOSDISK_CDTYPE_NO_EMUL)) + cd_drive = cdrp->drive_no; + /* Since diskboot.S rejects devices over 0x90 it must be a CD booted with + cdboot.S + */ + if (boot_drive >= 0x90) + cd_drive = boot_drive; + + grub_disk_dev_register (&grub_biosdisk_dev); +} + +GRUB_MOD_FINI(biosdisk) +{ + grub_disk_biosdisk_fini (); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/disk/loopback.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/disk/loopback.c new file mode 100644 index 0000000..ef946a4 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/disk/loopback.c @@ -0,0 +1,257 @@ +/* loopback.c - command to add loopback devices. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +struct grub_loopback +{ + char *devname; + grub_file_t file; + struct grub_loopback *next; + unsigned long id; + grub_off_t skip; +}; + +static struct grub_loopback *loopback_list; +static unsigned long last_id = 0; + +static const struct grub_arg_option options[] = + { + /* TRANSLATORS: The disk is simply removed from the list of available ones, + not wiped, avoid to scare user. */ + {"delete", 'd', 0, N_("Delete the specified loopback drive."), 0, 0}, + {"skip", 's', 0, "skip sectors of the file.", "SECTORS", ARG_TYPE_INT }, + {0, 0, 0, 0, 0, 0} + }; + +/* Delete the loopback device NAME. */ +static grub_err_t +delete_loopback (const char *name) +{ + struct grub_loopback *dev; + struct grub_loopback **prev; + + /* Search for the device. */ + for (dev = loopback_list, prev = &loopback_list; + dev; + prev = &dev->next, dev = dev->next) + if (grub_strcmp (dev->devname, name) == 0) + break; + + if (! dev) + return grub_error (GRUB_ERR_BAD_DEVICE, "device not found"); + + /* Remove the device from the list. */ + *prev = dev->next; + + grub_free (dev->devname); + grub_file_close (dev->file); + grub_free (dev); + + return 0; +} + +/* The command to add and remove loopback devices. */ +static grub_err_t +grub_cmd_loopback (grub_extcmd_context_t ctxt, int argc, char **args) +{ + struct grub_arg_list *state = ctxt->state; + grub_file_t file; + struct grub_loopback *newdev; + grub_err_t ret; + grub_off_t skip = 0; + + if (argc < 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); + + /* Check if `-d' was used. */ + if (state[0].set) + return delete_loopback (args[0]); + + if (state[1].set) + skip = (grub_off_t)grub_strtoull(state[1].arg, NULL, 10); + + if (argc < 2) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + + file = grub_file_open (args[1], GRUB_FILE_TYPE_LOOPBACK + | GRUB_FILE_TYPE_NO_DECOMPRESS); + if (! file) + return grub_errno; + + /* First try to replace the old device. */ + for (newdev = loopback_list; newdev; newdev = newdev->next) + if (grub_strcmp (newdev->devname, args[0]) == 0) + break; + + if (newdev) + { + grub_file_close (newdev->file); + newdev->file = file; + newdev->skip = skip; + + return 0; + } + + /* Unable to replace it, make a new entry. */ + newdev = grub_malloc (sizeof (struct grub_loopback)); + if (! newdev) + goto fail; + + newdev->devname = grub_strdup (args[0]); + if (! newdev->devname) + { + grub_free (newdev); + goto fail; + } + + newdev->file = file; + newdev->skip = skip; + newdev->id = last_id++; + + /* Add the new entry to the list. */ + newdev->next = loopback_list; + loopback_list = newdev; + + return 0; + +fail: + ret = grub_errno; + grub_file_close (file); + return ret; +} + + +static int +grub_loopback_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, + grub_disk_pull_t pull) +{ + struct grub_loopback *d; + if (pull != GRUB_DISK_PULL_NONE) + return 0; + for (d = loopback_list; d; d = d->next) + { + if (hook (d->devname, hook_data)) + return 1; + } + return 0; +} + +static grub_err_t +grub_loopback_open (const char *name, grub_disk_t disk) +{ + struct grub_loopback *dev; + + for (dev = loopback_list; dev; dev = dev->next) + if (grub_strcmp (dev->devname, name) == 0) + break; + + if (! dev) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device"); + + /* Use the filesize for the disk size, round up to a complete sector. */ + if (dev->file->size != GRUB_FILE_SIZE_UNKNOWN) + disk->total_sectors = ((dev->file->size + GRUB_DISK_SECTOR_SIZE - 1) + / GRUB_DISK_SECTOR_SIZE); + else + disk->total_sectors = GRUB_DISK_SIZE_UNKNOWN; + /* Avoid reading more than 512M. */ + disk->max_agglomerate = 1 << (29 - GRUB_DISK_SECTOR_BITS + - GRUB_DISK_CACHE_BITS); + + disk->id = dev->id; + + disk->data = dev; + + return 0; +} + +static grub_err_t +grub_loopback_read (grub_disk_t disk, grub_disk_addr_t sector, + grub_size_t size, char *buf) +{ + grub_file_t file = ((struct grub_loopback *) disk->data)->file; + grub_off_t skip = ((struct grub_loopback *) disk->data)->skip; + grub_off_t pos; + + grub_file_seek (file, (sector + skip) << GRUB_DISK_SECTOR_BITS); + + grub_file_read (file, buf, size << GRUB_DISK_SECTOR_BITS); + if (grub_errno) + return grub_errno; + + /* In case there is more data read than there is available, in case + of files that are not a multiple of GRUB_DISK_SECTOR_SIZE, fill + the rest with zeros. */ + pos = (sector + skip + size) << GRUB_DISK_SECTOR_BITS; + if (pos > file->size) + { + grub_size_t amount = pos - file->size; + grub_memset (buf + (size << GRUB_DISK_SECTOR_BITS) - amount, 0, amount); + } + + return 0; +} + +static grub_err_t +grub_loopback_write (grub_disk_t disk __attribute ((unused)), + grub_disk_addr_t sector __attribute ((unused)), + grub_size_t size __attribute ((unused)), + const char *buf __attribute ((unused))) +{ + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "loopback write is not supported"); +} + +static struct grub_disk_dev grub_loopback_dev = + { + .name = "loopback", + .id = GRUB_DISK_DEVICE_LOOPBACK_ID, + .disk_iterate = grub_loopback_iterate, + .disk_open = grub_loopback_open, + .disk_read = grub_loopback_read, + .disk_write = grub_loopback_write, + .next = 0 + }; + +static grub_extcmd_t cmd; + +GRUB_MOD_INIT(loopback) +{ + cmd = grub_register_extcmd ("loopback", grub_cmd_loopback, 0, + N_("[-d] DEVICENAME FILE."), + /* TRANSLATORS: The file itself is not destroyed + or transformed into drive. */ + N_("Make a virtual drive from a file."), options); + grub_disk_dev_register (&grub_loopback_dev); +} + +GRUB_MOD_FINI(loopback) +{ + grub_unregister_extcmd (cmd); + grub_disk_dev_unregister (&grub_loopback_dev); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/font/font.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/font/font.c new file mode 100644 index 0000000..b12fb6b --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/font/font.c @@ -0,0 +1,1603 @@ +/* font.c - Font API and font file loader. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +#if HAVE_FONT_SOURCE +#include "ascii.h" +#endif + +#ifndef FONT_DEBUG +#define FONT_DEBUG 0 +#endif + +struct char_index_entry +{ + grub_uint32_t code; + grub_uint8_t storage_flags; + grub_uint32_t offset; + + /* Glyph if loaded, or NULL otherwise. */ + struct grub_font_glyph *glyph; +}; + +#define FONT_WEIGHT_NORMAL 100 +#define FONT_WEIGHT_BOLD 200 +#define ASCII_BITMAP_SIZE 16 + +/* Definition of font registry. */ +struct grub_font_node *grub_font_list; + +static int register_font (grub_font_t font); +static void font_init (grub_font_t font); +static void free_font (grub_font_t font); +static void remove_font (grub_font_t font); + +struct font_file_section +{ + /* The file this section is in. */ + grub_file_t file; + + /* FOURCC name of the section. */ + char name[4]; + + /* Length of the section contents. */ + grub_uint32_t length; + + /* Set by open_section() on EOF. */ + int eof; +}; + +/* Replace unknown glyphs with a rounded question mark. */ +static grub_uint8_t unknown_glyph_bitmap[] = { + /* 76543210 */ + 0x7C, /* ooooo */ + 0x82, /* o o */ + 0xBA, /* o ooo o */ + 0xAA, /* o o o o */ + 0xAA, /* o o o o */ + 0x8A, /* o o o */ + 0x9A, /* o oo o */ + 0x92, /* o o o */ + 0x92, /* o o o */ + 0x92, /* o o o */ + 0x92, /* o o o */ + 0x82, /* o o */ + 0x92, /* o o o */ + 0x82, /* o o */ + 0x7C, /* ooooo */ + 0x00 /* */ +}; + +/* The "unknown glyph" glyph, used as a last resort. */ +static struct grub_font_glyph *unknown_glyph; + +/* The font structure used when no other font is loaded. This functions + as a "Null Object" pattern, so that code everywhere does not have to + check for a NULL grub_font_t to avoid dereferencing a null pointer. */ +static struct grub_font null_font; + +/* Flag to ensure module is initialized only once. */ +static grub_uint8_t font_loader_initialized; + +#if HAVE_FONT_SOURCE +static struct grub_font_glyph *ascii_font_glyph[0x80]; +#endif + +static struct grub_font_glyph * +ascii_glyph_lookup (grub_uint32_t code) +{ +#if HAVE_FONT_SOURCE + static int ascii_failback_initialized = 0; + + if (code >= 0x80) + return NULL; + + if (ascii_failback_initialized == 0) + { + int current; + for (current = 0; current < 0x80; current++) + { + ascii_font_glyph[current] = + grub_malloc (sizeof (struct grub_font_glyph) + ASCII_BITMAP_SIZE); + + ascii_font_glyph[current]->width = 8; + ascii_font_glyph[current]->height = 16; + ascii_font_glyph[current]->offset_x = 0; + ascii_font_glyph[current]->offset_y = -2; + ascii_font_glyph[current]->device_width = 8; + ascii_font_glyph[current]->font = NULL; + + grub_memcpy (ascii_font_glyph[current]->bitmap, + &ascii_bitmaps[current * ASCII_BITMAP_SIZE], + ASCII_BITMAP_SIZE); + } + + ascii_failback_initialized = 1; + } + + return ascii_font_glyph[code]; +#else + (void) code; + return NULL; +#endif +} + +void +grub_font_loader_init (void) +{ + /* Only initialize font loader once. */ + if (font_loader_initialized) + return; + + /* Make glyph for unknown glyph. */ + unknown_glyph = grub_malloc (sizeof (struct grub_font_glyph) + + sizeof (unknown_glyph_bitmap)); + if (!unknown_glyph) + return; + + unknown_glyph->width = 8; + unknown_glyph->height = 16; + unknown_glyph->offset_x = 0; + unknown_glyph->offset_y = -3; + unknown_glyph->device_width = 8; + grub_memcpy (unknown_glyph->bitmap, + unknown_glyph_bitmap, sizeof (unknown_glyph_bitmap)); + + /* Initialize the null font. */ + font_init (&null_font); + /* FIXME: Fix this slightly improper cast. */ + null_font.name = (char *) ""; + null_font.ascent = unknown_glyph->height - 3; + null_font.descent = 3; + null_font.max_char_width = unknown_glyph->width; + null_font.max_char_height = unknown_glyph->height; + + font_loader_initialized = 1; +} + +/* Initialize the font object with initial default values. */ +static void +font_init (grub_font_t font) +{ + font->name = 0; + font->file = 0; + font->family = 0; + font->point_size = 0; + font->weight = 0; + + /* Default leading value, not in font file yet. */ + font->leading = 1; + + font->max_char_width = 0; + font->max_char_height = 0; + font->ascent = 0; + font->descent = 0; + font->num_chars = 0; + font->char_index = 0; + font->bmp_idx = 0; +} + +/* Open the next section in the file. + + On success, the section name is stored in section->name and the length in + section->length, and 0 is returned. On failure, 1 is returned and + grub_errno is set appropriately with an error message. + + If 1 is returned due to being at the end of the file, then section->eof is + set to 1; otherwise, section->eof is set to 0. */ +static int +open_section (grub_file_t file, struct font_file_section *section) +{ + grub_ssize_t retval; + grub_uint32_t raw_length; + + section->file = file; + section->eof = 0; + + /* Read the FOURCC section name. */ + retval = grub_file_read (file, section->name, 4); + if (retval >= 0 && retval < 4) + { + /* EOF encountered. */ + section->eof = 1; + return 1; + } + else if (retval < 0) + { + /* Read error. */ + return 1; + } + + /* Read the big-endian 32-bit section length. */ + retval = grub_file_read (file, &raw_length, 4); + if (retval >= 0 && retval < 4) + { + /* EOF encountered. */ + section->eof = 1; + return 1; + } + else if (retval < 0) + { + /* Read error. */ + return 1; + } + + /* Convert byte-order and store in *length. */ + section->length = grub_be_to_cpu32 (raw_length); + + return 0; +} + +/* Size in bytes of each character index (CHIX section) + entry in the font file. */ +#define FONT_CHAR_INDEX_ENTRY_SIZE (4 + 1 + 4) + +/* Load the character index (CHIX) section contents from the font file. This + presumes that the position of FILE is positioned immediately after the + section length for the CHIX section (i.e., at the start of the section + contents). Returns 0 upon success, nonzero for failure (in which case + grub_errno is set appropriately). */ +static int +load_font_index (grub_file_t file, grub_uint32_t sect_length, struct + grub_font *font) +{ + unsigned i; + grub_uint32_t last_code; + +#if FONT_DEBUG >= 2 + grub_dprintf ("font", "load_font_index(sect_length=%d)\n", sect_length); +#endif + + /* Sanity check: ensure section length is divisible by the entry size. */ + if ((sect_length % FONT_CHAR_INDEX_ENTRY_SIZE) != 0) + { + grub_error (GRUB_ERR_BAD_FONT, + "font file format error: character index length %d " + "is not a multiple of the entry size %d", + sect_length, FONT_CHAR_INDEX_ENTRY_SIZE); + return 1; + } + + /* Calculate the number of characters. */ + font->num_chars = sect_length / FONT_CHAR_INDEX_ENTRY_SIZE; + + /* Allocate the character index array. */ + font->char_index = grub_malloc (font->num_chars + * sizeof (struct char_index_entry)); + if (!font->char_index) + return 1; + font->bmp_idx = grub_malloc (0x10000 * sizeof (grub_uint16_t)); + if (!font->bmp_idx) + return 1; + grub_memset (font->bmp_idx, 0xff, 0x10000 * sizeof (grub_uint16_t)); + + +#if FONT_DEBUG >= 2 + grub_dprintf ("font", "num_chars=%d)\n", font->num_chars); +#endif + + last_code = 0; + + /* Load the character index data from the file. */ + for (i = 0; i < font->num_chars; i++) + { + struct char_index_entry *entry = &font->char_index[i]; + + /* Read code point value; convert to native byte order. */ + if (grub_file_read (file, &entry->code, 4) != 4) + return 1; + entry->code = grub_be_to_cpu32 (entry->code); + + /* Verify that characters are in ascending order. */ + if (i != 0 && entry->code <= last_code) + { + grub_error (GRUB_ERR_BAD_FONT, + "font characters not in ascending order: %u <= %u", + entry->code, last_code); + return 1; + } + + if (entry->code < 0x10000) + font->bmp_idx[entry->code] = i; + + last_code = entry->code; + + /* Read storage flags byte. */ + if (grub_file_read (file, &entry->storage_flags, 1) != 1) + return 1; + + /* Read glyph data offset; convert to native byte order. */ + if (grub_file_read (file, &entry->offset, 4) != 4) + return 1; + entry->offset = grub_be_to_cpu32 (entry->offset); + + /* No glyph loaded. Will be loaded on demand and cached thereafter. */ + entry->glyph = 0; + +#if FONT_DEBUG >= 5 + /* Print the 1st 10 characters. */ + if (i < 10) + grub_dprintf ("font", "c=%d o=%d\n", entry->code, entry->offset); +#endif + } + + return 0; +} + +/* Read the contents of the specified section as a string, which is + allocated on the heap. Returns 0 if there is an error. */ +static char * +read_section_as_string (struct font_file_section *section) +{ + char *str; + grub_ssize_t ret; + + str = grub_malloc (section->length + 1); + if (!str) + return 0; + + ret = grub_file_read (section->file, str, section->length); + if (ret < 0 || ret != (grub_ssize_t) section->length) + { + grub_free (str); + return 0; + } + + str[section->length] = '\0'; + return str; +} + +/* Read the contents of the current section as a 16-bit integer value, + which is stored into *VALUE. + Returns 0 upon success, nonzero upon failure. */ +static int +read_section_as_short (struct font_file_section *section, + grub_int16_t * value) +{ + grub_uint16_t raw_value; + + if (section->length != 2) + { + grub_error (GRUB_ERR_BAD_FONT, + "font file format error: section %c%c%c%c length " + "is %d but should be 2", + section->name[0], section->name[1], + section->name[2], section->name[3], section->length); + return 1; + } + if (grub_file_read (section->file, &raw_value, 2) != 2) + return 1; + + *value = grub_be_to_cpu16 (raw_value); + return 0; +} + +/* Load a font and add it to the beginning of the global font list. + Returns 0 upon success, nonzero upon failure. */ +grub_font_t +grub_font_load (const char *filename) +{ + grub_file_t file = 0; + struct font_file_section section; + char magic[4]; + grub_font_t font = 0; + +#if FONT_DEBUG >= 1 + grub_dprintf ("font", "add_font(%s)\n", filename); +#endif + + if (filename[0] == '(' || filename[0] == '/' || filename[0] == '+') + file = grub_buffile_open (filename, GRUB_FILE_TYPE_FONT, 1024); + else if (grub_strncmp(filename, "mem:", 4) == 0) + file = grub_buffile_open (filename, GRUB_FILE_TYPE_FONT, 1024); + else + { + const char *prefix = grub_env_get ("prefix"); + char *fullname, *ptr; + if (!prefix) + { + grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), + "prefix"); + goto fail; + } + fullname = grub_malloc (grub_strlen (prefix) + grub_strlen (filename) + 1 + + sizeof ("/fonts/") + sizeof (".pf2")); + if (!fullname) + goto fail; + ptr = grub_stpcpy (fullname, prefix); + ptr = grub_stpcpy (ptr, "/fonts/"); + ptr = grub_stpcpy (ptr, filename); + ptr = grub_stpcpy (ptr, ".pf2"); + *ptr = 0; + file = grub_buffile_open (fullname, GRUB_FILE_TYPE_FONT, 1024); + grub_free (fullname); + } + if (!file) + goto fail; + +#if FONT_DEBUG >= 3 + grub_dprintf ("font", "file opened\n"); +#endif + + /* Read the FILE section. It indicates the file format. */ + if (open_section (file, §ion) != 0) + goto fail; + +#if FONT_DEBUG >= 3 + grub_dprintf ("font", "opened FILE section\n"); +#endif + if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_FILE, + sizeof (FONT_FORMAT_SECTION_NAMES_FILE) - 1) != 0) + { + grub_error (GRUB_ERR_BAD_FONT, + "font file format error: 1st section must be FILE"); + goto fail; + } + +#if FONT_DEBUG >= 3 + grub_dprintf ("font", "section name ok\n"); +#endif + if (section.length != 4) + { + grub_error (GRUB_ERR_BAD_FONT, + "font file format error (file type ID length is %d " + "but should be 4)", section.length); + goto fail; + } + +#if FONT_DEBUG >= 3 + grub_dprintf ("font", "section length ok\n"); +#endif + /* Check the file format type code. */ + if (grub_file_read (file, magic, 4) != 4) + goto fail; + +#if FONT_DEBUG >= 3 + grub_dprintf ("font", "read magic ok\n"); +#endif + + if (grub_memcmp (magic, FONT_FORMAT_PFF2_MAGIC, 4) != 0) + { + grub_error (GRUB_ERR_BAD_FONT, "invalid font magic %x %x %x %x", + magic[0], magic[1], magic[2], magic[3]); + goto fail; + } + +#if FONT_DEBUG >= 3 + grub_dprintf ("font", "compare magic ok\n"); +#endif + + /* Allocate the font object. */ + font = (grub_font_t) grub_zalloc (sizeof (struct grub_font)); + if (!font) + goto fail; + + font_init (font); + font->file = file; + +#if FONT_DEBUG >= 3 + grub_dprintf ("font", "allocate font ok; loading font info\n"); +#endif + + /* Load the font information. */ + while (1) + { + if (open_section (file, §ion) != 0) + { + if (section.eof) + break; /* Done reading the font file. */ + else + goto fail; + } + +#if FONT_DEBUG >= 2 + grub_dprintf ("font", "opened section %c%c%c%c ok\n", + section.name[0], section.name[1], + section.name[2], section.name[3]); +#endif + + if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_FONT_NAME, + sizeof (FONT_FORMAT_SECTION_NAMES_FONT_NAME) - 1) == 0) + { + font->name = read_section_as_string (§ion); + if (!font->name) + goto fail; + } + else if (grub_memcmp (section.name, + FONT_FORMAT_SECTION_NAMES_POINT_SIZE, + sizeof (FONT_FORMAT_SECTION_NAMES_POINT_SIZE) - + 1) == 0) + { + if (read_section_as_short (§ion, &font->point_size) != 0) + goto fail; + } + else if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_WEIGHT, + sizeof (FONT_FORMAT_SECTION_NAMES_WEIGHT) - 1) + == 0) + { + char *wt; + wt = read_section_as_string (§ion); + if (!wt) + continue; + /* Convert the weight string 'normal' or 'bold' into a number. */ + if (grub_strcmp (wt, "normal") == 0) + font->weight = FONT_WEIGHT_NORMAL; + else if (grub_strcmp (wt, "bold") == 0) + font->weight = FONT_WEIGHT_BOLD; + grub_free (wt); + } + else if (grub_memcmp (section.name, + FONT_FORMAT_SECTION_NAMES_MAX_CHAR_WIDTH, + sizeof (FONT_FORMAT_SECTION_NAMES_MAX_CHAR_WIDTH) + - 1) == 0) + { + if (read_section_as_short (§ion, &font->max_char_width) != 0) + goto fail; + } + else if (grub_memcmp (section.name, + FONT_FORMAT_SECTION_NAMES_MAX_CHAR_HEIGHT, + sizeof (FONT_FORMAT_SECTION_NAMES_MAX_CHAR_HEIGHT) + - 1) == 0) + { + if (read_section_as_short (§ion, &font->max_char_height) != 0) + goto fail; + } + else if (grub_memcmp (section.name, + FONT_FORMAT_SECTION_NAMES_ASCENT, + sizeof (FONT_FORMAT_SECTION_NAMES_ASCENT) - 1) + == 0) + { + if (read_section_as_short (§ion, &font->ascent) != 0) + goto fail; + } + else if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_DESCENT, + sizeof (FONT_FORMAT_SECTION_NAMES_DESCENT) - 1) + == 0) + { + if (read_section_as_short (§ion, &font->descent) != 0) + goto fail; + } + else if (grub_memcmp (section.name, + FONT_FORMAT_SECTION_NAMES_CHAR_INDEX, + sizeof (FONT_FORMAT_SECTION_NAMES_CHAR_INDEX) - + 1) == 0) + { + if (load_font_index (file, section.length, font) != 0) + goto fail; + } + else if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_DATA, + sizeof (FONT_FORMAT_SECTION_NAMES_DATA) - 1) == 0) + { + /* When the DATA section marker is reached, we stop reading. */ + break; + } + else + { + /* Unhandled section type, simply skip past it. */ +#if FONT_DEBUG >= 3 + grub_dprintf ("font", "Unhandled section type, skipping.\n"); +#endif + grub_off_t section_end = grub_file_tell (file) + section.length; + if ((int) grub_file_seek (file, section_end) == -1) + goto fail; + } + } + + if (!font->name) + { + grub_dprintf ("font", "Font has no name.\n"); + font->name = grub_strdup ("Unknown"); + } + +#if FONT_DEBUG >= 1 + grub_dprintf ("font", "Loaded font `%s'.\n" + "Ascent=%d Descent=%d MaxW=%d MaxH=%d Number of characters=%d.\n", + font->name, + font->ascent, font->descent, + font->max_char_width, font->max_char_height, font->num_chars); +#endif + + if (font->max_char_width == 0 + || font->max_char_height == 0 + || font->num_chars == 0 + || font->char_index == 0 || font->ascent == 0 || font->descent == 0) + { + grub_error (GRUB_ERR_BAD_FONT, + "invalid font file: missing some required data"); + goto fail; + } + + /* Add the font to the global font registry. */ + if (register_font (font) != 0) + goto fail; + + return font; + +fail: + if (file) + grub_file_close (file); + if (font) + font->file = 0; + + free_font (font); + return 0; +} + +/* Read a 16-bit big-endian integer from FILE, convert it to native byte + order, and store it in *VALUE. + Returns 0 on success, 1 on failure. */ +static int +read_be_uint16 (grub_file_t file, grub_uint16_t * value) +{ + if (grub_file_read (file, value, 2) != 2) + return 1; + *value = grub_be_to_cpu16 (*value); + return 0; +} + +static int +read_be_int16 (grub_file_t file, grub_int16_t * value) +{ + /* For the signed integer version, use the same code as for unsigned. */ + return read_be_uint16 (file, (grub_uint16_t *) value); +} + +/* Return a pointer to the character index entry for the glyph corresponding to + the codepoint CODE in the font FONT. If not found, return zero. */ +static inline struct char_index_entry * +find_glyph (const grub_font_t font, grub_uint32_t code) +{ + struct char_index_entry *table; + grub_size_t lo; + grub_size_t hi; + grub_size_t mid; + + table = font->char_index; + + /* Use BMP index if possible. */ + if (code < 0x10000 && font->bmp_idx) + { + if (font->bmp_idx[code] == 0xffff) + return 0; + return &table[font->bmp_idx[code]]; + } + + /* Do a binary search in `char_index', which is ordered by code point. */ + lo = 0; + hi = font->num_chars - 1; + + if (!table) + return 0; + + while (lo <= hi) + { + mid = lo + (hi - lo) / 2; + if (code < table[mid].code) + hi = mid - 1; + else if (code > table[mid].code) + lo = mid + 1; + else + return &table[mid]; + } + + return 0; +} + +/* Get a glyph for the Unicode character CODE in FONT. The glyph is loaded + from the font file if has not been loaded yet. + Returns a pointer to the glyph if found, or 0 if it is not found. */ +static struct grub_font_glyph * +grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code) +{ + struct char_index_entry *index_entry; + + index_entry = find_glyph (font, code); + if (index_entry) + { + struct grub_font_glyph *glyph = 0; + grub_uint16_t width; + grub_uint16_t height; + grub_int16_t xoff; + grub_int16_t yoff; + grub_int16_t dwidth; + int len; + + if (index_entry->glyph) + /* Return cached glyph. */ + return index_entry->glyph; + + if (!font->file) + /* No open file, can't load any glyphs. */ + return 0; + + /* Make sure we can find glyphs for error messages. Push active + error message to error stack and reset error message. */ + grub_error_push (); + + grub_file_seek (font->file, index_entry->offset); + + /* Read the glyph width, height, and baseline. */ + if (read_be_uint16 (font->file, &width) != 0 + || read_be_uint16 (font->file, &height) != 0 + || read_be_int16 (font->file, &xoff) != 0 + || read_be_int16 (font->file, &yoff) != 0 + || read_be_int16 (font->file, &dwidth) != 0) + { + remove_font (font); + return 0; + } + + len = (width * height + 7) / 8; + glyph = grub_malloc (sizeof (struct grub_font_glyph) + len); + if (!glyph) + { + remove_font (font); + return 0; + } + + glyph->font = font; + glyph->width = width; + glyph->height = height; + glyph->offset_x = xoff; + glyph->offset_y = yoff; + glyph->device_width = dwidth; + + /* Don't try to read empty bitmaps (e.g., space characters). */ + if (len != 0) + { + if (grub_file_read (font->file, glyph->bitmap, len) != len) + { + remove_font (font); + grub_free (glyph); + return 0; + } + } + + /* Restore old error message. */ + grub_error_pop (); + + /* Cache the glyph. */ + index_entry->glyph = glyph; + + return glyph; + } + + return 0; +} + +/* Free the memory used by FONT. + This should not be called if the font has been made available to + users (once it is added to the global font list), since there would + be the possibility of a dangling pointer. */ +static void +free_font (grub_font_t font) +{ + if (font) + { + if (font->file) + grub_file_close (font->file); + grub_free (font->name); + grub_free (font->family); + grub_free (font->char_index); + grub_free (font->bmp_idx); + grub_free (font); + } +} + +/* Add FONT to the global font registry. + Returns 0 upon success, nonzero on failure + (the font was not registered). */ +static int +register_font (grub_font_t font) +{ + struct grub_font_node *node = 0; + + node = grub_malloc (sizeof (struct grub_font_node)); + if (!node) + return 1; + + node->value = font; + node->next = grub_font_list; + grub_font_list = node; + + return 0; +} + +/* Remove the font from the global font list. We don't actually free the + font's memory since users could be holding references to the font. */ +static void +remove_font (grub_font_t font) +{ + struct grub_font_node **nextp, *cur; + + for (nextp = &grub_font_list, cur = *nextp; + cur; nextp = &cur->next, cur = cur->next) + { + if (cur->value == font) + { + *nextp = cur->next; + + /* Free the node, but not the font itself. */ + grub_free (cur); + + return; + } + } +} + +/* Get a font from the list of loaded fonts. This function will return + another font if the requested font is not available. If no fonts are + loaded, then a special 'null font' is returned, which contains no glyphs, + but is not a null pointer so the caller may omit checks for NULL. */ +grub_font_t +grub_font_get (const char *font_name) +{ + struct grub_font_node *node; + + for (node = grub_font_list; node; node = node->next) + { + grub_font_t font = node->value; + if (grub_strcmp (font->name, font_name) == 0) + return font; + } + + /* If no font by that name is found, return the first font in the list + as a fallback. */ + if (grub_font_list && grub_font_list->value) + return grub_font_list->value; + else + /* The null_font is a last resort. */ + return &null_font; +} + +/* Get the full name of the font. */ +const char * +grub_font_get_name (grub_font_t font) +{ + return font->name; +} + +/* Get the maximum width of any character in the font in pixels. */ +int +grub_font_get_max_char_width (grub_font_t font) +{ + return font->max_char_width; +} + +/* Get the distance in pixels from the baseline to the lowest descenders + (for instance, in a lowercase 'y', 'g', etc.). */ +int +grub_font_get_descent (grub_font_t font) +{ + return font->descent; +} + +/* FIXME: not correct for all fonts. */ +int +grub_font_get_xheight (grub_font_t font) +{ + return font->ascent / 2; +} + +/* Get the *standard leading* of the font in pixel, which is the spacing + between two lines of text. Specifically, it is the space between the + descent of one line and the ascent of the next line. This is included + in the *height* metric. */ +int +grub_font_get_leading (grub_font_t font) +{ + return font->leading; +} + +/* Get the distance in pixels between baselines of adjacent lines of text. */ +int +grub_font_get_height (grub_font_t font) +{ + return font->ascent + font->descent + font->leading; +} + +/* Get the glyph for FONT corresponding to the Unicode code point CODE. + Returns the ASCII glyph for the code if no other fonts are available. + The glyphs are cached once loaded. */ +struct grub_font_glyph * +grub_font_get_glyph (grub_font_t font, grub_uint32_t code) +{ + struct grub_font_glyph *glyph = 0; + if (font) + glyph = grub_font_get_glyph_internal (font, code); + if (glyph == 0) + { + glyph = ascii_glyph_lookup (code); + } + return glyph; +} + + +/* Calculate a subject value representing "how similar" two fonts are. + This is used to prioritize the order that fonts are scanned for missing + glyphs. The object is to select glyphs from the most similar font + possible, for the best appearance. + The heuristic is crude, but it helps greatly when fonts of similar + sizes are used so that tiny 8 point glyphs are not mixed into a string + of 24 point text unless there is no other choice. */ +static int +get_font_diversity (grub_font_t a, grub_font_t b) +{ + int d; + + d = 0; + + if (a->ascent && b->ascent) + d += grub_abs (a->ascent - b->ascent) * 8; + else + /* Penalty for missing attributes. */ + d += 50; + + if (a->max_char_height && b->max_char_height) + d += grub_abs (a->max_char_height - b->max_char_height) * 8; + else + /* Penalty for missing attributes. */ + d += 50; + + /* Weight is a minor factor. */ + d += (a->weight != b->weight) ? 5 : 0; + + return d; +} + +/* Get a glyph corresponding to the codepoint CODE. If FONT contains the + specified glyph, then it is returned. Otherwise, all other loaded fonts + are searched until one is found that contains a glyph for CODE. + If no glyph is available for CODE in the loaded fonts, then a glyph + representing an unknown character is returned. + This function never returns NULL. + The returned glyph is owned by the font manager and should not be freed + by the caller. The glyphs are cached. */ +struct grub_font_glyph * +grub_font_get_glyph_with_fallback (grub_font_t font, grub_uint32_t code) +{ + struct grub_font_glyph *glyph; + struct grub_font_node *node; + /* Keep track of next node, in case there's an I/O error in + grub_font_get_glyph_internal() and the font is removed from the list. */ + struct grub_font_node *next; + /* Information on the best glyph found so far, to help find the glyph in + the best matching to the requested one. */ + int best_diversity; + struct grub_font_glyph *best_glyph; + + if (font) + { + /* First try to get the glyph from the specified font. */ + glyph = grub_font_get_glyph_internal (font, code); + if (glyph) + return glyph; + } + + /* Otherwise, search all loaded fonts for the glyph and use the one from + the font that best matches the requested font. */ + best_diversity = 10000; + best_glyph = 0; + + for (node = grub_font_list; node; node = next) + { + grub_font_t curfont; + + curfont = node->value; + next = node->next; + + glyph = grub_font_get_glyph_internal (curfont, code); + if (glyph && !font) + return glyph; + if (glyph) + { + int d; + + d = get_font_diversity (curfont, font); + if (d < best_diversity) + { + best_diversity = d; + best_glyph = glyph; + } + } + } + + return best_glyph; +} + +#if 0 +static struct grub_font_glyph * +grub_font_dup_glyph (struct grub_font_glyph *glyph) +{ + static struct grub_font_glyph *ret; + ret = grub_malloc (sizeof (*ret) + (glyph->width * glyph->height + 7) / 8); + if (!ret) + return NULL; + grub_memcpy (ret, glyph, sizeof (*ret) + + (glyph->width * glyph->height + 7) / 8); + return ret; +} +#endif + +/* FIXME: suboptimal. */ +static void +grub_font_blit_glyph (struct grub_font_glyph *target, + struct grub_font_glyph *src, unsigned dx, unsigned dy) +{ + unsigned src_bit, tgt_bit, src_byte, tgt_byte; + unsigned i, j; + for (i = 0; i < src->height; i++) + { + src_bit = (src->width * i) % 8; + src_byte = (src->width * i) / 8; + tgt_bit = (target->width * (dy + i) + dx) % 8; + tgt_byte = (target->width * (dy + i) + dx) / 8; + for (j = 0; j < src->width; j++) + { + target->bitmap[tgt_byte] |= ((src->bitmap[src_byte] << src_bit) + & 0x80) >> tgt_bit; + src_bit++; + tgt_bit++; + if (src_bit == 8) + { + src_byte++; + src_bit = 0; + } + if (tgt_bit == 8) + { + tgt_byte++; + tgt_bit = 0; + } + } + } +} + +static void +grub_font_blit_glyph_mirror (struct grub_font_glyph *target, + struct grub_font_glyph *src, + unsigned dx, unsigned dy) +{ + unsigned tgt_bit, src_byte, tgt_byte; + signed src_bit; + unsigned i, j; + for (i = 0; i < src->height; i++) + { + src_bit = (src->width * i + src->width - 1) % 8; + src_byte = (src->width * i + src->width - 1) / 8; + tgt_bit = (target->width * (dy + i) + dx) % 8; + tgt_byte = (target->width * (dy + i) + dx) / 8; + for (j = 0; j < src->width; j++) + { + target->bitmap[tgt_byte] |= ((src->bitmap[src_byte] << src_bit) + & 0x80) >> tgt_bit; + src_bit--; + tgt_bit++; + if (src_bit == -1) + { + src_byte--; + src_bit = 7; + } + if (tgt_bit == 8) + { + tgt_byte++; + tgt_bit = 0; + } + } + } +} + +/* Context for blit_comb. */ +struct blit_comb_ctx +{ + struct grub_font_glyph *glyph; + int *device_width; + struct grub_video_signed_rect bounds; +}; + +/* Helper for blit_comb. */ +static void +do_blit (struct grub_font_glyph *src, signed dx, signed dy, + struct blit_comb_ctx *ctx) +{ + if (ctx->glyph) + grub_font_blit_glyph (ctx->glyph, src, dx - ctx->glyph->offset_x, + (ctx->glyph->height + ctx->glyph->offset_y) + dy); + if (dx < ctx->bounds.x) + { + ctx->bounds.width += ctx->bounds.x - dx; + ctx->bounds.x = dx; + } + if (ctx->bounds.y > -src->height - dy) + { + ctx->bounds.height += ctx->bounds.y - (-src->height - dy); + ctx->bounds.y = (-src->height - dy); + } + if (dx + src->width - ctx->bounds.x >= (signed) ctx->bounds.width) + ctx->bounds.width = dx + src->width - ctx->bounds.x + 1; + if ((signed) ctx->bounds.height < src->height + (-src->height - dy) + - ctx->bounds.y) + ctx->bounds.height = src->height + (-src->height - dy) - ctx->bounds.y; +} + +/* Helper for blit_comb. */ +static inline void +add_device_width (int val, struct blit_comb_ctx *ctx) +{ + if (ctx->glyph) + ctx->glyph->device_width += val; + if (ctx->device_width) + *ctx->device_width += val; +} + +static void +blit_comb (const struct grub_unicode_glyph *glyph_id, + struct grub_font_glyph *glyph, + struct grub_video_signed_rect *bounds_out, + struct grub_font_glyph *main_glyph, + struct grub_font_glyph **combining_glyphs, int *device_width) +{ + struct blit_comb_ctx ctx = { + .glyph = glyph, + .device_width = device_width + }; + unsigned i; + signed above_rightx, above_righty; + signed above_leftx, above_lefty; + signed below_rightx, below_righty; + signed min_devwidth = 0; + const struct grub_unicode_combining *comb; + + if (glyph) + glyph->device_width = main_glyph->device_width; + if (device_width) + *device_width = main_glyph->device_width; + + ctx.bounds.x = main_glyph->offset_x; + ctx.bounds.y = main_glyph->offset_y; + ctx.bounds.width = main_glyph->width; + ctx.bounds.height = main_glyph->height; + + above_rightx = main_glyph->offset_x + main_glyph->width; + above_righty = ctx.bounds.y + ctx.bounds.height; + + above_leftx = main_glyph->offset_x; + above_lefty = ctx.bounds.y + ctx.bounds.height; + + below_rightx = ctx.bounds.x + ctx.bounds.width; + below_righty = ctx.bounds.y; + + comb = grub_unicode_get_comb (glyph_id); + + for (i = 0; i < glyph_id->ncomb; i++) + { + grub_int16_t space = 0; + /* Center by default. */ + grub_int16_t targetx; + + if (!combining_glyphs[i]) + continue; + targetx = (ctx.bounds.width - combining_glyphs[i]->width) / 2 + ctx.bounds.x; + /* CGJ is to avoid diacritics reordering. */ + if (comb[i].code + == GRUB_UNICODE_COMBINING_GRAPHEME_JOINER) + continue; + switch (comb[i].type) + { + case GRUB_UNICODE_COMB_OVERLAY: + do_blit (combining_glyphs[i], + targetx, + (ctx.bounds.height - combining_glyphs[i]->height) / 2 + - (ctx.bounds.height + ctx.bounds.y), &ctx); + if (min_devwidth < combining_glyphs[i]->width) + min_devwidth = combining_glyphs[i]->width; + break; + + case GRUB_UNICODE_COMB_ATTACHED_ABOVE_RIGHT: + do_blit (combining_glyphs[i], above_rightx, -above_righty, &ctx); + above_rightx += combining_glyphs[i]->width; + break; + + case GRUB_UNICODE_COMB_ABOVE_RIGHT: + do_blit (combining_glyphs[i], above_rightx, + -(above_righty + combining_glyphs[i]->height), &ctx); + above_rightx += combining_glyphs[i]->width; + break; + + case GRUB_UNICODE_COMB_ABOVE_LEFT: + above_leftx -= combining_glyphs[i]->width; + do_blit (combining_glyphs[i], above_leftx, + -(above_lefty + combining_glyphs[i]->height), &ctx); + break; + + case GRUB_UNICODE_COMB_BELOW_RIGHT: + do_blit (combining_glyphs[i], below_rightx, below_righty, &ctx); + below_rightx += combining_glyphs[i]->width; + break; + + case GRUB_UNICODE_COMB_HEBREW_HOLAM: + if (glyph_id->base != GRUB_UNICODE_HEBREW_WAW) + targetx = + main_glyph->offset_x - combining_glyphs[i]->width - + (combining_glyphs[i]->width + 3) / 4; + goto above_on_main; + + case GRUB_UNICODE_COMB_HEBREW_SIN_DOT: + targetx = main_glyph->offset_x + combining_glyphs[i]->width / 4; + goto above_on_main; + + case GRUB_UNICODE_COMB_HEBREW_SHIN_DOT: + targetx = + main_glyph->width + main_glyph->offset_x - + combining_glyphs[i]->width; + above_on_main: + space = combining_glyphs[i]->offset_y + - grub_font_get_xheight (combining_glyphs[i]->font) - 1; + if (space <= 0) + space = 1 + (grub_font_get_xheight (main_glyph->font)) / 8; + do_blit (combining_glyphs[i], targetx, + -(main_glyph->height + main_glyph->offset_y + space + + combining_glyphs[i]->height), &ctx); + if (min_devwidth < combining_glyphs[i]->width) + min_devwidth = combining_glyphs[i]->width; + break; + + /* TODO: Put dammah, fathah and alif nearer to shadda. */ + case GRUB_UNICODE_COMB_SYRIAC_SUPERSCRIPT_ALAPH: + case GRUB_UNICODE_COMB_ARABIC_DAMMAH: + case GRUB_UNICODE_COMB_ARABIC_DAMMATAN: + case GRUB_UNICODE_COMB_ARABIC_FATHATAN: + case GRUB_UNICODE_COMB_ARABIC_FATHAH: + case GRUB_UNICODE_COMB_ARABIC_SUPERSCRIPT_ALIF: + case GRUB_UNICODE_COMB_ARABIC_SUKUN: + case GRUB_UNICODE_COMB_ARABIC_SHADDA: + case GRUB_UNICODE_COMB_HEBREW_RAFE: + case GRUB_UNICODE_STACK_ABOVE: + stacked_above: + space = combining_glyphs[i]->offset_y + - grub_font_get_xheight (combining_glyphs[i]->font) - 1; + if (space <= 0) + space = 1 + (grub_font_get_xheight (main_glyph->font)) / 8; + /* Fallthrough. */ + case GRUB_UNICODE_STACK_ATTACHED_ABOVE: + do_blit (combining_glyphs[i], targetx, + -(ctx.bounds.height + ctx.bounds.y + space + + combining_glyphs[i]->height), &ctx); + if (min_devwidth < combining_glyphs[i]->width) + min_devwidth = combining_glyphs[i]->width; + break; + + case GRUB_UNICODE_COMB_HEBREW_DAGESH: + do_blit (combining_glyphs[i], targetx, + -(ctx.bounds.height / 2 + ctx.bounds.y + + combining_glyphs[i]->height / 2), &ctx); + if (min_devwidth < combining_glyphs[i]->width) + min_devwidth = combining_glyphs[i]->width; + break; + + case GRUB_UNICODE_COMB_HEBREW_SHEVA: + case GRUB_UNICODE_COMB_HEBREW_HIRIQ: + case GRUB_UNICODE_COMB_HEBREW_QAMATS: + case GRUB_UNICODE_COMB_HEBREW_TSERE: + case GRUB_UNICODE_COMB_HEBREW_SEGOL: + /* TODO: placement in final kaf and under reish. */ + + case GRUB_UNICODE_COMB_HEBREW_HATAF_SEGOL: + case GRUB_UNICODE_COMB_HEBREW_HATAF_PATAH: + case GRUB_UNICODE_COMB_HEBREW_HATAF_QAMATS: + case GRUB_UNICODE_COMB_HEBREW_PATAH: + case GRUB_UNICODE_COMB_HEBREW_QUBUTS: + case GRUB_UNICODE_COMB_HEBREW_METEG: + /* TODO: Put kasra and kasratan under shadda. */ + case GRUB_UNICODE_COMB_ARABIC_KASRA: + case GRUB_UNICODE_COMB_ARABIC_KASRATAN: + /* I don't know how ypogegrammeni differs from subscript. */ + case GRUB_UNICODE_COMB_YPOGEGRAMMENI: + case GRUB_UNICODE_STACK_BELOW: + stacked_below: + space = -(combining_glyphs[i]->offset_y + + combining_glyphs[i]->height); + if (space <= 0) + space = 1 + (grub_font_get_xheight (main_glyph->font)) / 8; + /* Fallthrough. */ + + case GRUB_UNICODE_STACK_ATTACHED_BELOW: + do_blit (combining_glyphs[i], targetx, -(ctx.bounds.y - space), + &ctx); + if (min_devwidth < combining_glyphs[i]->width) + min_devwidth = combining_glyphs[i]->width; + break; + + case GRUB_UNICODE_COMB_MN: + switch (comb[i].code) + { + case GRUB_UNICODE_THAANA_ABAFILI: + case GRUB_UNICODE_THAANA_AABAAFILI: + case GRUB_UNICODE_THAANA_UBUFILI: + case GRUB_UNICODE_THAANA_OOBOOFILI: + case GRUB_UNICODE_THAANA_EBEFILI: + case GRUB_UNICODE_THAANA_EYBEYFILI: + case GRUB_UNICODE_THAANA_OBOFILI: + case GRUB_UNICODE_THAANA_OABOAFILI: + case GRUB_UNICODE_THAANA_SUKUN: + goto stacked_above; + case GRUB_UNICODE_THAANA_IBIFILI: + case GRUB_UNICODE_THAANA_EEBEEFILI: + goto stacked_below; + } + /* Fall through. */ + default: + { + /* Default handling. Just draw combining character on top + of base character. + FIXME: support more unicode types correctly. + */ + do_blit (combining_glyphs[i], + main_glyph->device_width + + combining_glyphs[i]->offset_x, + -(combining_glyphs[i]->height + + combining_glyphs[i]->offset_y), &ctx); + add_device_width (combining_glyphs[i]->device_width, &ctx); + } + } + } + add_device_width ((above_rightx > + below_rightx ? above_rightx : below_rightx) - + (main_glyph->offset_x + main_glyph->width), &ctx); + add_device_width (above_leftx - main_glyph->offset_x, &ctx); + if (glyph && glyph->device_width < min_devwidth) + glyph->device_width = min_devwidth; + if (device_width && *device_width < min_devwidth) + *device_width = min_devwidth; + + if (bounds_out) + *bounds_out = ctx.bounds; +} + +static struct grub_font_glyph * +grub_font_construct_dry_run (grub_font_t hinted_font, + const struct grub_unicode_glyph *glyph_id, + struct grub_video_signed_rect *bounds, + struct grub_font_glyph **combining_glyphs, + int *device_width) +{ + struct grub_font_glyph *main_glyph = NULL; + grub_uint32_t desired_attributes = 0; + unsigned i; + grub_uint32_t base = glyph_id->base; + const struct grub_unicode_combining *comb; + + if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED) + desired_attributes |= GRUB_FONT_CODE_RIGHT_JOINED; + + if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED) + desired_attributes |= GRUB_FONT_CODE_LEFT_JOINED; + + comb = grub_unicode_get_comb (glyph_id); + + if (base == 'i' || base == 'j') + { + for (i = 0; i < glyph_id->ncomb; i++) + if (comb[i].type == GRUB_UNICODE_STACK_ABOVE) + break; + if (i < glyph_id->ncomb && base == 'i') + base = GRUB_UNICODE_DOTLESS_LOWERCASE_I; + if (i < glyph_id->ncomb && base == 'j') + base = GRUB_UNICODE_DOTLESS_LOWERCASE_J; + } + + main_glyph = grub_font_get_glyph_with_fallback (hinted_font, base + | desired_attributes); + + if (!main_glyph) + main_glyph = grub_font_get_glyph_with_fallback (hinted_font, + base); + + /* Glyph not available in any font. Use ASCII fallback. */ + if (!main_glyph) + main_glyph = ascii_glyph_lookup (base); + + /* Glyph not available in any font. Return unknown glyph. */ + if (!main_glyph) + return NULL; + + if (device_width) + *device_width = main_glyph->device_width; + + if (!glyph_id->ncomb && !glyph_id->attributes) + return main_glyph; + + if (glyph_id->ncomb && !combining_glyphs) + { + grub_errno = GRUB_ERR_NONE; + return main_glyph; + } + + for (i = 0; i < glyph_id->ncomb; i++) + combining_glyphs[i] + = grub_font_get_glyph_with_fallback (main_glyph->font, + comb[i].code); + + blit_comb (glyph_id, NULL, bounds, main_glyph, combining_glyphs, + device_width); + + return main_glyph; +} + +static struct grub_font_glyph **render_combining_glyphs = 0; +static grub_size_t render_max_comb_glyphs = 0; + +static void +ensure_comb_space (const struct grub_unicode_glyph *glyph_id) +{ + if (glyph_id->ncomb <= render_max_comb_glyphs) + return; + + render_max_comb_glyphs = 2 * glyph_id->ncomb; + if (render_max_comb_glyphs < 8) + render_max_comb_glyphs = 8; + grub_free (render_combining_glyphs); + render_combining_glyphs = grub_malloc (render_max_comb_glyphs + * sizeof (render_combining_glyphs[0])); + if (!render_combining_glyphs) + grub_errno = 0; +} + +int +grub_font_get_constructed_device_width (grub_font_t hinted_font, + const struct grub_unicode_glyph + *glyph_id) +{ + int ret; + struct grub_font_glyph *main_glyph; + + ensure_comb_space (glyph_id); + + main_glyph = grub_font_construct_dry_run (hinted_font, glyph_id, NULL, + render_combining_glyphs, &ret); + if (!main_glyph) + return unknown_glyph->device_width; + return ret; +} + +struct grub_font_glyph * +grub_font_construct_glyph (grub_font_t hinted_font, + const struct grub_unicode_glyph *glyph_id) +{ + struct grub_font_glyph *main_glyph; + struct grub_video_signed_rect bounds; + static struct grub_font_glyph *glyph = 0; + static grub_size_t max_glyph_size = 0; + + ensure_comb_space (glyph_id); + + main_glyph = grub_font_construct_dry_run (hinted_font, glyph_id, + &bounds, render_combining_glyphs, + NULL); + + if (!main_glyph) + return unknown_glyph; + + if (!render_combining_glyphs && glyph_id->ncomb) + return main_glyph; + + if (!glyph_id->ncomb && !glyph_id->attributes) + return main_glyph; + + if (max_glyph_size < sizeof (*glyph) + (bounds.width * bounds.height + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT) + { + grub_free (glyph); + max_glyph_size = (sizeof (*glyph) + (bounds.width * bounds.height + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT) * 2; + if (max_glyph_size < 8) + max_glyph_size = 8; + glyph = grub_malloc (max_glyph_size); + } + if (!glyph) + { + grub_errno = GRUB_ERR_NONE; + return main_glyph; + } + + grub_memset (glyph, 0, sizeof (*glyph) + + (bounds.width * bounds.height + + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT); + + glyph->font = main_glyph->font; + glyph->width = bounds.width; + glyph->height = bounds.height; + glyph->offset_x = bounds.x; + glyph->offset_y = bounds.y; + + if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR) + grub_font_blit_glyph_mirror (glyph, main_glyph, + main_glyph->offset_x - glyph->offset_x, + (glyph->height + glyph->offset_y) + - (main_glyph->height + + main_glyph->offset_y)); + else + grub_font_blit_glyph (glyph, main_glyph, + main_glyph->offset_x - glyph->offset_x, + (glyph->height + glyph->offset_y) + - (main_glyph->height + main_glyph->offset_y)); + + blit_comb (glyph_id, glyph, NULL, main_glyph, render_combining_glyphs, NULL); + + return glyph; +} + +/* Draw the specified glyph at (x, y). The y coordinate designates the + baseline of the character, while the x coordinate designates the left + side location of the character. */ +grub_err_t +grub_font_draw_glyph (struct grub_font_glyph * glyph, + grub_video_color_t color, int left_x, int baseline_y) +{ + struct grub_video_bitmap glyph_bitmap; + + /* Don't try to draw empty glyphs (U+0020, etc.). */ + if (glyph->width == 0 || glyph->height == 0) + return GRUB_ERR_NONE; + + glyph_bitmap.mode_info.width = glyph->width; + glyph_bitmap.mode_info.height = glyph->height; + glyph_bitmap.mode_info.mode_type + = (1 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS) | GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP; + glyph_bitmap.mode_info.blit_format = GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED; + glyph_bitmap.mode_info.bpp = 1; + + /* Really 1 bit per pixel. */ + glyph_bitmap.mode_info.bytes_per_pixel = 0; + + /* Packed densely as bits. */ + glyph_bitmap.mode_info.pitch = glyph->width; + + glyph_bitmap.mode_info.number_of_colors = 2; + glyph_bitmap.mode_info.bg_red = 0; + glyph_bitmap.mode_info.bg_green = 0; + glyph_bitmap.mode_info.bg_blue = 0; + glyph_bitmap.mode_info.bg_alpha = 0; + grub_video_unmap_color (color, + &glyph_bitmap.mode_info.fg_red, + &glyph_bitmap.mode_info.fg_green, + &glyph_bitmap.mode_info.fg_blue, + &glyph_bitmap.mode_info.fg_alpha); + glyph_bitmap.data = glyph->bitmap; + + int bitmap_left = left_x + glyph->offset_x; + int bitmap_bottom = baseline_y - glyph->offset_y; + int bitmap_top = bitmap_bottom - glyph->height; + + return grub_video_blit_bitmap (&glyph_bitmap, GRUB_VIDEO_BLIT_BLEND, + bitmap_left, bitmap_top, + 0, 0, glyph->width, glyph->height); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/btrfs.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/btrfs.c new file mode 100644 index 0000000..dbd66d6 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/btrfs.c @@ -0,0 +1,2282 @@ +/* btrfs.c - B-tree file system. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010,2011,2012,2013 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +/* + * Tell zstd to expose functions that aren't part of the stable API, which + * aren't safe to use when linking against a dynamic library. We vendor in a + * specific zstd version, so we know what we're getting. We need these unstable + * functions to provide our own allocator, which uses grub_malloc(), to zstd. + */ +#define ZSTD_STATIC_LINKING_ONLY + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +#define GRUB_BTRFS_SIGNATURE "_BHRfS_M" + +/* From http://www.oberhumer.com/opensource/lzo/lzofaq.php + * LZO will expand incompressible data by a little amount. I still haven't + * computed the exact values, but I suggest using these formulas for + * a worst-case expansion calculation: + * + * output_block_size = input_block_size + (input_block_size / 16) + 64 + 3 + * */ +#define GRUB_BTRFS_LZO_BLOCK_SIZE 4096 +#define GRUB_BTRFS_LZO_BLOCK_MAX_CSIZE (GRUB_BTRFS_LZO_BLOCK_SIZE + \ + (GRUB_BTRFS_LZO_BLOCK_SIZE / 16) + 64 + 3) + +#define ZSTD_BTRFS_MAX_WINDOWLOG 17 +#define ZSTD_BTRFS_MAX_INPUT (1 << ZSTD_BTRFS_MAX_WINDOWLOG) + +typedef grub_uint8_t grub_btrfs_checksum_t[0x20]; +typedef grub_uint16_t grub_btrfs_uuid_t[8]; + +struct grub_btrfs_device +{ + grub_uint64_t device_id; + grub_uint64_t size; + grub_uint8_t dummy[0x62 - 0x10]; +} GRUB_PACKED; + +struct grub_btrfs_superblock +{ + grub_btrfs_checksum_t checksum; + grub_btrfs_uuid_t uuid; + grub_uint8_t dummy[0x10]; + grub_uint8_t signature[sizeof (GRUB_BTRFS_SIGNATURE) - 1]; + grub_uint64_t generation; + grub_uint64_t root_tree; + grub_uint64_t chunk_tree; + grub_uint8_t dummy2[0x20]; + grub_uint64_t root_dir_objectid; + grub_uint8_t dummy3[0x41]; + struct grub_btrfs_device this_device; + char label[0x100]; + grub_uint8_t dummy4[0x100]; + grub_uint8_t bootstrap_mapping[0x800]; +} GRUB_PACKED; + +struct btrfs_header +{ + grub_btrfs_checksum_t checksum; + grub_btrfs_uuid_t uuid; + grub_uint64_t bytenr; + grub_uint8_t dummy[0x28]; + grub_uint32_t nitems; + grub_uint8_t level; +} GRUB_PACKED; + +struct grub_btrfs_device_desc +{ + grub_device_t dev; + grub_uint64_t id; +}; + +struct grub_btrfs_data +{ + struct grub_btrfs_superblock sblock; + grub_uint64_t tree; + grub_uint64_t inode; + + struct grub_btrfs_device_desc *devices_attached; + unsigned n_devices_attached; + unsigned n_devices_allocated; + + /* Cached extent data. */ + grub_uint64_t extstart; + grub_uint64_t extend; + grub_uint64_t extino; + grub_uint64_t exttree; + grub_size_t extsize; + struct grub_btrfs_extent_data *extent; +}; + +struct grub_btrfs_chunk_item +{ + grub_uint64_t size; + grub_uint64_t dummy; + grub_uint64_t stripe_length; + grub_uint64_t type; +#define GRUB_BTRFS_CHUNK_TYPE_BITS_DONTCARE 0x07 +#define GRUB_BTRFS_CHUNK_TYPE_SINGLE 0x00 +#define GRUB_BTRFS_CHUNK_TYPE_RAID0 0x08 +#define GRUB_BTRFS_CHUNK_TYPE_RAID1 0x10 +#define GRUB_BTRFS_CHUNK_TYPE_DUPLICATED 0x20 +#define GRUB_BTRFS_CHUNK_TYPE_RAID10 0x40 +#define GRUB_BTRFS_CHUNK_TYPE_RAID5 0x80 +#define GRUB_BTRFS_CHUNK_TYPE_RAID6 0x100 + grub_uint8_t dummy2[0xc]; + grub_uint16_t nstripes; + grub_uint16_t nsubstripes; +} GRUB_PACKED; + +struct grub_btrfs_chunk_stripe +{ + grub_uint64_t device_id; + grub_uint64_t offset; + grub_btrfs_uuid_t device_uuid; +} GRUB_PACKED; + +struct grub_btrfs_leaf_node +{ + struct grub_btrfs_key key; + grub_uint32_t offset; + grub_uint32_t size; +} GRUB_PACKED; + +struct grub_btrfs_internal_node +{ + struct grub_btrfs_key key; + grub_uint64_t addr; + grub_uint64_t dummy; +} GRUB_PACKED; + +struct grub_btrfs_dir_item +{ + struct grub_btrfs_key key; + grub_uint8_t dummy[8]; + grub_uint16_t m; + grub_uint16_t n; +#define GRUB_BTRFS_DIR_ITEM_TYPE_REGULAR 1 +#define GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY 2 +#define GRUB_BTRFS_DIR_ITEM_TYPE_SYMLINK 7 + grub_uint8_t type; + char name[0]; +} GRUB_PACKED; + +struct grub_btrfs_leaf_descriptor +{ + unsigned depth; + unsigned allocated; + struct + { + grub_disk_addr_t addr; + unsigned iter; + unsigned maxiter; + int leaf; + } *data; +}; + +struct grub_btrfs_time +{ + grub_int64_t sec; + grub_uint32_t nanosec; +} GRUB_PACKED; + +struct grub_btrfs_inode +{ + grub_uint8_t dummy1[0x10]; + grub_uint64_t size; + grub_uint8_t dummy2[0x70]; + struct grub_btrfs_time mtime; +} GRUB_PACKED; + +struct grub_btrfs_extent_data +{ + grub_uint64_t dummy; + grub_uint64_t size; + grub_uint8_t compression; + grub_uint8_t encryption; + grub_uint16_t encoding; + grub_uint8_t type; + union + { + char inl[0]; + struct + { + grub_uint64_t laddr; + grub_uint64_t compressed_size; + grub_uint64_t offset; + grub_uint64_t filled; + }; + }; +} GRUB_PACKED; + +#define GRUB_BTRFS_EXTENT_INLINE 0 +#define GRUB_BTRFS_EXTENT_REGULAR 1 + +#define GRUB_BTRFS_COMPRESSION_NONE 0 +#define GRUB_BTRFS_COMPRESSION_ZLIB 1 +#define GRUB_BTRFS_COMPRESSION_LZO 2 +#define GRUB_BTRFS_COMPRESSION_ZSTD 3 + +#define GRUB_BTRFS_OBJECT_ID_CHUNK 0x100 + +static grub_uint64_t g_last_chunk_type = 0; +static grub_uint8_t g_last_compress_type = 0; + + +static grub_disk_addr_t superblock_sectors[] = { 64 * 2, 64 * 1024 * 2, + 256 * 1048576 * 2, 1048576ULL * 1048576ULL * 2 +}; + +static grub_err_t +grub_btrfs_read_logical (struct grub_btrfs_data *data, + grub_disk_addr_t addr, void *buf, grub_size_t size, + int recursion_depth); + +static grub_err_t +read_sblock (grub_disk_t disk, struct grub_btrfs_superblock *sb) +{ + struct grub_btrfs_superblock sblock; + unsigned i; + grub_err_t err = GRUB_ERR_NONE; + for (i = 0; i < ARRAY_SIZE (superblock_sectors); i++) + { + /* Don't try additional superblocks beyond device size. */ + if (i && (grub_le_to_cpu64 (sblock.this_device.size) + >> GRUB_DISK_SECTOR_BITS) <= superblock_sectors[i]) + break; + err = grub_disk_read (disk, superblock_sectors[i], 0, + sizeof (sblock), &sblock); + if (err == GRUB_ERR_OUT_OF_RANGE) + break; + + if (grub_memcmp ((char *) sblock.signature, GRUB_BTRFS_SIGNATURE, + sizeof (GRUB_BTRFS_SIGNATURE) - 1) != 0) + break; + if (i == 0 || grub_le_to_cpu64 (sblock.generation) + > grub_le_to_cpu64 (sb->generation)) + grub_memcpy (sb, &sblock, sizeof (sblock)); + } + + if ((err == GRUB_ERR_OUT_OF_RANGE || !err) && i == 0) + return grub_error (GRUB_ERR_BAD_FS, "not a Btrfs filesystem"); + + if (err == GRUB_ERR_OUT_OF_RANGE) + grub_errno = err = GRUB_ERR_NONE; + + return err; +} + +static int +key_cmp (const struct grub_btrfs_key *a, const struct grub_btrfs_key *b) +{ + if (grub_le_to_cpu64 (a->object_id) < grub_le_to_cpu64 (b->object_id)) + return -1; + if (grub_le_to_cpu64 (a->object_id) > grub_le_to_cpu64 (b->object_id)) + return +1; + + if (a->type < b->type) + return -1; + if (a->type > b->type) + return +1; + + if (grub_le_to_cpu64 (a->offset) < grub_le_to_cpu64 (b->offset)) + return -1; + if (grub_le_to_cpu64 (a->offset) > grub_le_to_cpu64 (b->offset)) + return +1; + return 0; +} + +static void +free_iterator (struct grub_btrfs_leaf_descriptor *desc) +{ + grub_free (desc->data); +} + +static grub_err_t +check_btrfs_header (struct grub_btrfs_data *data, struct btrfs_header *header, + grub_disk_addr_t addr) +{ + if (grub_le_to_cpu64 (header->bytenr) != addr) + { + grub_dprintf ("btrfs", "btrfs_header.bytenr is not equal node addr\n"); + return grub_error (GRUB_ERR_BAD_FS, + "header bytenr is not equal node addr"); + } + if (grub_memcmp (data->sblock.uuid, header->uuid, sizeof(grub_btrfs_uuid_t))) + { + grub_dprintf ("btrfs", "btrfs_header.uuid doesn't match sblock uuid\n"); + return grub_error (GRUB_ERR_BAD_FS, + "header uuid doesn't match sblock uuid"); + } + return GRUB_ERR_NONE; +} + +static grub_err_t +save_ref (struct grub_btrfs_leaf_descriptor *desc, + grub_disk_addr_t addr, unsigned i, unsigned m, int l) +{ + desc->depth++; + if (desc->allocated < desc->depth) + { + void *newdata; + desc->allocated *= 2; + newdata = grub_realloc (desc->data, sizeof (desc->data[0]) + * desc->allocated); + if (!newdata) + return grub_errno; + desc->data = newdata; + } + desc->data[desc->depth - 1].addr = addr; + desc->data[desc->depth - 1].iter = i; + desc->data[desc->depth - 1].maxiter = m; + desc->data[desc->depth - 1].leaf = l; + return GRUB_ERR_NONE; +} + +static int +next (struct grub_btrfs_data *data, + struct grub_btrfs_leaf_descriptor *desc, + grub_disk_addr_t * outaddr, grub_size_t * outsize, + struct grub_btrfs_key *key_out) +{ + grub_err_t err; + struct grub_btrfs_leaf_node leaf; + + for (; desc->depth > 0; desc->depth--) + { + desc->data[desc->depth - 1].iter++; + if (desc->data[desc->depth - 1].iter + < desc->data[desc->depth - 1].maxiter) + break; + } + if (desc->depth == 0) + return 0; + while (!desc->data[desc->depth - 1].leaf) + { + struct grub_btrfs_internal_node node; + struct btrfs_header head; + + err = grub_btrfs_read_logical (data, desc->data[desc->depth - 1].iter + * sizeof (node) + + sizeof (struct btrfs_header) + + desc->data[desc->depth - 1].addr, + &node, sizeof (node), 0); + if (err) + return -err; + + err = grub_btrfs_read_logical (data, grub_le_to_cpu64 (node.addr), + &head, sizeof (head), 0); + check_btrfs_header (data, &head, grub_le_to_cpu64 (node.addr)); + if (err) + return -err; + + save_ref (desc, grub_le_to_cpu64 (node.addr), 0, + grub_le_to_cpu32 (head.nitems), !head.level); + } + err = grub_btrfs_read_logical (data, desc->data[desc->depth - 1].iter + * sizeof (leaf) + + sizeof (struct btrfs_header) + + desc->data[desc->depth - 1].addr, &leaf, + sizeof (leaf), 0); + if (err) + return -err; + *outsize = grub_le_to_cpu32 (leaf.size); + *outaddr = desc->data[desc->depth - 1].addr + sizeof (struct btrfs_header) + + grub_le_to_cpu32 (leaf.offset); + *key_out = leaf.key; + return 1; +} + +static grub_err_t +lower_bound (struct grub_btrfs_data *data, + const struct grub_btrfs_key *key_in, + struct grub_btrfs_key *key_out, + grub_uint64_t root, + grub_disk_addr_t *outaddr, grub_size_t *outsize, + struct grub_btrfs_leaf_descriptor *desc, + int recursion_depth) +{ + grub_disk_addr_t addr = grub_le_to_cpu64 (root); + int depth = -1; + + if (desc) + { + desc->allocated = 16; + desc->depth = 0; + desc->data = grub_malloc (sizeof (desc->data[0]) * desc->allocated); + if (!desc->data) + return grub_errno; + } + + /* > 2 would work as well but be robust and allow a bit more just in case. + */ + if (recursion_depth > 10) + return grub_error (GRUB_ERR_BAD_FS, "too deep btrfs virtual nesting"); + + grub_dprintf ("btrfs", + "retrieving %" PRIxGRUB_UINT64_T + " %x %" PRIxGRUB_UINT64_T "\n", + key_in->object_id, key_in->type, key_in->offset); + + while (1) + { + grub_err_t err; + struct btrfs_header head; + + reiter: + depth++; + /* FIXME: preread few nodes into buffer. */ + err = grub_btrfs_read_logical (data, addr, &head, sizeof (head), + recursion_depth + 1); + check_btrfs_header (data, &head, addr); + if (err) + return err; + addr += sizeof (head); + if (head.level) + { + unsigned i; + struct grub_btrfs_internal_node node, node_last; + int have_last = 0; + grub_memset (&node_last, 0, sizeof (node_last)); + for (i = 0; i < grub_le_to_cpu32 (head.nitems); i++) + { + err = grub_btrfs_read_logical (data, addr + i * sizeof (node), + &node, sizeof (node), + recursion_depth + 1); + if (err) + return err; + + grub_dprintf ("btrfs", + "internal node (depth %d) %" PRIxGRUB_UINT64_T + " %x %" PRIxGRUB_UINT64_T "\n", depth, + node.key.object_id, node.key.type, + node.key.offset); + + if (key_cmp (&node.key, key_in) == 0) + { + err = GRUB_ERR_NONE; + if (desc) + err = save_ref (desc, addr - sizeof (head), i, + grub_le_to_cpu32 (head.nitems), 0); + if (err) + return err; + addr = grub_le_to_cpu64 (node.addr); + goto reiter; + } + if (key_cmp (&node.key, key_in) > 0) + break; + node_last = node; + have_last = 1; + } + if (have_last) + { + err = GRUB_ERR_NONE; + if (desc) + err = save_ref (desc, addr - sizeof (head), i - 1, + grub_le_to_cpu32 (head.nitems), 0); + if (err) + return err; + addr = grub_le_to_cpu64 (node_last.addr); + goto reiter; + } + *outsize = 0; + *outaddr = 0; + grub_memset (key_out, 0, sizeof (*key_out)); + if (desc) + return save_ref (desc, addr - sizeof (head), -1, + grub_le_to_cpu32 (head.nitems), 0); + return GRUB_ERR_NONE; + } + { + unsigned i; + struct grub_btrfs_leaf_node leaf, leaf_last; + int have_last = 0; + for (i = 0; i < grub_le_to_cpu32 (head.nitems); i++) + { + err = grub_btrfs_read_logical (data, addr + i * sizeof (leaf), + &leaf, sizeof (leaf), + recursion_depth + 1); + if (err) + return err; + + grub_dprintf ("btrfs", + "leaf (depth %d) %" PRIxGRUB_UINT64_T + " %x %" PRIxGRUB_UINT64_T "\n", depth, + leaf.key.object_id, leaf.key.type, leaf.key.offset); + + if (key_cmp (&leaf.key, key_in) == 0) + { + grub_memcpy (key_out, &leaf.key, sizeof (*key_out)); + *outsize = grub_le_to_cpu32 (leaf.size); + *outaddr = addr + grub_le_to_cpu32 (leaf.offset); + if (desc) + return save_ref (desc, addr - sizeof (head), i, + grub_le_to_cpu32 (head.nitems), 1); + return GRUB_ERR_NONE; + } + + if (key_cmp (&leaf.key, key_in) > 0) + break; + + have_last = 1; + leaf_last = leaf; + } + + if (have_last) + { + grub_memcpy (key_out, &leaf_last.key, sizeof (*key_out)); + *outsize = grub_le_to_cpu32 (leaf_last.size); + *outaddr = addr + grub_le_to_cpu32 (leaf_last.offset); + if (desc) + return save_ref (desc, addr - sizeof (head), i - 1, + grub_le_to_cpu32 (head.nitems), 1); + return GRUB_ERR_NONE; + } + *outsize = 0; + *outaddr = 0; + grub_memset (key_out, 0, sizeof (*key_out)); + if (desc) + return save_ref (desc, addr - sizeof (head), -1, + grub_le_to_cpu32 (head.nitems), 1); + return GRUB_ERR_NONE; + } + } +} + +/* Context for find_device. */ +struct find_device_ctx +{ + struct grub_btrfs_data *data; + grub_uint64_t id; + grub_device_t dev_found; +}; + +/* Helper for find_device. */ +static int +find_device_iter (const char *name, void *data) +{ + struct find_device_ctx *ctx = data; + grub_device_t dev; + grub_err_t err; + struct grub_btrfs_superblock sb; + + dev = grub_device_open (name); + if (!dev) + return 0; + if (!dev->disk) + { + grub_device_close (dev); + return 0; + } + err = read_sblock (dev->disk, &sb); + if (err == GRUB_ERR_BAD_FS) + { + grub_device_close (dev); + grub_errno = GRUB_ERR_NONE; + return 0; + } + if (err) + { + grub_device_close (dev); + grub_print_error (); + return 0; + } + if (grub_memcmp (ctx->data->sblock.uuid, sb.uuid, sizeof (sb.uuid)) != 0 + || sb.this_device.device_id != ctx->id) + { + grub_device_close (dev); + return 0; + } + + ctx->dev_found = dev; + return 1; +} + +static grub_device_t +find_device (struct grub_btrfs_data *data, grub_uint64_t id) +{ + struct find_device_ctx ctx = { + .data = data, + .id = id, + .dev_found = NULL + }; + unsigned i; + + for (i = 0; i < data->n_devices_attached; i++) + if (id == data->devices_attached[i].id) + return data->devices_attached[i].dev; + + grub_device_iterate (find_device_iter, &ctx); + + data->n_devices_attached++; + if (data->n_devices_attached > data->n_devices_allocated) + { + void *tmp; + data->n_devices_allocated = 2 * data->n_devices_attached + 1; + data->devices_attached + = grub_realloc (tmp = data->devices_attached, + data->n_devices_allocated + * sizeof (data->devices_attached[0])); + if (!data->devices_attached) + { + if (ctx.dev_found) + grub_device_close (ctx.dev_found); + data->devices_attached = tmp; + return NULL; + } + } + data->devices_attached[data->n_devices_attached - 1].id = id; + data->devices_attached[data->n_devices_attached - 1].dev = ctx.dev_found; + return ctx.dev_found; +} + +static grub_err_t +btrfs_read_from_chunk (struct grub_btrfs_data *data, + struct grub_btrfs_chunk_item *chunk, + grub_uint64_t stripen, grub_uint64_t stripe_offset, + int redundancy, grub_uint64_t csize, + void *buf) +{ + struct grub_btrfs_chunk_stripe *stripe; + grub_disk_addr_t paddr; + grub_device_t dev; + grub_err_t err; + + stripe = (struct grub_btrfs_chunk_stripe *) (chunk + 1); + /* Right now the redundancy handling is easy. + With RAID5-like it will be more difficult. */ + stripe += stripen + redundancy; + + paddr = grub_le_to_cpu64 (stripe->offset) + stripe_offset; + + grub_dprintf ("btrfs", "stripe %" PRIxGRUB_UINT64_T + " maps to 0x%" PRIxGRUB_UINT64_T "\n" + "reading paddr 0x%" PRIxGRUB_UINT64_T "\n", + stripen, stripe->offset, paddr); + + dev = find_device (data, stripe->device_id); + if (!dev) + { + grub_dprintf ("btrfs", + "couldn't find a necessary member device " + "of multi-device filesystem\n"); + grub_errno = GRUB_ERR_NONE; + return GRUB_ERR_READ_ERROR; + } + + err = grub_disk_read (dev->disk, paddr >> GRUB_DISK_SECTOR_BITS, + paddr & (GRUB_DISK_SECTOR_SIZE - 1), + csize, buf); + return err; +} + +struct raid56_buffer { + void *buf; + int data_is_valid; +}; + +static void +rebuild_raid5 (char *dest, struct raid56_buffer *buffers, + grub_uint64_t nstripes, grub_uint64_t csize) +{ + grub_uint64_t i; + int first; + + for(i = 0; buffers[i].data_is_valid && i < nstripes; i++); + + if (i == nstripes) + { + grub_dprintf ("btrfs", "called rebuild_raid5(), but all disks are OK\n"); + return; + } + + grub_dprintf ("btrfs", "rebuilding RAID 5 stripe #%" PRIuGRUB_UINT64_T "\n", i); + + for (i = 0, first = 1; i < nstripes; i++) + { + if (!buffers[i].data_is_valid) + continue; + + if (first) { + grub_memcpy(dest, buffers[i].buf, csize); + first = 0; + } else + grub_crypto_xor (dest, dest, buffers[i].buf, csize); + } +} + +static grub_err_t +raid6_recover_read_buffer (void *data, int disk_nr, + grub_uint64_t addr __attribute__ ((unused)), + void *dest, grub_size_t size) +{ + struct raid56_buffer *buffers = data; + + if (!buffers[disk_nr].data_is_valid) + return grub_errno = GRUB_ERR_READ_ERROR; + + grub_memcpy(dest, buffers[disk_nr].buf, size); + + return grub_errno = GRUB_ERR_NONE; +} + +static void +rebuild_raid6 (struct raid56_buffer *buffers, grub_uint64_t nstripes, + grub_uint64_t csize, grub_uint64_t parities_pos, void *dest, + grub_uint64_t stripen) + +{ + grub_raid6_recover_gen (buffers, nstripes, stripen, parities_pos, + dest, 0, csize, 0, raid6_recover_read_buffer); +} + +static grub_err_t +raid56_read_retry (struct grub_btrfs_data *data, + struct grub_btrfs_chunk_item *chunk, + grub_uint64_t stripe_offset, grub_uint64_t stripen, + grub_uint64_t csize, void *buf, grub_uint64_t parities_pos) +{ + struct raid56_buffer *buffers; + grub_uint64_t nstripes = grub_le_to_cpu16 (chunk->nstripes); + grub_uint64_t chunk_type = grub_le_to_cpu64 (chunk->type); + grub_err_t ret = GRUB_ERR_OUT_OF_MEMORY; + grub_uint64_t i, failed_devices; + + buffers = grub_zalloc (sizeof(*buffers) * nstripes); + if (!buffers) + goto cleanup; + + for (i = 0; i < nstripes; i++) + { + buffers[i].buf = grub_zalloc (csize); + if (!buffers[i].buf) + goto cleanup; + } + + for (failed_devices = 0, i = 0; i < nstripes; i++) + { + struct grub_btrfs_chunk_stripe *stripe; + grub_disk_addr_t paddr; + grub_device_t dev; + grub_err_t err; + + /* + * The struct grub_btrfs_chunk_stripe array lives + * behind struct grub_btrfs_chunk_item. + */ + stripe = (struct grub_btrfs_chunk_stripe *) (chunk + 1) + i; + + paddr = grub_le_to_cpu64 (stripe->offset) + stripe_offset; + grub_dprintf ("btrfs", "reading paddr %" PRIxGRUB_UINT64_T + " from stripe ID %" PRIxGRUB_UINT64_T "\n", + paddr, stripe->device_id); + + dev = find_device (data, stripe->device_id); + if (!dev) + { + grub_dprintf ("btrfs", "stripe %" PRIuGRUB_UINT64_T " FAILED (dev ID %" + PRIxGRUB_UINT64_T ")\n", i, stripe->device_id); + failed_devices++; + continue; + } + + err = grub_disk_read (dev->disk, paddr >> GRUB_DISK_SECTOR_BITS, + paddr & (GRUB_DISK_SECTOR_SIZE - 1), + csize, buffers[i].buf); + if (err == GRUB_ERR_NONE) + { + buffers[i].data_is_valid = 1; + grub_dprintf ("btrfs", "stripe %" PRIuGRUB_UINT64_T " OK (dev ID %" + PRIxGRUB_UINT64_T ")\n", i, stripe->device_id); + } + else + { + grub_dprintf ("btrfs", "stripe %" PRIuGRUB_UINT64_T + " READ FAILED (dev ID %" PRIxGRUB_UINT64_T ")\n", + i, stripe->device_id); + failed_devices++; + } + } + + if (failed_devices > 1 && (chunk_type & GRUB_BTRFS_CHUNK_TYPE_RAID5)) + { + grub_dprintf ("btrfs", "not enough disks for RAID 5: total %" PRIuGRUB_UINT64_T + ", missing %" PRIuGRUB_UINT64_T "\n", + nstripes, failed_devices); + ret = GRUB_ERR_READ_ERROR; + goto cleanup; + } + else if (failed_devices > 2 && (chunk_type & GRUB_BTRFS_CHUNK_TYPE_RAID6)) + { + grub_dprintf ("btrfs", "not enough disks for RAID 6: total %" PRIuGRUB_UINT64_T + ", missing %" PRIuGRUB_UINT64_T "\n", + nstripes, failed_devices); + ret = GRUB_ERR_READ_ERROR; + goto cleanup; + } + else + grub_dprintf ("btrfs", "enough disks for RAID 5: total %" + PRIuGRUB_UINT64_T ", missing %" PRIuGRUB_UINT64_T "\n", + nstripes, failed_devices); + + /* We have enough disks. So, rebuild the data. */ + if (chunk_type & GRUB_BTRFS_CHUNK_TYPE_RAID5) + rebuild_raid5 (buf, buffers, nstripes, csize); + else + rebuild_raid6 (buffers, nstripes, csize, parities_pos, buf, stripen); + + ret = GRUB_ERR_NONE; + cleanup: + if (buffers) + for (i = 0; i < nstripes; i++) + grub_free (buffers[i].buf); + grub_free (buffers); + + return ret; +} + +static grub_err_t +grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, + void *buf, grub_size_t size, int recursion_depth) +{ + while (size > 0) + { + grub_uint8_t *ptr; + struct grub_btrfs_key *key; + struct grub_btrfs_chunk_item *chunk; + grub_uint64_t csize; + grub_err_t err = 0; + struct grub_btrfs_key key_out; + int challoc = 0; + struct grub_btrfs_key key_in; + grub_size_t chsize; + grub_disk_addr_t chaddr; + + grub_dprintf ("btrfs", "searching for laddr %" PRIxGRUB_UINT64_T "\n", + addr); + for (ptr = data->sblock.bootstrap_mapping; + ptr < data->sblock.bootstrap_mapping + + sizeof (data->sblock.bootstrap_mapping) + - sizeof (struct grub_btrfs_key);) + { + key = (struct grub_btrfs_key *) ptr; + if (key->type != GRUB_BTRFS_ITEM_TYPE_CHUNK) + break; + chunk = (struct grub_btrfs_chunk_item *) (key + 1); + grub_dprintf ("btrfs", + "%" PRIxGRUB_UINT64_T " %" PRIxGRUB_UINT64_T " \n", + grub_le_to_cpu64 (key->offset), + grub_le_to_cpu64 (chunk->size)); + if (grub_le_to_cpu64 (key->offset) <= addr + && addr < grub_le_to_cpu64 (key->offset) + + grub_le_to_cpu64 (chunk->size)) + goto chunk_found; + ptr += sizeof (*key) + sizeof (*chunk) + + sizeof (struct grub_btrfs_chunk_stripe) + * grub_le_to_cpu16 (chunk->nstripes); + } + + key_in.object_id = grub_cpu_to_le64_compile_time (GRUB_BTRFS_OBJECT_ID_CHUNK); + key_in.type = GRUB_BTRFS_ITEM_TYPE_CHUNK; + key_in.offset = grub_cpu_to_le64 (addr); + err = lower_bound (data, &key_in, &key_out, + data->sblock.chunk_tree, + &chaddr, &chsize, NULL, recursion_depth); + if (err) + return err; + key = &key_out; + if (key->type != GRUB_BTRFS_ITEM_TYPE_CHUNK + || !(grub_le_to_cpu64 (key->offset) <= addr)) + return grub_error (GRUB_ERR_BAD_FS, + "couldn't find the chunk descriptor"); + + chunk = grub_malloc (chsize); + if (!chunk) + return grub_errno; + + challoc = 1; + err = grub_btrfs_read_logical (data, chaddr, chunk, chsize, + recursion_depth); + if (err) + { + grub_free (chunk); + return err; + } + + chunk_found: + { + grub_uint64_t stripen; + grub_uint64_t stripe_offset; + grub_uint64_t off = addr - grub_le_to_cpu64 (key->offset); + grub_uint64_t chunk_stripe_length; + grub_uint16_t nstripes; + unsigned redundancy = 1; + unsigned i, j; + int is_raid56; + grub_uint64_t parities_pos = 0; + + is_raid56 = !!(grub_le_to_cpu64 (chunk->type) & + (GRUB_BTRFS_CHUNK_TYPE_RAID5 | + GRUB_BTRFS_CHUNK_TYPE_RAID6)); + + if (grub_le_to_cpu64 (chunk->size) <= off) + { + grub_dprintf ("btrfs", "no chunk\n"); + return grub_error (GRUB_ERR_BAD_FS, + "couldn't find the chunk descriptor"); + } + + nstripes = grub_le_to_cpu16 (chunk->nstripes) ? : 1; + chunk_stripe_length = grub_le_to_cpu64 (chunk->stripe_length) ? : 512; + grub_dprintf ("btrfs", "chunk 0x%" PRIxGRUB_UINT64_T + "+0x%" PRIxGRUB_UINT64_T + " (%d stripes (%d substripes) of %" + PRIxGRUB_UINT64_T ")\n", + grub_le_to_cpu64 (key->offset), + grub_le_to_cpu64 (chunk->size), + nstripes, + grub_le_to_cpu16 (chunk->nsubstripes), + chunk_stripe_length); + + g_last_chunk_type = grub_le_to_cpu64 (chunk->type) & ~GRUB_BTRFS_CHUNK_TYPE_BITS_DONTCARE; + + switch (grub_le_to_cpu64 (chunk->type) + & ~GRUB_BTRFS_CHUNK_TYPE_BITS_DONTCARE) + { + case GRUB_BTRFS_CHUNK_TYPE_SINGLE: + { + grub_uint64_t stripe_length; + grub_dprintf ("btrfs", "single\n"); + stripe_length = grub_divmod64 (grub_le_to_cpu64 (chunk->size), + nstripes, + NULL); + if (stripe_length == 0) + stripe_length = 512; + stripen = grub_divmod64 (off, stripe_length, &stripe_offset); + csize = (stripen + 1) * stripe_length - off; + break; + } + case GRUB_BTRFS_CHUNK_TYPE_DUPLICATED: + case GRUB_BTRFS_CHUNK_TYPE_RAID1: + { + grub_dprintf ("btrfs", "RAID1\n"); + stripen = 0; + stripe_offset = off; + csize = grub_le_to_cpu64 (chunk->size) - off; + redundancy = 2; + break; + } + case GRUB_BTRFS_CHUNK_TYPE_RAID0: + { + grub_uint64_t middle, high; + grub_uint64_t low; + grub_dprintf ("btrfs", "RAID0\n"); + middle = grub_divmod64 (off, + chunk_stripe_length, + &low); + + high = grub_divmod64 (middle, nstripes, + &stripen); + stripe_offset = + low + chunk_stripe_length * high; + csize = chunk_stripe_length - low; + break; + } + case GRUB_BTRFS_CHUNK_TYPE_RAID10: + { + grub_uint64_t middle, high; + grub_uint64_t low; + grub_uint16_t nsubstripes; + nsubstripes = grub_le_to_cpu16 (chunk->nsubstripes) ? : 1; + middle = grub_divmod64 (off, + chunk_stripe_length, + &low); + + high = grub_divmod64 (middle, + nstripes / nsubstripes ? : 1, + &stripen); + stripen *= nsubstripes; + redundancy = nsubstripes; + stripe_offset = low + chunk_stripe_length + * high; + csize = chunk_stripe_length - low; + break; + } + case GRUB_BTRFS_CHUNK_TYPE_RAID5: + case GRUB_BTRFS_CHUNK_TYPE_RAID6: + { + grub_uint64_t nparities, stripe_nr, high, low; + + redundancy = 1; /* no redundancy for now */ + + if (grub_le_to_cpu64 (chunk->type) & GRUB_BTRFS_CHUNK_TYPE_RAID5) + { + grub_dprintf ("btrfs", "RAID5\n"); + nparities = 1; + } + else + { + grub_dprintf ("btrfs", "RAID6\n"); + nparities = 2; + } + + /* + * RAID 6 layout consists of several stripes spread over + * the disks, e.g.: + * + * Disk_0 Disk_1 Disk_2 Disk_3 + * A0 B0 P0 Q0 + * Q1 A1 B1 P1 + * P2 Q2 A2 B2 + * + * Note: placement of the parities depend on row number. + * + * Pay attention that the btrfs terminology may differ from + * terminology used in other RAID implementations, e.g. LVM, + * dm or md. The main difference is that btrfs calls contiguous + * block of data on a given disk, e.g. A0, stripe instead of chunk. + * + * The variables listed below have following meaning: + * - stripe_nr is the stripe number excluding the parities + * (A0 = 0, B0 = 1, A1 = 2, B1 = 3, etc.), + * - high is the row number (0 for A0...Q0, 1 for Q1...P1, etc.), + * - stripen is the disk number in a row (0 for A0, Q1, P2, + * 1 for B0, A1, Q2, etc.), + * - off is the logical address to read, + * - chunk_stripe_length is the size of a stripe (typically 64 KiB), + * - nstripes is the number of disks in a row, + * - low is the offset of the data inside a stripe, + * - stripe_offset is the data offset in an array, + * - csize is the "potential" data to read; it will be reduced + * to size if the latter is smaller, + * - nparities is the number of parities (1 for RAID 5, 2 for + * RAID 6); used only in RAID 5/6 code. + */ + stripe_nr = grub_divmod64 (off, chunk_stripe_length, &low); + + /* + * stripen is computed without the parities + * (0 for A0, A1, A2, 1 for B0, B1, B2, etc.). + */ + high = grub_divmod64 (stripe_nr, nstripes - nparities, &stripen); + + /* + * The stripes are spread over the disks. Every each row their + * positions are shifted by 1 place. So, the real disks number + * change. Hence, we have to take into account current row number + * modulo nstripes (0 for A0, 1 for A1, 2 for A2, etc.). + */ + grub_divmod64 (high + stripen, nstripes, &stripen); + + /* + * parities_pos is equal to ((high - nparities) % nstripes) + * (see the diagram above). However, (high - nparities) can + * be negative, e.g. when high == 0, leading to an incorrect + * results. (high + nstripes - nparities) is always positive and + * modulo nstripes is equal to ((high - nparities) % nstripes). + */ + grub_divmod64 (high + nstripes - nparities, nstripes, &parities_pos); + + stripe_offset = chunk_stripe_length * high + low; + csize = chunk_stripe_length - low; + + break; + } + default: + grub_dprintf ("btrfs", "unsupported RAID\n"); + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "unsupported RAID flags %" PRIxGRUB_UINT64_T, + grub_le_to_cpu64 (chunk->type)); + } + if (csize == 0) + return grub_error (GRUB_ERR_BUG, + "couldn't find the chunk descriptor"); + if (csize > (grub_uint64_t) size) + csize = size; + + for (j = 0; j < 2; j++) + { + grub_dprintf ("btrfs", "chunk 0x%" PRIxGRUB_UINT64_T + "+0x%" PRIxGRUB_UINT64_T + " (%d stripes (%d substripes) of %" + PRIxGRUB_UINT64_T ")\n", + grub_le_to_cpu64 (key->offset), + grub_le_to_cpu64 (chunk->size), + grub_le_to_cpu16 (chunk->nstripes), + grub_le_to_cpu16 (chunk->nsubstripes), + grub_le_to_cpu64 (chunk->stripe_length)); + grub_dprintf ("btrfs", "reading laddr 0x%" PRIxGRUB_UINT64_T "\n", + addr); + + if (is_raid56) + { + err = btrfs_read_from_chunk (data, chunk, stripen, + stripe_offset, + 0, /* no mirror */ + csize, buf); + grub_errno = GRUB_ERR_NONE; + if (err) + err = raid56_read_retry (data, chunk, stripe_offset, + stripen, csize, buf, parities_pos); + } + else + for (i = 0; i < redundancy; i++) + { + err = btrfs_read_from_chunk (data, chunk, stripen, + stripe_offset, + i, /* redundancy */ + csize, buf); + if (!err) + break; + grub_errno = GRUB_ERR_NONE; + } + if (!err) + break; + } + if (err) + return grub_errno = err; + } + size -= csize; + buf = (grub_uint8_t *) buf + csize; + addr += csize; + if (challoc) + grub_free (chunk); + } + return GRUB_ERR_NONE; +} + +static struct grub_btrfs_data * +grub_btrfs_mount (grub_device_t dev) +{ + struct grub_btrfs_data *data; + grub_err_t err; + + if (!dev->disk) + { + grub_error (GRUB_ERR_BAD_FS, "not BtrFS"); + return NULL; + } + + data = grub_zalloc (sizeof (*data)); + if (!data) + return NULL; + + err = read_sblock (dev->disk, &data->sblock); + if (err) + { + grub_free (data); + return NULL; + } + + data->n_devices_allocated = 16; + data->devices_attached = grub_malloc (sizeof (data->devices_attached[0]) + * data->n_devices_allocated); + if (!data->devices_attached) + { + grub_free (data); + return NULL; + } + data->n_devices_attached = 1; + data->devices_attached[0].dev = dev; + data->devices_attached[0].id = data->sblock.this_device.device_id; + + return data; +} + +static void +grub_btrfs_unmount (struct grub_btrfs_data *data) +{ + unsigned i; + /* The device 0 is closed one layer upper. */ + for (i = 1; i < data->n_devices_attached; i++) + if (data->devices_attached[i].dev) + grub_device_close (data->devices_attached[i].dev); + grub_free (data->devices_attached); + grub_free (data->extent); + grub_free (data); +} + +static grub_err_t +grub_btrfs_read_inode (struct grub_btrfs_data *data, + struct grub_btrfs_inode *inode, grub_uint64_t num, + grub_uint64_t tree) +{ + struct grub_btrfs_key key_in, key_out; + grub_disk_addr_t elemaddr; + grub_size_t elemsize; + grub_err_t err; + + key_in.object_id = num; + key_in.type = GRUB_BTRFS_ITEM_TYPE_INODE_ITEM; + key_in.offset = 0; + + err = lower_bound (data, &key_in, &key_out, tree, &elemaddr, &elemsize, NULL, + 0); + if (err) + return err; + if (num != key_out.object_id + || key_out.type != GRUB_BTRFS_ITEM_TYPE_INODE_ITEM) + return grub_error (GRUB_ERR_BAD_FS, "inode not found"); + + return grub_btrfs_read_logical (data, elemaddr, inode, sizeof (*inode), 0); +} + +static void *grub_zstd_malloc (void *state __attribute__((unused)), size_t size) +{ + return grub_malloc (size); +} + +static void grub_zstd_free (void *state __attribute__((unused)), void *address) +{ + return grub_free (address); +} + +static ZSTD_customMem grub_zstd_allocator (void) +{ + ZSTD_customMem allocator; + + allocator.customAlloc = &grub_zstd_malloc; + allocator.customFree = &grub_zstd_free; + allocator.opaque = NULL; + + return allocator; +} + +static grub_ssize_t +grub_btrfs_zstd_decompress (char *ibuf, grub_size_t isize, grub_off_t off, + char *obuf, grub_size_t osize) +{ + void *allocated = NULL; + char *otmpbuf = obuf; + grub_size_t otmpsize = osize; + ZSTD_DCtx *dctx = NULL; + grub_size_t zstd_ret; + grub_ssize_t ret = -1; + + /* + * Zstd will fail if it can't fit the entire output in the destination + * buffer, so if osize isn't large enough, allocate a temporary buffer. + */ + if (otmpsize < ZSTD_BTRFS_MAX_INPUT) + { + allocated = grub_malloc (ZSTD_BTRFS_MAX_INPUT); + if (!allocated) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, "failed allocate a zstd buffer"); + goto err; + } + otmpbuf = (char *) allocated; + otmpsize = ZSTD_BTRFS_MAX_INPUT; + } + + /* Create the ZSTD_DCtx. */ + dctx = ZSTD_createDCtx_advanced (grub_zstd_allocator ()); + if (!dctx) + { + /* ZSTD_createDCtx_advanced() only fails if it is out of memory. */ + grub_error (GRUB_ERR_OUT_OF_MEMORY, "failed to create a zstd context"); + goto err; + } + + /* + * Get the real input size, there may be junk at the + * end of the frame. + */ + isize = ZSTD_findFrameCompressedSize (ibuf, isize); + if (ZSTD_isError (isize)) + { + grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "zstd data corrupted"); + goto err; + } + + /* Decompress and check for errors. */ + zstd_ret = ZSTD_decompressDCtx (dctx, otmpbuf, otmpsize, ibuf, isize); + if (ZSTD_isError (zstd_ret)) + { + grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "zstd data corrupted"); + goto err; + } + + /* + * Move the requested data into the obuf. obuf may be equal + * to otmpbuf, which is why grub_memmove() is required. + */ + grub_memmove (obuf, otmpbuf + off, osize); + ret = osize; + +err: + grub_free (allocated); + ZSTD_freeDCtx (dctx); + + return ret; +} + +static grub_ssize_t +grub_btrfs_lzo_decompress(char *ibuf, grub_size_t isize, grub_off_t off, + char *obuf, grub_size_t osize) +{ + grub_uint32_t total_size, cblock_size; + grub_size_t ret = 0; + char *ibuf0 = ibuf; + + total_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); + ibuf += sizeof (total_size); + + if (isize < total_size) + return -1; + + /* Jump forward to first block with requested data. */ + while (off >= GRUB_BTRFS_LZO_BLOCK_SIZE) + { + /* Don't let following uint32_t cross the page boundary. */ + if (((ibuf - ibuf0) & 0xffc) == 0xffc) + ibuf = ((ibuf - ibuf0 + 3) & ~3) + ibuf0; + + cblock_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); + ibuf += sizeof (cblock_size); + + if (cblock_size > GRUB_BTRFS_LZO_BLOCK_MAX_CSIZE) + return -1; + + off -= GRUB_BTRFS_LZO_BLOCK_SIZE; + ibuf += cblock_size; + } + + while (osize > 0) + { + lzo_uint usize = GRUB_BTRFS_LZO_BLOCK_SIZE; + + /* Don't let following uint32_t cross the page boundary. */ + if (((ibuf - ibuf0) & 0xffc) == 0xffc) + ibuf = ((ibuf - ibuf0 + 3) & ~3) + ibuf0; + + cblock_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); + ibuf += sizeof (cblock_size); + + if (cblock_size > GRUB_BTRFS_LZO_BLOCK_MAX_CSIZE) + return -1; + + /* Block partially filled with requested data. */ + if (off > 0 || osize < GRUB_BTRFS_LZO_BLOCK_SIZE) + { + grub_size_t to_copy = GRUB_BTRFS_LZO_BLOCK_SIZE - off; + grub_uint8_t *buf; + + if (to_copy > osize) + to_copy = osize; + + buf = grub_malloc (GRUB_BTRFS_LZO_BLOCK_SIZE); + if (!buf) + return -1; + + if (lzo1x_decompress_safe ((lzo_bytep)ibuf, cblock_size, buf, &usize, + NULL) != LZO_E_OK) + { + grub_free (buf); + return -1; + } + + if (to_copy > usize) + to_copy = usize; + grub_memcpy(obuf, buf + off, to_copy); + + osize -= to_copy; + ret += to_copy; + obuf += to_copy; + ibuf += cblock_size; + off = 0; + + grub_free (buf); + continue; + } + + /* Decompress whole block directly to output buffer. */ + if (lzo1x_decompress_safe ((lzo_bytep)ibuf, cblock_size, (lzo_bytep)obuf, + &usize, NULL) != LZO_E_OK) + return -1; + + osize -= usize; + ret += usize; + obuf += usize; + ibuf += cblock_size; + } + + return ret; +} + +static grub_ssize_t +grub_btrfs_extent_read (struct grub_btrfs_data *data, + grub_uint64_t ino, grub_uint64_t tree, + grub_off_t pos0, char *buf, grub_size_t len) +{ + grub_off_t pos = pos0; + while (len) + { + grub_size_t csize; + grub_err_t err; + grub_off_t extoff; + if (!data->extent || data->extstart > pos || data->extino != ino + || data->exttree != tree || data->extend <= pos) + { + struct grub_btrfs_key key_in, key_out; + grub_disk_addr_t elemaddr; + grub_size_t elemsize; + + grub_free (data->extent); + key_in.object_id = ino; + key_in.type = GRUB_BTRFS_ITEM_TYPE_EXTENT_ITEM; + key_in.offset = grub_cpu_to_le64 (pos); + err = lower_bound (data, &key_in, &key_out, tree, + &elemaddr, &elemsize, NULL, 0); + if (err) + return -1; + if (key_out.object_id != ino + || key_out.type != GRUB_BTRFS_ITEM_TYPE_EXTENT_ITEM) + { + grub_error (GRUB_ERR_BAD_FS, "extent not found"); + return -1; + } + if ((grub_ssize_t) elemsize < ((char *) &data->extent->inl + - (char *) data->extent)) + { + grub_error (GRUB_ERR_BAD_FS, "extent descriptor is too short"); + return -1; + } + data->extstart = grub_le_to_cpu64 (key_out.offset); + data->extsize = elemsize; + data->extent = grub_malloc (elemsize); + data->extino = ino; + data->exttree = tree; + if (!data->extent) + return grub_errno; + + err = grub_btrfs_read_logical (data, elemaddr, data->extent, + elemsize, 0); + if (err) + return err; + + data->extend = data->extstart + grub_le_to_cpu64 (data->extent->size); + if (data->extent->type == GRUB_BTRFS_EXTENT_REGULAR + && (char *) data->extent + elemsize + >= (char *) &data->extent->filled + sizeof (data->extent->filled)) + data->extend = + data->extstart + grub_le_to_cpu64 (data->extent->filled); + + grub_dprintf ("btrfs", "regular extent 0x%" PRIxGRUB_UINT64_T "+0x%" + PRIxGRUB_UINT64_T "\n", + grub_le_to_cpu64 (key_out.offset), + grub_le_to_cpu64 (data->extent->size)); + if (data->extend <= pos) + { + grub_error (GRUB_ERR_BAD_FS, "extent not found"); + return -1; + } + } + csize = data->extend - pos; + extoff = pos - data->extstart; + if (csize > len) + csize = len; + + if (data->extent->encryption) + { + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "encryption not supported"); + return -1; + } + + g_last_compress_type = data->extent->compression; + + if (data->extent->compression != GRUB_BTRFS_COMPRESSION_NONE + && data->extent->compression != GRUB_BTRFS_COMPRESSION_ZLIB + && data->extent->compression != GRUB_BTRFS_COMPRESSION_LZO + && data->extent->compression != GRUB_BTRFS_COMPRESSION_ZSTD) + { + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "compression type 0x%x not supported", + data->extent->compression); + return -1; + } + + if (data->extent->encoding) + { + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "encoding not supported"); + return -1; + } + + switch (data->extent->type) + { + case GRUB_BTRFS_EXTENT_INLINE: + if (data->extent->compression == GRUB_BTRFS_COMPRESSION_ZLIB) + { + if (grub_zlib_decompress (data->extent->inl, data->extsize - + ((grub_uint8_t *) data->extent->inl + - (grub_uint8_t *) data->extent), + extoff, buf, csize) + != (grub_ssize_t) csize) + { + if (!grub_errno) + grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, + "premature end of compressed"); + return -1; + } + } + else if (data->extent->compression == GRUB_BTRFS_COMPRESSION_LZO) + { + if (grub_btrfs_lzo_decompress(data->extent->inl, data->extsize - + ((grub_uint8_t *) data->extent->inl + - (grub_uint8_t *) data->extent), + extoff, buf, csize) + != (grub_ssize_t) csize) + return -1; + } + else if (data->extent->compression == GRUB_BTRFS_COMPRESSION_ZSTD) + { + if (grub_btrfs_zstd_decompress (data->extent->inl, data->extsize - + ((grub_uint8_t *) data->extent->inl + - (grub_uint8_t *) data->extent), + extoff, buf, csize) + != (grub_ssize_t) csize) + return -1; + } + else + grub_memcpy (buf, data->extent->inl + extoff, csize); + break; + case GRUB_BTRFS_EXTENT_REGULAR: + if (!data->extent->laddr) + { + grub_memset (buf, 0, csize); + break; + } + + if (data->extent->compression != GRUB_BTRFS_COMPRESSION_NONE) + { + char *tmp; + grub_uint64_t zsize; + grub_ssize_t ret; + + zsize = grub_le_to_cpu64 (data->extent->compressed_size); + tmp = grub_malloc (zsize); + if (!tmp) + return -1; + err = grub_btrfs_read_logical (data, + grub_le_to_cpu64 (data->extent->laddr), + tmp, zsize, 0); + if (err) + { + grub_free (tmp); + return -1; + } + + if (data->extent->compression == GRUB_BTRFS_COMPRESSION_ZLIB) + ret = grub_zlib_decompress (tmp, zsize, extoff + + grub_le_to_cpu64 (data->extent->offset), + buf, csize); + else if (data->extent->compression == GRUB_BTRFS_COMPRESSION_LZO) + ret = grub_btrfs_lzo_decompress (tmp, zsize, extoff + + grub_le_to_cpu64 (data->extent->offset), + buf, csize); + else if (data->extent->compression == GRUB_BTRFS_COMPRESSION_ZSTD) + ret = grub_btrfs_zstd_decompress (tmp, zsize, extoff + + grub_le_to_cpu64 (data->extent->offset), + buf, csize); + else + ret = -1; + + grub_free (tmp); + + if (ret != (grub_ssize_t) csize) + { + if (!grub_errno) + grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, + "premature end of compressed"); + return -1; + } + + break; + } + err = grub_btrfs_read_logical (data, + grub_le_to_cpu64 (data->extent->laddr) + + grub_le_to_cpu64 (data->extent->offset) + + extoff, buf, csize, 0); + if (err) + return -1; + break; + default: + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "unsupported extent type 0x%x", data->extent->type); + return -1; + } + buf += csize; + pos += csize; + len -= csize; + } + return pos - pos0; +} + +static grub_err_t +get_root (struct grub_btrfs_data *data, struct grub_btrfs_key *key, + grub_uint64_t *tree, grub_uint8_t *type) +{ + grub_err_t err; + grub_disk_addr_t elemaddr; + grub_size_t elemsize; + struct grub_btrfs_key key_out, key_in; + struct grub_btrfs_root_item ri; + + key_in.object_id = grub_cpu_to_le64_compile_time (GRUB_BTRFS_ROOT_VOL_OBJECTID); + key_in.offset = 0; + key_in.type = GRUB_BTRFS_ITEM_TYPE_ROOT_ITEM; + err = lower_bound (data, &key_in, &key_out, + data->sblock.root_tree, + &elemaddr, &elemsize, NULL, 0); + if (err) + return err; + if (key_in.object_id != key_out.object_id + || key_in.type != key_out.type + || key_in.offset != key_out.offset) + return grub_error (GRUB_ERR_BAD_FS, "no root"); + err = grub_btrfs_read_logical (data, elemaddr, &ri, + sizeof (ri), 0); + if (err) + return err; + key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; + key->offset = 0; + key->object_id = grub_cpu_to_le64_compile_time (GRUB_BTRFS_OBJECT_ID_CHUNK); + *tree = ri.tree; + *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; + return GRUB_ERR_NONE; +} + +static grub_err_t +find_path (struct grub_btrfs_data *data, + const char *path, struct grub_btrfs_key *key, + grub_uint64_t *tree, grub_uint8_t *type) +{ + const char *slash = path; + grub_err_t err; + grub_disk_addr_t elemaddr; + grub_size_t elemsize; + grub_size_t allocated = 0; + struct grub_btrfs_dir_item *direl = NULL; + struct grub_btrfs_key key_out; + const char *ctoken; + grub_size_t ctokenlen; + char *path_alloc = NULL; + char *origpath = NULL; + unsigned symlinks_max = 32; + + err = get_root (data, key, tree, type); + if (err) + return err; + + origpath = grub_strdup (path); + if (!origpath) + return grub_errno; + + while (1) + { + while (path[0] == '/') + path++; + if (!path[0]) + break; + slash = grub_strchr (path, '/'); + if (!slash) + slash = path + grub_strlen (path); + ctoken = path; + ctokenlen = slash - path; + + if (*type != GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY) + { + grub_free (path_alloc); + grub_free (origpath); + return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory")); + } + + if (ctokenlen == 1 && ctoken[0] == '.') + { + path = slash; + continue; + } + if (ctokenlen == 2 && ctoken[0] == '.' && ctoken[1] == '.') + { + key->type = GRUB_BTRFS_ITEM_TYPE_INODE_REF; + key->offset = -1; + + err = lower_bound (data, key, &key_out, *tree, &elemaddr, &elemsize, + NULL, 0); + if (err) + { + grub_free (direl); + grub_free (path_alloc); + grub_free (origpath); + return err; + } + + if (key_out.type != key->type + || key->object_id != key_out.object_id) + { + grub_free (direl); + grub_free (path_alloc); + err = grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), origpath); + grub_free (origpath); + return err; + } + + *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; + key->object_id = key_out.offset; + + path = slash; + + continue; + } + + key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; + key->offset = grub_cpu_to_le64 (~grub_getcrc32c (1, ctoken, ctokenlen)); + + err = lower_bound (data, key, &key_out, *tree, &elemaddr, &elemsize, + NULL, 0); + if (err) + { + grub_free (direl); + grub_free (path_alloc); + grub_free (origpath); + return err; + } + if (key_cmp (key, &key_out) != 0) + { + grub_free (direl); + grub_free (path_alloc); + err = grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), origpath); + grub_free (origpath); + return err; + } + + struct grub_btrfs_dir_item *cdirel; + if (elemsize > allocated) + { + allocated = 2 * elemsize; + grub_free (direl); + direl = grub_malloc (allocated + 1); + if (!direl) + { + grub_free (path_alloc); + grub_free (origpath); + return grub_errno; + } + } + + err = grub_btrfs_read_logical (data, elemaddr, direl, elemsize, 0); + if (err) + { + grub_free (direl); + grub_free (path_alloc); + grub_free (origpath); + return err; + } + + for (cdirel = direl; + (grub_uint8_t *) cdirel - (grub_uint8_t *) direl + < (grub_ssize_t) elemsize; + cdirel = (void *) ((grub_uint8_t *) (direl + 1) + + grub_le_to_cpu16 (cdirel->n) + + grub_le_to_cpu16 (cdirel->m))) + { + if (ctokenlen == grub_le_to_cpu16 (cdirel->n) + && grub_memcmp (cdirel->name, ctoken, ctokenlen) == 0) + break; + } + if ((grub_uint8_t *) cdirel - (grub_uint8_t *) direl + >= (grub_ssize_t) elemsize) + { + grub_free (direl); + grub_free (path_alloc); + err = grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), origpath); + grub_free (origpath); + return err; + } + + path = slash; + if (cdirel->type == GRUB_BTRFS_DIR_ITEM_TYPE_SYMLINK) + { + struct grub_btrfs_inode inode; + char *tmp; + if (--symlinks_max == 0) + { + grub_free (direl); + grub_free (path_alloc); + grub_free (origpath); + return grub_error (GRUB_ERR_SYMLINK_LOOP, + N_("too deep nesting of symlinks")); + } + + err = grub_btrfs_read_inode (data, &inode, + cdirel->key.object_id, *tree); + if (err) + { + grub_free (direl); + grub_free (path_alloc); + grub_free (origpath); + return err; + } + tmp = grub_malloc (grub_le_to_cpu64 (inode.size) + + grub_strlen (path) + 1); + if (!tmp) + { + grub_free (direl); + grub_free (path_alloc); + grub_free (origpath); + return grub_errno; + } + + if (grub_btrfs_extent_read (data, cdirel->key.object_id, + *tree, 0, tmp, + grub_le_to_cpu64 (inode.size)) + != (grub_ssize_t) grub_le_to_cpu64 (inode.size)) + { + grub_free (direl); + grub_free (path_alloc); + grub_free (origpath); + grub_free (tmp); + return grub_errno; + } + grub_memcpy (tmp + grub_le_to_cpu64 (inode.size), path, + grub_strlen (path) + 1); + grub_free (path_alloc); + path = path_alloc = tmp; + if (path[0] == '/') + { + err = get_root (data, key, tree, type); + if (err) + return err; + } + continue; + } + *type = cdirel->type; + + switch (cdirel->key.type) + { + case GRUB_BTRFS_ITEM_TYPE_ROOT_ITEM: + { + struct grub_btrfs_root_item ri; + err = lower_bound (data, &cdirel->key, &key_out, + data->sblock.root_tree, + &elemaddr, &elemsize, NULL, 0); + if (err) + { + grub_free (direl); + grub_free (path_alloc); + grub_free (origpath); + return err; + } + if (cdirel->key.object_id != key_out.object_id + || cdirel->key.type != key_out.type) + { + grub_free (direl); + grub_free (path_alloc); + err = grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), origpath); + grub_free (origpath); + return err; + } + err = grub_btrfs_read_logical (data, elemaddr, &ri, + sizeof (ri), 0); + if (err) + { + grub_free (direl); + grub_free (path_alloc); + grub_free (origpath); + return err; + } + key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; + key->offset = 0; + key->object_id = grub_cpu_to_le64_compile_time (GRUB_BTRFS_OBJECT_ID_CHUNK); + *tree = ri.tree; + break; + } + case GRUB_BTRFS_ITEM_TYPE_INODE_ITEM: + if (*slash && *type == GRUB_BTRFS_DIR_ITEM_TYPE_REGULAR) + { + grub_free (direl); + grub_free (path_alloc); + err = grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), origpath); + grub_free (origpath); + return err; + } + *key = cdirel->key; + if (*type == GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY) + key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; + break; + default: + grub_free (path_alloc); + grub_free (origpath); + grub_free (direl); + return grub_error (GRUB_ERR_BAD_FS, "unrecognised object type 0x%x", + cdirel->key.type); + } + } + + grub_free (direl); + grub_free (origpath); + grub_free (path_alloc); + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_btrfs_dir (grub_device_t device, const char *path, + grub_fs_dir_hook_t hook, void *hook_data) +{ + struct grub_btrfs_data *data = grub_btrfs_mount (device); + struct grub_btrfs_key key_in, key_out; + grub_err_t err; + grub_disk_addr_t elemaddr; + grub_size_t elemsize; + grub_size_t allocated = 0; + struct grub_btrfs_dir_item *direl = NULL; + struct grub_btrfs_leaf_descriptor desc; + int r = 0; + grub_uint64_t tree; + grub_uint8_t type; + + if (!data) + return grub_errno; + + err = find_path (data, path, &key_in, &tree, &type); + if (err) + { + grub_btrfs_unmount (data); + return err; + } + if (type != GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY) + { + grub_btrfs_unmount (data); + return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory")); + } + + err = lower_bound (data, &key_in, &key_out, tree, + &elemaddr, &elemsize, &desc, 0); + if (err) + { + grub_btrfs_unmount (data); + return err; + } + if (key_out.type != GRUB_BTRFS_ITEM_TYPE_DIR_ITEM + || key_out.object_id != key_in.object_id) + { + r = next (data, &desc, &elemaddr, &elemsize, &key_out); + if (r <= 0) + goto out; + } + do + { + struct grub_btrfs_dir_item *cdirel; + if (key_out.type != GRUB_BTRFS_ITEM_TYPE_DIR_ITEM + || key_out.object_id != key_in.object_id) + { + r = 0; + break; + } + if (elemsize > allocated) + { + allocated = 2 * elemsize; + grub_free (direl); + direl = grub_malloc (allocated + 1); + if (!direl) + { + r = -grub_errno; + break; + } + } + + err = grub_btrfs_read_logical (data, elemaddr, direl, elemsize, 0); + if (err) + { + r = -err; + break; + } + + for (cdirel = direl; + (grub_uint8_t *) cdirel - (grub_uint8_t *) direl + < (grub_ssize_t) elemsize; + cdirel = (void *) ((grub_uint8_t *) (direl + 1) + + grub_le_to_cpu16 (cdirel->n) + + grub_le_to_cpu16 (cdirel->m))) + { + char c; + struct grub_btrfs_inode inode; + struct grub_dirhook_info info; + err = grub_btrfs_read_inode (data, &inode, cdirel->key.object_id, + tree); + grub_memset (&info, 0, sizeof (info)); + if (err) + grub_errno = GRUB_ERR_NONE; + else + { + info.mtime = grub_le_to_cpu64 (inode.mtime.sec); + info.mtimeset = 1; + } + c = cdirel->name[grub_le_to_cpu16 (cdirel->n)]; + cdirel->name[grub_le_to_cpu16 (cdirel->n)] = 0; + info.dir = (cdirel->type == GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY); + if (hook (cdirel->name, &info, hook_data)) + goto out; + cdirel->name[grub_le_to_cpu16 (cdirel->n)] = c; + } + r = next (data, &desc, &elemaddr, &elemsize, &key_out); + } + while (r > 0); + +out: + grub_free (direl); + + free_iterator (&desc); + grub_btrfs_unmount (data); + + return -r; +} + +static grub_err_t +grub_btrfs_open (struct grub_file *file, const char *name) +{ + struct grub_btrfs_data *data = grub_btrfs_mount (file->device); + grub_err_t err; + struct grub_btrfs_inode inode; + grub_uint8_t type; + struct grub_btrfs_key key_in; + + if (!data) + return grub_errno; + + err = find_path (data, name, &key_in, &data->tree, &type); + if (err) + { + grub_btrfs_unmount (data); + return err; + } + if (type != GRUB_BTRFS_DIR_ITEM_TYPE_REGULAR) + { + grub_btrfs_unmount (data); + return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a regular file")); + } + + data->inode = key_in.object_id; + err = grub_btrfs_read_inode (data, &inode, data->inode, data->tree); + if (err) + { + grub_btrfs_unmount (data); + return err; + } + + file->data = data; + file->size = grub_le_to_cpu64 (inode.size); + + return err; +} + +static grub_err_t +grub_btrfs_close (grub_file_t file) +{ + grub_btrfs_unmount (file->data); + + return GRUB_ERR_NONE; +} + +static grub_ssize_t +grub_btrfs_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_btrfs_data *data = file->data; + + return grub_btrfs_extent_read (data, data->inode, + data->tree, file->offset, buf, len); +} + +static grub_err_t +grub_btrfs_uuid (grub_device_t device, char **uuid) +{ + struct grub_btrfs_data *data; + + *uuid = NULL; + + data = grub_btrfs_mount (device); + if (!data) + return grub_errno; + + *uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x", + grub_be_to_cpu16 (data->sblock.uuid[0]), + grub_be_to_cpu16 (data->sblock.uuid[1]), + grub_be_to_cpu16 (data->sblock.uuid[2]), + grub_be_to_cpu16 (data->sblock.uuid[3]), + grub_be_to_cpu16 (data->sblock.uuid[4]), + grub_be_to_cpu16 (data->sblock.uuid[5]), + grub_be_to_cpu16 (data->sblock.uuid[6]), + grub_be_to_cpu16 (data->sblock.uuid[7])); + + grub_btrfs_unmount (data); + + return grub_errno; +} + +static grub_err_t +grub_btrfs_label (grub_device_t device, char **label) +{ + struct grub_btrfs_data *data; + + *label = NULL; + + data = grub_btrfs_mount (device); + if (!data) + return grub_errno; + + *label = grub_strndup (data->sblock.label, sizeof (data->sblock.label)); + + grub_btrfs_unmount (data); + + return grub_errno; +} + +int grub_btrfs_get_file_chunk(grub_uint64_t part_start, grub_file_t file, ventoy_img_chunk_list *chunk_list) +{ + grub_uint32_t i = 0; + grub_off_t size = 0; + grub_off_t read = 0; + grub_disk_t disk = NULL; + char *buf = NULL; + void *read_hook_data = NULL; + grub_disk_read_hook_t read_hook = NULL; + struct grub_btrfs_data *data = (struct grub_btrfs_data *)file->data; + + if (data->n_devices_attached != 1) + { + chunk_list->err_code = VTOY_CHUNK_ERR_MULTI_DEV; + return 1; + } + + buf = (char *)grub_malloc(VTOY_CHUNK_BUF_SIZE); + if (!buf) + { + return 1; + } + + + //trigger read + grub_file_read(file, buf, 512); + grub_file_seek(file, 0); + + if (g_last_chunk_type != GRUB_BTRFS_CHUNK_TYPE_SINGLE) + { + chunk_list->err_code = VTOY_CHUNK_ERR_RAID; + grub_free(buf); + return 1; + } + else if (g_last_compress_type != GRUB_BTRFS_COMPRESSION_NONE) + { + chunk_list->err_code = VTOY_CHUNK_ERR_COMPRESS; + grub_free(buf); + return 1; + } + + disk = data->devices_attached[0].dev->disk; + read_hook = disk->read_hook; + read_hook_data = disk->read_hook_data; + + disk->read_hook = (grub_disk_read_hook_t)(void *)grub_disk_blocklist_read2; + disk->read_hook_data = chunk_list; + + chunk_list->buf = buf; + chunk_list->last_off = 0; + chunk_list->err_code = 0; + + for (size = file->size; size > 0 && chunk_list->err_code == 0; size -= read) + { + read = (size > VTOY_CHUNK_BUF_SIZE) ? VTOY_CHUNK_BUF_SIZE : size; + grub_file_read(file, buf, read); + } + + disk->read_hook = read_hook; + disk->read_hook_data = read_hook_data; + + chunk_list->buf = NULL; + chunk_list->last_off = 0; + + grub_free(buf); + + for (i = 0; i < chunk_list->cur_chunk; i++) + { + chunk_list->chunk[i].disk_start_sector += part_start; + chunk_list->chunk[i].disk_end_sector += part_start; + } + + return 0; +} + + + +#ifdef GRUB_UTIL +static grub_err_t +grub_btrfs_embed (grub_device_t device __attribute__ ((unused)), + unsigned int *nsectors, + unsigned int max_nsectors, + grub_embed_type_t embed_type, + grub_disk_addr_t **sectors) +{ + unsigned i; + + if (embed_type != GRUB_EMBED_PCBIOS) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "BtrFS currently supports only PC-BIOS embedding"); + + if (64 * 2 - 1 < *nsectors) + return grub_error (GRUB_ERR_OUT_OF_RANGE, + N_("your core.img is unusually large. " + "It won't fit in the embedding area")); + + *nsectors = 64 * 2 - 1; + if (*nsectors > max_nsectors) + *nsectors = max_nsectors; + *sectors = grub_malloc (*nsectors * sizeof (**sectors)); + if (!*sectors) + return grub_errno; + for (i = 0; i < *nsectors; i++) + (*sectors)[i] = i + 1; + + return GRUB_ERR_NONE; +} +#endif + +static struct grub_fs grub_btrfs_fs = { + .name = "btrfs", + .fs_dir = grub_btrfs_dir, + .fs_open = grub_btrfs_open, + .fs_read = grub_btrfs_read, + .fs_close = grub_btrfs_close, + .fs_uuid = grub_btrfs_uuid, + .fs_label = grub_btrfs_label, +#ifdef GRUB_UTIL + .fs_embed = grub_btrfs_embed, + .reserved_first_sector = 1, + .blocklist_install = 0, +#endif +}; + +GRUB_MOD_INIT (btrfs) +{ + grub_fs_register (&grub_btrfs_fs); +} + +GRUB_MOD_FINI (btrfs) +{ + grub_fs_unregister (&grub_btrfs_fs); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/ext2.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/ext2.c new file mode 100644 index 0000000..0a69a96 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/ext2.c @@ -0,0 +1,1149 @@ +/* ext2.c - Second Extended filesystem */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +/* Magic value used to identify an ext2 filesystem. */ +#define EXT2_MAGIC 0xEF53 +/* Amount of indirect blocks in an inode. */ +#define INDIRECT_BLOCKS 12 + +/* The good old revision and the default inode size. */ +#define EXT2_GOOD_OLD_REVISION 0 +#define EXT2_GOOD_OLD_INODE_SIZE 128 + +/* Filetype used in directory entry. */ +#define FILETYPE_UNKNOWN 0 +#define FILETYPE_REG 1 +#define FILETYPE_DIRECTORY 2 +#define FILETYPE_SYMLINK 7 + +/* Filetype information as used in inodes. */ +#define FILETYPE_INO_MASK 0170000 +#define FILETYPE_INO_REG 0100000 +#define FILETYPE_INO_DIRECTORY 0040000 +#define FILETYPE_INO_SYMLINK 0120000 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +/* Log2 size of ext2 block in 512 blocks. */ +#define LOG2_EXT2_BLOCK_SIZE(data) \ + (grub_le_to_cpu32 (data->sblock.log2_block_size) + 1) + +/* Log2 size of ext2 block in bytes. */ +#define LOG2_BLOCK_SIZE(data) \ + (grub_le_to_cpu32 (data->sblock.log2_block_size) + 10) + +/* The size of an ext2 block in bytes. */ +#define EXT2_BLOCK_SIZE(data) (1U << LOG2_BLOCK_SIZE (data)) + +/* The revision level. */ +#define EXT2_REVISION(data) grub_le_to_cpu32 (data->sblock.revision_level) + +/* The inode size. */ +#define EXT2_INODE_SIZE(data) \ + (data->sblock.revision_level \ + == grub_cpu_to_le32_compile_time (EXT2_GOOD_OLD_REVISION) \ + ? EXT2_GOOD_OLD_INODE_SIZE \ + : grub_le_to_cpu16 (data->sblock.inode_size)) + +/* Superblock filesystem feature flags (RW compatible) + * A filesystem with any of these enabled can be read and written by a driver + * that does not understand them without causing metadata/data corruption. */ +#define EXT2_FEATURE_COMPAT_DIR_PREALLOC 0x0001 +#define EXT2_FEATURE_COMPAT_IMAGIC_INODES 0x0002 +#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004 +#define EXT2_FEATURE_COMPAT_EXT_ATTR 0x0008 +#define EXT2_FEATURE_COMPAT_RESIZE_INODE 0x0010 +#define EXT2_FEATURE_COMPAT_DIR_INDEX 0x0020 +/* Superblock filesystem feature flags (RO compatible) + * A filesystem with any of these enabled can be safely read by a driver that + * does not understand them, but should not be written to, usually because + * additional metadata is required. */ +#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 +#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 +#define EXT2_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 +#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010 +#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020 +#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040 +/* Superblock filesystem feature flags (back-incompatible) + * A filesystem with any of these enabled should not be attempted to be read + * by a driver that does not understand them, since they usually indicate + * metadata format changes that might confuse the reader. */ +#define EXT2_FEATURE_INCOMPAT_COMPRESSION 0x0001 +#define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002 +#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */ +#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Volume is journal device */ +#define EXT2_FEATURE_INCOMPAT_META_BG 0x0010 +#define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 /* Extents used */ +#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080 +#define EXT4_FEATURE_INCOMPAT_MMP 0x0100 +#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200 +#define EXT4_FEATURE_INCOMPAT_CSUM_SEED 0x2000 +#define EXT4_FEATURE_INCOMPAT_ENCRYPT 0x10000 + +/* The set of back-incompatible features this driver DOES support. Add (OR) + * flags here as the related features are implemented into the driver. */ +#define EXT2_DRIVER_SUPPORTED_INCOMPAT ( EXT2_FEATURE_INCOMPAT_FILETYPE \ + | EXT4_FEATURE_INCOMPAT_EXTENTS \ + | EXT4_FEATURE_INCOMPAT_FLEX_BG \ + | EXT2_FEATURE_INCOMPAT_META_BG \ + | EXT4_FEATURE_INCOMPAT_64BIT \ + | EXT4_FEATURE_INCOMPAT_ENCRYPT) +/* List of rationales for the ignored "incompatible" features: + * needs_recovery: Not really back-incompatible - was added as such to forbid + * ext2 drivers from mounting an ext3 volume with a dirty + * journal because they will ignore the journal, but the next + * ext3 driver to mount the volume will find the journal and + * replay it, potentially corrupting the metadata written by + * the ext2 drivers. Safe to ignore for this RO driver. + * mmp: Not really back-incompatible - was added as such to + * avoid multiple read-write mounts. Safe to ignore for this + * RO driver. + * checksum seed: Not really back-incompatible - was added to allow tools + * such as tune2fs to change the UUID on a mounted metadata + * checksummed filesystem. Safe to ignore for now since the + * driver doesn't support checksum verification. But it must + * be removed from this list if that support is added later. + * + */ +#define EXT2_DRIVER_IGNORED_INCOMPAT ( EXT3_FEATURE_INCOMPAT_RECOVER \ + | EXT4_FEATURE_INCOMPAT_MMP \ + | EXT4_FEATURE_INCOMPAT_CSUM_SEED) + + +#define EXT3_JOURNAL_MAGIC_NUMBER 0xc03b3998U + +#define EXT3_JOURNAL_DESCRIPTOR_BLOCK 1 +#define EXT3_JOURNAL_COMMIT_BLOCK 2 +#define EXT3_JOURNAL_SUPERBLOCK_V1 3 +#define EXT3_JOURNAL_SUPERBLOCK_V2 4 +#define EXT3_JOURNAL_REVOKE_BLOCK 5 + +#define EXT3_JOURNAL_FLAG_ESCAPE 1 +#define EXT3_JOURNAL_FLAG_SAME_UUID 2 +#define EXT3_JOURNAL_FLAG_DELETED 4 +#define EXT3_JOURNAL_FLAG_LAST_TAG 8 + +#define EXT4_ENCRYPT_FLAG 0x800 +#define EXT4_EXTENTS_FLAG 0x80000 + +/* The ext2 superblock. */ +struct grub_ext2_sblock +{ + grub_uint32_t total_inodes; + grub_uint32_t total_blocks; + grub_uint32_t reserved_blocks; + grub_uint32_t free_blocks; + grub_uint32_t free_inodes; + grub_uint32_t first_data_block; + grub_uint32_t log2_block_size; + grub_uint32_t log2_fragment_size; + grub_uint32_t blocks_per_group; + grub_uint32_t fragments_per_group; + grub_uint32_t inodes_per_group; + grub_uint32_t mtime; + grub_uint32_t utime; + grub_uint16_t mnt_count; + grub_uint16_t max_mnt_count; + grub_uint16_t magic; + grub_uint16_t fs_state; + grub_uint16_t error_handling; + grub_uint16_t minor_revision_level; + grub_uint32_t lastcheck; + grub_uint32_t checkinterval; + grub_uint32_t creator_os; + grub_uint32_t revision_level; + grub_uint16_t uid_reserved; + grub_uint16_t gid_reserved; + grub_uint32_t first_inode; + grub_uint16_t inode_size; + grub_uint16_t block_group_number; + grub_uint32_t feature_compatibility; + grub_uint32_t feature_incompat; + grub_uint32_t feature_ro_compat; + grub_uint16_t uuid[8]; + char volume_name[16]; + char last_mounted_on[64]; + grub_uint32_t compression_info; + grub_uint8_t prealloc_blocks; + grub_uint8_t prealloc_dir_blocks; + grub_uint16_t reserved_gdt_blocks; + grub_uint8_t journal_uuid[16]; + grub_uint32_t journal_inum; + grub_uint32_t journal_dev; + grub_uint32_t last_orphan; + grub_uint32_t hash_seed[4]; + grub_uint8_t def_hash_version; + grub_uint8_t jnl_backup_type; + grub_uint16_t group_desc_size; + grub_uint32_t default_mount_opts; + grub_uint32_t first_meta_bg; + grub_uint32_t mkfs_time; + grub_uint32_t jnl_blocks[17]; +}; + +/* The ext2 blockgroup. */ +struct grub_ext2_block_group +{ + grub_uint32_t block_id; + grub_uint32_t inode_id; + grub_uint32_t inode_table_id; + grub_uint16_t free_blocks; + grub_uint16_t free_inodes; + grub_uint16_t used_dirs; + grub_uint16_t pad; + grub_uint32_t reserved[3]; + grub_uint32_t block_id_hi; + grub_uint32_t inode_id_hi; + grub_uint32_t inode_table_id_hi; + grub_uint16_t free_blocks_hi; + grub_uint16_t free_inodes_hi; + grub_uint16_t used_dirs_hi; + grub_uint16_t pad2; + grub_uint32_t reserved2[3]; +}; + +/* The ext2 inode. */ +struct grub_ext2_inode +{ + grub_uint16_t mode; + grub_uint16_t uid; + grub_uint32_t size; + grub_uint32_t atime; + grub_uint32_t ctime; + grub_uint32_t mtime; + grub_uint32_t dtime; + grub_uint16_t gid; + grub_uint16_t nlinks; + grub_uint32_t blockcnt; /* Blocks of 512 bytes!! */ + grub_uint32_t flags; + grub_uint32_t osd1; + union + { + struct datablocks + { + grub_uint32_t dir_blocks[INDIRECT_BLOCKS]; + grub_uint32_t indir_block; + grub_uint32_t double_indir_block; + grub_uint32_t triple_indir_block; + } blocks; + char symlink[60]; + }; + grub_uint32_t version; + grub_uint32_t acl; + grub_uint32_t size_high; + grub_uint32_t fragment_addr; + grub_uint32_t osd2[3]; +}; + +/* The header of an ext2 directory entry. */ +struct ext2_dirent +{ + grub_uint32_t inode; + grub_uint16_t direntlen; +#define MAX_NAMELEN 255 + grub_uint8_t namelen; + grub_uint8_t filetype; +}; + +struct grub_ext3_journal_header +{ + grub_uint32_t magic; + grub_uint32_t block_type; + grub_uint32_t sequence; +}; + +struct grub_ext3_journal_revoke_header +{ + struct grub_ext3_journal_header header; + grub_uint32_t count; + grub_uint32_t data[0]; +}; + +struct grub_ext3_journal_block_tag +{ + grub_uint32_t block; + grub_uint32_t flags; +}; + +struct grub_ext3_journal_sblock +{ + struct grub_ext3_journal_header header; + grub_uint32_t block_size; + grub_uint32_t maxlen; + grub_uint32_t first; + grub_uint32_t sequence; + grub_uint32_t start; +}; + +#define EXT4_EXT_MAGIC 0xf30a + +struct grub_ext4_extent_header +{ + grub_uint16_t magic; + grub_uint16_t entries; + grub_uint16_t max; + grub_uint16_t depth; + grub_uint32_t generation; +}; + +struct grub_ext4_extent +{ + grub_uint32_t block; + grub_uint16_t len; + grub_uint16_t start_hi; + grub_uint32_t start; +}; + +struct grub_ext4_extent_idx +{ + grub_uint32_t block; + grub_uint32_t leaf; + grub_uint16_t leaf_hi; + grub_uint16_t unused; +}; + +struct grub_fshelp_node +{ + struct grub_ext2_data *data; + struct grub_ext2_inode inode; + int ino; + int inode_read; +}; + +/* Information about a "mounted" ext2 filesystem. */ +struct grub_ext2_data +{ + struct grub_ext2_sblock sblock; + int log_group_desc_size; + grub_disk_t disk; + struct grub_ext2_inode *inode; + struct grub_fshelp_node diropen; +}; + +static grub_dl_t my_mod; + +static int g_ventoy_block_count; + +/* Check is a = b^x for some x. */ +static inline int +is_power_of (grub_uint64_t a, grub_uint32_t b) +{ + grub_uint64_t c; + /* Prevent overflow assuming b < 8. */ + if (a >= (1LL << 60)) + return 0; + for (c = 1; c <= a; c *= b); + return (c == a); +} + + +static inline int +group_has_super_block (struct grub_ext2_data *data, grub_uint64_t group) +{ + if (!(data->sblock.feature_ro_compat + & grub_cpu_to_le32_compile_time(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER))) + return 1; + /* Algorithm looked up in Linux source. */ + if (group <= 1) + return 1; + /* Even number is never a power of odd number. */ + if (!(group & 1)) + return 0; + return (is_power_of(group, 7) || is_power_of(group, 5) || + is_power_of(group, 3)); +} + +/* Read into BLKGRP the blockgroup descriptor of blockgroup GROUP of + the mounted filesystem DATA. */ +inline static grub_err_t +grub_ext2_blockgroup (struct grub_ext2_data *data, grub_uint64_t group, + struct grub_ext2_block_group *blkgrp) +{ + grub_uint64_t full_offset = (group << data->log_group_desc_size); + grub_uint64_t block, offset; + block = (full_offset >> LOG2_BLOCK_SIZE (data)); + offset = (full_offset & ((1 << LOG2_BLOCK_SIZE (data)) - 1)); + if ((data->sblock.feature_incompat + & grub_cpu_to_le32_compile_time (EXT2_FEATURE_INCOMPAT_META_BG)) + && block >= grub_le_to_cpu32(data->sblock.first_meta_bg)) + { + grub_uint64_t first_block_group; + /* Find the first block group for which a descriptor + is stored in given block. */ + first_block_group = (block << (LOG2_BLOCK_SIZE (data) + - data->log_group_desc_size)); + + block = (first_block_group + * grub_le_to_cpu32(data->sblock.blocks_per_group)); + + if (group_has_super_block (data, first_block_group)) + block++; + } + else + /* Superblock. */ + block++; + return grub_disk_read (data->disk, + ((grub_le_to_cpu32 (data->sblock.first_data_block) + + block) + << LOG2_EXT2_BLOCK_SIZE (data)), offset, + sizeof (struct grub_ext2_block_group), blkgrp); +} + +static struct grub_ext4_extent_header * +grub_ext4_find_leaf (struct grub_ext2_data *data, + struct grub_ext4_extent_header *ext_block, + grub_uint32_t fileblock) +{ + struct grub_ext4_extent_idx *index; + void *buf = NULL; + + while (1) + { + int i; + grub_disk_addr_t block; + + index = (struct grub_ext4_extent_idx *) (ext_block + 1); + + if (ext_block->magic != grub_cpu_to_le16_compile_time (EXT4_EXT_MAGIC)) + goto fail; + + if (ext_block->depth == 0) + return ext_block; + + for (i = 0; i < grub_le_to_cpu16 (ext_block->entries); i++) + { + if (fileblock < grub_le_to_cpu32(index[i].block)) + break; + } + + if (--i < 0) + goto fail; + + block = grub_le_to_cpu16 (index[i].leaf_hi); + block = (block << 32) | grub_le_to_cpu32 (index[i].leaf); + if (!buf) + buf = grub_malloc (EXT2_BLOCK_SIZE(data)); + if (!buf) + goto fail; + if (grub_disk_read (data->disk, + block << LOG2_EXT2_BLOCK_SIZE (data), + 0, EXT2_BLOCK_SIZE(data), buf)) + goto fail; + + ext_block = buf; + } + fail: + grub_free (buf); + return 0; +} + +static grub_disk_addr_t +grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) +{ + struct grub_ext2_data *data = node->data; + struct grub_ext2_inode *inode = &node->inode; + unsigned int blksz = EXT2_BLOCK_SIZE (data); + grub_disk_addr_t blksz_quarter = blksz / 4; + int log2_blksz = LOG2_EXT2_BLOCK_SIZE (data); + int log_perblock = log2_blksz + 9 - 2; + grub_uint32_t indir; + int shift; + + if (inode->flags & grub_cpu_to_le32_compile_time (EXT4_EXTENTS_FLAG)) + { + struct grub_ext4_extent_header *leaf; + struct grub_ext4_extent *ext; + int i; + grub_disk_addr_t ret; + + leaf = grub_ext4_find_leaf (data, (struct grub_ext4_extent_header *) inode->blocks.dir_blocks, fileblock); + if (! leaf) + { + grub_error (GRUB_ERR_BAD_FS, "invalid extent"); + return -1; + } + + ext = (struct grub_ext4_extent *) (leaf + 1); + for (i = 0; i < grub_le_to_cpu16 (leaf->entries); i++) + { + if (fileblock < grub_le_to_cpu32 (ext[i].block)) + break; + } + + if (--i >= 0) + { + fileblock -= grub_le_to_cpu32 (ext[i].block); + if (fileblock >= grub_le_to_cpu16 (ext[i].len)) + ret = 0; + else + { + grub_disk_addr_t start; + + start = grub_le_to_cpu16 (ext[i].start_hi); + start = (start << 32) + grub_le_to_cpu32 (ext[i].start); + + g_ventoy_block_count = (int)(grub_le_to_cpu16 (ext[i].len) - fileblock); + ret = fileblock + start; + } + } + else + { + grub_error (GRUB_ERR_BAD_FS, "something wrong with extent"); + ret = -1; + } + + if (leaf != (struct grub_ext4_extent_header *) inode->blocks.dir_blocks) + grub_free (leaf); + + return ret; + } + + /* Direct blocks. */ + if (fileblock < INDIRECT_BLOCKS) + return grub_le_to_cpu32 (inode->blocks.dir_blocks[fileblock]); + fileblock -= INDIRECT_BLOCKS; + /* Indirect. */ + if (fileblock < blksz_quarter) + { + indir = inode->blocks.indir_block; + shift = 0; + goto indirect; + } + fileblock -= blksz_quarter; + /* Double indirect. */ + if (fileblock < blksz_quarter * blksz_quarter) + { + indir = inode->blocks.double_indir_block; + shift = 1; + goto indirect; + } + fileblock -= blksz_quarter * blksz_quarter; + /* Triple indirect. */ + if (fileblock < blksz_quarter * blksz_quarter * (blksz_quarter + 1)) + { + indir = inode->blocks.triple_indir_block; + shift = 2; + goto indirect; + } + grub_error (GRUB_ERR_BAD_FS, + "ext2fs doesn't support quadruple indirect blocks"); + return -1; + +indirect: + do { + /* If the indirect block is zero, all child blocks are absent + (i.e. filled with zeros.) */ + if (indir == 0) + return 0; + if (grub_disk_read (data->disk, + ((grub_disk_addr_t) grub_le_to_cpu32 (indir)) + << log2_blksz, + ((fileblock >> (log_perblock * shift)) + & ((1 << log_perblock) - 1)) + * sizeof (indir), + sizeof (indir), &indir)) + return -1; + } while (shift--); + + return grub_le_to_cpu32 (indir); +} + +/* Read LEN bytes from the file described by DATA starting with byte + POS. Return the amount of read bytes in READ. */ +static grub_ssize_t +grub_ext2_read_file (grub_fshelp_node_t node, + grub_disk_read_hook_t read_hook, void *read_hook_data, + grub_off_t pos, grub_size_t len, char *buf) +{ + return grub_fshelp_read_file (node->data->disk, node, + read_hook, read_hook_data, + pos, len, buf, grub_ext2_read_block, + grub_cpu_to_le32 (node->inode.size) + | (((grub_off_t) grub_cpu_to_le32 (node->inode.size_high)) << 32), + LOG2_EXT2_BLOCK_SIZE (node->data), 0); + +} + + +/* Read the inode INO for the file described by DATA into INODE. */ +static grub_err_t +grub_ext2_read_inode (struct grub_ext2_data *data, + int ino, struct grub_ext2_inode *inode) +{ + struct grub_ext2_block_group blkgrp; + struct grub_ext2_sblock *sblock = &data->sblock; + int inodes_per_block; + unsigned int blkno; + unsigned int blkoff; + grub_disk_addr_t base; + + /* It is easier to calculate if the first inode is 0. */ + ino--; + + grub_ext2_blockgroup (data, + ino / grub_le_to_cpu32 (sblock->inodes_per_group), + &blkgrp); + if (grub_errno) + return grub_errno; + + inodes_per_block = EXT2_BLOCK_SIZE (data) / EXT2_INODE_SIZE (data); + blkno = (ino % grub_le_to_cpu32 (sblock->inodes_per_group)) + / inodes_per_block; + blkoff = (ino % grub_le_to_cpu32 (sblock->inodes_per_group)) + % inodes_per_block; + + base = grub_le_to_cpu32 (blkgrp.inode_table_id); + if (data->log_group_desc_size >= 6) + base |= (((grub_disk_addr_t) grub_le_to_cpu32 (blkgrp.inode_table_id_hi)) + << 32); + + /* Read the inode. */ + if (grub_disk_read (data->disk, + ((base + blkno) << LOG2_EXT2_BLOCK_SIZE (data)), + EXT2_INODE_SIZE (data) * blkoff, + sizeof (struct grub_ext2_inode), inode)) + return grub_errno; + + return 0; +} + +static struct grub_ext2_data * +grub_ext2_mount (grub_disk_t disk) +{ + struct grub_ext2_data *data; + + data = grub_malloc (sizeof (struct grub_ext2_data)); + if (!data) + return 0; + + /* Read the superblock. */ + grub_disk_read (disk, 1 * 2, 0, sizeof (struct grub_ext2_sblock), + &data->sblock); + if (grub_errno) + goto fail; + + /* Make sure this is an ext2 filesystem. */ + if (data->sblock.magic != grub_cpu_to_le16_compile_time (EXT2_MAGIC) + || grub_le_to_cpu32 (data->sblock.log2_block_size) >= 16 + || data->sblock.inodes_per_group == 0 + /* 20 already means 1GiB blocks. We don't want to deal with blocks overflowing int32. */ + || grub_le_to_cpu32 (data->sblock.log2_block_size) > 20 + || EXT2_INODE_SIZE (data) == 0 + || EXT2_BLOCK_SIZE (data) / EXT2_INODE_SIZE (data) == 0) + { + grub_error (GRUB_ERR_BAD_FS, "not an ext2 filesystem"); + goto fail; + } + + /* Check the FS doesn't have feature bits enabled that we don't support. */ + if (data->sblock.revision_level != grub_cpu_to_le32_compile_time (EXT2_GOOD_OLD_REVISION) + && (data->sblock.feature_incompat + & grub_cpu_to_le32_compile_time (~(EXT2_DRIVER_SUPPORTED_INCOMPAT + | EXT2_DRIVER_IGNORED_INCOMPAT)))) + { + grub_error (GRUB_ERR_BAD_FS, "filesystem has unsupported incompatible features"); + goto fail; + } + + if (data->sblock.revision_level != grub_cpu_to_le32_compile_time (EXT2_GOOD_OLD_REVISION) + && (data->sblock.feature_incompat + & grub_cpu_to_le32_compile_time (EXT4_FEATURE_INCOMPAT_64BIT)) + && data->sblock.group_desc_size != 0 + && ((data->sblock.group_desc_size & (data->sblock.group_desc_size - 1)) + == 0) + && (data->sblock.group_desc_size & grub_cpu_to_le16_compile_time (0x1fe0))) + { + grub_uint16_t b = grub_le_to_cpu16 (data->sblock.group_desc_size); + for (data->log_group_desc_size = 0; b != (1 << data->log_group_desc_size); + data->log_group_desc_size++); + } + else + data->log_group_desc_size = 5; + + data->disk = disk; + + data->diropen.data = data; + data->diropen.ino = 2; + data->diropen.inode_read = 1; + + data->inode = &data->diropen.inode; + + grub_ext2_read_inode (data, 2, data->inode); + if (grub_errno) + goto fail; + + return data; + + fail: + if (grub_errno == GRUB_ERR_OUT_OF_RANGE) + grub_error (GRUB_ERR_BAD_FS, "not an ext2 filesystem"); + + grub_free (data); + return 0; +} + +static char * +grub_ext2_read_symlink (grub_fshelp_node_t node) +{ + char *symlink; + struct grub_fshelp_node *diro = node; + + if (! diro->inode_read) + { + grub_ext2_read_inode (diro->data, diro->ino, &diro->inode); + if (grub_errno) + return 0; + + if (diro->inode.flags & grub_cpu_to_le32_compile_time (EXT4_ENCRYPT_FLAG)) + { + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "symlink is encrypted"); + return 0; + } + } + + symlink = grub_malloc (grub_le_to_cpu32 (diro->inode.size) + 1); + if (! symlink) + return 0; + + /* + * If the filesize of the symlink is equal to or bigger than 60 the symlink + * is stored in a separate block, otherwise it is stored in the inode. + */ + if (grub_le_to_cpu32 (diro->inode.size) < sizeof (diro->inode.symlink)) + grub_memcpy (symlink, + diro->inode.symlink, + grub_le_to_cpu32 (diro->inode.size)); + else + { + grub_ext2_read_file (diro, 0, 0, 0, + grub_le_to_cpu32 (diro->inode.size), + symlink); + if (grub_errno) + { + grub_free (symlink); + return 0; + } + } + + symlink[grub_le_to_cpu32 (diro->inode.size)] = '\0'; + return symlink; +} + +static int +grub_ext2_iterate_dir (grub_fshelp_node_t dir, + grub_fshelp_iterate_dir_hook_t hook, void *hook_data) +{ + unsigned int fpos = 0; + struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir; + + if (! diro->inode_read) + { + grub_ext2_read_inode (diro->data, diro->ino, &diro->inode); + if (grub_errno) + return 0; + } + + if (diro->inode.flags & grub_cpu_to_le32_compile_time (EXT4_ENCRYPT_FLAG)) + { + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "directory is encrypted"); + return 0; + } + + /* Search the file. */ + while (fpos < grub_le_to_cpu32 (diro->inode.size)) + { + struct ext2_dirent dirent; + + grub_ext2_read_file (diro, 0, 0, fpos, sizeof (struct ext2_dirent), + (char *) &dirent); + if (grub_errno) + return 0; + + if (dirent.direntlen == 0) + return 0; + + if (dirent.inode != 0 && dirent.namelen != 0) + { + char filename[MAX_NAMELEN + 1]; + struct grub_fshelp_node *fdiro; + enum grub_fshelp_filetype type = GRUB_FSHELP_UNKNOWN; + + grub_ext2_read_file (diro, 0, 0, fpos + sizeof (struct ext2_dirent), + dirent.namelen, filename); + if (grub_errno) + return 0; + + fdiro = grub_malloc (sizeof (struct grub_fshelp_node)); + if (! fdiro) + return 0; + + fdiro->data = diro->data; + fdiro->ino = grub_le_to_cpu32 (dirent.inode); + + filename[dirent.namelen] = '\0'; + + if (dirent.filetype != FILETYPE_UNKNOWN) + { + fdiro->inode_read = 0; + + if (dirent.filetype == FILETYPE_DIRECTORY) + type = GRUB_FSHELP_DIR; + else if (dirent.filetype == FILETYPE_SYMLINK) + type = GRUB_FSHELP_SYMLINK; + else if (dirent.filetype == FILETYPE_REG) + type = GRUB_FSHELP_REG; + } + else + { + /* The filetype can not be read from the dirent, read + the inode to get more information. */ + grub_ext2_read_inode (diro->data, + grub_le_to_cpu32 (dirent.inode), + &fdiro->inode); + if (grub_errno) + { + grub_free (fdiro); + return 0; + } + + fdiro->inode_read = 1; + + if ((grub_le_to_cpu16 (fdiro->inode.mode) + & FILETYPE_INO_MASK) == FILETYPE_INO_DIRECTORY) + type = GRUB_FSHELP_DIR; + else if ((grub_le_to_cpu16 (fdiro->inode.mode) + & FILETYPE_INO_MASK) == FILETYPE_INO_SYMLINK) + type = GRUB_FSHELP_SYMLINK; + else if ((grub_le_to_cpu16 (fdiro->inode.mode) + & FILETYPE_INO_MASK) == FILETYPE_INO_REG) + type = GRUB_FSHELP_REG; + } + + if (hook (filename, type, fdiro, hook_data)) + return 1; + } + + fpos += grub_le_to_cpu16 (dirent.direntlen); + } + + return 0; +} + +/* Open a file named NAME and initialize FILE. */ +static grub_err_t +grub_ext2_open (struct grub_file *file, const char *name) +{ + struct grub_ext2_data *data; + struct grub_fshelp_node *fdiro = 0; + grub_err_t err; + + grub_dl_ref (my_mod); + + data = grub_ext2_mount (file->device->disk); + if (! data) + { + err = grub_errno; + goto fail; + } + + err = grub_fshelp_find_file (name, &data->diropen, &fdiro, + grub_ext2_iterate_dir, + grub_ext2_read_symlink, GRUB_FSHELP_REG); + if (err) + goto fail; + + if (! fdiro->inode_read) + { + err = grub_ext2_read_inode (data, fdiro->ino, &fdiro->inode); + if (err) + goto fail; + } + + if (fdiro->inode.flags & grub_cpu_to_le32_compile_time (EXT4_ENCRYPT_FLAG)) + { + err = grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "file is encrypted"); + goto fail; + } + + grub_memcpy (data->inode, &fdiro->inode, sizeof (struct grub_ext2_inode)); + grub_free (fdiro); + + file->size = grub_le_to_cpu32 (data->inode->size); + file->size |= ((grub_off_t) grub_le_to_cpu32 (data->inode->size_high)) << 32; + file->data = data; + file->offset = 0; + + return 0; + + fail: + if (fdiro != &data->diropen) + grub_free (fdiro); + grub_free (data); + + grub_dl_unref (my_mod); + + return err; +} + +static grub_err_t +grub_ext2_close (grub_file_t file) +{ + grub_free (file->data); + + grub_dl_unref (my_mod); + + return GRUB_ERR_NONE; +} + +/* Read LEN bytes data from FILE into BUF. */ +static grub_ssize_t +grub_ext2_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_ext2_data *data = (struct grub_ext2_data *) file->data; + + return grub_ext2_read_file (&data->diropen, + file->read_hook, file->read_hook_data, + file->offset, len, buf); +} + + +/* Context for grub_ext2_dir. */ +struct grub_ext2_dir_ctx +{ + grub_fs_dir_hook_t hook; + void *hook_data; + struct grub_ext2_data *data; +}; + +/* Helper for grub_ext2_dir. */ +static int +grub_ext2_dir_iter (const char *filename, enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node, void *data) +{ + struct grub_ext2_dir_ctx *ctx = data; + struct grub_dirhook_info info; + + grub_memset (&info, 0, sizeof (info)); + if (! node->inode_read) + { + grub_ext2_read_inode (ctx->data, node->ino, &node->inode); + if (!grub_errno) + node->inode_read = 1; + grub_errno = GRUB_ERR_NONE; + } + if (node->inode_read) + { + info.mtimeset = 1; + info.mtime = grub_le_to_cpu32 (node->inode.mtime); + } + + info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); + if (!info.dir) + info.size = (((grub_off_t) grub_le_to_cpu32 (node->inode.size_high)) << 32) | grub_le_to_cpu32 (node->inode.size); + grub_free (node); + return ctx->hook (filename, &info, ctx->hook_data); +} + +static grub_err_t +grub_ext2_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook, + void *hook_data) +{ + struct grub_ext2_dir_ctx ctx = { + .hook = hook, + .hook_data = hook_data + }; + struct grub_fshelp_node *fdiro = 0; + + grub_dl_ref (my_mod); + + ctx.data = grub_ext2_mount (device->disk); + if (! ctx.data) + goto fail; + + grub_fshelp_find_file (path, &ctx.data->diropen, &fdiro, + grub_ext2_iterate_dir, grub_ext2_read_symlink, + GRUB_FSHELP_DIR); + if (grub_errno) + goto fail; + + grub_ext2_iterate_dir (fdiro, grub_ext2_dir_iter, &ctx); + + fail: + if (fdiro != &ctx.data->diropen) + grub_free (fdiro); + grub_free (ctx.data); + + grub_dl_unref (my_mod); + + return grub_errno; +} + +static grub_err_t +grub_ext2_label (grub_device_t device, char **label) +{ + struct grub_ext2_data *data; + grub_disk_t disk = device->disk; + + grub_dl_ref (my_mod); + + data = grub_ext2_mount (disk); + if (data) + *label = grub_strndup (data->sblock.volume_name, + sizeof (data->sblock.volume_name)); + else + *label = NULL; + + grub_dl_unref (my_mod); + + grub_free (data); + + return grub_errno; +} + +static grub_err_t +grub_ext2_uuid (grub_device_t device, char **uuid) +{ + struct grub_ext2_data *data; + grub_disk_t disk = device->disk; + + grub_dl_ref (my_mod); + + data = grub_ext2_mount (disk); + if (data) + { + *uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x", + grub_be_to_cpu16 (data->sblock.uuid[0]), + grub_be_to_cpu16 (data->sblock.uuid[1]), + grub_be_to_cpu16 (data->sblock.uuid[2]), + grub_be_to_cpu16 (data->sblock.uuid[3]), + grub_be_to_cpu16 (data->sblock.uuid[4]), + grub_be_to_cpu16 (data->sblock.uuid[5]), + grub_be_to_cpu16 (data->sblock.uuid[6]), + grub_be_to_cpu16 (data->sblock.uuid[7])); + } + else + *uuid = NULL; + + grub_dl_unref (my_mod); + + grub_free (data); + + return grub_errno; +} + +/* Get mtime. */ +static grub_err_t +grub_ext2_mtime (grub_device_t device, grub_int32_t *tm) +{ + struct grub_ext2_data *data; + grub_disk_t disk = device->disk; + + grub_dl_ref (my_mod); + + data = grub_ext2_mount (disk); + if (!data) + *tm = 0; + else + *tm = grub_le_to_cpu32 (data->sblock.utime); + + grub_dl_unref (my_mod); + + grub_free (data); + + return grub_errno; + +} + +int grub_ext_get_file_chunk(grub_uint64_t part_start, grub_file_t file, ventoy_img_chunk_list *chunk_list) +{ + int blocksize; + int log2blocksize; + grub_disk_t disk; + grub_disk_addr_t i = 0; + grub_disk_addr_t blockcnt; + grub_disk_addr_t blknr; + grub_fshelp_node_t node = NULL; + + disk = file->device->disk; + node = &(((struct grub_ext2_data *)file->data)->diropen); + + log2blocksize = LOG2_EXT2_BLOCK_SIZE (node->data); + blocksize = 1 << (log2blocksize + GRUB_DISK_SECTOR_BITS); + blockcnt = (file->size + blocksize - 1) >> (log2blocksize + GRUB_DISK_SECTOR_BITS); + + while (i < blockcnt) + { + g_ventoy_block_count = 1; + blknr = grub_ext2_read_block(node, i); + if (blknr == 0) + { + return 0; + } + + i += g_ventoy_block_count; + blknr = blknr << log2blocksize; + grub_disk_blocklist_read(chunk_list, blknr, g_ventoy_block_count * blocksize, disk->log_sector_size); + } + + for (i = 0; i < chunk_list->cur_chunk; i++) + { + chunk_list->chunk[i].disk_start_sector += part_start; + chunk_list->chunk[i].disk_end_sector += part_start; + } + + return 0; +} + +static struct grub_fs grub_ext2_fs = + { + .name = "ext2", + .fs_dir = grub_ext2_dir, + .fs_open = grub_ext2_open, + .fs_read = grub_ext2_read, + .fs_close = grub_ext2_close, + .fs_label = grub_ext2_label, + .fs_uuid = grub_ext2_uuid, + .fs_mtime = grub_ext2_mtime, +#ifdef GRUB_UTIL + .reserved_first_sector = 1, + .blocklist_install = 1, +#endif + .next = 0 + }; + +GRUB_MOD_INIT(ext2) +{ + grub_fs_register (&grub_ext2_fs); + my_mod = mod; +} + +GRUB_MOD_FINI(ext2) +{ + grub_fs_unregister (&grub_ext2_fs); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/fat.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/fat.c new file mode 100644 index 0000000..439ec41 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/fat.c @@ -0,0 +1,1403 @@ +/* fat.c - FAT filesystem */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef MODE_EXFAT +#include +#else +#include +#endif +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +enum + { + GRUB_FAT_ATTR_READ_ONLY = 0x01, + GRUB_FAT_ATTR_HIDDEN = 0x02, + GRUB_FAT_ATTR_SYSTEM = 0x04, +#ifndef MODE_EXFAT + GRUB_FAT_ATTR_VOLUME_ID = 0x08, +#endif + GRUB_FAT_ATTR_DIRECTORY = 0x10, + GRUB_FAT_ATTR_ARCHIVE = 0x20, + +#ifndef MODE_EXFAT + GRUB_FAT_ATTR_LONG_NAME = (GRUB_FAT_ATTR_READ_ONLY + | GRUB_FAT_ATTR_HIDDEN + | GRUB_FAT_ATTR_SYSTEM + | GRUB_FAT_ATTR_VOLUME_ID), +#endif + GRUB_FAT_ATTR_VALID = (GRUB_FAT_ATTR_READ_ONLY + | GRUB_FAT_ATTR_HIDDEN + | GRUB_FAT_ATTR_SYSTEM + | GRUB_FAT_ATTR_DIRECTORY + | GRUB_FAT_ATTR_ARCHIVE +#ifndef MODE_EXFAT + | GRUB_FAT_ATTR_VOLUME_ID +#endif + ) + }; + +#ifdef MODE_EXFAT +typedef struct grub_exfat_bpb grub_current_fat_bpb_t; +#else +typedef struct grub_fat_bpb grub_current_fat_bpb_t; +#endif + +#ifdef MODE_EXFAT +enum + { + FLAG_CONTIGUOUS = 2 + }; +struct grub_fat_dir_entry +{ + grub_uint8_t entry_type; + union + { + grub_uint8_t placeholder[31]; + struct { + grub_uint8_t secondary_count; + grub_uint16_t checksum; + grub_uint16_t attr; + grub_uint16_t reserved1; + grub_uint32_t c_time; + grub_uint32_t m_time; + grub_uint32_t a_time; + grub_uint8_t c_time_tenth; + grub_uint8_t m_time_tenth; + grub_uint8_t a_time_tenth; + grub_uint8_t reserved2[9]; + } GRUB_PACKED file; + struct { + grub_uint8_t flags; + grub_uint8_t reserved1; + grub_uint8_t name_length; + grub_uint16_t name_hash; + grub_uint16_t reserved2; + grub_uint64_t valid_size; + grub_uint32_t reserved3; + grub_uint32_t first_cluster; + grub_uint64_t file_size; + } GRUB_PACKED stream_extension; + struct { + grub_uint8_t flags; + grub_uint16_t str[15]; + } GRUB_PACKED file_name; + struct { + grub_uint8_t character_count; + grub_uint16_t str[15]; + } GRUB_PACKED volume_label; + } GRUB_PACKED type_specific; +} GRUB_PACKED; + +struct grub_fat_dir_node +{ + grub_uint32_t attr; + grub_uint32_t first_cluster; + grub_uint64_t file_size; + grub_uint64_t valid_size; + int have_stream; + int is_contiguous; +}; + +typedef struct grub_fat_dir_node grub_fat_dir_node_t; + +#else +struct grub_fat_dir_entry +{ + grub_uint8_t name[11]; + grub_uint8_t attr; + grub_uint8_t nt_reserved; + grub_uint8_t c_time_tenth; + grub_uint16_t c_time; + grub_uint16_t c_date; + grub_uint16_t a_date; + grub_uint16_t first_cluster_high; + grub_uint16_t w_time; + grub_uint16_t w_date; + grub_uint16_t first_cluster_low; + grub_uint32_t file_size; +} GRUB_PACKED; + +struct grub_fat_long_name_entry +{ + grub_uint8_t id; + grub_uint16_t name1[5]; + grub_uint8_t attr; + grub_uint8_t reserved; + grub_uint8_t checksum; + grub_uint16_t name2[6]; + grub_uint16_t first_cluster; + grub_uint16_t name3[2]; +} GRUB_PACKED; + +typedef struct grub_fat_dir_entry grub_fat_dir_node_t; + +#endif + +struct grub_fat_data +{ + int logical_sector_bits; + grub_uint32_t num_sectors; + + grub_uint32_t fat_sector; + grub_uint32_t sectors_per_fat; + int fat_size; + + grub_uint32_t root_cluster; +#ifndef MODE_EXFAT + grub_uint32_t root_sector; + grub_uint32_t num_root_sectors; +#endif + + int cluster_bits; + grub_uint32_t cluster_eof_mark; + grub_uint32_t cluster_sector; + grub_uint32_t num_clusters; + + grub_uint32_t uuid; +}; + +struct grub_fshelp_node { + grub_disk_t disk; + struct grub_fat_data *data; + + grub_uint8_t attr; +#ifndef MODE_EXFAT + grub_uint32_t file_size; +#else + grub_uint64_t file_size; +#endif + grub_uint32_t file_cluster; + grub_uint32_t cur_cluster_num; + grub_uint32_t cur_cluster; + +#ifdef MODE_EXFAT + int is_contiguous; +#endif +}; + +static grub_dl_t my_mod; + +#ifndef MODE_EXFAT +static int +fat_log2 (unsigned x) +{ + int i; + + if (x == 0) + return -1; + + for (i = 0; (x & 1) == 0; i++) + x >>= 1; + + if (x != 1) + return -1; + + return i; +} +#endif + +static struct grub_fat_data * +grub_fat_mount (grub_disk_t disk) +{ + grub_current_fat_bpb_t bpb; + struct grub_fat_data *data = 0; + grub_uint32_t first_fat, magic; + + if (! disk) + goto fail; + + data = (struct grub_fat_data *) grub_malloc (sizeof (*data)); + if (! data) + goto fail; + + /* Read the BPB. */ + if (grub_disk_read (disk, 0, 0, sizeof (bpb), &bpb)) + goto fail; + +#ifdef MODE_EXFAT + if (grub_memcmp ((const char *) bpb.oem_name, "EXFAT ", + sizeof (bpb.oem_name)) != 0) + goto fail; +#endif + + /* Get the sizes of logical sectors and clusters. */ +#ifdef MODE_EXFAT + data->logical_sector_bits = bpb.bytes_per_sector_shift; +#else + data->logical_sector_bits = + fat_log2 (grub_le_to_cpu16 (bpb.bytes_per_sector)); +#endif + if (data->logical_sector_bits < GRUB_DISK_SECTOR_BITS + || data->logical_sector_bits >= 16) + goto fail; + data->logical_sector_bits -= GRUB_DISK_SECTOR_BITS; + +#ifdef MODE_EXFAT + data->cluster_bits = bpb.sectors_per_cluster_shift; +#else + data->cluster_bits = fat_log2 (bpb.sectors_per_cluster); +#endif + if (data->cluster_bits < 0 || data->cluster_bits > 25) + goto fail; + data->cluster_bits += data->logical_sector_bits; + + /* Get information about FATs. */ +#ifdef MODE_EXFAT + data->fat_sector = (grub_le_to_cpu32 (bpb.num_reserved_sectors) + << data->logical_sector_bits); +#else + data->fat_sector = (grub_le_to_cpu16 (bpb.num_reserved_sectors) + << data->logical_sector_bits); +#endif + if (data->fat_sector == 0) + goto fail; + +#ifdef MODE_EXFAT + data->sectors_per_fat = (grub_le_to_cpu32 (bpb.sectors_per_fat) + << data->logical_sector_bits); +#else + data->sectors_per_fat = ((bpb.sectors_per_fat_16 + ? grub_le_to_cpu16 (bpb.sectors_per_fat_16) + : grub_le_to_cpu32 (bpb.version_specific.fat32.sectors_per_fat_32)) + << data->logical_sector_bits); +#endif + if (data->sectors_per_fat == 0) + goto fail; + + /* Get the number of sectors in this volume. */ +#ifdef MODE_EXFAT + data->num_sectors = ((grub_le_to_cpu64 (bpb.num_total_sectors)) + << data->logical_sector_bits); +#else + data->num_sectors = ((bpb.num_total_sectors_16 + ? grub_le_to_cpu16 (bpb.num_total_sectors_16) + : grub_le_to_cpu32 (bpb.num_total_sectors_32)) + << data->logical_sector_bits); +#endif + if (data->num_sectors == 0) + goto fail; + + /* Get information about the root directory. */ + if (bpb.num_fats == 0) + goto fail; + +#ifndef MODE_EXFAT + data->root_sector = data->fat_sector + bpb.num_fats * data->sectors_per_fat; + data->num_root_sectors + = ((((grub_uint32_t) grub_le_to_cpu16 (bpb.num_root_entries) + * sizeof (struct grub_fat_dir_entry) + + grub_le_to_cpu16 (bpb.bytes_per_sector) - 1) + >> (data->logical_sector_bits + GRUB_DISK_SECTOR_BITS)) + << (data->logical_sector_bits)); +#endif + +#ifdef MODE_EXFAT + data->cluster_sector = (grub_le_to_cpu32 (bpb.cluster_offset) + << data->logical_sector_bits); + data->num_clusters = (grub_le_to_cpu32 (bpb.cluster_count) + << data->logical_sector_bits); +#else + data->cluster_sector = data->root_sector + data->num_root_sectors; + data->num_clusters = (((data->num_sectors - data->cluster_sector) + >> data->cluster_bits) + + 2); +#endif + + if (data->num_clusters <= 2) + goto fail; + +#ifdef MODE_EXFAT + { + /* exFAT. */ + data->root_cluster = grub_le_to_cpu32 (bpb.root_cluster); + data->fat_size = 32; + data->cluster_eof_mark = 0xffffffff; + + if ((bpb.volume_flags & grub_cpu_to_le16_compile_time (0x1)) + && bpb.num_fats > 1) + data->fat_sector += data->sectors_per_fat; + } +#else + if (! bpb.sectors_per_fat_16) + { + /* FAT32. */ + grub_uint16_t flags = grub_le_to_cpu16 (bpb.version_specific.fat32.extended_flags); + + data->root_cluster = grub_le_to_cpu32 (bpb.version_specific.fat32.root_cluster); + data->fat_size = 32; + data->cluster_eof_mark = 0x0ffffff8; + + if (flags & 0x80) + { + /* Get an active FAT. */ + unsigned active_fat = flags & 0xf; + + if (active_fat > bpb.num_fats) + goto fail; + + data->fat_sector += active_fat * data->sectors_per_fat; + } + + if (bpb.num_root_entries != 0 || bpb.version_specific.fat32.fs_version != 0) + goto fail; + } + else + { + /* FAT12 or FAT16. */ + data->root_cluster = ~0U; + + if (data->num_clusters <= 4085 + 2) + { + /* FAT12. */ + data->fat_size = 12; + data->cluster_eof_mark = 0x0ff8; + } + else + { + /* FAT16. */ + data->fat_size = 16; + data->cluster_eof_mark = 0xfff8; + } + } +#endif + + /* More sanity checks. */ + if (data->num_sectors <= data->fat_sector) + goto fail; + + if (grub_disk_read (disk, + data->fat_sector, + 0, + sizeof (first_fat), + &first_fat)) + goto fail; + + first_fat = grub_le_to_cpu32 (first_fat); + + if (data->fat_size == 32) + { + first_fat &= 0x0fffffff; + magic = 0x0fffff00; + } + else if (data->fat_size == 16) + { + first_fat &= 0x0000ffff; + magic = 0xff00; + } + else + { + first_fat &= 0x00000fff; + magic = 0x0f00; + } + + /* Serial number. */ +#ifdef MODE_EXFAT + data->uuid = grub_le_to_cpu32 (bpb.num_serial); +#else + if (bpb.sectors_per_fat_16) + data->uuid = grub_le_to_cpu32 (bpb.version_specific.fat12_or_fat16.num_serial); + else + data->uuid = grub_le_to_cpu32 (bpb.version_specific.fat32.num_serial); +#endif + +#ifndef MODE_EXFAT + /* Ignore the 3rd bit, because some BIOSes assigns 0xF0 to the media + descriptor, even if it is a so-called superfloppy (e.g. an USB key). + The check may be too strict for this kind of stupid BIOSes, as + they overwrite the media descriptor. */ + if ((first_fat | 0x8) != (magic | bpb.media | 0x8)) + goto fail; +#else + (void) magic; +#endif + + return data; + + fail: + + grub_free (data); + grub_error (GRUB_ERR_BAD_FS, "not a FAT filesystem"); + return 0; +} + +static grub_ssize_t +grub_fat_read_data (grub_disk_t disk, grub_fshelp_node_t node, + grub_disk_read_hook_t read_hook, void *read_hook_data, + grub_off_t offset, grub_size_t len, char *buf) +{ + grub_size_t size; + grub_uint32_t logical_cluster; + unsigned logical_cluster_bits; + grub_ssize_t ret = 0; + unsigned long sector; + +#ifndef MODE_EXFAT + /* This is a special case. FAT12 and FAT16 doesn't have the root directory + in clusters. */ + if (node->file_cluster == ~0U) + { + size = (node->data->num_root_sectors << GRUB_DISK_SECTOR_BITS) - offset; + if (size > len) + size = len; + + if (grub_disk_read (disk, node->data->root_sector, offset, size, buf)) + return -1; + + return size; + } +#endif + +#ifdef MODE_EXFAT + if (node->is_contiguous) + { + /* Read the data here. */ + sector = (node->data->cluster_sector + + ((node->file_cluster - 2) + << node->data->cluster_bits)); + + disk->read_hook = read_hook; + disk->read_hook_data = read_hook_data; + grub_disk_read (disk, sector + (offset >> GRUB_DISK_SECTOR_BITS), + offset & (GRUB_DISK_SECTOR_SIZE - 1), len, buf); + disk->read_hook = 0; + if (grub_errno) + return -1; + + return len; + } +#endif + + /* Calculate the logical cluster number and offset. */ + logical_cluster_bits = (node->data->cluster_bits + + GRUB_DISK_SECTOR_BITS); + logical_cluster = offset >> logical_cluster_bits; + offset &= (1ULL << logical_cluster_bits) - 1; + + if (logical_cluster < node->cur_cluster_num) + { + node->cur_cluster_num = 0; + node->cur_cluster = node->file_cluster; + } + + while (len) + { + while (logical_cluster > node->cur_cluster_num) + { + /* Find next cluster. */ + grub_uint32_t next_cluster; + grub_uint32_t fat_offset; + + switch (node->data->fat_size) + { + case 32: + fat_offset = node->cur_cluster << 2; + break; + case 16: + fat_offset = node->cur_cluster << 1; + break; + default: + /* case 12: */ + fat_offset = node->cur_cluster + (node->cur_cluster >> 1); + break; + } + + /* Read the FAT. */ + if (grub_disk_read (disk, node->data->fat_sector, fat_offset, + (node->data->fat_size + 7) >> 3, + (char *) &next_cluster)) + return -1; + + next_cluster = grub_le_to_cpu32 (next_cluster); + switch (node->data->fat_size) + { + case 16: + next_cluster &= 0xFFFF; + break; + case 12: + if (node->cur_cluster & 1) + next_cluster >>= 4; + + next_cluster &= 0x0FFF; + break; + } + + grub_dprintf ("fat", "fat_size=%d, next_cluster=%u\n", + node->data->fat_size, next_cluster); + + /* Check the end. */ + if (next_cluster >= node->data->cluster_eof_mark) + return ret; + + if (next_cluster < 2 || (next_cluster - 2) >= node->data->num_clusters) + { + grub_error (GRUB_ERR_BAD_FS, "invalid cluster %u", + next_cluster); + return -1; + } + + node->cur_cluster = next_cluster; + node->cur_cluster_num++; + } + + /* Read the data here. */ + sector = (node->data->cluster_sector + + ((node->cur_cluster - 2) + << node->data->cluster_bits)); + size = (1 << logical_cluster_bits) - offset; + if (size > len) + size = len; + + disk->read_hook = read_hook; + disk->read_hook_data = read_hook_data; + grub_disk_read (disk, sector, offset, size, buf); + disk->read_hook = 0; + if (grub_errno) + return -1; + + len -= size; + buf += size; + ret += size; + logical_cluster++; + offset = 0; + } + + return ret; +} + +struct grub_fat_iterate_context +{ +#ifdef MODE_EXFAT + struct grub_fat_dir_node dir; +#else + struct grub_fat_dir_entry dir; +#endif + char *filename; + grub_uint16_t *unibuf; + grub_ssize_t offset; +}; + +static grub_err_t +grub_fat_iterate_init (struct grub_fat_iterate_context *ctxt) +{ + ctxt->offset = -sizeof (struct grub_fat_dir_entry); + +#ifndef MODE_EXFAT + /* Allocate space enough to hold a long name. */ + ctxt->filename = grub_malloc (0x40 * 13 * GRUB_MAX_UTF8_PER_UTF16 + 1); + ctxt->unibuf = (grub_uint16_t *) grub_malloc (0x40 * 13 * 2); +#else + ctxt->unibuf = grub_malloc (15 * 256 * 2); + ctxt->filename = grub_malloc (15 * 256 * GRUB_MAX_UTF8_PER_UTF16 + 1); +#endif + + if (! ctxt->filename || ! ctxt->unibuf) + { + grub_free (ctxt->filename); + grub_free (ctxt->unibuf); + return grub_errno; + } + return GRUB_ERR_NONE; +} + +static void +grub_fat_iterate_fini (struct grub_fat_iterate_context *ctxt) +{ + grub_free (ctxt->filename); + grub_free (ctxt->unibuf); +} + +#ifdef MODE_EXFAT +static grub_err_t +grub_fat_iterate_dir_next (grub_fshelp_node_t node, + struct grub_fat_iterate_context *ctxt) +{ + grub_memset (&ctxt->dir, 0, sizeof (ctxt->dir)); + while (1) + { + struct grub_fat_dir_entry dir; + + ctxt->offset += sizeof (dir); + + if (grub_fat_read_data (node->disk, node, 0, 0, ctxt->offset, sizeof (dir), + (char *) &dir) + != sizeof (dir)) + break; + + if (dir.entry_type == 0) + break; + if (!(dir.entry_type & 0x80)) + continue; + + if (dir.entry_type == 0x85) + { + unsigned i, nsec, slots = 0; + + nsec = dir.type_specific.file.secondary_count; + + ctxt->dir.attr = grub_cpu_to_le16 (dir.type_specific.file.attr); + ctxt->dir.have_stream = 0; + for (i = 0; i < nsec; i++) + { + struct grub_fat_dir_entry sec; + ctxt->offset += sizeof (sec); + if (grub_fat_read_data (node->disk, node, 0, 0, + ctxt->offset, sizeof (sec), (char *) &sec) + != sizeof (sec)) + break; + if (!(sec.entry_type & 0x80)) + continue; + if (!(sec.entry_type & 0x40)) + break; + switch (sec.entry_type) + { + case 0xc0: + ctxt->dir.first_cluster = grub_cpu_to_le32 (sec.type_specific.stream_extension.first_cluster); + ctxt->dir.valid_size + = grub_cpu_to_le64 (sec.type_specific.stream_extension.valid_size); + ctxt->dir.file_size + = grub_cpu_to_le64 (sec.type_specific.stream_extension.file_size); + ctxt->dir.have_stream = 1; + ctxt->dir.is_contiguous = !!(sec.type_specific.stream_extension.flags + & grub_cpu_to_le16_compile_time (FLAG_CONTIGUOUS)); + break; + case 0xc1: + { + int j; + for (j = 0; j < 15; j++) + ctxt->unibuf[slots * 15 + j] + = grub_le_to_cpu16 (sec.type_specific.file_name.str[j]); + slots++; + } + break; + default: + grub_dprintf ("exfat", "unknown secondary type 0x%02x\n", + sec.entry_type); + } + } + + if (i != nsec) + { + ctxt->offset -= sizeof (dir); + continue; + } + + *grub_utf16_to_utf8 ((grub_uint8_t *) ctxt->filename, ctxt->unibuf, + slots * 15) = '\0'; + + return 0; + } + /* Allocation bitmap. */ + if (dir.entry_type == 0x81) + continue; + /* Upcase table. */ + if (dir.entry_type == 0x82) + continue; + /* Volume label. */ + if (dir.entry_type == 0x83) + continue; + grub_dprintf ("exfat", "unknown primary type 0x%02x\n", + dir.entry_type); + } + return grub_errno ? : GRUB_ERR_EOF; +} + +#else + +static grub_err_t +grub_fat_iterate_dir_next (grub_fshelp_node_t node, + struct grub_fat_iterate_context *ctxt) +{ + char *filep = 0; + int checksum = -1; + int slot = -1, slots = -1; + + while (1) + { + unsigned i; + + /* Adjust the offset. */ + ctxt->offset += sizeof (ctxt->dir); + + /* Read a directory entry. */ + if (grub_fat_read_data (node->disk, node, 0, 0, + ctxt->offset, sizeof (ctxt->dir), + (char *) &ctxt->dir) + != sizeof (ctxt->dir) || ctxt->dir.name[0] == 0) + break; + + /* Handle long name entries. */ + if (ctxt->dir.attr == GRUB_FAT_ATTR_LONG_NAME) + { + struct grub_fat_long_name_entry *long_name + = (struct grub_fat_long_name_entry *) &ctxt->dir; + grub_uint8_t id = long_name->id; + + if (id & 0x40) + { + id &= 0x3f; + slots = slot = id; + checksum = long_name->checksum; + } + + if (id != slot || slot == 0 || checksum != long_name->checksum) + { + checksum = -1; + continue; + } + + slot--; + grub_memcpy (ctxt->unibuf + slot * 13, long_name->name1, 5 * 2); + grub_memcpy (ctxt->unibuf + slot * 13 + 5, long_name->name2, 6 * 2); + grub_memcpy (ctxt->unibuf + slot * 13 + 11, long_name->name3, 2 * 2); + continue; + } + + /* Check if this entry is valid. */ + if (ctxt->dir.name[0] == 0xe5 || (ctxt->dir.attr & ~GRUB_FAT_ATTR_VALID)) + continue; + + /* This is a workaround for Japanese. */ + if (ctxt->dir.name[0] == 0x05) + ctxt->dir.name[0] = 0xe5; + + if (checksum != -1 && slot == 0) + { + grub_uint8_t sum; + + for (sum = 0, i = 0; i < sizeof (ctxt->dir.name); i++) + sum = ((sum >> 1) | (sum << 7)) + ctxt->dir.name[i]; + + if (sum == checksum) + { + int u; + + for (u = 0; u < slots * 13; u++) + ctxt->unibuf[u] = grub_le_to_cpu16 (ctxt->unibuf[u]); + + *grub_utf16_to_utf8 ((grub_uint8_t *) ctxt->filename, + ctxt->unibuf, + slots * 13) = '\0'; + + return GRUB_ERR_NONE; + } + + checksum = -1; + } + + /* Convert the 8.3 file name. */ + filep = ctxt->filename; + if (ctxt->dir.attr & GRUB_FAT_ATTR_VOLUME_ID) + { + for (i = 0; i < sizeof (ctxt->dir.name) && ctxt->dir.name[i]; i++) + *filep++ = ctxt->dir.name[i]; + while (i > 0 && ctxt->dir.name[i - 1] == ' ') + { + filep--; + i--; + } + } + else + { + for (i = 0; i < 8 && ctxt->dir.name[i]; i++) + *filep++ = grub_tolower (ctxt->dir.name[i]); + while (i > 0 && ctxt->dir.name[i - 1] == ' ') + { + filep--; + i--; + } + + /* XXX should we check that dir position is 0 or 1? */ + if (i > 2 || filep[0] != '.' || (i == 2 && filep[1] != '.')) + *filep++ = '.'; + + for (i = 8; i < 11 && ctxt->dir.name[i]; i++) + *filep++ = grub_tolower (ctxt->dir.name[i]); + while (i > 8 && ctxt->dir.name[i - 1] == ' ') + { + filep--; + i--; + } + + if (i == 8) + filep--; + } + *filep = '\0'; + return GRUB_ERR_NONE; + } + + return grub_errno ? : GRUB_ERR_EOF; +} + +#endif + +static grub_err_t lookup_file (grub_fshelp_node_t node, + const char *name, + grub_fshelp_node_t *foundnode, + enum grub_fshelp_filetype *foundtype) +{ + grub_err_t err; + struct grub_fat_iterate_context ctxt; + + err = grub_fat_iterate_init (&ctxt); + if (err) + return err; + + while (!(err = grub_fat_iterate_dir_next (node, &ctxt))) + { + +#ifdef MODE_EXFAT + if (!ctxt.dir.have_stream) + continue; +#else + if (ctxt.dir.attr & GRUB_FAT_ATTR_VOLUME_ID) + continue; +#endif + + if (grub_strcasecmp (name, ctxt.filename) == 0) + { + *foundnode = grub_malloc (sizeof (struct grub_fshelp_node)); + if (!*foundnode) + return grub_errno; + (*foundnode)->attr = ctxt.dir.attr; +#ifdef MODE_EXFAT + (*foundnode)->file_size = ctxt.dir.file_size; + (*foundnode)->file_cluster = ctxt.dir.first_cluster; + (*foundnode)->is_contiguous = ctxt.dir.is_contiguous; +#else + (*foundnode)->file_size = grub_le_to_cpu32 (ctxt.dir.file_size); + (*foundnode)->file_cluster = ((grub_le_to_cpu16 (ctxt.dir.first_cluster_high) << 16) + | grub_le_to_cpu16 (ctxt.dir.first_cluster_low)); + /* If directory points to root, starting cluster is 0 */ + if (!(*foundnode)->file_cluster) + (*foundnode)->file_cluster = node->data->root_cluster; +#endif + (*foundnode)->cur_cluster_num = ~0U; + (*foundnode)->data = node->data; + (*foundnode)->disk = node->disk; + + *foundtype = ((*foundnode)->attr & GRUB_FAT_ATTR_DIRECTORY) ? GRUB_FSHELP_DIR : GRUB_FSHELP_REG; + + grub_fat_iterate_fini (&ctxt); + return GRUB_ERR_NONE; + } + } + + grub_fat_iterate_fini (&ctxt); + if (err == GRUB_ERR_EOF) + err = 0; + + return err; + +} + +static grub_err_t +grub_fat_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook, + void *hook_data) +{ + struct grub_fat_data *data = 0; + grub_disk_t disk = device->disk; + grub_fshelp_node_t found = NULL; + grub_err_t err; + struct grub_fat_iterate_context ctxt; + + grub_dl_ref (my_mod); + + data = grub_fat_mount (disk); + if (! data) + goto fail; + + struct grub_fshelp_node root = { + .data = data, + .disk = disk, + .attr = GRUB_FAT_ATTR_DIRECTORY, + .file_size = 0, + .file_cluster = data->root_cluster, + .cur_cluster_num = ~0U, + .cur_cluster = 0, +#ifdef MODE_EXFAT + .is_contiguous = 0, +#endif + }; + + err = grub_fshelp_find_file_lookup (path, &root, &found, lookup_file, NULL, GRUB_FSHELP_DIR); + if (err) + goto fail; + + err = grub_fat_iterate_init (&ctxt); + if (err) + goto fail; + + while (!(err = grub_fat_iterate_dir_next (found, &ctxt))) + { + struct grub_dirhook_info info; + grub_memset (&info, 0, sizeof (info)); + + info.dir = !! (ctxt.dir.attr & GRUB_FAT_ATTR_DIRECTORY); + info.case_insensitive = 1; + + if (!info.dir) + info.size = ctxt.dir.file_size; + +#ifdef MODE_EXFAT + if (!ctxt.dir.have_stream) + continue; +#else + if (ctxt.dir.attr & GRUB_FAT_ATTR_VOLUME_ID) + continue; +#endif + + if (hook (ctxt.filename, &info, hook_data)) + break; + } + grub_fat_iterate_fini (&ctxt); + if (err == GRUB_ERR_EOF) + err = 0; + + fail: + if (found != &root) + grub_free (found); + + grub_free (data); + + grub_dl_unref (my_mod); + + return grub_errno; +} + +static grub_err_t +grub_fat_open (grub_file_t file, const char *name) +{ + struct grub_fat_data *data = 0; + grub_fshelp_node_t found = NULL; + grub_err_t err; + grub_disk_t disk = file->device->disk; + + grub_dl_ref (my_mod); + + data = grub_fat_mount (disk); + if (! data) + goto fail; + + struct grub_fshelp_node root = { + .data = data, + .disk = disk, + .attr = GRUB_FAT_ATTR_DIRECTORY, + .file_size = 0, + .file_cluster = data->root_cluster, + .cur_cluster_num = ~0U, + .cur_cluster = 0, +#ifdef MODE_EXFAT + .is_contiguous = 0, +#endif + }; + + err = grub_fshelp_find_file_lookup (name, &root, &found, lookup_file, NULL, GRUB_FSHELP_REG); + if (err) + goto fail; + + file->data = found; + file->size = found->file_size; + + return GRUB_ERR_NONE; + + fail: + + if (found != &root) + grub_free (found); + + grub_free (data); + + grub_dl_unref (my_mod); + + return grub_errno; +} + +static grub_ssize_t +grub_fat_read (grub_file_t file, char *buf, grub_size_t len) +{ + return grub_fat_read_data (file->device->disk, file->data, + file->read_hook, file->read_hook_data, + file->offset, len, buf); +} + +static grub_err_t +grub_fat_close (grub_file_t file) +{ + grub_fshelp_node_t node = file->data; + + grub_free (node->data); + grub_free (node); + + grub_dl_unref (my_mod); + + return grub_errno; +} + +#ifdef MODE_EXFAT +static grub_err_t +grub_fat_label (grub_device_t device, char **label) +{ + struct grub_fat_dir_entry dir; + grub_ssize_t offset = -sizeof(dir); + grub_disk_t disk = device->disk; + struct grub_fshelp_node root = { + .disk = disk, + .attr = GRUB_FAT_ATTR_DIRECTORY, + .file_size = 0, + .cur_cluster_num = ~0U, + .cur_cluster = 0, + .is_contiguous = 0, + }; + + root.data = grub_fat_mount (disk); + if (! root.data) + return grub_errno; + + root.file_cluster = root.data->root_cluster; + + *label = NULL; + + while (1) + { + offset += sizeof (dir); + + if (grub_fat_read_data (disk, &root, 0, 0, + offset, sizeof (dir), (char *) &dir) + != sizeof (dir)) + break; + + if (dir.entry_type == 0) + break; + if (!(dir.entry_type & 0x80)) + continue; + + /* Volume label. */ + if (dir.entry_type == 0x83) + { + grub_size_t chc; + grub_uint16_t t[ARRAY_SIZE (dir.type_specific.volume_label.str)]; + grub_size_t i; + *label = grub_malloc (ARRAY_SIZE (dir.type_specific.volume_label.str) + * GRUB_MAX_UTF8_PER_UTF16 + 1); + if (!*label) + { + grub_free (root.data); + return grub_errno; + } + chc = dir.type_specific.volume_label.character_count; + if (chc > ARRAY_SIZE (dir.type_specific.volume_label.str)) + chc = ARRAY_SIZE (dir.type_specific.volume_label.str); + for (i = 0; i < chc; i++) + t[i] = grub_le_to_cpu16 (dir.type_specific.volume_label.str[i]); + *grub_utf16_to_utf8 ((grub_uint8_t *) *label, t, chc) = '\0'; + } + } + + grub_free (root.data); + return grub_errno; +} + +#else + +static grub_err_t +grub_fat_label (grub_device_t device, char **label) +{ + grub_disk_t disk = device->disk; + grub_err_t err; + struct grub_fat_iterate_context ctxt; + struct grub_fshelp_node root = { + .disk = disk, + .attr = GRUB_FAT_ATTR_DIRECTORY, + .file_size = 0, + .cur_cluster_num = ~0U, + .cur_cluster = 0, + }; + + *label = 0; + + grub_dl_ref (my_mod); + + root.data = grub_fat_mount (disk); + if (! root.data) + goto fail; + + root.file_cluster = root.data->root_cluster; + + err = grub_fat_iterate_init (&ctxt); + if (err) + goto fail; + + while (!(err = grub_fat_iterate_dir_next (&root, &ctxt))) + if ((ctxt.dir.attr & ~GRUB_FAT_ATTR_ARCHIVE) == GRUB_FAT_ATTR_VOLUME_ID) + { + *label = grub_strdup (ctxt.filename); + break; + } + + grub_fat_iterate_fini (&ctxt); + + fail: + + grub_dl_unref (my_mod); + + grub_free (root.data); + + return grub_errno; +} + +#endif + +static grub_err_t +grub_fat_uuid (grub_device_t device, char **uuid) +{ + struct grub_fat_data *data; + grub_disk_t disk = device->disk; + + grub_dl_ref (my_mod); + + data = grub_fat_mount (disk); + if (data) + { + char *ptr; + *uuid = grub_xasprintf ("%04x-%04x", + (grub_uint16_t) (data->uuid >> 16), + (grub_uint16_t) data->uuid); + for (ptr = *uuid; ptr && *ptr; ptr++) + *ptr = grub_toupper (*ptr); + } + else + *uuid = NULL; + + grub_dl_unref (my_mod); + + grub_free (data); + + return grub_errno; +} + +#ifdef GRUB_UTIL +#ifndef MODE_EXFAT +grub_disk_addr_t +grub_fat_get_cluster_sector (grub_disk_t disk, grub_uint64_t *sec_per_lcn) +#else +grub_disk_addr_t + grub_exfat_get_cluster_sector (grub_disk_t disk, grub_uint64_t *sec_per_lcn) +#endif +{ + grub_disk_addr_t ret; + struct grub_fat_data *data; + data = grub_fat_mount (disk); + if (!data) + return 0; + ret = data->cluster_sector; + + *sec_per_lcn = 1ULL << data->cluster_bits; + + grub_free (data); + return ret; +} +#endif + +static struct grub_fs grub_fat_fs = + { +#ifdef MODE_EXFAT + .name = "exfat", +#else + .name = "fat", +#endif + .fs_dir = grub_fat_dir, + .fs_open = grub_fat_open, + .fs_read = grub_fat_read, + .fs_close = grub_fat_close, + .fs_label = grub_fat_label, + .fs_uuid = grub_fat_uuid, +#ifdef GRUB_UTIL +#ifdef MODE_EXFAT + /* ExFAT BPB is 30 larger than FAT32 one. */ + .reserved_first_sector = 0, +#else + .reserved_first_sector = 1, +#endif + .blocklist_install = 1, +#endif + .next = 0 + }; + +#ifdef MODE_EXFAT +GRUB_MOD_INIT(exfat) +#else +GRUB_MOD_INIT(fat) +#endif +{ + COMPILE_TIME_ASSERT (sizeof (struct grub_fat_dir_entry) == 32); + grub_fs_register (&grub_fat_fs); + my_mod = mod; +} +#ifdef MODE_EXFAT +GRUB_MOD_FINI(exfat) +#else +GRUB_MOD_FINI(fat) +#endif +{ + grub_fs_unregister (&grub_fat_fs); +} + +#ifdef MODE_EXFAT + +int grub_fat_get_file_chunk(grub_uint64_t part_start, grub_file_t file, ventoy_img_chunk_list *chunk_list) +{ + grub_size_t size; + grub_uint32_t i; + grub_uint32_t logical_cluster; + unsigned logical_cluster_bits; + unsigned long sector; + grub_fshelp_node_t node; + grub_disk_t disk; + grub_uint64_t len; + + disk = file->device->disk; + node = file->data; + len = file->size; + + if (node->is_contiguous) + { + /* Read the data here. */ + sector = (node->data->cluster_sector + ((node->file_cluster - 2) << node->data->cluster_bits)); + + chunk_list->chunk[0].img_start_sector = 0; + chunk_list->chunk[0].img_end_sector = (file->size >> 11) - 1; + chunk_list->chunk[0].disk_start_sector = sector; + chunk_list->chunk[0].disk_end_sector = sector + (file->size >> disk->log_sector_size) - 1; + chunk_list->cur_chunk = 1; + + goto END; + } + + /* Calculate the logical cluster number and offset. */ + logical_cluster = 0; + logical_cluster_bits = (node->data->cluster_bits + GRUB_DISK_SECTOR_BITS); + + if (logical_cluster < node->cur_cluster_num) + { + node->cur_cluster_num = 0; + node->cur_cluster = node->file_cluster; + } + + while (len) + { + while (logical_cluster > node->cur_cluster_num) + { + /* Find next cluster. */ + grub_uint32_t next_cluster; + grub_uint32_t fat_offset; + + switch (node->data->fat_size) + { + case 32: + fat_offset = node->cur_cluster << 2; + break; + case 16: + fat_offset = node->cur_cluster << 1; + break; + default: + /* case 12: */ + fat_offset = node->cur_cluster + (node->cur_cluster >> 1); + break; + } + + /* Read the FAT. */ + if (grub_disk_read (disk, node->data->fat_sector, fat_offset, + (node->data->fat_size + 7) >> 3, + (char *) &next_cluster)) + { + return -1; + } + + next_cluster = grub_le_to_cpu32 (next_cluster); + switch (node->data->fat_size) + { + case 16: + next_cluster &= 0xFFFF; + break; + case 12: + if (node->cur_cluster & 1) + next_cluster >>= 4; + + next_cluster &= 0x0FFF; + break; + } + + grub_dprintf ("fat", "fat_size=%d, next_cluster=%u\n", node->data->fat_size, next_cluster); + + /* Check the end. */ + if (next_cluster >= node->data->cluster_eof_mark) + { + return 0; + } + + if (next_cluster < 2 || (next_cluster - 2) >= node->data->num_clusters) + { + grub_error (GRUB_ERR_BAD_FS, "invalid cluster %u", next_cluster); + return -1; + } + + node->cur_cluster = next_cluster; + node->cur_cluster_num++; + } + + /* Read the data here. */ + sector = (node->data->cluster_sector + + ((node->cur_cluster - 2) + << node->data->cluster_bits)); + size = (1 << logical_cluster_bits); + if (size > len) + size = len; + + grub_disk_blocklist_read(chunk_list, sector, size, disk->log_sector_size); + + len -= size; + logical_cluster++; + } + +END: + + for (i = 0; i < chunk_list->cur_chunk; i++) + { + chunk_list->chunk[i].disk_start_sector += part_start; + chunk_list->chunk[i].disk_end_sector += part_start; + } + + return 0; +} + +#endif diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/fshelp.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/fshelp.c new file mode 100644 index 0000000..53a65ec --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/fshelp.c @@ -0,0 +1,436 @@ +/* fshelp.c -- Filesystem helper functions */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +typedef int (*iterate_dir_func) (grub_fshelp_node_t dir, + grub_fshelp_iterate_dir_hook_t hook, + void *data); +typedef grub_err_t (*lookup_file_func) (grub_fshelp_node_t dir, + const char *name, + grub_fshelp_node_t *foundnode, + enum grub_fshelp_filetype *foundtype); +typedef char *(*read_symlink_func) (grub_fshelp_node_t node); + +struct stack_element { + struct stack_element *parent; + grub_fshelp_node_t node; + enum grub_fshelp_filetype type; +}; + +/* Context for grub_fshelp_find_file. */ +struct grub_fshelp_find_file_ctx +{ + /* Inputs. */ + const char *path; + grub_fshelp_node_t rootnode; + + /* Global options. */ + int symlinknest; + + /* Current file being traversed and its parents. */ + struct stack_element *currnode; +}; + +/* Helper for find_file_iter. */ +static void +free_node (grub_fshelp_node_t node, struct grub_fshelp_find_file_ctx *ctx) +{ + if (node != ctx->rootnode) + grub_free (node); +} + +static void +pop_element (struct grub_fshelp_find_file_ctx *ctx) +{ + struct stack_element *el; + el = ctx->currnode; + ctx->currnode = el->parent; + free_node (el->node, ctx); + grub_free (el); +} + +static void +free_stack (struct grub_fshelp_find_file_ctx *ctx) +{ + while (ctx->currnode) + pop_element (ctx); +} + +static void +go_up_a_level (struct grub_fshelp_find_file_ctx *ctx) +{ + if (!ctx->currnode->parent) + return; + pop_element (ctx); +} + +static grub_err_t +push_node (struct grub_fshelp_find_file_ctx *ctx, grub_fshelp_node_t node, enum grub_fshelp_filetype filetype) +{ + struct stack_element *nst; + nst = grub_malloc (sizeof (*nst)); + if (!nst) + return grub_errno; + nst->node = node; + nst->type = filetype & ~GRUB_FSHELP_CASE_INSENSITIVE; + nst->parent = ctx->currnode; + ctx->currnode = nst; + return GRUB_ERR_NONE; +} + +static grub_err_t +go_to_root (struct grub_fshelp_find_file_ctx *ctx) +{ + free_stack (ctx); + return push_node (ctx, ctx->rootnode, GRUB_FSHELP_DIR); +} + +struct grub_fshelp_find_file_iter_ctx +{ + const char *name; + grub_fshelp_node_t *foundnode; + enum grub_fshelp_filetype *foundtype; +}; + +int g_ventoy_case_insensitive = 0; + +/* Helper for grub_fshelp_find_file. */ +static int +find_file_iter (const char *filename, enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node, void *data) +{ + struct grub_fshelp_find_file_iter_ctx *ctx = data; + + if (g_ventoy_case_insensitive) + { + filetype |= GRUB_FSHELP_CASE_INSENSITIVE; + } + + if (filetype == GRUB_FSHELP_UNKNOWN || + ((filetype & GRUB_FSHELP_CASE_INSENSITIVE) + ? grub_strcasecmp (ctx->name, filename) + : grub_strcmp (ctx->name, filename))) + { + grub_free (node); + return 0; + } + + /* The node is found, stop iterating over the nodes. */ + *ctx->foundnode = node; + *ctx->foundtype = filetype; + return 1; +} + +static grub_err_t +directory_find_file (grub_fshelp_node_t node, const char *name, grub_fshelp_node_t *foundnode, + enum grub_fshelp_filetype *foundtype, iterate_dir_func iterate_dir) +{ + int found; + struct grub_fshelp_find_file_iter_ctx ctx = { + .foundnode = foundnode, + .foundtype = foundtype, + .name = name + }; + found = iterate_dir (node, find_file_iter, &ctx); + if (! found) + { + if (grub_errno) + return grub_errno; + } + return GRUB_ERR_NONE; +} + +static grub_err_t +find_file (char *currpath, + iterate_dir_func iterate_dir, lookup_file_func lookup_file, + read_symlink_func read_symlink, + struct grub_fshelp_find_file_ctx *ctx) +{ + char *name, *next; + grub_err_t err; + for (name = currpath; ; name = next) + { + char c; + grub_fshelp_node_t foundnode = NULL; + enum grub_fshelp_filetype foundtype = 0; + + /* Remove all leading slashes. */ + while (*name == '/') + name++; + + /* Found the node! */ + if (! *name) + return 0; + + /* Extract the actual part from the pathname. */ + for (next = name; *next && *next != '/'; next++); + + /* At this point it is expected that the current node is a + directory, check if this is true. */ + if (ctx->currnode->type != GRUB_FSHELP_DIR) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory")); + + /* Don't rely on fs providing actual . in the listing. */ + if (next - name == 1 && name[0] == '.') + continue; + + /* Don't rely on fs providing actual .. in the listing. */ + if (next - name == 2 && name[0] == '.' && name[1] == '.') + { + go_up_a_level (ctx); + continue; + } + + /* Iterate over the directory. */ + c = *next; + *next = '\0'; + if (lookup_file) + err = lookup_file (ctx->currnode->node, name, &foundnode, &foundtype); + else + err = directory_find_file (ctx->currnode->node, name, &foundnode, &foundtype, iterate_dir); + *next = c; + + if (err) + return err; + + if (!foundnode) + break; + + push_node (ctx, foundnode, foundtype); + + /* Read in the symlink and follow it. */ + if (ctx->currnode->type == GRUB_FSHELP_SYMLINK) + { + char *symlink; + + /* Test if the symlink does not loop. */ + if (++ctx->symlinknest == 8) + return grub_error (GRUB_ERR_SYMLINK_LOOP, + N_("too deep nesting of symlinks")); + + symlink = read_symlink (ctx->currnode->node); + + if (!symlink) + return grub_errno; + + /* The symlink is an absolute path, go back to the root inode. */ + if (symlink[0] == '/') + { + err = go_to_root (ctx); + if (err) + return err; + } + else + { + /* Get from symlink to containing directory. */ + go_up_a_level (ctx); + } + + + /* Lookup the node the symlink points to. */ + find_file (symlink, iterate_dir, lookup_file, read_symlink, ctx); + grub_free (symlink); + + if (grub_errno) + return grub_errno; + } + } + + return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), + ctx->path); +} + +static grub_err_t +grub_fshelp_find_file_real (const char *path, grub_fshelp_node_t rootnode, + grub_fshelp_node_t *foundnode, + iterate_dir_func iterate_dir, + lookup_file_func lookup_file, + read_symlink_func read_symlink, + enum grub_fshelp_filetype expecttype) +{ + struct grub_fshelp_find_file_ctx ctx = { + .path = path, + .rootnode = rootnode, + .symlinknest = 0, + .currnode = 0 + }; + grub_err_t err; + enum grub_fshelp_filetype foundtype; + char *duppath; + + if (!path || path[0] != '/') + { + return grub_error (GRUB_ERR_BAD_FILENAME, N_("invalid file name `%s'"), path); + } + + err = go_to_root (&ctx); + if (err) + return err; + + duppath = grub_strdup (path); + if (!duppath) + return grub_errno; + err = find_file (duppath, iterate_dir, lookup_file, read_symlink, &ctx); + grub_free (duppath); + if (err) + { + free_stack (&ctx); + return err; + } + + *foundnode = ctx.currnode->node; + foundtype = ctx.currnode->type; + /* Avoid the node being freed. */ + ctx.currnode->node = 0; + free_stack (&ctx); + + /* Check if the node that was found was of the expected type. */ + if (expecttype == GRUB_FSHELP_REG && foundtype != expecttype) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a regular file")); + else if (expecttype == GRUB_FSHELP_DIR && foundtype != expecttype) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory")); + + return 0; +} + +/* Lookup the node PATH. The node ROOTNODE describes the root of the + directory tree. The node found is returned in FOUNDNODE, which is + either a ROOTNODE or a new malloc'ed node. ITERATE_DIR is used to + iterate over all directory entries in the current node. + READ_SYMLINK is used to read the symlink if a node is a symlink. + EXPECTTYPE is the type node that is expected by the called, an + error is generated if the node is not of the expected type. */ +grub_err_t +grub_fshelp_find_file (const char *path, grub_fshelp_node_t rootnode, + grub_fshelp_node_t *foundnode, + iterate_dir_func iterate_dir, + read_symlink_func read_symlink, + enum grub_fshelp_filetype expecttype) +{ + return grub_fshelp_find_file_real (path, rootnode, foundnode, + iterate_dir, NULL, + read_symlink, expecttype); + +} + +grub_err_t +grub_fshelp_find_file_lookup (const char *path, grub_fshelp_node_t rootnode, + grub_fshelp_node_t *foundnode, + lookup_file_func lookup_file, + read_symlink_func read_symlink, + enum grub_fshelp_filetype expecttype) +{ + return grub_fshelp_find_file_real (path, rootnode, foundnode, + NULL, lookup_file, + read_symlink, expecttype); + +} + +/* Read LEN bytes from the file NODE on disk DISK into the buffer BUF, + beginning with the block POS. READ_HOOK should be set before + reading a block from the file. READ_HOOK_DATA is passed through as + the DATA argument to READ_HOOK. GET_BLOCK is used to translate + file blocks to disk blocks. The file is FILESIZE bytes big and the + blocks have a size of LOG2BLOCKSIZE (in log2). */ +grub_ssize_t +grub_fshelp_read_file (grub_disk_t disk, grub_fshelp_node_t node, + grub_disk_read_hook_t read_hook, void *read_hook_data, + grub_off_t pos, grub_size_t len, char *buf, + grub_disk_addr_t (*get_block) (grub_fshelp_node_t node, + grub_disk_addr_t block), + grub_off_t filesize, int log2blocksize, + grub_disk_addr_t blocks_start) +{ + grub_disk_addr_t i, blockcnt; + int blocksize = 1 << (log2blocksize + GRUB_DISK_SECTOR_BITS); + + if (pos > filesize) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, + N_("attempt to read past the end of file")); + return -1; + } + + /* Adjust LEN so it we can't read past the end of the file. */ + if (pos + len > filesize) + len = filesize - pos; + + blockcnt = ((len + pos) + blocksize - 1) >> (log2blocksize + GRUB_DISK_SECTOR_BITS); + + for (i = pos >> (log2blocksize + GRUB_DISK_SECTOR_BITS); i < blockcnt; i++) + { + grub_disk_addr_t blknr; + int blockoff = pos & (blocksize - 1); + int blockend = blocksize; + + int skipfirst = 0; + + blknr = get_block (node, i); + if (grub_errno) + return -1; + + blknr = blknr << log2blocksize; + + /* Last block. */ + if (i == blockcnt - 1) + { + blockend = (len + pos) & (blocksize - 1); + + /* The last portion is exactly blocksize. */ + if (! blockend) + blockend = blocksize; + } + + /* First block. */ + if (i == (pos >> (log2blocksize + GRUB_DISK_SECTOR_BITS))) + { + skipfirst = blockoff; + blockend -= skipfirst; + } + + /* If the block number is 0 this block is not stored on disk but + is zero filled instead. */ + if (blknr) + { + disk->read_hook = read_hook; + disk->read_hook_data = read_hook_data; + + grub_disk_read (disk, blknr + blocks_start, skipfirst, + blockend, buf); + disk->read_hook = 0; + if (grub_errno) + return -1; + } + else if (read_hook != (grub_disk_read_hook_t)(void *)grub_disk_blocklist_read) + grub_memset (buf, 0, blockend); + + buf += blocksize - skipfirst; + } + + return len; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/iso9660.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/iso9660.c new file mode 100644 index 0000000..9a26bb2 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/iso9660.c @@ -0,0 +1,1167 @@ +/* iso9660.c - iso9660 implementation with extensions: + SUSP, Rock Ridge. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +static int g_ventoy_no_joliet = 0; +static int g_ventoy_cur_joliet = 0; +static grub_uint64_t g_ventoy_last_read_pos = 0; +static grub_uint64_t g_ventoy_last_read_offset = 0; +static grub_uint64_t g_ventoy_last_read_dirent_pos = 0; +static grub_uint64_t g_ventoy_last_read_dirent_offset = 0; +static grub_uint64_t g_ventoy_last_file_dirent_pos = 0; +static grub_uint64_t g_ventoy_last_file_dirent_offset = 0; + +#define GRUB_ISO9660_FSTYPE_DIR 0040000 +#define GRUB_ISO9660_FSTYPE_REG 0100000 +#define GRUB_ISO9660_FSTYPE_SYMLINK 0120000 +#define GRUB_ISO9660_FSTYPE_MASK 0170000 + +#define GRUB_ISO9660_LOG2_BLKSZ 2 +#define GRUB_ISO9660_BLKSZ 2048 + +#define GRUB_ISO9660_RR_DOT 2 +#define GRUB_ISO9660_RR_DOTDOT 4 + +#define GRUB_ISO9660_VOLDESC_BOOT 0 +#define GRUB_ISO9660_VOLDESC_PRIMARY 1 +#define GRUB_ISO9660_VOLDESC_SUPP 2 +#define GRUB_ISO9660_VOLDESC_PART 3 +#define GRUB_ISO9660_VOLDESC_END 255 + +/* The head of a volume descriptor. */ +struct grub_iso9660_voldesc +{ + grub_uint8_t type; + grub_uint8_t magic[5]; + grub_uint8_t version; +} GRUB_PACKED; + +struct grub_iso9660_date2 +{ + grub_uint8_t year; + grub_uint8_t month; + grub_uint8_t day; + grub_uint8_t hour; + grub_uint8_t minute; + grub_uint8_t second; + grub_uint8_t offset; +} GRUB_PACKED; + +/* A directory entry. */ +struct grub_iso9660_dir +{ + grub_uint8_t len; + grub_uint8_t ext_sectors; + grub_uint32_t first_sector; + grub_uint32_t first_sector_be; + grub_uint32_t size; + grub_uint32_t size_be; + struct grub_iso9660_date2 mtime; + grub_uint8_t flags; + grub_uint8_t unused2[6]; +#define MAX_NAMELEN 255 + grub_uint8_t namelen; +} GRUB_PACKED; + +struct grub_iso9660_date +{ + grub_uint8_t year[4]; + grub_uint8_t month[2]; + grub_uint8_t day[2]; + grub_uint8_t hour[2]; + grub_uint8_t minute[2]; + grub_uint8_t second[2]; + grub_uint8_t hundredth[2]; + grub_uint8_t offset; +} GRUB_PACKED; + +/* The primary volume descriptor. Only little endian is used. */ +struct grub_iso9660_primary_voldesc +{ + struct grub_iso9660_voldesc voldesc; + grub_uint8_t unused1[33]; + grub_uint8_t volname[32]; + grub_uint8_t unused2[16]; + grub_uint8_t escape[32]; + grub_uint8_t unused3[12]; + grub_uint32_t path_table_size; + grub_uint8_t unused4[4]; + grub_uint32_t path_table; + grub_uint8_t unused5[12]; + struct grub_iso9660_dir rootdir; + grub_uint8_t unused6[624]; + struct grub_iso9660_date created; + struct grub_iso9660_date modified; +} GRUB_PACKED; + +/* A single entry in the path table. */ +struct grub_iso9660_path +{ + grub_uint8_t len; + grub_uint8_t sectors; + grub_uint32_t first_sector; + grub_uint16_t parentdir; + grub_uint8_t name[0]; +} GRUB_PACKED; + +/* An entry in the System Usage area of the directory entry. */ +struct grub_iso9660_susp_entry +{ + grub_uint8_t sig[2]; + grub_uint8_t len; + grub_uint8_t version; + grub_uint8_t data[0]; +} GRUB_PACKED; + +/* The CE entry. This is used to describe the next block where data + can be found. */ +struct grub_iso9660_susp_ce +{ + struct grub_iso9660_susp_entry entry; + grub_uint32_t blk; + grub_uint32_t blk_be; + grub_uint32_t off; + grub_uint32_t off_be; + grub_uint32_t len; + grub_uint32_t len_be; +} GRUB_PACKED; + +struct grub_iso9660_data +{ + struct grub_iso9660_primary_voldesc voldesc; + grub_disk_t disk; + int rockridge; + int susp_skip; + int joliet; + struct grub_fshelp_node *node; +}; + +struct grub_fshelp_node +{ + struct grub_iso9660_data *data; + grub_size_t have_dirents, alloc_dirents; + int have_symlink; + struct grub_iso9660_dir dirents[8]; + char symlink[0]; +}; + +enum + { + FLAG_TYPE_PLAIN = 0, + FLAG_TYPE_DIR = 2, + FLAG_TYPE = 3, + FLAG_MORE_EXTENTS = 0x80 + }; + +static grub_dl_t my_mod; + + +static grub_err_t +iso9660_to_unixtime (const struct grub_iso9660_date *i, grub_int32_t *nix) +{ + struct grub_datetime datetime; + + if (! i->year[0] && ! i->year[1] + && ! i->year[2] && ! i->year[3] + && ! i->month[0] && ! i->month[1] + && ! i->day[0] && ! i->day[1] + && ! i->hour[0] && ! i->hour[1] + && ! i->minute[0] && ! i->minute[1] + && ! i->second[0] && ! i->second[1] + && ! i->hundredth[0] && ! i->hundredth[1]) + return grub_error (GRUB_ERR_BAD_NUMBER, "empty date"); + datetime.year = (i->year[0] - '0') * 1000 + (i->year[1] - '0') * 100 + + (i->year[2] - '0') * 10 + (i->year[3] - '0'); + datetime.month = (i->month[0] - '0') * 10 + (i->month[1] - '0'); + datetime.day = (i->day[0] - '0') * 10 + (i->day[1] - '0'); + datetime.hour = (i->hour[0] - '0') * 10 + (i->hour[1] - '0'); + datetime.minute = (i->minute[0] - '0') * 10 + (i->minute[1] - '0'); + datetime.second = (i->second[0] - '0') * 10 + (i->second[1] - '0'); + + if (!grub_datetime2unixtime (&datetime, nix)) + return grub_error (GRUB_ERR_BAD_NUMBER, "incorrect date"); + *nix -= i->offset * 60 * 15; + return GRUB_ERR_NONE; +} + +static int +iso9660_to_unixtime2 (const struct grub_iso9660_date2 *i, grub_int32_t *nix) +{ + struct grub_datetime datetime; + + datetime.year = i->year + 1900; + datetime.month = i->month; + datetime.day = i->day; + datetime.hour = i->hour; + datetime.minute = i->minute; + datetime.second = i->second; + + if (!grub_datetime2unixtime (&datetime, nix)) + return 0; + *nix -= i->offset * 60 * 15; + return 1; +} + +static grub_err_t +read_node (grub_fshelp_node_t node, grub_off_t off, grub_size_t len, char *buf) +{ + grub_size_t i = 0; + + while (len > 0) + { + grub_size_t toread; + grub_err_t err; + while (i < node->have_dirents + && off >= grub_le_to_cpu32 (node->dirents[i].size)) + { + off -= grub_le_to_cpu32 (node->dirents[i].size); + i++; + } + if (i == node->have_dirents) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "read out of range"); + toread = grub_le_to_cpu32 (node->dirents[i].size); + if (toread > len) + toread = len; + g_ventoy_last_read_pos = ((grub_disk_addr_t) grub_le_to_cpu32 (node->dirents[i].first_sector)) << GRUB_ISO9660_LOG2_BLKSZ; + g_ventoy_last_read_offset = off; + err = grub_disk_read (node->data->disk, g_ventoy_last_read_pos, off, toread, buf); + if (err) + return err; + len -= toread; + off += toread; + buf += toread; + } + return GRUB_ERR_NONE; +} + +/* Iterate over the susp entries, starting with block SUA_BLOCK on the + offset SUA_POS with a size of SUA_SIZE bytes. Hook is called for + every entry. */ +static grub_err_t +grub_iso9660_susp_iterate (grub_fshelp_node_t node, grub_off_t off, + grub_ssize_t sua_size, + grub_err_t (*hook) + (struct grub_iso9660_susp_entry *entry, void *hook_arg), + void *hook_arg) +{ + char *sua; + struct grub_iso9660_susp_entry *entry; + grub_err_t err; + + if (sua_size <= 0) + return GRUB_ERR_NONE; + + sua = grub_malloc (sua_size); + if (!sua) + return grub_errno; + + /* Load a part of the System Usage Area. */ + err = read_node (node, off, sua_size, sua); + if (err) + return err; + + for (entry = (struct grub_iso9660_susp_entry *) sua; (char *) entry < (char *) sua + sua_size - 1 && entry->len > 0; + entry = (struct grub_iso9660_susp_entry *) + ((char *) entry + entry->len)) + { + /* The last entry. */ + if (grub_strncmp ((char *) entry->sig, "ST", 2) == 0) + break; + + /* Additional entries are stored elsewhere. */ + if (grub_strncmp ((char *) entry->sig, "CE", 2) == 0) + { + struct grub_iso9660_susp_ce *ce; + grub_disk_addr_t ce_block; + + ce = (struct grub_iso9660_susp_ce *) entry; + sua_size = grub_le_to_cpu32 (ce->len); + off = grub_le_to_cpu32 (ce->off); + ce_block = grub_le_to_cpu32 (ce->blk) << GRUB_ISO9660_LOG2_BLKSZ; + + grub_free (sua); + sua = grub_malloc (sua_size); + if (!sua) + return grub_errno; + + /* Load a part of the System Usage Area. */ + err = grub_disk_read (node->data->disk, ce_block, off, + sua_size, sua); + if (err) + return err; + + entry = (struct grub_iso9660_susp_entry *) sua; + } + + if (hook (entry, hook_arg)) + { + grub_free (sua); + return 0; + } + } + + grub_free (sua); + return 0; +} + +static char * +grub_iso9660_convert_string (grub_uint8_t *us, int len) +{ + char *p; + int i; + grub_uint16_t t[MAX_NAMELEN / 2 + 1]; + + p = grub_malloc (len * GRUB_MAX_UTF8_PER_UTF16 + 1); + if (! p) + return NULL; + + for (i=0; isig, "ER", 2) == 0) + { + data->rockridge = 1; + return 1; + } + return 0; +} + +static grub_err_t +set_rockridge (struct grub_iso9660_data *data) +{ + int sua_pos; + int sua_size; + char *sua; + struct grub_iso9660_dir rootdir; + struct grub_iso9660_susp_entry *entry; + + data->rockridge = 0; + + /* Read the system use area and test it to see if SUSP is + supported. */ + if (grub_disk_read (data->disk, + (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector) + << GRUB_ISO9660_LOG2_BLKSZ), 0, + sizeof (rootdir), (char *) &rootdir)) + return grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem"); + + sua_pos = (sizeof (rootdir) + rootdir.namelen + + (rootdir.namelen % 2) - 1); + sua_size = rootdir.len - sua_pos; + + if (!sua_size) + return GRUB_ERR_NONE; + + sua = grub_malloc (sua_size); + if (! sua) + return grub_errno; + + if (grub_disk_read (data->disk, + (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector) + << GRUB_ISO9660_LOG2_BLKSZ), sua_pos, + sua_size, sua)) + { + grub_free (sua); + return grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem"); + } + + entry = (struct grub_iso9660_susp_entry *) sua; + + /* Test if the SUSP protocol is used on this filesystem. */ + if (grub_strncmp ((char *) entry->sig, "SP", 2) == 0) + { + struct grub_fshelp_node rootnode; + + rootnode.data = data; + rootnode.alloc_dirents = ARRAY_SIZE (rootnode.dirents); + rootnode.have_dirents = 1; + rootnode.have_symlink = 0; + rootnode.dirents[0] = data->voldesc.rootdir; + + /* The 2nd data byte stored how many bytes are skipped every time + to get to the SUA (System Usage Area). */ + data->susp_skip = entry->data[2]; + entry = (struct grub_iso9660_susp_entry *) ((char *) entry + entry->len); + + /* Iterate over the entries in the SUA area to detect + extensions. */ + if (grub_iso9660_susp_iterate (&rootnode, + sua_pos, sua_size, susp_iterate_set_rockridge, + data)) + { + grub_free (sua); + return grub_errno; + } + } + grub_free (sua); + return GRUB_ERR_NONE; +} + +static struct grub_iso9660_data * +grub_iso9660_mount (grub_disk_t disk) +{ + struct grub_iso9660_data *data = 0; + struct grub_iso9660_primary_voldesc voldesc; + int block; + + data = grub_zalloc (sizeof (struct grub_iso9660_data)); + if (! data) + return 0; + + data->disk = disk; + + g_ventoy_cur_joliet = 0; + block = 16; + do + { + int copy_voldesc = 0; + + /* Read the superblock. */ + if (grub_disk_read (disk, block << GRUB_ISO9660_LOG2_BLKSZ, 0, + sizeof (struct grub_iso9660_primary_voldesc), + (char *) &voldesc)) + { + grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem"); + goto fail; + } + + if (grub_strncmp ((char *) voldesc.voldesc.magic, "CD001", 5) != 0) + { + grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem"); + goto fail; + } + + if (voldesc.voldesc.type == GRUB_ISO9660_VOLDESC_PRIMARY) + copy_voldesc = 1; + else if (!data->rockridge + && (voldesc.voldesc.type == GRUB_ISO9660_VOLDESC_SUPP) + && (voldesc.escape[0] == 0x25) && (voldesc.escape[1] == 0x2f) + && + ((voldesc.escape[2] == 0x40) || /* UCS-2 Level 1. */ + (voldesc.escape[2] == 0x43) || /* UCS-2 Level 2. */ + (voldesc.escape[2] == 0x45))) /* UCS-2 Level 3. */ + { + if (0 == g_ventoy_no_joliet) { + copy_voldesc = 1; + data->joliet = 1; + g_ventoy_cur_joliet = 1; + } + } + + if (copy_voldesc) + { + grub_memcpy((char *) &data->voldesc, (char *) &voldesc, + sizeof (struct grub_iso9660_primary_voldesc)); + if (set_rockridge (data)) + goto fail; + } + + block++; + } while (voldesc.voldesc.type != GRUB_ISO9660_VOLDESC_END); + + return data; + + fail: + grub_free (data); + return 0; +} + + +static char * +grub_iso9660_read_symlink (grub_fshelp_node_t node) +{ + return node->have_symlink + ? grub_strdup (node->symlink + + (node->have_dirents) * sizeof (node->dirents[0]) + - sizeof (node->dirents)) : grub_strdup (""); +} + +static grub_off_t +get_node_size (grub_fshelp_node_t node) +{ + grub_off_t ret = 0; + grub_size_t i; + + for (i = 0; i < node->have_dirents; i++) + ret += grub_le_to_cpu32 (node->dirents[i].size); + return ret; +} + +struct iterate_dir_ctx +{ + char *filename; + int filename_alloc; + enum grub_fshelp_filetype type; + char *symlink; + int was_continue; +}; + + /* Extend the symlink. */ +static void +add_part (struct iterate_dir_ctx *ctx, + const char *part, + int len2) +{ + int size = ctx->symlink ? grub_strlen (ctx->symlink) : 0; + + ctx->symlink = grub_realloc (ctx->symlink, size + len2 + 1); + if (! ctx->symlink) + return; + + grub_memcpy (ctx->symlink + size, part, len2); + ctx->symlink[size + len2] = 0; +} + +static grub_err_t +susp_iterate_dir (struct grub_iso9660_susp_entry *entry, + void *_ctx) +{ + struct iterate_dir_ctx *ctx = _ctx; + + /* The filename in the rock ridge entry. */ + if (grub_strncmp ("NM", (char *) entry->sig, 2) == 0) + { + /* The flags are stored at the data position 0, here the + filename type is stored. */ + /* FIXME: Fix this slightly improper cast. */ + if (entry->data[0] & GRUB_ISO9660_RR_DOT) + ctx->filename = (char *) "."; + else if (entry->data[0] & GRUB_ISO9660_RR_DOTDOT) + ctx->filename = (char *) ".."; + else if (entry->len >= 5) + { + grub_size_t off = 0, csize = 1; + char *old; + csize = entry->len - 5; + old = ctx->filename; + if (ctx->filename_alloc) + { + off = grub_strlen (ctx->filename); + ctx->filename = grub_realloc (ctx->filename, csize + off + 1); + } + else + { + off = 0; + ctx->filename = grub_zalloc (csize + 1); + } + if (!ctx->filename) + { + ctx->filename = old; + return grub_errno; + } + ctx->filename_alloc = 1; + grub_memcpy (ctx->filename + off, (char *) &entry->data[1], csize); + ctx->filename[off + csize] = '\0'; + } + } + /* The mode information (st_mode). */ + else if (grub_strncmp ((char *) entry->sig, "PX", 2) == 0) + { + /* At position 0 of the PX record the st_mode information is + stored (little-endian). */ + grub_uint32_t mode = ((entry->data[0] + (entry->data[1] << 8)) + & GRUB_ISO9660_FSTYPE_MASK); + + switch (mode) + { + case GRUB_ISO9660_FSTYPE_DIR: + ctx->type = GRUB_FSHELP_DIR; + break; + case GRUB_ISO9660_FSTYPE_REG: + ctx->type = GRUB_FSHELP_REG; + break; + case GRUB_ISO9660_FSTYPE_SYMLINK: + ctx->type = GRUB_FSHELP_SYMLINK; + break; + default: + ctx->type = GRUB_FSHELP_UNKNOWN; + } + } + else if (grub_strncmp ("SL", (char *) entry->sig, 2) == 0) + { + unsigned int pos = 1; + + /* The symlink is not stored as a POSIX symlink, translate it. */ + while (pos + sizeof (*entry) < entry->len) + { + /* The current position is the `Component Flag'. */ + switch (entry->data[pos] & 30) + { + case 0: + { + /* The data on pos + 2 is the actual data, pos + 1 + is the length. Both are part of the `Component + Record'. */ + if (ctx->symlink && !ctx->was_continue) + add_part (ctx, "/", 1); + add_part (ctx, (char *) &entry->data[pos + 2], + entry->data[pos + 1]); + ctx->was_continue = (entry->data[pos] & 1); + break; + } + + case 2: + add_part (ctx, "./", 2); + break; + + case 4: + add_part (ctx, "../", 3); + break; + + case 8: + add_part (ctx, "/", 1); + break; + } + /* In pos + 1 the length of the `Component Record' is + stored. */ + pos += entry->data[pos + 1] + 2; + } + + /* Check if `grub_realloc' failed. */ + if (grub_errno) + return grub_errno; + } + + return 0; +} + +static int +grub_iso9660_iterate_dir (grub_fshelp_node_t dir, + grub_fshelp_iterate_dir_hook_t hook, void *hook_data) +{ + struct grub_iso9660_dir dirent; + grub_off_t offset = 0; + grub_off_t len; + struct iterate_dir_ctx ctx; + + len = get_node_size (dir); + + for (; offset < len; offset += dirent.len) + { + ctx.symlink = 0; + ctx.was_continue = 0; + + if (read_node (dir, offset, sizeof (dirent), (char *) &dirent)) + return 0; + + if ((dirent.flags & FLAG_TYPE) != FLAG_TYPE_DIR) { + g_ventoy_last_read_dirent_pos = g_ventoy_last_read_pos; + g_ventoy_last_read_dirent_offset = g_ventoy_last_read_offset; + } + + /* The end of the block, skip to the next one. */ + if (!dirent.len) + { + offset = (offset / GRUB_ISO9660_BLKSZ + 1) * GRUB_ISO9660_BLKSZ; + continue; + } + + { + char name[MAX_NAMELEN + 1]; + int nameoffset = offset + sizeof (dirent); + struct grub_fshelp_node *node; + int sua_off = (sizeof (dirent) + dirent.namelen + 1 + - (dirent.namelen % 2)); + int sua_size = dirent.len - sua_off; + + sua_off += offset + dir->data->susp_skip; + + ctx.filename = 0; + ctx.filename_alloc = 0; + ctx.type = GRUB_FSHELP_UNKNOWN; + + if (dir->data->rockridge + && grub_iso9660_susp_iterate (dir, sua_off, sua_size, + susp_iterate_dir, &ctx)) + return 0; + + /* Read the name. */ + if (read_node (dir, nameoffset, dirent.namelen, (char *) name)) + return 0; + + node = grub_malloc (sizeof (struct grub_fshelp_node)); + if (!node) + return 0; + + node->alloc_dirents = ARRAY_SIZE (node->dirents); + node->have_dirents = 1; + + /* Setup a new node. */ + node->data = dir->data; + node->have_symlink = 0; + + /* If the filetype was not stored using rockridge, use + whatever is stored in the iso9660 filesystem. */ + if (ctx.type == GRUB_FSHELP_UNKNOWN) + { + if ((dirent.flags & FLAG_TYPE) == FLAG_TYPE_DIR) + ctx.type = GRUB_FSHELP_DIR; + else if ((dirent.flags & FLAG_TYPE) == 3) + ctx.type = GRUB_FSHELP_DIR; + else + ctx.type = GRUB_FSHELP_REG; + } + + /* . and .. */ + if (!ctx.filename && dirent.namelen == 1 && name[0] == 0) + ctx.filename = (char *) "."; + + if (!ctx.filename && dirent.namelen == 1 && name[0] == 1) + ctx.filename = (char *) ".."; + + /* The filename was not stored in a rock ridge entry. Read it + from the iso9660 filesystem. */ + if (!dir->data->joliet && !ctx.filename) + { + char *ptr; + name[dirent.namelen] = '\0'; + ctx.filename = grub_strrchr (name, ';'); + if (ctx.filename) + *ctx.filename = '\0'; + /* ISO9660 names are not case-preserving. */ + ctx.type |= GRUB_FSHELP_CASE_INSENSITIVE; + for (ptr = name; *ptr; ptr++) + *ptr = grub_tolower (*ptr); + if (ptr != name && *(ptr - 1) == '.') + *(ptr - 1) = 0; + ctx.filename = name; + } + + if (dir->data->joliet && !ctx.filename) + { + char *semicolon; + + ctx.filename = grub_iso9660_convert_string + ((grub_uint8_t *) name, dirent.namelen >> 1); + + semicolon = grub_strrchr (ctx.filename, ';'); + if (semicolon) + *semicolon = '\0'; + + ctx.filename_alloc = 1; + } + + node->dirents[0] = dirent; + while (dirent.flags & FLAG_MORE_EXTENTS) + { + offset += dirent.len; + if (read_node (dir, offset, sizeof (dirent), (char *) &dirent)) + { + if (ctx.filename_alloc) + grub_free (ctx.filename); + grub_free (node); + return 0; + } + if (node->have_dirents >= node->alloc_dirents) + { + struct grub_fshelp_node *new_node; + node->alloc_dirents *= 2; + new_node = grub_realloc (node, + sizeof (struct grub_fshelp_node) + + ((node->alloc_dirents + - ARRAY_SIZE (node->dirents)) + * sizeof (node->dirents[0]))); + if (!new_node) + { + if (ctx.filename_alloc) + grub_free (ctx.filename); + grub_free (node); + return 0; + } + node = new_node; + } + node->dirents[node->have_dirents++] = dirent; + } + if (ctx.symlink) + { + if ((node->alloc_dirents - node->have_dirents) + * sizeof (node->dirents[0]) < grub_strlen (ctx.symlink) + 1) + { + struct grub_fshelp_node *new_node; + new_node = grub_realloc (node, + sizeof (struct grub_fshelp_node) + + ((node->alloc_dirents + - ARRAY_SIZE (node->dirents)) + * sizeof (node->dirents[0])) + + grub_strlen (ctx.symlink) + 1); + if (!new_node) + { + if (ctx.filename_alloc) + grub_free (ctx.filename); + grub_free (node); + return 0; + } + node = new_node; + } + node->have_symlink = 1; + grub_strcpy (node->symlink + + node->have_dirents * sizeof (node->dirents[0]) + - sizeof (node->dirents), ctx.symlink); + grub_free (ctx.symlink); + ctx.symlink = 0; + ctx.was_continue = 0; + } + if (hook (ctx.filename, ctx.type, node, hook_data)) + { + g_ventoy_last_file_dirent_pos = g_ventoy_last_read_dirent_pos; + g_ventoy_last_file_dirent_offset = g_ventoy_last_read_dirent_offset; + if (ctx.filename_alloc) + grub_free (ctx.filename); + return 1; + } + if (ctx.filename_alloc) + grub_free (ctx.filename); + } + } + + return 0; +} + + + +/* Context for grub_iso9660_dir. */ +struct grub_iso9660_dir_ctx +{ + grub_fs_dir_hook_t hook; + void *hook_data; +}; + +/* Helper for grub_iso9660_dir. */ +static int +grub_iso9660_dir_iter (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node, void *data) +{ + struct grub_iso9660_dir_ctx *ctx = data; + struct grub_dirhook_info info; + + grub_memset (&info, 0, sizeof (info)); + info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); + info.mtimeset = !!iso9660_to_unixtime2 (&node->dirents[0].mtime, &info.mtime); + + grub_free (node); + return ctx->hook (filename, &info, ctx->hook_data); +} + +static grub_err_t +grub_iso9660_dir (grub_device_t device, const char *path, + grub_fs_dir_hook_t hook, void *hook_data) +{ + struct grub_iso9660_dir_ctx ctx = { hook, hook_data }; + struct grub_iso9660_data *data = 0; + struct grub_fshelp_node rootnode; + struct grub_fshelp_node *foundnode; + + grub_dl_ref (my_mod); + + data = grub_iso9660_mount (device->disk); + if (! data) + goto fail; + + rootnode.data = data; + rootnode.alloc_dirents = 0; + rootnode.have_dirents = 1; + rootnode.have_symlink = 0; + rootnode.dirents[0] = data->voldesc.rootdir; + + /* Use the fshelp function to traverse the path. */ + if (grub_fshelp_find_file (path, &rootnode, + &foundnode, + grub_iso9660_iterate_dir, + grub_iso9660_read_symlink, + GRUB_FSHELP_DIR)) + goto fail; + + /* List the files in the directory. */ + grub_iso9660_iterate_dir (foundnode, grub_iso9660_dir_iter, &ctx); + + if (foundnode != &rootnode) + grub_free (foundnode); + + fail: + grub_free (data); + + grub_dl_unref (my_mod); + + return grub_errno; +} + + +/* Open a file named NAME and initialize FILE. */ +static grub_err_t +grub_iso9660_open (struct grub_file *file, const char *name) +{ + struct grub_iso9660_data *data; + struct grub_fshelp_node rootnode; + struct grub_fshelp_node *foundnode; + + grub_dl_ref (my_mod); + + data = grub_iso9660_mount (file->device->disk); + if (!data) + goto fail; + + rootnode.data = data; + rootnode.alloc_dirents = 0; + rootnode.have_dirents = 1; + rootnode.have_symlink = 0; + rootnode.dirents[0] = data->voldesc.rootdir; + + /* Use the fshelp function to traverse the path. */ + if (grub_fshelp_find_file (name, &rootnode, + &foundnode, + grub_iso9660_iterate_dir, + grub_iso9660_read_symlink, + GRUB_FSHELP_REG)) + goto fail; + + data->node = foundnode; + file->data = data; + file->size = get_node_size (foundnode); + file->offset = 0; + + return 0; + + fail: + grub_dl_unref (my_mod); + + grub_free (data); + + return grub_errno; +} + + +static grub_ssize_t +grub_iso9660_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_iso9660_data *data = + (struct grub_iso9660_data *) file->data; + grub_err_t err; + + /* XXX: The file is stored in as a single extent. */ + data->disk->read_hook = file->read_hook; + data->disk->read_hook_data = file->read_hook_data; + err = read_node (data->node, file->offset, len, buf); + data->disk->read_hook = NULL; + + if (err || grub_errno) + return -1; + + return len; +} + + +static grub_err_t +grub_iso9660_close (grub_file_t file) +{ + struct grub_iso9660_data *data = + (struct grub_iso9660_data *) file->data; + grub_free (data->node); + grub_free (data); + + grub_dl_unref (my_mod); + + return GRUB_ERR_NONE; +} + + +static grub_err_t +grub_iso9660_label (grub_device_t device, char **label) +{ + struct grub_iso9660_data *data; + data = grub_iso9660_mount (device->disk); + + if (data) + { + if (data->joliet) + *label = grub_iso9660_convert_string (data->voldesc.volname, 16); + else + *label = grub_strndup ((char *) data->voldesc.volname, 32); + if (*label) + { + char *ptr; + for (ptr = *label; *ptr;ptr++); + ptr--; + while (ptr >= *label && *ptr == ' ') + *ptr-- = 0; + } + + grub_free (data); + } + else + *label = 0; + + return grub_errno; +} + + +static grub_err_t +grub_iso9660_uuid (grub_device_t device, char **uuid) +{ + struct grub_iso9660_data *data; + grub_disk_t disk = device->disk; + + grub_dl_ref (my_mod); + + data = grub_iso9660_mount (disk); + if (data) + { + if (! data->voldesc.modified.year[0] && ! data->voldesc.modified.year[1] + && ! data->voldesc.modified.year[2] && ! data->voldesc.modified.year[3] + && ! data->voldesc.modified.month[0] && ! data->voldesc.modified.month[1] + && ! data->voldesc.modified.day[0] && ! data->voldesc.modified.day[1] + && ! data->voldesc.modified.hour[0] && ! data->voldesc.modified.hour[1] + && ! data->voldesc.modified.minute[0] && ! data->voldesc.modified.minute[1] + && ! data->voldesc.modified.second[0] && ! data->voldesc.modified.second[1] + && ! data->voldesc.modified.hundredth[0] && ! data->voldesc.modified.hundredth[1]) + { + grub_error (GRUB_ERR_BAD_NUMBER, "no creation date in filesystem to generate UUID"); + *uuid = NULL; + } + else + { + *uuid = grub_xasprintf ("%c%c%c%c-%c%c-%c%c-%c%c-%c%c-%c%c-%c%c", + data->voldesc.modified.year[0], + data->voldesc.modified.year[1], + data->voldesc.modified.year[2], + data->voldesc.modified.year[3], + data->voldesc.modified.month[0], + data->voldesc.modified.month[1], + data->voldesc.modified.day[0], + data->voldesc.modified.day[1], + data->voldesc.modified.hour[0], + data->voldesc.modified.hour[1], + data->voldesc.modified.minute[0], + data->voldesc.modified.minute[1], + data->voldesc.modified.second[0], + data->voldesc.modified.second[1], + data->voldesc.modified.hundredth[0], + data->voldesc.modified.hundredth[1]); + } + } + else + *uuid = NULL; + + grub_dl_unref (my_mod); + + grub_free (data); + + return grub_errno; +} + +/* Get writing time of filesystem. */ +static grub_err_t +grub_iso9660_mtime (grub_device_t device, grub_int32_t *timebuf) +{ + struct grub_iso9660_data *data; + grub_disk_t disk = device->disk; + grub_err_t err; + + grub_dl_ref (my_mod); + + data = grub_iso9660_mount (disk); + if (!data) + { + grub_dl_unref (my_mod); + return grub_errno; + } + err = iso9660_to_unixtime (&data->voldesc.modified, timebuf); + + grub_dl_unref (my_mod); + + grub_free (data); + + return err; +} + +void grub_iso9660_set_nojoliet(int nojoliet) +{ + g_ventoy_no_joliet = nojoliet; +} + +int grub_iso9660_is_joliet(void) +{ + return g_ventoy_cur_joliet; +} + +grub_uint64_t grub_iso9660_get_last_read_pos(grub_file_t file) +{ + (void)file; + return (g_ventoy_last_read_pos << GRUB_DISK_SECTOR_BITS); +} + +grub_uint64_t grub_iso9660_get_last_file_dirent_pos(grub_file_t file) +{ + (void)file; + return (g_ventoy_last_file_dirent_pos << GRUB_DISK_SECTOR_BITS) + g_ventoy_last_file_dirent_offset; +} + +static struct grub_fs grub_iso9660_fs = + { + .name = "iso9660", + .fs_dir = grub_iso9660_dir, + .fs_open = grub_iso9660_open, + .fs_read = grub_iso9660_read, + .fs_close = grub_iso9660_close, + .fs_label = grub_iso9660_label, + .fs_uuid = grub_iso9660_uuid, + .fs_mtime = grub_iso9660_mtime, +#ifdef GRUB_UTIL + .reserved_first_sector = 1, + .blocklist_install = 1, +#endif + .next = 0 + }; + +GRUB_MOD_INIT(iso9660) +{ + grub_fs_register (&grub_iso9660_fs); + my_mod = mod; +} + +GRUB_MOD_FINI(iso9660) +{ + grub_fs_unregister (&grub_iso9660_fs); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/ntfs.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/ntfs.c new file mode 100644 index 0000000..986ef75 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/ntfs.c @@ -0,0 +1,1244 @@ +/* ntfs.c - NTFS filesystem */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007,2008,2009 Free Software Foundation, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#define grub_fshelp_node grub_ntfs_file + +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +static grub_dl_t my_mod; + +#define grub_fshelp_node grub_ntfs_file + +static inline grub_uint16_t +u16at (void *ptr, grub_size_t ofs) +{ + return grub_le_to_cpu16 (grub_get_unaligned16 ((char *) ptr + ofs)); +} + +static inline grub_uint32_t +u32at (void *ptr, grub_size_t ofs) +{ + return grub_le_to_cpu32 (grub_get_unaligned32 ((char *) ptr + ofs)); +} + +static inline grub_uint64_t +u64at (void *ptr, grub_size_t ofs) +{ + return grub_le_to_cpu64 (grub_get_unaligned64 ((char *) ptr + ofs)); +} + +grub_ntfscomp_func_t grub_ntfscomp_func; + +static grub_err_t +fixup (grub_uint8_t *buf, grub_size_t len, const grub_uint8_t *magic) +{ + grub_uint16_t ss; + grub_uint8_t *pu; + grub_uint16_t us; + + COMPILE_TIME_ASSERT ((1 << GRUB_NTFS_BLK_SHR) == GRUB_DISK_SECTOR_SIZE); + + if (grub_memcmp (buf, magic, 4)) + return grub_error (GRUB_ERR_BAD_FS, "%s label not found", magic); + + ss = u16at (buf, 6) - 1; + if (ss != len) + return grub_error (GRUB_ERR_BAD_FS, "size not match"); + pu = buf + u16at (buf, 4); + us = u16at (pu, 0); + buf -= 2; + while (ss > 0) + { + buf += GRUB_DISK_SECTOR_SIZE; + pu += 2; + if (u16at (buf, 0) != us) + return grub_error (GRUB_ERR_BAD_FS, "fixup signature not match"); + buf[0] = pu[0]; + buf[1] = pu[1]; + ss--; + } + + return 0; +} + +static grub_err_t read_mft (struct grub_ntfs_data *data, grub_uint8_t *buf, + grub_uint64_t mftno); +static grub_err_t read_attr (struct grub_ntfs_attr *at, grub_uint8_t *dest, + grub_disk_addr_t ofs, grub_size_t len, + int cached, + grub_disk_read_hook_t read_hook, + void *read_hook_data); + +static grub_err_t read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, + grub_uint8_t *dest, + grub_disk_addr_t ofs, grub_size_t len, + int cached, + grub_disk_read_hook_t read_hook, + void *read_hook_data); + +static void +init_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft) +{ + at->mft = mft; + at->flags = (mft == &mft->data->mmft) ? GRUB_NTFS_AF_MMFT : 0; + at->attr_nxt = mft->buf + u16at (mft->buf, 0x14); + at->attr_end = at->emft_buf = at->edat_buf = at->sbuf = NULL; +} + +static void +free_attr (struct grub_ntfs_attr *at) +{ + grub_free (at->emft_buf); + grub_free (at->edat_buf); + grub_free (at->sbuf); +} + +static grub_uint8_t * +find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr) +{ + if (at->flags & GRUB_NTFS_AF_ALST) + { + retry: + while (at->attr_nxt < at->attr_end) + { + at->attr_cur = at->attr_nxt; + at->attr_nxt += u16at (at->attr_cur, 4); + if ((*at->attr_cur == attr) || (attr == 0)) + { + grub_uint8_t *new_pos; + + if (at->flags & GRUB_NTFS_AF_MMFT) + { + if ((grub_disk_read + (at->mft->data->disk, u32at (at->attr_cur, 0x10), 0, + 512, at->emft_buf)) + || + (grub_disk_read + (at->mft->data->disk, u32at (at->attr_cur, 0x14), 0, + 512, at->emft_buf + 512))) + return NULL; + + if (fixup (at->emft_buf, at->mft->data->mft_size, + (const grub_uint8_t *) "FILE")) + return NULL; + } + else + { + if (read_mft (at->mft->data, at->emft_buf, + u32at (at->attr_cur, 0x10))) + return NULL; + } + + new_pos = &at->emft_buf[u16at (at->emft_buf, 0x14)]; + while (*new_pos != 0xFF) + { + if ((*new_pos == *at->attr_cur) + && (u16at (new_pos, 0xE) == u16at (at->attr_cur, 0x18))) + { + return new_pos; + } + new_pos += u16at (new_pos, 4); + } + grub_error (GRUB_ERR_BAD_FS, + "can\'t find 0x%X in attribute list", + (unsigned char) *at->attr_cur); + return NULL; + } + } + return NULL; + } + at->attr_cur = at->attr_nxt; + while (*at->attr_cur != 0xFF) + { + at->attr_nxt += u16at (at->attr_cur, 4); + if (*at->attr_cur == GRUB_NTFS_AT_ATTRIBUTE_LIST) + at->attr_end = at->attr_cur; + if ((*at->attr_cur == attr) || (attr == 0)) + return at->attr_cur; + at->attr_cur = at->attr_nxt; + } + if (at->attr_end) + { + grub_uint8_t *pa; + + at->emft_buf = grub_malloc (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR); + if (at->emft_buf == NULL) + return NULL; + + pa = at->attr_end; + if (pa[8]) + { + grub_uint32_t n; + + n = ((u32at (pa, 0x30) + GRUB_DISK_SECTOR_SIZE - 1) + & (~(GRUB_DISK_SECTOR_SIZE - 1))); + at->attr_cur = at->attr_end; + at->edat_buf = grub_malloc (n); + if (!at->edat_buf) + return NULL; + if (read_data (at, pa, at->edat_buf, 0, n, 0, 0, 0)) + { + grub_error (GRUB_ERR_BAD_FS, + "fail to read non-resident attribute list"); + return NULL; + } + at->attr_nxt = at->edat_buf; + at->attr_end = at->edat_buf + u32at (pa, 0x30); + } + else + { + at->attr_nxt = at->attr_end + u16at (pa, 0x14); + at->attr_end = at->attr_end + u32at (pa, 4); + } + at->flags |= GRUB_NTFS_AF_ALST; + while (at->attr_nxt < at->attr_end) + { + if ((*at->attr_nxt == attr) || (attr == 0)) + break; + at->attr_nxt += u16at (at->attr_nxt, 4); + } + if (at->attr_nxt >= at->attr_end) + return NULL; + + if ((at->flags & GRUB_NTFS_AF_MMFT) && (attr == GRUB_NTFS_AT_DATA)) + { + at->flags |= GRUB_NTFS_AF_GPOS; + at->attr_cur = at->attr_nxt; + pa = at->attr_cur; + grub_set_unaligned32 ((char *) pa + 0x10, + grub_cpu_to_le32 (at->mft->data->mft_start)); + grub_set_unaligned32 ((char *) pa + 0x14, + grub_cpu_to_le32 (at->mft->data->mft_start + + 1)); + pa = at->attr_nxt + u16at (pa, 4); + while (pa < at->attr_end) + { + if (*pa != attr) + break; + if (read_attr + (at, pa + 0x10, + u32at (pa, 0x10) * (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR), + at->mft->data->mft_size << GRUB_NTFS_BLK_SHR, 0, 0, 0)) + return NULL; + pa += u16at (pa, 4); + } + at->attr_nxt = at->attr_cur; + at->flags &= ~GRUB_NTFS_AF_GPOS; + } + goto retry; + } + return NULL; +} + +static grub_uint8_t * +locate_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft, + grub_uint8_t attr) +{ + grub_uint8_t *pa; + + init_attr (at, mft); + pa = find_attr (at, attr); + if (pa == NULL) + return NULL; + if ((at->flags & GRUB_NTFS_AF_ALST) == 0) + { + while (1) + { + pa = find_attr (at, attr); + if (pa == NULL) + break; + if (at->flags & GRUB_NTFS_AF_ALST) + return pa; + } + grub_errno = GRUB_ERR_NONE; + free_attr (at); + init_attr (at, mft); + pa = find_attr (at, attr); + } + return pa; +} + +static grub_disk_addr_t +read_run_data (const grub_uint8_t *run, int nn, int sig) +{ + grub_uint64_t r = 0; + + if (sig && nn && (run[nn - 1] & 0x80)) + r = -1; + + grub_memcpy (&r, run, nn); + + return grub_le_to_cpu64 (r); +} + +grub_err_t +grub_ntfs_read_run_list (struct grub_ntfs_rlst * ctx) +{ + grub_uint8_t c1, c2; + grub_disk_addr_t val; + grub_uint8_t *run; + + run = ctx->cur_run; +retry: + c1 = ((*run) & 0x7); + c2 = ((*run) >> 4) & 0x7; + run++; + if (!c1) + { + if ((ctx->attr) && (ctx->attr->flags & GRUB_NTFS_AF_ALST)) + { + grub_disk_read_hook_t save_hook; + + save_hook = ctx->comp.disk->read_hook; + ctx->comp.disk->read_hook = 0; + run = find_attr (ctx->attr, *ctx->attr->attr_cur); + ctx->comp.disk->read_hook = save_hook; + if (run) + { + if (run[8] == 0) + return grub_error (GRUB_ERR_BAD_FS, + "$DATA should be non-resident"); + + run += u16at (run, 0x20); + ctx->curr_lcn = 0; + goto retry; + } + } + return grub_error (GRUB_ERR_BAD_FS, "run list overflown"); + } + ctx->curr_vcn = ctx->next_vcn; + ctx->next_vcn += read_run_data (run, c1, 0); /* length of current VCN */ + run += c1; + val = read_run_data (run, c2, 1); /* offset to previous LCN */ + run += c2; + ctx->curr_lcn += val; + if (val == 0) + ctx->flags |= GRUB_NTFS_RF_BLNK; + else + ctx->flags &= ~GRUB_NTFS_RF_BLNK; + ctx->cur_run = run; + return 0; +} + +static grub_disk_addr_t +grub_ntfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t block) +{ + struct grub_ntfs_rlst *ctx; + + ctx = (struct grub_ntfs_rlst *) node; + if (block >= ctx->next_vcn) + { + if (grub_ntfs_read_run_list (ctx)) + return -1; + return ctx->curr_lcn; + } + else + return (ctx->flags & GRUB_NTFS_RF_BLNK) ? 0 : (block - + ctx->curr_vcn + ctx->curr_lcn); +} + +static grub_err_t +read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, grub_uint8_t *dest, + grub_disk_addr_t ofs, grub_size_t len, int cached, + grub_disk_read_hook_t read_hook, void *read_hook_data) +{ + struct grub_ntfs_rlst cc, *ctx; + + if (len == 0) + return 0; + + grub_memset (&cc, 0, sizeof (cc)); + ctx = &cc; + ctx->attr = at; + ctx->comp.log_spc = at->mft->data->log_spc; + ctx->comp.disk = at->mft->data->disk; + + if (read_hook == grub_file_progress_hook) + ctx->file = read_hook_data; + + if (pa[8] == 0) + { + if (ofs + len > u32at (pa, 0x10)) + return grub_error (GRUB_ERR_BAD_FS, "read out of range"); + grub_memcpy (dest, pa + u32at (pa, 0x14) + ofs, len); + return 0; + } + + ctx->cur_run = pa + u16at (pa, 0x20); + + ctx->next_vcn = u32at (pa, 0x10); + ctx->curr_lcn = 0; + + if ((pa[0xC] & GRUB_NTFS_FLAG_COMPRESSED) + && !(at->flags & GRUB_NTFS_AF_GPOS)) + { + if (!cached) + return grub_error (GRUB_ERR_BAD_FS, "attribute can\'t be compressed"); + + return (grub_ntfscomp_func) ? grub_ntfscomp_func (dest, ofs, len, ctx) + : grub_error (GRUB_ERR_BAD_FS, N_("module `%s' isn't loaded"), + "ntfscomp"); + } + + ctx->target_vcn = ofs >> (GRUB_NTFS_BLK_SHR + ctx->comp.log_spc); + while (ctx->next_vcn <= ctx->target_vcn) + { + if (grub_ntfs_read_run_list (ctx)) + return grub_errno; + } + + if (at->flags & GRUB_NTFS_AF_GPOS) + { + grub_disk_addr_t st0, st1; + grub_uint64_t m; + + m = (ofs >> GRUB_NTFS_BLK_SHR) & ((1 << ctx->comp.log_spc) - 1); + + st0 = + ((ctx->target_vcn - ctx->curr_vcn + ctx->curr_lcn) << ctx->comp.log_spc) + m; + st1 = st0 + 1; + if (st1 == + (ctx->next_vcn - ctx->curr_vcn + ctx->curr_lcn) << ctx->comp.log_spc) + { + if (grub_ntfs_read_run_list (ctx)) + return grub_errno; + st1 = ctx->curr_lcn << ctx->comp.log_spc; + } + grub_set_unaligned32 (dest, grub_cpu_to_le32 (st0)); + grub_set_unaligned32 (dest + 4, grub_cpu_to_le32 (st1)); + return 0; + } + + grub_fshelp_read_file (ctx->comp.disk, (grub_fshelp_node_t) ctx, + read_hook, read_hook_data, ofs, len, + (char *) dest, + grub_ntfs_read_block, ofs + len, + ctx->comp.log_spc, 0); + return grub_errno; +} + +static grub_err_t +read_attr (struct grub_ntfs_attr *at, grub_uint8_t *dest, grub_disk_addr_t ofs, + grub_size_t len, int cached, + grub_disk_read_hook_t read_hook, void *read_hook_data) +{ + grub_uint8_t *save_cur; + grub_uint8_t attr; + grub_uint8_t *pp; + grub_err_t ret; + + save_cur = at->attr_cur; + at->attr_nxt = at->attr_cur; + attr = *at->attr_nxt; + if (at->flags & GRUB_NTFS_AF_ALST) + { + grub_uint8_t *pa; + grub_disk_addr_t vcn; + + /* If compression is possible make sure that we include possible + compressed block size. */ + if (GRUB_NTFS_LOG_COM_SEC >= at->mft->data->log_spc) + vcn = ((ofs >> GRUB_NTFS_COM_LOG_LEN) + << (GRUB_NTFS_LOG_COM_SEC - at->mft->data->log_spc)) & ~0xFULL; + else + vcn = ofs >> (at->mft->data->log_spc + GRUB_NTFS_BLK_SHR); + pa = at->attr_nxt + u16at (at->attr_nxt, 4); + while (pa < at->attr_end) + { + if (*pa != attr) + break; + if (u32at (pa, 8) > vcn) + break; + at->attr_nxt = pa; + pa += u16at (pa, 4); + } + } + pp = find_attr (at, attr); + if (pp) + ret = read_data (at, pp, dest, ofs, len, cached, + read_hook, read_hook_data); + else + ret = + (grub_errno) ? grub_errno : grub_error (GRUB_ERR_BAD_FS, + "attribute not found"); + at->attr_cur = save_cur; + return ret; +} + +static grub_err_t +read_mft (struct grub_ntfs_data *data, grub_uint8_t *buf, grub_uint64_t mftno) +{ + if (read_attr + (&data->mmft.attr, buf, mftno * ((grub_disk_addr_t) data->mft_size << GRUB_NTFS_BLK_SHR), + data->mft_size << GRUB_NTFS_BLK_SHR, 0, 0, 0)) + return grub_error (GRUB_ERR_BAD_FS, "read MFT 0x%llx fails", (unsigned long long) mftno); + return fixup (buf, data->mft_size, (const grub_uint8_t *) "FILE"); +} + +static grub_err_t +init_file (struct grub_ntfs_file *mft, grub_uint64_t mftno) +{ + unsigned short flag; + + mft->inode_read = 1; + + mft->buf = grub_malloc (mft->data->mft_size << GRUB_NTFS_BLK_SHR); + if (mft->buf == NULL) + return grub_errno; + + if (read_mft (mft->data, mft->buf, mftno)) + return grub_errno; + + flag = u16at (mft->buf, 0x16); + if ((flag & 1) == 0) + return grub_error (GRUB_ERR_BAD_FS, "MFT 0x%llx is not in use", + (unsigned long long) mftno); + + if ((flag & 2) == 0) + { + grub_uint8_t *pa; + + pa = locate_attr (&mft->attr, mft, GRUB_NTFS_AT_DATA); + if (pa == NULL) + return grub_error (GRUB_ERR_BAD_FS, "no $DATA in MFT 0x%llx", + (unsigned long long) mftno); + + if (!pa[8]) + mft->size = u32at (pa, 0x10); + else + mft->size = u64at (pa, 0x30); + + if ((mft->attr.flags & GRUB_NTFS_AF_ALST) == 0) + mft->attr.attr_end = 0; /* Don't jump to attribute list */ + } + else + init_attr (&mft->attr, mft); + + return 0; +} + +static void +free_file (struct grub_ntfs_file *mft) +{ + free_attr (&mft->attr); + grub_free (mft->buf); +} + +static char * +get_utf8 (grub_uint8_t *in, grub_size_t len) +{ + grub_uint8_t *buf; + grub_uint16_t *tmp; + grub_size_t i; + + buf = grub_malloc (len * GRUB_MAX_UTF8_PER_UTF16 + 1); + tmp = grub_malloc (len * sizeof (tmp[0])); + if (!buf || !tmp) + { + grub_free (buf); + grub_free (tmp); + return NULL; + } + for (i = 0; i < len; i++) + tmp[i] = grub_le_to_cpu16 (grub_get_unaligned16 (in + 2 * i)); + *grub_utf16_to_utf8 (buf, tmp, len) = '\0'; + grub_free (tmp); + return (char *) buf; +} + +static int +list_file (struct grub_ntfs_file *diro, grub_uint8_t *pos, + grub_fshelp_iterate_dir_hook_t hook, void *hook_data) +{ + grub_uint8_t *np; + int ns; + + while (1) + { + grub_uint8_t namespace; + char *ustr; + + if (pos[0xC] & 2) /* end signature */ + break; + + np = pos + 0x50; + ns = *(np++); + namespace = *(np++); + + /* + * Ignore files in DOS namespace, as they will reappear as Win32 + * names. + */ + if ((ns) && (namespace != 2)) + { + enum grub_fshelp_filetype type; + struct grub_ntfs_file *fdiro; + grub_uint32_t attr; + + attr = u32at (pos, 0x48); + if (attr & GRUB_NTFS_ATTR_REPARSE) + type = GRUB_FSHELP_SYMLINK; + else if (attr & GRUB_NTFS_ATTR_DIRECTORY) + type = GRUB_FSHELP_DIR; + else + type = GRUB_FSHELP_REG; + + fdiro = grub_zalloc (sizeof (struct grub_ntfs_file)); + if (!fdiro) + return 0; + + fdiro->data = diro->data; + fdiro->ino = u64at (pos, 0) & 0xffffffffffffULL; + fdiro->mtime = u64at (pos, 0x20); + + ustr = get_utf8 (np, ns); + if (ustr == NULL) + { + grub_free (fdiro); + return 0; + } + if (namespace) + type |= GRUB_FSHELP_CASE_INSENSITIVE; + + if (hook (ustr, type, fdiro, hook_data)) + { + grub_free (ustr); + return 1; + } + + grub_free (ustr); + } + pos += u16at (pos, 8); + } + return 0; +} + +struct symlink_descriptor +{ + grub_uint32_t type; + grub_uint32_t total_len; + grub_uint16_t off1; + grub_uint16_t len1; + grub_uint16_t off2; + grub_uint16_t len2; +} GRUB_PACKED; + +static char * +grub_ntfs_read_symlink (grub_fshelp_node_t node) +{ + struct grub_ntfs_file *mft; + struct symlink_descriptor symdesc; + grub_err_t err; + grub_uint8_t *buf16; + char *buf, *end; + grub_size_t len; + grub_uint8_t *pa; + grub_size_t off; + + mft = (struct grub_ntfs_file *) node; + + mft->buf = grub_malloc (mft->data->mft_size << GRUB_NTFS_BLK_SHR); + if (mft->buf == NULL) + return NULL; + + if (read_mft (mft->data, mft->buf, mft->ino)) + return NULL; + + pa = locate_attr (&mft->attr, mft, GRUB_NTFS_AT_SYMLINK); + if (pa == NULL) + { + grub_error (GRUB_ERR_BAD_FS, "no $SYMLINK in MFT 0x%llx", + (unsigned long long) mft->ino); + return NULL; + } + + err = read_attr (&mft->attr, (grub_uint8_t *) &symdesc, 0, + sizeof (struct symlink_descriptor), 1, 0, 0); + if (err) + return NULL; + + switch (grub_cpu_to_le32 (symdesc.type)) + { + case 0xa000000c: + off = (sizeof (struct symlink_descriptor) + 4 + + grub_cpu_to_le32 (symdesc.off1)); + len = grub_cpu_to_le32 (symdesc.len1); + break; + case 0xa0000003: + off = (sizeof (struct symlink_descriptor) + + grub_cpu_to_le32 (symdesc.off1)); + len = grub_cpu_to_le32 (symdesc.len1); + break; + default: + grub_error (GRUB_ERR_BAD_FS, "symlink type invalid (%x)", + grub_cpu_to_le32 (symdesc.type)); + return NULL; + } + + buf16 = grub_malloc (len); + if (!buf16) + return NULL; + + err = read_attr (&mft->attr, buf16, off, len, 1, 0, 0); + if (err) + return NULL; + + buf = get_utf8 (buf16, len / 2); + if (!buf) + { + grub_free (buf16); + return NULL; + } + grub_free (buf16); + + for (end = buf; *end; end++) + if (*end == '\\') + *end = '/'; + + /* Split the sequence to avoid GCC thinking that this is a trigraph. */ + if (grub_memcmp (buf, "/?" "?/", 4) == 0 && buf[5] == ':' && buf[6] == '/' + && grub_isalpha (buf[4])) + { + grub_memmove (buf, buf + 6, end - buf + 1 - 6); + end -= 6; + } + return buf; +} + +static int +grub_ntfs_iterate_dir (grub_fshelp_node_t dir, + grub_fshelp_iterate_dir_hook_t hook, void *hook_data) +{ + grub_uint8_t *bitmap; + struct grub_ntfs_attr attr, *at; + grub_uint8_t *cur_pos, *indx, *bmp; + int ret = 0; + grub_size_t bitmap_len; + struct grub_ntfs_file *mft; + + mft = (struct grub_ntfs_file *) dir; + + if (!mft->inode_read) + { + if (init_file (mft, mft->ino)) + return 0; + } + + indx = NULL; + bmp = NULL; + + at = &attr; + init_attr (at, mft); + while (1) + { + cur_pos = find_attr (at, GRUB_NTFS_AT_INDEX_ROOT); + if (cur_pos == NULL) + { + grub_error (GRUB_ERR_BAD_FS, "no $INDEX_ROOT"); + goto done; + } + + /* Resident, Namelen=4, Offset=0x18, Flags=0x00, Name="$I30" */ + if ((u32at (cur_pos, 8) != 0x180400) || + (u32at (cur_pos, 0x18) != 0x490024) || + (u32at (cur_pos, 0x1C) != 0x300033)) + continue; + cur_pos += u16at (cur_pos, 0x14); + if (*cur_pos != 0x30) /* Not filename index */ + continue; + break; + } + + cur_pos += 0x10; /* Skip index root */ + ret = list_file (mft, cur_pos + u16at (cur_pos, 0), hook, hook_data); + if (ret) + goto done; + + bitmap = NULL; + bitmap_len = 0; + free_attr (at); + init_attr (at, mft); + while ((cur_pos = find_attr (at, GRUB_NTFS_AT_BITMAP)) != NULL) + { + int ofs; + + ofs = cur_pos[0xA]; + /* Namelen=4, Name="$I30" */ + if ((cur_pos[9] == 4) && + (u32at (cur_pos, ofs) == 0x490024) && + (u32at (cur_pos, ofs + 4) == 0x300033)) + { + int is_resident = (cur_pos[8] == 0); + + bitmap_len = ((is_resident) ? u32at (cur_pos, 0x10) : + u32at (cur_pos, 0x28)); + + bmp = grub_malloc (bitmap_len); + if (bmp == NULL) + goto done; + + if (is_resident) + { + grub_memcpy (bmp, cur_pos + u16at (cur_pos, 0x14), + bitmap_len); + } + else + { + if (read_data (at, cur_pos, bmp, 0, bitmap_len, 0, 0, 0)) + { + grub_error (GRUB_ERR_BAD_FS, + "fails to read non-resident $BITMAP"); + goto done; + } + bitmap_len = u32at (cur_pos, 0x30); + } + + bitmap = bmp; + break; + } + } + + free_attr (at); + cur_pos = locate_attr (at, mft, GRUB_NTFS_AT_INDEX_ALLOCATION); + while (cur_pos != NULL) + { + /* Non-resident, Namelen=4, Offset=0x40, Flags=0, Name="$I30" */ + if ((u32at (cur_pos, 8) == 0x400401) && + (u32at (cur_pos, 0x40) == 0x490024) && + (u32at (cur_pos, 0x44) == 0x300033)) + break; + cur_pos = find_attr (at, GRUB_NTFS_AT_INDEX_ALLOCATION); + } + + if ((!cur_pos) && (bitmap)) + { + grub_error (GRUB_ERR_BAD_FS, "$BITMAP without $INDEX_ALLOCATION"); + goto done; + } + + if (bitmap) + { + grub_disk_addr_t i; + grub_uint8_t v; + + indx = grub_malloc (mft->data->idx_size << GRUB_NTFS_BLK_SHR); + if (indx == NULL) + goto done; + + v = 1; + for (i = 0; i < (grub_disk_addr_t)bitmap_len * 8; i++) + { + if (*bitmap & v) + { + if ((read_attr + (at, indx, i * (mft->data->idx_size << GRUB_NTFS_BLK_SHR), + (mft->data->idx_size << GRUB_NTFS_BLK_SHR), 0, 0, 0)) + || (fixup (indx, mft->data->idx_size, + (const grub_uint8_t *) "INDX"))) + goto done; + ret = list_file (mft, &indx[0x18 + u16at (indx, 0x18)], + hook, hook_data); + if (ret) + goto done; + } + v <<= 1; + if (!v) + { + v = 1; + bitmap++; + } + } + } + +done: + free_attr (at); + grub_free (indx); + grub_free (bmp); + + return ret; +} + +static struct grub_ntfs_data * +grub_ntfs_mount (grub_disk_t disk) +{ + struct grub_ntfs_bpb bpb; + struct grub_ntfs_data *data = 0; + grub_uint32_t spc; + grub_uint32_t sectors_per_cluster; + + if (!disk) + goto fail; + + data = (struct grub_ntfs_data *) grub_zalloc (sizeof (*data)); + if (!data) + goto fail; + + data->disk = disk; + + /* Read the BPB. */ + if (grub_disk_read (disk, 0, 0, sizeof (bpb), &bpb)) + goto fail; + + sectors_per_cluster = bpb.sectors_per_cluster; + if (sectors_per_cluster > 0x80) + sectors_per_cluster = 1U << (256U - bpb.sectors_per_cluster); + + if (grub_memcmp ((char *) &bpb.oem_name, "NTFS", 4) != 0 + || sectors_per_cluster == 0 + || (sectors_per_cluster & (sectors_per_cluster - 1)) != 0 + || bpb.bytes_per_sector == 0 + || (bpb.bytes_per_sector & (bpb.bytes_per_sector - 1)) != 0) + goto fail; + + spc = (((grub_uint32_t) sectors_per_cluster + * (grub_uint32_t) grub_le_to_cpu16 (bpb.bytes_per_sector)) + >> GRUB_NTFS_BLK_SHR); + if (spc == 0) + goto fail; + + for (data->log_spc = 0; (1U << data->log_spc) < spc; data->log_spc++); + + if (bpb.clusters_per_mft > 0) + data->mft_size = ((grub_disk_addr_t) bpb.clusters_per_mft) << data->log_spc; + else if (-bpb.clusters_per_mft < GRUB_NTFS_BLK_SHR || -bpb.clusters_per_mft >= 31) + goto fail; + else + data->mft_size = 1ULL << (-bpb.clusters_per_mft - GRUB_NTFS_BLK_SHR); + + if (bpb.clusters_per_index > 0) + data->idx_size = (((grub_disk_addr_t) bpb.clusters_per_index) + << data->log_spc); + else if (-bpb.clusters_per_index < GRUB_NTFS_BLK_SHR || -bpb.clusters_per_index >= 31) + goto fail; + else + data->idx_size = 1ULL << (-bpb.clusters_per_index - GRUB_NTFS_BLK_SHR); + + data->mft_start = grub_le_to_cpu64 (bpb.mft_lcn) << data->log_spc; + + if ((data->mft_size > GRUB_NTFS_MAX_MFT) || (data->idx_size > GRUB_NTFS_MAX_IDX)) + goto fail; + + data->mmft.data = data; + data->cmft.data = data; + + data->mmft.buf = grub_malloc (data->mft_size << GRUB_NTFS_BLK_SHR); + if (!data->mmft.buf) + goto fail; + + if (grub_disk_read + (disk, data->mft_start, 0, data->mft_size << GRUB_NTFS_BLK_SHR, data->mmft.buf)) + goto fail; + + data->uuid = grub_le_to_cpu64 (bpb.num_serial); + + if (fixup (data->mmft.buf, data->mft_size, (const grub_uint8_t *) "FILE")) + goto fail; + + if (!locate_attr (&data->mmft.attr, &data->mmft, GRUB_NTFS_AT_DATA)) + goto fail; + + if (init_file (&data->cmft, GRUB_NTFS_FILE_ROOT)) + goto fail; + + return data; + +fail: + grub_error (GRUB_ERR_BAD_FS, "not an ntfs filesystem"); + + if (data) + { + free_file (&data->mmft); + free_file (&data->cmft); + grub_free (data); + } + return 0; +} + +/* Context for grub_ntfs_dir. */ +struct grub_ntfs_dir_ctx +{ + grub_fs_dir_hook_t hook; + void *hook_data; +}; + +/* Helper for grub_ntfs_dir. */ +static int +grub_ntfs_dir_iter (const char *filename, enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node, void *data) +{ + struct grub_ntfs_dir_ctx *ctx = data; + struct grub_dirhook_info info; + + grub_memset (&info, 0, sizeof (info)); + info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); + info.mtimeset = 1; + info.mtime = grub_divmod64 (node->mtime, 10000000, 0) + - 86400ULL * 365 * (1970 - 1601) + - 86400ULL * ((1970 - 1601) / 4) + 86400ULL * ((1970 - 1601) / 100); + if (!info.dir) + info.size = node->size; + grub_free (node); + return ctx->hook (filename, &info, ctx->hook_data); +} + +static grub_err_t +grub_ntfs_dir (grub_device_t device, const char *path, + grub_fs_dir_hook_t hook, void *hook_data) +{ + struct grub_ntfs_dir_ctx ctx = { hook, hook_data }; + struct grub_ntfs_data *data = 0; + struct grub_fshelp_node *fdiro = 0; + + grub_dl_ref (my_mod); + + data = grub_ntfs_mount (device->disk); + if (!data) + goto fail; + + grub_fshelp_find_file (path, &data->cmft, &fdiro, grub_ntfs_iterate_dir, + grub_ntfs_read_symlink, GRUB_FSHELP_DIR); + + if (grub_errno) + goto fail; + + grub_ntfs_iterate_dir (fdiro, grub_ntfs_dir_iter, &ctx); + +fail: + if ((fdiro) && (fdiro != &data->cmft)) + { + free_file (fdiro); + grub_free (fdiro); + } + if (data) + { + free_file (&data->mmft); + free_file (&data->cmft); + grub_free (data); + } + + grub_dl_unref (my_mod); + + return grub_errno; +} + +static grub_err_t +grub_ntfs_open (grub_file_t file, const char *name) +{ + struct grub_ntfs_data *data = 0; + struct grub_fshelp_node *mft = 0; + + grub_dl_ref (my_mod); + + data = grub_ntfs_mount (file->device->disk); + if (!data) + goto fail; + + grub_fshelp_find_file (name, &data->cmft, &mft, grub_ntfs_iterate_dir, + grub_ntfs_read_symlink, GRUB_FSHELP_REG); + + if (grub_errno) + goto fail; + + if (mft != &data->cmft) + { + free_file (&data->cmft); + grub_memcpy (&data->cmft, mft, sizeof (*mft)); + grub_free (mft); + if (!data->cmft.inode_read) + { + if (init_file (&data->cmft, data->cmft.ino)) + goto fail; + } + } + + file->size = data->cmft.size; + file->data = data; + file->offset = 0; + + return 0; + +fail: + if (data) + { + free_file (&data->mmft); + free_file (&data->cmft); + grub_free (data); + } + + grub_dl_unref (my_mod); + + return grub_errno; +} + +static grub_ssize_t +grub_ntfs_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_ntfs_file *mft; + + mft = &((struct grub_ntfs_data *) file->data)->cmft; + if (file->read_hook) + mft->attr.save_pos = 1; + + read_attr (&mft->attr, (grub_uint8_t *) buf, file->offset, len, 1, + file->read_hook, file->read_hook_data); + return (grub_errno) ? -1 : (grub_ssize_t) len; +} + +static grub_err_t +grub_ntfs_close (grub_file_t file) +{ + struct grub_ntfs_data *data; + + data = file->data; + + if (data) + { + free_file (&data->mmft); + free_file (&data->cmft); + grub_free (data); + } + + grub_dl_unref (my_mod); + + return grub_errno; +} + +static grub_err_t +grub_ntfs_label (grub_device_t device, char **label) +{ + struct grub_ntfs_data *data = 0; + struct grub_fshelp_node *mft = 0; + grub_uint8_t *pa; + + grub_dl_ref (my_mod); + + *label = 0; + + data = grub_ntfs_mount (device->disk); + if (!data) + goto fail; + + grub_fshelp_find_file ("/$Volume", &data->cmft, &mft, grub_ntfs_iterate_dir, + 0, GRUB_FSHELP_REG); + + if (grub_errno) + goto fail; + + if (!mft->inode_read) + { + mft->buf = grub_malloc (mft->data->mft_size << GRUB_NTFS_BLK_SHR); + if (mft->buf == NULL) + goto fail; + + if (read_mft (mft->data, mft->buf, mft->ino)) + goto fail; + } + + init_attr (&mft->attr, mft); + pa = find_attr (&mft->attr, GRUB_NTFS_AT_VOLUME_NAME); + if ((pa) && (pa[8] == 0) && (u32at (pa, 0x10))) + { + int len; + + len = u32at (pa, 0x10) / 2; + pa += u16at (pa, 0x14); + *label = get_utf8 (pa, len); + } + +fail: + if ((mft) && (mft != &data->cmft)) + { + free_file (mft); + grub_free (mft); + } + if (data) + { + free_file (&data->mmft); + free_file (&data->cmft); + grub_free (data); + } + + grub_dl_unref (my_mod); + + return grub_errno; +} + +static grub_err_t +grub_ntfs_uuid (grub_device_t device, char **uuid) +{ + struct grub_ntfs_data *data; + grub_disk_t disk = device->disk; + + grub_dl_ref (my_mod); + + data = grub_ntfs_mount (disk); + if (data) + { + char *ptr; + *uuid = grub_xasprintf ("%016llx", (unsigned long long) data->uuid); + if (*uuid) + for (ptr = *uuid; *ptr; ptr++) + *ptr = grub_toupper (*ptr); + free_file (&data->mmft); + free_file (&data->cmft); + grub_free (data); + } + else + *uuid = NULL; + + grub_dl_unref (my_mod); + + return grub_errno; +} + +static struct grub_fs grub_ntfs_fs = + { + .name = "ntfs", + .fs_dir = grub_ntfs_dir, + .fs_open = grub_ntfs_open, + .fs_read = grub_ntfs_read, + .fs_close = grub_ntfs_close, + .fs_label = grub_ntfs_label, + .fs_uuid = grub_ntfs_uuid, +#ifdef GRUB_UTIL + .reserved_first_sector = 1, + .blocklist_install = 1, +#endif + .next = 0 +}; + +GRUB_MOD_INIT (ntfs) +{ + grub_fs_register (&grub_ntfs_fs); + my_mod = mod; +} + +GRUB_MOD_FINI (ntfs) +{ + grub_fs_unregister (&grub_ntfs_fs); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/squash4.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/squash4.c new file mode 100644 index 0000000..06a4a3c --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/squash4.c @@ -0,0 +1,1067 @@ +/* squash4.c - SquashFS */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "xz.h" +#include "xz_stream.h" + +GRUB_MOD_LICENSE ("GPLv3+"); + +/* + object format Pointed by + superblock RAW Fixed offset (0) + data RAW ? Fixed offset (60) + inode table Chunk superblock + dir table Chunk superblock + fragment table Chunk unk1 + unk1 RAW, Chunk superblock + unk2 RAW superblock + UID/GID Chunk exttblptr + exttblptr RAW superblock + + UID/GID table is the array ot uint32_t + unk1 contains pointer to fragment table followed by some chunk. + unk2 containts one uint64_t +*/ + +struct grub_squash_super +{ + grub_uint32_t magic; +#define SQUASH_MAGIC 0x73717368 + grub_uint32_t dummy1; + grub_uint32_t creation_time; + grub_uint32_t block_size; + grub_uint32_t dummy2; + grub_uint16_t compression; + grub_uint16_t dummy3; + grub_uint64_t dummy4; + grub_uint16_t root_ino_offset; + grub_uint32_t root_ino_chunk; + grub_uint16_t dummy5; + grub_uint64_t total_size; + grub_uint64_t exttbloffset; + grub_uint64_t dummy6; + grub_uint64_t inodeoffset; + grub_uint64_t diroffset; + grub_uint64_t unk1offset; + grub_uint64_t unk2offset; +} GRUB_PACKED; + +/* Chunk-based */ +struct grub_squash_inode +{ + /* Same values as direlem types. */ + grub_uint16_t type; + grub_uint16_t dummy[3]; + grub_uint32_t mtime; + grub_uint32_t dummy2; + union + { + struct { + grub_uint32_t chunk; + grub_uint32_t fragment; + grub_uint32_t offset; + grub_uint32_t size; + grub_uint32_t block_size[0]; + } GRUB_PACKED file; + struct { + grub_uint64_t chunk; + grub_uint64_t size; + grub_uint32_t dummy1[3]; + grub_uint32_t fragment; + grub_uint32_t offset; + grub_uint32_t dummy3; + grub_uint32_t block_size[0]; + } GRUB_PACKED long_file; + struct { + grub_uint32_t chunk; + grub_uint32_t dummy; + grub_uint16_t size; + grub_uint16_t offset; + } GRUB_PACKED dir; + struct { + grub_uint32_t dummy1; + grub_uint32_t size; + grub_uint32_t chunk; + grub_uint32_t dummy2; + grub_uint16_t dummy3; + grub_uint16_t offset; + } GRUB_PACKED long_dir; + struct { + grub_uint32_t dummy; + grub_uint32_t namelen; + char name[0]; + } GRUB_PACKED symlink; + } GRUB_PACKED; +} GRUB_PACKED; + +struct grub_squash_cache_inode +{ + struct grub_squash_inode ino; + grub_disk_addr_t ino_chunk; + grub_uint16_t ino_offset; + grub_uint32_t *block_sizes; + grub_disk_addr_t *cumulated_block_sizes; +}; + +/* Chunk-based. */ +struct grub_squash_dirent_header +{ + /* Actually the value is the number of elements - 1. */ + grub_uint32_t nelems; + grub_uint32_t ino_chunk; + grub_uint32_t dummy; +} GRUB_PACKED; + +struct grub_squash_dirent +{ + grub_uint16_t ino_offset; + grub_uint16_t dummy; + grub_uint16_t type; + /* Actually the value is the length of name - 1. */ + grub_uint16_t namelen; + char name[0]; +} GRUB_PACKED; + +enum + { + SQUASH_TYPE_DIR = 1, + SQUASH_TYPE_REGULAR = 2, + SQUASH_TYPE_SYMLINK = 3, + SQUASH_TYPE_LONG_DIR = 8, + SQUASH_TYPE_LONG_REGULAR = 9, + }; + + +struct grub_squash_frag_desc +{ + grub_uint64_t offset; + grub_uint32_t size; + grub_uint32_t dummy; +} GRUB_PACKED; + +enum + { + SQUASH_CHUNK_FLAGS = 0x8000, + SQUASH_CHUNK_UNCOMPRESSED = 0x8000 + }; + +enum + { + SQUASH_BLOCK_FLAGS = 0x1000000, + SQUASH_BLOCK_UNCOMPRESSED = 0x1000000 + }; + +enum + { + COMPRESSION_ZLIB = 1, + COMPRESSION_LZO = 3, + COMPRESSION_XZ = 4, + COMPRESSION_LZ4 = 5, + COMPRESSION_ZSTD = 6, + }; + + +#define SQUASH_CHUNK_SIZE 0x2000 +#define XZBUFSIZ 0x2000 + +struct grub_squash_data +{ + grub_disk_t disk; + struct grub_squash_super sb; + struct grub_squash_cache_inode ino; + grub_uint64_t fragments; + int log2_blksz; + grub_size_t blksz; + grub_ssize_t (*decompress) (char *inbuf, grub_size_t insize, grub_off_t off, + char *outbuf, grub_size_t outsize, + struct grub_squash_data *data); + struct xz_dec *xzdec; + char *xzbuf; +}; + +struct grub_fshelp_node +{ + struct grub_squash_data *data; + struct grub_squash_inode ino; + grub_size_t stsize; + struct + { + grub_disk_addr_t ino_chunk; + grub_uint16_t ino_offset; + } stack[1]; +}; + +static grub_err_t +read_chunk (struct grub_squash_data *data, void *buf, grub_size_t len, + grub_uint64_t chunk_start, grub_off_t offset) +{ + while (len > 0) + { + grub_uint64_t csize; + grub_uint16_t d; + grub_err_t err; + while (1) + { + err = grub_disk_read (data->disk, + chunk_start >> GRUB_DISK_SECTOR_BITS, + chunk_start & (GRUB_DISK_SECTOR_SIZE - 1), + sizeof (d), &d); + if (err) + return err; + if (offset < SQUASH_CHUNK_SIZE) + break; + offset -= SQUASH_CHUNK_SIZE; + chunk_start += 2 + (grub_le_to_cpu16 (d) & ~SQUASH_CHUNK_FLAGS); + } + + csize = SQUASH_CHUNK_SIZE - offset; + if (csize > len) + csize = len; + + if (grub_le_to_cpu16 (d) & SQUASH_CHUNK_UNCOMPRESSED) + { + grub_disk_addr_t a = chunk_start + 2 + offset; + err = grub_disk_read (data->disk, (a >> GRUB_DISK_SECTOR_BITS), + a & (GRUB_DISK_SECTOR_SIZE - 1), + csize, buf); + if (err) + return err; + } + else + { + char *tmp; + grub_size_t bsize = grub_le_to_cpu16 (d) & ~SQUASH_CHUNK_FLAGS; + grub_disk_addr_t a = chunk_start + 2; + tmp = grub_malloc (bsize); + if (!tmp) + return grub_errno; + /* FIXME: buffer uncompressed data. */ + err = grub_disk_read (data->disk, (a >> GRUB_DISK_SECTOR_BITS), + a & (GRUB_DISK_SECTOR_SIZE - 1), + bsize, tmp); + if (err) + { + grub_free (tmp); + return err; + } + + if (data->decompress (tmp, bsize, offset, + buf, csize, data) < 0) + { + grub_free (tmp); + return grub_errno; + } + grub_free (tmp); + } + len -= csize; + offset += csize; + buf = (char *) buf + csize; + } + return GRUB_ERR_NONE; +} + +static grub_ssize_t +zlib_decompress (char *inbuf, grub_size_t insize, grub_off_t off, + char *outbuf, grub_size_t outsize, + struct grub_squash_data *data __attribute__ ((unused))) +{ + return grub_zlib_decompress (inbuf, insize, off, outbuf, outsize); +} + +static grub_ssize_t +lzo_decompress (char *inbuf, grub_size_t insize, grub_off_t off, + char *outbuf, grub_size_t len, struct grub_squash_data *data) +{ + lzo_uint usize = data->blksz; + grub_uint8_t *udata; + + if (usize < 8192) + usize = 8192; + + udata = grub_malloc (usize); + if (!udata) + return -1; + + if (lzo1x_decompress_safe ((grub_uint8_t *) inbuf, + insize, udata, &usize, NULL) != LZO_E_OK) + { + grub_error (GRUB_ERR_BAD_FS, "incorrect compressed chunk"); + grub_free (udata); + return -1; + } + grub_memcpy (outbuf, udata + off, len); + grub_free (udata); + return len; +} + +static grub_ssize_t +xz_decompress (char *inbuf, grub_size_t insize, grub_off_t off, + char *outbuf, grub_size_t len, struct grub_squash_data *data) +{ + grub_size_t ret = 0; + grub_off_t pos = 0; + struct xz_buf buf; + + xz_dec_reset (data->xzdec); + buf.in = (grub_uint8_t *) inbuf; + buf.in_pos = 0; + buf.in_size = insize; + buf.out = (grub_uint8_t *) data->xzbuf; + buf.out_pos = 0; + buf.out_size = XZBUFSIZ; + + while (len) + { + enum xz_ret xzret; + + buf.out_pos = 0; + + xzret = xz_dec_run (data->xzdec, &buf); + + if (xzret != XZ_OK && xzret != XZ_STREAM_END) + { + grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "invalid xz chunk"); + return -1; + } + if (pos + buf.out_pos >= off) + { + grub_ssize_t outoff = pos - off; + grub_size_t l; + if (outoff >= 0) + { + l = buf.out_pos; + if (l > len) + l = len; + grub_memcpy (outbuf + outoff, buf.out, l); + } + else + { + outoff = -outoff; + l = buf.out_pos - outoff; + if (l > len) + l = len; + grub_memcpy (outbuf, buf.out + outoff, l); + } + ret += l; + len -= l; + } + pos += buf.out_pos; + if (xzret == XZ_STREAM_END) + break; + } + return ret; +} + +int LZ4_uncompress_unknownOutputSize(const char *source, char *dest, int isize, int maxOutputSize); +static grub_ssize_t lz4_decompress_wrap(char *inbuf, grub_size_t insize, grub_off_t off, + char *outbuf, grub_size_t len, struct grub_squash_data *data) +{ + char *udata = NULL; + int usize = data->blksz; + + if (usize < 8192) + usize = 8192; + + udata = grub_malloc (usize); + if (!udata) + return -1; + + LZ4_uncompress_unknownOutputSize(inbuf, udata, insize, usize); + grub_memcpy (outbuf, udata + off, len); + grub_free (udata); + return len; +} + +static grub_ssize_t zstd_decompress_wrap(char *inbuf, grub_size_t insize, grub_off_t off, + char *outbuf, grub_size_t len, struct grub_squash_data *data) +{ + char *udata = NULL; + int usize = data->blksz; + if (usize < 8192) + usize = 8192; + + udata = grub_malloc (usize); + if (!udata) + return -1; + + ZSTD_decompress(udata, usize, inbuf, insize); + grub_memcpy(outbuf, udata + off, len); + grub_free(udata); + + return len; +} + +static struct grub_squash_data * +squash_mount (grub_disk_t disk) +{ + struct grub_squash_super sb; + grub_err_t err; + struct grub_squash_data *data; + grub_uint64_t frag; + + err = grub_disk_read (disk, 0, 0, sizeof (sb), &sb); + if (grub_errno == GRUB_ERR_OUT_OF_RANGE) + grub_error (GRUB_ERR_BAD_FS, "not a squash4"); + if (err) + return NULL; + if (sb.magic != grub_cpu_to_le32_compile_time (SQUASH_MAGIC) + || sb.block_size == 0 + || ((sb.block_size - 1) & sb.block_size)) + { + grub_error (GRUB_ERR_BAD_FS, "not squash4"); + return NULL; + } + + err = grub_disk_read (disk, + grub_le_to_cpu64 (sb.unk1offset) + >> GRUB_DISK_SECTOR_BITS, + grub_le_to_cpu64 (sb.unk1offset) + & (GRUB_DISK_SECTOR_SIZE - 1), sizeof (frag), &frag); + if (grub_errno == GRUB_ERR_OUT_OF_RANGE) + grub_error (GRUB_ERR_BAD_FS, "not a squash4"); + if (err) + return NULL; + + data = grub_zalloc (sizeof (*data)); + if (!data) + return NULL; + data->sb = sb; + data->disk = disk; + data->fragments = grub_le_to_cpu64 (frag); + + switch (sb.compression) + { + case grub_cpu_to_le16_compile_time (COMPRESSION_ZLIB): + data->decompress = zlib_decompress; + break; + case grub_cpu_to_le16_compile_time (COMPRESSION_LZO): + data->decompress = lzo_decompress; + break; + case grub_cpu_to_le16_compile_time (COMPRESSION_LZ4): + data->decompress = lz4_decompress_wrap; + break; + case grub_cpu_to_le16_compile_time (COMPRESSION_ZSTD): + data->decompress = zstd_decompress_wrap; + break; + case grub_cpu_to_le16_compile_time (COMPRESSION_XZ): + data->decompress = xz_decompress; + data->xzbuf = grub_malloc (XZBUFSIZ); + if (!data->xzbuf) + { + grub_free (data); + return NULL; + } + data->xzdec = xz_dec_init (1 << 16); + if (!data->xzdec) + { + grub_free (data->xzbuf); + grub_free (data); + return NULL; + } + break; + default: + grub_free (data); + grub_error (GRUB_ERR_BAD_FS, "unsupported compression %d", + grub_le_to_cpu16 (sb.compression)); + return NULL; + } + + data->blksz = grub_le_to_cpu32 (data->sb.block_size); + for (data->log2_blksz = 0; + (1U << data->log2_blksz) < data->blksz; + data->log2_blksz++); + + return data; +} + +static char * +grub_squash_read_symlink (grub_fshelp_node_t node) +{ + char *ret; + grub_err_t err; + ret = grub_malloc (grub_le_to_cpu32 (node->ino.symlink.namelen) + 1); + + err = read_chunk (node->data, ret, + grub_le_to_cpu32 (node->ino.symlink.namelen), + grub_le_to_cpu64 (node->data->sb.inodeoffset) + + node->stack[node->stsize - 1].ino_chunk, + node->stack[node->stsize - 1].ino_offset + + (node->ino.symlink.name - (char *) &node->ino)); + if (err) + { + grub_free (ret); + return NULL; + } + ret[grub_le_to_cpu32 (node->ino.symlink.namelen)] = 0; + return ret; +} + +static int +grub_squash_iterate_dir (grub_fshelp_node_t dir, + grub_fshelp_iterate_dir_hook_t hook, void *hook_data) +{ + grub_uint32_t off; + grub_uint32_t endoff; + grub_uint64_t chunk; + unsigned i; + + /* FIXME: why - 3 ? */ + switch (dir->ino.type) + { + case grub_cpu_to_le16_compile_time (SQUASH_TYPE_DIR): + off = grub_le_to_cpu16 (dir->ino.dir.offset); + endoff = grub_le_to_cpu16 (dir->ino.dir.size) + off - 3; + chunk = grub_le_to_cpu32 (dir->ino.dir.chunk); + break; + case grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_DIR): + off = grub_le_to_cpu16 (dir->ino.long_dir.offset); + endoff = grub_le_to_cpu32 (dir->ino.long_dir.size) + off - 3; + chunk = grub_le_to_cpu32 (dir->ino.long_dir.chunk); + break; + default: + grub_error (GRUB_ERR_BAD_FS, "unexpected ino type 0x%x", + grub_le_to_cpu16 (dir->ino.type)); + return 0; + } + + { + grub_fshelp_node_t node; + node = grub_malloc (sizeof (*node) + dir->stsize * sizeof (dir->stack[0])); + if (!node) + return 0; + grub_memcpy (node, dir, + sizeof (*node) + dir->stsize * sizeof (dir->stack[0])); + if (hook (".", GRUB_FSHELP_DIR, node, hook_data)) + return 1; + + if (dir->stsize != 1) + { + grub_err_t err; + + node = grub_malloc (sizeof (*node) + dir->stsize * sizeof (dir->stack[0])); + if (!node) + return 0; + + grub_memcpy (node, dir, + sizeof (*node) + dir->stsize * sizeof (dir->stack[0])); + + node->stsize--; + err = read_chunk (dir->data, &node->ino, sizeof (node->ino), + grub_le_to_cpu64 (dir->data->sb.inodeoffset) + + node->stack[node->stsize - 1].ino_chunk, + node->stack[node->stsize - 1].ino_offset); + if (err) + return 0; + + if (hook ("..", GRUB_FSHELP_DIR, node, hook_data)) + return 1; + } + } + + while (off < endoff) + { + struct grub_squash_dirent_header dh; + grub_err_t err; + + err = read_chunk (dir->data, &dh, sizeof (dh), + grub_le_to_cpu64 (dir->data->sb.diroffset) + + chunk, off); + if (err) + return 0; + off += sizeof (dh); + for (i = 0; i < (unsigned) grub_le_to_cpu32 (dh.nelems) + 1; i++) + { + char *buf; + int r; + struct grub_fshelp_node *node; + enum grub_fshelp_filetype filetype = GRUB_FSHELP_REG; + struct grub_squash_dirent di; + struct grub_squash_inode ino; + + err = read_chunk (dir->data, &di, sizeof (di), + grub_le_to_cpu64 (dir->data->sb.diroffset) + + chunk, off); + if (err) + return 0; + off += sizeof (di); + + err = read_chunk (dir->data, &ino, sizeof (ino), + grub_le_to_cpu64 (dir->data->sb.inodeoffset) + + grub_le_to_cpu32 (dh.ino_chunk), + grub_cpu_to_le16 (di.ino_offset)); + if (err) + return 0; + + buf = grub_malloc (grub_le_to_cpu16 (di.namelen) + 2); + if (!buf) + return 0; + err = read_chunk (dir->data, buf, + grub_le_to_cpu16 (di.namelen) + 1, + grub_le_to_cpu64 (dir->data->sb.diroffset) + + chunk, off); + if (err) + return 0; + + off += grub_le_to_cpu16 (di.namelen) + 1; + buf[grub_le_to_cpu16 (di.namelen) + 1] = 0; + if (grub_le_to_cpu16 (di.type) == SQUASH_TYPE_DIR) + filetype = GRUB_FSHELP_DIR; + if (grub_le_to_cpu16 (di.type) == SQUASH_TYPE_SYMLINK) + filetype = GRUB_FSHELP_SYMLINK; + + node = grub_malloc (sizeof (*node) + + (dir->stsize + 1) * sizeof (dir->stack[0])); + if (! node) + return 0; + + grub_memcpy (node, dir, + sizeof (*node) + dir->stsize * sizeof (dir->stack[0])); + + node->ino = ino; + node->stack[node->stsize].ino_chunk = grub_le_to_cpu32 (dh.ino_chunk); + node->stack[node->stsize].ino_offset = grub_le_to_cpu16 (di.ino_offset); + node->stsize++; + r = hook (buf, filetype, node, hook_data); + + grub_free (buf); + if (r) + return r; + } + } + return 0; +} + +static grub_err_t +make_root_node (struct grub_squash_data *data, struct grub_fshelp_node *root) +{ + grub_memset (root, 0, sizeof (*root)); + root->data = data; + root->stsize = 1; + root->stack[0].ino_chunk = grub_le_to_cpu32 (data->sb.root_ino_chunk); + root->stack[0].ino_offset = grub_cpu_to_le16 (data->sb.root_ino_offset); + return read_chunk (data, &root->ino, sizeof (root->ino), + grub_le_to_cpu64 (data->sb.inodeoffset) + + root->stack[0].ino_chunk, + root->stack[0].ino_offset); +} + +static void +squash_unmount (struct grub_squash_data *data) +{ + if (data->xzdec) + xz_dec_end (data->xzdec); + grub_free (data->xzbuf); + grub_free (data->ino.cumulated_block_sizes); + grub_free (data->ino.block_sizes); + grub_free (data); +} + + +/* Context for grub_squash_dir. */ +struct grub_squash_dir_ctx +{ + grub_fs_dir_hook_t hook; + void *hook_data; +}; + +/* Helper for grub_squash_dir. */ +static int +grub_squash_dir_iter (const char *filename, enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node, void *data) +{ + struct grub_squash_dir_ctx *ctx = data; + struct grub_dirhook_info info; + + grub_memset (&info, 0, sizeof (info)); + info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); + info.mtimeset = 1; + info.mtime = grub_le_to_cpu32 (node->ino.mtime); + grub_free (node); + return ctx->hook (filename, &info, ctx->hook_data); +} + +static grub_err_t +grub_squash_dir (grub_device_t device, const char *path, + grub_fs_dir_hook_t hook, void *hook_data) +{ + struct grub_squash_dir_ctx ctx = { hook, hook_data }; + struct grub_squash_data *data = 0; + struct grub_fshelp_node *fdiro = 0; + struct grub_fshelp_node root; + grub_err_t err; + + data = squash_mount (device->disk); + if (! data) + return grub_errno; + + err = make_root_node (data, &root); + if (err) + return err; + + grub_fshelp_find_file (path, &root, &fdiro, grub_squash_iterate_dir, + grub_squash_read_symlink, GRUB_FSHELP_DIR); + if (!grub_errno) + grub_squash_iterate_dir (fdiro, grub_squash_dir_iter, &ctx); + + squash_unmount (data); + + return grub_errno; +} + +static grub_err_t +grub_squash_open (struct grub_file *file, const char *name) +{ + struct grub_squash_data *data = 0; + struct grub_fshelp_node *fdiro = 0; + struct grub_fshelp_node root; + grub_err_t err; + + data = squash_mount (file->device->disk); + if (! data) + return grub_errno; + + err = make_root_node (data, &root); + if (err) + return err; + + grub_fshelp_find_file (name, &root, &fdiro, grub_squash_iterate_dir, + grub_squash_read_symlink, GRUB_FSHELP_REG); + if (grub_errno) + { + squash_unmount (data); + return grub_errno; + } + + file->data = data; + data->ino.ino = fdiro->ino; + data->ino.block_sizes = NULL; + data->ino.cumulated_block_sizes = NULL; + data->ino.ino_chunk = fdiro->stack[fdiro->stsize - 1].ino_chunk; + data->ino.ino_offset = fdiro->stack[fdiro->stsize - 1].ino_offset; + + switch (fdiro->ino.type) + { + case grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_REGULAR): + file->size = grub_le_to_cpu64 (fdiro->ino.long_file.size); + break; + case grub_cpu_to_le16_compile_time (SQUASH_TYPE_REGULAR): + file->size = grub_le_to_cpu32 (fdiro->ino.file.size); + break; + default: + { + grub_uint16_t type = grub_le_to_cpu16 (fdiro->ino.type); + grub_free (fdiro); + squash_unmount (data); + return grub_error (GRUB_ERR_BAD_FS, "unexpected ino type 0x%x", type); + } + } + + grub_free (fdiro); + + return GRUB_ERR_NONE; +} + +static grub_ssize_t +direct_read (struct grub_squash_data *data, + struct grub_squash_cache_inode *ino, + grub_off_t off, char *buf, grub_size_t len) +{ + grub_err_t err; + grub_off_t cumulated_uncompressed_size = 0; + grub_uint64_t a = 0; + grub_size_t i; + grub_size_t origlen = len; + + switch (ino->ino.type) + { + case grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_REGULAR): + a = grub_le_to_cpu64 (ino->ino.long_file.chunk); + break; + case grub_cpu_to_le16_compile_time (SQUASH_TYPE_REGULAR): + a = grub_le_to_cpu32 (ino->ino.file.chunk); + break; + } + + if (!ino->block_sizes) + { + grub_off_t total_size = 0; + grub_size_t total_blocks; + grub_size_t block_offset = 0; + switch (ino->ino.type) + { + case grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_REGULAR): + total_size = grub_le_to_cpu64 (ino->ino.long_file.size); + block_offset = ((char *) &ino->ino.long_file.block_size + - (char *) &ino->ino); + break; + case grub_cpu_to_le16_compile_time (SQUASH_TYPE_REGULAR): + total_size = grub_le_to_cpu32 (ino->ino.file.size); + block_offset = ((char *) &ino->ino.file.block_size + - (char *) &ino->ino); + break; + } + total_blocks = ((total_size + data->blksz - 1) >> data->log2_blksz); + ino->block_sizes = grub_malloc (total_blocks + * sizeof (ino->block_sizes[0])); + ino->cumulated_block_sizes = grub_malloc (total_blocks + * sizeof (ino->cumulated_block_sizes[0])); + if (!ino->block_sizes || !ino->cumulated_block_sizes) + { + grub_free (ino->block_sizes); + grub_free (ino->cumulated_block_sizes); + ino->block_sizes = 0; + ino->cumulated_block_sizes = 0; + return -1; + } + err = read_chunk (data, ino->block_sizes, + total_blocks * sizeof (ino->block_sizes[0]), + grub_le_to_cpu64 (data->sb.inodeoffset) + + ino->ino_chunk, + ino->ino_offset + block_offset); + if (err) + { + grub_free (ino->block_sizes); + grub_free (ino->cumulated_block_sizes); + ino->block_sizes = 0; + ino->cumulated_block_sizes = 0; + return -1; + } + ino->cumulated_block_sizes[0] = 0; + for (i = 1; i < total_blocks; i++) + ino->cumulated_block_sizes[i] = ino->cumulated_block_sizes[i - 1] + + (grub_le_to_cpu32 (ino->block_sizes[i - 1]) & ~SQUASH_BLOCK_FLAGS); + } + + if (a == 0) + a = sizeof (struct grub_squash_super); + i = off >> data->log2_blksz; + cumulated_uncompressed_size = data->blksz * (grub_disk_addr_t) i; + while (cumulated_uncompressed_size < off + len) + { + grub_size_t boff, curread; + boff = off - cumulated_uncompressed_size; + curread = data->blksz - boff; + if (curread > len) + curread = len; + if (!ino->block_sizes[i]) + { + /* Sparse block */ + grub_memset (buf, '\0', curread); + } + else if (!(ino->block_sizes[i] + & grub_cpu_to_le32_compile_time (SQUASH_BLOCK_UNCOMPRESSED))) + { + char *block; + grub_size_t csize; + csize = grub_le_to_cpu32 (ino->block_sizes[i]) & ~SQUASH_BLOCK_FLAGS; + block = grub_malloc (csize); + if (!block) + return -1; + err = grub_disk_read (data->disk, + (ino->cumulated_block_sizes[i] + a) + >> GRUB_DISK_SECTOR_BITS, + (ino->cumulated_block_sizes[i] + a) + & (GRUB_DISK_SECTOR_SIZE - 1), + csize, block); + if (err) + { + grub_free (block); + return -1; + } + if (data->decompress (block, csize, boff, buf, curread, data) + != (grub_ssize_t) curread) + { + grub_free (block); + if (!grub_errno) + grub_error (GRUB_ERR_BAD_FS, "incorrect compressed chunk"); + return -1; + } + grub_free (block); + } + else + err = grub_disk_read (data->disk, + (ino->cumulated_block_sizes[i] + a + boff) + >> GRUB_DISK_SECTOR_BITS, + (ino->cumulated_block_sizes[i] + a + boff) + & (GRUB_DISK_SECTOR_SIZE - 1), + curread, buf); + if (err) + return -1; + off += curread; + len -= curread; + buf += curread; + cumulated_uncompressed_size += grub_le_to_cpu32 (data->sb.block_size); + i++; + } + return origlen; +} + + +static grub_ssize_t +grub_squash_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_squash_data *data = file->data; + struct grub_squash_cache_inode *ino = &data->ino; + grub_off_t off = file->offset; + grub_err_t err; + grub_uint64_t a, b; + grub_uint32_t fragment = 0; + int compressed = 0; + struct grub_squash_frag_desc frag; + grub_off_t direct_len; + grub_uint64_t mask = grub_le_to_cpu32 (data->sb.block_size) - 1; + grub_size_t orig_len = len; + + switch (ino->ino.type) + { + case grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_REGULAR): + fragment = grub_le_to_cpu32 (ino->ino.long_file.fragment); + break; + case grub_cpu_to_le16_compile_time (SQUASH_TYPE_REGULAR): + fragment = grub_le_to_cpu32 (ino->ino.file.fragment); + break; + } + + /* Squash may pack file tail as fragment. So read initial part directly and + get tail from fragments */ + direct_len = fragment == 0xffffffff ? file->size : file->size & ~mask; + if (off < direct_len) + { + grub_size_t read_len = direct_len - off; + grub_ssize_t res; + + if (read_len > len) + read_len = len; + res = direct_read (data, ino, off, buf, read_len); + if ((grub_size_t) res != read_len) + return -1; /* FIXME: is short read possible here? */ + len -= read_len; + if (!len) + return read_len; + buf += read_len; + off = 0; + } + else + off -= direct_len; + + err = read_chunk (data, &frag, sizeof (frag), + data->fragments, sizeof (frag) * fragment); + if (err) + return -1; + a = grub_le_to_cpu64 (frag.offset); + compressed = !(frag.size & grub_cpu_to_le32_compile_time (SQUASH_BLOCK_UNCOMPRESSED)); + if (ino->ino.type == grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_REGULAR)) + b = grub_le_to_cpu32 (ino->ino.long_file.offset) + off; + else + b = grub_le_to_cpu32 (ino->ino.file.offset) + off; + + /* FIXME: cache uncompressed chunks. */ + if (compressed) + { + char *block; + block = grub_malloc (grub_le_to_cpu32 (frag.size)); + if (!block) + return -1; + err = grub_disk_read (data->disk, + a >> GRUB_DISK_SECTOR_BITS, + a & (GRUB_DISK_SECTOR_SIZE - 1), + grub_le_to_cpu32 (frag.size), block); + if (err) + { + grub_free (block); + return -1; + } + if (data->decompress (block, grub_le_to_cpu32 (frag.size), + b, buf, len, data) + != (grub_ssize_t) len) + { + grub_free (block); + if (!grub_errno) + grub_error (GRUB_ERR_BAD_FS, "incorrect compressed chunk"); + return -1; + } + grub_free (block); + } + else + { + err = grub_disk_read (data->disk, (a + b) >> GRUB_DISK_SECTOR_BITS, + (a + b) & (GRUB_DISK_SECTOR_SIZE - 1), len, buf); + if (err) + return -1; + } + return orig_len; +} + +static grub_err_t +grub_squash_close (grub_file_t file) +{ + squash_unmount (file->data); + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_squash_mtime (grub_device_t dev, grub_int32_t *tm) +{ + struct grub_squash_data *data = 0; + + data = squash_mount (dev->disk); + if (! data) + return grub_errno; + *tm = grub_le_to_cpu32 (data->sb.creation_time); + squash_unmount (data); + return GRUB_ERR_NONE; +} + +static struct grub_fs grub_squash_fs = + { + .name = "squash4", + .fs_dir = grub_squash_dir, + .fs_open = grub_squash_open, + .fs_read = grub_squash_read, + .fs_close = grub_squash_close, + .fs_mtime = grub_squash_mtime, +#ifdef GRUB_UTIL + .reserved_first_sector = 0, + .blocklist_install = 0, +#endif + .next = 0 + }; + +GRUB_MOD_INIT(squash4) +{ + grub_fs_register (&grub_squash_fs); +} + +GRUB_MOD_FINI(squash4) +{ + grub_fs_unregister (&grub_squash_fs); +} + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/udf.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/udf.c new file mode 100644 index 0000000..dab046b --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/udf.c @@ -0,0 +1,1439 @@ +/* udf.c - Universal Disk Format filesystem. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +#define OFFSET_OF(TYPE, MEMBER) ((grub_size_t) &((TYPE *)0)->MEMBER) + +grub_uint32_t g_last_disk_read_sector = 0; +grub_uint32_t g_last_fe_tag_ident = 0; +grub_uint32_t g_last_icb_read_sector = 0; +grub_uint32_t g_last_icb_read_sector_tag_ident = 0; +grub_uint32_t g_last_fileattr_read_sector = 0; +grub_uint32_t g_last_fileattr_read_sector_tag_ident = 0; +grub_uint32_t g_last_fileattr_offset = 0; +grub_uint64_t g_last_pd_length_offset = 0; + +#define GRUB_UDF_MAX_PDS 2 +#define GRUB_UDF_MAX_PMS 6 + +#define U16 grub_le_to_cpu16 +#define U32 grub_le_to_cpu32 +#define U64 grub_le_to_cpu64 + +#define GRUB_UDF_TAG_IDENT_PVD 0x0001 +#define GRUB_UDF_TAG_IDENT_AVDP 0x0002 +#define GRUB_UDF_TAG_IDENT_VDP 0x0003 +#define GRUB_UDF_TAG_IDENT_IUVD 0x0004 +#define GRUB_UDF_TAG_IDENT_PD 0x0005 +#define GRUB_UDF_TAG_IDENT_LVD 0x0006 +#define GRUB_UDF_TAG_IDENT_USD 0x0007 +#define GRUB_UDF_TAG_IDENT_TD 0x0008 +#define GRUB_UDF_TAG_IDENT_LVID 0x0009 + +#define GRUB_UDF_TAG_IDENT_FSD 0x0100 +#define GRUB_UDF_TAG_IDENT_FID 0x0101 +#define GRUB_UDF_TAG_IDENT_AED 0x0102 +#define GRUB_UDF_TAG_IDENT_IE 0x0103 +#define GRUB_UDF_TAG_IDENT_TE 0x0104 +#define GRUB_UDF_TAG_IDENT_FE 0x0105 +#define GRUB_UDF_TAG_IDENT_EAHD 0x0106 +#define GRUB_UDF_TAG_IDENT_USE 0x0107 +#define GRUB_UDF_TAG_IDENT_SBD 0x0108 +#define GRUB_UDF_TAG_IDENT_PIE 0x0109 +#define GRUB_UDF_TAG_IDENT_EFE 0x010A + +#define GRUB_UDF_ICBTAG_TYPE_UNDEF 0x00 +#define GRUB_UDF_ICBTAG_TYPE_USE 0x01 +#define GRUB_UDF_ICBTAG_TYPE_PIE 0x02 +#define GRUB_UDF_ICBTAG_TYPE_IE 0x03 +#define GRUB_UDF_ICBTAG_TYPE_DIRECTORY 0x04 +#define GRUB_UDF_ICBTAG_TYPE_REGULAR 0x05 +#define GRUB_UDF_ICBTAG_TYPE_BLOCK 0x06 +#define GRUB_UDF_ICBTAG_TYPE_CHAR 0x07 +#define GRUB_UDF_ICBTAG_TYPE_EA 0x08 +#define GRUB_UDF_ICBTAG_TYPE_FIFO 0x09 +#define GRUB_UDF_ICBTAG_TYPE_SOCKET 0x0A +#define GRUB_UDF_ICBTAG_TYPE_TE 0x0B +#define GRUB_UDF_ICBTAG_TYPE_SYMLINK 0x0C +#define GRUB_UDF_ICBTAG_TYPE_STREAMDIR 0x0D + +#define GRUB_UDF_ICBTAG_FLAG_AD_MASK 0x0007 +#define GRUB_UDF_ICBTAG_FLAG_AD_SHORT 0x0000 +#define GRUB_UDF_ICBTAG_FLAG_AD_LONG 0x0001 +#define GRUB_UDF_ICBTAG_FLAG_AD_EXT 0x0002 +#define GRUB_UDF_ICBTAG_FLAG_AD_IN_ICB 0x0003 + +#define GRUB_UDF_EXT_NORMAL 0x00000000 +#define GRUB_UDF_EXT_NREC_ALLOC 0x40000000 +#define GRUB_UDF_EXT_NREC_NALLOC 0x80000000 +#define GRUB_UDF_EXT_MASK 0xC0000000 + +#define GRUB_UDF_FID_CHAR_HIDDEN 0x01 +#define GRUB_UDF_FID_CHAR_DIRECTORY 0x02 +#define GRUB_UDF_FID_CHAR_DELETED 0x04 +#define GRUB_UDF_FID_CHAR_PARENT 0x08 +#define GRUB_UDF_FID_CHAR_METADATA 0x10 + +#define GRUB_UDF_STD_IDENT_BEA01 "BEA01" +#define GRUB_UDF_STD_IDENT_BOOT2 "BOOT2" +#define GRUB_UDF_STD_IDENT_CD001 "CD001" +#define GRUB_UDF_STD_IDENT_CDW02 "CDW02" +#define GRUB_UDF_STD_IDENT_NSR02 "NSR02" +#define GRUB_UDF_STD_IDENT_NSR03 "NSR03" +#define GRUB_UDF_STD_IDENT_TEA01 "TEA01" + +#define GRUB_UDF_CHARSPEC_TYPE_CS0 0x00 +#define GRUB_UDF_CHARSPEC_TYPE_CS1 0x01 +#define GRUB_UDF_CHARSPEC_TYPE_CS2 0x02 +#define GRUB_UDF_CHARSPEC_TYPE_CS3 0x03 +#define GRUB_UDF_CHARSPEC_TYPE_CS4 0x04 +#define GRUB_UDF_CHARSPEC_TYPE_CS5 0x05 +#define GRUB_UDF_CHARSPEC_TYPE_CS6 0x06 +#define GRUB_UDF_CHARSPEC_TYPE_CS7 0x07 +#define GRUB_UDF_CHARSPEC_TYPE_CS8 0x08 + +#define GRUB_UDF_PARTMAP_TYPE_1 1 +#define GRUB_UDF_PARTMAP_TYPE_2 2 + +struct grub_udf_lb_addr +{ + grub_uint32_t block_num; + grub_uint16_t part_ref; +} GRUB_PACKED; + +struct grub_udf_short_ad +{ + grub_uint32_t length; + grub_uint32_t position; +} GRUB_PACKED; + +struct grub_udf_long_ad +{ + grub_uint32_t length; + struct grub_udf_lb_addr block; + grub_uint8_t imp_use[6]; +} GRUB_PACKED; + +struct grub_udf_extent_ad +{ + grub_uint32_t length; + grub_uint32_t start; +} GRUB_PACKED; + +struct grub_udf_charspec +{ + grub_uint8_t charset_type; + grub_uint8_t charset_info[63]; +} GRUB_PACKED; + +struct grub_udf_timestamp +{ + grub_uint16_t type_and_timezone; + grub_uint16_t year; + grub_uint8_t month; + grub_uint8_t day; + grub_uint8_t hour; + grub_uint8_t minute; + grub_uint8_t second; + grub_uint8_t centi_seconds; + grub_uint8_t hundreds_of_micro_seconds; + grub_uint8_t micro_seconds; +} GRUB_PACKED; + +struct grub_udf_regid +{ + grub_uint8_t flags; + grub_uint8_t ident[23]; + grub_uint8_t ident_suffix[8]; +} GRUB_PACKED; + +struct grub_udf_tag +{ + grub_uint16_t tag_ident; + grub_uint16_t desc_version; + grub_uint8_t tag_checksum; + grub_uint8_t reserved; + grub_uint16_t tag_serial_number; + grub_uint16_t desc_crc; + grub_uint16_t desc_crc_length; + grub_uint32_t tag_location; +} GRUB_PACKED; + +struct grub_udf_fileset +{ + struct grub_udf_tag tag; + struct grub_udf_timestamp datetime; + grub_uint16_t interchange_level; + grub_uint16_t max_interchange_level; + grub_uint32_t charset_list; + grub_uint32_t max_charset_list; + grub_uint32_t fileset_num; + grub_uint32_t fileset_desc_num; + struct grub_udf_charspec vol_charset; + grub_uint8_t vol_ident[128]; + struct grub_udf_charspec fileset_charset; + grub_uint8_t fileset_ident[32]; + grub_uint8_t copyright_file_ident[32]; + grub_uint8_t abstract_file_ident[32]; + struct grub_udf_long_ad root_icb; + struct grub_udf_regid domain_ident; + struct grub_udf_long_ad next_ext; + struct grub_udf_long_ad streamdir_icb; +} GRUB_PACKED; + +struct grub_udf_icbtag +{ + grub_uint32_t prior_recorded_num_direct_entries; + grub_uint16_t strategy_type; + grub_uint16_t strategy_parameter; + grub_uint16_t num_entries; + grub_uint8_t reserved; + grub_uint8_t file_type; + struct grub_udf_lb_addr parent_idb; + grub_uint16_t flags; +} GRUB_PACKED; + +struct grub_udf_file_ident +{ + struct grub_udf_tag tag; + grub_uint16_t version_num; + grub_uint8_t characteristics; +#define MAX_FILE_IDENT_LENGTH 256 + grub_uint8_t file_ident_length; + struct grub_udf_long_ad icb; + grub_uint16_t imp_use_length; +} GRUB_PACKED; + +struct grub_udf_file_entry +{ + struct grub_udf_tag tag; + struct grub_udf_icbtag icbtag; + grub_uint32_t uid; + grub_uint32_t gid; + grub_uint32_t permissions; + grub_uint16_t link_count; + grub_uint8_t record_format; + grub_uint8_t record_display_attr; + grub_uint32_t record_length; + grub_uint64_t file_size; + grub_uint64_t blocks_recorded; + struct grub_udf_timestamp access_time; + struct grub_udf_timestamp modification_time; + struct grub_udf_timestamp attr_time; + grub_uint32_t checkpoint; + struct grub_udf_long_ad extended_attr_idb; + struct grub_udf_regid imp_ident; + grub_uint64_t unique_id; + grub_uint32_t ext_attr_length; + grub_uint32_t alloc_descs_length; + grub_uint8_t ext_attr[0]; +} GRUB_PACKED; + +struct grub_udf_extended_file_entry +{ + struct grub_udf_tag tag; + struct grub_udf_icbtag icbtag; + grub_uint32_t uid; + grub_uint32_t gid; + grub_uint32_t permissions; + grub_uint16_t link_count; + grub_uint8_t record_format; + grub_uint8_t record_display_attr; + grub_uint32_t record_length; + grub_uint64_t file_size; + grub_uint64_t object_size; + grub_uint64_t blocks_recorded; + struct grub_udf_timestamp access_time; + struct grub_udf_timestamp modification_time; + struct grub_udf_timestamp create_time; + struct grub_udf_timestamp attr_time; + grub_uint32_t checkpoint; + grub_uint32_t reserved; + struct grub_udf_long_ad extended_attr_icb; + struct grub_udf_long_ad streamdir_icb; + struct grub_udf_regid imp_ident; + grub_uint64_t unique_id; + grub_uint32_t ext_attr_length; + grub_uint32_t alloc_descs_length; + grub_uint8_t ext_attr[0]; +} GRUB_PACKED; + +struct grub_udf_vrs +{ + grub_uint8_t type; + grub_uint8_t magic[5]; + grub_uint8_t version; +} GRUB_PACKED; + +struct grub_udf_avdp +{ + struct grub_udf_tag tag; + struct grub_udf_extent_ad vds; +} GRUB_PACKED; + +struct grub_udf_pd +{ + struct grub_udf_tag tag; + grub_uint32_t seq_num; + grub_uint16_t flags; + grub_uint16_t part_num; + struct grub_udf_regid contents; + grub_uint8_t contents_use[128]; + grub_uint32_t access_type; + grub_uint32_t start; + grub_uint32_t length; +} GRUB_PACKED; + +struct grub_udf_partmap +{ + grub_uint8_t type; + grub_uint8_t length; + union + { + struct + { + grub_uint16_t seq_num; + grub_uint16_t part_num; + } type1; + + struct + { + grub_uint8_t ident[62]; + } type2; + }; +} GRUB_PACKED; + +struct grub_udf_pvd +{ + struct grub_udf_tag tag; + grub_uint32_t seq_num; + grub_uint32_t pvd_num; + grub_uint8_t ident[32]; + grub_uint16_t vol_seq_num; + grub_uint16_t max_vol_seq_num; + grub_uint16_t interchange_level; + grub_uint16_t max_interchange_level; + grub_uint32_t charset_list; + grub_uint32_t max_charset_list; + grub_uint8_t volset_ident[128]; + struct grub_udf_charspec desc_charset; + struct grub_udf_charspec expl_charset; + struct grub_udf_extent_ad vol_abstract; + struct grub_udf_extent_ad vol_copyright; + struct grub_udf_regid app_ident; + struct grub_udf_timestamp recording_time; + struct grub_udf_regid imp_ident; + grub_uint8_t imp_use[64]; + grub_uint32_t pred_vds_loc; + grub_uint16_t flags; + grub_uint8_t reserved[22]; +} GRUB_PACKED; + +struct grub_udf_lvd +{ + struct grub_udf_tag tag; + grub_uint32_t seq_num; + struct grub_udf_charspec charset; + grub_uint8_t ident[128]; + grub_uint32_t bsize; + struct grub_udf_regid domain_ident; + struct grub_udf_long_ad root_fileset; + grub_uint32_t map_table_length; + grub_uint32_t num_part_maps; + struct grub_udf_regid imp_ident; + grub_uint8_t imp_use[128]; + struct grub_udf_extent_ad integrity_seq_ext; + grub_uint8_t part_maps[1608]; +} GRUB_PACKED; + +struct grub_udf_aed +{ + struct grub_udf_tag tag; + grub_uint32_t prev_ae; + grub_uint32_t ae_len; +} GRUB_PACKED; + +struct grub_udf_data +{ + grub_disk_t disk; + struct grub_udf_pvd pvd; + struct grub_udf_lvd lvd; + struct grub_udf_pd pds[GRUB_UDF_MAX_PDS]; + struct grub_udf_partmap *pms[GRUB_UDF_MAX_PMS]; + struct grub_udf_long_ad root_icb; + int npd, npm, lbshift; +}; + +struct grub_fshelp_node +{ + struct grub_udf_data *data; + int part_ref; + union + { + struct grub_udf_file_entry fe; + struct grub_udf_extended_file_entry efe; + char raw[0]; + } block; +}; + +static inline grub_size_t +get_fshelp_size (struct grub_udf_data *data) +{ + struct grub_fshelp_node *x = NULL; + return sizeof (*x) + + (1 << (GRUB_DISK_SECTOR_BITS + + data->lbshift)) - sizeof (x->block); +} + +static grub_dl_t my_mod; + +static grub_uint32_t +grub_udf_get_block (struct grub_udf_data *data, + grub_uint16_t part_ref, grub_uint32_t block) +{ + part_ref = U16 (part_ref); + + if (part_ref >= data->npm) + { + grub_error (GRUB_ERR_BAD_FS, "invalid part ref"); + return 0; + } + + return (U32 (data->pds[data->pms[part_ref]->type1.part_num].start) + + U32 (block)); +} + +static grub_err_t +grub_udf_read_icb (struct grub_udf_data *data, + struct grub_udf_long_ad *icb, + struct grub_fshelp_node *node) +{ + grub_uint32_t block; + + block = grub_udf_get_block (data, + icb->block.part_ref, + icb->block.block_num); + + if (grub_errno) + return grub_errno; + + if (grub_disk_read (data->disk, block << data->lbshift, 0, + 1 << (GRUB_DISK_SECTOR_BITS + + data->lbshift), + &node->block)) + return grub_errno; + + g_last_disk_read_sector = block; + g_last_fe_tag_ident = U16(node->block.fe.tag.tag_ident); + + if ((U16 (node->block.fe.tag.tag_ident) != GRUB_UDF_TAG_IDENT_FE) && + (U16 (node->block.fe.tag.tag_ident) != GRUB_UDF_TAG_IDENT_EFE)) + return grub_error (GRUB_ERR_BAD_FS, "invalid fe/efe descriptor"); + + node->part_ref = icb->block.part_ref; + node->data = data; + return 0; +} + +static grub_disk_addr_t +grub_udf_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) +{ + char *buf = NULL; + char *ptr; + grub_ssize_t len; + grub_disk_addr_t filebytes; + + switch (U16 (node->block.fe.tag.tag_ident)) + { + case GRUB_UDF_TAG_IDENT_FE: + ptr = (char *) &node->block.fe.ext_attr[0] + U32 (node->block.fe.ext_attr_length); + len = U32 (node->block.fe.alloc_descs_length); + break; + + case GRUB_UDF_TAG_IDENT_EFE: + ptr = (char *) &node->block.efe.ext_attr[0] + U32 (node->block.efe.ext_attr_length); + len = U32 (node->block.efe.alloc_descs_length); + break; + + default: + grub_error (GRUB_ERR_BAD_FS, "invalid file entry"); + return 0; + } + + if ((U16 (node->block.fe.icbtag.flags) & GRUB_UDF_ICBTAG_FLAG_AD_MASK) + == GRUB_UDF_ICBTAG_FLAG_AD_SHORT) + { + struct grub_udf_short_ad *ad = (struct grub_udf_short_ad *) ptr; + + filebytes = fileblock * U32 (node->data->lvd.bsize); + while (len >= (grub_ssize_t) sizeof (struct grub_udf_short_ad)) + { + grub_uint32_t adlen = U32 (ad->length) & 0x3fffffff; + grub_uint32_t adtype = U32 (ad->length) >> 30; + if (adtype == 3) + { + struct grub_udf_aed *extension; + grub_disk_addr_t sec = grub_udf_get_block(node->data, + node->part_ref, + ad->position); + if (!buf) + { + buf = grub_malloc (U32 (node->data->lvd.bsize)); + if (!buf) + return 0; + } + if (grub_disk_read (node->data->disk, sec << node->data->lbshift, + 0, adlen, buf)) + goto fail; + + extension = (struct grub_udf_aed *) buf; + if (U16 (extension->tag.tag_ident) != GRUB_UDF_TAG_IDENT_AED) + { + grub_error (GRUB_ERR_BAD_FS, "invalid aed tag"); + goto fail; + } + + len = U32 (extension->ae_len); + ad = (struct grub_udf_short_ad *) + (buf + sizeof (struct grub_udf_aed)); + continue; + } + + if (filebytes < adlen) + { + grub_uint32_t ad_pos = ad->position; + grub_free (buf); + return ((U32 (ad_pos) & GRUB_UDF_EXT_MASK) ? 0 : + (grub_udf_get_block (node->data, node->part_ref, ad_pos) + + (filebytes >> (GRUB_DISK_SECTOR_BITS + + node->data->lbshift)))); + } + + filebytes -= adlen; + ad++; + len -= sizeof (struct grub_udf_short_ad); + } + } + else + { + struct grub_udf_long_ad *ad = (struct grub_udf_long_ad *) ptr; + + filebytes = fileblock * U32 (node->data->lvd.bsize); + while (len >= (grub_ssize_t) sizeof (struct grub_udf_long_ad)) + { + grub_uint32_t adlen = U32 (ad->length) & 0x3fffffff; + grub_uint32_t adtype = U32 (ad->length) >> 30; + if (adtype == 3) + { + struct grub_udf_aed *extension; + grub_disk_addr_t sec = grub_udf_get_block(node->data, + ad->block.part_ref, + ad->block.block_num); + if (!buf) + { + buf = grub_malloc (U32 (node->data->lvd.bsize)); + if (!buf) + return 0; + } + if (grub_disk_read (node->data->disk, sec << node->data->lbshift, + 0, adlen, buf)) + goto fail; + + extension = (struct grub_udf_aed *) buf; + if (U16 (extension->tag.tag_ident) != GRUB_UDF_TAG_IDENT_AED) + { + grub_error (GRUB_ERR_BAD_FS, "invalid aed tag"); + goto fail; + } + + len = U32 (extension->ae_len); + ad = (struct grub_udf_long_ad *) + (buf + sizeof (struct grub_udf_aed)); + continue; + } + + if (filebytes < adlen) + { + grub_uint32_t ad_block_num = ad->block.block_num; + grub_uint32_t ad_part_ref = ad->block.part_ref; + grub_free (buf); + return ((U32 (ad_block_num) & GRUB_UDF_EXT_MASK) ? 0 : + (grub_udf_get_block (node->data, ad_part_ref, + ad_block_num) + + (filebytes >> (GRUB_DISK_SECTOR_BITS + + node->data->lbshift)))); + } + + filebytes -= adlen; + ad++; + len -= sizeof (struct grub_udf_long_ad); + } + } + +fail: + grub_free (buf); + + return 0; +} + +static grub_ssize_t +grub_udf_read_file (grub_fshelp_node_t node, + grub_disk_read_hook_t read_hook, void *read_hook_data, + grub_off_t pos, grub_size_t len, char *buf) +{ + switch (U16 (node->block.fe.icbtag.flags) & GRUB_UDF_ICBTAG_FLAG_AD_MASK) + { + case GRUB_UDF_ICBTAG_FLAG_AD_IN_ICB: + { + char *ptr; + + ptr = ((U16 (node->block.fe.tag.tag_ident) == GRUB_UDF_TAG_IDENT_FE) ? + ((char *) &node->block.fe.ext_attr[0] + + U32 (node->block.fe.ext_attr_length)) : + ((char *) &node->block.efe.ext_attr[0] + + U32 (node->block.efe.ext_attr_length))); + + grub_memcpy (buf, ptr + pos, len); + + return len; + } + + case GRUB_UDF_ICBTAG_FLAG_AD_EXT: + grub_error (GRUB_ERR_BAD_FS, "invalid extent type"); + return 0; + } + + return grub_fshelp_read_file (node->data->disk, node, + read_hook, read_hook_data, + pos, len, buf, grub_udf_read_block, + U64 (node->block.fe.file_size), + node->data->lbshift, 0); +} + +static unsigned sblocklist[] = { 256, 512, 0 }; + +static struct grub_udf_data * +grub_udf_mount (grub_disk_t disk) +{ + struct grub_udf_data *data = 0; + struct grub_udf_fileset root_fs; + unsigned *sblklist; + grub_uint32_t block, vblock; + int i, lbshift; + + data = grub_malloc (sizeof (struct grub_udf_data)); + if (!data) + return 0; + + data->disk = disk; + + /* Search for Anchor Volume Descriptor Pointer (AVDP) + * and determine logical block size. */ + block = 0; + for (lbshift = 0; lbshift < 4; lbshift++) + { + for (sblklist = sblocklist; *sblklist; sblklist++) + { + struct grub_udf_avdp avdp; + + if (grub_disk_read (disk, *sblklist << lbshift, 0, + sizeof (struct grub_udf_avdp), &avdp)) + { + grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem"); + goto fail; + } + + if (U16 (avdp.tag.tag_ident) == GRUB_UDF_TAG_IDENT_AVDP && + U32 (avdp.tag.tag_location) == *sblklist) + { + block = U32 (avdp.vds.start); + break; + } + } + + if (block) + break; + } + + if (!block) + { + grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem"); + goto fail; + } + data->lbshift = lbshift; + + /* Search for Volume Recognition Sequence (VRS). */ + for (vblock = (32767 >> (lbshift + GRUB_DISK_SECTOR_BITS)) + 1;; + vblock += (2047 >> (lbshift + GRUB_DISK_SECTOR_BITS)) + 1) + { + struct grub_udf_vrs vrs; + + if (grub_disk_read (disk, vblock << lbshift, 0, + sizeof (struct grub_udf_vrs), &vrs)) + { + grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem"); + goto fail; + } + + if ((!grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_NSR03, 5)) || + (!grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_NSR02, 5))) + break; + + if ((grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_BEA01, 5)) && + (grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_BOOT2, 5)) && + (grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_CD001, 5)) && + (grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_CDW02, 5)) && + (grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_TEA01, 5))) + { + grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem"); + goto fail; + } + } + + data->npd = data->npm = 0; + /* Locate Partition Descriptor (PD) and Logical Volume Descriptor (LVD). */ + while (1) + { + struct grub_udf_tag tag; + + if (grub_disk_read (disk, block << lbshift, 0, + sizeof (struct grub_udf_tag), &tag)) + { + grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem"); + goto fail; + } + + tag.tag_ident = U16 (tag.tag_ident); + if (tag.tag_ident == GRUB_UDF_TAG_IDENT_PVD) + { + if (grub_disk_read (disk, block << lbshift, 0, + sizeof (struct grub_udf_pvd), + &data->pvd)) + { + grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem"); + goto fail; + } + } + else if (tag.tag_ident == GRUB_UDF_TAG_IDENT_PD) + { + if (data->npd >= GRUB_UDF_MAX_PDS) + { + grub_error (GRUB_ERR_BAD_FS, "too many PDs"); + goto fail; + } + + if (grub_disk_read (disk, block << lbshift, 0, + sizeof (struct grub_udf_pd), + &data->pds[data->npd])) + { + grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem"); + goto fail; + } + + g_last_pd_length_offset = (block << lbshift) * 512 + OFFSET_OF(struct grub_udf_pd, length); + + data->npd++; + } + else if (tag.tag_ident == GRUB_UDF_TAG_IDENT_LVD) + { + int k; + + struct grub_udf_partmap *ppm; + + if (grub_disk_read (disk, block << lbshift, 0, + sizeof (struct grub_udf_lvd), + &data->lvd)) + { + grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem"); + goto fail; + } + + if (data->npm + U32 (data->lvd.num_part_maps) > GRUB_UDF_MAX_PMS) + { + grub_error (GRUB_ERR_BAD_FS, "too many partition maps"); + goto fail; + } + + ppm = (struct grub_udf_partmap *) &data->lvd.part_maps; + for (k = U32 (data->lvd.num_part_maps); k > 0; k--) + { + if (ppm->type != GRUB_UDF_PARTMAP_TYPE_1) + { + grub_error (GRUB_ERR_BAD_FS, "partmap type not supported"); + goto fail; + } + + data->pms[data->npm++] = ppm; + ppm = (struct grub_udf_partmap *) ((char *) ppm + + U32 (ppm->length)); + } + } + else if (tag.tag_ident > GRUB_UDF_TAG_IDENT_TD) + { + grub_error (GRUB_ERR_BAD_FS, "invalid tag ident"); + goto fail; + } + else if (tag.tag_ident == GRUB_UDF_TAG_IDENT_TD) + break; + + block++; + } + + for (i = 0; i < data->npm; i++) + { + int j; + + for (j = 0; j < data->npd; j++) + if (data->pms[i]->type1.part_num == data->pds[j].part_num) + { + data->pms[i]->type1.part_num = j; + break; + } + + if (j == data->npd) + { + grub_error (GRUB_ERR_BAD_FS, "can\'t find PD"); + goto fail; + } + } + + block = grub_udf_get_block (data, + data->lvd.root_fileset.block.part_ref, + data->lvd.root_fileset.block.block_num); + + if (grub_errno) + goto fail; + + if (grub_disk_read (disk, block << lbshift, 0, + sizeof (struct grub_udf_fileset), &root_fs)) + { + grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem"); + goto fail; + } + + if (U16 (root_fs.tag.tag_ident) != GRUB_UDF_TAG_IDENT_FSD) + { + grub_error (GRUB_ERR_BAD_FS, "invalid fileset descriptor"); + goto fail; + } + + data->root_icb = root_fs.root_icb; + + return data; + +fail: + grub_free (data); + return 0; +} + +#ifdef GRUB_UTIL +grub_disk_addr_t +grub_udf_get_cluster_sector (grub_disk_t disk, grub_uint64_t *sec_per_lcn) +{ + grub_disk_addr_t ret; + static struct grub_udf_data *data; + + data = grub_udf_mount (disk); + if (!data) + return 0; + + ret = U32 (data->pds[data->pms[0]->type1.part_num].start); + *sec_per_lcn = 1ULL << data->lbshift; + grub_free (data); + return ret; +} +#endif + +static char * +read_string (const grub_uint8_t *raw, grub_size_t sz, char *outbuf) +{ + grub_uint16_t *utf16 = NULL; + grub_size_t utf16len = 0; + + if (sz == 0) + return NULL; + + if (raw[0] != 8 && raw[0] != 16) + return NULL; + + if (raw[0] == 8) + { + unsigned i; + utf16len = sz - 1; + utf16 = grub_malloc (utf16len * sizeof (utf16[0])); + if (!utf16) + return NULL; + for (i = 0; i < utf16len; i++) + utf16[i] = raw[i + 1]; + } + if (raw[0] == 16) + { + unsigned i; + utf16len = (sz - 1) / 2; + utf16 = grub_malloc (utf16len * sizeof (utf16[0])); + if (!utf16) + return NULL; + for (i = 0; i < utf16len; i++) + utf16[i] = (raw[2 * i + 1] << 8) | raw[2*i + 2]; + } + if (!outbuf) + outbuf = grub_malloc (utf16len * GRUB_MAX_UTF8_PER_UTF16 + 1); + if (outbuf) + *grub_utf16_to_utf8 ((grub_uint8_t *) outbuf, utf16, utf16len) = '\0'; + grub_free (utf16); + return outbuf; +} + +static char * +read_dstring (const grub_uint8_t *raw, grub_size_t sz) +{ + grub_size_t len; + + if (raw[0] == 0) { + char *outbuf = grub_malloc (1); + if (!outbuf) + return NULL; + outbuf[0] = 0; + return outbuf; + } + + len = raw[sz - 1]; + if (len > sz - 1) + len = sz - 1; + return read_string (raw, len, NULL); +} + +static int +grub_udf_iterate_dir (grub_fshelp_node_t dir, + grub_fshelp_iterate_dir_hook_t hook, void *hook_data) +{ + grub_fshelp_node_t child; + struct grub_udf_file_ident dirent; + grub_off_t offset = 0; + + child = grub_malloc (get_fshelp_size (dir->data)); + if (!child) + return 0; + + /* The current directory is not stored. */ + grub_memcpy (child, dir, get_fshelp_size (dir->data)); + + if (hook (".", GRUB_FSHELP_DIR, child, hook_data)) + return 1; + + while (offset < U64 (dir->block.fe.file_size)) + { + if (grub_udf_read_file (dir, 0, 0, offset, sizeof (dirent), + (char *) &dirent) != sizeof (dirent)) + return 0; + + if (U16 (dirent.tag.tag_ident) != GRUB_UDF_TAG_IDENT_FID) + { + grub_error (GRUB_ERR_BAD_FS, "invalid fid tag"); + return 0; + } + + offset += sizeof (dirent) + U16 (dirent.imp_use_length); + if (!(dirent.characteristics & GRUB_UDF_FID_CHAR_DELETED)) + { + child = grub_malloc (get_fshelp_size (dir->data)); + if (!child) + return 0; + + if (grub_udf_read_icb (dir->data, &dirent.icb, child)) + return 0; + + g_last_icb_read_sector = g_last_disk_read_sector; + g_last_icb_read_sector_tag_ident = g_last_fe_tag_ident; + if (dirent.characteristics & GRUB_UDF_FID_CHAR_PARENT) + { + /* This is the parent directory. */ + if (hook ("..", GRUB_FSHELP_DIR, child, hook_data)) + return 1; + } + else + { + enum grub_fshelp_filetype type; + char *filename; + grub_uint8_t raw[MAX_FILE_IDENT_LENGTH]; + + type = ((dirent.characteristics & GRUB_UDF_FID_CHAR_DIRECTORY) ? + (GRUB_FSHELP_DIR) : (GRUB_FSHELP_REG)); + if (child->block.fe.icbtag.file_type == GRUB_UDF_ICBTAG_TYPE_SYMLINK) + type = GRUB_FSHELP_SYMLINK; + + if ((grub_udf_read_file (dir, 0, 0, offset, + dirent.file_ident_length, + (char *) raw)) + != dirent.file_ident_length) + return 0; + + filename = read_string (raw, dirent.file_ident_length, 0); + if (!filename) + grub_print_error (); + + if (filename && hook (filename, type, child, hook_data)) + { + g_last_fileattr_read_sector = g_last_icb_read_sector; + g_last_fileattr_read_sector_tag_ident = g_last_icb_read_sector_tag_ident; + g_last_fileattr_offset = (grub_uint32_t)((child->block.fe.ext_attr + child->block.fe.ext_attr_length) - (grub_uint8_t *)&(child->block.fe)); + grub_free (filename); + return 1; + } + grub_free (filename); + } + } + + /* Align to dword boundary. */ + offset = (offset + dirent.file_ident_length + 3) & (~3); + } + + return 0; +} + +static char * +grub_udf_read_symlink (grub_fshelp_node_t node) +{ + grub_size_t sz = U64 (node->block.fe.file_size); + grub_uint8_t *raw; + const grub_uint8_t *ptr; + char *out, *optr; + + if (sz < 4) + return NULL; + raw = grub_malloc (sz); + if (!raw) + return NULL; + if (grub_udf_read_file (node, NULL, NULL, 0, sz, (char *) raw) < 0) + { + grub_free (raw); + return NULL; + } + + out = grub_malloc (sz * 2 + 1); + if (!out) + { + grub_free (raw); + return NULL; + } + + optr = out; + + for (ptr = raw; ptr < raw + sz; ) + { + grub_size_t s; + if ((grub_size_t) (ptr - raw + 4) > sz) + goto fail; + if (!(ptr[2] == 0 && ptr[3] == 0)) + goto fail; + s = 4 + ptr[1]; + if ((grub_size_t) (ptr - raw + s) > sz) + goto fail; + switch (*ptr) + { + case 1: + if (ptr[1]) + goto fail; + /* Fallthrough. */ + case 2: + /* in 4 bytes. out: 1 byte. */ + optr = out; + *optr++ = '/'; + break; + case 3: + /* in 4 bytes. out: 3 bytes. */ + if (optr != out) + *optr++ = '/'; + *optr++ = '.'; + *optr++ = '.'; + break; + case 4: + /* in 4 bytes. out: 2 bytes. */ + if (optr != out) + *optr++ = '/'; + *optr++ = '.'; + break; + case 5: + /* in 4 + n bytes. out, at most: 1 + 2 * n bytes. */ + if (optr != out) + *optr++ = '/'; + if (!read_string (ptr + 4, s - 4, optr)) + goto fail; + optr += grub_strlen (optr); + break; + default: + goto fail; + } + ptr += s; + } + *optr = 0; + grub_free (raw); + return out; + + fail: + grub_free (raw); + grub_free (out); + grub_error (GRUB_ERR_BAD_FS, "invalid symlink"); + return NULL; +} + +/* Context for grub_udf_dir. */ +struct grub_udf_dir_ctx +{ + grub_fs_dir_hook_t hook; + void *hook_data; +}; + +/* Helper for grub_udf_dir. */ +static int +grub_udf_dir_iter (const char *filename, enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node, void *data) +{ + struct grub_udf_dir_ctx *ctx = data; + struct grub_dirhook_info info; + const struct grub_udf_timestamp *tstamp = NULL; + + grub_memset (&info, 0, sizeof (info)); + info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); + if (U16 (node->block.fe.tag.tag_ident) == GRUB_UDF_TAG_IDENT_FE) + tstamp = &node->block.fe.modification_time; + else if (U16 (node->block.fe.tag.tag_ident) == GRUB_UDF_TAG_IDENT_EFE) + tstamp = &node->block.efe.modification_time; + + if (tstamp && (U16 (tstamp->type_and_timezone) & 0xf000) == 0x1000) + { + grub_int16_t tz; + struct grub_datetime datetime; + + datetime.year = U16 (tstamp->year); + datetime.month = tstamp->month; + datetime.day = tstamp->day; + datetime.hour = tstamp->hour; + datetime.minute = tstamp->minute; + datetime.second = tstamp->second; + + tz = U16 (tstamp->type_and_timezone) & 0xfff; + if (tz & 0x800) + tz |= 0xf000; + if (tz == -2047) + tz = 0; + + info.mtimeset = !!grub_datetime2unixtime (&datetime, &info.mtime); + + info.mtime -= 60 * tz; + } + if (!info.dir) + info.size = U64 (node->block.fe.file_size); + grub_free (node); + return ctx->hook (filename, &info, ctx->hook_data); +} + +static grub_err_t +grub_udf_dir (grub_device_t device, const char *path, + grub_fs_dir_hook_t hook, void *hook_data) +{ + struct grub_udf_dir_ctx ctx = { hook, hook_data }; + struct grub_udf_data *data = 0; + struct grub_fshelp_node *rootnode = 0; + struct grub_fshelp_node *foundnode = 0; + + grub_dl_ref (my_mod); + + data = grub_udf_mount (device->disk); + if (!data) + goto fail; + + rootnode = grub_malloc (get_fshelp_size (data)); + if (!rootnode) + goto fail; + + if (grub_udf_read_icb (data, &data->root_icb, rootnode)) + goto fail; + + if (grub_fshelp_find_file (path, rootnode, + &foundnode, + grub_udf_iterate_dir, grub_udf_read_symlink, + GRUB_FSHELP_DIR)) + goto fail; + + grub_udf_iterate_dir (foundnode, grub_udf_dir_iter, &ctx); + + if (foundnode != rootnode) + grub_free (foundnode); + +fail: + grub_free (rootnode); + + grub_free (data); + + grub_dl_unref (my_mod); + + return grub_errno; +} + +static grub_err_t +grub_udf_open (struct grub_file *file, const char *name) +{ + struct grub_udf_data *data; + struct grub_fshelp_node *rootnode = 0; + struct grub_fshelp_node *foundnode; + + grub_dl_ref (my_mod); + + data = grub_udf_mount (file->device->disk); + if (!data) + goto fail; + + rootnode = grub_malloc (get_fshelp_size (data)); + if (!rootnode) + goto fail; + + if (grub_udf_read_icb (data, &data->root_icb, rootnode)) + goto fail; + + if (grub_fshelp_find_file (name, rootnode, + &foundnode, + grub_udf_iterate_dir, grub_udf_read_symlink, + GRUB_FSHELP_REG)) + goto fail; + + file->data = foundnode; + file->offset = 0; + file->size = U64 (foundnode->block.fe.file_size); + + grub_free (rootnode); + + return 0; + +fail: + grub_dl_unref (my_mod); + + grub_free (data); + grub_free (rootnode); + + return grub_errno; +} + +static grub_ssize_t +grub_udf_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_fshelp_node *node = (struct grub_fshelp_node *) file->data; + + return grub_udf_read_file (node, file->read_hook, file->read_hook_data, + file->offset, len, buf); +} + +static grub_err_t +grub_udf_close (grub_file_t file) +{ + if (file->data) + { + struct grub_fshelp_node *node = (struct grub_fshelp_node *) file->data; + + grub_free (node->data); + grub_free (node); + } + + grub_dl_unref (my_mod); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_udf_label (grub_device_t device, char **label) +{ + struct grub_udf_data *data; + data = grub_udf_mount (device->disk); + + if (data) + { + *label = read_dstring (data->lvd.ident, sizeof (data->lvd.ident)); + grub_free (data); + } + else + *label = 0; + + return grub_errno; +} + +static char * +gen_uuid_from_volset (char *volset_ident) +{ + grub_size_t i; + grub_size_t len; + grub_size_t nonhexpos; + grub_uint8_t buf[17]; + char *uuid; + + len = grub_strlen (volset_ident); + if (len < 8) + return NULL; + + uuid = grub_malloc (17); + if (!uuid) + return NULL; + + if (len > 16) + len = 16; + + grub_memset (buf, 0, sizeof (buf)); + grub_memcpy (buf, volset_ident, len); + + nonhexpos = 16; + for (i = 0; i < 16; ++i) + { + if (!grub_isxdigit (buf[i])) + { + nonhexpos = i; + break; + } + } + + if (nonhexpos < 8) + { + grub_snprintf (uuid, 17, "%02x%02x%02x%02x%02x%02x%02x%02x", + buf[0], buf[1], buf[2], buf[3], + buf[4], buf[5], buf[6], buf[7]); + } + else if (nonhexpos < 16) + { + for (i = 0; i < 8; ++i) + uuid[i] = grub_tolower (buf[i]); + grub_snprintf (uuid+8, 9, "%02x%02x%02x%02x", + buf[8], buf[9], buf[10], buf[11]); + } + else + { + for (i = 0; i < 16; ++i) + uuid[i] = grub_tolower (buf[i]); + uuid[16] = 0; + } + + return uuid; +} + +static grub_err_t +grub_udf_uuid (grub_device_t device, char **uuid) +{ + char *volset_ident; + struct grub_udf_data *data; + data = grub_udf_mount (device->disk); + + if (data) + { + volset_ident = read_dstring (data->pvd.volset_ident, sizeof (data->pvd.volset_ident)); + if (volset_ident) + { + *uuid = gen_uuid_from_volset (volset_ident); + grub_free (volset_ident); + } + else + *uuid = 0; + grub_free (data); + } + else + *uuid = 0; + + return grub_errno; +} + +grub_uint64_t grub_udf_get_file_offset(grub_file_t file) +{ + grub_disk_addr_t sector; + struct grub_fshelp_node *node = (struct grub_fshelp_node *)file->data; + + sector = grub_udf_read_block(node, 0); + + return 512 * (sector << node->data->lbshift); +} + +grub_uint64_t grub_udf_get_last_pd_size_offset(void) +{ + return g_last_pd_length_offset; +} + +grub_uint64_t grub_udf_get_last_file_attr_offset +( + grub_file_t file, + grub_uint32_t *startBlock, + grub_uint64_t *fe_entry_size_offset +) +{ + grub_uint64_t attr_offset; + struct grub_fshelp_node *node; + struct grub_udf_data *data; + + node = (struct grub_fshelp_node *)file->data; + data = node->data; + + *startBlock = data->pds[data->pms[0]->type1.part_num].start; + + attr_offset = g_last_fileattr_read_sector * 2048 + g_last_fileattr_offset; + + if (GRUB_UDF_TAG_IDENT_FE == g_last_fileattr_read_sector_tag_ident) + { + *fe_entry_size_offset = g_last_fileattr_read_sector * 2048 + OFFSET_OF(struct grub_udf_file_entry, file_size); + } + else + { + *fe_entry_size_offset = g_last_fileattr_read_sector * 2048 + OFFSET_OF(struct grub_udf_extended_file_entry, file_size); + } + + return attr_offset; +} + +static struct grub_fs grub_udf_fs = { + .name = "udf", + .fs_dir = grub_udf_dir, + .fs_open = grub_udf_open, + .fs_read = grub_udf_read, + .fs_close = grub_udf_close, + .fs_label = grub_udf_label, + .fs_uuid = grub_udf_uuid, +#ifdef GRUB_UTIL + .reserved_first_sector = 1, + .blocklist_install = 1, +#endif + .next = 0 +}; + +GRUB_MOD_INIT (udf) +{ + grub_fs_register (&grub_udf_fs); + my_mod = mod; +} + +GRUB_MOD_FINI (udf) +{ + grub_fs_unregister (&grub_udf_fs); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/xfs.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/xfs.c new file mode 100644 index 0000000..3e1cb78 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/xfs.c @@ -0,0 +1,1356 @@ +/* xfs.c - XFS. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +#define NSEC_PER_SEC ((grub_int64_t) 1000000000) + +// GRUB 2.04 doesn't have safemath.h +// #include + +// gcc < 5.1 doesn't support __builtin_add_overflow and __builtin_mul_overflow +// #define grub_add(a, b, res) __builtin_add_overflow(a, b, res) +// #define grub_mul(a, b, res) __builtin_mul_overflow(a, b, res) +// Warning: This is unsafe! +#define grub_add(a, b, res) ({ *(res) = (a) + (b); 0; }) + +#define grub_mul(a, b, res) ({ *(res) = (a) * (b); 0; }) + +#define XFS_INODE_EXTENTS 9 + +#define XFS_INODE_FORMAT_INO 1 +#define XFS_INODE_FORMAT_EXT 2 +#define XFS_INODE_FORMAT_BTREE 3 + +/* Superblock version field flags */ +#define XFS_SB_VERSION_NUMBITS 0x000f +#define XFS_SB_VERSION_ATTRBIT 0x0010 +#define XFS_SB_VERSION_NLINKBIT 0x0020 +#define XFS_SB_VERSION_QUOTABIT 0x0040 +#define XFS_SB_VERSION_ALIGNBIT 0x0080 +#define XFS_SB_VERSION_DALIGNBIT 0x0100 +#define XFS_SB_VERSION_LOGV2BIT 0x0400 +#define XFS_SB_VERSION_SECTORBIT 0x0800 +#define XFS_SB_VERSION_EXTFLGBIT 0x1000 +#define XFS_SB_VERSION_DIRV2BIT 0x2000 +#define XFS_SB_VERSION_MOREBITSBIT 0x8000 +#define XFS_SB_VERSION_BITS_SUPPORTED \ + (XFS_SB_VERSION_NUMBITS | \ + XFS_SB_VERSION_ATTRBIT | \ + XFS_SB_VERSION_NLINKBIT | \ + XFS_SB_VERSION_QUOTABIT | \ + XFS_SB_VERSION_ALIGNBIT | \ + XFS_SB_VERSION_DALIGNBIT | \ + XFS_SB_VERSION_LOGV2BIT | \ + XFS_SB_VERSION_SECTORBIT | \ + XFS_SB_VERSION_EXTFLGBIT | \ + XFS_SB_VERSION_DIRV2BIT | \ + XFS_SB_VERSION_MOREBITSBIT) + +/* Recognized xfs format versions */ +#define XFS_SB_VERSION_4 4 /* Good old XFS filesystem */ +#define XFS_SB_VERSION_5 5 /* CRC enabled filesystem */ + +/* features2 field flags */ +#define XFS_SB_VERSION2_LAZYSBCOUNTBIT 0x00000002 /* Superblk counters */ +#define XFS_SB_VERSION2_ATTR2BIT 0x00000008 /* Inline attr rework */ +#define XFS_SB_VERSION2_PROJID32BIT 0x00000080 /* 32-bit project ids */ +#define XFS_SB_VERSION2_FTYPE 0x00000200 /* inode type in dir */ +#define XFS_SB_VERSION2_BITS_SUPPORTED \ + (XFS_SB_VERSION2_LAZYSBCOUNTBIT | \ + XFS_SB_VERSION2_ATTR2BIT | \ + XFS_SB_VERSION2_PROJID32BIT | \ + XFS_SB_VERSION2_FTYPE) + +/* Inode flags2 flags */ +#define XFS_DIFLAG2_BIGTIME_BIT 3 +#define XFS_DIFLAG2_BIGTIME (1 << XFS_DIFLAG2_BIGTIME_BIT) +#define XFS_DIFLAG2_NREXT64_BIT 4 +#define XFS_DIFLAG2_NREXT64 (1 << XFS_DIFLAG2_NREXT64_BIT) + +/* incompat feature flags */ +#define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */ +#define XFS_SB_FEAT_INCOMPAT_SPINODES (1 << 1) /* sparse inode chunks */ +#define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2) /* metadata UUID */ +#define XFS_SB_FEAT_INCOMPAT_BIGTIME (1 << 3) /* large timestamps */ +#define XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR (1 << 4) /* needs xfs_repair */ +#define XFS_SB_FEAT_INCOMPAT_NREXT64 (1 << 5) /* large extent counters */ +#define XFS_SB_FEAT_INCOMPAT_EXCHRANGE (1 << 6) /* exchangerange supported */ +#define XFS_SB_FEAT_INCOMPAT_PARENT (1 << 7) /* parent pointers */ +#define XFS_SB_FEAT_INCOMPAT_METADIR (1 << 8) /* metadata dir tree */ + +/* + * Directory entries with ftype are explicitly handled by GRUB code. + * + * We do not currently read the inode btrees, so it is safe to read filesystems + * with the XFS_SB_FEAT_INCOMPAT_SPINODES feature. + * + * We do not currently verify metadata UUID, so it is safe to read filesystems + * with the XFS_SB_FEAT_INCOMPAT_META_UUID feature. + * + * We do not currently replay the log, so it is safe to read filesystems + * with the XFS_SB_FEAT_INCOMPAT_EXCHRANGE feature. + * + * We do not currently read directory parent pointers, so it is safe to read + * filesystems with the XFS_SB_FEAT_INCOMPAT_PARENT feature. + * + * We do not currently look at realtime or quota metadata, so it is safe to + * read filesystems with the XFS_SB_FEAT_INCOMPAT_METADIR feature. + */ +#define XFS_SB_FEAT_INCOMPAT_SUPPORTED \ + (XFS_SB_FEAT_INCOMPAT_FTYPE | \ + XFS_SB_FEAT_INCOMPAT_SPINODES | \ + XFS_SB_FEAT_INCOMPAT_META_UUID | \ + XFS_SB_FEAT_INCOMPAT_BIGTIME | \ + XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR | \ + XFS_SB_FEAT_INCOMPAT_NREXT64 | \ + XFS_SB_FEAT_INCOMPAT_EXCHRANGE | \ + XFS_SB_FEAT_INCOMPAT_PARENT | \ + XFS_SB_FEAT_INCOMPAT_METADIR) + +struct grub_xfs_sblock +{ + grub_uint8_t magic[4]; + grub_uint32_t bsize; + grub_uint8_t unused1[24]; + grub_uint16_t uuid[8]; + grub_uint8_t unused2[8]; + grub_uint64_t rootino; + grub_uint8_t unused3[20]; + grub_uint32_t agsize; + grub_uint8_t unused4[12]; + grub_uint16_t version; + grub_uint8_t unused5[6]; + grub_uint8_t label[12]; + grub_uint8_t log2_bsize; + grub_uint8_t log2_sect; + grub_uint8_t log2_inode; + grub_uint8_t log2_inop; + grub_uint8_t log2_agblk; + grub_uint8_t unused6[67]; + grub_uint8_t log2_dirblk; + grub_uint8_t unused7[7]; + grub_uint32_t features2; + grub_uint8_t unused8[4]; + grub_uint32_t sb_features_compat; + grub_uint32_t sb_features_ro_compat; + grub_uint32_t sb_features_incompat; + grub_uint32_t sb_features_log_incompat; +} GRUB_PACKED; + +struct grub_xfs_dir_header +{ + grub_uint8_t count; + grub_uint8_t largeino; + union + { + grub_uint32_t i4; + grub_uint64_t i8; + } GRUB_PACKED parent; +} GRUB_PACKED; + +/* Structure for directory entry inlined in the inode */ +struct grub_xfs_dir_entry +{ + grub_uint8_t len; + grub_uint16_t offset; + char name[1]; + /* Inode number follows, 32 / 64 bits. */ +} GRUB_PACKED; + +/* Structure for directory entry in a block */ +struct grub_xfs_dir2_entry +{ + grub_uint64_t inode; + grub_uint8_t len; +} GRUB_PACKED; + +struct grub_xfs_extent +{ + /* This should be a bitfield but bietfields are unportable, so just have + a raw array and functions extracting useful info from it. + */ + grub_uint32_t raw[4]; +} GRUB_PACKED; + +struct grub_xfs_btree_node +{ + grub_uint8_t magic[4]; + grub_uint16_t level; + grub_uint16_t numrecs; + grub_uint64_t left; + grub_uint64_t right; + /* In V5 here follow crc, uuid, etc. */ + /* Then follow keys and block pointers */ +} GRUB_PACKED; + +struct grub_xfs_btree_root +{ + grub_uint16_t level; + grub_uint16_t numrecs; + grub_uint64_t keys[1]; +} GRUB_PACKED; + +struct grub_xfs_time_legacy +{ + grub_uint32_t sec; + grub_uint32_t nanosec; +} GRUB_PACKED; + +/* + * The struct grub_xfs_inode layout was taken from the + * struct xfs_dinode_core which is described here: + * https://mirrors.edge.kernel.org/pub/linux/utils/fs/xfs/docs/xfs_filesystem_structure.pdf + */ +struct grub_xfs_inode +{ + grub_uint8_t magic[2]; + grub_uint16_t mode; + grub_uint8_t version; + grub_uint8_t format; + grub_uint8_t unused2[18]; + grub_uint64_t nextents_big; + grub_uint64_t atime; + grub_uint64_t mtime; + grub_uint64_t ctime; + grub_uint64_t size; + grub_uint64_t nblocks; + grub_uint32_t extsize; + grub_uint32_t nextents; + grub_uint16_t unused3; + grub_uint8_t fork_offset; + grub_uint8_t unused4[17]; /* Last member of inode v2. */ + grub_uint8_t unused5[20]; /* First member of inode v3. */ + grub_uint64_t flags2; + grub_uint8_t unused6[48]; /* Last member of inode v3. */ +} GRUB_PACKED; + +#define XFS_V3_INODE_SIZE sizeof(struct grub_xfs_inode) +/* Size of struct grub_xfs_inode v2, up to unused4 member included. */ +#define XFS_V2_INODE_SIZE (XFS_V3_INODE_SIZE - 76) + +struct grub_xfs_dir_leaf_entry +{ + grub_uint32_t hashval; + grub_uint32_t address; +} GRUB_PACKED; + +struct grub_xfs_dirblock_tail +{ + grub_uint32_t leaf_count; + grub_uint32_t leaf_stale; +} GRUB_PACKED; + +struct grub_fshelp_node +{ + struct grub_xfs_data *data; + grub_uint64_t ino; + int inode_read; + struct grub_xfs_inode inode; +}; + +struct grub_xfs_data +{ + grub_size_t data_size; + struct grub_xfs_sblock sblock; + grub_disk_t disk; + int pos; + int bsize; + grub_uint32_t agsize; + unsigned int hasftype:1; + unsigned int hascrc:1; + struct grub_fshelp_node diropen; +}; + +static grub_dl_t my_mod; + +static int grub_xfs_sb_hascrc(struct grub_xfs_data *data) +{ + return (data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_NUMBITS)) == + grub_cpu_to_be16_compile_time(XFS_SB_VERSION_5); +} + +static int grub_xfs_sb_hasftype(struct grub_xfs_data *data) +{ + if ((data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_NUMBITS)) == + grub_cpu_to_be16_compile_time(XFS_SB_VERSION_5) && + data->sblock.sb_features_incompat & grub_cpu_to_be32_compile_time(XFS_SB_FEAT_INCOMPAT_FTYPE)) + return 1; + if (data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_MOREBITSBIT) && + data->sblock.features2 & grub_cpu_to_be32_compile_time(XFS_SB_VERSION2_FTYPE)) + return 1; + return 0; +} + +static int grub_xfs_sb_valid(struct grub_xfs_data *data) +{ + grub_dprintf("xfs", "Validating superblock\n"); + if (grub_strncmp ((char *) (data->sblock.magic), "XFSB", 4) + || data->sblock.log2_bsize < GRUB_DISK_SECTOR_BITS + || ((int) data->sblock.log2_bsize + + (int) data->sblock.log2_dirblk) >= 27) + { + grub_error (GRUB_ERR_BAD_FS, "not a XFS filesystem"); + return 0; + } + if ((data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_NUMBITS)) == + grub_cpu_to_be16_compile_time(XFS_SB_VERSION_5)) + { + grub_dprintf("xfs", "XFS v5 superblock detected\n"); + if (data->sblock.sb_features_incompat & + grub_cpu_to_be32_compile_time(~XFS_SB_FEAT_INCOMPAT_SUPPORTED)) + { + grub_error (GRUB_ERR_BAD_FS, "XFS filesystem has unsupported " + "incompatible features"); + return 0; + } + return 1; + } + else if ((data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_NUMBITS)) == + grub_cpu_to_be16_compile_time(XFS_SB_VERSION_4)) + { + grub_dprintf("xfs", "XFS v4 superblock detected\n"); + if (!(data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_DIRV2BIT))) + { + grub_error (GRUB_ERR_BAD_FS, "XFS filesystem without V2 directories " + "is unsupported"); + return 0; + } + if (data->sblock.version & grub_cpu_to_be16_compile_time(~XFS_SB_VERSION_BITS_SUPPORTED) || + (data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_MOREBITSBIT) && + data->sblock.features2 & grub_cpu_to_be16_compile_time(~XFS_SB_VERSION2_BITS_SUPPORTED))) + { + grub_error (GRUB_ERR_BAD_FS, "XFS filesystem has unsupported version " + "bits"); + return 0; + } + return 1; + } + + grub_error (GRUB_ERR_BAD_FS, "unsupported XFS filesystem version"); + return 0; +} + +static int +grub_xfs_sb_needs_repair (struct grub_xfs_data *data) +{ + return ((data->sblock.version & + grub_cpu_to_be16_compile_time (XFS_SB_VERSION_NUMBITS)) == + grub_cpu_to_be16_compile_time (XFS_SB_VERSION_5) && + (data->sblock.sb_features_incompat & + grub_cpu_to_be32_compile_time (XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR))); +} + +/* Filetype information as used in inodes. */ +#define FILETYPE_INO_MASK 0170000 +#define FILETYPE_INO_REG 0100000 +#define FILETYPE_INO_DIRECTORY 0040000 +#define FILETYPE_INO_SYMLINK 0120000 + +static inline int +GRUB_XFS_INO_AGBITS(struct grub_xfs_data *data) +{ + return ((data)->sblock.log2_agblk + (data)->sblock.log2_inop); +} + +static inline grub_uint64_t +GRUB_XFS_INO_INOINAG (struct grub_xfs_data *data, + grub_uint64_t ino) +{ + return (ino & ((1LL << GRUB_XFS_INO_AGBITS (data)) - 1)); +} + +static inline grub_uint64_t +GRUB_XFS_INO_AG (struct grub_xfs_data *data, + grub_uint64_t ino) +{ + return (ino >> GRUB_XFS_INO_AGBITS (data)); +} + +static inline grub_disk_addr_t +GRUB_XFS_FSB_TO_BLOCK (struct grub_xfs_data *data, grub_disk_addr_t fsb) +{ + return ((fsb >> data->sblock.log2_agblk) * data->agsize + + (fsb & ((1LL << data->sblock.log2_agblk) - 1))); +} + +static inline grub_uint64_t +GRUB_XFS_EXTENT_OFFSET (struct grub_xfs_extent *exts, int ex) +{ + return ((grub_be_to_cpu32 (exts[ex].raw[0]) & ~(1 << 31)) << 23 + | grub_be_to_cpu32 (exts[ex].raw[1]) >> 9); +} + +static inline grub_uint64_t +GRUB_XFS_EXTENT_BLOCK (struct grub_xfs_extent *exts, int ex) +{ + return ((grub_uint64_t) (grub_be_to_cpu32 (exts[ex].raw[1]) + & (0x1ff)) << 43 + | (grub_uint64_t) grub_be_to_cpu32 (exts[ex].raw[2]) << 11 + | grub_be_to_cpu32 (exts[ex].raw[3]) >> 21); +} + +static inline grub_uint64_t +GRUB_XFS_EXTENT_SIZE (struct grub_xfs_extent *exts, int ex) +{ + return (grub_be_to_cpu32 (exts[ex].raw[3]) & ((1 << 21) - 1)); +} + +static inline grub_uint64_t +grub_xfs_inode_block (struct grub_xfs_data *data, + grub_uint64_t ino) +{ + long long int inoinag = GRUB_XFS_INO_INOINAG (data, ino); + long long ag = GRUB_XFS_INO_AG (data, ino); + long long block; + + block = (inoinag >> data->sblock.log2_inop) + ag * data->agsize; + block <<= (data->sblock.log2_bsize - GRUB_DISK_SECTOR_BITS); + return block; +} + + +static inline int +grub_xfs_inode_offset (struct grub_xfs_data *data, + grub_uint64_t ino) +{ + int inoag = GRUB_XFS_INO_INOINAG (data, ino); + return ((inoag & ((1 << data->sblock.log2_inop) - 1)) << + data->sblock.log2_inode); +} + +static inline grub_size_t +grub_xfs_inode_size(struct grub_xfs_data *data) +{ + return (grub_size_t)1 << data->sblock.log2_inode; +} + +/* + * Returns size occupied by XFS inode stored in memory - we store struct + * grub_fshelp_node there but on disk inode size may be actually larger than + * struct grub_xfs_inode so we need to account for that so that we can read + * from disk directly into in-memory structure. + */ +static inline grub_size_t +grub_xfs_fshelp_size(struct grub_xfs_data *data) +{ + return sizeof (struct grub_fshelp_node) - sizeof (struct grub_xfs_inode) + + grub_xfs_inode_size(data); +} + +/* This should return void * but XFS code is error-prone with alignment, so + return char to retain cast-align. + */ +static char * +grub_xfs_inode_data(struct grub_xfs_inode *inode) +{ + if (inode->version <= 2) + return ((char *)inode) + XFS_V2_INODE_SIZE; + return ((char *)inode) + XFS_V3_INODE_SIZE; +} + +static struct grub_xfs_dir_entry * +grub_xfs_inline_de(struct grub_xfs_dir_header *head) +{ + /* + With small inode numbers the header is 4 bytes smaller because of + smaller parent pointer + */ + return (struct grub_xfs_dir_entry *) + (((char *) head) + sizeof(struct grub_xfs_dir_header) - + (head->largeino ? 0 : sizeof(grub_uint32_t))); +} + +static grub_uint8_t * +grub_xfs_inline_de_inopos(struct grub_xfs_data *data, + struct grub_xfs_dir_entry *de) +{ + return ((grub_uint8_t *)(de + 1)) + de->len - 1 + (data->hasftype ? 1 : 0); +} + +static struct grub_xfs_dir_entry * +grub_xfs_inline_next_de(struct grub_xfs_data *data, + struct grub_xfs_dir_header *head, + struct grub_xfs_dir_entry *de) +{ + char *p = (char *)de + sizeof(struct grub_xfs_dir_entry) - 1 + de->len; + + p += head->largeino ? sizeof(grub_uint64_t) : sizeof(grub_uint32_t); + if (data->hasftype) + p++; + + return (struct grub_xfs_dir_entry *)p; +} + +static struct grub_xfs_dirblock_tail * +grub_xfs_dir_tail(struct grub_xfs_data *data, void *dirblock) +{ + int dirblksize = 1 << (data->sblock.log2_bsize + data->sblock.log2_dirblk); + + return (struct grub_xfs_dirblock_tail *) + ((char *)dirblock + dirblksize - sizeof (struct grub_xfs_dirblock_tail)); +} + +static struct grub_xfs_dir2_entry * +grub_xfs_first_de(struct grub_xfs_data *data, void *dirblock) +{ + if (data->hascrc) + return (struct grub_xfs_dir2_entry *)((char *)dirblock + 64); + return (struct grub_xfs_dir2_entry *)((char *)dirblock + 16); +} + +static struct grub_xfs_dir2_entry * +grub_xfs_next_de(struct grub_xfs_data *data, struct grub_xfs_dir2_entry *de) +{ + int size = sizeof (struct grub_xfs_dir2_entry) + de->len + 2 /* Tag */; + + if (data->hasftype) + size++; /* File type */ + return (struct grub_xfs_dir2_entry *)(((char *)de) + ALIGN_UP(size, 8)); +} + +/* This should return void * but XFS code is error-prone with alignment, so + return char to retain cast-align. + */ +static char * +grub_xfs_btree_keys(struct grub_xfs_data *data, + struct grub_xfs_btree_node *leaf) +{ + char *keys = (char *)(leaf + 1); + + if (data->hascrc) + keys += 48; /* skip crc, uuid, ... */ + return keys; +} + +static grub_err_t +grub_xfs_read_inode (struct grub_xfs_data *data, grub_uint64_t ino, + struct grub_xfs_inode *inode) +{ + grub_uint64_t block = grub_xfs_inode_block (data, ino); + int offset = grub_xfs_inode_offset (data, ino); + + grub_dprintf("xfs", "Reading inode (%" PRIuGRUB_UINT64_T ") - %" PRIuGRUB_UINT64_T ", %d\n", + ino, block, offset); + /* Read the inode. */ + if (grub_disk_read (data->disk, block, offset, grub_xfs_inode_size(data), + inode)) + return grub_errno; + + if (grub_strncmp ((char *) inode->magic, "IN", 2)) + return grub_error (GRUB_ERR_BAD_FS, "not a correct XFS inode"); + + return 0; +} + +static grub_uint64_t +get_fsb (const void *keys, int idx) +{ + const char *p = (const char *) keys + sizeof(grub_uint64_t) * idx; + return grub_be_to_cpu64 (grub_get_unaligned64 (p)); +} + +static int +grub_xfs_inode_has_large_extent_counts (const struct grub_xfs_inode *inode) +{ + return inode->version >= 3 && + (inode->flags2 & grub_cpu_to_be64_compile_time (XFS_DIFLAG2_NREXT64)); +} + +static grub_uint64_t +grub_xfs_get_inode_nextents (struct grub_xfs_inode *inode) +{ + return (grub_xfs_inode_has_large_extent_counts (inode)) ? + grub_be_to_cpu64 (inode->nextents_big) : + grub_be_to_cpu32 (inode->nextents); +} + +static grub_disk_addr_t +grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) +{ + struct grub_xfs_btree_node *leaf = 0; + grub_uint64_t ex, nrec; + struct grub_xfs_extent *exts; + grub_uint64_t ret = 0; + + if (node->inode.format == XFS_INODE_FORMAT_BTREE) + { + struct grub_xfs_btree_root *root; + const char *keys; + int recoffset; + + leaf = grub_malloc (node->data->bsize); + if (leaf == 0) + return 0; + + root = (struct grub_xfs_btree_root *) grub_xfs_inode_data(&node->inode); + nrec = grub_be_to_cpu16 (root->numrecs); + keys = (char *) &root->keys[0]; + if (node->inode.fork_offset) + recoffset = (node->inode.fork_offset - 1) / 2; + else + recoffset = (grub_xfs_inode_size(node->data) + - ((char *) keys - (char *) &node->inode)) + / (2 * sizeof (grub_uint64_t)); + do + { + grub_uint64_t i; + grub_addr_t keys_end, data_end; + + if (grub_mul (sizeof (grub_uint64_t), nrec, &keys_end) || + grub_add ((grub_addr_t) keys, keys_end, &keys_end) || + grub_add ((grub_addr_t) node->data, node->data->data_size, &data_end) || + keys_end > data_end) + { + grub_error (GRUB_ERR_BAD_FS, "invalid number of XFS root keys"); + grub_free (leaf); + return 0; + } + + for (i = 0; i < nrec; i++) + { + if (fileblock < get_fsb(keys, i)) + break; + } + + /* Sparse block. */ + if (i == 0) + { + grub_free (leaf); + return 0; + } + + if (grub_disk_read (node->data->disk, + GRUB_XFS_FSB_TO_BLOCK (node->data, get_fsb (keys, i - 1 + recoffset)) << (node->data->sblock.log2_bsize - GRUB_DISK_SECTOR_BITS), + 0, node->data->bsize, leaf)) + { + grub_free (leaf); + return 0; + } + + if ((!node->data->hascrc && + grub_strncmp ((char *) leaf->magic, "BMAP", 4)) || + (node->data->hascrc && + grub_strncmp ((char *) leaf->magic, "BMA3", 4))) + { + grub_free (leaf); + grub_error (GRUB_ERR_BAD_FS, "not a correct XFS BMAP node"); + return 0; + } + + nrec = grub_be_to_cpu16 (leaf->numrecs); + keys = grub_xfs_btree_keys(node->data, leaf); + recoffset = ((node->data->bsize - ((char *) keys + - (char *) leaf)) + / (2 * sizeof (grub_uint64_t))); + } + while (leaf->level); + exts = (struct grub_xfs_extent *) keys; + } + else if (node->inode.format == XFS_INODE_FORMAT_EXT) + { + grub_addr_t exts_end = 0; + grub_addr_t data_end = 0; + + nrec = grub_xfs_get_inode_nextents (&node->inode); + exts = (struct grub_xfs_extent *) grub_xfs_inode_data(&node->inode); + + if (grub_mul (sizeof (struct grub_xfs_extent), nrec, &exts_end) || + grub_add ((grub_addr_t) node->data, exts_end, &exts_end) || + grub_add ((grub_addr_t) node->data, node->data->data_size, &data_end) || + exts_end > data_end) + { + grub_error (GRUB_ERR_BAD_FS, "invalid number of XFS extents"); + return 0; + } + } + else + { + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "XFS does not support inode format %d yet", + node->inode.format); + return 0; + } + + /* Iterate over each extent to figure out which extent has + the block we are looking for. */ + for (ex = 0; ex < nrec; ex++) + { + grub_uint64_t start = GRUB_XFS_EXTENT_BLOCK (exts, ex); + grub_uint64_t offset = GRUB_XFS_EXTENT_OFFSET (exts, ex); + grub_uint64_t size = GRUB_XFS_EXTENT_SIZE (exts, ex); + + /* Sparse block. */ + if (fileblock < offset) + break; + else if (fileblock < offset + size) + { + ret = (fileblock - offset + start); + break; + } + } + + grub_free (leaf); + + return GRUB_XFS_FSB_TO_BLOCK(node->data, ret); +} + + +/* Read LEN bytes from the file described by DATA starting with byte + POS. Return the amount of read bytes in READ. */ +static grub_ssize_t +grub_xfs_read_file (grub_fshelp_node_t node, + grub_disk_read_hook_t read_hook, void *read_hook_data, + grub_off_t pos, grub_size_t len, char *buf, grub_uint32_t header_size) +{ + return grub_fshelp_read_file (node->data->disk, node, + read_hook, read_hook_data, + pos, len, buf, grub_xfs_read_block, + grub_be_to_cpu64 (node->inode.size) + header_size, + node->data->sblock.log2_bsize + - GRUB_DISK_SECTOR_BITS, 0); +} + + +static char * +grub_xfs_read_symlink (grub_fshelp_node_t node) +{ + grub_ssize_t size = grub_be_to_cpu64 (node->inode.size); + grub_size_t sz; + + if (size < 0) + { + grub_error (GRUB_ERR_BAD_FS, "invalid symlink"); + return 0; + } + + switch (node->inode.format) + { + case XFS_INODE_FORMAT_INO: + return grub_strndup (grub_xfs_inode_data(&node->inode), size); + + case XFS_INODE_FORMAT_EXT: + { + char *symlink; + grub_ssize_t numread; + int off = 0; + + if (node->data->hascrc) + off = 56; + + if (grub_add (size, 1, &sz)) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("symlink size overflow")); + return 0; + } + symlink = grub_malloc (sz); + if (!symlink) + return 0; + + node->inode.size = grub_be_to_cpu64 (size + off); + numread = grub_xfs_read_file (node, 0, 0, off, size, symlink, off); + if (numread != size) + { + grub_free (symlink); + return 0; + } + symlink[size] = '\0'; + return symlink; + } + } + + return 0; +} + + +static enum grub_fshelp_filetype +grub_xfs_mode_to_filetype (grub_uint16_t mode) +{ + if ((grub_be_to_cpu16 (mode) + & FILETYPE_INO_MASK) == FILETYPE_INO_DIRECTORY) + return GRUB_FSHELP_DIR; + else if ((grub_be_to_cpu16 (mode) + & FILETYPE_INO_MASK) == FILETYPE_INO_SYMLINK) + return GRUB_FSHELP_SYMLINK; + else if ((grub_be_to_cpu16 (mode) + & FILETYPE_INO_MASK) == FILETYPE_INO_REG) + return GRUB_FSHELP_REG; + return GRUB_FSHELP_UNKNOWN; +} + + +/* Context for grub_xfs_iterate_dir. */ +struct grub_xfs_iterate_dir_ctx +{ + grub_fshelp_iterate_dir_hook_t hook; + void *hook_data; + struct grub_fshelp_node *diro; +}; + +/* Helper for grub_xfs_iterate_dir. */ +static int iterate_dir_call_hook (grub_uint64_t ino, const char *filename, + struct grub_xfs_iterate_dir_ctx *ctx) +{ + struct grub_fshelp_node *fdiro; + grub_err_t err; + grub_size_t sz; + + if (grub_add (grub_xfs_fshelp_size(ctx->diro->data), 1, &sz)) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("directory data size overflow")); + grub_print_error (); + return 0; + } + fdiro = grub_malloc (sz); + if (!fdiro) + { + grub_print_error (); + return 0; + } + + /* The inode should be read, otherwise the filetype can + not be determined. */ + fdiro->ino = ino; + fdiro->inode_read = 1; + fdiro->data = ctx->diro->data; + err = grub_xfs_read_inode (ctx->diro->data, ino, &fdiro->inode); + if (err) + { + grub_print_error (); + grub_free (fdiro); + return 0; + } + + return ctx->hook (filename, grub_xfs_mode_to_filetype (fdiro->inode.mode), + fdiro, ctx->hook_data); +} + +static int +grub_xfs_iterate_dir (grub_fshelp_node_t dir, + grub_fshelp_iterate_dir_hook_t hook, void *hook_data) +{ + struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir; + struct grub_xfs_iterate_dir_ctx ctx = { + .hook = hook, + .hook_data = hook_data, + .diro = diro + }; + + switch (diro->inode.format) + { + case XFS_INODE_FORMAT_INO: + { + struct grub_xfs_dir_header *head = (struct grub_xfs_dir_header *) grub_xfs_inode_data(&diro->inode); + struct grub_xfs_dir_entry *de = grub_xfs_inline_de(head); + int smallino = !head->largeino; + int i; + grub_uint64_t parent; + + /* If small inode numbers are used to pack the direntry, the + parent inode number is small too. */ + if (smallino) + parent = grub_be_to_cpu32 (head->parent.i4); + else + parent = grub_be_to_cpu64 (head->parent.i8); + + /* Synthesize the direntries for `.' and `..'. */ + if (iterate_dir_call_hook (diro->ino, ".", &ctx)) + return 1; + + if (iterate_dir_call_hook (parent, "..", &ctx)) + return 1; + + for (i = 0; i < head->count && + (grub_uint8_t *) de < ((grub_uint8_t *) dir + grub_xfs_fshelp_size (dir->data)); i++) + { + grub_uint64_t ino; + grub_uint8_t *inopos = grub_xfs_inline_de_inopos(dir->data, de); + grub_uint8_t c; + + if ((inopos + (smallino ? 4 : 8)) > (grub_uint8_t *) dir + grub_xfs_fshelp_size (dir->data)) + { + grub_error (GRUB_ERR_BAD_FS, "invalid XFS inode"); + return 0; + } + + + /* inopos might be unaligned. */ + if (smallino) + ino = (((grub_uint32_t) inopos[0]) << 24) + | (((grub_uint32_t) inopos[1]) << 16) + | (((grub_uint32_t) inopos[2]) << 8) + | (((grub_uint32_t) inopos[3]) << 0); + else + ino = (((grub_uint64_t) inopos[0]) << 56) + | (((grub_uint64_t) inopos[1]) << 48) + | (((grub_uint64_t) inopos[2]) << 40) + | (((grub_uint64_t) inopos[3]) << 32) + | (((grub_uint64_t) inopos[4]) << 24) + | (((grub_uint64_t) inopos[5]) << 16) + | (((grub_uint64_t) inopos[6]) << 8) + | (((grub_uint64_t) inopos[7]) << 0); + + c = de->name[de->len]; + de->name[de->len] = '\0'; + if (iterate_dir_call_hook (ino, de->name, &ctx)) + { + de->name[de->len] = c; + return 1; + } + de->name[de->len] = c; + + de = grub_xfs_inline_next_de(dir->data, head, de); + } + break; + } + + case XFS_INODE_FORMAT_BTREE: + case XFS_INODE_FORMAT_EXT: + { + grub_ssize_t numread; + char *dirblock; + grub_uint64_t blk; + int dirblk_size, dirblk_log2; + + dirblk_log2 = (dir->data->sblock.log2_bsize + + dir->data->sblock.log2_dirblk); + dirblk_size = 1 << dirblk_log2; + + dirblock = grub_malloc (dirblk_size); + if (! dirblock) + return 0; + + /* Iterate over every block the directory has. */ + for (blk = 0; + blk < (grub_be_to_cpu64 (dir->inode.size) + >> dirblk_log2); + blk++) + { + struct grub_xfs_dir2_entry *direntry = + grub_xfs_first_de(dir->data, dirblock); + int entries = -1; + char *end = dirblock + dirblk_size; + grub_uint32_t magic; + + numread = grub_xfs_read_file (dir, 0, 0, + blk << dirblk_log2, + dirblk_size, dirblock, 0); + if (numread != dirblk_size) + { + grub_free (dirblock); + return 0; + } + + /* + * If this data block isn't actually part of the extent list then + * grub_xfs_read_file() returns a block of zeros. So, if the magic + * number field is all zeros then this block should be skipped. + */ + magic = *(grub_uint32_t *)(void *) dirblock; + if (!magic) + continue; + + /* + * Leaf and tail information are only in the data block if the number + * of extents is 1. + */ + if (grub_xfs_get_inode_nextents (&dir->inode) == 1) + { + struct grub_xfs_dirblock_tail *tail = grub_xfs_dir_tail (dir->data, dirblock); + + end = (char *) tail; + + /* Subtract the space used by leaf nodes. */ + end -= grub_be_to_cpu32 (tail->leaf_count) * sizeof (struct grub_xfs_dir_leaf_entry); + + entries = grub_be_to_cpu32 (tail->leaf_count) - grub_be_to_cpu32 (tail->leaf_stale); + + if (!entries) + continue; + } + + /* Iterate over all entries within this block. */ + while ((char *) direntry < (char *) end) + { + grub_uint8_t *freetag; + char *filename; + + freetag = (grub_uint8_t *) direntry; + + if (grub_get_unaligned16 (freetag) == 0XFFFF) + { + grub_uint8_t *skip = (freetag + sizeof (grub_uint16_t)); + + /* This entry is not used, go to the next one. */ + direntry = (struct grub_xfs_dir2_entry *) + (((char *)direntry) + + grub_be_to_cpu16 (grub_get_unaligned16 (skip))); + + continue; + } + + filename = (char *)(direntry + 1); + if (filename + direntry->len + 1 > (char *) end) + { + grub_error (GRUB_ERR_BAD_FS, "invalid XFS directory entry"); + return 0; + } + + /* The byte after the filename is for the filetype, padding, or + tag, which is not used by GRUB. So it can be overwritten. */ + filename[direntry->len] = '\0'; + + if (iterate_dir_call_hook (grub_be_to_cpu64(direntry->inode), + filename, &ctx)) + { + grub_free (dirblock); + return 1; + } + + /* + * The expected number of directory entries is only tracked for the + * single extent case. + */ + if (grub_xfs_get_inode_nextents (&dir->inode) == 1) + { + /* Check if last direntry in this block is reached. */ + entries--; + if (!entries) + break; + } + + /* Select the next directory entry. */ + direntry = grub_xfs_next_de(dir->data, direntry); + } + } + grub_free (dirblock); + break; + } + + default: + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "XFS does not support inode format %d yet", + diro->inode.format); + } + return 0; +} + + +static struct grub_xfs_data * +grub_xfs_mount (grub_disk_t disk) +{ + struct grub_xfs_data *data = 0; + grub_size_t sz; + + data = grub_zalloc (sizeof (struct grub_xfs_data)); + if (!data) + return 0; + + data->data_size = sizeof (struct grub_xfs_data); + + grub_dprintf("xfs", "Reading sb\n"); + /* Read the superblock. */ + if (grub_disk_read (disk, 0, 0, + sizeof (struct grub_xfs_sblock), &data->sblock)) + goto fail; + + if (!grub_xfs_sb_valid(data)) + goto fail; + + if (grub_xfs_sb_needs_repair (data)) + grub_dprintf ("xfs", "XFS filesystem needs repair, boot may fail\n"); + + if (grub_add (grub_xfs_inode_size (data), + sizeof (struct grub_xfs_data) - sizeof (struct grub_xfs_inode) + 1, &sz)) + goto fail; + + data = grub_realloc (data, sz); + + if (! data) + goto fail; + + data->data_size = sz; + data->diropen.data = data; + data->diropen.ino = grub_be_to_cpu64(data->sblock.rootino); + data->diropen.inode_read = 1; + data->bsize = grub_be_to_cpu32 (data->sblock.bsize); + data->agsize = grub_be_to_cpu32 (data->sblock.agsize); + data->hasftype = grub_xfs_sb_hasftype(data); + data->hascrc = grub_xfs_sb_hascrc(data); + + data->disk = disk; + data->pos = 0; + grub_dprintf("xfs", "Reading root ino %" PRIuGRUB_UINT64_T "\n", + grub_cpu_to_be64(data->sblock.rootino)); + + grub_xfs_read_inode (data, data->diropen.ino, &data->diropen.inode); + + return data; + fail: + + if (grub_errno == GRUB_ERR_OUT_OF_RANGE || grub_errno == GRUB_ERR_NONE) + grub_error (GRUB_ERR_BAD_FS, "not an XFS filesystem"); + + grub_free (data); + + return 0; +} + +/* Context for grub_xfs_dir. */ +struct grub_xfs_dir_ctx +{ + grub_fs_dir_hook_t hook; + void *hook_data; +}; + +/* Bigtime inodes helpers. */ +#define XFS_BIGTIME_EPOCH_OFFSET (-(grub_int64_t) GRUB_INT32_MIN) + +static int grub_xfs_inode_has_bigtime (const struct grub_xfs_inode *inode) +{ + return inode->version >= 3 && + (inode->flags2 & grub_cpu_to_be64_compile_time (XFS_DIFLAG2_BIGTIME)); +} + +static grub_int64_t +grub_xfs_get_inode_time (struct grub_xfs_inode *inode) +{ + struct grub_xfs_time_legacy *lts; + + if (grub_xfs_inode_has_bigtime (inode)) + return grub_divmod64 (grub_be_to_cpu64 (inode->mtime), NSEC_PER_SEC, NULL) - XFS_BIGTIME_EPOCH_OFFSET; + + lts = (struct grub_xfs_time_legacy *) &inode->mtime; + return grub_be_to_cpu32 (lts->sec); +} + +/* Helper for grub_xfs_dir. */ +static int +grub_xfs_dir_iter (const char *filename, enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node, void *data) +{ + struct grub_xfs_dir_ctx *ctx = data; + struct grub_dirhook_info info; + + grub_memset (&info, 0, sizeof (info)); + if (node->inode_read) + { + info.mtimeset = 1; + info.mtime = grub_xfs_get_inode_time (&node->inode); + } + info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); + grub_free (node); + return ctx->hook (filename, &info, ctx->hook_data); +} + +static grub_err_t +grub_xfs_dir (grub_device_t device, const char *path, + grub_fs_dir_hook_t hook, void *hook_data) +{ + struct grub_xfs_dir_ctx ctx = { hook, hook_data }; + struct grub_xfs_data *data = 0; + struct grub_fshelp_node *fdiro = 0; + + grub_dl_ref (my_mod); + + data = grub_xfs_mount (device->disk); + if (!data) + goto mount_fail; + + grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_xfs_iterate_dir, + grub_xfs_read_symlink, GRUB_FSHELP_DIR); + if (grub_errno) + goto fail; + + grub_xfs_iterate_dir (fdiro, grub_xfs_dir_iter, &ctx); + + fail: + if (fdiro != &data->diropen) + grub_free (fdiro); + grub_free (data); + + mount_fail: + + grub_dl_unref (my_mod); + + return grub_errno; +} + + +/* Open a file named NAME and initialize FILE. */ +static grub_err_t +grub_xfs_open (struct grub_file *file, const char *name) +{ + struct grub_xfs_data *data; + struct grub_fshelp_node *fdiro = 0; + + grub_dl_ref (my_mod); + + data = grub_xfs_mount (file->device->disk); + if (!data) + goto mount_fail; + + grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_xfs_iterate_dir, + grub_xfs_read_symlink, GRUB_FSHELP_REG); + if (grub_errno) + goto fail; + + if (!fdiro->inode_read) + { + grub_xfs_read_inode (data, fdiro->ino, &fdiro->inode); + if (grub_errno) + goto fail; + } + + if (fdiro != &data->diropen) + { + grub_memcpy (&data->diropen, fdiro, grub_xfs_fshelp_size(data)); + grub_free (fdiro); + } + + file->size = grub_be_to_cpu64 (data->diropen.inode.size); + file->data = data; + file->offset = 0; + + return 0; + + fail: + if (fdiro != &data->diropen) + grub_free (fdiro); + grub_free (data); + + mount_fail: + grub_dl_unref (my_mod); + + return grub_errno; +} + + +static grub_ssize_t +grub_xfs_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_xfs_data *data = + (struct grub_xfs_data *) file->data; + + return grub_xfs_read_file (&data->diropen, + file->read_hook, file->read_hook_data, + file->offset, len, buf, 0); +} + + +static grub_err_t +grub_xfs_close (grub_file_t file) +{ + grub_free (file->data); + + grub_dl_unref (my_mod); + + return GRUB_ERR_NONE; +} + + +static grub_err_t +grub_xfs_label (grub_device_t device, char **label) +{ + struct grub_xfs_data *data; + grub_disk_t disk = device->disk; + + grub_dl_ref (my_mod); + + data = grub_xfs_mount (disk); + if (data) + *label = grub_strndup ((char *) (data->sblock.label), 12); + else + *label = 0; + + grub_dl_unref (my_mod); + + grub_free (data); + + return grub_errno; +} + +static grub_err_t +grub_xfs_uuid (grub_device_t device, char **uuid) +{ + struct grub_xfs_data *data; + grub_disk_t disk = device->disk; + + grub_dl_ref (my_mod); + + data = grub_xfs_mount (disk); + if (data) + { + *uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x", + grub_be_to_cpu16 (data->sblock.uuid[0]), + grub_be_to_cpu16 (data->sblock.uuid[1]), + grub_be_to_cpu16 (data->sblock.uuid[2]), + grub_be_to_cpu16 (data->sblock.uuid[3]), + grub_be_to_cpu16 (data->sblock.uuid[4]), + grub_be_to_cpu16 (data->sblock.uuid[5]), + grub_be_to_cpu16 (data->sblock.uuid[6]), + grub_be_to_cpu16 (data->sblock.uuid[7])); + } + else + *uuid = NULL; + + grub_dl_unref (my_mod); + + grub_free (data); + + return grub_errno; +} + +static struct grub_fs grub_xfs_fs = + { + .name = "xfs", + .fs_dir = grub_xfs_dir, + .fs_open = grub_xfs_open, + .fs_read = grub_xfs_read, + .fs_close = grub_xfs_close, + .fs_label = grub_xfs_label, + .fs_uuid = grub_xfs_uuid, +#ifdef GRUB_UTIL + .reserved_first_sector = 0, + .blocklist_install = 1, +#endif + .next = 0 + }; + +GRUB_MOD_INIT(xfs) +{ + //grub_xfs_fs.mod = mod; + grub_fs_register (&grub_xfs_fs); + my_mod = mod; +} + +GRUB_MOD_FINI(xfs) +{ + grub_fs_unregister (&grub_xfs_fs); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/zfs/zfs_lz4.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/zfs/zfs_lz4.c new file mode 100644 index 0000000..0309905 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/zfs/zfs_lz4.c @@ -0,0 +1,285 @@ +/* + * LZ4 - Fast LZ compression algorithm + * Header File + * Copyright (C) 2011-2013, Yann Collet. + * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * 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. + * + * You can contact the author at : + * - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html + * - LZ4 source repository : http://code.google.com/p/lz4/ + */ + +#include +#include +#include +#include + +int LZ4_uncompress_unknownOutputSize(const char *source, char *dest, + int isize, int maxOutputSize); + +/* + * CPU Feature Detection + */ + +/* 32 or 64 bits ? */ +#if (GRUB_CPU_SIZEOF_VOID_P == 8) +#define LZ4_ARCH64 1 +#else +#define LZ4_ARCH64 0 +#endif + +/* + * Compiler Options + */ + + +#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) + +#if (GCC_VERSION >= 302) || (defined (__INTEL_COMPILER) && __INTEL_COMPILER >= 800) || defined(__clang__) +#define expect(expr, value) (__builtin_expect((expr), (value))) +#else +#define expect(expr, value) (expr) +#endif + +#define likely(expr) expect((expr) != 0, 1) +#define unlikely(expr) expect((expr) != 0, 0) + +/* Basic types */ +#define BYTE grub_uint8_t +#define U16 grub_uint16_t +#define U32 grub_uint32_t +#define S32 grub_int32_t +#define U64 grub_uint64_t + +typedef struct _U16_S { + U16 v; +} GRUB_PACKED U16_S; +typedef struct _U32_S { + U32 v; +} GRUB_PACKED U32_S; +typedef struct _U64_S { + U64 v; +} GRUB_PACKED U64_S; + +#define A64(x) (((U64_S *)(x))->v) +#define A32(x) (((U32_S *)(x))->v) +#define A16(x) (((U16_S *)(x))->v) + +/* + * Constants + */ +#define MINMATCH 4 + +#define COPYLENGTH 8 +#define LASTLITERALS 5 + +#define ML_BITS 4 +#define ML_MASK ((1U< s_len) + return grub_error(GRUB_ERR_BAD_FS,"lz4 decompression failed."); + + /* + * Returns 0 on success (decompression function returned non-negative) + * and appropriate error on failure (decompression function returned negative). + */ + return (LZ4_uncompress_unknownOutputSize((char*)s_start + 4, d_start, bufsiz, + d_len) < 0)?grub_error(GRUB_ERR_BAD_FS,"lz4 decompression failed."):0; +} + +int +LZ4_uncompress_unknownOutputSize(const char *source, + char *dest, int isize, int maxOutputSize) +{ + /* Local Variables */ + const BYTE * ip = (const BYTE *) source; + const BYTE *const iend = ip + isize; + const BYTE * ref; + + BYTE * op = (BYTE *) dest; + BYTE *const oend = op + maxOutputSize; + BYTE *cpy; + + grub_size_t dec[] = { 0, 3, 2, 3, 0, 0, 0, 0 }; + + /* Main Loop */ + while (ip < iend) { + BYTE token; + int length; + + /* get runlength */ + token = *ip++; + if ((length = (token >> ML_BITS)) == RUN_MASK) { + int s = 255; + while ((ip < iend) && (s == 255)) { + s = *ip++; + length += s; + } + } + /* copy literals */ + if ((grub_addr_t) length > ~(grub_addr_t)op) + goto _output_error; + cpy = op + length; + if ((cpy > oend - COPYLENGTH) || + (ip + length > iend - COPYLENGTH)) { + if (cpy > oend) + /* + * Error: request to write beyond destination + * buffer. + */ + goto _output_error; + if (ip + length > iend) + /* + * Error : request to read beyond source + * buffer. + */ + goto _output_error; + grub_memcpy(op, ip, length); + op += length; + ip += length; + if (ip < iend) + /* Error : LZ4 format violation */ + goto _output_error; + /* Necessarily EOF, due to parsing restrictions. */ + break; + } + LZ4_WILDCOPY(ip, op, cpy); + ip -= (op - cpy); + op = cpy; + + /* get offset */ + LZ4_READ_LITTLEENDIAN_16(ref, cpy, ip); + ip += 2; + if (ref < (BYTE * const) dest) + /* + * Error: offset creates reference outside of + * destination buffer. + */ + goto _output_error; + + /* get matchlength */ + if ((length = (token & ML_MASK)) == ML_MASK) { + while (ip < iend) { + int s = *ip++; + length += s; + if (s == 255) + continue; + break; + } + } + /* copy repeated sequence */ + if unlikely(op - ref < STEPSIZE) { +#if LZ4_ARCH64 + grub_size_t dec2table[] = { 0, 0, 0, -1, 0, 1, 2, 3 }; + grub_size_t dec2 = dec2table[op - ref]; +#else + const int dec2 = 0; +#endif + *op++ = *ref++; + *op++ = *ref++; + *op++ = *ref++; + *op++ = *ref++; + ref -= dec[op - ref]; + A32(op) = A32(ref); + op += STEPSIZE - 4; + ref -= dec2; + } else { + LZ4_COPYSTEP(ref, op); + } + cpy = op + length - (STEPSIZE - 4); + if (cpy > oend - COPYLENGTH) { + if (cpy > oend) + /* + * Error: request to write outside of + * destination buffer. + */ + goto _output_error; + LZ4_SECURECOPY(ref, op, (oend - COPYLENGTH)); + while (op < cpy) + *op++ = *ref++; + op = cpy; + if (op == oend) + /* + * Check EOF (should never happen, since last + * 5 bytes are supposed to be literals). + */ + break; + continue; + } + LZ4_SECURECOPY(ref, op, cpy); + op = cpy; /* correction */ + } + + /* end of decoding */ + return (int)(((char *)op) - dest); + + /* write overflow error detected */ + _output_error: + return (int)(-(((char *)ip) - source)); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/gfxmenu.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/gfxmenu.c new file mode 100644 index 0000000..1e2d4e5 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/gfxmenu.c @@ -0,0 +1,165 @@ +/* gfxmenu.c - Graphical menu interface controller. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +extern int g_ventoy_menu_refresh; + +static grub_gfxmenu_view_t cached_view; + +static void +grub_gfxmenu_viewer_fini (void *data __attribute__ ((unused))) +{ +} + +/* FIXME: Previously 't' changed to text menu is it necessary? */ +static grub_err_t +grub_gfxmenu_try (int entry, grub_menu_t menu, int nested) +{ + int force_refresh = 0; + grub_gfxmenu_view_t view = NULL; + const char *theme_path; + char *full_theme_path = 0; + struct grub_menu_viewer *instance; + grub_err_t err; + struct grub_video_mode_info mode_info; + + theme_path = grub_env_get ("theme"); + if (! theme_path) + return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), + "theme"); + + err = grub_video_get_info (&mode_info); + if (err) + return err; + + instance = grub_zalloc (sizeof (*instance)); + if (!instance) + return grub_errno; + + if (theme_path[0] != '/' && theme_path[0] != '(') + { + const char *prefix; + prefix = grub_env_get ("prefix"); + full_theme_path = grub_xasprintf ("%s/themes/%s", + prefix, + theme_path); + } + + if (g_ventoy_menu_refresh) + { + g_ventoy_menu_refresh = 0; + force_refresh = 1; + } + + if (force_refresh || + !cached_view || grub_strcmp (cached_view->theme_path, + full_theme_path ? : theme_path) != 0 + || cached_view->screen.width != mode_info.width + || cached_view->screen.height != mode_info.height) + { + grub_gfxmenu_view_destroy (cached_view); + /* Create the view. */ + cached_view = grub_gfxmenu_view_new (full_theme_path ? : theme_path, + mode_info.width, + mode_info.height); + } + grub_free (full_theme_path); + + if (! cached_view) + { + grub_free (instance); + return grub_errno; + } + + view = cached_view; + + view->double_repaint = (mode_info.mode_type + & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED) + && !(mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP); + view->selected = entry; + view->menu = menu; + view->nested = nested; + view->first_timeout = -1; + if (menu->size) + view->menu_title_offset = grub_zalloc (sizeof (*view->menu_title_offset) * menu->size); + + grub_video_set_viewport (0, 0, mode_info.width, mode_info.height); + if (view->double_repaint) + { + grub_video_swap_buffers (); + grub_video_set_viewport (0, 0, mode_info.width, mode_info.height); + } + + grub_gfxmenu_view_draw (view); + + instance->data = view; + instance->set_chosen_entry = grub_gfxmenu_set_chosen_entry; + instance->fini = grub_gfxmenu_viewer_fini; + instance->print_timeout = grub_gfxmenu_print_timeout; + instance->clear_timeout = grub_gfxmenu_clear_timeout; + if (view->menu_title_offset) + instance->scroll_chosen_entry = grub_gfxmenu_scroll_chosen_entry; + + grub_menu_register_viewer (instance); + + return GRUB_ERR_NONE; +} + +GRUB_MOD_INIT (gfxmenu) +{ + struct grub_term_output *term; + + FOR_ACTIVE_TERM_OUTPUTS(term) + if (grub_gfxmenu_try_hook && term->fullscreen) + { + term->fullscreen (); + break; + } + + grub_gfxmenu_try_hook = grub_gfxmenu_try; +} + +GRUB_MOD_FINI (gfxmenu) +{ + grub_gfxmenu_view_destroy (cached_view); + grub_gfxmenu_try_hook = NULL; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/gui_label.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/gui_label.c new file mode 100644 index 0000000..32e79f2 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/gui_label.c @@ -0,0 +1,324 @@ +/* gui_label.c - GUI component to display a line of text. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +extern int g_ventoy_memdisk_mode; +extern int g_ventoy_iso_raw; +extern int g_ventoy_grub2_mode; +extern int g_ventoy_wimboot_mode; +extern int g_ventoy_iso_uefi_drv; +extern char g_ventoy_hotkey_tip[256]; + +static const char *align_options[] = +{ + "left", + "center", + "right", + 0 +}; + +enum align_mode { + align_left, + align_center, + align_right +}; + +struct grub_gui_label +{ + struct grub_gui_component comp; + + grub_gui_container_t parent; + grub_video_rect_t bounds; + char *id; + int visible; + char *text; + char *template; + grub_font_t font; + grub_video_rgba_color_t color; + int value; + int vtoytip; + enum align_mode align; +}; + +typedef struct grub_gui_label *grub_gui_label_t; + +extern const char * g_ventoy_tip_msg1; +extern const char * g_ventoy_tip_msg2; + +static void +label_destroy (void *vself) +{ + grub_gui_label_t self = vself; + grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self); + grub_free (self->text); + grub_free (self->template); + grub_free (self); +} + +static const char * +label_get_id (void *vself) +{ + grub_gui_label_t self = vself; + return self->id; +} + +static int +label_is_instance (void *vself __attribute__((unused)), const char *type) +{ + return grub_strcmp (type, "component") == 0; +} + +static void +label_paint (void *vself, const grub_video_rect_t *region) +{ + const char *text; + grub_gui_label_t self = vself; + + if (! self->visible) + return; + + if (!grub_video_have_common_points (region, &self->bounds)) + return; + + if (self->vtoytip == 1) { + text = g_ventoy_tip_msg1 ? g_ventoy_tip_msg1 : ""; + } else if (self->vtoytip == 2) { + text = g_ventoy_tip_msg2 ? g_ventoy_tip_msg2 : ""; + } else { + text = self->text; + } + + /* Calculate the starting x coordinate. */ + int left_x; + if (self->align == align_left) + left_x = 0; + else if (self->align == align_center) + left_x = (self->bounds.width + - grub_font_get_string_width (self->font, text)) / 2; + else if (self->align == align_right) + left_x = (self->bounds.width + - grub_font_get_string_width (self->font, text)); + else + return; /* Invalid alignment. */ + + if (left_x < 0 || left_x > (int) self->bounds.width) + left_x = 0; + + grub_video_rect_t vpsave; + grub_gui_set_viewport (&self->bounds, &vpsave); + grub_font_draw_string (text, + self->font, + grub_video_map_rgba_color (self->color), + left_x, + grub_font_get_ascent (self->font)); + grub_gui_restore_viewport (&vpsave); +} + +static void +label_set_parent (void *vself, grub_gui_container_t parent) +{ + grub_gui_label_t self = vself; + self->parent = parent; +} + +static grub_gui_container_t +label_get_parent (void *vself) +{ + grub_gui_label_t self = vself; + return self->parent; +} + +static void +label_set_bounds (void *vself, const grub_video_rect_t *bounds) +{ + grub_gui_label_t self = vself; + self->bounds = *bounds; +} + +static void +label_get_bounds (void *vself, grub_video_rect_t *bounds) +{ + grub_gui_label_t self = vself; + *bounds = self->bounds; +} + +static void +label_get_minimal_size (void *vself, unsigned *width, unsigned *height) +{ + grub_gui_label_t self = vself; + *width = grub_font_get_string_width (self->font, self->text); + *height = (grub_font_get_ascent (self->font) + + grub_font_get_descent (self->font)); +} + +#pragma GCC diagnostic ignored "-Wformat-nonliteral" + +static void +label_set_state (void *vself, int visible, int start __attribute__ ((unused)), + int current, int end __attribute__ ((unused))) +{ + grub_gui_label_t self = vself; + self->value = -current; + self->visible = visible; + grub_free (self->text); + self->text = grub_xasprintf (self->template ? : "%d", self->value); +} + +static grub_err_t +label_set_property (void *vself, const char *name, const char *value) +{ + grub_gui_label_t self = vself; + if (grub_strcmp (name, "text") == 0) + { + grub_free (self->text); + grub_free (self->template); + if (! value) + { + self->template = NULL; + self->text = grub_strdup (""); + } + else + { + if (grub_strcmp (value, "@KEYMAP_LONG@") == 0) + value = _("Press enter to boot the selected OS, " + "`e' to edit the commands before booting " + "or `c' for a command-line. ESC to return previous menu."); + else if (grub_strcmp (value, "@KEYMAP_MIDDLE@") == 0) + value = _("Press enter to boot the selected OS, " + "`e' to edit the commands before booting " + "or `c' for a command-line."); + else if (grub_strcmp (value, "@KEYMAP_SHORT@") == 0) + value = _("enter: boot, `e': options, `c': cmd-line"); + /* FIXME: Add more templates here if needed. */ + + else if (grub_strcmp (value, "@VTOY_MEM_DISK@") == 0) { + value = g_ventoy_memdisk_mode ? grub_env_get("VTOY_MEM_DISK_STR") : " "; + } + else if (grub_strcmp (value, "@VTOY_ISO_RAW@") == 0) { + value = g_ventoy_iso_raw ? grub_env_get("VTOY_ISO_RAW_STR") : " "; + } + else if (grub_strcmp (value, "@VTOY_GRUB2_MODE@") == 0) { + value = g_ventoy_grub2_mode ? grub_env_get("VTOY_GRUB2_MODE_STR") : " "; + } + else if (grub_strcmp (value, "@VTOY_WIMBOOT_MODE@") == 0) { + value = g_ventoy_wimboot_mode ? grub_env_get("VTOY_WIMBOOT_MODE_STR") : " "; + } + else if (grub_strcmp (value, "@VTOY_ISO_UEFI_DRV@") == 0) { + value = g_ventoy_iso_uefi_drv ? grub_env_get("VTOY_ISO_UEFI_DRV_STR") : " "; + } + else if (grub_strcmp (value, "@VTOY_HOTKEY_TIP@") == 0) { + value = g_ventoy_hotkey_tip; + } else if (value[0] == '@' && value[1] == '@' && value[2]) { + value = grub_env_get(value + 2); + if (!value) + value = " "; + } + + self->template = grub_strdup (value); + self->text = grub_xasprintf (value, self->value); + } + } + else if (grub_strcmp (name, "font") == 0) + { + self->font = grub_font_get (value); + } + else if (grub_strcmp (name, "color") == 0) + { + grub_video_parse_color (value, &self->color); + } + else if (grub_strcmp (name, "align") == 0) + { + int i; + for (i = 0; align_options[i]; i++) + { + if (grub_strcmp (align_options[i], value) == 0) + { + self->align = i; /* Set the alignment mode. */ + break; + } + } + } + else if (grub_strcmp (name, "visible") == 0) + { + self->visible = grub_strcmp (value, "false") != 0; + } + else if (grub_strcmp (name, "id") == 0) + { + grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self); + grub_free (self->id); + if (value) { + self->id = grub_strdup (value); + if (grub_strcmp(value, "VTOY_MENU_TIP_1") == 0) { + self->vtoytip = 1; + } else if (grub_strcmp(value, "VTOY_MENU_TIP_2") == 0) { + self->vtoytip = 2; + } + } + else + self->id = 0; + if (self->id && grub_strcmp (self->id, GRUB_GFXMENU_TIMEOUT_COMPONENT_ID) + == 0) + grub_gfxmenu_timeout_register ((grub_gui_component_t) self, + label_set_state); + } + return GRUB_ERR_NONE; +} + +#pragma GCC diagnostic error "-Wformat-nonliteral" + +static struct grub_gui_component_ops label_ops = +{ + .destroy = label_destroy, + .get_id = label_get_id, + .is_instance = label_is_instance, + .paint = label_paint, + .set_parent = label_set_parent, + .get_parent = label_get_parent, + .set_bounds = label_set_bounds, + .get_bounds = label_get_bounds, + .get_minimal_size = label_get_minimal_size, + .set_property = label_set_property +}; + +grub_gui_component_t +grub_gui_label_new (void) +{ + grub_gui_label_t label; + label = grub_zalloc (sizeof (*label)); + if (! label) + return 0; + label->comp.ops = &label_ops; + label->visible = 1; + label->text = grub_strdup (""); + label->font = grub_font_get ("Unknown Regular 16"); + label->color.red = 0; + label->color.green = 0; + label->color.blue = 0; + label->color.alpha = 255; + label->align = align_left; + return (grub_gui_component_t) label; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/gui_list.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/gui_list.c new file mode 100644 index 0000000..6b25750 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/gui_list.c @@ -0,0 +1,961 @@ +/* gui_list.c - GUI component to display a selectable list of items. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +enum scrollbar_slice_mode { + SCROLLBAR_SLICE_WEST, + SCROLLBAR_SLICE_CENTER, + SCROLLBAR_SLICE_EAST +}; + +struct grub_gui_list_impl +{ + struct grub_gui_list list; + + grub_gui_container_t parent; + grub_video_rect_t bounds; + char *id; + int visible; + + int icon_width; + int icon_height; + int item_height; + int item_padding; + int item_icon_space; + int item_spacing; + grub_font_t item_font; + int selected_item_font_inherit; + grub_font_t selected_item_font; + grub_video_rgba_color_t item_color; + int selected_item_color_inherit; + grub_video_rgba_color_t selected_item_color; + + int draw_scrollbar; + int need_to_recreate_scrollbar; + char *scrollbar_frame_pattern; + char *scrollbar_thumb_pattern; + grub_gfxmenu_box_t scrollbar_frame; + grub_gfxmenu_box_t scrollbar_thumb; + int scrollbar_thumb_overlay; + int scrollbar_width; + enum scrollbar_slice_mode scrollbar_slice; + int scrollbar_left_pad; + int scrollbar_right_pad; + int scrollbar_top_pad; + int scrollbar_bottom_pad; + + int first_shown_index; + + int need_to_recreate_boxes; + char *theme_dir; + char *menu_box_pattern; + char *item_box_pattern; + int selected_item_box_pattern_inherit; + char *selected_item_box_pattern; + grub_gfxmenu_box_t menu_box; + grub_gfxmenu_box_t selected_item_box; + grub_gfxmenu_box_t item_box; + + grub_gfxmenu_icon_manager_t icon_manager; + + grub_gfxmenu_view_t view; +}; + +typedef struct grub_gui_list_impl *list_impl_t; + +static void +list_destroy (void *vself) +{ + list_impl_t self = vself; + + grub_free (self->theme_dir); + grub_free (self->menu_box_pattern); + grub_free (self->item_box_pattern); + grub_free (self->selected_item_box_pattern); + if (self->menu_box) + self->menu_box->destroy (self->menu_box); + if (self->item_box) + self->item_box->destroy (self->item_box); + if (self->selected_item_box) + self->selected_item_box->destroy (self->selected_item_box); + if (self->icon_manager) + grub_gfxmenu_icon_manager_destroy (self->icon_manager); + if (self->scrollbar_thumb) + self->scrollbar_thumb->destroy (self->scrollbar_thumb); + if (self->scrollbar_frame) + self->scrollbar_frame->destroy (self->scrollbar_frame); + grub_free (self->scrollbar_thumb_pattern); + grub_free (self->scrollbar_frame_pattern); + grub_free (self); +} + +static int +get_num_shown_items (list_impl_t self) +{ + int boxpad = self->item_padding; + int item_vspace = self->item_spacing; + int item_height = self->item_height; + + grub_gfxmenu_box_t box = self->menu_box; + int box_top_pad = box->get_top_pad (box); + int box_bottom_pad = box->get_bottom_pad (box); + grub_gfxmenu_box_t itembox = self->item_box; + grub_gfxmenu_box_t selbox = self->selected_item_box; + int item_top_pad = itembox->get_top_pad (itembox); + int item_bottom_pad = itembox->get_bottom_pad (itembox); + int sel_top_pad = selbox->get_top_pad (selbox); + int sel_bottom_pad = selbox->get_bottom_pad (selbox); + int max_top_pad = grub_max (item_top_pad, sel_top_pad); + int max_bottom_pad = grub_max (item_bottom_pad, sel_bottom_pad); + + if (item_height + item_vspace <= 0) + return 1; + + return (self->bounds.height + item_vspace - 2 * boxpad + - max_top_pad - max_bottom_pad + - box_top_pad - box_bottom_pad) / (item_height + item_vspace); +} + +static int +check_boxes (list_impl_t self) +{ + if (self->need_to_recreate_boxes) + { + grub_gui_recreate_box (&self->menu_box, + self->menu_box_pattern, + self->theme_dir); + + grub_gui_recreate_box (&self->item_box, + self->item_box_pattern, + self->theme_dir); + + grub_gui_recreate_box (&self->selected_item_box, + self->selected_item_box_pattern, + self->theme_dir); + + self->need_to_recreate_boxes = 0; + } + + return (self->menu_box != 0 && self->selected_item_box != 0 + && self->item_box != 0); +} + +static int +check_scrollbar (list_impl_t self) +{ + if (self->need_to_recreate_scrollbar) + { + grub_gui_recreate_box (&self->scrollbar_frame, + self->scrollbar_frame_pattern, + self->theme_dir); + + grub_gui_recreate_box (&self->scrollbar_thumb, + self->scrollbar_thumb_pattern, + self->theme_dir); + + self->need_to_recreate_scrollbar = 0; + } + + if (self->scrollbar_frame == 0 || self->scrollbar_thumb == 0) + return 0; + + /* Sanity checks. */ + grub_gfxmenu_box_t frame = self->scrollbar_frame; + grub_gfxmenu_box_t thumb = self->scrollbar_thumb; + grub_gfxmenu_box_t menu = self->menu_box; + int min_width = frame->get_left_pad (frame) + + frame->get_right_pad (frame); + int min_height = frame->get_top_pad (frame) + + frame->get_bottom_pad (frame) + + self->scrollbar_top_pad + self->scrollbar_bottom_pad + + menu->get_top_pad (menu) + + menu->get_bottom_pad (menu); + if (!self->scrollbar_thumb_overlay) + { + min_width += thumb->get_left_pad (thumb) + + thumb->get_right_pad (thumb); + min_height += thumb->get_top_pad (thumb) + + thumb->get_bottom_pad (thumb); + } + if (min_width <= self->scrollbar_width + && min_height <= (int) self->bounds.height) + return 1; + + /* Unprintable dimenstions. */ + self->draw_scrollbar = 0; + return 0; +} + +static const char * +list_get_id (void *vself) +{ + list_impl_t self = vself; + return self->id; +} + +static int +list_is_instance (void *vself __attribute__((unused)), const char *type) +{ + return (grub_strcmp (type, "component") == 0 + || grub_strcmp (type, "list") == 0); +} + +static struct grub_video_bitmap * +get_item_icon (list_impl_t self, int item_index) +{ + grub_menu_entry_t entry; + entry = grub_menu_get_entry (self->view->menu, item_index); + if (! entry) + return 0; + + return grub_gfxmenu_icon_manager_get_icon (self->icon_manager, entry); +} + +static void +make_selected_item_visible (list_impl_t self) +{ + int selected_index = self->view->selected; + if (selected_index < 0) + return; /* No item is selected. */ + int num_shown_items = get_num_shown_items (self); + int last_shown_index = self->first_shown_index + (num_shown_items - 1); + if (selected_index < self->first_shown_index) + self->first_shown_index = selected_index; + else if (selected_index > last_shown_index) + self->first_shown_index = selected_index - (num_shown_items - 1); +} + +/* Draw a scrollbar on the menu. */ +static void +draw_scrollbar (list_impl_t self, + int value, int extent, int min, int max, + int scrollbar_width, int scrollbar_height) +{ + unsigned thumby, thumbheight; + + grub_gfxmenu_box_t frame = self->scrollbar_frame; + grub_gfxmenu_box_t thumb = self->scrollbar_thumb; + int frame_vertical_pad = (frame->get_top_pad (frame) + + frame->get_bottom_pad (frame)); + int frame_horizontal_pad = (frame->get_left_pad (frame) + + frame->get_right_pad (frame)); + unsigned thumb_vertical_pad = (thumb->get_top_pad (thumb) + + thumb->get_bottom_pad (thumb)); + int thumb_horizontal_pad = (thumb->get_left_pad (thumb) + + thumb->get_right_pad (thumb)); + int tracktop = frame->get_top_pad (frame); + unsigned tracklen; + if (scrollbar_height <= frame_vertical_pad) + tracklen = 0; + else + tracklen = scrollbar_height - frame_vertical_pad; + frame->set_content_size (frame, + scrollbar_width - frame_horizontal_pad, + tracklen); + if (self->scrollbar_thumb_overlay) + { + tracklen += thumb_vertical_pad; + tracktop -= thumb->get_top_pad (thumb); + } + if (value <= min || max <= min) + thumby = 0; + else + thumby = ((unsigned) tracklen * (value - min)) + / ((unsigned) (max - min)); + if (max <= min) + thumbheight = 1; + else + thumbheight = ((unsigned) (tracklen * extent) + / ((unsigned) (max - min))) + 1; + /* Rare occasion: too many entries or too low height. */ + if (thumbheight < thumb_vertical_pad) + { + thumbheight = thumb_vertical_pad; + if (value <= min || max <= extent + || tracklen <= thumb_vertical_pad) + thumby = 0; + else + thumby = ((unsigned) ((tracklen - thumb_vertical_pad) * (value - min)) + / ((unsigned)(max - extent))); + } + thumby += tracktop; + int thumbx = frame->get_left_pad (frame); + int thumbwidth = scrollbar_width - frame_horizontal_pad; + if (!self->scrollbar_thumb_overlay) + thumbwidth -= thumb_horizontal_pad; + else + thumbx -= thumb->get_left_pad (thumb); + thumb->set_content_size (thumb, thumbwidth, + thumbheight - thumb_vertical_pad); + frame->draw (frame, 0, 0); + thumb->draw (thumb, thumbx, thumby); +} + +/* Draw the list of items. */ +static void +draw_menu (list_impl_t self, int num_shown_items) +{ + if (! self->menu_box || ! self->selected_item_box || ! self->item_box) + return; + + int boxpad = self->item_padding; + int icon_text_space = self->item_icon_space; + int item_vspace = self->item_spacing; + + int ascent = grub_font_get_ascent (self->item_font); + int descent = grub_font_get_descent (self->item_font); + int selected_ascent = grub_font_get_ascent (self->selected_item_font); + int selected_descent = grub_font_get_descent (self->selected_item_font); + int text_box_height = self->item_height; + + make_selected_item_visible (self); + + grub_gfxmenu_box_t itembox = self->item_box; + grub_gfxmenu_box_t selbox = self->selected_item_box; + int item_leftpad = itembox->get_left_pad (itembox); + int item_rightpad = itembox->get_right_pad (itembox); + int item_border_width = item_leftpad + item_rightpad; + int item_toppad = itembox->get_top_pad (itembox); + int sel_leftpad = selbox->get_left_pad (selbox); + int sel_rightpad = selbox->get_right_pad (selbox); + int sel_border_width = sel_leftpad + sel_rightpad; + int sel_toppad = selbox->get_top_pad (selbox); + + int max_leftpad = grub_max (item_leftpad, sel_leftpad); + int max_toppad = grub_max (item_toppad, sel_toppad); + int item_top = 0; + int menu_index; + int visible_index; + struct grub_video_rect oviewport; + + grub_video_get_viewport (&oviewport.x, &oviewport.y, + &oviewport.width, &oviewport.height); + grub_video_set_viewport (oviewport.x + boxpad, + oviewport.y + boxpad, + oviewport.width - 2 * boxpad, + oviewport.height - 2 * boxpad); + + int cwidth = oviewport.width - 2 * boxpad; + + itembox->set_content_size (itembox, cwidth - item_border_width, + text_box_height); + selbox->set_content_size (selbox, cwidth - sel_border_width, + text_box_height); + + int text_left_offset = self->icon_width + icon_text_space; + int item_text_top_offset = (text_box_height - (ascent + descent)) / 2 + ascent; + int sel_text_top_offset = (text_box_height - (selected_ascent + + selected_descent)) / 2 + + selected_ascent; + + grub_video_rect_t svpsave, sviewport; + sviewport.x = max_leftpad + text_left_offset; + int text_viewport_width = cwidth - sviewport.x; + sviewport.height = text_box_height; + + grub_video_color_t item_color; + grub_video_color_t sel_color; + item_color = grub_video_map_rgba_color (self->item_color); + sel_color = grub_video_map_rgba_color (self->selected_item_color); + + int item_box_top_offset = max_toppad - item_toppad; + int sel_box_top_offset = max_toppad - sel_toppad; + int item_viewport_width = text_viewport_width - item_rightpad; + int sel_viewport_width = text_viewport_width - sel_rightpad; + int tmp_icon_top_offset = (text_box_height - self->icon_height) / 2; + int item_icon_top_offset = item_toppad + tmp_icon_top_offset; + int sel_icon_top_offset = sel_toppad + tmp_icon_top_offset; + + for (visible_index = 0, menu_index = self->first_shown_index; + visible_index < num_shown_items && menu_index < self->view->menu->size; + visible_index++, menu_index++) + { + int is_selected = (menu_index == self->view->selected); + struct grub_video_bitmap *icon; + grub_font_t font; + grub_video_color_t color; + int text_top_offset; + int top_pad; + int icon_top_offset; + int viewport_width; + + if (is_selected) + { + selbox->draw (selbox, 0, item_top + sel_box_top_offset); + font = self->selected_item_font; + color = sel_color; + text_top_offset = sel_text_top_offset; + top_pad = sel_toppad; + icon_top_offset = sel_icon_top_offset; + viewport_width = sel_viewport_width; + } + else + { + itembox->draw (itembox, 0, item_top + item_box_top_offset); + font = self->item_font; + color = item_color; + text_top_offset = item_text_top_offset; + top_pad = item_toppad; + icon_top_offset = item_icon_top_offset; + viewport_width = item_viewport_width; + } + + icon = get_item_icon (self, menu_index); + if (icon != 0) + grub_video_blit_bitmap (icon, GRUB_VIDEO_BLIT_BLEND, + max_leftpad, + item_top + icon_top_offset, + 0, 0, self->icon_width, self->icon_height); + + const char *item_title = + grub_menu_get_entry (self->view->menu, menu_index)->title; + + + int off = self->view->menu_title_offset[menu_index]; + const char *scrolled_title = + grub_utf8_offset_code (item_title, grub_strlen (item_title), off); + if (scrolled_title) + item_title = scrolled_title; + + sviewport.y = item_top + top_pad; + sviewport.width = viewport_width; + grub_gui_set_viewport (&sviewport, &svpsave); + grub_font_draw_string (item_title, + font, + color, + 0, + text_top_offset); + grub_gui_restore_viewport (&svpsave); + + item_top += text_box_height + item_vspace; + } + grub_video_set_viewport (oviewport.x, + oviewport.y, + oviewport.width, + oviewport.height); +} + +static void +list_paint (void *vself, const grub_video_rect_t *region) +{ + list_impl_t self = vself; + grub_video_rect_t vpsave; + + if (! self->visible) + return; + if (!grub_video_have_common_points (region, &self->bounds)) + return; + + check_boxes (self); + + if (! self->menu_box || ! self->selected_item_box || ! self->item_box) + return; + + grub_gui_set_viewport (&self->bounds, &vpsave); + { + grub_gfxmenu_box_t box = self->menu_box; + int box_left_pad = box->get_left_pad (box); + int box_top_pad = box->get_top_pad (box); + int box_right_pad = box->get_right_pad (box); + int box_bottom_pad = box->get_bottom_pad (box); + grub_video_rect_t vpsave2, content_rect; + int num_shown_items = get_num_shown_items (self); + int drawing_scrollbar = (self->draw_scrollbar + && (num_shown_items < self->view->menu->size) + && check_scrollbar (self)); + int scrollbar_width = self->scrollbar_width; + + content_rect.x = box_left_pad; + content_rect.y = box_top_pad; + content_rect.width = self->bounds.width - box_left_pad - box_right_pad; + content_rect.height = self->bounds.height - box_top_pad - box_bottom_pad; + + box->set_content_size (box, content_rect.width, content_rect.height); + + box->draw (box, 0, 0); + + switch (self->scrollbar_slice) + { + case SCROLLBAR_SLICE_WEST: + content_rect.x += self->scrollbar_right_pad; + content_rect.width -= self->scrollbar_right_pad; + break; + case SCROLLBAR_SLICE_CENTER: + if (drawing_scrollbar) + content_rect.width -= scrollbar_width + self->scrollbar_left_pad + + self->scrollbar_right_pad; + break; + case SCROLLBAR_SLICE_EAST: + content_rect.width -= self->scrollbar_left_pad; + break; + } + + grub_gui_set_viewport (&content_rect, &vpsave2); + draw_menu (self, num_shown_items); + grub_gui_restore_viewport (&vpsave2); + + if (drawing_scrollbar) + { + content_rect.y += self->scrollbar_top_pad; + content_rect.height -= self->scrollbar_top_pad + + self->scrollbar_bottom_pad; + content_rect.width = scrollbar_width; + switch (self->scrollbar_slice) + { + case SCROLLBAR_SLICE_WEST: + if (box_left_pad > scrollbar_width) + { + content_rect.x = box_left_pad - scrollbar_width; + content_rect.width = scrollbar_width; + } + else + { + content_rect.x = 0; + content_rect.width = box_left_pad; + } + break; + case SCROLLBAR_SLICE_CENTER: + content_rect.x = self->bounds.width - box_right_pad + - scrollbar_width - self->scrollbar_right_pad; + content_rect.width = scrollbar_width; + break; + case SCROLLBAR_SLICE_EAST: + content_rect.x = self->bounds.width - box_right_pad; + content_rect.width = box_right_pad; + break; + } + + grub_gui_set_viewport (&content_rect, &vpsave2); + draw_scrollbar (self, + self->first_shown_index, num_shown_items, + 0, self->view->menu->size, + scrollbar_width, + content_rect.height); + grub_gui_restore_viewport (&vpsave2); + } + } + + grub_gui_restore_viewport (&vpsave); +} + +static void +list_set_parent (void *vself, grub_gui_container_t parent) +{ + list_impl_t self = vself; + self->parent = parent; +} + +static grub_gui_container_t +list_get_parent (void *vself) +{ + list_impl_t self = vself; + return self->parent; +} + +static void +list_set_bounds (void *vself, const grub_video_rect_t *bounds) +{ + list_impl_t self = vself; + self->bounds = *bounds; +} + +static void +list_get_bounds (void *vself, grub_video_rect_t *bounds) +{ + list_impl_t self = vself; + *bounds = self->bounds; +} + +static void +list_get_minimal_size (void *vself, unsigned *width, unsigned *height) +{ + list_impl_t self = vself; + + if (check_boxes (self)) + { + int boxpad = self->item_padding; + int item_vspace = self->item_spacing; + int item_height = self->item_height; + int num_items = 3; + + grub_gfxmenu_box_t box = self->menu_box; + int box_left_pad = box->get_left_pad (box); + int box_top_pad = box->get_top_pad (box); + int box_right_pad = box->get_right_pad (box); + int box_bottom_pad = box->get_bottom_pad (box); + unsigned width_s; + + grub_gfxmenu_box_t selbox = self->selected_item_box; + int sel_top_pad = selbox->get_top_pad (selbox); + int sel_bottom_pad = selbox->get_bottom_pad (selbox); + int sel_left_pad = selbox->get_left_pad (selbox); + int sel_right_pad = selbox->get_right_pad (selbox); + + grub_gfxmenu_box_t itembox = self->item_box; + int item_top_pad = itembox->get_top_pad (itembox); + int item_bottom_pad = itembox->get_bottom_pad (itembox); + int item_left_pad = itembox->get_left_pad (itembox); + int item_right_pad = itembox->get_right_pad (itembox); + + int max_left_pad = grub_max (item_left_pad, sel_left_pad); + int max_right_pad = grub_max (item_right_pad, sel_right_pad); + int max_top_pad = grub_max (item_top_pad, sel_top_pad); + int max_bottom_pad = grub_max (item_bottom_pad, sel_bottom_pad); + + *width = grub_font_get_string_width (self->item_font, "Typical OS"); + width_s = grub_font_get_string_width (self->selected_item_font, + "Typical OS"); + if (*width < width_s) + *width = width_s; + + *width += 2 * boxpad + box_left_pad + box_right_pad + + max_left_pad + max_right_pad + + self->item_icon_space + self->icon_width; + + switch (self->scrollbar_slice) + { + case SCROLLBAR_SLICE_WEST: + *width += self->scrollbar_right_pad; + break; + case SCROLLBAR_SLICE_CENTER: + *width += self->scrollbar_width + self->scrollbar_left_pad + + self->scrollbar_right_pad; + break; + case SCROLLBAR_SLICE_EAST: + *width += self->scrollbar_left_pad; + break; + } + + /* Set the menu box height to fit the items. */ + *height = (item_height * num_items + + item_vspace * (num_items - 1) + + 2 * boxpad + + box_top_pad + box_bottom_pad + + max_top_pad + max_bottom_pad); + } + else + { + *width = 0; + *height = 0; + } +} + +static grub_err_t +list_set_property (void *vself, const char *name, const char *value) +{ + list_impl_t self = vself; + if (grub_strcmp (name, "item_font") == 0) + { + self->item_font = grub_font_get (value); + if (self->selected_item_font_inherit) + self->selected_item_font = self->item_font; + } + else if (grub_strcmp (name, "selected_item_font") == 0) + { + if (! value || grub_strcmp (value, "inherit") == 0) + { + self->selected_item_font = self->item_font; + self->selected_item_font_inherit = 1; + } + else + { + self->selected_item_font = grub_font_get (value); + self->selected_item_font_inherit = 0; + } + } + else if (grub_strcmp (name, "item_color") == 0) + { + grub_video_rgba_color_t color; + if (grub_video_parse_color (value, &color) == GRUB_ERR_NONE) + { + self->item_color = color; + if (self->selected_item_color_inherit) + self->selected_item_color = self->item_color; + } + } + else if (grub_strcmp (name, "selected_item_color") == 0) + { + if (! value || grub_strcmp (value, "inherit") == 0) + { + self->selected_item_color = self->item_color; + self->selected_item_color_inherit = 1; + } + else + { + grub_video_rgba_color_t color; + if (grub_video_parse_color (value, &color) + == GRUB_ERR_NONE) + { + self->selected_item_color = color; + self->selected_item_color_inherit = 0; + } + } + } + else if (grub_strcmp (name, "icon_width") == 0) + { + self->icon_width = grub_strtol (value, 0, 10); + grub_gfxmenu_icon_manager_set_icon_size (self->icon_manager, + self->icon_width, + self->icon_height); + } + else if (grub_strcmp (name, "icon_height") == 0) + { + self->icon_height = grub_strtol (value, 0, 10); + grub_gfxmenu_icon_manager_set_icon_size (self->icon_manager, + self->icon_width, + self->icon_height); + } + else if (grub_strcmp (name, "item_height") == 0) + { + self->item_height = grub_strtol (value, 0, 10); + } + else if (grub_strcmp (name, "item_padding") == 0) + { + self->item_padding = grub_strtol (value, 0, 10); + } + else if (grub_strcmp (name, "item_icon_space") == 0) + { + self->item_icon_space = grub_strtol (value, 0, 10); + } + else if (grub_strcmp (name, "item_spacing") == 0) + { + self->item_spacing = grub_strtol (value, 0, 10); + } + else if (grub_strcmp (name, "visible") == 0) + { + self->visible = grub_strcmp (value, "false") != 0; + } + else if (grub_strcmp (name, "menu_pixmap_style") == 0) + { + self->need_to_recreate_boxes = 1; + grub_free (self->menu_box_pattern); + self->menu_box_pattern = value ? grub_strdup (value) : 0; + } + else if (grub_strcmp (name, "item_pixmap_style") == 0) + { + self->need_to_recreate_boxes = 1; + grub_free (self->item_box_pattern); + self->item_box_pattern = value ? grub_strdup (value) : 0; + if (self->selected_item_box_pattern_inherit) + { + grub_free (self->selected_item_box_pattern); + self->selected_item_box_pattern = value ? grub_strdup (value) : 0; + } + } + else if (grub_strcmp (name, "selected_item_pixmap_style") == 0) + { + if (!value || grub_strcmp (value, "inherit") == 0) + { + grub_free (self->selected_item_box_pattern); + char *tmp = self->item_box_pattern; + self->selected_item_box_pattern = tmp ? grub_strdup (tmp) : 0; + self->selected_item_box_pattern_inherit = 1; + } + else + { + self->need_to_recreate_boxes = 1; + grub_free (self->selected_item_box_pattern); + self->selected_item_box_pattern = value ? grub_strdup (value) : 0; + self->selected_item_box_pattern_inherit = 0; + } + } + else if (grub_strcmp (name, "scrollbar_frame") == 0) + { + self->need_to_recreate_scrollbar = 1; + grub_free (self->scrollbar_frame_pattern); + self->scrollbar_frame_pattern = value ? grub_strdup (value) : 0; + } + else if (grub_strcmp (name, "scrollbar_thumb") == 0) + { + self->need_to_recreate_scrollbar = 1; + grub_free (self->scrollbar_thumb_pattern); + self->scrollbar_thumb_pattern = value ? grub_strdup (value) : 0; + } + else if (grub_strcmp (name, "scrollbar_thumb_overlay") == 0) + { + self->scrollbar_thumb_overlay = grub_strcmp (value, "true") == 0; + } + else if (grub_strcmp (name, "scrollbar_width") == 0) + { + self->scrollbar_width = grub_strtol (value, 0, 10); + } + else if (grub_strcmp (name, "scrollbar_slice") == 0) + { + if (grub_strcmp (value, "west") == 0) + self->scrollbar_slice = SCROLLBAR_SLICE_WEST; + else if (grub_strcmp (value, "center") == 0) + self->scrollbar_slice = SCROLLBAR_SLICE_CENTER; + else if (grub_strcmp (value, "east") == 0) + self->scrollbar_slice = SCROLLBAR_SLICE_EAST; + } + else if (grub_strcmp (name, "scrollbar_left_pad") == 0) + { + self->scrollbar_left_pad = grub_strtol (value, 0, 10); + } + else if (grub_strcmp (name, "scrollbar_right_pad") == 0) + { + self->scrollbar_right_pad = grub_strtol (value, 0, 10); + } + else if (grub_strcmp (name, "scrollbar_top_pad") == 0) + { + self->scrollbar_top_pad = grub_strtol (value, 0, 10); + } + else if (grub_strcmp (name, "scrollbar_bottom_pad") == 0) + { + self->scrollbar_bottom_pad = grub_strtol (value, 0, 10); + } + else if (grub_strcmp (name, "scrollbar") == 0) + { + self->draw_scrollbar = grub_strcmp (value, "false") != 0; + } + else if (grub_strcmp (name, "theme_dir") == 0) + { + self->need_to_recreate_boxes = 1; + grub_free (self->theme_dir); + self->theme_dir = value ? grub_strdup (value) : 0; + } + else if (grub_strcmp (name, "id") == 0) + { + grub_free (self->id); + if (value) + self->id = grub_strdup (value); + else + self->id = 0; + } + return grub_errno; +} + +/* Set necessary information that the gfxmenu view provides. */ +static void +list_set_view_info (void *vself, + grub_gfxmenu_view_t view) +{ + list_impl_t self = vself; + grub_gfxmenu_icon_manager_set_theme_path (self->icon_manager, + view->theme_path); + self->view = view; +} + +/* Refresh list variables */ +static void +list_refresh_info (void *vself, + grub_gfxmenu_view_t view) +{ + list_impl_t self = vself; + if (view->nested) + self->first_shown_index = 0; +} + +static struct grub_gui_component_ops list_comp_ops = + { + .destroy = list_destroy, + .get_id = list_get_id, + .is_instance = list_is_instance, + .paint = list_paint, + .set_parent = list_set_parent, + .get_parent = list_get_parent, + .set_bounds = list_set_bounds, + .get_bounds = list_get_bounds, + .get_minimal_size = list_get_minimal_size, + .set_property = list_set_property + }; + +static struct grub_gui_list_ops list_ops = +{ + .set_view_info = list_set_view_info, + .refresh_list = list_refresh_info +}; + +grub_gui_component_t +grub_gui_list_new (void) +{ + list_impl_t self; + grub_font_t default_font; + grub_video_rgba_color_t default_fg_color; + + self = grub_zalloc (sizeof (*self)); + if (! self) + return 0; + + self->list.ops = &list_ops; + self->list.component.ops = &list_comp_ops; + + self->visible = 1; + + default_font = grub_font_get ("Unknown Regular 16"); + default_fg_color = grub_video_rgba_color_rgb (0, 0, 0); + + self->icon_width = 32; + self->icon_height = 32; + self->item_height = 42; + self->item_padding = 14; + self->item_icon_space = 4; + self->item_spacing = 16; + self->item_font = default_font; + self->selected_item_font_inherit = 1; /* Default to using the item_font. */ + self->selected_item_font = default_font; + self->item_color = default_fg_color; + self->selected_item_color_inherit = 1; /* Default to using the item_color. */ + self->selected_item_color = default_fg_color; + + self->draw_scrollbar = 1; + self->need_to_recreate_scrollbar = 1; + self->scrollbar_frame = 0; + self->scrollbar_thumb = 0; + self->scrollbar_frame_pattern = 0; + self->scrollbar_thumb_pattern = 0; + self->scrollbar_thumb_overlay = 0; + self->scrollbar_width = 16; + self->scrollbar_slice = SCROLLBAR_SLICE_EAST; + self->scrollbar_left_pad = 2; + self->scrollbar_right_pad = 0; + self->scrollbar_top_pad = 0; + self->scrollbar_bottom_pad = 0; + + self->first_shown_index = 0; + + self->need_to_recreate_boxes = 0; + self->theme_dir = 0; + self->menu_box_pattern = 0; + self->item_box_pattern = 0; + self->selected_item_box_pattern_inherit = 1;/*Default to using the item_box.*/ + self->selected_item_box_pattern = 0; + self->menu_box = grub_gfxmenu_create_box (0, 0); + self->item_box = grub_gfxmenu_create_box (0, 0); + self->selected_item_box = grub_gfxmenu_create_box (0, 0); + + self->icon_manager = grub_gfxmenu_icon_manager_new (); + if (! self->icon_manager) + { + self->list.component.ops->destroy (self); + return 0; + } + grub_gfxmenu_icon_manager_set_icon_size (self->icon_manager, + self->icon_width, + self->icon_height); + return (grub_gui_component_t) self; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/theme_loader.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/theme_loader.c new file mode 100644 index 0000000..af90ce4 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/theme_loader.c @@ -0,0 +1,893 @@ +/* theme_loader.c - Theme file loader for gfxmenu. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static grub_err_t +parse_proportional_spec (const char *value, signed *abs, grub_fixed_signed_t *prop); + +/* Construct a new box widget using ABSPATTERN to find the pixmap files for + it, storing the new box instance at *BOXPTR. + PATTERN should be of the form: "(hd0,0)/somewhere/style*.png". + The '*' then gets substituted with the various pixmap names that the + box uses. */ +static grub_err_t +recreate_box_absolute (grub_gfxmenu_box_t *boxptr, const char *abspattern) +{ + char *prefix; + char *suffix; + char *star; + grub_gfxmenu_box_t box; + + star = grub_strchr (abspattern, '*'); + if (! star) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "missing `*' in box pixmap pattern `%s'", abspattern); + + /* Prefix: Get the part before the '*'. */ + prefix = grub_malloc (star - abspattern + 1); + if (! prefix) + return grub_errno; + + grub_memcpy (prefix, abspattern, star - abspattern); + prefix[star - abspattern] = '\0'; + + /* Suffix: Everything after the '*' is the suffix. */ + suffix = star + 1; + + box = grub_gfxmenu_create_box (prefix, suffix); + grub_free (prefix); + if (! box) + return grub_errno; + + if (*boxptr) + (*boxptr)->destroy (*boxptr); + *boxptr = box; + return grub_errno; +} + + +/* Construct a new box widget using PATTERN to find the pixmap files for it, + storing the new widget at *BOXPTR. PATTERN should be of the form: + "somewhere/style*.png". The '*' then gets substituted with the various + pixmap names that the widget uses. + + Important! The value of *BOXPTR must be initialized! It must either + (1) Be 0 (a NULL pointer), or + (2) Be a pointer to a valid 'grub_gfxmenu_box_t' instance. + In this case, the previous instance is destroyed. */ +grub_err_t +grub_gui_recreate_box (grub_gfxmenu_box_t *boxptr, + const char *pattern, const char *theme_dir) +{ + char *abspattern; + + /* Check arguments. */ + if (! pattern) + { + /* If no pixmap pattern is given, then just create an empty box. */ + if (*boxptr) + (*boxptr)->destroy (*boxptr); + *boxptr = grub_gfxmenu_create_box (0, 0); + return grub_errno; + } + + if (! theme_dir) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "styled box missing theme directory"); + + /* Resolve to an absolute path. */ + abspattern = grub_resolve_relative_path (theme_dir, pattern); + if (! abspattern) + return grub_errno; + + /* Create the box. */ + recreate_box_absolute (boxptr, abspattern); + grub_free (abspattern); + return grub_errno; +} + +static grub_err_t +theme_get_unsigned_int_from_proportional (const char *value, + unsigned absolute_value, + unsigned int *parsed_value) +{ + grub_err_t err; + grub_fixed_signed_t frac; + signed pixels; + err = parse_proportional_spec (value, &pixels, &frac); + if (err != GRUB_ERR_NONE) + return err; + int result = grub_fixed_sfs_multiply (absolute_value, frac) + pixels; + if (result < 0) + result = 0; + *parsed_value = result; + return GRUB_ERR_NONE; +} + +/* Set the specified property NAME on the view to the given string VALUE. + The caller is responsible for the lifetimes of NAME and VALUE. */ +static grub_err_t +theme_set_string (grub_gfxmenu_view_t view, + const char *name, + const char *value, + const char *theme_dir, + const char *filename, + int line_num, + int col_num) +{ + if (! grub_strcmp ("title-font", name)) + view->title_font = grub_font_get (value); + else if (! grub_strcmp ("message-font", name)) + view->message_font = grub_font_get (value); + else if (! grub_strcmp ("terminal-font", name)) + { + grub_free (view->terminal_font_name); + view->terminal_font_name = grub_strdup (value); + if (! view->terminal_font_name) + return grub_errno; + } + else if (! grub_strcmp ("title-color", name)) + grub_video_parse_color (value, &view->title_color); + else if (! grub_strcmp ("message-color", name)) + grub_video_parse_color (value, &view->message_color); + else if (! grub_strcmp ("message-bg-color", name)) + grub_video_parse_color (value, &view->message_bg_color); + else if (! grub_strcmp("menu-tip-left", name)) + grub_env_set("VTOY_TIP_LEFT", value); + else if (! grub_strcmp("menu-tip-top", name)) + grub_env_set("VTOY_TIP_TOP", value); + else if (! grub_strcmp("menu-tip-color", name)) + grub_env_set("VTOY_TIP_COLOR", value); + else if (! grub_strcmp ("desktop-image", name)) + { + struct grub_video_bitmap *raw_bitmap; + char *path; + path = grub_resolve_relative_path (theme_dir, value); + if (! path) + return grub_errno; + if (grub_video_bitmap_load (&raw_bitmap, path) != GRUB_ERR_NONE) + { + grub_free (path); + return grub_errno; + } + grub_free(path); + grub_video_bitmap_destroy (view->raw_desktop_image); + view->raw_desktop_image = raw_bitmap; + } + else if (! grub_strcmp ("desktop-image-scale-method", name)) + { + if (! value || ! grub_strcmp ("stretch", value)) + view->desktop_image_scale_method = + GRUB_VIDEO_BITMAP_SELECTION_METHOD_STRETCH; + else if (! grub_strcmp ("crop", value)) + view->desktop_image_scale_method = + GRUB_VIDEO_BITMAP_SELECTION_METHOD_CROP; + else if (! grub_strcmp ("padding", value)) + view->desktop_image_scale_method = + GRUB_VIDEO_BITMAP_SELECTION_METHOD_PADDING; + else if (! grub_strcmp ("fitwidth", value)) + view->desktop_image_scale_method = + GRUB_VIDEO_BITMAP_SELECTION_METHOD_FITWIDTH; + else if (! grub_strcmp ("fitheight", value)) + view->desktop_image_scale_method = + GRUB_VIDEO_BITMAP_SELECTION_METHOD_FITHEIGHT; + else + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "Unsupported scale method: %s", + value); + } + else if (! grub_strcmp ("desktop-image-h-align", name)) + { + if (! grub_strcmp ("left", value)) + view->desktop_image_h_align = GRUB_VIDEO_BITMAP_H_ALIGN_LEFT; + else if (! grub_strcmp ("center", value)) + view->desktop_image_h_align = GRUB_VIDEO_BITMAP_H_ALIGN_CENTER; + else if (! grub_strcmp ("right", value)) + view->desktop_image_h_align = GRUB_VIDEO_BITMAP_H_ALIGN_RIGHT; + else + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "Unsupported horizontal align method: %s", + value); + } + else if (! grub_strcmp ("desktop-image-v-align", name)) + { + if (! grub_strcmp ("top", value)) + view->desktop_image_v_align = GRUB_VIDEO_BITMAP_V_ALIGN_TOP; + else if (! grub_strcmp ("center", value)) + view->desktop_image_v_align = GRUB_VIDEO_BITMAP_V_ALIGN_CENTER; + else if (! grub_strcmp ("bottom", value)) + view->desktop_image_v_align = GRUB_VIDEO_BITMAP_V_ALIGN_BOTTOM; + else + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "Unsupported vertical align method: %s", + value); + } + else if (! grub_strcmp ("desktop-color", name)) + grub_video_parse_color (value, &view->desktop_color); + else if (! grub_strcmp ("terminal-box", name)) + { + grub_err_t err; + err = grub_gui_recreate_box (&view->terminal_box, value, theme_dir); + if (err != GRUB_ERR_NONE) + return err; + } + else if (! grub_strcmp ("terminal-border", name)) + { + view->terminal_border = grub_strtoul (value, 0, 10); + if (grub_errno) + return grub_errno; + } + else if (! grub_strcmp ("terminal-left", name)) + { + unsigned int tmp; + int err = theme_get_unsigned_int_from_proportional (value, + view->screen.width, + &tmp); + if (err != GRUB_ERR_NONE) + return err; + view->terminal_rect.x = tmp; + } + else if (! grub_strcmp ("terminal-top", name)) + { + unsigned int tmp; + int err = theme_get_unsigned_int_from_proportional (value, + view->screen.height, + &tmp); + if (err != GRUB_ERR_NONE) + return err; + view->terminal_rect.y = tmp; + } + else if (! grub_strcmp ("terminal-width", name)) + { + unsigned int tmp; + int err = theme_get_unsigned_int_from_proportional (value, + view->screen.width, + &tmp); + if (err != GRUB_ERR_NONE) + return err; + view->terminal_rect.width = tmp; + } + else if (! grub_strcmp ("terminal-height", name)) + { + unsigned int tmp; + int err = theme_get_unsigned_int_from_proportional (value, + view->screen.height, + &tmp); + if (err != GRUB_ERR_NONE) + return err; + view->terminal_rect.height = tmp; + } + else if (! grub_strcmp ("title-text", name)) + { + grub_free (view->title_text); + view->title_text = grub_strdup (value); + if (! view->title_text) + return grub_errno; + } + else if (! grub_strcmp ("ventoy_left_top_color", name)) + return grub_errno; + else + { + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "%s:%d:%d unknown property `%s'", + filename, line_num, col_num, name); + } + return grub_errno; +} + +struct parsebuf +{ + char *buf; + int pos; + int len; + int line_num; + int col_num; + const char *filename; + char *theme_dir; + grub_gfxmenu_view_t view; +}; + +static int +has_more (struct parsebuf *p) +{ + return p->pos < p->len; +} + +static int +read_char (struct parsebuf *p) +{ + if (has_more (p)) + { + char c; + c = p->buf[p->pos++]; + if (c == '\n') + { + p->line_num++; + p->col_num = 1; + } + else + { + p->col_num++; + } + return c; + } + else + return -1; +} + +static int +peek_char (struct parsebuf *p) +{ + if (has_more (p)) + return p->buf[p->pos]; + else + return -1; +} + +static int +is_whitespace (char c) +{ + return (c == ' ' + || c == '\t' + || c == '\r' + || c == '\n' + || c == '\f'); +} + +static void +skip_whitespace (struct parsebuf *p) +{ + while (has_more (p) && is_whitespace(peek_char (p))) + read_char (p); +} + +static void +advance_to_next_line (struct parsebuf *p) +{ + int c; + + /* Eat characters up to the newline. */ + do + { + c = read_char (p); + } + while (c != -1 && c != '\n'); +} + +static int +is_identifier_char (int c) +{ + return (c != -1 + && (grub_isalpha(c) + || grub_isdigit(c) + || c == '_' + || c == '-')); +} + +static char * +read_identifier (struct parsebuf *p) +{ + /* Index of the first character of the identifier in p->buf. */ + int start; + /* Next index after the last character of the identifer in p->buf. */ + int end; + + skip_whitespace (p); + + /* Capture the start of the identifier. */ + start = p->pos; + + /* Scan for the end. */ + while (is_identifier_char (peek_char (p))) + read_char (p); + end = p->pos; + + if (end - start < 1) + return 0; + + return grub_new_substring (p->buf, start, end); +} + +static char * +read_expression (struct parsebuf *p) +{ + int start; + int end; + + skip_whitespace (p); + if (peek_char (p) == '"') + { + /* Read as a quoted string. + The quotation marks are not included in the expression value. */ + /* Skip opening quotation mark. */ + read_char (p); + start = p->pos; + while (has_more (p) && peek_char (p) != '"') + read_char (p); + end = p->pos; + /* Skip the terminating quotation mark. */ + read_char (p); + } + else if (peek_char (p) == '(') + { + /* Read as a parenthesized string -- for tuples/coordinates. */ + /* The parentheses are included in the expression value. */ + int c; + + start = p->pos; + do + { + c = read_char (p); + } + while (c != -1 && c != ')'); + end = p->pos; + } + else if (has_more (p)) + { + /* Read as a single word -- for numeric values or words without + whitespace. */ + start = p->pos; + while (has_more (p) && ! is_whitespace (peek_char (p)) + && peek_char (p) != '}') + read_char (p); + end = p->pos; + } + else + { + /* The end of the theme file has been reached. */ + grub_error (GRUB_ERR_IO, "%s:%d:%d expression expected in theme file", + p->filename, p->line_num, p->col_num); + return 0; + } + + return grub_new_substring (p->buf, start, end); +} + +static grub_err_t +parse_proportional_spec (const char *value, signed *abs, grub_fixed_signed_t *prop) +{ + signed num; + const char *ptr; + int sig = 0; + *abs = 0; + *prop = 0; + ptr = value; + while (*ptr) + { + sig = 0; + + while (*ptr == '-' || *ptr == '+') + { + if (*ptr == '-') + sig = !sig; + ptr++; + } + + num = grub_strtoul (ptr, (char **) &ptr, 0); + if (grub_errno) + return grub_errno; + if (sig) + num = -num; + if (*ptr == '%') + { + *prop += grub_fixed_fsf_divide (grub_signed_to_fixed (num), 100); + ptr++; + } + else + *abs += num; + } + return GRUB_ERR_NONE; +} + + +/* Read a GUI object specification from the theme file. + Any components created will be added to the GUI container PARENT. */ +static grub_err_t +read_object (struct parsebuf *p, grub_gui_container_t parent) +{ + grub_video_rect_t bounds; + + char *name; + name = read_identifier (p); + if (! name) + goto cleanup; + + grub_gui_component_t component = 0; + if (grub_strcmp (name, "label") == 0) + { + component = grub_gui_label_new (); + } + else if (grub_strcmp (name, "image") == 0) + { + component = grub_gui_image_new (); + } + else if (grub_strcmp (name, "vbox") == 0) + { + component = (grub_gui_component_t) grub_gui_vbox_new (); + } + else if (grub_strcmp (name, "hbox") == 0) + { + component = (grub_gui_component_t) grub_gui_hbox_new (); + } + else if (grub_strcmp (name, "canvas") == 0) + { + component = (grub_gui_component_t) grub_gui_canvas_new (); + } + else if (grub_strcmp (name, "progress_bar") == 0) + { + component = grub_gui_progress_bar_new (); + } + else if (grub_strcmp (name, "circular_progress") == 0) + { + component = grub_gui_circular_progress_new (); + } + else if (grub_strcmp (name, "boot_menu") == 0) + { + component = grub_gui_list_new (); + } + else + { + /* Unknown type. */ + grub_error (GRUB_ERR_IO, "%s:%d:%d unknown object type `%s'", + p->filename, p->line_num, p->col_num, name); + goto cleanup; + } + + if (! component) + goto cleanup; + + /* Inform the component about the theme so it can find its resources. */ + component->ops->set_property (component, "theme_dir", p->theme_dir); + component->ops->set_property (component, "theme_path", p->filename); + + /* Add the component as a child of PARENT. */ + bounds.x = 0; + bounds.y = 0; + bounds.width = -1; + bounds.height = -1; + component->ops->set_bounds (component, &bounds); + parent->ops->add (parent, component); + + skip_whitespace (p); + if (read_char (p) != '{') + { + grub_error (GRUB_ERR_IO, + "%s:%d:%d expected `{' after object type name `%s'", + p->filename, p->line_num, p->col_num, name); + goto cleanup; + } + + while (has_more (p)) + { + skip_whitespace (p); + + /* Check whether the end has been encountered. */ + if (peek_char (p) == '}') + { + /* Skip the closing brace. */ + read_char (p); + break; + } + + if (peek_char (p) == '#') + { + /* Skip comments. */ + advance_to_next_line (p); + continue; + } + + if (peek_char (p) == '+') + { + /* Skip the '+'. */ + read_char (p); + + /* Check whether this component is a container. */ + if (component->ops->is_instance (component, "container")) + { + /* Read the sub-object recursively and add it as a child. */ + if (read_object (p, (grub_gui_container_t) component) != 0) + goto cleanup; + /* After reading the sub-object, resume parsing, expecting + another property assignment or sub-object definition. */ + continue; + } + else + { + grub_error (GRUB_ERR_IO, + "%s:%d:%d attempted to add object to non-container", + p->filename, p->line_num, p->col_num); + goto cleanup; + } + } + + char *property; + property = read_identifier (p); + if (! property) + { + grub_error (GRUB_ERR_IO, "%s:%d:%d identifier expected in theme file", + p->filename, p->line_num, p->col_num); + goto cleanup; + } + + skip_whitespace (p); + if (read_char (p) != '=') + { + grub_error (GRUB_ERR_IO, + "%s:%d:%d expected `=' after property name `%s'", + p->filename, p->line_num, p->col_num, property); + grub_free (property); + goto cleanup; + } + skip_whitespace (p); + + char *value; + value = read_expression (p); + if (! value) + { + grub_free (property); + goto cleanup; + } + + /* Handle the property value. */ + if (grub_strcmp (property, "left") == 0) + parse_proportional_spec (value, &component->x, &component->xfrac); + else if (grub_strcmp (property, "top") == 0) + parse_proportional_spec (value, &component->y, &component->yfrac); + else if (grub_strcmp (property, "width") == 0) + parse_proportional_spec (value, &component->w, &component->wfrac); + else if (grub_strcmp (property, "height") == 0) + parse_proportional_spec (value, &component->h, &component->hfrac); + else + /* General property handling. */ + component->ops->set_property (component, property, value); + + grub_free (value); + grub_free (property); + if (grub_errno != GRUB_ERR_NONE) + goto cleanup; + } + +cleanup: + grub_free (name); + return grub_errno; +} + +static grub_err_t +read_property (struct parsebuf *p) +{ + char *name; + + /* Read the property name. */ + name = read_identifier (p); + if (! name) + { + advance_to_next_line (p); + return grub_errno; + } + + /* Skip whitespace before separator. */ + skip_whitespace (p); + + /* Read separator. */ + if (read_char (p) != ':') + { + grub_error (GRUB_ERR_IO, + "%s:%d:%d missing separator after property name `%s'", + p->filename, p->line_num, p->col_num, name); + goto done; + } + + /* Skip whitespace after separator. */ + skip_whitespace (p); + + /* Get the value based on its type. */ + if (peek_char (p) == '"') + { + /* String value (e.g., '"My string"'). */ + char *value = read_expression (p); + if (! value) + { + grub_error (GRUB_ERR_IO, "%s:%d:%d missing property value", + p->filename, p->line_num, p->col_num); + goto done; + } + /* If theme_set_string results in an error, grub_errno will be returned + below. */ + theme_set_string (p->view, name, value, p->theme_dir, + p->filename, p->line_num, p->col_num); + grub_free (value); + } + else + { + grub_error (GRUB_ERR_IO, + "%s:%d:%d property value invalid; " + "enclose literal values in quotes (\")", + p->filename, p->line_num, p->col_num); + + grub_printf("File: %s\nLine:%d Column:%d\n" + "property value invalid; enclose literal values in quotes (\")\n\n", + p->filename, p->line_num, p->col_num); + + goto done; + } + +done: + grub_free (name); + return grub_errno; +} + +extern int g_menu_update_mode; + +/* Set properties on the view based on settings from the specified + theme file. */ +grub_err_t +grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view, const char *theme_path) +{ + int flag = 0; + grub_file_t file; + struct parsebuf p; + + p.view = view; + p.theme_dir = grub_get_dirname (theme_path); + + file = grub_file_open (theme_path, GRUB_FILE_TYPE_THEME); + if (! file) + { + grub_free (p.theme_dir); + return grub_errno; + } + + p.len = grub_file_size (file); + p.buf = grub_malloc (p.len + 8192); + p.pos = 0; + p.line_num = 1; + p.col_num = 1; + p.filename = theme_path; + if (! p.buf) + { + grub_file_close (file); + grub_free (p.theme_dir); + return grub_errno; + } + if (grub_file_read (file, p.buf, p.len) != p.len) + { + grub_free (p.buf); + grub_file_close (file); + grub_free (p.theme_dir); + return grub_errno; + } + +{ + const char *checkret = grub_env_get("VTOY_CHKDEV_RESULT_STRING"); + if (checkret == NULL || checkret[0] != '0') + { + p.len += grub_snprintf(p.buf + p.len, 4096, "\n+ hbox{\n left = 1%%\n top = 90%%\n" + " + label {text = \"[Unofficial Ventoy]\" color = \"red\" align = \"left\"}\n" + "}\n"); + } +} + + + + if (view->canvas) + view->canvas->component.ops->destroy (view->canvas); + + view->canvas = grub_gui_canvas_new (); + if (!view->canvas) + goto fail; + ((grub_gui_component_t) view->canvas) + ->ops->set_bounds ((grub_gui_component_t) view->canvas, + &view->screen); + +parse: + while (has_more (&p)) + { + /* Skip comments (lines beginning with #). */ + if (peek_char (&p) == '#') + { + advance_to_next_line (&p); + continue; + } + + /* Find the first non-whitespace character. */ + skip_whitespace (&p); + + /* Handle the content. */ + if (peek_char (&p) == '+') + { + /* Skip the '+'. */ + read_char (&p); + read_object (&p, view->canvas); + } + else + { + read_property (&p); + } + + if (grub_errno != GRUB_ERR_NONE) + goto fail; + } + + +if (flag == 0) +{ + const char *tip = grub_env_get("VTOY_MENU_TIP_ENABLE"); + if (tip && tip[0] == '1') + { + char tmpmsg[512]; + + grub_memset(tmpmsg, 'w', 500); + tmpmsg[500] = 0; + + g_menu_update_mode = 1; + p.len += grub_snprintf(p.buf + p.len, 4096, + "\n+ vbox{\n left = %s\n top = %s\n" + "+ label { id=\"VTOY_MENU_TIP_1\" text = \"%s\" color = \"%s\" align = \"%s\"}\n" + "+ label { id=\"VTOY_MENU_TIP_2\" text = \"%s\" color = \"%s\" align = \"%s\"}\n" + "}\n", + grub_env_get("VTOY_TIP_LEFT"), + grub_env_get("VTOY_TIP_TOP"), + tmpmsg, + grub_env_get("VTOY_TIP_COLOR"), + grub_env_get("VTOY_TIP_ALIGN"), + tmpmsg, + grub_env_get("VTOY_TIP_COLOR"), + grub_env_get("VTOY_TIP_ALIGN") + ); + + flag = 1; + goto parse; + } +} + + + + /* Set the new theme path. */ + grub_free (view->theme_path); + view->theme_path = grub_strdup (theme_path); + goto cleanup; + +fail: + if (view->canvas) + { + view->canvas->component.ops->destroy (view->canvas); + view->canvas = 0; + } + +cleanup: + grub_free (p.buf); + grub_file_close (file); + grub_free (p.theme_dir); + return grub_errno; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/view.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/view.c new file mode 100644 index 0000000..b69f099 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/view.c @@ -0,0 +1,694 @@ +/* view.c - Graphical menu interface MVC view. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void +init_terminal (grub_gfxmenu_view_t view); +static void +init_background (grub_gfxmenu_view_t view); +static grub_gfxmenu_view_t term_view; + +/* Create a new view object, loading the theme specified by THEME_PATH and + associating MODEL with the view. */ +grub_gfxmenu_view_t +grub_gfxmenu_view_new (const char *theme_path, + int width, int height) +{ + grub_gfxmenu_view_t view; + grub_font_t default_font; + grub_video_rgba_color_t default_fg_color; + grub_video_rgba_color_t default_bg_color; + + view = grub_malloc (sizeof (*view)); + if (! view) + return 0; + + while (grub_gfxmenu_timeout_notifications) + { + struct grub_gfxmenu_timeout_notify *p; + p = grub_gfxmenu_timeout_notifications; + grub_gfxmenu_timeout_notifications = grub_gfxmenu_timeout_notifications->next; + grub_free (p); + } + + view->screen.x = 0; + view->screen.y = 0; + view->screen.width = width; + view->screen.height = height; + + view->need_to_check_sanity = 1; + view->terminal_border = 3; + view->terminal_rect.width = view->screen.width * 7 / 10; + view->terminal_rect.height = view->screen.height * 7 / 10; + view->terminal_rect.x = view->screen.x + (view->screen.width + - view->terminal_rect.width) / 2; + view->terminal_rect.y = view->screen.y + (view->screen.height + - view->terminal_rect.height) / 2; + + default_font = grub_font_get ("Unknown Regular 16"); + default_fg_color = grub_video_rgba_color_rgb (0, 0, 0); + default_bg_color = grub_video_rgba_color_rgb (255, 255, 255); + + view->canvas = 0; + + view->title_font = default_font; + view->message_font = default_font; + view->terminal_font_name = grub_strdup ("Fixed 10"); + view->title_color = default_fg_color; + view->message_color = default_bg_color; + view->message_bg_color = default_fg_color; + view->raw_desktop_image = 0; + view->scaled_desktop_image = 0; + view->desktop_image_scale_method = GRUB_VIDEO_BITMAP_SELECTION_METHOD_STRETCH; + view->desktop_image_h_align = GRUB_VIDEO_BITMAP_H_ALIGN_CENTER; + view->desktop_image_v_align = GRUB_VIDEO_BITMAP_V_ALIGN_CENTER; + view->desktop_color = default_bg_color; + view->terminal_box = grub_gfxmenu_create_box (0, 0); + view->title_text = grub_strdup (_("GRUB Boot Menu")); + view->progress_message_text = 0; + view->theme_path = 0; + + /* Set the timeout bar's frame. */ + view->progress_message_frame.width = view->screen.width * 4 / 5; + view->progress_message_frame.height = 50; + view->progress_message_frame.x = view->screen.x + + (view->screen.width - view->progress_message_frame.width) / 2; + view->progress_message_frame.y = view->screen.y + + view->screen.height - 90 - 20 - view->progress_message_frame.height; + + if (grub_gfxmenu_view_load_theme (view, theme_path) != 0) + { + grub_gfxmenu_view_destroy (view); + return 0; + } + + return view; +} + +/* Destroy the view object. All used memory is freed. */ +void +grub_gfxmenu_view_destroy (grub_gfxmenu_view_t view) +{ + if (!view) + return; + while (grub_gfxmenu_timeout_notifications) + { + struct grub_gfxmenu_timeout_notify *p; + p = grub_gfxmenu_timeout_notifications; + grub_gfxmenu_timeout_notifications = grub_gfxmenu_timeout_notifications->next; + grub_free (p); + } + grub_video_bitmap_destroy (view->raw_desktop_image); + grub_video_bitmap_destroy (view->scaled_desktop_image); + if (view->terminal_box) + view->terminal_box->destroy (view->terminal_box); + grub_free (view->terminal_font_name); + grub_free (view->title_text); + grub_free (view->progress_message_text); + grub_free (view->theme_path); + if (view->menu_title_offset) + grub_free (view->menu_title_offset); + if (view->canvas) + view->canvas->component.ops->destroy (view->canvas); + grub_free (view); +} + +static void +redraw_background (grub_gfxmenu_view_t view, + const grub_video_rect_t *bounds) +{ + if (view->scaled_desktop_image) + { + struct grub_video_bitmap *img = view->scaled_desktop_image; + grub_video_blit_bitmap (img, GRUB_VIDEO_BLIT_REPLACE, + bounds->x, bounds->y, + bounds->x - view->screen.x, + bounds->y - view->screen.y, + bounds->width, bounds->height); + } + else + { + grub_video_fill_rect (grub_video_map_rgba_color (view->desktop_color), + bounds->x, bounds->y, + bounds->width, bounds->height); + } +} + +static void +draw_title (grub_gfxmenu_view_t view) +{ + if (! view->title_text) + return; + + /* Center the title. */ + int title_width = grub_font_get_string_width (view->title_font, + view->title_text); + int x = (view->screen.width - title_width) / 2; + int y = 40 + grub_font_get_ascent (view->title_font); + grub_font_draw_string (view->title_text, + view->title_font, + grub_video_map_rgba_color (view->title_color), + x, y); +} + +struct progress_value_data +{ + int visible; + int start; + int end; + int value; +}; + +struct grub_gfxmenu_timeout_notify *grub_gfxmenu_timeout_notifications; + +static void +update_timeouts (int visible, int start, int value, int end) +{ + struct grub_gfxmenu_timeout_notify *cur; + + for (cur = grub_gfxmenu_timeout_notifications; cur; cur = cur->next) + cur->set_state (cur->self, visible, start, value, end); +} + +static void +redraw_timeouts (struct grub_gfxmenu_view *view) +{ + struct grub_gfxmenu_timeout_notify *cur; + + for (cur = grub_gfxmenu_timeout_notifications; cur; cur = cur->next) + { + grub_video_rect_t bounds; + cur->self->ops->get_bounds (cur->self, &bounds); + grub_video_set_area_status (GRUB_VIDEO_AREA_ENABLED); + grub_gfxmenu_view_redraw (view, &bounds); + } +} + +void +grub_gfxmenu_print_timeout (int timeout, void *data) +{ + struct grub_gfxmenu_view *view = data; + + if (view->first_timeout == -1) + view->first_timeout = timeout; + + update_timeouts (1, -view->first_timeout, -timeout, 0); + redraw_timeouts (view); + grub_video_swap_buffers (); + if (view->double_repaint) + redraw_timeouts (view); +} + +void +grub_gfxmenu_clear_timeout (void *data) +{ + struct grub_gfxmenu_view *view = data; + + update_timeouts (0, 1, 0, 0); + redraw_timeouts (view); + grub_video_swap_buffers (); + if (view->double_repaint) + redraw_timeouts (view); +} + +static void +update_menu_visit (grub_gui_component_t component, + void *userdata) +{ + grub_gfxmenu_view_t view; + view = userdata; + if (component->ops->is_instance (component, "list")) + { + grub_gui_list_t list = (grub_gui_list_t) component; + list->ops->set_view_info (list, view); + } +} + +/* Update any boot menu components with the current menu model and + theme path. */ +static void +update_menu_components (grub_gfxmenu_view_t view) +{ + grub_gui_iterate_recursively ((grub_gui_component_t) view->canvas, + update_menu_visit, view); +} + +static void +refresh_menu_visit (grub_gui_component_t component, + void *userdata) +{ + grub_gfxmenu_view_t view; + view = userdata; + if (component->ops->is_instance (component, "list")) + { + grub_gui_list_t list = (grub_gui_list_t) component; + list->ops->refresh_list (list, view); + } +} + +/* Refresh list information (useful for submenus) */ +static void +refresh_menu_components (grub_gfxmenu_view_t view) +{ + grub_gui_iterate_recursively ((grub_gui_component_t) view->canvas, + refresh_menu_visit, view); +} + +static void +draw_message (grub_gfxmenu_view_t view) +{ + char *text = view->progress_message_text; + grub_video_rect_t f = view->progress_message_frame; + if (! text) + return; + + grub_font_t font = view->message_font; + grub_video_color_t color = grub_video_map_rgba_color (view->message_color); + + /* Border. */ + grub_video_fill_rect (color, + f.x-1, f.y-1, f.width+2, f.height+2); + /* Fill. */ + grub_video_fill_rect (grub_video_map_rgba_color (view->message_bg_color), + f.x, f.y, f.width, f.height); + + /* Center the text. */ + int text_width = grub_font_get_string_width (font, text); + int x = f.x + (f.width - text_width) / 2; + int y = (f.y + (f.height - grub_font_get_descent (font)) / 2 + + grub_font_get_ascent (font) / 2); + grub_font_draw_string (text, font, color, x, y); +} + +void +grub_gfxmenu_view_redraw (grub_gfxmenu_view_t view, + const grub_video_rect_t *region) +{ + if (grub_video_have_common_points (&view->terminal_rect, region)) + grub_gfxterm_schedule_repaint (); + + grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); + grub_video_area_status_t area_status; + grub_video_get_area_status (&area_status); + if (area_status == GRUB_VIDEO_AREA_ENABLED) + grub_video_set_region (region->x, region->y, + region->width, region->height); + + redraw_background (view, region); + if (view->canvas) + view->canvas->component.ops->paint (view->canvas, region); + draw_title (view); + if (grub_video_have_common_points (&view->progress_message_frame, region)) + draw_message (view); + + if (area_status == GRUB_VIDEO_AREA_ENABLED) + grub_video_set_area_status (GRUB_VIDEO_AREA_ENABLED); +} + +void +grub_gfxmenu_view_draw (grub_gfxmenu_view_t view) +{ + init_terminal (view); + + init_background (view); + + /* Clear the screen; there may be garbage left over in video memory. */ + grub_video_fill_rect (grub_video_map_rgb (0, 0, 0), + view->screen.x, view->screen.y, + view->screen.width, view->screen.height); + grub_video_swap_buffers (); + if (view->double_repaint) + grub_video_fill_rect (grub_video_map_rgb (0, 0, 0), + view->screen.x, view->screen.y, + view->screen.width, view->screen.height); + + refresh_menu_components (view); + update_menu_components (view); + + grub_video_set_area_status (GRUB_VIDEO_AREA_DISABLED); + grub_gfxmenu_view_redraw (view, &view->screen); + grub_video_swap_buffers (); + if (view->double_repaint) + { + grub_video_set_area_status (GRUB_VIDEO_AREA_DISABLED); + grub_gfxmenu_view_redraw (view, &view->screen); + } + +} + +static void +redraw_menu_visit (grub_gui_component_t component, + void *userdata) +{ + grub_gfxmenu_view_t view; + view = userdata; + if (component->ops->is_instance (component, "list")) + { + grub_video_rect_t bounds; + + component->ops->get_bounds (component, &bounds); + grub_video_set_area_status (GRUB_VIDEO_AREA_ENABLED); + grub_gfxmenu_view_redraw (view, &bounds); + } +} + +extern int g_menu_update_mode; + +static void grub_gfxmenu_update_all(grub_gfxmenu_view_t view) +{ + grub_video_set_area_status(GRUB_VIDEO_AREA_DISABLED); + grub_gfxmenu_view_redraw(view, &view->screen); +} + +void +grub_gfxmenu_redraw_menu (grub_gfxmenu_view_t view) +{ + update_menu_components (view); + + if (g_menu_update_mode) + grub_gfxmenu_update_all(view); + else + grub_gui_iterate_recursively ((grub_gui_component_t) view->canvas, + redraw_menu_visit, view); + + grub_video_swap_buffers (); + if (view->double_repaint) + { + if (g_menu_update_mode) + grub_gfxmenu_update_all(view); + else + grub_gui_iterate_recursively ((grub_gui_component_t) view->canvas, + redraw_menu_visit, view); + } +} + + +void +grub_gfxmenu_set_chosen_entry (int entry, void *data) +{ + grub_gfxmenu_view_t view = data; + + view->selected = entry; + grub_gfxmenu_redraw_menu (view); + + +} + +void +grub_gfxmenu_scroll_chosen_entry (void *data, int diren) +{ + grub_gfxmenu_view_t view = data; + const char *item_title; + int off; + int max; + + if (!view->menu->size) + return; + + item_title = grub_menu_get_entry (view->menu, view->selected)->title; + off = view->menu_title_offset[view->selected] + diren; + max = grub_utf8_get_num_code (item_title, grub_strlen(item_title)); + + if (diren == 1000000) + off = (max >= 20) ? (max - 20) : 0; + else if (off < 0) + off = 0; + else if (off > max) + off = max; + + view->menu_title_offset[view->selected] = off; + grub_gfxmenu_redraw_menu (view); +} + +static void +grub_gfxmenu_draw_terminal_box (void) +{ + grub_gfxmenu_box_t term_box; + + term_box = term_view->terminal_box; + if (!term_box) + return; + + grub_video_set_area_status (GRUB_VIDEO_AREA_DISABLED); + + term_box->set_content_size (term_box, term_view->terminal_rect.width, + term_view->terminal_rect.height); + + term_box->draw (term_box, + term_view->terminal_rect.x - term_box->get_left_pad (term_box), + term_view->terminal_rect.y - term_box->get_top_pad (term_box)); +} + +static void +get_min_terminal (grub_font_t terminal_font, + unsigned int border_width, + unsigned int *min_terminal_width, + unsigned int *min_terminal_height) +{ + struct grub_font_glyph *glyph; + glyph = grub_font_get_glyph (terminal_font, 'M'); + *min_terminal_width = (glyph? glyph->device_width : 8) * 80 + + 2 * border_width; + *min_terminal_height = grub_font_get_max_char_height (terminal_font) * 24 + + 2 * border_width; +} + +static void +terminal_sanity_check (grub_gfxmenu_view_t view) +{ + if (!view->need_to_check_sanity) + return; + + /* terminal_font was checked before in the init_terminal function. */ + grub_font_t terminal_font = grub_font_get (view->terminal_font_name); + + /* Non-negative numbers below. */ + int scr_x = view->screen.x; + int scr_y = view->screen.y; + int scr_width = view->screen.width; + int scr_height = view->screen.height; + int term_x = view->terminal_rect.x; + int term_y = view->terminal_rect.y; + int term_width = view->terminal_rect.width; + int term_height = view->terminal_rect.height; + + /* Check that border_width isn't too big. */ + unsigned int border_width = view->terminal_border; + unsigned int min_terminal_width; + unsigned int min_terminal_height; + get_min_terminal (terminal_font, border_width, + &min_terminal_width, &min_terminal_height); + if (border_width > 3 && ((int) min_terminal_width >= scr_width + || (int) min_terminal_height >= scr_height)) + { + border_width = 3; + get_min_terminal (terminal_font, border_width, + &min_terminal_width, &min_terminal_height); + } + + /* Sanity checks. */ + if (term_width > scr_width) + term_width = scr_width; + if (term_height > scr_height) + term_height = scr_height; + + if (scr_width <= (int) min_terminal_width + || scr_height <= (int) min_terminal_height) + { + /* The screen resulution is too low. Use all space, except a small border + to show the user, that it is a window. Then center the window. */ + term_width = scr_width - 6 * border_width; + term_height = scr_height - 6 * border_width; + term_x = scr_x + (scr_width - term_width) / 2; + term_y = scr_y + (scr_height - term_height) / 2; + } + else if (term_width < (int) min_terminal_width + || term_height < (int) min_terminal_height) + { + /* The screen resolution is big enough. Make sure, that terminal screen + dimensions aren't less than minimal values. Then center the window. */ + term_width = (int) min_terminal_width; + term_height = (int) min_terminal_height; + term_x = scr_x + (scr_width - term_width) / 2; + term_y = scr_y + (scr_height - term_height) / 2; + } + + /* At this point w and h are satisfying. */ + if (term_x + term_width > scr_width) + term_x = scr_width - term_width; + if (term_y + term_height > scr_height) + term_y = scr_height - term_height; + + /* Write down corrected data. */ + view->terminal_rect.x = (unsigned int) term_x; + view->terminal_rect.y = (unsigned int) term_y; + view->terminal_rect.width = (unsigned int) term_width; + view->terminal_rect.height = (unsigned int) term_height; + view->terminal_border = border_width; + + view->need_to_check_sanity = 0; +} + +static void +init_terminal (grub_gfxmenu_view_t view) +{ + grub_font_t terminal_font; + + terminal_font = grub_font_get (view->terminal_font_name); + if (!terminal_font) + { + grub_error (GRUB_ERR_BAD_FONT, "no font loaded"); + return; + } + + /* Check that terminal window size and position are sane. */ + terminal_sanity_check (view); + + term_view = view; + + /* Note: currently there is no API for changing the gfxterm font + on the fly, so whatever font the initially loaded theme specifies + will be permanent. */ + grub_gfxterm_set_window (GRUB_VIDEO_RENDER_TARGET_DISPLAY, + view->terminal_rect.x, + view->terminal_rect.y, + view->terminal_rect.width, + view->terminal_rect.height, + view->double_repaint, + terminal_font, + view->terminal_border); + grub_gfxterm_decorator_hook = grub_gfxmenu_draw_terminal_box; +} + +static void +init_background (grub_gfxmenu_view_t view) +{ + if (view->scaled_desktop_image || (!view->raw_desktop_image)) + return; + + struct grub_video_bitmap *scaled_bitmap; + if (view->desktop_image_scale_method == + GRUB_VIDEO_BITMAP_SELECTION_METHOD_STRETCH) + grub_video_bitmap_create_scaled (&scaled_bitmap, + view->screen.width, + view->screen.height, + view->raw_desktop_image, + GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST); + else + grub_video_bitmap_scale_proportional (&scaled_bitmap, + view->screen.width, + view->screen.height, + view->raw_desktop_image, + GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST, + view->desktop_image_scale_method, + view->desktop_image_v_align, + view->desktop_image_h_align); + if (! scaled_bitmap) + return; + view->scaled_desktop_image = scaled_bitmap; + +} + +/* FIXME: previously notifications were displayed in special case. + Is it necessary? + */ +#if 0 +/* Sets MESSAGE as the progress message for the view. + MESSAGE can be 0, in which case no message is displayed. */ +static void +set_progress_message (grub_gfxmenu_view_t view, const char *message) +{ + grub_free (view->progress_message_text); + if (message) + view->progress_message_text = grub_strdup (message); + else + view->progress_message_text = 0; +} + +static void +notify_booting (grub_menu_entry_t entry, void *userdata) +{ + grub_gfxmenu_view_t view = (grub_gfxmenu_view_t) userdata; + + char *s = grub_malloc (100 + grub_strlen (entry->title)); + if (!s) + return; + + grub_sprintf (s, "Booting '%s'", entry->title); + set_progress_message (view, s); + grub_free (s); + grub_gfxmenu_view_redraw (view, &view->progress_message_frame); + grub_video_swap_buffers (); + if (view->double_repaint) + grub_gfxmenu_view_redraw (view, &view->progress_message_frame); +} + +static void +notify_fallback (grub_menu_entry_t entry, void *userdata) +{ + grub_gfxmenu_view_t view = (grub_gfxmenu_view_t) userdata; + + char *s = grub_malloc (100 + grub_strlen (entry->title)); + if (!s) + return; + + grub_sprintf (s, "Falling back to '%s'", entry->title); + set_progress_message (view, s); + grub_free (s); + grub_gfxmenu_view_redraw (view, &view->progress_message_frame); + grub_video_swap_buffers (); + if (view->double_repaint) + grub_gfxmenu_view_redraw (view, &view->progress_message_frame); +} + +static void +notify_execution_failure (void *userdata __attribute__ ((unused))) +{ +} + + +static struct grub_menu_execute_callback execute_callback = +{ + .notify_booting = notify_booting, + .notify_fallback = notify_fallback, + .notify_failure = notify_execution_failure +}; + +#endif diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/corecmd.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/corecmd.c new file mode 100644 index 0000000..69c85d0 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/corecmd.c @@ -0,0 +1,195 @@ +/* corecmd.c - critical commands which are registered in kernel */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* set ENVVAR=VALUE */ +static grub_err_t +grub_core_cmd_set (struct grub_command *cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + char *var; + char *val; + + if (argc < 1) + { + struct grub_env_var *env; + FOR_SORTED_ENV (env) + grub_printf ("%s=%s\n", env->name, grub_env_get (env->name)); + return 0; + } + + var = argv[0]; + val = grub_strchr (var, '='); + if (! val) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "not an assignment"); + + val[0] = 0; + grub_env_set (var, val + 1); + val[0] = '='; + + return 0; +} + +static grub_err_t +grub_core_cmd_unset (struct grub_command *cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + if (argc < 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("one argument expected")); + + grub_env_unset (argv[0]); + return 0; +} + +/* insmod MODULE */ +static grub_err_t +grub_core_cmd_insmod (struct grub_command *cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + grub_dl_t mod; + + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); + + /* For simple, just disable insmod when SecureBoot is enabled. */ + if (g_sys_sb && g_sb_policy == VTOY_SB_POLICY_CHECK) + { + return grub_error (GRUB_ERR_BAD_SIGNATURE, "Cannot insmod when SecureBoot is enabled and Policy is check."); + } + + if (argv[0][0] == '/' || argv[0][0] == '(' || argv[0][0] == '+') + mod = grub_dl_load_file (argv[0]); + else + mod = grub_dl_load (argv[0]); + + if (mod) + grub_dl_ref (mod); + + return 0; +} + +static int +grub_mini_print_devices (const char *name, void *data __attribute__ ((unused))) +{ + grub_printf ("(%s) ", name); + + return 0; +} + +static int +grub_mini_print_files (const char *filename, + const struct grub_dirhook_info *info, + void *data __attribute__ ((unused))) +{ + grub_printf ("%s%s ", filename, info->dir ? "/" : ""); + + return 0; +} + +/* ls [ARG] */ +static grub_err_t +grub_core_cmd_ls (struct grub_command *cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + if (argc < 1) + { + grub_device_iterate (grub_mini_print_devices, NULL); + grub_xputs ("\n"); + grub_refresh (); + } + else + { + char *device_name; + grub_device_t dev = 0; + grub_fs_t fs; + char *path; + + device_name = grub_file_get_device_name (argv[0]); + if (grub_errno) + goto fail; + dev = grub_device_open (device_name); + if (! dev) + goto fail; + + fs = grub_fs_probe (dev); + path = grub_strchr (argv[0], ')'); + if (! path) + path = argv[0]; + else + path++; + + if (! *path && ! device_name) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument"); + goto fail; + } + + if (! *path) + { + if (grub_errno == GRUB_ERR_UNKNOWN_FS) + grub_errno = GRUB_ERR_NONE; + + grub_printf ("(%s): Filesystem is %s.\n", + device_name, fs ? fs->name : "unknown"); + } + else if (fs) + { + (fs->fs_dir) (dev, path, grub_mini_print_files, NULL); + grub_xputs ("\n"); + grub_refresh (); + } + + fail: + if (dev) + grub_device_close (dev); + + grub_free (device_name); + } + + return grub_errno; +} + +void +grub_register_core_commands (void) +{ + grub_command_t cmd; + cmd = grub_register_command ("set", grub_core_cmd_set, + N_("[ENVVAR=VALUE]"), + N_("Set an environment variable.")); + if (cmd) + cmd->flags |= GRUB_COMMAND_FLAG_EXTRACTOR; + grub_register_command ("unset", grub_core_cmd_unset, + N_("ENVVAR"), + N_("Remove an environment variable.")); + grub_register_command ("ls", grub_core_cmd_ls, + N_("[ARG]"), N_("List devices or files.")); + grub_register_command ("insmod", grub_core_cmd_insmod, + N_("MODULE"), N_("Insert a module.")); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/disk.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/disk.c new file mode 100644 index 0000000..9742682 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/disk.c @@ -0,0 +1,646 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define GRUB_CACHE_TIMEOUT 10 + +/* The last time the disk was used. */ +static grub_uint64_t grub_last_time = 0; + +struct grub_disk_cache grub_disk_cache_table[GRUB_DISK_CACHE_NUM]; + +void (*grub_disk_firmware_fini) (void); +int grub_disk_firmware_is_tainted; + +#if DISK_CACHE_STATS +static unsigned long grub_disk_cache_hits; +static unsigned long grub_disk_cache_misses; + +void +grub_disk_cache_get_performance (unsigned long *hits, unsigned long *misses) +{ + *hits = grub_disk_cache_hits; + *misses = grub_disk_cache_misses; +} +#endif + +grub_err_t (*grub_disk_write_weak) (grub_disk_t disk, + grub_disk_addr_t sector, + grub_off_t offset, + grub_size_t size, + const void *buf); +#include "disk_common.c" + +void +grub_disk_cache_invalidate_all (void) +{ + unsigned i; + + for (i = 0; i < GRUB_DISK_CACHE_NUM; i++) + { + struct grub_disk_cache *cache = grub_disk_cache_table + i; + + if (cache->data && ! cache->lock) + { + grub_free (cache->data); + cache->data = 0; + } + } +} + +static char * +grub_disk_cache_fetch (unsigned long dev_id, unsigned long disk_id, + grub_disk_addr_t sector) +{ + struct grub_disk_cache *cache; + unsigned cache_index; + + cache_index = grub_disk_cache_get_index (dev_id, disk_id, sector); + cache = grub_disk_cache_table + cache_index; + + if (cache->dev_id == dev_id && cache->disk_id == disk_id + && cache->sector == sector) + { + cache->lock = 1; +#if DISK_CACHE_STATS + grub_disk_cache_hits++; +#endif + return cache->data; + } + +#if DISK_CACHE_STATS + grub_disk_cache_misses++; +#endif + + return 0; +} + +static void +grub_disk_cache_unlock (unsigned long dev_id, unsigned long disk_id, + grub_disk_addr_t sector) +{ + struct grub_disk_cache *cache; + unsigned cache_index; + + cache_index = grub_disk_cache_get_index (dev_id, disk_id, sector); + cache = grub_disk_cache_table + cache_index; + + if (cache->dev_id == dev_id && cache->disk_id == disk_id + && cache->sector == sector) + cache->lock = 0; +} + +static grub_err_t +grub_disk_cache_store (unsigned long dev_id, unsigned long disk_id, + grub_disk_addr_t sector, const char *data) +{ + unsigned cache_index; + struct grub_disk_cache *cache; + + cache_index = grub_disk_cache_get_index (dev_id, disk_id, sector); + cache = grub_disk_cache_table + cache_index; + + cache->lock = 1; + grub_free (cache->data); + cache->data = 0; + cache->lock = 0; + + cache->data = grub_malloc (GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS); + if (! cache->data) + return grub_errno; + + grub_memcpy (cache->data, data, + GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS); + cache->dev_id = dev_id; + cache->disk_id = disk_id; + cache->sector = sector; + + return GRUB_ERR_NONE; +} + + + +grub_disk_dev_t grub_disk_dev_list; + +void +grub_disk_dev_register (grub_disk_dev_t dev) +{ + dev->next = grub_disk_dev_list; + grub_disk_dev_list = dev; +} + +void +grub_disk_dev_unregister (grub_disk_dev_t dev) +{ + grub_disk_dev_t *p, q; + + for (p = &grub_disk_dev_list, q = *p; q; p = &(q->next), q = q->next) + if (q == dev) + { + *p = q->next; + break; + } +} + +/* Return the location of the first ',', if any, which is not + escaped by a '\'. */ +static const char * +find_part_sep (const char *name) +{ + const char *p = name; + char c; + + while ((c = *p++) != '\0') + { + if (c == '\\' && *p == ',') + p++; + else if (c == ',') + return p - 1; + } + return NULL; +} + +grub_disk_t +grub_disk_open (const char *name) +{ + const char *p; + grub_disk_t disk; + grub_disk_dev_t dev; + char *raw = (char *) name; + grub_uint64_t current_time; + + grub_dprintf ("disk", "Opening `%s'...\n", name); + + disk = (grub_disk_t) grub_zalloc (sizeof (*disk)); + if (! disk) + return 0; + disk->log_sector_size = GRUB_DISK_SECTOR_BITS; + /* Default 1MiB of maximum agglomerate. */ + disk->max_agglomerate = 1048576 >> (GRUB_DISK_SECTOR_BITS + + GRUB_DISK_CACHE_BITS); + + p = find_part_sep (name); + if (p) + { + grub_size_t len = p - name; + + raw = grub_malloc (len + 1); + if (! raw) + goto fail; + + grub_memcpy (raw, name, len); + raw[len] = '\0'; + disk->name = grub_strdup (raw); + } + else + disk->name = grub_strdup (name); + if (! disk->name) + goto fail; + + for (dev = grub_disk_dev_list; dev; dev = dev->next) + { + if ((dev->disk_open) (raw, disk) == GRUB_ERR_NONE) + break; + else if (grub_errno == GRUB_ERR_UNKNOWN_DEVICE) + grub_errno = GRUB_ERR_NONE; + else + goto fail; + } + + if (! dev) + { + grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("disk `%s' not found"), + name); + goto fail; + } + if (disk->log_sector_size > GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS + || disk->log_sector_size < GRUB_DISK_SECTOR_BITS) + { + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "sector sizes of %d bytes aren't supported yet", + (1 << disk->log_sector_size)); + goto fail; + } + + disk->dev = dev; + + if (p) + { + disk->partition = grub_partition_probe (disk, p + 1); + if (! disk->partition) + { + /* TRANSLATORS: It means that the specified partition e.g. + hd0,msdos1=/dev/sda1 doesn't exist. */ + grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("no such partition")); + goto fail; + } + } + + /* The cache will be invalidated about 2 seconds after a device was + closed. */ + current_time = grub_get_time_ms (); + + if (current_time > (grub_last_time + + GRUB_CACHE_TIMEOUT * 1000)) + grub_disk_cache_invalidate_all (); + + grub_last_time = current_time; + + fail: + + if (raw && raw != name) + grub_free (raw); + + if (grub_errno != GRUB_ERR_NONE) + { + grub_error_push (); + grub_dprintf ("disk", "Opening `%s' failed.\n", name); + grub_error_pop (); + + grub_disk_close (disk); + return 0; + } + + return disk; +} + +void +grub_disk_close (grub_disk_t disk) +{ + grub_partition_t part; + grub_dprintf ("disk", "Closing `%s'.\n", disk->name); + + if (disk->dev && disk->dev->disk_close) + (disk->dev->disk_close) (disk); + + /* Reset the timer. */ + grub_last_time = grub_get_time_ms (); + + while (disk->partition) + { + part = disk->partition->parent; + grub_free (disk->partition); + disk->partition = part; + } + grub_free ((void *) disk->name); + grub_free (disk); +} + +/* Small read (less than cache size and not pass across cache unit boundaries). + sector is already adjusted and is divisible by cache unit size. + */ +static grub_err_t +grub_disk_read_small_real (grub_disk_t disk, grub_disk_addr_t sector, + grub_off_t offset, grub_size_t size, void *buf) +{ + char *data; + char *tmp_buf; + + /* Fetch the cache. */ + data = grub_disk_cache_fetch (disk->dev->id, disk->id, sector); + if (data) + { + /* Just copy it! */ + grub_memcpy (buf, data + offset, size); + grub_disk_cache_unlock (disk->dev->id, disk->id, sector); + return GRUB_ERR_NONE; + } + + /* Allocate a temporary buffer. */ + tmp_buf = grub_malloc (GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS); + if (! tmp_buf) + return grub_errno; + + /* Otherwise read data from the disk actually. */ + if (disk->total_sectors == GRUB_DISK_SIZE_UNKNOWN + || sector + GRUB_DISK_CACHE_SIZE + < (disk->total_sectors << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS))) + { + grub_err_t err; + err = (disk->dev->disk_read) (disk, transform_sector (disk, sector), + 1U << (GRUB_DISK_CACHE_BITS + + GRUB_DISK_SECTOR_BITS + - disk->log_sector_size), tmp_buf); + if (!err) + { + /* Copy it and store it in the disk cache. */ + grub_memcpy (buf, tmp_buf + offset, size); + grub_disk_cache_store (disk->dev->id, disk->id, + sector, tmp_buf); + grub_free (tmp_buf); + return GRUB_ERR_NONE; + } + } + + grub_free (tmp_buf); + grub_errno = GRUB_ERR_NONE; + + { + /* Uggh... Failed. Instead, just read necessary data. */ + unsigned num; + grub_disk_addr_t aligned_sector; + + sector += (offset >> GRUB_DISK_SECTOR_BITS); + offset &= ((1 << GRUB_DISK_SECTOR_BITS) - 1); + aligned_sector = (sector & ~((1ULL << (disk->log_sector_size + - GRUB_DISK_SECTOR_BITS)) + - 1)); + offset += ((sector - aligned_sector) << GRUB_DISK_SECTOR_BITS); + num = ((size + offset + (1ULL << (disk->log_sector_size)) + - 1) >> (disk->log_sector_size)); + + tmp_buf = grub_malloc (num << disk->log_sector_size); + if (!tmp_buf) + return grub_errno; + + if ((disk->dev->disk_read) (disk, transform_sector (disk, aligned_sector), + num, tmp_buf)) + { + grub_error_push (); + grub_dprintf ("disk", "%s read failed\n", disk->name); + grub_error_pop (); + grub_free (tmp_buf); + return grub_errno; + } + grub_memcpy (buf, tmp_buf + offset, size); + grub_free (tmp_buf); + return GRUB_ERR_NONE; + } +} + +static grub_err_t +grub_disk_read_small (grub_disk_t disk, grub_disk_addr_t sector, + grub_off_t offset, grub_size_t size, void *buf) +{ + grub_err_t err; + + err = grub_disk_read_small_real (disk, sector, offset, size, buf); + if (err) + return err; + if (disk->read_hook) + (disk->read_hook) (sector + (offset >> GRUB_DISK_SECTOR_BITS), + offset & (GRUB_DISK_SECTOR_SIZE - 1), + size, disk->read_hook_data); + return GRUB_ERR_NONE; +} + +grub_err_t grub_disk_blocklist_read(void *chunklist, grub_uint64_t sector, + grub_uint64_t size, grub_uint32_t log_sector_size) +{ + grub_uint64_t sizeshift; + ventoy_img_chunk *last_chunk = NULL; + ventoy_img_chunk *new_chunk = NULL; + ventoy_img_chunk_list *chunk_list = (ventoy_img_chunk_list *)chunklist; + + sizeshift = (size >> log_sector_size); + if (sizeshift == 0) + { + sizeshift = 1; + } + + if (chunk_list->cur_chunk == 0) + { + chunk_list->chunk[0].img_start_sector = 0; + chunk_list->chunk[0].img_end_sector = (size >> 11) - 1; + chunk_list->chunk[0].disk_start_sector = sector; + chunk_list->chunk[0].disk_end_sector = sector + sizeshift - 1; + chunk_list->cur_chunk = 1; + return 0; + } + + last_chunk = chunk_list->chunk + chunk_list->cur_chunk - 1; + if (last_chunk->disk_end_sector + 1 == sector) + { + last_chunk->img_end_sector += (size >> 11); + last_chunk->disk_end_sector += sizeshift; + return 0; + } + + if (chunk_list->cur_chunk == chunk_list->max_chunk) + { + new_chunk = grub_realloc(chunk_list->chunk, chunk_list->max_chunk * 2 * sizeof(ventoy_img_chunk)); + if (NULL == new_chunk) + { + return -1; + } + chunk_list->chunk = new_chunk; + chunk_list->max_chunk *= 2; + + /* issue: update last_chunk */ + last_chunk = chunk_list->chunk + chunk_list->cur_chunk - 1; + } + + new_chunk = chunk_list->chunk + chunk_list->cur_chunk; + new_chunk->img_start_sector = last_chunk->img_end_sector + 1; + new_chunk->img_end_sector = new_chunk->img_start_sector + (size >> 11) - 1; + new_chunk->disk_start_sector = sector; + new_chunk->disk_end_sector = sector + sizeshift - 1; + + chunk_list->cur_chunk++; + + return 0; +} + +grub_err_t grub_disk_blocklist_read2(grub_disk_t disk, grub_uint64_t sector, + grub_uint64_t size, char *buf) +{ + ventoy_img_chunk_list *chunk_list = (ventoy_img_chunk_list *)(disk->read_hook_data); + + if (buf < chunk_list->buf || buf >= chunk_list->buf + VTOY_CHUNK_BUF_SIZE) + { + return 2; + } + + if ((chunk_list->buf + chunk_list->last_off) != buf) + { + chunk_list->err_code = VTOY_CHUNK_ERR_NOT_FLAT; + return 0; + } + + if (chunk_list->last_off + size > VTOY_CHUNK_BUF_SIZE) + { + chunk_list->err_code = VTOY_CHUNK_ERR_OVER_FLOW; + return 0; + } + + chunk_list->last_off += (grub_uint32_t)size; + if (chunk_list->last_off == VTOY_CHUNK_BUF_SIZE) + { + chunk_list->last_off = 0; + } + + return grub_disk_blocklist_read(chunk_list, sector, size, disk->log_sector_size); +} + +/* Read data from the disk. */ +grub_err_t +grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector, + grub_off_t offset, grub_size_t size, void *buf) +{ + if (disk->read_hook == (grub_disk_read_hook_t)(void *)grub_disk_blocklist_read) + { + return grub_disk_blocklist_read((ventoy_img_chunk_list *)disk->read_hook_data, sector, size, disk->log_sector_size); + } + else if (disk->read_hook == (grub_disk_read_hook_t)(void *)grub_disk_blocklist_read2) + { + grub_err_t rv = grub_disk_blocklist_read2(disk, sector, size, (char *)buf); + if (rv != 2) + { + return rv; + } + } + + /* First of all, check if the region is within the disk. */ + if (grub_disk_adjust_range (disk, §or, &offset, size) != GRUB_ERR_NONE) + { + grub_error_push (); + grub_dprintf ("disk", "Read out of range: sector 0x%llx (%s).\n", + (unsigned long long) sector, grub_errmsg); + grub_error_pop (); + return grub_errno; + } + + /* First read until first cache boundary. */ + if (offset || (sector & (GRUB_DISK_CACHE_SIZE - 1))) + { + grub_disk_addr_t start_sector; + grub_size_t pos; + grub_err_t err; + grub_size_t len; + + start_sector = sector & ~((grub_disk_addr_t) GRUB_DISK_CACHE_SIZE - 1); + pos = (sector - start_sector) << GRUB_DISK_SECTOR_BITS; + len = ((GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS) + - pos - offset); + if (len > size) + len = size; + err = grub_disk_read_small (disk, start_sector, + offset + pos, len, buf); + if (err) + return err; + buf = (char *) buf + len; + size -= len; + offset += len; + sector += (offset >> GRUB_DISK_SECTOR_BITS); + offset &= ((1 << GRUB_DISK_SECTOR_BITS) - 1); + } + + /* Until SIZE is zero... */ + while (size >= (GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS)) + { + char *data = NULL; + grub_disk_addr_t agglomerate; + grub_err_t err; + + /* agglomerate read until we find a first cached entry. */ + for (agglomerate = 0; agglomerate + < (size >> (GRUB_DISK_SECTOR_BITS + GRUB_DISK_CACHE_BITS)) + && agglomerate < disk->max_agglomerate; + agglomerate++) + { + data = grub_disk_cache_fetch (disk->dev->id, disk->id, + sector + (agglomerate + << GRUB_DISK_CACHE_BITS)); + if (data) + break; + } + + if (data) + { + grub_memcpy ((char *) buf + + (agglomerate << (GRUB_DISK_CACHE_BITS + + GRUB_DISK_SECTOR_BITS)), + data, GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS); + grub_disk_cache_unlock (disk->dev->id, disk->id, + sector + (agglomerate + << GRUB_DISK_CACHE_BITS)); + } + + if (agglomerate) + { + grub_disk_addr_t i; + + err = (disk->dev->disk_read) (disk, transform_sector (disk, sector), + agglomerate << (GRUB_DISK_CACHE_BITS + + GRUB_DISK_SECTOR_BITS + - disk->log_sector_size), + buf); + if (err) + return err; + + for (i = 0; i < agglomerate; i ++) + grub_disk_cache_store (disk->dev->id, disk->id, + sector + (i << GRUB_DISK_CACHE_BITS), + (char *) buf + + (i << (GRUB_DISK_CACHE_BITS + + GRUB_DISK_SECTOR_BITS))); + + + if (disk->read_hook) + (disk->read_hook) (sector, 0, agglomerate << (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS), + disk->read_hook_data); + + sector += agglomerate << GRUB_DISK_CACHE_BITS; + size -= agglomerate << (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS); + buf = (char *) buf + + (agglomerate << (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS)); + } + + if (data) + { + if (disk->read_hook) + (disk->read_hook) (sector, 0, (GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS), + disk->read_hook_data); + sector += GRUB_DISK_CACHE_SIZE; + buf = (char *) buf + (GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS); + size -= (GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS); + } + } + + /* And now read the last part. */ + if (size) + { + grub_err_t err; + err = grub_disk_read_small (disk, sector, 0, size, buf); + if (err) + return err; + } + + return grub_errno; +} + +grub_uint64_t +grub_disk_get_size (grub_disk_t disk) +{ + if (disk->partition) + return grub_partition_get_len (disk->partition); + else if (disk->total_sectors != GRUB_DISK_SIZE_UNKNOWN) + return disk->total_sectors << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS); + else + return GRUB_DISK_SIZE_UNKNOWN; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/efi/efi.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/efi/efi.c new file mode 100644 index 0000000..a93da19 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/efi/efi.c @@ -0,0 +1,983 @@ +/* efi.c - generic EFI support */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* The handle of GRUB itself. Filled in by the startup code. */ +grub_efi_handle_t grub_efi_image_handle; + +/* The pointer to a system table. Filled in by the startup code. */ +grub_efi_system_table_t *grub_efi_system_table; + +static grub_efi_guid_t console_control_guid = GRUB_EFI_CONSOLE_CONTROL_GUID; +static grub_efi_guid_t loaded_image_guid = GRUB_EFI_LOADED_IMAGE_GUID; +static grub_efi_guid_t device_path_guid = GRUB_EFI_DEVICE_PATH_GUID; + +void * +grub_efi_locate_protocol (grub_efi_guid_t *protocol, void *registration) +{ + void *interface; + grub_efi_status_t status; + + status = efi_call_3 (grub_efi_system_table->boot_services->locate_protocol, + protocol, registration, &interface); + if (status != GRUB_EFI_SUCCESS) + return 0; + + return interface; +} + +/* Return the array of handles which meet the requirement. If successful, + the number of handles is stored in NUM_HANDLES. The array is allocated + from the heap. */ +grub_efi_handle_t * +grub_efi_locate_handle (grub_efi_locate_search_type_t search_type, + grub_efi_guid_t *protocol, + void *search_key, + grub_efi_uintn_t *num_handles) +{ + grub_efi_boot_services_t *b; + grub_efi_status_t status; + grub_efi_handle_t *buffer; + grub_efi_uintn_t buffer_size = 8 * sizeof (grub_efi_handle_t); + + buffer = grub_malloc (buffer_size); + if (! buffer) + return 0; + + b = grub_efi_system_table->boot_services; + status = efi_call_5 (b->locate_handle, search_type, protocol, search_key, + &buffer_size, buffer); + if (status == GRUB_EFI_BUFFER_TOO_SMALL) + { + grub_free (buffer); + buffer = grub_malloc (buffer_size); + if (! buffer) + return 0; + + status = efi_call_5 (b->locate_handle, search_type, protocol, search_key, + &buffer_size, buffer); + } + + if (status != GRUB_EFI_SUCCESS) + { + grub_free (buffer); + return 0; + } + + *num_handles = buffer_size / sizeof (grub_efi_handle_t); + return buffer; +} + +void * +grub_efi_open_protocol (grub_efi_handle_t handle, + grub_efi_guid_t *protocol, + grub_efi_uint32_t attributes) +{ + grub_efi_boot_services_t *b; + grub_efi_status_t status; + void *interface; + + b = grub_efi_system_table->boot_services; + status = efi_call_6 (b->open_protocol, handle, + protocol, + &interface, + grub_efi_image_handle, + 0, + attributes); + if (status != GRUB_EFI_SUCCESS) + return 0; + + return interface; +} + +int +grub_efi_set_text_mode (int on) +{ + grub_efi_console_control_protocol_t *c; + grub_efi_screen_mode_t mode, new_mode; + + c = grub_efi_locate_protocol (&console_control_guid, 0); + if (! c) + /* No console control protocol instance available, assume it is + already in text mode. */ + return 1; + + if (efi_call_4 (c->get_mode, c, &mode, 0, 0) != GRUB_EFI_SUCCESS) + return 0; + + new_mode = on ? GRUB_EFI_SCREEN_TEXT : GRUB_EFI_SCREEN_GRAPHICS; + if (mode != new_mode) + if (efi_call_2 (c->set_mode, c, new_mode) != GRUB_EFI_SUCCESS) + return 0; + + return 1; +} + +void +grub_efi_stall (grub_efi_uintn_t microseconds) +{ + efi_call_1 (grub_efi_system_table->boot_services->stall, microseconds); +} + +grub_efi_loaded_image_t * +grub_efi_get_loaded_image (grub_efi_handle_t image_handle) +{ + return grub_efi_open_protocol (image_handle, + &loaded_image_guid, + GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); +} + +void +grub_reboot (void) +{ + grub_machine_fini (GRUB_LOADER_FLAG_NORETURN); + efi_call_4 (grub_efi_system_table->runtime_services->reset_system, + GRUB_EFI_RESET_COLD, GRUB_EFI_SUCCESS, 0, NULL); + for (;;) ; +} + +void +grub_exit (void) +{ + grub_machine_fini (GRUB_LOADER_FLAG_NORETURN); + efi_call_4 (grub_efi_system_table->boot_services->exit, + grub_efi_image_handle, GRUB_EFI_SUCCESS, 0, 0); + for (;;) ; +} + +grub_err_t +grub_efi_set_virtual_address_map (grub_efi_uintn_t memory_map_size, + grub_efi_uintn_t descriptor_size, + grub_efi_uint32_t descriptor_version, + grub_efi_memory_descriptor_t *virtual_map) +{ + grub_efi_runtime_services_t *r; + grub_efi_status_t status; + + r = grub_efi_system_table->runtime_services; + status = efi_call_4 (r->set_virtual_address_map, memory_map_size, + descriptor_size, descriptor_version, virtual_map); + + if (status == GRUB_EFI_SUCCESS) + return GRUB_ERR_NONE; + + return grub_error (GRUB_ERR_IO, "set_virtual_address_map failed"); +} + +grub_err_t +grub_efi_set_variable(const char *var, const grub_efi_guid_t *guid, + void *data, grub_size_t datasize) +{ + grub_efi_status_t status; + grub_efi_runtime_services_t *r; + grub_efi_char16_t *var16; + grub_size_t len, len16; + + len = grub_strlen (var); + len16 = len * GRUB_MAX_UTF16_PER_UTF8; + var16 = grub_malloc ((len16 + 1) * sizeof (var16[0])); + if (!var16) + return grub_errno; + len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL); + var16[len16] = 0; + + r = grub_efi_system_table->runtime_services; + + status = efi_call_5 (r->set_variable, var16, guid, + (GRUB_EFI_VARIABLE_NON_VOLATILE + | GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS + | GRUB_EFI_VARIABLE_RUNTIME_ACCESS), + datasize, data); + grub_free (var16); + if (status == GRUB_EFI_SUCCESS) + return GRUB_ERR_NONE; + + return grub_error (GRUB_ERR_IO, "could not set EFI variable `%s'", var); +} + +void * +grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid, + grub_size_t *datasize_out) +{ + grub_efi_status_t status; + grub_efi_uintn_t datasize = 0; + grub_efi_runtime_services_t *r; + grub_efi_char16_t *var16; + void *data; + grub_size_t len, len16; + + *datasize_out = 0; + + len = grub_strlen (var); + len16 = len * GRUB_MAX_UTF16_PER_UTF8; + var16 = grub_malloc ((len16 + 1) * sizeof (var16[0])); + if (!var16) + return NULL; + len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL); + var16[len16] = 0; + + r = grub_efi_system_table->runtime_services; + + status = efi_call_5 (r->get_variable, var16, guid, NULL, &datasize, NULL); + + if (status != GRUB_EFI_BUFFER_TOO_SMALL || !datasize) + { + grub_free (var16); + return NULL; + } + + data = grub_malloc (datasize); + if (!data) + { + grub_free (var16); + return NULL; + } + + status = efi_call_5 (r->get_variable, var16, guid, NULL, &datasize, data); + grub_free (var16); + + if (status == GRUB_EFI_SUCCESS) + { + *datasize_out = datasize; + return data; + } + + grub_free (data); + return NULL; +} + +#pragma GCC diagnostic ignored "-Wcast-align" + +/* Search the mods section from the PE32/PE32+ image. This code uses + a PE32 header, but should work with PE32+ as well. */ +grub_addr_t +grub_efi_modules_addr (void) +{ + grub_efi_loaded_image_t *image; + struct grub_pe32_header *header; + struct grub_pe32_coff_header *coff_header; + struct grub_pe32_section_table *sections; + struct grub_pe32_section_table *section; + struct grub_module_info *info; + grub_uint16_t i; + + image = grub_efi_get_loaded_image (grub_efi_image_handle); + if (! image) + return 0; + + header = image->image_base; + coff_header = &(header->coff_header); + sections + = (struct grub_pe32_section_table *) ((char *) coff_header + + sizeof (*coff_header) + + coff_header->optional_header_size); + + for (i = 0, section = sections; + i < coff_header->num_sections; + i++, section++) + { + if (grub_strcmp (section->name, "mods") == 0) + break; + } + + if (i == coff_header->num_sections) + return 0; + + info = (struct grub_module_info *) ((char *) image->image_base + + section->virtual_address); + if (info->magic != GRUB_MODULE_MAGIC) + return 0; + + return (grub_addr_t) info; +} + +#pragma GCC diagnostic error "-Wcast-align" + +char * +grub_efi_get_filename (grub_efi_device_path_t *dp0) +{ + char *name = 0, *p, *pi; + grub_size_t filesize = 0; + grub_efi_device_path_t *dp; + + if (!dp0) + return NULL; + + dp = dp0; + + while (1) + { + grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp); + grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp); + + if (type == GRUB_EFI_END_DEVICE_PATH_TYPE) + break; + if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE + && subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE) + { + grub_efi_uint16_t len; + len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4) + / sizeof (grub_efi_char16_t)); + filesize += GRUB_MAX_UTF8_PER_UTF16 * len + 2; + } + + dp = GRUB_EFI_NEXT_DEVICE_PATH (dp); + } + + if (!filesize) + return NULL; + + dp = dp0; + + p = name = grub_malloc (filesize); + if (!name) + return NULL; + + while (1) + { + grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp); + grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp); + + if (type == GRUB_EFI_END_DEVICE_PATH_TYPE) + break; + else if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE + && subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE) + { + grub_efi_file_path_device_path_t *fp; + grub_efi_uint16_t len; + grub_efi_char16_t *dup_name; + + *p++ = '/'; + + len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4) + / sizeof (grub_efi_char16_t)); + fp = (grub_efi_file_path_device_path_t *) dp; + /* According to EFI spec Path Name is NULL terminated */ + while (len > 0 && fp->path_name[len - 1] == 0) + len--; + + dup_name = grub_malloc (len * sizeof (*dup_name)); + if (!dup_name) + { + grub_free (name); + return NULL; + } + p = (char *) grub_utf16_to_utf8 ((unsigned char *) p, + grub_memcpy (dup_name, fp->path_name, len * sizeof (*dup_name)), + len); + grub_free (dup_name); + } + + dp = GRUB_EFI_NEXT_DEVICE_PATH (dp); + } + + *p = '\0'; + + for (pi = name, p = name; *pi;) + { + /* EFI breaks paths with backslashes. */ + if (*pi == '\\' || *pi == '/') + { + *p++ = '/'; + while (*pi == '\\' || *pi == '/') + pi++; + continue; + } + *p++ = *pi++; + } + *p = '\0'; + + return name; +} + +grub_efi_device_path_t * +grub_efi_get_device_path (grub_efi_handle_t handle) +{ + return grub_efi_open_protocol (handle, &device_path_guid, + GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); +} + +/* Return the device path node right before the end node. */ +grub_efi_device_path_t * +grub_efi_find_last_device_path (const grub_efi_device_path_t *dp) +{ + grub_efi_device_path_t *next, *p; + + if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp)) + return 0; + + for (p = (grub_efi_device_path_t *) dp, next = GRUB_EFI_NEXT_DEVICE_PATH (p); + ! GRUB_EFI_END_ENTIRE_DEVICE_PATH (next); + p = next, next = GRUB_EFI_NEXT_DEVICE_PATH (next)) + ; + + return p; +} + +/* Duplicate a device path. */ +grub_efi_device_path_t * +grub_efi_duplicate_device_path (const grub_efi_device_path_t *dp) +{ + grub_efi_device_path_t *p; + grub_size_t total_size = 0; + + for (p = (grub_efi_device_path_t *) dp; + ; + p = GRUB_EFI_NEXT_DEVICE_PATH (p)) + { + total_size += GRUB_EFI_DEVICE_PATH_LENGTH (p); + if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (p)) + break; + } + + p = grub_malloc (total_size); + if (! p) + return 0; + + grub_memcpy (p, dp, total_size); + return p; +} + +static void +dump_vendor_path (const char *type, grub_efi_vendor_device_path_t *vendor) +{ + grub_uint32_t vendor_data_len = vendor->header.length - sizeof (*vendor); + grub_printf ("/%sVendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)[%x: ", + type, + (unsigned) vendor->vendor_guid.data1, + (unsigned) vendor->vendor_guid.data2, + (unsigned) vendor->vendor_guid.data3, + (unsigned) vendor->vendor_guid.data4[0], + (unsigned) vendor->vendor_guid.data4[1], + (unsigned) vendor->vendor_guid.data4[2], + (unsigned) vendor->vendor_guid.data4[3], + (unsigned) vendor->vendor_guid.data4[4], + (unsigned) vendor->vendor_guid.data4[5], + (unsigned) vendor->vendor_guid.data4[6], + (unsigned) vendor->vendor_guid.data4[7], + vendor_data_len); + if (vendor->header.length > sizeof (*vendor)) + { + grub_uint32_t i; + for (i = 0; i < vendor_data_len; i++) + grub_printf ("%02x ", vendor->vendor_defined_data[i]); + } + grub_printf ("]"); +} + + +/* Print the chain of Device Path nodes. This is mainly for debugging. */ +void +grub_efi_print_device_path (grub_efi_device_path_t *dp) +{ + while (1) + { + grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp); + grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp); + grub_efi_uint16_t len = GRUB_EFI_DEVICE_PATH_LENGTH (dp); + + switch (type) + { + case GRUB_EFI_END_DEVICE_PATH_TYPE: + switch (subtype) + { + case GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE: + grub_printf ("/EndEntire\n"); + //grub_putchar ('\n'); + break; + case GRUB_EFI_END_THIS_DEVICE_PATH_SUBTYPE: + grub_printf ("/EndThis\n"); + //grub_putchar ('\n'); + break; + default: + grub_printf ("/EndUnknown(%x)\n", (unsigned) subtype); + break; + } + break; + + case GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE: + switch (subtype) + { + case GRUB_EFI_PCI_DEVICE_PATH_SUBTYPE: + { + grub_efi_pci_device_path_t *pci + = (grub_efi_pci_device_path_t *) dp; + grub_printf ("/PCI(%x,%x)", + (unsigned) pci->function, (unsigned) pci->device); + } + break; + case GRUB_EFI_PCCARD_DEVICE_PATH_SUBTYPE: + { + grub_efi_pccard_device_path_t *pccard + = (grub_efi_pccard_device_path_t *) dp; + grub_printf ("/PCCARD(%x)", + (unsigned) pccard->function); + } + break; + case GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE: + { + grub_efi_memory_mapped_device_path_t *mmapped + = (grub_efi_memory_mapped_device_path_t *) dp; + grub_printf ("/MMap(%x,%llx,%llx)", + (unsigned) mmapped->memory_type, + (unsigned long long) mmapped->start_address, + (unsigned long long) mmapped->end_address); + } + break; + case GRUB_EFI_VENDOR_DEVICE_PATH_SUBTYPE: + dump_vendor_path ("Hardware", + (grub_efi_vendor_device_path_t *) dp); + break; + case GRUB_EFI_CONTROLLER_DEVICE_PATH_SUBTYPE: + { + grub_efi_controller_device_path_t *controller + = (grub_efi_controller_device_path_t *) dp; + grub_printf ("/Ctrl(%x)", + (unsigned) controller->controller_number); + } + break; + default: + grub_printf ("/UnknownHW(%x)", (unsigned) subtype); + break; + } + break; + + case GRUB_EFI_ACPI_DEVICE_PATH_TYPE: + switch (subtype) + { + case GRUB_EFI_ACPI_DEVICE_PATH_SUBTYPE: + { + grub_efi_acpi_device_path_t *acpi + = (grub_efi_acpi_device_path_t *) dp; + grub_printf ("/ACPI(%x,%x)", + (unsigned) acpi->hid, + (unsigned) acpi->uid); + } + break; + case GRUB_EFI_EXPANDED_ACPI_DEVICE_PATH_SUBTYPE: + { + grub_efi_expanded_acpi_device_path_t *eacpi + = (grub_efi_expanded_acpi_device_path_t *) dp; + grub_printf ("/ACPI("); + + if (GRUB_EFI_EXPANDED_ACPI_HIDSTR (dp)[0] == '\0') + grub_printf ("%x,", (unsigned) eacpi->hid); + else + grub_printf ("%s,", GRUB_EFI_EXPANDED_ACPI_HIDSTR (dp)); + + if (GRUB_EFI_EXPANDED_ACPI_UIDSTR (dp)[0] == '\0') + grub_printf ("%x,", (unsigned) eacpi->uid); + else + grub_printf ("%s,", GRUB_EFI_EXPANDED_ACPI_UIDSTR (dp)); + + if (GRUB_EFI_EXPANDED_ACPI_CIDSTR (dp)[0] == '\0') + grub_printf ("%x)", (unsigned) eacpi->cid); + else + grub_printf ("%s)", GRUB_EFI_EXPANDED_ACPI_CIDSTR (dp)); + } + break; + default: + grub_printf ("/UnknownACPI(%x)", (unsigned) subtype); + break; + } + break; + + case GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE: + switch (subtype) + { + case GRUB_EFI_ATAPI_DEVICE_PATH_SUBTYPE: + { + grub_efi_atapi_device_path_t *atapi + = (grub_efi_atapi_device_path_t *) dp; + grub_printf ("/ATAPI(%x,%x,%x)", + (unsigned) atapi->primary_secondary, + (unsigned) atapi->slave_master, + (unsigned) atapi->lun); + } + break; + case GRUB_EFI_SCSI_DEVICE_PATH_SUBTYPE: + { + grub_efi_scsi_device_path_t *scsi + = (grub_efi_scsi_device_path_t *) dp; + grub_printf ("/SCSI(%x,%x)", + (unsigned) scsi->pun, + (unsigned) scsi->lun); + } + break; + case GRUB_EFI_FIBRE_CHANNEL_DEVICE_PATH_SUBTYPE: + { + grub_efi_fibre_channel_device_path_t *fc + = (grub_efi_fibre_channel_device_path_t *) dp; + grub_printf ("/FibreChannel(%llx,%llx)", + (unsigned long long) fc->wwn, + (unsigned long long) fc->lun); + } + break; + case GRUB_EFI_1394_DEVICE_PATH_SUBTYPE: + { + grub_efi_1394_device_path_t *firewire + = (grub_efi_1394_device_path_t *) dp; + grub_printf ("/1394(%llx)", + (unsigned long long) firewire->guid); + } + break; + case GRUB_EFI_USB_DEVICE_PATH_SUBTYPE: + { + grub_efi_usb_device_path_t *usb + = (grub_efi_usb_device_path_t *) dp; + grub_printf ("/USB(%x,%x)", + (unsigned) usb->parent_port_number, + (unsigned) usb->usb_interface); + } + break; + case GRUB_EFI_USB_CLASS_DEVICE_PATH_SUBTYPE: + { + grub_efi_usb_class_device_path_t *usb_class + = (grub_efi_usb_class_device_path_t *) dp; + grub_printf ("/USBClass(%x,%x,%x,%x,%x)", + (unsigned) usb_class->vendor_id, + (unsigned) usb_class->product_id, + (unsigned) usb_class->device_class, + (unsigned) usb_class->device_subclass, + (unsigned) usb_class->device_protocol); + } + break; + case GRUB_EFI_I2O_DEVICE_PATH_SUBTYPE: + { + grub_efi_i2o_device_path_t *i2o + = (grub_efi_i2o_device_path_t *) dp; + grub_printf ("/I2O(%x)", (unsigned) i2o->tid); + } + break; + case GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE: + { + grub_efi_mac_address_device_path_t *mac + = (grub_efi_mac_address_device_path_t *) dp; + grub_printf ("/MacAddr(%02x:%02x:%02x:%02x:%02x:%02x,%x)", + (unsigned) mac->mac_address[0], + (unsigned) mac->mac_address[1], + (unsigned) mac->mac_address[2], + (unsigned) mac->mac_address[3], + (unsigned) mac->mac_address[4], + (unsigned) mac->mac_address[5], + (unsigned) mac->if_type); + } + break; + case GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE: + { + grub_efi_ipv4_device_path_t *ipv4 + = (grub_efi_ipv4_device_path_t *) dp; + grub_printf ("/IPv4(%u.%u.%u.%u,%u.%u.%u.%u,%u,%u,%x,%x)", + (unsigned) ipv4->local_ip_address[0], + (unsigned) ipv4->local_ip_address[1], + (unsigned) ipv4->local_ip_address[2], + (unsigned) ipv4->local_ip_address[3], + (unsigned) ipv4->remote_ip_address[0], + (unsigned) ipv4->remote_ip_address[1], + (unsigned) ipv4->remote_ip_address[2], + (unsigned) ipv4->remote_ip_address[3], + (unsigned) ipv4->local_port, + (unsigned) ipv4->remote_port, + (unsigned) ipv4->protocol, + (unsigned) ipv4->static_ip_address); + } + break; + case GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE: + { + grub_efi_ipv6_device_path_t *ipv6 + = (grub_efi_ipv6_device_path_t *) dp; + grub_printf ("/IPv6(%x:%x:%x:%x:%x:%x:%x:%x,%x:%x:%x:%x:%x:%x:%x:%x,%u,%u,%x,%x)", + (unsigned) ipv6->local_ip_address[0], + (unsigned) ipv6->local_ip_address[1], + (unsigned) ipv6->local_ip_address[2], + (unsigned) ipv6->local_ip_address[3], + (unsigned) ipv6->local_ip_address[4], + (unsigned) ipv6->local_ip_address[5], + (unsigned) ipv6->local_ip_address[6], + (unsigned) ipv6->local_ip_address[7], + (unsigned) ipv6->remote_ip_address[0], + (unsigned) ipv6->remote_ip_address[1], + (unsigned) ipv6->remote_ip_address[2], + (unsigned) ipv6->remote_ip_address[3], + (unsigned) ipv6->remote_ip_address[4], + (unsigned) ipv6->remote_ip_address[5], + (unsigned) ipv6->remote_ip_address[6], + (unsigned) ipv6->remote_ip_address[7], + (unsigned) ipv6->local_port, + (unsigned) ipv6->remote_port, + (unsigned) ipv6->protocol, + (unsigned) ipv6->static_ip_address); + } + break; + case GRUB_EFI_INFINIBAND_DEVICE_PATH_SUBTYPE: + { + grub_efi_infiniband_device_path_t *ib + = (grub_efi_infiniband_device_path_t *) dp; + grub_printf ("/InfiniBand(%x,%llx,%llx,%llx)", + (unsigned) ib->port_gid[0], /* XXX */ + (unsigned long long) ib->remote_id, + (unsigned long long) ib->target_port_id, + (unsigned long long) ib->device_id); + } + break; + case GRUB_EFI_UART_DEVICE_PATH_SUBTYPE: + { + grub_efi_uart_device_path_t *uart + = (grub_efi_uart_device_path_t *) dp; + grub_printf ("/UART(%llu,%u,%x,%x)", + (unsigned long long) uart->baud_rate, + uart->data_bits, + uart->parity, + uart->stop_bits); + } + break; + case GRUB_EFI_SATA_DEVICE_PATH_SUBTYPE: + { + grub_efi_sata_device_path_t *sata; + sata = (grub_efi_sata_device_path_t *) dp; + grub_printf ("/Sata(%x,%x,%x)", + sata->hba_port, + sata->multiplier_port, + sata->lun); + } + break; + + case GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE: + dump_vendor_path ("Messaging", + (grub_efi_vendor_device_path_t *) dp); + break; + default: + grub_printf ("/UnknownMessaging(%x)", (unsigned) subtype); + break; + } + break; + + case GRUB_EFI_MEDIA_DEVICE_PATH_TYPE: + switch (subtype) + { + case GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE: + { + grub_efi_hard_drive_device_path_t *hd = (grub_efi_hard_drive_device_path_t *) dp; + grub_printf ("/HD(%u,%llx,%llx,%02x%02x%02x%02x%02x%02x%02x%02x,%x,%x)", + hd->partition_number, + (unsigned long long) hd->partition_start, + (unsigned long long) hd->partition_size, + (unsigned) hd->partition_signature[0], + (unsigned) hd->partition_signature[1], + (unsigned) hd->partition_signature[2], + (unsigned) hd->partition_signature[3], + (unsigned) hd->partition_signature[4], + (unsigned) hd->partition_signature[5], + (unsigned) hd->partition_signature[6], + (unsigned) hd->partition_signature[7], + (unsigned) hd->partmap_type, + (unsigned) hd->signature_type); + } + break; + case GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE: + { + grub_efi_cdrom_device_path_t *cd + = (grub_efi_cdrom_device_path_t *) dp; + grub_printf ("/CD(%u,%llx,%llx)", + cd->boot_entry, + (unsigned long long) cd->partition_start, + (unsigned long long) cd->partition_size); + } + break; + case GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE: + dump_vendor_path ("Media", + (grub_efi_vendor_device_path_t *) dp); + break; + case GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE: + { + grub_efi_file_path_device_path_t *fp; + grub_uint8_t *buf; + fp = (grub_efi_file_path_device_path_t *) dp; + buf = grub_malloc ((len - 4) * 2 + 1); + if (buf) + { + grub_efi_char16_t *dup_name = grub_malloc (len - 4); + if (!dup_name) + { + grub_errno = GRUB_ERR_NONE; + grub_printf ("/File((null))"); + grub_free (buf); + break; + } + *grub_utf16_to_utf8 (buf, grub_memcpy (dup_name, fp->path_name, len - 4), + (len - 4) / sizeof (grub_efi_char16_t)) + = '\0'; + grub_free (dup_name); + } + else + grub_errno = GRUB_ERR_NONE; + grub_printf ("/File(%s)", buf); + grub_free (buf); + } + break; + case GRUB_EFI_PROTOCOL_DEVICE_PATH_SUBTYPE: + { + grub_efi_protocol_device_path_t *proto + = (grub_efi_protocol_device_path_t *) dp; + grub_printf ("/Protocol(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)", + (unsigned) proto->guid.data1, + (unsigned) proto->guid.data2, + (unsigned) proto->guid.data3, + (unsigned) proto->guid.data4[0], + (unsigned) proto->guid.data4[1], + (unsigned) proto->guid.data4[2], + (unsigned) proto->guid.data4[3], + (unsigned) proto->guid.data4[4], + (unsigned) proto->guid.data4[5], + (unsigned) proto->guid.data4[6], + (unsigned) proto->guid.data4[7]); + } + break; + default: + grub_printf ("/UnknownMedia(%x)", (unsigned) subtype); + break; + } + break; + + case GRUB_EFI_BIOS_DEVICE_PATH_TYPE: + switch (subtype) + { + case GRUB_EFI_BIOS_DEVICE_PATH_SUBTYPE: + { + grub_efi_bios_device_path_t *bios + = (grub_efi_bios_device_path_t *) dp; + grub_printf ("/BIOS(%x,%x,%s)", + (unsigned) bios->device_type, + (unsigned) bios->status_flags, + (char *) (dp + 1)); + } + break; + default: + grub_printf ("/UnknownBIOS(%x)", (unsigned) subtype); + break; + } + break; + + default: + grub_printf ("/UnknownType(%x,%x)\n", + (unsigned) type, + (unsigned) subtype); + return; + break; + } + + if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp)) + break; + + dp = (grub_efi_device_path_t *) ((char *) dp + len); + } +} + +/* Compare device paths. */ +int +grub_efi_compare_device_paths (const grub_efi_device_path_t *dp1, + const grub_efi_device_path_t *dp2) +{ + if (! dp1 || ! dp2) + /* Return non-zero. */ + return 1; + + while (1) + { + grub_efi_uint8_t type1, type2; + grub_efi_uint8_t subtype1, subtype2; + grub_efi_uint16_t len1, len2; + int ret; + + type1 = GRUB_EFI_DEVICE_PATH_TYPE (dp1); + type2 = GRUB_EFI_DEVICE_PATH_TYPE (dp2); + + if (type1 != type2) + return (int) type2 - (int) type1; + + subtype1 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp1); + subtype2 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp2); + + if (subtype1 != subtype2) + return (int) subtype1 - (int) subtype2; + + len1 = GRUB_EFI_DEVICE_PATH_LENGTH (dp1); + len2 = GRUB_EFI_DEVICE_PATH_LENGTH (dp2); + + if (len1 != len2) + return (int) len1 - (int) len2; + + ret = grub_memcmp (dp1, dp2, len1); + if (ret != 0) + return ret; + + if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp1)) + break; + + dp1 = (grub_efi_device_path_t *) ((char *) dp1 + len1); + dp2 = (grub_efi_device_path_t *) ((char *) dp2 + len2); + } + + return 0; +} + +void * grub_efi_allocate_iso_buf(grub_uint64_t size) +{ + grub_efi_boot_services_t *b; + grub_efi_status_t status; + grub_efi_physical_address_t address = 0; + grub_efi_uintn_t pages = GRUB_EFI_BYTES_TO_PAGES(size); + + b = grub_efi_system_table->boot_services; + status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ANY_PAGES, GRUB_EFI_RUNTIME_SERVICES_DATA, pages, &address); + if (status != GRUB_EFI_SUCCESS) + { + return NULL; + } + + return (void *)(unsigned long)address; +} + +void * grub_efi_allocate_chain_buf(grub_uint64_t size) +{ + grub_efi_boot_services_t *b; + grub_efi_status_t status; + grub_efi_physical_address_t address = 0; + grub_efi_uintn_t pages = GRUB_EFI_BYTES_TO_PAGES(size); + + b = grub_efi_system_table->boot_services; + status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ANY_PAGES, GRUB_EFI_LOADER_DATA, pages, &address); + if (status != GRUB_EFI_SUCCESS) + { + return NULL; + } + + return (void *)(unsigned long)address; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/efi/mm.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/efi/mm.c new file mode 100644 index 0000000..5a70e09 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/efi/mm.c @@ -0,0 +1,702 @@ +/* mm.c - generic EFI memory management */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +#if defined (__i386__) || defined (__x86_64__) +#include +#endif + +#define NEXT_MEMORY_DESCRIPTOR(desc, size) \ + ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size))) + +#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12) +#define BYTES_TO_PAGES_DOWN(bytes) ((bytes) >> 12) +#define PAGES_TO_BYTES(pages) ((pages) << 12) + +/* The size of a memory map obtained from the firmware. This must be + a multiplier of 4KB. */ +#define MEMORY_MAP_SIZE 0x3000 + +/* The minimum and maximum heap size for GRUB itself. */ +#define MIN_HEAP_SIZE 0x100000 +#define MAX_HEAP_SIZE (1600 * 0x100000) + +static void *finish_mmap_buf = 0; +static grub_efi_uintn_t finish_mmap_size = 0; +static grub_efi_uintn_t finish_key = 0; +static grub_efi_uintn_t finish_desc_size; +static grub_efi_uint32_t finish_desc_version; +int grub_efi_is_finished = 0; + +/* 160MB 160 * 1024 * 1024 / 4096 */ +#define VTOY_CHAIN_MIN_PAGES (160 * 256) +static grub_efi_uint64_t g_total_pages; +static grub_efi_uint64_t g_org_required_pages; +static grub_efi_uint64_t g_new_required_pages; + +/* + * We need to roll back EFI allocations on exit. Remember allocations that + * we'll free on exit. + */ +struct efi_allocation; +struct efi_allocation { + grub_efi_physical_address_t address; + grub_efi_uint64_t pages; + struct efi_allocation *next; +}; +static struct efi_allocation *efi_allocated_memory; + +static void +grub_efi_store_alloc (grub_efi_physical_address_t address, + grub_efi_uintn_t pages) +{ + grub_efi_boot_services_t *b; + struct efi_allocation *alloc; + grub_efi_status_t status; + + b = grub_efi_system_table->boot_services; + status = efi_call_3 (b->allocate_pool, GRUB_EFI_LOADER_DATA, + sizeof(*alloc), (void**)&alloc); + + if (status == GRUB_EFI_SUCCESS) + { + alloc->next = efi_allocated_memory; + alloc->address = address; + alloc->pages = pages; + efi_allocated_memory = alloc; + } + else + grub_printf ("Could not malloc memory to remember EFI allocation. " + "Exiting GRUB won't free all memory.\n"); +} + +static void +grub_efi_drop_alloc (grub_efi_physical_address_t address, + grub_efi_uintn_t pages) +{ + struct efi_allocation *ea, *eap; + grub_efi_boot_services_t *b; + + b = grub_efi_system_table->boot_services; + + for (eap = NULL, ea = efi_allocated_memory; ea; eap = ea, ea = ea->next) + { + if (ea->address != address || ea->pages != pages) + continue; + + /* Remove the current entry from the list. */ + if (eap) + eap->next = ea->next; + else + efi_allocated_memory = ea->next; + + /* Then free the memory backing it. */ + efi_call_1 (b->free_pool, ea); + + /* And leave, we're done. */ + break; + } +} + +/* Allocate pages. Return the pointer to the first of allocated pages. */ +void * +grub_efi_allocate_pages_real (grub_efi_physical_address_t address, + grub_efi_uintn_t pages, + grub_efi_allocate_type_t alloctype, + grub_efi_memory_type_t memtype) +{ + grub_efi_status_t status; + grub_efi_boot_services_t *b; + + /* Limit the memory access to less than 4GB for 32-bit platforms. */ + if (address > GRUB_EFI_MAX_USABLE_ADDRESS) + return 0; + + b = grub_efi_system_table->boot_services; + status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address); + if (status != GRUB_EFI_SUCCESS) + return 0; + + if (address == 0) + { + /* Uggh, the address 0 was allocated... This is too annoying, + so reallocate another one. */ + address = GRUB_EFI_MAX_USABLE_ADDRESS; + status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address); + grub_efi_free_pages (0, pages); + if (status != GRUB_EFI_SUCCESS) + return 0; + } + + grub_efi_store_alloc (address, pages); + + return (void *) ((grub_addr_t) address); +} + +void * +grub_efi_allocate_any_pages (grub_efi_uintn_t pages) +{ + return grub_efi_allocate_pages_real (GRUB_EFI_MAX_USABLE_ADDRESS, + pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, + GRUB_EFI_LOADER_DATA); +} + +void * +grub_efi_allocate_fixed (grub_efi_physical_address_t address, + grub_efi_uintn_t pages) +{ + return grub_efi_allocate_pages_real (address, pages, + GRUB_EFI_ALLOCATE_ADDRESS, + GRUB_EFI_LOADER_DATA); +} + +/* Free pages starting from ADDRESS. */ +void +grub_efi_free_pages (grub_efi_physical_address_t address, + grub_efi_uintn_t pages) +{ + grub_efi_boot_services_t *b; + + b = grub_efi_system_table->boot_services; + efi_call_2 (b->free_pages, address, pages); + + grub_efi_drop_alloc (address, pages); +} + +#if defined (__i386__) || defined (__x86_64__) + +/* Helper for stop_broadcom. */ +static int +find_card (grub_pci_device_t dev, grub_pci_id_t pciid, + void *data __attribute__ ((unused))) +{ + grub_pci_address_t addr; + grub_uint8_t cap; + grub_uint16_t pm_state; + + if ((pciid & 0xffff) != GRUB_PCI_VENDOR_BROADCOM) + return 0; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); + if (grub_pci_read (addr) >> 24 != GRUB_PCI_CLASS_NETWORK) + return 0; + cap = grub_pci_find_capability (dev, GRUB_PCI_CAP_POWER_MANAGEMENT); + if (!cap) + return 0; + addr = grub_pci_make_address (dev, cap + 4); + pm_state = grub_pci_read_word (addr); + pm_state = pm_state | 0x03; + grub_pci_write_word (addr, pm_state); + grub_pci_read_word (addr); + return 0; +} + +static void +stop_broadcom (void) +{ + grub_pci_iterate (find_card, NULL); +} + +#endif + +grub_err_t +grub_efi_finish_boot_services (grub_efi_uintn_t *outbuf_size, void *outbuf, + grub_efi_uintn_t *map_key, + grub_efi_uintn_t *efi_desc_size, + grub_efi_uint32_t *efi_desc_version) +{ + grub_efi_boot_services_t *b; + grub_efi_status_t status; + +#if defined (__i386__) || defined (__x86_64__) + const grub_uint16_t apple[] = { 'A', 'p', 'p', 'l', 'e' }; + int is_apple; + + is_apple = (grub_memcmp (grub_efi_system_table->firmware_vendor, + apple, sizeof (apple)) == 0); +#endif + + while (1) + { + if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf, &finish_key, + &finish_desc_size, &finish_desc_version) < 0) + return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map"); + + if (outbuf && *outbuf_size < finish_mmap_size) + return grub_error (GRUB_ERR_IO, "memory map buffer is too small"); + + finish_mmap_buf = grub_malloc (finish_mmap_size); + if (!finish_mmap_buf) + return grub_errno; + + if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf, &finish_key, + &finish_desc_size, &finish_desc_version) <= 0) + { + grub_free (finish_mmap_buf); + return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map"); + } + + b = grub_efi_system_table->boot_services; + status = efi_call_2 (b->exit_boot_services, grub_efi_image_handle, + finish_key); + if (status == GRUB_EFI_SUCCESS) + break; + + if (status != GRUB_EFI_INVALID_PARAMETER) + { + grub_free (finish_mmap_buf); + return grub_error (GRUB_ERR_IO, "couldn't terminate EFI services"); + } + + grub_free (finish_mmap_buf); + grub_printf ("Trying to terminate EFI services again\n"); + } + grub_efi_is_finished = 1; + if (outbuf_size) + *outbuf_size = finish_mmap_size; + if (outbuf) + grub_memcpy (outbuf, finish_mmap_buf, finish_mmap_size); + if (map_key) + *map_key = finish_key; + if (efi_desc_size) + *efi_desc_size = finish_desc_size; + if (efi_desc_version) + *efi_desc_version = finish_desc_version; + +#if defined (__i386__) || defined (__x86_64__) + if (is_apple) + stop_broadcom (); +#endif + + return GRUB_ERR_NONE; +} + +/* + * To obtain the UEFI memory map, we must pass a buffer of sufficient size + * to hold the entire map. This function returns a sane start value for + * buffer size. + */ +grub_efi_uintn_t +grub_efi_find_mmap_size (void) +{ + grub_efi_uintn_t mmap_size = 0; + grub_efi_uintn_t desc_size; + + if (grub_efi_get_memory_map (&mmap_size, NULL, NULL, &desc_size, 0) < 0) + { + grub_error (GRUB_ERR_IO, "cannot get EFI memory map size"); + return 0; + } + + /* + * Add an extra page, since UEFI can alter the memory map itself on + * callbacks or explicit calls, including console output. + */ + return ALIGN_UP (mmap_size + GRUB_EFI_PAGE_SIZE, GRUB_EFI_PAGE_SIZE); +} + +/* Get the memory map as defined in the EFI spec. Return 1 if successful, + return 0 if partial, or return -1 if an error occurs. */ +int +grub_efi_get_memory_map (grub_efi_uintn_t *memory_map_size, + grub_efi_memory_descriptor_t *memory_map, + grub_efi_uintn_t *map_key, + grub_efi_uintn_t *descriptor_size, + grub_efi_uint32_t *descriptor_version) +{ + grub_efi_status_t status; + grub_efi_boot_services_t *b; + grub_efi_uintn_t key; + grub_efi_uint32_t version; + grub_efi_uintn_t size; + + if (grub_efi_is_finished) + { + int ret = 1; + if (*memory_map_size < finish_mmap_size) + { + grub_memcpy (memory_map, finish_mmap_buf, *memory_map_size); + ret = 0; + } + else + { + grub_memcpy (memory_map, finish_mmap_buf, finish_mmap_size); + ret = 1; + } + *memory_map_size = finish_mmap_size; + if (map_key) + *map_key = finish_key; + if (descriptor_size) + *descriptor_size = finish_desc_size; + if (descriptor_version) + *descriptor_version = finish_desc_version; + return ret; + } + + /* Allow some parameters to be missing. */ + if (! map_key) + map_key = &key; + if (! descriptor_version) + descriptor_version = &version; + if (! descriptor_size) + descriptor_size = &size; + + b = grub_efi_system_table->boot_services; + status = efi_call_5 (b->get_memory_map, memory_map_size, memory_map, map_key, + descriptor_size, descriptor_version); + if (*descriptor_size == 0) + *descriptor_size = sizeof (grub_efi_memory_descriptor_t); + if (status == GRUB_EFI_SUCCESS) + return 1; + else if (status == GRUB_EFI_BUFFER_TOO_SMALL) + return 0; + else + return -1; +} + +/* Sort the memory map in place. */ +static void +sort_memory_map (grub_efi_memory_descriptor_t *memory_map, + grub_efi_uintn_t desc_size, + grub_efi_memory_descriptor_t *memory_map_end) +{ + grub_efi_memory_descriptor_t *d1; + grub_efi_memory_descriptor_t *d2; + + for (d1 = memory_map; + d1 < memory_map_end; + d1 = NEXT_MEMORY_DESCRIPTOR (d1, desc_size)) + { + grub_efi_memory_descriptor_t *max_desc = d1; + + for (d2 = NEXT_MEMORY_DESCRIPTOR (d1, desc_size); + d2 < memory_map_end; + d2 = NEXT_MEMORY_DESCRIPTOR (d2, desc_size)) + { + if (max_desc->num_pages < d2->num_pages) + max_desc = d2; + } + + if (max_desc != d1) + { + grub_efi_memory_descriptor_t tmp; + + tmp = *d1; + *d1 = *max_desc; + *max_desc = tmp; + } + } +} + +/* Filter the descriptors. GRUB needs only available memory. */ +static grub_efi_memory_descriptor_t * +filter_memory_map (grub_efi_memory_descriptor_t *memory_map, + grub_efi_memory_descriptor_t *filtered_memory_map, + grub_efi_uintn_t desc_size, + grub_efi_memory_descriptor_t *memory_map_end) +{ + grub_efi_memory_descriptor_t *desc; + grub_efi_memory_descriptor_t *filtered_desc; + + for (desc = memory_map, filtered_desc = filtered_memory_map; + desc < memory_map_end; + desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) + { + if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY +#if 1 + && desc->physical_start <= GRUB_EFI_MAX_USABLE_ADDRESS +#endif + && desc->physical_start + PAGES_TO_BYTES (desc->num_pages) > 0x100000 + && desc->num_pages != 0) + { + grub_memcpy (filtered_desc, desc, desc_size); + + /* Avoid less than 1MB, because some loaders seem to be confused. */ + if (desc->physical_start < 0x100000) + { + desc->num_pages -= BYTES_TO_PAGES (0x100000 + - desc->physical_start); + desc->physical_start = 0x100000; + } + +#if 1 + if (BYTES_TO_PAGES (filtered_desc->physical_start) + + filtered_desc->num_pages + > BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_USABLE_ADDRESS)) + filtered_desc->num_pages + = (BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_USABLE_ADDRESS) + - BYTES_TO_PAGES (filtered_desc->physical_start)); +#endif + + if (filtered_desc->num_pages == 0) + continue; + + filtered_desc = NEXT_MEMORY_DESCRIPTOR (filtered_desc, desc_size); + } + } + + return filtered_desc; +} + +/* Return the total number of pages. */ +static grub_efi_uint64_t +get_total_pages (grub_efi_memory_descriptor_t *memory_map, + grub_efi_uintn_t desc_size, + grub_efi_memory_descriptor_t *memory_map_end) +{ + grub_efi_memory_descriptor_t *desc; + grub_efi_uint64_t total = 0; + + for (desc = memory_map; + desc < memory_map_end; + desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) + total += desc->num_pages; + + return total; +} + +/* Add memory regions. */ +static void +add_memory_regions (grub_efi_memory_descriptor_t *memory_map, + grub_efi_uintn_t desc_size, + grub_efi_memory_descriptor_t *memory_map_end, + grub_efi_uint64_t required_pages) +{ + grub_efi_memory_descriptor_t *desc; + + for (desc = memory_map; + desc < memory_map_end; + desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) + { + grub_efi_uint64_t pages; + grub_efi_physical_address_t start; + void *addr; + + start = desc->physical_start; + pages = desc->num_pages; + if (pages > required_pages) + { + start += PAGES_TO_BYTES (pages - required_pages); + pages = required_pages; + } + + addr = grub_efi_allocate_pages_real (start, pages, + GRUB_EFI_ALLOCATE_ADDRESS, + GRUB_EFI_LOADER_CODE); + if (! addr) + grub_fatal ("cannot allocate conventional memory %p with %u pages", + (void *) ((grub_addr_t) start), + (unsigned) pages); + + grub_mm_init_region (addr, PAGES_TO_BYTES (pages)); + + required_pages -= pages; + if (required_pages == 0) + break; + } + + if (required_pages > 0) + grub_fatal ("too little memory"); +} + +void +grub_efi_memory_fini (void) +{ + /* + * Free all stale allocations. grub_efi_free_pages() will remove + * the found entry from the list and it will always find the first + * list entry (efi_allocated_memory is the list start). Hence we + * remove all entries from the list until none is left altogether. + */ + while (efi_allocated_memory) + grub_efi_free_pages (efi_allocated_memory->address, + efi_allocated_memory->pages); +} + +#if 0 +/* Print the memory map. */ +static void +print_memory_map (grub_efi_memory_descriptor_t *memory_map, + grub_efi_uintn_t desc_size, + grub_efi_memory_descriptor_t *memory_map_end) +{ + grub_efi_memory_descriptor_t *desc; + int i; + + for (desc = memory_map, i = 0; + desc < memory_map_end; + desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size), i++) + { + grub_printf ("MD: t=%x, p=%llx, v=%llx, n=%llx, a=%llx\n", + desc->type, desc->physical_start, desc->virtual_start, + desc->num_pages, desc->attribute); + } +} +#endif + +void +grub_efi_mm_init (void) +{ + grub_efi_memory_descriptor_t *memory_map; + grub_efi_memory_descriptor_t *memory_map_end; + grub_efi_memory_descriptor_t *filtered_memory_map; + grub_efi_memory_descriptor_t *filtered_memory_map_end; + grub_efi_uintn_t map_size; + grub_efi_uintn_t desc_size; + grub_efi_uint64_t total_pages; + grub_efi_uint64_t required_pages; + int mm_status; + + /* Prepare a memory region to store two memory maps. */ + memory_map = grub_efi_allocate_any_pages (2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE)); + if (! memory_map) + grub_fatal ("cannot allocate memory"); + + /* Obtain descriptors for available memory. */ + map_size = MEMORY_MAP_SIZE; + + mm_status = grub_efi_get_memory_map (&map_size, memory_map, 0, &desc_size, 0); + + if (mm_status == 0) + { + grub_efi_free_pages + ((grub_efi_physical_address_t) ((grub_addr_t) memory_map), + 2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE)); + + /* Freeing/allocating operations may increase memory map size. */ + map_size += desc_size * 32; + + memory_map = grub_efi_allocate_any_pages (2 * BYTES_TO_PAGES (map_size)); + if (! memory_map) + grub_fatal ("cannot allocate memory"); + + mm_status = grub_efi_get_memory_map (&map_size, memory_map, 0, + &desc_size, 0); + } + + if (mm_status < 0) + grub_fatal ("cannot get memory map"); + + memory_map_end = NEXT_MEMORY_DESCRIPTOR (memory_map, map_size); + + filtered_memory_map = memory_map_end; + + filtered_memory_map_end = filter_memory_map (memory_map, filtered_memory_map, + desc_size, memory_map_end); + + /* By default, request a quarter of the available memory. */ + total_pages = get_total_pages (filtered_memory_map, desc_size, + filtered_memory_map_end); + + #if defined (__mips__) && (_MIPS_SIM == _ABI64) + required_pages = (total_pages > 4096) ? (total_pages - 4096) : (total_pages >> 1); + #else + required_pages = (total_pages >> 2); + #endif + + if (required_pages < BYTES_TO_PAGES (MIN_HEAP_SIZE)) + required_pages = BYTES_TO_PAGES (MIN_HEAP_SIZE); + else if (required_pages > BYTES_TO_PAGES (MAX_HEAP_SIZE)) + required_pages = BYTES_TO_PAGES (MAX_HEAP_SIZE); + + g_org_required_pages = required_pages; + if (((total_pages - required_pages) >> 2) < VTOY_CHAIN_MIN_PAGES) + { + if (total_pages > (VTOY_CHAIN_MIN_PAGES << 2)) + { + g_new_required_pages = total_pages - (VTOY_CHAIN_MIN_PAGES << 2); + if (g_new_required_pages >= 8192) + { + required_pages = g_new_required_pages; + } + } + } + + g_total_pages = total_pages; + g_new_required_pages = required_pages; + + /* Sort the filtered descriptors, so that GRUB can allocate pages + from smaller regions. */ + sort_memory_map (filtered_memory_map, desc_size, filtered_memory_map_end); + + /* Allocate memory regions for GRUB's memory management. */ + add_memory_regions (filtered_memory_map, desc_size, + filtered_memory_map_end, required_pages); + +#if 0 + /* For debug. */ + map_size = MEMORY_MAP_SIZE; + + if (grub_efi_get_memory_map (&map_size, memory_map, 0, &desc_size, 0) < 0) + grub_fatal ("cannot get memory map"); + + grub_printf ("printing memory map\n"); + print_memory_map (memory_map, desc_size, + NEXT_MEMORY_DESCRIPTOR (memory_map, map_size)); + grub_fatal ("Debug. "); +#endif + + /* Release the memory maps. */ + grub_efi_free_pages ((grub_addr_t) memory_map, + 2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE)); +} + +#if defined (__aarch64__) || defined (__arm__) || defined (__riscv) +grub_err_t +grub_efi_get_ram_base(grub_addr_t *base_addr) +{ + grub_efi_memory_descriptor_t *memory_map, *desc; + grub_efi_uintn_t memory_map_size, desc_size; + int ret; + + memory_map_size = grub_efi_find_mmap_size(); + + memory_map = grub_malloc (memory_map_size); + if (! memory_map) + return GRUB_ERR_OUT_OF_MEMORY; + ret = grub_efi_get_memory_map (&memory_map_size, memory_map, NULL, + &desc_size, NULL); + + if (ret < 1) + return GRUB_ERR_BUG; + + for (desc = memory_map, *base_addr = GRUB_EFI_MAX_USABLE_ADDRESS; + (grub_addr_t) desc < ((grub_addr_t) memory_map + memory_map_size); + desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) + if (desc->attribute & GRUB_EFI_MEMORY_WB) + *base_addr = grub_min (*base_addr, desc->physical_start); + + grub_free(memory_map); + + return GRUB_ERR_NONE; +} +#endif + +void grub_efi_get_reserved_page_num(grub_uint64_t *total, grub_uint64_t *org_required, grub_uint64_t *new_required) +{ + *total = g_total_pages; + *org_required = g_org_required_pages; + *new_required = g_new_required_pages; +} + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/env.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/env.c new file mode 100644 index 0000000..e008204 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/env.c @@ -0,0 +1,253 @@ +/* env.c - Environment variables */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include + +grub_uint8_t g_sys_sb = 0; +grub_uint8_t g_sb_policy = VTOY_SB_POLICY_BYPASS; + +/* The initial context. */ +static struct grub_env_context initial_context; + +/* The current context. */ +struct grub_env_context *grub_current_context = &initial_context; + +static grub_env_read_hook_t vtoy_menu_lang_read_hook; + +/* Return the hash representation of the string S. */ +static unsigned int +grub_env_hashval (const char *s) +{ + unsigned int i = 0; + + /* XXX: This can be done much more efficiently. */ + while (*s) + i += 5 * *(s++); + + return i % HASHSZ; +} + +static struct grub_env_var * +grub_env_find (const char *name) +{ + struct grub_env_var *var; + int idx = grub_env_hashval (name); + + /* Look for the variable in the current context. */ + for (var = grub_current_context->vars[idx]; var; var = var->next) + if (grub_strcmp (var->name, name) == 0) + return var; + + return 0; +} + +static void +grub_env_insert (struct grub_env_context *context, + struct grub_env_var *var) +{ + int idx = grub_env_hashval (var->name); + + /* Insert the variable into the hashtable. */ + var->prevp = &context->vars[idx]; + var->next = context->vars[idx]; + if (var->next) + var->next->prevp = &(var->next); + context->vars[idx] = var; +} + +static void +grub_env_remove (struct grub_env_var *var) +{ + /* Remove the entry from the variable table. */ + *var->prevp = var->next; + if (var->next) + var->next->prevp = var->prevp; +} + +grub_err_t +grub_env_set (const char *name, const char *val) +{ + struct grub_env_var *var; + + /* If the variable does already exist, just update the variable. */ + var = grub_env_find (name); + if (var) + { + char *old = var->value; + + if (var->write_hook) + var->value = var->write_hook (var, val); + else + var->value = grub_strdup (val); + + if (! var->value) + { + var->value = old; + return grub_errno; + } + + grub_free (old); + return GRUB_ERR_NONE; + } + + /* The variable does not exist, so create a new one. */ + var = grub_zalloc (sizeof (*var)); + if (! var) + return grub_errno; + + var->name = grub_strdup (name); + if (! var->name) + goto fail; + + var->value = grub_strdup (val); + if (! var->value) + goto fail; + + grub_env_insert (grub_current_context, var); + + return GRUB_ERR_NONE; + + fail: + grub_free (var->name); + grub_free (var->value); + grub_free (var); + + return grub_errno; +} + +const char * +grub_env_get (const char *name) +{ + struct grub_env_var *var; + + if (name && vtoy_menu_lang_read_hook && grub_strncmp(name, "VTLANG_", 7) == 0) + return vtoy_menu_lang_read_hook(NULL, name); + + var = grub_env_find (name); + if (! var) + return 0; + + if (var->read_hook) + return var->read_hook (var, var->value); + + return var->value; +} + +void +grub_env_unset (const char *name) +{ + struct grub_env_var *var; + + var = grub_env_find (name); + if (! var) + return; + + if (var->read_hook || var->write_hook) + { + grub_env_set (name, ""); + return; + } + + grub_env_remove (var); + + grub_free (var->name); + grub_free (var->value); + grub_free (var); +} + +struct grub_env_var * +grub_env_update_get_sorted (void) +{ + struct grub_env_var *sorted_list = 0; + int i; + + /* Add variables associated with this context into a sorted list. */ + for (i = 0; i < HASHSZ; i++) + { + struct grub_env_var *var; + + for (var = grub_current_context->vars[i]; var; var = var->next) + { + struct grub_env_var *p, **q; + + for (q = &sorted_list, p = *q; p; q = &((*q)->sorted_next), p = *q) + { + if (grub_strcmp (p->name, var->name) > 0) + break; + } + + var->sorted_next = *q; + *q = var; + } + } + + return sorted_list; +} + +grub_err_t +grub_register_variable_hook (const char *name, + grub_env_read_hook_t read_hook, + grub_env_write_hook_t write_hook) +{ + struct grub_env_var *var = grub_env_find (name); + + if (! var) + { + if (grub_env_set (name, "") != GRUB_ERR_NONE) + return grub_errno; + + var = grub_env_find (name); + /* XXX Insert an assertion? */ + } + + var->read_hook = read_hook; + var->write_hook = write_hook; + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_register_vtoy_menu_lang_hook(grub_env_read_hook_t read_hook) +{ + vtoy_menu_lang_read_hook = read_hook; + return GRUB_ERR_NONE; +} + +grub_err_t +grub_env_export (const char *name) +{ + struct grub_env_var *var; + + var = grub_env_find (name); + if (! var) + { + grub_err_t err; + + err = grub_env_set (name, ""); + if (err) + return err; + var = grub_env_find (name); + } + var->global = 1; + + return GRUB_ERR_NONE; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/file.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/file.c new file mode 100644 index 0000000..b328d21 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/file.c @@ -0,0 +1,399 @@ +/* file.c - file I/O functions */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2006,2007,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +void (*EXPORT_VAR (grub_grubnet_fini)) (void); + +grub_file_filter_t grub_file_filters[GRUB_FILE_FILTER_MAX]; + +/* Get the device part of the filename NAME. It is enclosed by parentheses. */ +char * +grub_file_get_device_name (const char *name) +{ + if (name[0] == '(') + { + char *p = grub_strchr (name, ')'); + char *ret; + + if (! p) + { + grub_error (GRUB_ERR_BAD_FILENAME, N_("missing `%c' symbol"), ')'); + return 0; + } + + ret = (char *) grub_malloc (p - name); + if (! ret) + return 0; + + grub_memcpy (ret, name + 1, p - name - 1); + ret[p - name - 1] = '\0'; + return ret; + } + + return 0; +} + +/* Support mem:xxx:size:xxx format in chainloader */ +grub_file_t grub_memfile_open(const char *name); +#define GRUB_MEMFILE_MEM "mem:" +#define GRUB_MEMFILE_SIZE "size:" + +grub_file_t grub_memfile_open(const char *name) +{ + char *size = NULL; + grub_file_t file = 0; + + file = (grub_file_t)grub_zalloc(sizeof(*file)); + if (NULL == file) + { + return 0; + } + + file->name = grub_strdup(name); + file->data = (void *)grub_strtoul(name + grub_strlen(GRUB_MEMFILE_MEM), NULL, 0); + + size = grub_strstr(name, GRUB_MEMFILE_SIZE); + file->size = (grub_off_t)grub_strtoul(size + grub_strlen(GRUB_MEMFILE_SIZE), NULL, 0); + + grub_errno = GRUB_ERR_NONE; + return file; +} + +int ventoy_check_file_exist(const char * fmt, ...) +{ + va_list ap; + grub_file_t file; + char fullpath[256] = {0}; + + va_start (ap, fmt); + grub_vsnprintf(fullpath, 255, fmt, ap); + va_end (ap); + + file = grub_file_open(fullpath, GRUB_FILE_TYPE_NONE); + if (!file) + { + grub_errno = 0; + return 0; + } + else + { + grub_file_close(file); + return 1; + } +} + +typedef struct grub_vlnk +{ + int srclen; + char src[512]; + char dst[512]; + struct grub_vlnk *next; +}grub_vlnk; + +static grub_vlnk g_vtoy_vlnk; +static grub_vlnk *g_vlnk_list; + +int grub_file_is_vlnk_suffix(const char *name, int len) +{ + grub_uint32_t suffix; + + if (len > 9) + { + suffix = *(grub_uint32_t *)(name + len - 4); + if (grub_strncmp(name + len - 9, ".vlnk.", 6) == 0) + { + /* .iso .wim .img .vhd .efi .dat */ + if (suffix == 0x6F73692E || suffix == 0x6D69772E || + suffix == 0x676D692E || suffix == 0x6468762E || + suffix == 0x6966652E || suffix == 0x7461642E) + { + return 1; + } + } + else if (len > 10 && grub_strncmp(name + len - 10, ".vlnk.", 6) == 0) + { + /* vhdx vtoy */ + if (suffix == 0x78646876 || suffix == 0x796F7476) + { + return 1; + } + } + } + + return 0; +} + +int grub_file_vtoy_vlnk(const char *src, const char *dst) +{ + if (src) + { + g_vtoy_vlnk.srclen = (int)grub_strlen(src); + grub_strncpy(g_vtoy_vlnk.src, src, sizeof(g_vtoy_vlnk.src) - 1); + grub_strncpy(g_vtoy_vlnk.dst, dst, sizeof(g_vtoy_vlnk.dst) - 1); + } + else + { + g_vtoy_vlnk.srclen = 0; + g_vtoy_vlnk.src[0] = 0; + g_vtoy_vlnk.dst[0] = 0; + } + return 0; +} + +int grub_file_add_vlnk(const char *src, const char *dst) +{ + grub_vlnk *node = NULL; + + if (src && dst) + { + node = grub_zalloc(sizeof(grub_vlnk)); + if (node) + { + node->srclen = (int)grub_strlen(src); + grub_strncpy(node->src, src, sizeof(node->src) - 1); + grub_strncpy(node->dst, dst, sizeof(node->dst) - 1); + + node->next = g_vlnk_list; + g_vlnk_list = node; + return 0; + } + } + + return 1; +} + +const char *grub_file_get_vlnk(const char *name, int *vlnk) +{ + int len; + grub_vlnk *node = g_vlnk_list; + + len = grub_strlen(name); + + if (!grub_file_is_vlnk_suffix(name, len)) + { + return name; + } + + if (len == g_vtoy_vlnk.srclen && grub_strcmp(name, g_vtoy_vlnk.src) == 0) + { + if (vlnk) + *vlnk = 1; + return g_vtoy_vlnk.dst; + } + + while (node) + { + if (node->srclen == len && grub_strcmp(name, node->src) == 0) + { + if (vlnk) + *vlnk = 1; + return node->dst; + } + node = node->next; + } + + return name; +} + +grub_file_t +grub_file_open (const char *name, enum grub_file_type type) +{ + int vlnk = 0; + grub_device_t device = 0; + grub_file_t file = 0, last_file = 0; + char *device_name; + const char *file_name; + grub_file_filter_id_t filter; + + /* : mem:xxx:size:xxx format in chainloader grub_strlen(GRUB_MEMFILE_MEM) */ + if (grub_strncmp(name, GRUB_MEMFILE_MEM, 4) == 0) { + return grub_memfile_open(name); + } + + if ((g_vlnk_list || g_vtoy_vlnk.srclen) && (type & GRUB_FILE_TYPE_NO_VLNK) == 0) + name = grub_file_get_vlnk(name, &vlnk); + + device_name = grub_file_get_device_name (name); + if (grub_errno) + goto fail; + + /* Get the file part of NAME. */ + file_name = (name[0] == '(') ? grub_strchr (name, ')') : NULL; + if (file_name) + file_name++; + else + file_name = name; + + device = grub_device_open (device_name); + grub_free (device_name); + if (! device) + goto fail; + + file = (grub_file_t) grub_zalloc (sizeof (*file)); + if (! file) + goto fail; + + file->device = device; + file->vlnk = vlnk; + + /* In case of relative pathnames and non-Unix systems (like Windows) + * name of host files may not start with `/'. Blocklists for host files + * are meaningless as well (for a start, host disk does not allow any direct + * access - it is just a marker). So skip host disk in this case. + */ + if (device->disk && file_name[0] != '/' +#if defined(GRUB_UTIL) || defined(GRUB_MACHINE_EMU) + && grub_strcmp (device->disk->name, "host") +#endif + ) + /* This is a block list. */ + file->fs = &grub_fs_blocklist; + else + { + file->fs = grub_fs_probe (device); + if (! file->fs) + goto fail; + } + + if ((file->fs->fs_open) (file, file_name) != GRUB_ERR_NONE) + goto fail; + + file->name = grub_strdup (name); + grub_errno = GRUB_ERR_NONE; + + for (filter = 0; file && filter < ARRAY_SIZE (grub_file_filters); + filter++) + if (grub_file_filters[filter]) + { + last_file = file; + file = grub_file_filters[filter] (file, type); + if (file && file != last_file) + { + file->name = grub_strdup (name); + grub_errno = GRUB_ERR_NONE; + } + } + if (!file) + grub_file_close (last_file); + + return file; + + fail: + if (device) + grub_device_close (device); + + /* if (net) grub_net_close (net); */ + + grub_free (file); + + return 0; +} + +grub_disk_read_hook_t grub_file_progress_hook; + +grub_ssize_t +grub_file_read (grub_file_t file, void *buf, grub_size_t len) +{ + grub_ssize_t res; + grub_disk_read_hook_t read_hook; + void *read_hook_data; + + if (file->offset > file->size) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, + N_("attempt to read past the end of file")); + return -1; + } + + if (len == 0) + return 0; + + if (len > file->size - file->offset) + len = file->size - file->offset; + + /* Prevent an overflow. */ + if ((grub_ssize_t) len < 0) + len >>= 1; + + if (len == 0) + return 0; + + if (file->name) { + if (grub_strncmp(file->name, GRUB_MEMFILE_MEM, grub_strlen(GRUB_MEMFILE_MEM)) == 0) { + grub_memcpy(buf, (grub_uint8_t *)(file->data) + file->offset, len); + file->offset += len; + return len; + } + } + + read_hook = file->read_hook; + read_hook_data = file->read_hook_data; + if (!file->read_hook) + { + file->read_hook = grub_file_progress_hook; + file->read_hook_data = file; + file->progress_offset = file->offset; + } + res = (file->fs->fs_read) (file, buf, len); + file->read_hook = read_hook; + file->read_hook_data = read_hook_data; + if (res > 0) + file->offset += res; + + return res; +} + +grub_err_t +grub_file_close (grub_file_t file) +{ + if (file->fs && file->fs->fs_close) + (file->fs->fs_close) (file); + + if (file->device) + grub_device_close (file->device); + grub_free (file->name); + grub_free (file); + return grub_errno; +} + +grub_off_t +grub_file_seek (grub_file_t file, grub_off_t offset) +{ + grub_off_t old; + + if (offset > file->size) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, + N_("attempt to seek outside of the file")); + return -1; + } + + old = file->offset; + file->offset = offset; + + return old; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/fs.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/fs.c new file mode 100644 index 0000000..2736259 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/fs.c @@ -0,0 +1,342 @@ +/* fs.c - filesystem manager */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2005,2007 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +grub_fs_t grub_fs_list = 0; + +grub_fs_autoload_hook_t grub_fs_autoload_hook = 0; + +/* Helper for grub_fs_probe. */ +static int +probe_dummy_iter (const char *filename __attribute__ ((unused)), + const struct grub_dirhook_info *info __attribute__ ((unused)), + void *data __attribute__ ((unused))) +{ + return 1; +} + +grub_fs_t grub_fs_list_probe(grub_device_t device, const char **list) +{ + int i; + grub_fs_t p; + + if (!device->disk) + return 0; + + for (p = grub_fs_list; p; p = p->next) + { + for (i = 0; list[i]; i++) + { + if (grub_strcmp(p->name, list[i]) == 0) + break; + } + + if (list[i] == NULL) + continue; + + grub_dprintf("fs", "Detecting %s...\n", p->name); + + (p->fs_dir) (device, "/", probe_dummy_iter, NULL); + if (grub_errno == GRUB_ERR_NONE) + return p; + + grub_error_push (); + grub_dprintf ("fs", "%s detection failed.\n", p->name); + grub_error_pop (); + + if (grub_errno != GRUB_ERR_BAD_FS && grub_errno != GRUB_ERR_OUT_OF_RANGE) { + return 0; + } + grub_errno = GRUB_ERR_NONE; + } + + return 0; +} + +grub_fs_t +grub_fs_probe (grub_device_t device) +{ + grub_fs_t p; + const char *first_probe; + grub_size_t len; + + if (device->disk) + { + /* Make it sure not to have an infinite recursive calls. */ + static int count = 0; + + first_probe = grub_env_get("ventoy_fs_probe"); + if (!first_probe) + { + first_probe = "iso9660"; + } + len = grub_strlen(first_probe); + + /* use iso9660 first */ + for (p = grub_fs_list; p; p = p->next) + { + if (grub_strncmp(p->name, first_probe, len) == 0) + { + break; + } + } + + if (p) + { + grub_dprintf ("fs", "Detecting %s...\n", p->name); + + /* This is evil: newly-created just mounted BtrFS after copying all + GRUB files has a very peculiar unrecoverable corruption which + will be fixed at sync but we'd rather not do a global sync and + syncing just files doesn't seem to help. Relax the check for + this time. */ +#ifdef GRUB_UTIL + if (grub_strcmp (p->name, "btrfs") == 0) + { + char *label = 0; + p->fs_uuid (device, &label); + if (label) + grub_free (label); + } + else +#endif + (p->fs_dir) (device, "/", probe_dummy_iter, NULL); + if (grub_errno == GRUB_ERR_NONE) + return p; + + grub_error_push (); + grub_dprintf ("fs", "%s detection failed.\n", p->name); + grub_error_pop (); + + if (grub_errno != GRUB_ERR_BAD_FS + && grub_errno != GRUB_ERR_OUT_OF_RANGE) + return 0; + + grub_errno = GRUB_ERR_NONE; + } + + for (p = grub_fs_list; p; p = p->next) + { + grub_dprintf ("fs", "Detecting %s...\n", p->name); + + /* This is evil: newly-created just mounted BtrFS after copying all + GRUB files has a very peculiar unrecoverable corruption which + will be fixed at sync but we'd rather not do a global sync and + syncing just files doesn't seem to help. Relax the check for + this time. */ +#ifdef GRUB_UTIL + if (grub_strcmp (p->name, "btrfs") == 0) + { + char *label = 0; + p->fs_uuid (device, &label); + if (label) + grub_free (label); + } + else +#endif + (p->fs_dir) (device, "/", probe_dummy_iter, NULL); + if (grub_errno == GRUB_ERR_NONE) + return p; + + grub_error_push (); + grub_dprintf ("fs", "%s detection failed.\n", p->name); + grub_error_pop (); + + if (grub_errno != GRUB_ERR_BAD_FS + && grub_errno != GRUB_ERR_OUT_OF_RANGE) + return 0; + + grub_errno = GRUB_ERR_NONE; + } + + /* Let's load modules automatically. */ + if (grub_fs_autoload_hook && count == 0) + { + count++; + + while (grub_fs_autoload_hook ()) + { + p = grub_fs_list; + + (p->fs_dir) (device, "/", probe_dummy_iter, NULL); + if (grub_errno == GRUB_ERR_NONE) + { + count--; + return p; + } + + if (grub_errno != GRUB_ERR_BAD_FS + && grub_errno != GRUB_ERR_OUT_OF_RANGE) + { + count--; + return 0; + } + + grub_errno = GRUB_ERR_NONE; + } + + count--; + } + } + else if (device->net && device->net->fs) + return device->net->fs; + + grub_error (GRUB_ERR_UNKNOWN_FS, N_("unknown filesystem")); + return 0; +} + + + +/* Block list support routines. */ + +struct grub_fs_block +{ + grub_disk_addr_t offset; + unsigned long length; +}; + +static grub_err_t +grub_fs_blocklist_open (grub_file_t file, const char *name) +{ + char *p = (char *) name; + unsigned num = 0; + unsigned i; + grub_disk_t disk = file->device->disk; + struct grub_fs_block *blocks; + + /* First, count the number of blocks. */ + do + { + num++; + p = grub_strchr (p, ','); + if (p) + p++; + } + while (p); + + /* Allocate a block list. */ + blocks = grub_zalloc (sizeof (struct grub_fs_block) * (num + 1)); + if (! blocks) + return 0; + + file->size = 0; + p = (char *) name; + for (i = 0; i < num; i++) + { + if (*p != '+') + { + blocks[i].offset = grub_strtoull (p, &p, 0); + if (grub_errno != GRUB_ERR_NONE || *p != '+') + { + grub_error (GRUB_ERR_BAD_FILENAME, + N_("invalid file name `%s'"), name); + goto fail; + } + } + + p++; + blocks[i].length = grub_strtoul (p, &p, 0); + if (grub_errno != GRUB_ERR_NONE + || blocks[i].length == 0 + || (*p && *p != ',' && ! grub_isspace (*p))) + { + grub_error (GRUB_ERR_BAD_FILENAME, + N_("invalid file name `%s'"), name); + goto fail; + } + + if (disk->total_sectors < blocks[i].offset + blocks[i].length) + { + grub_error (GRUB_ERR_BAD_FILENAME, "beyond the total sectors"); + goto fail; + } + + file->size += (blocks[i].length << GRUB_DISK_SECTOR_BITS); + p++; + } + + file->data = blocks; + + return GRUB_ERR_NONE; + + fail: + grub_free (blocks); + return grub_errno; +} + +static grub_ssize_t +grub_fs_blocklist_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_fs_block *p; + grub_disk_addr_t sector; + grub_off_t offset; + grub_ssize_t ret = 0; + + if (len > file->size - file->offset) + len = file->size - file->offset; + + sector = (file->offset >> GRUB_DISK_SECTOR_BITS); + offset = (file->offset & (GRUB_DISK_SECTOR_SIZE - 1)); + for (p = file->data; p->length && len > 0; p++) + { + if (sector < p->length) + { + grub_size_t size; + + size = len; + if (((size + offset + GRUB_DISK_SECTOR_SIZE - 1) + >> GRUB_DISK_SECTOR_BITS) > p->length - sector) + size = ((p->length - sector) << GRUB_DISK_SECTOR_BITS) - offset; + + if (grub_disk_read (file->device->disk, p->offset + sector, offset, + size, buf) != GRUB_ERR_NONE) + return -1; + + ret += size; + len -= size; + sector -= ((size + offset) >> GRUB_DISK_SECTOR_BITS); + offset = ((size + offset) & (GRUB_DISK_SECTOR_SIZE - 1)); + } + else + sector -= p->length; + } + + return ret; +} + +struct grub_fs grub_fs_blocklist = + { + .name = "blocklist", + .fs_dir = 0, + .fs_open = grub_fs_blocklist_open, + .fs_read = grub_fs_blocklist_read, + .fs_close = 0, + .next = 0 + }; diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/main.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/main.c new file mode 100644 index 0000000..42bc22f --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/main.c @@ -0,0 +1,403 @@ +/* main.c - the kernel main routine */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2005,2006,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef GRUB_MACHINE_PCBIOS +#include +#endif + +grub_addr_t +grub_modules_get_end (void) +{ + struct grub_module_info *modinfo; + + modinfo = (struct grub_module_info *) grub_modbase; + + /* Check if there are any modules. */ + if ((modinfo == 0) || modinfo->magic != GRUB_MODULE_MAGIC) + return grub_modbase; + + return grub_modbase + modinfo->size; +} + +/* Load all modules in core. */ +static void +grub_load_modules (void) +{ + struct grub_module_header *header; + FOR_MODULES (header) + { + /* Not an ELF module, skip. */ + if (header->type != OBJ_TYPE_ELF) + continue; + + if (! grub_dl_load_core ((char *) header + sizeof (struct grub_module_header), + (header->size - sizeof (struct grub_module_header)))) + grub_fatal ("%s", grub_errmsg); + + if (grub_errno) + grub_print_error (); + } +} + +static char *load_config; + +static void +grub_load_config (void) +{ + struct grub_module_header *header; + FOR_MODULES (header) + { + /* Not an embedded config, skip. */ + if (header->type != OBJ_TYPE_CONFIG) + continue; + + load_config = grub_malloc (header->size - sizeof (struct grub_module_header) + 1); + if (!load_config) + { + grub_print_error (); + break; + } + grub_memcpy (load_config, (char *) header + + sizeof (struct grub_module_header), + header->size - sizeof (struct grub_module_header)); + load_config[header->size - sizeof (struct grub_module_header)] = 0; + break; + } +} + +/* Write hook for the environment variables of root. Remove surrounding + parentheses, if any. */ +static char * +grub_env_write_root (struct grub_env_var *var __attribute__ ((unused)), + const char *val) +{ + /* XXX Is it better to check the existence of the device? */ + grub_size_t len = grub_strlen (val); + + if (val[0] == '(' && val[len - 1] == ')') + return grub_strndup (val + 1, len - 2); + + return grub_strdup (val); +} + +static int g_ventoy_hook_root = 0; +void ventoy_env_hook_root(int hook) +{ + g_ventoy_hook_root = hook; +} + +static char * +ventoy_env_write_root (struct grub_env_var *var __attribute__ ((unused)), + const char *val) +{ + const char *pos = val; + char buf[256]; + + if (g_ventoy_hook_root == 0) + { + return grub_env_write_root(var, val); + } + + if (pos[0] == '(') + { + pos++; + } + + if (grub_strncmp(pos, "vtimghd", 7) == 0) + { + return grub_env_write_root(var, val); + } + + pos = grub_strchr(val, ','); + if (!pos) + { + return grub_env_write_root(var, val); + } + + if (val[0] == '(') + { + grub_snprintf(buf, sizeof(buf), "(vtimghd%s", pos); + } + else + { + grub_snprintf(buf, sizeof(buf), "vtimghd%s", pos); + } + + return grub_env_write_root(var, buf); +} + +static void +grub_set_prefix_and_root (void) +{ + char *device = NULL; + char *path = NULL; + char *fwdevice = NULL; + char *fwpath = NULL; + char *prefix = NULL; + struct grub_module_header *header; + + FOR_MODULES (header) + if (header->type == OBJ_TYPE_PREFIX) + prefix = (char *) header + sizeof (struct grub_module_header); + + grub_register_variable_hook ("root", 0, ventoy_env_write_root); + + grub_machine_get_bootlocation (&fwdevice, &fwpath); + + if (fwdevice) + { + char *cmdpath; + + cmdpath = grub_xasprintf ("(%s)%s", fwdevice, fwpath ? : ""); + if (cmdpath) + { + grub_env_set ("cmdpath", cmdpath); + grub_env_export ("cmdpath"); + grub_free (cmdpath); + } + } + + if (prefix) + { + char *pptr = NULL; + if (prefix[0] == '(') + { + pptr = grub_strrchr (prefix, ')'); + if (pptr) + { + device = grub_strndup (prefix + 1, pptr - prefix - 1); + pptr++; + } + } + if (!pptr) + pptr = prefix; + if (pptr[0]) + path = grub_strdup (pptr); + } + + if (!device && fwdevice) + device = fwdevice; + else if (fwdevice && (device[0] == ',' || !device[0])) + { + /* We have a partition, but still need to fill in the drive. */ + char *comma, *new_device; + + for (comma = fwdevice; *comma; ) + { + if (comma[0] == '\\' && comma[1] == ',') + { + comma += 2; + continue; + } + if (*comma == ',') + break; + comma++; + } + if (*comma) + { + char *drive = grub_strndup (fwdevice, comma - fwdevice); + new_device = grub_xasprintf ("%s%s", drive, device); + grub_free (drive); + } + else + new_device = grub_xasprintf ("%s%s", fwdevice, device); + + grub_free (fwdevice); + grub_free (device); + device = new_device; + } + else + grub_free (fwdevice); + if (fwpath && !path) + { + grub_size_t len = grub_strlen (fwpath); + while (len > 1 && fwpath[len - 1] == '/') + fwpath[--len] = 0; + if (len >= sizeof (GRUB_TARGET_CPU "-" GRUB_PLATFORM) - 1 + && grub_memcmp (fwpath + len - (sizeof (GRUB_TARGET_CPU "-" GRUB_PLATFORM) - 1), GRUB_TARGET_CPU "-" GRUB_PLATFORM, + sizeof (GRUB_TARGET_CPU "-" GRUB_PLATFORM) - 1) == 0) + fwpath[len - (sizeof (GRUB_TARGET_CPU "-" GRUB_PLATFORM) - 1)] = 0; + path = fwpath; + } + else + grub_free (fwpath); + if (device) + { + char *prefix_set; + + prefix_set = grub_xasprintf ("(%s)%s", device, path ? : ""); + if (prefix_set) + { + grub_env_set ("prefix", prefix_set); + grub_free (prefix_set); + } + grub_env_set ("root", device); + } + + grub_free (device); + grub_free (path); + grub_print_error (); +} + +/* Load the normal mode module and execute the normal mode if possible. */ +static void +grub_load_normal_mode (void) +{ + /* Load the module. */ + grub_dl_load ("normal"); + + /* Print errors if any. */ + grub_print_error (); + grub_errno = 0; + + grub_command_execute ("normal", 0, 0); +} + +static void +reclaim_module_space (void) +{ + grub_addr_t modstart, modend; + + if (!grub_modbase) + return; + +#ifdef GRUB_MACHINE_PCBIOS + modstart = GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR; +#else + modstart = grub_modbase; +#endif + modend = grub_modules_get_end (); + grub_modbase = 0; + +#if GRUB_KERNEL_PRELOAD_SPACE_REUSABLE + grub_mm_init_region ((void *) modstart, modend - modstart); +#else + (void) modstart; + (void) modend; +#endif +} + +#ifndef GRUB_MACHINE_EFI +static int ventoy_legacy_limit_workaround(void) +{ + grub_file_t file; + char *pos, *root; + char buf[128]; + + root = grub_strdup(grub_env_get("root")); + if (!root) + { + return 1; + } + + pos = grub_strchr(root, ','); + if (pos) *pos = 0; + + grub_snprintf(buf, sizeof(buf), "(%s,1)/ventoy/ventoy.disk.img.xz", root); + file = grub_file_open(buf, GRUB_FILE_TYPE_NONE); + if (file) + { + pos = grub_malloc(file->size); + if (pos) + { + grub_file_read(file, pos, file->size); + grub_snprintf(buf, sizeof(buf), "loopback ventoydisk mem:0x%lx:size:%lu", + (unsigned long)pos, (unsigned long)file->size); + + grub_parser_execute(buf); + grub_env_set("prefix", "(ventoydisk)/grub"); + } + + grub_file_close(file); + } + + grub_free(root); + return 0; +} +#endif + +/* The main routine. */ +void __attribute__ ((noreturn)) +grub_main (void) +{ + /* First of all, initialize the machine. */ + grub_machine_init (); + + grub_boot_time ("After machine init."); + + /* Hello. */ + grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); + //grub_printf ("Welcome to GRUB!\n\n"); + grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); + + grub_load_config (); + + grub_boot_time ("Before loading embedded modules."); + + /* Load pre-loaded modules and free the space. */ + grub_register_exported_symbols (); +#ifdef GRUB_LINKER_HAVE_INIT + grub_arch_dl_init_linker (); +#endif + grub_load_modules (); + + grub_boot_time ("After loading embedded modules."); + + /* It is better to set the root device as soon as possible, + for convenience. */ + grub_set_prefix_and_root (); + grub_env_export ("root"); + grub_env_export ("prefix"); + +#ifndef GRUB_MACHINE_EFI + if (0 == ventoy_check_file_exist("%s/grub.cfg", grub_env_get("prefix"))) { + ventoy_legacy_limit_workaround(); + } +#endif + + /* Reclaim space used for modules. */ + reclaim_module_space (); + + grub_boot_time ("After reclaiming module space."); + + grub_register_core_commands (); + + grub_boot_time ("Before execution of embedded config."); + + if (load_config) + grub_parser_execute (load_config); + + grub_boot_time ("After execution of embedded config. Attempt to go to normal mode"); + + grub_load_normal_mode (); + grub_rescue_run (); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/cache.S b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/cache.S new file mode 100644 index 0000000..c1fb4d4 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/cache.S @@ -0,0 +1,23 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009,2017 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include + +FUNCTION (grub_arch_sync_caches) + jr.hb $ra + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/dl.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/dl.c new file mode 100644 index 0000000..7c6a083 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/dl.c @@ -0,0 +1,150 @@ +/* dl-mips64.c - arch-dependent part of loadable module support */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2005,2007,2009,2017 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +/* Check if EHDR is a valid ELF header. */ +grub_err_t +grub_arch_dl_check_header (void *ehdr) +{ + Elf_Ehdr *e = ehdr; + + /* Check the magic numbers. */ +#ifdef GRUB_CPU_WORDS_BIGENDIAN + if (e->e_ident[EI_CLASS] != ELFCLASS64 + || e->e_ident[EI_DATA] != ELFDATA2MSB + || e->e_machine != EM_MIPS) +#else + if (e->e_ident[EI_CLASS] != ELFCLASS64 + || e->e_ident[EI_DATA] != ELFDATA2LSB + || e->e_machine != EM_MIPS) +#endif + return grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-dependent ELF magic")); + + return GRUB_ERR_NONE; +} + +#pragma GCC diagnostic ignored "-Wcast-align" + +grub_err_t +grub_arch_dl_get_tramp_got_size (const void *ehdr __attribute__ ((unused)), + grub_size_t *tramp, grub_size_t *got) +{ + *tramp = 0; + *got = 0; + return GRUB_ERR_NONE; +} + +/* Relocate symbols. */ +grub_err_t +grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, + Elf_Shdr *s, grub_dl_segment_t seg) +{ + Elf_Ehdr *e = ehdr; + Elf_Rel *rel, *max; + + for (rel = (Elf_Rel *) ((char *) e + s->sh_offset), + max = (Elf_Rel *) ((char *) rel + s->sh_size); + rel < max; + rel = (Elf_Rel *) ((char *) rel + s->sh_entsize)) + { + grub_uint8_t *addr; + Elf_Sym *sym; + Elf_Addr r_info; + grub_uint64_t sym_value; + + if (seg->size < rel->r_offset) + return grub_error (GRUB_ERR_BAD_MODULE, + "reloc offset is out of the segment"); + + r_info = ((grub_uint64_t) rel->r_info << 32) | + (grub_uint32_t) grub_be_to_cpu64 (rel->r_info); + + addr = (grub_uint8_t *) ((char *) seg->addr + rel->r_offset); + sym = (Elf_Sym *) ((char *) mod->symtab + + mod->symsize * ELF_R_SYM (r_info)); + sym_value = sym->st_value; + if (s->sh_type == SHT_RELA) + { + sym_value += ((Elf_Rela *) rel)->r_addend; + } + switch (ELF_R_TYPE (r_info)) + { + case R_MIPS_64: + *(grub_uint64_t *) addr += sym_value; + break; + case R_MIPS_32: + *(grub_uint32_t *) addr += sym_value; + break; + case R_MIPS_26: + { + grub_uint32_t value; + grub_uint32_t raw; + raw = (*(grub_uint32_t *) addr) & 0x3ffffff; + value = raw << 2; + value += sym_value; + raw = (value >> 2) & 0x3ffffff; + + *(grub_uint32_t *) addr = + raw | ((*(grub_uint32_t *) addr) & 0xfc000000); + } + break; + case R_MIPS_LO16: +#ifdef GRUB_CPU_WORDS_BIGENDIAN + addr += 2; +#endif + *(grub_uint16_t *) addr = (grub_int16_t) sym_value; + break; + case R_MIPS_HI16: +#ifdef GRUB_CPU_WORDS_BIGENDIAN + addr += 2; +#endif + *(grub_uint16_t *) addr = (grub_int16_t) ((sym_value + 0x8000UL) >> 16); + break; + case R_MIPS_HIGHER: +#ifdef GRUB_CPU_WORDS_BIGENDIAN + addr += 2; +#endif + *(grub_uint16_t *) addr = (grub_int16_t) ((sym_value + 0x80008000UL) >> 32); + break; + case R_MIPS_HIGHEST: +#ifdef GRUB_CPU_WORDS_BIGENDIAN + addr += 2; +#endif + *(grub_uint16_t *) addr = (grub_uint16_t) ((sym_value + 0x800080008000UL) >> 48); + break; + default: + { + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + N_("relocation 0x%x is not implemented yet"), + ELF_R_TYPE (r_info)); + } + break; + } + } + + return GRUB_ERR_NONE; +} + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/efi/init.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/efi/init.c new file mode 100644 index 0000000..f9f846e --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/efi/init.c @@ -0,0 +1,85 @@ +/* init.c - initialize an arm-based EFI system */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static grub_uint64_t tmr; +static grub_efi_event_t tmr_evt; + +static grub_uint64_t +grub_efi_get_time_ms (void) +{ + return tmr; +} + +static void +grub_loongson_increment_timer (grub_efi_event_t event __attribute__ ((unused)), + void *context __attribute__ ((unused))) +{ + tmr += 10; +} + + + +void +grub_machine_init (void) +{ + grub_efi_boot_services_t *b; + + grub_efi_init (); + + b = grub_efi_system_table->boot_services; + efi_call_5 (b->create_event, GRUB_EFI_EVT_TIMER | GRUB_EFI_EVT_NOTIFY_SIGNAL, + GRUB_EFI_TPL_CALLBACK, grub_loongson_increment_timer, NULL, &tmr_evt); + efi_call_3 (b->set_timer, tmr_evt, GRUB_EFI_TIMER_PERIODIC, 100000); + + grub_install_get_time_ms (grub_efi_get_time_ms); + + if (grub_efi_is_loongson ()) + grub_efi_loongson_init (); + else + /* FIXME: Get cpuclock from EFI. */ + grub_timer_init (1000000000U); +} + +void +grub_machine_fini (int flags) +{ + grub_efi_boot_services_t *b; + + if (!(flags & GRUB_LOADER_FLAG_NORETURN)) + return; + + b = grub_efi_system_table->boot_services; + + efi_call_3 (b->set_timer, tmr_evt, GRUB_EFI_TIMER_CANCEL, 0); + efi_call_1 (b->close_event, tmr_evt); + + if (grub_efi_is_loongson ()) + grub_efi_loongson_fini (); + grub_efi_fini (); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/efi/loongson.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/efi/loongson.c new file mode 100644 index 0000000..fde01b4 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/efi/loongson.c @@ -0,0 +1,33 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2017 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include + +void +grub_efi_loongson_init (void) +{ +} + +void +grub_efi_loongson_fini (void) +{ +} + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/efi/startup.S b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/efi/startup.S new file mode 100644 index 0000000..4fee9be --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/efi/startup.S @@ -0,0 +1,47 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include + + .file "startup.S" + .text + + .set push + .align 4 + +FUNCTION(_start) + /* + * EFI_SYSTEM_TABLE and EFI_HANDLE are passed in a1/a0. + */ + daddiu $sp, -16 + sd $ra, ($sp) + + dla $a2, grub_efi_image_handle + sd $a0, ($a2) + dla $a2, grub_efi_system_table + sd $a1, ($a2) + + jal grub_main + +1: + ld $ra, ($sp) + daddiu $sp, 16 + jr $ra + + .set pop + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/init.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/init.c new file mode 100644 index 0000000..8fd0a88 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/init.c @@ -0,0 +1,47 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009,2017 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include + +grub_uint32_t grub_arch_cpuclock; + +/* FIXME: use interrupt to count high. */ +grub_uint64_t +grub_get_rtc (void) +{ + static grub_uint32_t high = 0; + static grub_uint32_t last = 0; + grub_uint32_t low; + + asm volatile ("mfc0 %0, " GRUB_CPU_MIPS_COP0_TIMER_COUNT : "=r" (low)); + if (low < last) + high++; + last = low; + + return (((grub_uint64_t) high) << 32) | low; +} + +void +grub_timer_init (grub_uint32_t cpuclock) +{ + grub_arch_cpuclock = cpuclock; + grub_install_get_time_ms (grub_rtc_get_time_ms); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/term.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/term.c new file mode 100644 index 0000000..816a405 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/term.c @@ -0,0 +1,133 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2005,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +struct grub_term_output *grub_term_outputs_disabled; +struct grub_term_input *grub_term_inputs_disabled; +struct grub_term_output *grub_term_outputs; +struct grub_term_input *grub_term_inputs; + +/* Current color state. */ +grub_uint8_t grub_term_normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR; +grub_uint8_t grub_term_highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR; + +void (*grub_term_poll_usb) (int wait_for_completion) = NULL; +void (*grub_net_poll_cards_idle) (void) = NULL; + +/* Put a Unicode character. */ +static void +grub_putcode_dumb (grub_uint32_t code, + struct grub_term_output *term) +{ + struct grub_unicode_glyph c = + { + .base = code, + .variant = 0, + .attributes = 0, + .ncomb = 0, + .estimated_width = 1 + }; + + if (code == '\t' && term->getxy) + { + int n; + + n = GRUB_TERM_TAB_WIDTH - ((term->getxy (term).x) + % GRUB_TERM_TAB_WIDTH); + while (n--) + grub_putcode_dumb (' ', term); + + return; + } + + (term->putchar) (term, &c); + if (code == '\n') + grub_putcode_dumb ('\r', term); +} + +static void +grub_xputs_dumb (const char *str) +{ + for (; *str; str++) + { + grub_term_output_t term; + grub_uint32_t code = *str; + if (code > 0x7f) + code = '?'; + + FOR_ACTIVE_TERM_OUTPUTS(term) + grub_putcode_dumb (code, term); + } +} + +void (*grub_xputs) (const char *str) = grub_xputs_dumb; + +int (*grub_key_remap)(int key) = NULL; +int +grub_getkey_noblock (void) +{ + grub_term_input_t term; + + if (grub_term_poll_usb) + grub_term_poll_usb (0); + + if (grub_net_poll_cards_idle) + grub_net_poll_cards_idle (); + + FOR_ACTIVE_TERM_INPUTS(term) + { + int key = term->getkey (term); + if (grub_key_remap) + key = grub_key_remap(key); + if (key != GRUB_TERM_NO_KEY) + return key; + } + + return GRUB_TERM_NO_KEY; +} + +int +grub_getkey (void) +{ + int ret; + + grub_refresh (); + + while (1) + { + ret = grub_getkey_noblock (); + if (ret != GRUB_TERM_NO_KEY) + return ret; + grub_cpu_idle (); + } +} + +void +grub_refresh (void) +{ + struct grub_term_output *term; + + FOR_ACTIVE_TERM_OUTPUTS(term) + grub_term_refresh (term); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/cmdline.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/cmdline.c new file mode 100644 index 0000000..cc87e16 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/cmdline.c @@ -0,0 +1,118 @@ +/* cmdline.c - linux command line handling */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include + +static unsigned int check_arg (char *c, int *has_space) +{ + int space = 0; + unsigned int size = 0; + + while (*c) + { + if (*c == '\\' || *c == '\'' || *c == '"') + size++; + else if (*c == ' ') + space = 1; + + size++; + c++; + } + + if (space) + size += 2; + + if (has_space) + *has_space = space; + + return size; +} + +unsigned int grub_loader_cmdline_size (int argc, char *argv[]) +{ + int i; + unsigned int size = 0; + + for (i = 0; i < argc; i++) + { + size += check_arg (argv[i], 0); + size++; /* Separator space or NULL. */ + } + + if (size == 0) + size = 1; + + return size; +} + +grub_err_t +grub_create_loader_cmdline (int argc, char *argv[], char *buf, + grub_size_t size, enum grub_verify_string_type type) +{ + int i, space; + unsigned int arg_size; + char *c, *orig_buf = buf; + + for (i = 0; i < argc; i++) + { + c = argv[i]; + arg_size = check_arg(argv[i], &space); + arg_size++; /* Separator space or NULL. */ + + if (size < arg_size) + break; + + size -= arg_size; + + if (space) + *buf++ = '"'; + + while (*c) + { + if (*c == '\\' && *(c+1) == 'x' && + grub_isxdigit(*(c+2)) && grub_isxdigit(*(c+3))) + { + *buf++ = *c++; + *buf++ = *c++; + *buf++ = *c++; + *buf++ = *c++; + continue; + } + else if (*c == '\\' || *c == '\'' || *c == '"') + *buf++ = '\\'; + + *buf++ = *c; + c++; + } + + if (space) + *buf++ = '"'; + + *buf++ = ' '; + } + + /* Replace last space with null. */ + if (i) + buf--; + + *buf = 0; + + return grub_verify_string (orig_buf, type); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/efi/halt.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/efi/halt.c new file mode 100644 index 0000000..7ea5182 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/efi/halt.c @@ -0,0 +1,40 @@ +/* efi.c - generic EFI support */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +void +grub_halt (void) +{ + grub_machine_fini (GRUB_LOADER_FLAG_NORETURN); +#if !defined(__ia64__) && !defined(__arm__) && !defined(__aarch64__) && !defined(__mips__) &&\ + !defined(__riscv) + grub_acpi_halt (); +#endif + efi_call_4 (grub_efi_system_table->runtime_services->reset_system, + GRUB_EFI_RESET_SHUTDOWN, GRUB_EFI_SUCCESS, 0, NULL); + + while (1); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/efi/loongson.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/efi/loongson.c new file mode 100644 index 0000000..42e2b28 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/efi/loongson.c @@ -0,0 +1,495 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2017 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#pragma GCC diagnostic ignored "-Wunused-function" + +#define loongson_params (&loongson_boot_params->boot_params.efi.smbios.lp) +#define loongson_boot_params_size ALIGN_UP (sizeof (*loongson_boot_params), 8) +#define loongson_reset_code_size (&grub_efi_loongson_reset_end - &grub_efi_loongson_reset_start) + +extern grub_uint8_t grub_efi_loongson_reset_start; +extern grub_uint8_t grub_efi_loongson_reset_end; + +static struct +{ + grub_efi_loongson_boot_params boot_params; + grub_efi_loongson_memory_map memory_map; + grub_efi_loongson_cpu_info cpu_info; + grub_efi_loongson_system_info system_info; + grub_efi_loongson_irq_src_routing_table irq_src_routing_table; + grub_efi_loongson_interface_info interface_info; + grub_efi_loongson_special_attribute special_attribute; + grub_efi_loongson_board_devices board_devices; +} GRUB_PACKED +* loongson_boot_params; + +static void +grub_efi_loongson_init_reset_system (void) +{ + grub_efi_loongson_boot_params *boot_params; + grub_uint8_t *reset_code_addr = (grub_uint8_t *) loongson_boot_params + + loongson_boot_params_size; + + boot_params = &loongson_boot_params->boot_params; + grub_efi_loongson_reset_system_addr = + (grub_uint64_t) grub_efi_system_table->runtime_services->reset_system; + grub_memcpy (reset_code_addr, &grub_efi_loongson_reset_start, loongson_reset_code_size); + grub_arch_sync_caches (reset_code_addr, loongson_reset_code_size); + + boot_params->reset_system.reset_cold = (grub_uint64_t) reset_code_addr + + ((grub_uint64_t) &grub_efi_loongson_reset_cold - + (grub_uint64_t) &grub_efi_loongson_reset_start); + boot_params->reset_system.reset_warm = (grub_uint64_t) reset_code_addr + + ((grub_uint64_t) &grub_efi_loongson_reset_warm - + (grub_uint64_t) &grub_efi_loongson_reset_start); + boot_params->reset_system.shutdown = (grub_uint64_t) reset_code_addr + + ((grub_uint64_t) &grub_efi_loongson_reset_shutdown - + (grub_uint64_t) &grub_efi_loongson_reset_start); + boot_params->reset_system.do_suspend = (grub_uint64_t) reset_code_addr + + ((grub_uint64_t) &grub_efi_loongson_reset_suspend - + (grub_uint64_t) &grub_efi_loongson_reset_start); +} + +static void +grub_efi_loongson_init_smbios (grub_efi_loongson_smbios_table *smbios_table) +{ + grub_efi_loongson_smbios_table *dst = &loongson_boot_params->boot_params.efi.smbios; + + dst->vers = smbios_table->vers; + dst->vga_bios = smbios_table->vga_bios; +} + +static void +grub_efi_loongson_init_cpu_info (grub_efi_loongson_smbios_table *smbios_table) +{ + grub_efi_loongson_cpu_info *src = (void *) smbios_table->lp.cpu_offset; + grub_efi_loongson_cpu_info *dst = &loongson_boot_params->cpu_info; + + if (!src) + return; + + grub_memcpy (dst, src, sizeof (grub_efi_loongson_cpu_info)); + loongson_params->cpu_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; +} + +static void +grub_efi_loongson_init_system_info (grub_efi_loongson_smbios_table *smbios_table) +{ + grub_efi_loongson_system_info *src = (void *) smbios_table->lp.system_offset; + grub_efi_loongson_system_info *dst = &loongson_boot_params->system_info; + + if (!src) + return; + + grub_memcpy (dst, src, sizeof (grub_efi_loongson_system_info)); + loongson_params->system_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; +} + +static void +grub_efi_loongson_init_irq_src_routing_table (grub_efi_loongson_smbios_table *smbios_table) +{ + grub_efi_loongson_irq_src_routing_table *src = (void *) smbios_table->lp.irq_offset; + grub_efi_loongson_irq_src_routing_table *dst = &loongson_boot_params->irq_src_routing_table; + + if (!src) + return; + + grub_memcpy (dst, src, sizeof (grub_efi_loongson_irq_src_routing_table)); + loongson_params->irq_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; +} + +static void +grub_efi_loongson_init_interface_info (grub_efi_loongson_smbios_table *smbios_table) +{ + grub_efi_loongson_interface_info *src = (void *) smbios_table->lp.interface_offset; + grub_efi_loongson_interface_info *dst = &loongson_boot_params->interface_info; + + if (!src) + return; + + grub_memcpy (dst, src, sizeof (grub_efi_loongson_interface_info)); + loongson_params->interface_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; +} + +static void +grub_efi_loongson_init_special_attribute (grub_efi_loongson_smbios_table *smbios_table) +{ + grub_efi_loongson_special_attribute *src = (void *) smbios_table->lp.special_offset; + grub_efi_loongson_special_attribute *dst = &loongson_boot_params->special_attribute; + + if (!src) + return; + + grub_memcpy (dst, src, sizeof (grub_efi_loongson_special_attribute)); + loongson_params->special_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; +} + +static void +grub_efi_loongson_init_board_devices (grub_efi_loongson_smbios_table *smbios_table) +{ + grub_efi_loongson_board_devices *src = (void *) smbios_table->lp.boarddev_table_offset; + grub_efi_loongson_board_devices *dst = &loongson_boot_params->board_devices; + + if (!src) + return; + + grub_memcpy (dst, src, sizeof (grub_efi_loongson_board_devices)); + loongson_params->boarddev_table_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; +} + +#define ADD_MEMORY_DESCRIPTOR(desc, size) \ + ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size))) + +static void +grub_efi_loongson_init_memory_map (grub_efi_loongson_smbios_table *smbios_table, + grub_efi_memory_descriptor_t *mmap_buf, + grub_efi_uintn_t mmap_size, + grub_efi_uintn_t desc_size) +{ + grub_efi_loongson_memory_map *src = (void *) smbios_table->lp.memory_offset; + grub_efi_loongson_memory_map *dst = &loongson_boot_params->memory_map; + grub_efi_memory_descriptor_t *mmap_end; + grub_efi_memory_descriptor_t *desc; + grub_efi_memory_descriptor_t *desc_next; + grub_efi_uint32_t mem_types_reserved[] = + { + 1, // GRUB_EFI_RESERVED_MEMORY_TYPE + 0, // GRUB_EFI_LOADER_CODE + 0, // GRUB_EFI_LOADER_DATA + 0, // GRUB_EFI_BOOT_SERVICES_CODE + 0, // GRUB_EFI_BOOT_SERVICES_DATA + 1, // GRUB_EFI_RUNTIME_SERVICES_CODE + 1, // GRUB_EFI_RUNTIME_SERVICES_DATA + 0, // GRUB_EFI_CONVENTIONAL_MEMORY + 1, // GRUB_EFI_UNUSABLE_MEMORY + 0, // GRUB_EFI_ACPI_RECLAIM_MEMORY + 0, // GRUB_EFI_ACPI_MEMORY_NVS + 1, // GRUB_EFI_MEMORY_MAPPED_IO + 1, // GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE + 1, // GRUB_EFI_PAL_CODE + 1, // GRUB_EFI_PERSISTENT_MEMORY + }; + grub_uint32_t need_sort = 1; + + if (!src) + return; + + dst->vers = src->vers; + dst->nr_map = 0; + dst->mem_freq = src->mem_freq; + loongson_params->memory_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; + + if (!mmap_buf || !mmap_size || !desc_size) + return; + + mmap_end = ADD_MEMORY_DESCRIPTOR (mmap_buf, mmap_size); + + /* drop reserved */ + for (desc = mmap_buf, + desc_next = desc; + desc < mmap_end; + desc = ADD_MEMORY_DESCRIPTOR (desc, desc_size)) + { + desc->type = mem_types_reserved[desc->type]; + if (desc->type) + continue; + + if (desc != desc_next) + *desc_next = *desc; + desc_next = ADD_MEMORY_DESCRIPTOR (desc_next, desc_size); + } + mmap_end = desc_next; + + /* sort: low->high */ + while (need_sort) + { + need_sort = 0; + + for (desc = mmap_buf, + desc_next = ADD_MEMORY_DESCRIPTOR (desc, desc_size); + (desc < mmap_end) && (desc_next < mmap_end); + desc = desc_next, + desc_next = ADD_MEMORY_DESCRIPTOR (desc, desc_size)) + { + grub_efi_memory_descriptor_t tmp; + + if (desc->physical_start <= desc_next->physical_start) + continue; + + tmp = *desc; + *desc = *desc_next; + *desc_next = tmp; + need_sort = 1; + } + } + + /* combine continuous memory map */ + for (desc = mmap_buf, + desc_next = ADD_MEMORY_DESCRIPTOR (desc, desc_size); + desc_next < mmap_end; + desc_next = ADD_MEMORY_DESCRIPTOR (desc_next, desc_size)) + { + grub_efi_physical_address_t prev_end = desc->physical_start + (desc->num_pages << 12); + + if (prev_end == desc_next->physical_start) + { + desc->num_pages += desc_next->num_pages; + continue; + } + + desc = ADD_MEMORY_DESCRIPTOR (desc, desc_size); + grub_memcpy (desc, desc_next, desc_size); + } + mmap_end = ADD_MEMORY_DESCRIPTOR (desc, desc_size); + + /* write to loongson memory map */ + for (desc = mmap_buf; + desc < mmap_end; + desc = ADD_MEMORY_DESCRIPTOR (desc, desc_size)) + { + grub_efi_physical_address_t physical_start = grub_vtop ((void *) desc->physical_start); + grub_efi_physical_address_t physical_end = physical_start + (desc->num_pages << 12); + + physical_start = ALIGN_UP (physical_start, 0x100000); + physical_end = ALIGN_DOWN (physical_end, 0x100000); + + if (physical_start >= physical_end || (physical_end - physical_start) < 0x100000) + continue; + + dst->map[dst->nr_map].node_id = (desc->physical_start >> 44) & 0xf; + dst->map[dst->nr_map].mem_type = (physical_end <= 0x10000000) ? + GRUB_EFI_LOONGSON_SYSTEM_RAM_LOW : + GRUB_EFI_LOONGSON_SYSTEM_RAM_HIGH; + dst->map[dst->nr_map].mem_start = physical_start; + dst->map[dst->nr_map].mem_size = (physical_end - physical_start) >> 20; + + grub_dprintf ("loongson", "memory map %03u: 0x%016lx 0x%016lx @ %u\n", + dst->nr_map, physical_start, physical_end - physical_start, + dst->map[dst->nr_map].node_id); + + dst->nr_map ++; + } +} + +#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12) +#define SUB_MEMORY_DESCRIPTOR(desc, size) \ + ((grub_efi_memory_descriptor_t *) ((char *) (desc) - (size))) + +void +grub_efi_loongson_alloc_boot_params (void) +{ + grub_efi_memory_descriptor_t *mmap_buf; + grub_efi_memory_descriptor_t *mmap_end; + grub_efi_memory_descriptor_t *desc; + grub_efi_uintn_t mmap_size; + grub_efi_uintn_t desc_size; + grub_efi_physical_address_t address; + grub_efi_allocate_type_t type; + grub_efi_uintn_t pages; + grub_efi_status_t status; + grub_efi_boot_services_t *b; + int mm_status; + + type = GRUB_EFI_ALLOCATE_ADDRESS; + pages = BYTES_TO_PAGES (loongson_boot_params_size + loongson_reset_code_size); + + mmap_size = (1 << 12); + mmap_buf = grub_malloc (mmap_size); + if (!mmap_buf) + grub_fatal ("out of memory!"); + + mm_status = grub_efi_get_memory_map (&mmap_size, mmap_buf, 0, &desc_size, 0); + if (mm_status == 0) + { + grub_free (mmap_buf); + mmap_size += desc_size * 32; + + mmap_buf = grub_malloc (mmap_size); + if (!mmap_buf) + grub_fatal ("out of memory!"); + + mm_status = grub_efi_get_memory_map (&mmap_size, mmap_buf, 0, &desc_size, 0); + } + + if (mm_status < 0) + grub_fatal ("cannot get memory map!"); + + mmap_end = ADD_MEMORY_DESCRIPTOR (mmap_buf, mmap_size); + + for (desc = SUB_MEMORY_DESCRIPTOR (mmap_end, desc_size); + desc >= mmap_buf; + desc = SUB_MEMORY_DESCRIPTOR (desc, desc_size)) + { + if (desc->type != GRUB_EFI_CONVENTIONAL_MEMORY) + continue; + if (desc->physical_start >= GRUB_EFI_MAX_USABLE_ADDRESS) + continue; + if (desc->num_pages < pages) + continue; + + address = desc->physical_start; + break; + } + + grub_free (mmap_buf); + + b = grub_efi_system_table->boot_services; + status = efi_call_4 (b->allocate_pages, type, GRUB_EFI_RUNTIME_SERVICES_DATA, pages, &address); + if (status != GRUB_EFI_SUCCESS) + grub_fatal ("cannot allocate Loongson boot parameters!"); + + loongson_boot_params = (void *) ((grub_addr_t) address); +} + +void +grub_efi_loongson_free_boot_params (void) +{ + grub_efi_free_pages ((grub_addr_t) loongson_boot_params, + BYTES_TO_PAGES (loongson_boot_params_size + loongson_reset_code_size)); +} + +void * +grub_efi_loongson_get_smbios_table (void) +{ + static grub_efi_loongson_smbios_table *smbios_table; + grub_efi_loongson_boot_params *old_boot_params; + struct bootparamsinterface* boot_params; + void * tmp_boot_params = NULL; + char * p = NULL; + if(smbios_table) + return smbios_table; + + tmp_boot_params = grub_efi_loongson_get_boot_params(); + if(tmp_boot_params == NULL) + { + grub_dprintf("loongson", "tmp_boot_params is NULL\n"); + return tmp_boot_params; + } + + boot_params = (struct bootparamsinterface *)tmp_boot_params; + p = (char *)&(boot_params->signature); + if(grub_strncmp(p, "BPI", 3) == 0) + { + grub_dprintf("loongson", "find new bpi\n"); + return boot_params ? boot_params : 0; + } + else + { + old_boot_params = (grub_efi_loongson_boot_params *)tmp_boot_params; + return old_boot_params ? &old_boot_params->efi.smbios : 0; + } + +} + +int +grub_efi_is_loongson (void) +{ + return grub_efi_loongson_get_smbios_table () ? 1 : 0; +} + +void * +grub_efi_loongson_get_boot_params (void) +{ + static void * boot_params = NULL; + grub_efi_configuration_table_t *tables; + grub_efi_guid_t smbios_guid = GRUB_EFI_LOONGSON_SMBIOS_TABLE_GUID; + unsigned int i; + + if (boot_params) + return boot_params; + + /* Look for Loongson SMBIOS in UEFI config tables. */ + tables = grub_efi_system_table->configuration_table; + + for (i = 0; i < grub_efi_system_table->num_table_entries; i++) + if (grub_memcmp (&tables[i].vendor_guid, &smbios_guid, sizeof (smbios_guid)) == 0) + { + boot_params= tables[i].vendor_table; + grub_dprintf ("loongson", "found registered SMBIOS @ %p\n", boot_params); + break; + } + return boot_params; +} + +grub_uint8_t +grub_efi_loongson_calculatesum8 (const grub_uint8_t *buffer, grub_efi_uintn_t length) +{ + grub_uint8_t sum; + grub_efi_uintn_t count; + + for (sum = 0, count = 0; count < length; count++) + { + sum = (grub_uint8_t) (sum + *(buffer + count)); + } + return sum; +} + +grub_uint8_t +grub_efi_loongson_grub_calculatechecksum8 (const grub_uint8_t *buffer, grub_efi_uintn_t length) +{ + grub_uint8_t checksum; + + checksum = grub_efi_loongson_calculatesum8(buffer, length); + + return (grub_uint8_t) (0x100 - checksum); +} + + +grub_uint32_t +grub_efi_loongson_memmap_sort(struct memmap array[], grub_uint32_t length, mem_map * bpmem, grub_uint32_t index, grub_uint32_t memtype) +{ + grub_uint64_t tempmemsize = 0; + grub_uint32_t j = 0; + grub_uint32_t t = 0; + + for(j = 0; j < length;) + { + tempmemsize = array[j].memsize; + for(t = j + 1; t < length; t++) + { + if(array[j].memstart + tempmemsize == array[t].memstart) + { + tempmemsize += array[t].memsize; + } + else + { + break; + } + } + bpmem->map[index].memtype = memtype; + bpmem->map[index].memstart = array[j].memstart; + bpmem->map[index].memsize = tempmemsize; + grub_dprintf("loongson", "map[%d]:type %x, start 0x%llx, end 0x%llx\n", + index, + bpmem->map[index].memtype, + (unsigned long long)bpmem->map[index].memstart, + (unsigned long long)bpmem->map[index].memstart+ bpmem->map[index].memsize + ); + j = t; + index++; + } + return index; +} + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/efi/loongson_asm.S b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/efi/loongson_asm.S new file mode 100644 index 0000000..976ebd4 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/efi/loongson_asm.S @@ -0,0 +1,61 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2017 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include + + .file "loongson.S" + .text + + .set push + .set noreorder + .align 4 + +VARIABLE (grub_efi_loongson_reset_start) + +VARIABLE (grub_efi_loongson_reset_system_addr) + .dword 0 + +reset_system: + bal 1f + move $a1, $zero +1: + ld $t9, -16($ra) + move $a2, $zero + jalr $t9 + move $a3, $zero + +FUNCTION(grub_efi_loongson_reset_cold) + b reset_system + li $a0, 0 + +FUNCTION(grub_efi_loongson_reset_warm) + b reset_system + li $a0, 1 + +FUNCTION(grub_efi_loongson_reset_shutdown) + b reset_system + li $a0, 2 + +FUNCTION(grub_efi_loongson_reset_suspend) + b reset_system + li $a0, 3 + +VARIABLE (grub_efi_loongson_reset_end) + + .set pop + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/relocator.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/relocator.c new file mode 100644 index 0000000..9712b6f --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/relocator.c @@ -0,0 +1,169 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2017 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include + +#include +#include +#include +#include + +#include +#include + +extern grub_uint8_t grub_relocator_forward_start; +extern grub_uint8_t grub_relocator_forward_end; +extern grub_uint8_t grub_relocator_backward_start; +extern grub_uint8_t grub_relocator_backward_end; + +#define REGW_SIZEOF (6 * sizeof (grub_uint32_t)) +#define JUMP_SIZEOF (2 * sizeof (grub_uint32_t)) + +#define RELOCATOR_SRC_SIZEOF(x) (&grub_relocator_##x##_end \ + - &grub_relocator_##x##_start) +#define RELOCATOR_SIZEOF(x) (RELOCATOR_SRC_SIZEOF(x) \ + + REGW_SIZEOF * 3) +grub_size_t grub_relocator_align = sizeof (grub_uint64_t); +grub_size_t grub_relocator_forward_size; +grub_size_t grub_relocator_backward_size; +grub_size_t grub_relocator_jumper_size = JUMP_SIZEOF + REGW_SIZEOF; + +void +grub_cpu_relocator_init (void) +{ + grub_relocator_forward_size = RELOCATOR_SIZEOF(forward); + grub_relocator_backward_size = RELOCATOR_SIZEOF(backward); +} + +static void +write_reg (int regn, grub_uint64_t val, void **target) +{ + grub_uint32_t lui; + grub_uint32_t ori; + grub_uint32_t dsll; + + /* lui $r, 0 */ + lui = (0x3c00 | regn) << 16; + /* ori $r, $r, 0 */ + ori = (0x3400 | (regn << 5) | regn) << 16; + /* dsll $r, $r, 16 */ + dsll = (regn << 16) | (regn << 11) | (16 << 6) | 56; + + /* lui $r, val[63:48]. */ + *(grub_uint32_t *) *target = lui | (grub_uint16_t) (val >> 48); + *target = ((grub_uint32_t *) *target) + 1; + /* ori $r, val[47:32]. */ + *(grub_uint32_t *) *target = ori | (grub_uint16_t) (val >> 32); + *target = ((grub_uint32_t *) *target) + 1; + /* dsll $r, $r, 16 */ + *(grub_uint32_t *) *target = dsll; + *target = ((grub_uint32_t *) *target) + 1; + /* ori $r, val[31:16]. */ + *(grub_uint32_t *) *target = ori | (grub_uint16_t) (val >> 16); + *target = ((grub_uint32_t *) *target) + 1; + /* dsll $r, $r, 16 */ + *(grub_uint32_t *) *target = dsll; + *target = ((grub_uint32_t *) *target) + 1; + /* ori $r, val[15:0]. */ + *(grub_uint32_t *) *target = ori | (grub_uint16_t) val; + *target = ((grub_uint32_t *) *target) + 1; +} + +static void +write_jump (int regn, void **target) +{ + /* j $r. */ + *(grub_uint32_t *) *target = (regn << 21) | 0x8; + *target = ((grub_uint32_t *) *target) + 1; + /* nop. */ + *(grub_uint32_t *) *target = 0; + *target = ((grub_uint32_t *) *target) + 1; +} + +void +grub_cpu_relocator_jumper (void *rels, grub_addr_t addr) +{ + write_reg (1, addr, &rels); + write_jump (1, &rels); +} + +void +grub_cpu_relocator_backward (void *ptr0, void *src, void *dest, + grub_size_t size) +{ + void *ptr = ptr0; + write_reg (8, (grub_uint64_t) src, &ptr); + write_reg (9, (grub_uint64_t) dest, &ptr); + write_reg (10, (grub_uint64_t) size, &ptr); + grub_memcpy (ptr, &grub_relocator_backward_start, + RELOCATOR_SRC_SIZEOF (backward)); +} + +void +grub_cpu_relocator_forward (void *ptr0, void *src, void *dest, + grub_size_t size) +{ + void *ptr = ptr0; + write_reg (8, (grub_uint64_t) src, &ptr); + write_reg (9, (grub_uint64_t) dest, &ptr); + write_reg (10, (grub_uint64_t) size, &ptr); + grub_memcpy (ptr, &grub_relocator_forward_start, + RELOCATOR_SRC_SIZEOF (forward)); +} + +grub_err_t +grub_relocator64_boot (struct grub_relocator *rel, + struct grub_relocator64_state state) +{ + grub_relocator_chunk_t ch; + void *ptr; + grub_err_t err; + void *relst; + grub_size_t relsize; + grub_size_t stateset_size = 31 * REGW_SIZEOF + JUMP_SIZEOF; + unsigned i; + grub_addr_t vtarget; + + err = grub_relocator_alloc_chunk_align (rel, &ch, 0, + (0xffffffff - stateset_size) + + 1, stateset_size, + grub_relocator_align, + GRUB_RELOCATOR_PREFERENCE_NONE, 0); + if (err) + return err; + + ptr = get_virtual_current_address (ch); + for (i = 1; i < 32; i++) + write_reg (i, state.gpr[i], &ptr); + write_jump (state.jumpreg, &ptr); + + vtarget = (grub_addr_t) grub_map_memory (get_physical_target_address (ch), + stateset_size); + + err = grub_relocator_prepare_relocs (rel, vtarget, &relst, &relsize); + if (err) + return err; + + grub_arch_sync_caches ((void *) relst, relsize); + + ((void (*) (void)) relst) (); + + /* Not reached. */ + return GRUB_ERR_NONE; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/relocator_asm.S b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/relocator_asm.S new file mode 100644 index 0000000..ae37be3 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/relocator_asm.S @@ -0,0 +1,56 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2017 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include + + .p2align 4 /* force 16-byte alignment */ + + .set push + .set noreorder + .set nomacro + +VARIABLE (grub_relocator_forward_start) + +copycont1: + ld $11,0($8) + sd $11,0($9) + daddiu $8, $8, 8 + daddiu $10, $10, -8 + bne $10, $0, copycont1 + daddiu $9, $9, 8 + +VARIABLE (grub_relocator_forward_end) + +VARIABLE (grub_relocator_backward_start) + + daddu $9, $9, $10 + daddu $8, $8, $10 + /* Backward movsl is implicitly off-by-one. compensate that. */ + daddiu $9, $9, -8 + daddiu $8, $8, -8 +copycont2: + ld $11,0($8) + sd $11,0($9) + daddiu $8, $8, -8 + daddiu $10, $10, -8 + bne $10, $0, copycont2 + daddiu $9, $9, -8 + +VARIABLE (grub_relocator_backward_end) + + .set pop diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/setjmp.S b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/setjmp.S new file mode 100644 index 0000000..99ae22c --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/setjmp.S @@ -0,0 +1,69 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2007,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include + + .file "setjmp.S" + +GRUB_MOD_LICENSE "GPLv3+" + + .text + +/* + * int grub_setjmp (grub_jmp_buf env) + */ +FUNCTION(grub_setjmp) + GRUB_ASM_REG_S $s0, 0($a0) + GRUB_ASM_REG_S $s1, 8($a0) + GRUB_ASM_REG_S $s2, 16($a0) + GRUB_ASM_REG_S $s3, 24($a0) + GRUB_ASM_REG_S $s4, 32($a0) + GRUB_ASM_REG_S $s5, 40($a0) + GRUB_ASM_REG_S $s6, 48($a0) + GRUB_ASM_REG_S $s7, 56($a0) + GRUB_ASM_REG_S $s8, 64($a0) + GRUB_ASM_REG_S $gp, 72($a0) + GRUB_ASM_REG_S $sp, 80($a0) + GRUB_ASM_REG_S $ra, 88($a0) + move $v0, $zero + move $v1, $zero + jr $ra + nop +/* + * int grub_longjmp (grub_jmp_buf env, int val) + */ +FUNCTION(grub_longjmp) + GRUB_ASM_REG_L $s0, 0($a0) + GRUB_ASM_REG_L $s1, 8($a0) + GRUB_ASM_REG_L $s2, 16($a0) + GRUB_ASM_REG_L $s3, 24($a0) + GRUB_ASM_REG_L $s4, 32($a0) + GRUB_ASM_REG_L $s5, 40($a0) + GRUB_ASM_REG_L $s6, 48($a0) + GRUB_ASM_REG_L $s7, 56($a0) + GRUB_ASM_REG_L $s8, 64($a0) + GRUB_ASM_REG_L $gp, 72($a0) + GRUB_ASM_REG_L $sp, 80($a0) + GRUB_ASM_REG_L $ra, 88($a0) + addiu $v0, $zero, 1 + movn $v0, $a1, $a1 + move $v1, $zero + jr $ra + nop diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/relocator.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/relocator.c new file mode 100644 index 0000000..0ee1cb5 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/relocator.c @@ -0,0 +1,1660 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009, 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +struct grub_relocator +{ + struct grub_relocator_chunk *chunks; + grub_phys_addr_t postchunks; + grub_phys_addr_t highestaddr; + grub_phys_addr_t highestnonpostaddr; + grub_size_t relocators_size; +}; + +struct grub_relocator_subchunk +{ + enum {CHUNK_TYPE_IN_REGION, CHUNK_TYPE_REGION_START, +#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS + CHUNK_TYPE_FIRMWARE, CHUNK_TYPE_LEFTOVER +#endif + } type; + grub_mm_region_t reg; + grub_phys_addr_t start; + grub_size_t size; + grub_size_t pre_size; + struct grub_relocator_extra_block *extra; +#if GRUB_RELOCATOR_HAVE_LEFTOVERS + struct grub_relocator_fw_leftover *pre, *post; +#endif +}; + +struct grub_relocator_chunk +{ + struct grub_relocator_chunk *next; + grub_phys_addr_t src; + void *srcv; + grub_phys_addr_t target; + grub_size_t size; + struct grub_relocator_subchunk *subchunks; + unsigned nsubchunks; +}; + +struct grub_relocator_extra_block +{ + struct grub_relocator_extra_block *next; + struct grub_relocator_extra_block **prev; + grub_phys_addr_t start; + grub_phys_addr_t end; +}; + +#if GRUB_RELOCATOR_HAVE_LEFTOVERS +struct grub_relocator_fw_leftover +{ + struct grub_relocator_fw_leftover *next; + struct grub_relocator_fw_leftover **prev; + grub_phys_addr_t quantstart; + grub_uint8_t freebytes[GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT / 8]; +}; + +static struct grub_relocator_fw_leftover *leftovers; +#endif + +static struct grub_relocator_extra_block *extra_blocks; + +void * +get_virtual_current_address (grub_relocator_chunk_t in) +{ + return in->srcv; +} + +grub_phys_addr_t +get_physical_target_address (grub_relocator_chunk_t in) +{ + return in->target; +} + +struct grub_relocator * +grub_relocator_new (void) +{ + struct grub_relocator *ret; + + grub_cpu_relocator_init (); + + ret = grub_zalloc (sizeof (struct grub_relocator)); + if (!ret) + return NULL; + + ret->postchunks = ~(grub_phys_addr_t) 0; + ret->relocators_size = grub_relocator_jumper_size; + grub_dprintf ("relocator", "relocators_size=%lu\n", + (unsigned long) ret->relocators_size); + return ret; +} + +#define DIGITSORT_BITS 8 +#define DIGITSORT_MASK ((1 << DIGITSORT_BITS) - 1) +#define BITS_IN_BYTE 8 + +#define max(a, b) (((a) > (b)) ? (a) : (b)) +#define min(a, b) (((a) < (b)) ? (a) : (b)) + +static inline int +is_start (int type) +{ + return !(type & 1) && (type != COLLISION_START); +} + +static void +allocate_regstart (grub_phys_addr_t addr, grub_size_t size, grub_mm_region_t rb, + grub_mm_region_t *regancestor, grub_mm_header_t hancestor) +{ + grub_addr_t newreg_start, newreg_raw_start + = (grub_addr_t) rb + (addr - grub_vtop (rb)) + size; + grub_addr_t newreg_size, newreg_presize; + grub_mm_header_t new_header; + grub_mm_header_t hb = (grub_mm_header_t) (rb + 1); + +#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF + grub_dprintf ("relocator", "ra = %p, rb = %p\n", regancestor, rb); +#endif + newreg_start = ALIGN_UP (newreg_raw_start, GRUB_MM_ALIGN); + newreg_presize = newreg_start - newreg_raw_start; + newreg_size = rb->size - (newreg_start - (grub_addr_t) rb); + if ((hb->size << GRUB_MM_ALIGN_LOG2) >= newreg_start + - (grub_addr_t) rb) + { + grub_mm_header_t newhnext = hb->next; + grub_size_t newhsize = ((hb->size << GRUB_MM_ALIGN_LOG2) + - (newreg_start + - (grub_addr_t) rb)) >> GRUB_MM_ALIGN_LOG2; + new_header = (void *) (newreg_start + sizeof (*rb)); + if (newhnext == hb) + newhnext = new_header; + new_header->next = newhnext; + new_header->size = newhsize; + new_header->magic = GRUB_MM_FREE_MAGIC; + } + else + { + new_header = hb->next; + if (new_header == hb) + new_header = (void *) (newreg_start + sizeof (*rb)); + } + { + struct grub_mm_header *newregfirst = rb->first; + struct grub_mm_region *newregnext = rb->next; + struct grub_mm_region *newreg = (void *) newreg_start; + hancestor->next = new_header; + if (newregfirst == hb) + newregfirst = new_header; + newreg->first = newregfirst; + newreg->next = newregnext; + newreg->pre_size = newreg_presize; + newreg->size = newreg_size; + *regancestor = newreg; + { + grub_mm_header_t h = newreg->first, hp = NULL; + do + { + if ((void *) h < (void *) (newreg + 1)) + grub_fatal ("Failed to adjust memory region: %p, %p, %p, %p, %p", + newreg, newreg->first, h, hp, hb); +#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF + if ((void *) h == (void *) (newreg + 1)) + grub_dprintf ("relocator", + "Free start memory region: %p, %p, %p, %p, %p", + newreg, newreg->first, h, hp, hb); +#endif + hp = h; + h = h->next; + } + while (h != newreg->first); + } + } +} + +static void +allocate_inreg (grub_phys_addr_t paddr, grub_size_t size, + grub_mm_header_t hb, grub_mm_header_t hbp, + grub_mm_region_t rb) +{ + struct grub_mm_header *foll = NULL; + grub_addr_t vaddr = (grub_addr_t) hb + (paddr - grub_vtop (hb)); + +#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF + grub_dprintf ("relocator", "inreg paddr = 0x%lx, size = %lu," + " hb = %p, hbp = %p, rb = %p, vaddr = 0x%lx\n", + (unsigned long) paddr, (unsigned long) size, hb, hbp, + rb, (unsigned long) vaddr); +#endif + + if (ALIGN_UP (vaddr + size, GRUB_MM_ALIGN) + GRUB_MM_ALIGN + <= (grub_addr_t) (hb + hb->size)) + { + foll = (void *) ALIGN_UP (vaddr + size, GRUB_MM_ALIGN); + foll->magic = GRUB_MM_FREE_MAGIC; + foll->size = hb + hb->size - foll; +#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF + grub_dprintf ("relocator", "foll = %p, foll->size = %lu\n", foll, + (unsigned long) foll->size); +#endif + } + + if (vaddr - (grub_addr_t) hb >= sizeof (*hb)) + { + hb->size = ((vaddr - (grub_addr_t) hb) >> GRUB_MM_ALIGN_LOG2); + if (foll) + { + foll->next = hb; + hbp->next = foll; + if (rb->first == hb) + { + rb->first = foll; + } + } + } + else + { + if (foll) + { + foll->next = hb->next; + } + else + foll = hb->next; + + hbp->next = foll; + if (rb->first == hb) + { + rb->first = foll; + } + if (rb->first == hb) + { + rb->first = (void *) (rb + 1); + } + } +} + +#if GRUB_RELOCATOR_HAVE_LEFTOVERS +static void +check_leftover (struct grub_relocator_fw_leftover *lo) +{ + unsigned i; + for (i = 0; i < sizeof (lo->freebytes); i++) + if (lo->freebytes[i] != 0xff) + return; + grub_relocator_firmware_free_region (lo->quantstart, + GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT); + *lo->prev = lo->next; + if (lo->next) + lo->next->prev = lo->prev; +} +#endif + +static void +free_subchunk (const struct grub_relocator_subchunk *subchu) +{ + switch (subchu->type) + { + case CHUNK_TYPE_REGION_START: + { + grub_mm_region_t r1, r2, *rp; + grub_mm_header_t h; + grub_size_t pre_size; + r1 = subchu->reg; + r2 = (grub_mm_region_t) ALIGN_UP ((grub_addr_t) subchu->reg + + (grub_vtop (subchu->reg) + - subchu->start) + subchu->size, + GRUB_MM_ALIGN); + for (rp = &grub_mm_base; *rp && *rp != r2; rp = &((*rp)->next)); + pre_size = subchu->pre_size; + + if (*rp) + { + grub_mm_header_t h2, *hp; + r1->first = r2->first; + r1->next = r2->next; + r1->pre_size = pre_size; + r1->size = r2->size + (r2 - r1) * sizeof (*r2); + *rp = r1; + h = (grub_mm_header_t) (r1 + 1); + h->next = r2->first; + h->magic = GRUB_MM_FREE_MAGIC; + h->size = (r2 - r1 - 1); + for (hp = &r2->first, h2 = *hp; h2->next != r2->first; + hp = &(h2->next), h2 = *hp) + if (h2 == (grub_mm_header_t) (r2 + 1)) + break; + if (h2 == (grub_mm_header_t) (r2 + 1)) + { + h->size = h2->size + (h2 - h); + h->next = h2->next; + *hp = h; + if (hp == &r2->first) + { + for (h2 = r2->first; h2->next != r2->first; h2 = h2->next); + h2->next = h; + } + } + else + { + h2->next = h; + } + } + else + { + r1->pre_size = pre_size; + r1->size = (r2 - r1) * sizeof (*r2); + /* Find where to insert this region. + Put a smaller one before bigger ones, + to prevent fragmentation. */ + for (rp = &grub_mm_base; *rp; rp = &((*rp)->next)) + if ((*rp)->size > r1->size) + break; + r1->next = *rp; + *rp = r1->next; + h = (grub_mm_header_t) (r1 + 1); + r1->first = h; + h->next = h; + h->magic = GRUB_MM_FREE_MAGIC; + h->size = (r2 - r1 - 1); + } + for (r2 = grub_mm_base; r2; r2 = r2->next) + if ((grub_addr_t) r2 + r2->size == (grub_addr_t) r1) + break; + if (r2) + { + grub_mm_header_t hl2, hl, g; + g = (grub_mm_header_t) ((grub_addr_t) r2 + r2->size); + g->size = (grub_mm_header_t) r1 - g; + r2->size += r1->size; + for (hl = r2->first; hl->next != r2->first; hl = hl->next); + for (hl2 = r1->first; hl2->next != r1->first; hl2 = hl2->next); + hl2->next = r2->first; + r2->first = r1->first; + hl->next = r2->first; + *rp = (*rp)->next; + grub_free (g + 1); + } + break; + } + case CHUNK_TYPE_IN_REGION: + { + grub_mm_header_t h = (grub_mm_header_t) ALIGN_DOWN ((grub_addr_t) subchu->start, + GRUB_MM_ALIGN); + h->size + = ((subchu->start + subchu->size + GRUB_MM_ALIGN - 1) / GRUB_MM_ALIGN) + - (subchu->start / GRUB_MM_ALIGN) - 1; + h->next = h; + h->magic = GRUB_MM_ALLOC_MAGIC; + grub_free (h + 1); + break; + } +#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS + case CHUNK_TYPE_FIRMWARE: + case CHUNK_TYPE_LEFTOVER: + { + grub_addr_t fstart, fend; + fstart = ALIGN_UP (subchu->start, + GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT); + fend = ALIGN_DOWN (subchu->start + subchu->size, + GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT); + if (fstart < fend) + grub_relocator_firmware_free_region (fstart, fend - fstart); +#if GRUB_RELOCATOR_HAVE_LEFTOVERS + if (subchu->pre) + { + int off = subchu->start - fstart + - GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT; + grub_memset (subchu->pre->freebytes + off / 8 + 1, + 0xff, sizeof (subchu->pre->freebytes) - off / 8 - 1); + subchu->pre->freebytes[off / 8] |= ~((1 << (off % 8)) - 1); + check_leftover (subchu->pre); + } + if (subchu->post) + { + int off = subchu->start + subchu->size - fend; + grub_memset (subchu->pre->freebytes, + 0xff, sizeof (subchu->pre->freebytes) - off / 8); + subchu->pre->freebytes[off / 8] |= ((1 << (8 - (off % 8))) - 1); + check_leftover (subchu->post); + } +#endif + *subchu->extra->prev = subchu->extra->next; + grub_free (subchu->extra); + } + break; +#endif + } +} + +static int +malloc_in_range (struct grub_relocator *rel, + grub_addr_t start, grub_addr_t end, grub_addr_t align, + grub_size_t size, struct grub_relocator_chunk *res, + int from_low_priv, int collisioncheck) +{ + grub_mm_region_t r, *ra, base_saved; + struct grub_relocator_mmap_event *events = NULL, *eventt = NULL, *t; + /* 128 is just in case of additional malloc (shouldn't happen). */ + unsigned maxevents = 2 + 128; + grub_mm_header_t p, pa; + unsigned *counter; + int nallocs = 0; + unsigned j, N = 0; + grub_addr_t target = 0; + + grub_dprintf ("relocator", + "trying to allocate in 0x%lx-0x%lx aligned 0x%lx size 0x%lx\n", + (unsigned long) start, (unsigned long) end, + (unsigned long) align, (unsigned long) size); + + start = ALIGN_UP (start, align); + end = ALIGN_DOWN (end - size, align) + size; + + if (end < start + size) + return 0; + + /* We have to avoid any allocations when filling scanline events. + Hence 2-stages. + */ + for (r = grub_mm_base; r; r = r->next) + { + p = r->first; + do + { + if ((grub_addr_t) p < (grub_addr_t) (r + 1) + || (grub_addr_t) p >= (grub_addr_t) (r + 1) + r->size) + grub_fatal ("%d: out of range pointer: %p\n", __LINE__, p); + maxevents += 2; + p = p->next; + } + while (p != r->first); + maxevents += 4; + } + + if (collisioncheck && rel) + { + struct grub_relocator_chunk *chunk; + for (chunk = rel->chunks; chunk; chunk = chunk->next) + maxevents += 2; + } + +#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS + { + struct grub_relocator_extra_block *cur; + for (cur = extra_blocks; cur; cur = cur->next) + maxevents += 2; + } + for (r = grub_mm_base; r; r = r->next) + maxevents += 2; + + maxevents += grub_relocator_firmware_get_max_events (); +#endif + +#if GRUB_RELOCATOR_HAVE_LEFTOVERS + { + struct grub_relocator_fw_leftover *cur; + for (cur = leftovers; cur; cur = cur->next) + { + int l = 0; + unsigned i; + for (i = 0; i < GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT; i++) + { + if (l != ((cur->freebytes[i / 8] >> (i % 8)) & 1)) + maxevents++; + l = ((cur->freebytes[i / 8] >> (i % 8)) & 1); + } + if (l) + maxevents++; + } + } +#endif + + eventt = grub_malloc (maxevents * sizeof (events[0])); + counter = grub_malloc ((DIGITSORT_MASK + 2) * sizeof (counter[0])); + events = grub_malloc (maxevents * sizeof (events[0])); + if (!events || !eventt || !counter) + { + grub_dprintf ("relocator", "events or counter allocation failed %d\n", + maxevents); + grub_free (events); + grub_free (eventt); + grub_free (counter); + return 0; + } + + if (collisioncheck && rel) + { + struct grub_relocator_chunk *chunk; + for (chunk = rel->chunks; chunk; chunk = chunk->next) + { + events[N].type = COLLISION_START; + events[N].pos = chunk->target; + N++; + events[N].type = COLLISION_END; + events[N].pos = chunk->target + chunk->size; + N++; + } + } + +#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS + for (r = grub_mm_base; r; r = r->next) + { +#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF + grub_dprintf ("relocator", "Blocking at 0x%lx-0x%lx\n", + (unsigned long) r - r->pre_size, + (unsigned long) (r + 1) + r->size); +#endif + events[N].type = FIRMWARE_BLOCK_START; + events[N].pos = (grub_addr_t) r - r->pre_size; + N++; + events[N].type = FIRMWARE_BLOCK_END; + events[N].pos = (grub_addr_t) (r + 1) + r->size; + N++; + } + { + struct grub_relocator_extra_block *cur; + for (cur = extra_blocks; cur; cur = cur->next) + { +#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF + grub_dprintf ("relocator", "Blocking at 0x%lx-0x%lx\n", + (unsigned long) cur->start, (unsigned long) cur->end); +#endif + events[N].type = FIRMWARE_BLOCK_START; + events[N].pos = cur->start; + N++; + events[N].type = FIRMWARE_BLOCK_END; + events[N].pos = cur->end; + N++; + } + } + + N += grub_relocator_firmware_fill_events (events + N); + +#if GRUB_RELOCATOR_HAVE_LEFTOVERS + { + struct grub_relocator_fw_leftover *cur; + for (cur = leftovers; cur; cur = cur->next) + { + unsigned i; + int l = 0; + for (i = 0; i < GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT; i++) + { + if (l != ((cur->freebytes[i / 8] >> (i % 8)) & 1)) + { + events[N].type = l ? REG_LEFTOVER_END : REG_LEFTOVER_START; + events[N].pos = cur->quantstart + i; + events[N].leftover = cur; + N++; + } + l = ((cur->freebytes[i / 8] >> (i % 8)) & 1); + } + if (l) + { + events[N].type = REG_LEFTOVER_END; + events[N].pos = cur->quantstart + i; + events[N].leftover = cur; + N++; + } + } + } +#endif +#endif + + /* No malloc from this point. */ + base_saved = grub_mm_base; + grub_mm_base = NULL; + + for (ra = &base_saved, r = *ra; r; ra = &(r->next), r = *ra) + { + pa = r->first; + p = pa->next; + if (p->magic == GRUB_MM_ALLOC_MAGIC) + continue; + do + { + if (p->magic != GRUB_MM_FREE_MAGIC) + grub_fatal ("%s:%d free magic broken at %p (0x%x)\n", + __FILE__, + __LINE__, p, p->magic); + if (p == (grub_mm_header_t) (r + 1)) + { + events[N].type = REG_BEG_START; + events[N].pos = grub_vtop (r) - r->pre_size; + events[N].reg = r; + events[N].regancestor = ra; + events[N].head = p; + events[N].hancestor = pa; + N++; + events[N].type = REG_BEG_END; + events[N].pos = grub_vtop (p + p->size) - sizeof (*r) + - sizeof (struct grub_mm_header); + N++; + } + else + { + events[N].type = IN_REG_START; + events[N].pos = grub_vtop (p); + events[N].head = p; + events[N].hancestor = pa; + events[N].reg = r; + N++; + events[N].type = IN_REG_END; + events[N].pos = grub_vtop (p + p->size); + N++; + } + pa = p; + p = pa->next; + } + while (pa != r->first); + } + + /* Put ending events after starting events. */ + { + int st = 0, e = N / 2; + for (j = 0; j < N; j++) + if (is_start (events[j].type) || events[j].type == COLLISION_START) + eventt[st++] = events[j]; + else + eventt[e++] = events[j]; + t = eventt; + eventt = events; + events = t; + } + + { + unsigned i; + for (i = 0; i < (BITS_IN_BYTE * sizeof (grub_addr_t) / DIGITSORT_BITS); + i++) + { + grub_memset (counter, 0, (1 + (1 << DIGITSORT_BITS)) * sizeof (counter[0])); + for (j = 0; j < N; j++) + counter[((events[j].pos >> (DIGITSORT_BITS * i)) + & DIGITSORT_MASK) + 1]++; + for (j = 0; j <= DIGITSORT_MASK; j++) + counter[j+1] += counter[j]; + for (j = 0; j < N; j++) + eventt[counter[((events[j].pos >> (DIGITSORT_BITS * i)) + & DIGITSORT_MASK)]++] = events[j]; + t = eventt; + eventt = events; + events = t; + } + } + +#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS + retry: +#endif + + /* Now events are nicely sorted. */ + { + int nstarted = 0, ncollisions = 0, nstartedfw = 0, nblockfw = 0; +#if GRUB_RELOCATOR_HAVE_LEFTOVERS + int nlefto = 0; +#else + const int nlefto = 0; +#endif + grub_addr_t starta = 0; + for (j = from_low_priv ? 0 : N - 1; from_low_priv ? j < N : (j + 1); + from_low_priv ? j++ : j--) + { + int isinsidebefore, isinsideafter; + isinsidebefore = (!ncollisions && (nstarted || (((nlefto || nstartedfw) + && !nblockfw)))); + switch (events[j].type) + { +#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS + case REG_FIRMWARE_START: + nstartedfw++; + break; + + case REG_FIRMWARE_END: + nstartedfw--; + break; + + case FIRMWARE_BLOCK_START: + nblockfw++; + break; + + case FIRMWARE_BLOCK_END: + nblockfw--; + break; +#endif + +#if GRUB_RELOCATOR_HAVE_LEFTOVERS + case REG_LEFTOVER_START: + nlefto++; + break; + + case REG_LEFTOVER_END: + nlefto--; + break; +#endif + + case COLLISION_START: + ncollisions++; + break; + + case COLLISION_END: + ncollisions--; + break; + + case IN_REG_START: + case REG_BEG_START: + nstarted++; + break; + + case IN_REG_END: + case REG_BEG_END: + nstarted--; + break; + } + isinsideafter = (!ncollisions && (nstarted || ((nlefto || nstartedfw) + && !nblockfw))); + if (from_low_priv) { + if (!isinsidebefore && isinsideafter) + starta = ALIGN_UP (events[j].pos, align); + + if (isinsidebefore && !isinsideafter) + { + target = starta; + if (target < start) + target = start; + if (target + size <= end && target + size <= events[j].pos) + /* Found an usable address. */ + goto found; + } + } else { + if (!isinsidebefore && isinsideafter) + { + if (events[j].pos >= size) + starta = ALIGN_DOWN (events[j].pos - size, align) + size; + else + starta = 0; + } + if (isinsidebefore && !isinsideafter && starta >= size) + { + target = starta - size; + if (target > end - size) + target = end - size; + if (target >= start && target >= events[j].pos) + goto found; + } + } + } + } + + grub_mm_base = base_saved; + grub_free (events); + grub_free (eventt); + grub_free (counter); + return 0; + + found: + { + int inreg = 0, regbeg = 0, ncol = 0; +#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS + int fwin = 0, fwb = 0, fwlefto = 0; +#endif +#if GRUB_RELOCATOR_HAVE_LEFTOVERS + int last_lo = 0; +#endif + int last_start = 0; + for (j = 0; j < N; j++) + { + int typepre; + if (ncol) + typepre = -1; + else if (regbeg) + typepre = CHUNK_TYPE_REGION_START; + else if (inreg) + typepre = CHUNK_TYPE_IN_REGION; +#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS + else if (fwin && !fwb) + typepre = CHUNK_TYPE_FIRMWARE; + else if (fwlefto && !fwb) + typepre = CHUNK_TYPE_LEFTOVER; +#endif + else + typepre = -1; + + if (j != 0 && events[j - 1].pos != events[j].pos) + { + grub_addr_t alloc_start, alloc_end; + alloc_start = max (events[j - 1].pos, target); + alloc_end = min (events[j].pos, target + size); + if (alloc_end > alloc_start) + { + switch (typepre) + { + case CHUNK_TYPE_REGION_START: + allocate_regstart (alloc_start, alloc_end - alloc_start, + events[last_start].reg, + events[last_start].regancestor, + events[last_start].hancestor); + /* TODO: maintain a reverse lookup tree for hancestor. */ + { + unsigned k; + for (k = 0; k < N; k++) + if (events[k].hancestor == events[last_start].head) + events[k].hancestor = events[last_start].hancestor; + } + break; + case CHUNK_TYPE_IN_REGION: + allocate_inreg (alloc_start, alloc_end - alloc_start, + events[last_start].head, + events[last_start].hancestor, + events[last_start].reg); + { + unsigned k; + for (k = 0; k < N; k++) + if (events[k].hancestor == events[last_start].head) + events[k].hancestor = events[last_start].hancestor; + } + break; +#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS + case CHUNK_TYPE_FIRMWARE: + { + grub_addr_t fstart, fend; + fstart + = ALIGN_DOWN (alloc_start, + GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT); + fend + = ALIGN_UP (alloc_end, + GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT); +#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF + grub_dprintf ("relocator", "requesting %lx-%lx\n", + (unsigned long) fstart, + (unsigned long) fend); +#endif + /* The failure here can be very expensive. */ + if (!grub_relocator_firmware_alloc_region (fstart, + fend - fstart)) + { + if (from_low_priv) + start = fend; + else + end = fstart; + goto retry; + } + break; + } +#endif + +#if GRUB_RELOCATOR_HAVE_LEFTOVERS + case CHUNK_TYPE_LEFTOVER: + { + unsigned offstart = alloc_start + % GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT; + unsigned offend = alloc_end + % GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT; + struct grub_relocator_fw_leftover *lo + = events[last_lo].leftover; + if (offend == 0 && alloc_end != alloc_start) + offend = GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT; + lo->freebytes[offstart / 8] + &= ((1 << (8 - (start % 8))) - 1); + grub_memset (lo->freebytes + (offstart + 7) / 8, 0, + offend / 8 - (offstart + 7) / 8); + lo->freebytes[offend / 8] &= ~((1 << (offend % 8)) - 1); + } + break; +#endif + } + nallocs++; + } + } + + switch (events[j].type) + { + case REG_BEG_START: + case IN_REG_START: + if (events[j].type == REG_BEG_START && + (grub_addr_t) (events[j].reg + 1) > target) + regbeg++; + else + inreg++; + last_start = j; + break; + + case REG_BEG_END: + case IN_REG_END: + if (regbeg) + regbeg--; + else + inreg--; + break; + +#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS + case REG_FIRMWARE_START: + fwin++; + break; + + case REG_FIRMWARE_END: + fwin--; + break; + + case FIRMWARE_BLOCK_START: + fwb++; + break; + + case FIRMWARE_BLOCK_END: + fwb--; + break; +#endif + +#if GRUB_RELOCATOR_HAVE_LEFTOVERS + case REG_LEFTOVER_START: + fwlefto++; + last_lo = j; + break; + + case REG_LEFTOVER_END: + fwlefto--; + break; +#endif + case COLLISION_START: + ncol++; + break; + case COLLISION_END: + ncol--; + break; + } + + } + } + + /* Malloc is available again. */ + grub_mm_base = base_saved; + + grub_free (eventt); + grub_free (counter); + + { + int last_start = 0; + int inreg = 0, regbeg = 0, ncol = 0; +#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS + int fwin = 0, fwlefto = 0, fwb = 0; +#endif + unsigned cural = 0; + int oom = 0; + res->subchunks = grub_malloc (sizeof (res->subchunks[0]) * nallocs); + if (!res->subchunks) + oom = 1; + res->nsubchunks = nallocs; + + for (j = 0; j < N; j++) + { + int typepre; + if (ncol) + typepre = -1; + else if (regbeg) + typepre = CHUNK_TYPE_REGION_START; + else if (inreg) + typepre = CHUNK_TYPE_IN_REGION; +#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS + else if (fwin && !fwb) + typepre = CHUNK_TYPE_FIRMWARE; + else if (fwlefto && !fwb) + typepre = CHUNK_TYPE_LEFTOVER; +#endif + else + typepre = -1; + + if (j != 0 && events[j - 1].pos != events[j].pos) + { + grub_addr_t alloc_start, alloc_end; + struct grub_relocator_subchunk tofree; + struct grub_relocator_subchunk *curschu = &tofree; + if (!oom) + curschu = &res->subchunks[cural]; + alloc_start = max (events[j - 1].pos, target); + alloc_end = min (events[j].pos, target + size); + if (alloc_end > alloc_start) + { +#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF + grub_dprintf ("relocator", "subchunk 0x%lx-0x%lx, %d\n", + (unsigned long) alloc_start, + (unsigned long) alloc_end, typepre); +#endif + curschu->type = typepre; + curschu->start = alloc_start; + curschu->size = alloc_end - alloc_start; + if (typepre == CHUNK_TYPE_REGION_START + || typepre == CHUNK_TYPE_IN_REGION) + { + curschu->reg = events[last_start].reg; + curschu->pre_size = alloc_start - events[j - 1].pos; + } + if (!oom && (typepre == CHUNK_TYPE_REGION_START +#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS + || typepre == CHUNK_TYPE_FIRMWARE +#endif + )) + { + struct grub_relocator_extra_block *ne; + ne = grub_malloc (sizeof (*ne)); + if (!ne) + { + oom = 1; + grub_memcpy (&tofree, curschu, sizeof (tofree)); + } + else + { + ne->start = alloc_start; + ne->end = alloc_end; + ne->next = extra_blocks; + ne->prev = &extra_blocks; + if (extra_blocks) + extra_blocks->prev = &(ne->next); + extra_blocks = ne; + curschu->extra = ne; + } + } + +#if GRUB_RELOCATOR_HAVE_LEFTOVERS + if (!oom && typepre == CHUNK_TYPE_FIRMWARE) + { + grub_addr_t fstart, fend; + + fstart + = ALIGN_DOWN (alloc_start, + GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT); + fend + = ALIGN_UP (alloc_end, + GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT); + + { + struct grub_relocator_fw_leftover *lo1 = NULL; + struct grub_relocator_fw_leftover *lo2 = NULL; + if (fstart != alloc_start) + lo1 = grub_malloc (sizeof (*lo1)); + if (fend != alloc_end) + lo2 = grub_malloc (sizeof (*lo2)); + if ((!lo1 && fstart != alloc_start) + || (!lo2 && fend != alloc_end)) + { + struct grub_relocator_extra_block *ne; + grub_free (lo1); + grub_free (lo2); + lo1 = NULL; + lo2 = NULL; + oom = 1; + grub_memcpy (&tofree, curschu, sizeof (tofree)); + ne = extra_blocks; + extra_blocks = extra_blocks->next; + grub_free (ne); + } + if (lo1) + { + lo1->quantstart = fstart; + grub_memset (lo1->freebytes, 0xff, + (alloc_start - fstart) / 8); + lo1->freebytes[(alloc_start - fstart) / 8] + = (1 << ((alloc_start - fstart) % 8)) - 1; + grub_memset (lo1->freebytes + + ((alloc_start - fstart) / 8) + 1, 0, + sizeof (lo1->freebytes) + - (alloc_start - fstart) / 8 - 1); + lo1->next = leftovers; + lo1->prev = &leftovers; + if (leftovers) + leftovers->prev = &lo1->next; + leftovers = lo1; + } + if (lo2) + { + lo2->quantstart + = fend - GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT; + grub_memset (lo2->freebytes, 0, + (alloc_end - lo2->quantstart) / 8); + lo2->freebytes[(alloc_end - lo2->quantstart) / 8] + = ~((1 << ((alloc_end - lo2->quantstart) % 8)) - 1); + grub_memset (lo2->freebytes + + ((alloc_end - lo2->quantstart) / 8) + + 1, 0, sizeof (lo2->freebytes) + - (alloc_end - lo2->quantstart) / 8 - 1); + lo2->prev = &leftovers; + if (leftovers) + leftovers->prev = &lo2->next; + lo2->next = leftovers; + leftovers = lo2; + } + curschu->pre = lo1; + curschu->post = lo2; + } + } + + if (typepre == CHUNK_TYPE_LEFTOVER) + { + curschu->pre = events[last_start].leftover; + curschu->post = events[last_start].leftover; + } +#endif + + if (!oom) + cural++; + else + free_subchunk (&tofree); + } + } + + switch (events[j].type) + { + case REG_BEG_START: + case IN_REG_START: + if (events[j].type == REG_BEG_START && + (grub_addr_t) (events[j].reg + 1) > target) + regbeg++; + else + inreg++; + last_start = j; + break; + + case REG_BEG_END: + case IN_REG_END: + inreg = regbeg = 0; + break; + +#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS + case REG_FIRMWARE_START: + fwin++; + break; + + case REG_FIRMWARE_END: + fwin--; + break; + + case FIRMWARE_BLOCK_START: + fwb++; + break; + + case FIRMWARE_BLOCK_END: + fwb--; + break; +#endif + +#if GRUB_RELOCATOR_HAVE_LEFTOVERS + case REG_LEFTOVER_START: + fwlefto++; + break; + + case REG_LEFTOVER_END: + fwlefto--; + break; +#endif + case COLLISION_START: + ncol++; + break; + case COLLISION_END: + ncol--; + break; + } + } + if (oom) + { + unsigned i; + for (i = 0; i < cural; i++) + free_subchunk (&res->subchunks[i]); + grub_free (res->subchunks); + grub_dprintf ("relocator", "allocation failed with out-of-memory\n"); + grub_free (events); + + return 0; + } + } + + res->src = target; + res->size = size; + + grub_free (events); + + grub_dprintf ("relocator", "allocated: 0x%lx+0x%lx\n", (unsigned long) target, + (unsigned long) size); + + return 1; +} + +static void +adjust_limits (struct grub_relocator *rel, + grub_phys_addr_t *min_addr, grub_phys_addr_t *max_addr, + grub_phys_addr_t in_min, grub_phys_addr_t in_max) +{ + struct grub_relocator_chunk *chunk; + + *min_addr = 0; + *max_addr = rel->postchunks; + + /* Keep chunks in memory in the same order as they'll be after relocation. */ + for (chunk = rel->chunks; chunk; chunk = chunk->next) + { + if (chunk->target > in_max && chunk->src < *max_addr + && chunk->src < rel->postchunks) + *max_addr = chunk->src; + if (chunk->target + chunk->size <= in_min + && chunk->src + chunk->size > *min_addr + && chunk->src < rel->postchunks) + *min_addr = chunk->src + chunk->size; + } +} + +grub_err_t +grub_relocator_alloc_chunk_addr (struct grub_relocator *rel, + grub_relocator_chunk_t *out, + grub_phys_addr_t target, grub_size_t size) +{ + struct grub_relocator_chunk *chunk; + grub_phys_addr_t min_addr = 0, max_addr; + + if (target > ~size) + return grub_error (GRUB_ERR_BUG, "address is out of range"); + + adjust_limits (rel, &min_addr, &max_addr, target, target); + + for (chunk = rel->chunks; chunk; chunk = chunk->next) + if ((chunk->target <= target && target < chunk->target + chunk->size) + || (target <= chunk->target && chunk->target < target + size)) + return grub_error (GRUB_ERR_BUG, "overlap detected"); + + chunk = grub_malloc (sizeof (struct grub_relocator_chunk)); + if (!chunk) + return grub_errno; + + grub_dprintf ("relocator", + "min_addr = 0x%llx, max_addr = 0x%llx, target = 0x%llx\n", + (unsigned long long) min_addr, (unsigned long long) max_addr, + (unsigned long long) target); + + do + { + /* A trick to improve Linux allocation. */ +#if defined (__i386__) || defined (__x86_64__) + if (target < 0x100000) + if (malloc_in_range (rel, rel->highestnonpostaddr, ~(grub_addr_t)0, 1, + size, chunk, 0, 1)) + { + if (rel->postchunks > chunk->src) + rel->postchunks = chunk->src; + break; + } +#elif defined(__mips__) && (_MIPS_SIM == _ABI64) + if (malloc_in_range (rel, target, max_addr, 8, size, chunk, 1, 0)) + break; +#endif + if (malloc_in_range (rel, target, max_addr, 1, size, chunk, 1, 0)) + break; + + if (malloc_in_range (rel, min_addr, target, 1, size, chunk, 0, 0)) + break; + + if (malloc_in_range (rel, rel->highestnonpostaddr, ~(grub_addr_t)0, 1, + size, chunk, 0, 1)) + { + if (rel->postchunks > chunk->src) + rel->postchunks = chunk->src; + break; + } + + grub_dprintf ("relocator", "not allocated\n"); + grub_free (chunk); + return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + } + while (0); + + grub_dprintf ("relocator", "allocated 0x%llx/0x%llx\n", + (unsigned long long) chunk->src, (unsigned long long) target); + + if (rel->highestaddr < target + size) + rel->highestaddr = target + size; + + if (rel->highestaddr < chunk->src + size) + rel->highestaddr = chunk->src + size; + + if (chunk->src < rel->postchunks) + { + if (rel->highestnonpostaddr < target + size) + rel->highestnonpostaddr = target + size; + + if (rel->highestnonpostaddr < chunk->src + size) + rel->highestnonpostaddr = chunk->src + size; + } + + grub_dprintf ("relocator", "relocators_size=%ld\n", + (unsigned long) rel->relocators_size); + + if (chunk->src < target) + rel->relocators_size += grub_relocator_backward_size; + if (chunk->src > target) + rel->relocators_size += grub_relocator_forward_size; + + grub_dprintf ("relocator", "relocators_size=%ld\n", + (unsigned long) rel->relocators_size); + + chunk->target = target; + chunk->size = size; + chunk->next = rel->chunks; + rel->chunks = chunk; + grub_dprintf ("relocator", "cur = %p, next = %p\n", rel->chunks, + rel->chunks->next); + + chunk->srcv = grub_map_memory (chunk->src, chunk->size); + *out = chunk; +#ifdef DEBUG_RELOCATOR + grub_memset (chunk->srcv, 0xfa, chunk->size); + grub_mm_check (); +#endif + return GRUB_ERR_NONE; +} + +/* Context for grub_relocator_alloc_chunk_align. */ +struct grub_relocator_alloc_chunk_align_ctx +{ + grub_phys_addr_t min_addr, max_addr; + grub_size_t size, align; + int preference; + struct grub_relocator_chunk *chunk; + int found; +}; + +/* Helper for grub_relocator_alloc_chunk_align. */ +static int +grub_relocator_alloc_chunk_align_iter (grub_uint64_t addr, grub_uint64_t sz, + grub_memory_type_t type, void *data) +{ + struct grub_relocator_alloc_chunk_align_ctx *ctx = data; + grub_uint64_t candidate; + + if (type != GRUB_MEMORY_AVAILABLE) + return 0; + candidate = ALIGN_UP (addr, ctx->align); + if (candidate < ctx->min_addr) + candidate = ALIGN_UP (ctx->min_addr, ctx->align); + if (candidate + ctx->size > addr + sz + || candidate > ALIGN_DOWN (ctx->max_addr, ctx->align)) + return 0; + if (ctx->preference == GRUB_RELOCATOR_PREFERENCE_HIGH) + candidate = ALIGN_DOWN (min (addr + sz - ctx->size, ctx->max_addr), + ctx->align); + if (!ctx->found || (ctx->preference == GRUB_RELOCATOR_PREFERENCE_HIGH + && candidate > ctx->chunk->target)) + ctx->chunk->target = candidate; + if (!ctx->found || (ctx->preference == GRUB_RELOCATOR_PREFERENCE_LOW + && candidate < ctx->chunk->target)) + ctx->chunk->target = candidate; + ctx->found = 1; + return 0; +} + +grub_err_t +grub_relocator_alloc_chunk_align (struct grub_relocator *rel, + grub_relocator_chunk_t *out, + grub_phys_addr_t min_addr, + grub_phys_addr_t max_addr, + grub_size_t size, grub_size_t align, + int preference, + int avoid_efi_boot_services) +{ + struct grub_relocator_alloc_chunk_align_ctx ctx = { + .min_addr = min_addr, + .max_addr = max_addr, + .size = size, + .align = align, + .preference = preference, + .found = 0 + }; + grub_addr_t min_addr2 = 0, max_addr2; + + if (max_addr > ~size) + max_addr = ~size; + +#ifdef GRUB_MACHINE_PCBIOS + if (min_addr < 0x1000) + min_addr = 0x1000; +#endif + + grub_dprintf ("relocator", "chunks = %p\n", rel->chunks); + + ctx.chunk = grub_malloc (sizeof (struct grub_relocator_chunk)); + if (!ctx.chunk) + return grub_errno; + + if (malloc_in_range (rel, min_addr, max_addr, align, + size, ctx.chunk, + preference != GRUB_RELOCATOR_PREFERENCE_HIGH, 1)) + { + grub_dprintf ("relocator", "allocated 0x%llx/0x%llx\n", + (unsigned long long) ctx.chunk->src, + (unsigned long long) ctx.chunk->src); + grub_dprintf ("relocator", "chunks = %p\n", rel->chunks); + ctx.chunk->target = ctx.chunk->src; + ctx.chunk->size = size; + ctx.chunk->next = rel->chunks; + rel->chunks = ctx.chunk; + ctx.chunk->srcv = grub_map_memory (ctx.chunk->src, ctx.chunk->size); + *out = ctx.chunk; + return GRUB_ERR_NONE; + } + + adjust_limits (rel, &min_addr2, &max_addr2, min_addr, max_addr); + grub_dprintf ("relocator", "Adjusted limits from %lx-%lx to %lx-%lx\n", + (unsigned long) min_addr, (unsigned long) max_addr, + (unsigned long) min_addr2, (unsigned long) max_addr2); + + do + { + if (malloc_in_range (rel, min_addr2, max_addr2, align, + size, ctx.chunk, 1, 1)) + break; + + if (malloc_in_range (rel, rel->highestnonpostaddr, ~(grub_addr_t)0, 1, + size, ctx.chunk, 0, 1)) + { + if (rel->postchunks > ctx.chunk->src) + rel->postchunks = ctx.chunk->src; + break; + } + + return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + } + while (0); + + { +#ifdef GRUB_MACHINE_EFI + grub_efi_mmap_iterate (grub_relocator_alloc_chunk_align_iter, &ctx, + avoid_efi_boot_services); +#elif defined (__powerpc__) || defined (GRUB_MACHINE_XEN) + (void) avoid_efi_boot_services; + grub_machine_mmap_iterate (grub_relocator_alloc_chunk_align_iter, &ctx); +#else + (void) avoid_efi_boot_services; + grub_mmap_iterate (grub_relocator_alloc_chunk_align_iter, &ctx); +#endif + if (!ctx.found) + return grub_error (GRUB_ERR_BAD_OS, "couldn't find suitable memory target"); + } + while (1) + { + struct grub_relocator_chunk *chunk2; + for (chunk2 = rel->chunks; chunk2; chunk2 = chunk2->next) + if ((chunk2->target <= ctx.chunk->target + && ctx.chunk->target < chunk2->target + chunk2->size) + || (ctx.chunk->target <= chunk2->target && chunk2->target + < ctx.chunk->target + size)) + { + if (preference == GRUB_RELOCATOR_PREFERENCE_HIGH) + ctx.chunk->target = ALIGN_DOWN (chunk2->target, align); + else + ctx.chunk->target = ALIGN_UP (chunk2->target + chunk2->size, + align); + break; + } + if (!chunk2) + break; + } + + grub_dprintf ("relocator", "relocators_size=%ld\n", + (unsigned long) rel->relocators_size); + + if (ctx.chunk->src < ctx.chunk->target) + rel->relocators_size += grub_relocator_backward_size; + if (ctx.chunk->src > ctx.chunk->target) + rel->relocators_size += grub_relocator_forward_size; + + grub_dprintf ("relocator", "relocators_size=%ld\n", + (unsigned long) rel->relocators_size); + + ctx.chunk->size = size; + ctx.chunk->next = rel->chunks; + rel->chunks = ctx.chunk; + grub_dprintf ("relocator", "cur = %p, next = %p\n", rel->chunks, + rel->chunks->next); + ctx.chunk->srcv = grub_map_memory (ctx.chunk->src, ctx.chunk->size); + *out = ctx.chunk; +#ifdef DEBUG_RELOCATOR + grub_memset (ctx.chunk->srcv, 0xfa, ctx.chunk->size); + grub_mm_check (); +#endif + return GRUB_ERR_NONE; +} + +void +grub_relocator_unload (struct grub_relocator *rel) +{ + struct grub_relocator_chunk *chunk, *next; + if (!rel) + return; + for (chunk = rel->chunks; chunk; chunk = next) + { + unsigned i; + for (i = 0; i < chunk->nsubchunks; i++) + free_subchunk (&chunk->subchunks[i]); + grub_unmap_memory (chunk->srcv, chunk->size); + next = chunk->next; + grub_free (chunk->subchunks); + grub_free (chunk); + } + grub_free (rel); +} + +grub_err_t +grub_relocator_prepare_relocs (struct grub_relocator *rel, grub_addr_t addr, + void **relstart, grub_size_t *relsize) +{ + grub_uint8_t *rels; + grub_uint8_t *rels0; + struct grub_relocator_chunk *sorted; + grub_size_t nchunks = 0; + unsigned j; + struct grub_relocator_chunk movers_chunk; + + grub_dprintf ("relocator", "Preparing relocs (size=%ld)\n", + (unsigned long) rel->relocators_size); + + if (!malloc_in_range (rel, 0, ~(grub_addr_t)0 - rel->relocators_size + 1, + grub_relocator_align, + rel->relocators_size, &movers_chunk, 1, 1)) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + movers_chunk.srcv = rels = rels0 + = grub_map_memory (movers_chunk.src, movers_chunk.size); + + if (relsize) + *relsize = rel->relocators_size; + + grub_dprintf ("relocator", "Relocs allocated at %p\n", movers_chunk.srcv); + + { + unsigned i; + grub_size_t count[257]; + struct grub_relocator_chunk *from, *to, *tmp; + + grub_memset (count, 0, sizeof (count)); + + { + struct grub_relocator_chunk *chunk; + for (chunk = rel->chunks; chunk; chunk = chunk->next) + { + grub_dprintf ("relocator", "chunk %p->%p, 0x%lx\n", + (void *) chunk->src, (void *) chunk->target, + (unsigned long) chunk->size); + nchunks++; + count[(chunk->src & 0xff) + 1]++; + } + } + from = grub_malloc (nchunks * sizeof (sorted[0])); + to = grub_malloc (nchunks * sizeof (sorted[0])); + if (!from || !to) + { + grub_free (from); + grub_free (to); + return grub_errno; + } + + for (j = 0; j < 256; j++) + count[j+1] += count[j]; + + { + struct grub_relocator_chunk *chunk; + for (chunk = rel->chunks; chunk; chunk = chunk->next) + from[count[chunk->src & 0xff]++] = *chunk; + } + + for (i = 1; i < GRUB_CPU_SIZEOF_VOID_P; i++) + { + grub_memset (count, 0, sizeof (count)); + for (j = 0; j < nchunks; j++) + count[((from[j].src >> (8 * i)) & 0xff) + 1]++; + for (j = 0; j < 256; j++) + count[j+1] += count[j]; + for (j = 0; j < nchunks; j++) + to[count[(from[j].src >> (8 * i)) & 0xff]++] = from[j]; + tmp = to; + to = from; + from = tmp; + } + sorted = from; + grub_free (to); + } + + for (j = 0; j < nchunks; j++) + { + grub_dprintf ("relocator", "sorted chunk %p->%p, 0x%lx\n", + (void *) sorted[j].src, (void *) sorted[j].target, + (unsigned long) sorted[j].size); + if (sorted[j].src < sorted[j].target) + { + grub_cpu_relocator_backward ((void *) rels, + sorted[j].srcv, + grub_map_memory (sorted[j].target, + sorted[j].size), + sorted[j].size); + rels += grub_relocator_backward_size; + } + if (sorted[j].src > sorted[j].target) + { + grub_cpu_relocator_forward ((void *) rels, + sorted[j].srcv, + grub_map_memory (sorted[j].target, + sorted[j].size), + sorted[j].size); + rels += grub_relocator_forward_size; + } + if (sorted[j].src == sorted[j].target) + grub_arch_sync_caches (sorted[j].srcv, sorted[j].size); + } + grub_cpu_relocator_jumper ((void *) rels, (grub_addr_t) addr); + *relstart = rels0; + grub_free (sorted); + return GRUB_ERR_NONE; +} + +void +grub_mm_check_real (const char *file, int line) +{ + grub_mm_region_t r; + grub_mm_header_t p, pa; + + for (r = grub_mm_base; r; r = r->next) + { + pa = r->first; + p = pa->next; + if (p->magic == GRUB_MM_ALLOC_MAGIC) + continue; + do + { + if ((grub_addr_t) p < (grub_addr_t) (r + 1) + || (grub_addr_t) p >= (grub_addr_t) (r + 1) + r->size) + grub_fatal ("%s:%d: out of range pointer: %p\n", file, line, p); + if (p->magic != GRUB_MM_FREE_MAGIC) + grub_fatal ("%s:%d free magic broken at %p (0x%x)\n", file, + line, p, p->magic); + pa = p; + p = pa->next; + } + while (pa != r->first); + } +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/setjmp.S b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/setjmp.S new file mode 100644 index 0000000..617b827 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/setjmp.S @@ -0,0 +1,26 @@ +#if defined(__i386__) +#include "./i386/setjmp.S" +#elif defined(__x86_64__) +#include "./x86_64/setjmp.S" +#elif defined(__sparc__) +#include "./sparc64/setjmp.S" +#elif defined(__mips__) +#if _MIPS_SIM == _ABI64 +#include "./mips64/setjmp.S" +#else +#include "./mips/setjmp.S" +#endif +#elif defined(__powerpc__) || defined(__PPC__) +#include "./powerpc/setjmp.S" +#elif defined(__ia64__) +#include "./ia64/setjmp.S" +#include "./ia64/longjmp.S" +#elif defined(__arm__) +#include "./arm/setjmp.S" +#elif defined(__aarch64__) +#include "./arm64/setjmp.S" +#elif defined(__riscv) +#include "./riscv/setjmp.S" +#else +#error "Unknown target cpu type" +#endif diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/syslinux_parse.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/syslinux_parse.c new file mode 100644 index 0000000..8c63c7a --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/syslinux_parse.c @@ -0,0 +1,1560 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include + +struct syslinux_say +{ + struct syslinux_say *next; + struct syslinux_say *prev; + char msg[0]; +}; + +struct initrd_list +{ + struct initrd_list *next; + char *file; +}; + +struct syslinux_menuentry +{ + struct syslinux_menuentry *next; + struct syslinux_menuentry *prev; + char *label; + char *extlabel; + char *kernel_file; + struct initrd_list *initrds; + struct initrd_list *initrds_last; + char *append; + char *argument; + char *help; + char *comments; + grub_size_t commentslen; + char hotkey; + int make_default; + struct syslinux_say *say; + + enum { KERNEL_NO_KERNEL, KERNEL_LINUX, KERNEL_CHAINLOADER, + KERNEL_BIN, KERNEL_PXE, KERNEL_CHAINLOADER_BPB, + KERNEL_COM32, KERNEL_COM, KERNEL_IMG, KERNEL_CONFIG, LOCALBOOT } + entry_type; +}; + +struct syslinux_menu +{ + struct syslinux_menu *parent; + struct syslinux_menuentry *entries; + char *def; + char *comments; + char *background; + const char *root_read_directory; + const char *root_target_directory; + const char *current_read_directory; + const char *current_target_directory; + const char *filename; + grub_size_t commentslen; + unsigned long timeout; + struct syslinux_say *say; + grub_syslinux_flavour_t flavour; +}; + +struct output_buffer +{ + grub_size_t alloc; + grub_size_t ptr; + char *buf; +}; + +static grub_err_t +syslinux_parse_real (struct syslinux_menu *menu); +static grub_err_t +config_file (struct output_buffer *outbuf, + const char *root, const char *target_root, + const char *cwd, const char *target_cwd, + const char *fname, struct syslinux_menu *parent, + grub_syslinux_flavour_t flav); +static grub_err_t +print_entry (struct output_buffer *outbuf, + struct syslinux_menu *menu, + const char *str); + +static grub_err_t +ensure_space (struct output_buffer *outbuf, grub_size_t len) +{ + grub_size_t newlen; + char *newbuf; + if (len < outbuf->alloc - outbuf->ptr) + return GRUB_ERR_NONE; + newlen = (outbuf->ptr + len + 10) * 2; + newbuf = grub_realloc (outbuf->buf, newlen); + if (!newbuf) + return grub_errno; + outbuf->alloc = newlen; + outbuf->buf = newbuf; + return GRUB_ERR_NONE; +} + +static grub_err_t +print (struct output_buffer *outbuf, const char *str, grub_size_t len) +{ + grub_err_t err; + err = ensure_space (outbuf, len); + if (err) + return err; + grub_memcpy (&outbuf->buf[outbuf->ptr], str, len); + outbuf->ptr += len; + return GRUB_ERR_NONE; +} + +static grub_err_t +add_comment (struct syslinux_menu *menu, const char *comment, int nl) +{ + if (menu->entries) + { + if (menu->entries->commentslen == 0 && *comment == 0) + return GRUB_ERR_NONE; + menu->entries->comments = grub_realloc (menu->entries->comments, + menu->entries->commentslen + + 2 + grub_strlen (comment)); + if (!menu->entries->comments) + return grub_errno; + menu->entries->commentslen + += grub_stpcpy (menu->entries->comments + menu->entries->commentslen, + comment) + - (menu->entries->comments + menu->entries->commentslen); + if (nl) + menu->entries->comments[menu->entries->commentslen++] = '\n'; + menu->entries->comments[menu->entries->commentslen] = '\0'; + } + else + { + if (menu->commentslen == 0 && *comment == 0) + return GRUB_ERR_NONE; + menu->comments = grub_realloc (menu->comments, menu->commentslen + + 2 + grub_strlen (comment)); + if (!menu->comments) + return grub_errno; + menu->commentslen += grub_stpcpy (menu->comments + menu->commentslen, + comment) + - (menu->comments + menu->commentslen); + if (nl) + menu->comments[menu->commentslen++] = '\n'; + menu->comments[menu->commentslen] = '\0'; + } + return GRUB_ERR_NONE; +} + + +#define print_string(x) do { err = print (outbuf, x, sizeof (x) - 1); if (err) return err; } while (0) + +static grub_err_t +print_num (struct output_buffer *outbuf, int n) +{ + char buf[20]; + grub_snprintf (buf, sizeof (buf), "%d", n); + return print (outbuf, buf, grub_strlen (buf)); +} + +static grub_err_t +label (const char *line, struct syslinux_menu *menu) +{ + struct syslinux_menuentry *entry; + + entry = grub_malloc (sizeof (*entry)); + if (!entry) + return grub_errno; + grub_memset (entry, 0, sizeof (*entry)); + entry->label = grub_strdup (line); + if (!entry->label) + { + grub_free (entry); + return grub_errno; + } + entry->next = menu->entries; + entry->prev = NULL; + if (menu->entries) + menu->entries->prev = entry; + menu->entries = entry; + return GRUB_ERR_NONE; +} + +static grub_err_t +kernel (const char *line, struct syslinux_menu *menu) +{ + const char *end = line + grub_strlen (line); + + if (!menu->entries) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); + + menu->entries->kernel_file = grub_strdup (line); + if (!menu->entries->kernel_file) + return grub_errno; + + menu->entries->entry_type = KERNEL_LINUX; + + if (end - line >= 2 && grub_strcmp (end - 2, ".0") == 0) + menu->entries->entry_type = KERNEL_PXE; + + if (end - line >= 4 && grub_strcasecmp (end - 4, ".bin") == 0) + menu->entries->entry_type = KERNEL_BIN; + + if (end - line >= 3 && grub_strcasecmp (end - 3, ".bs") == 0) + menu->entries->entry_type = KERNEL_CHAINLOADER; + + if (end - line >= 4 && grub_strcasecmp (end - 4, ".bss") == 0) + menu->entries->entry_type = KERNEL_CHAINLOADER_BPB; + + if (end - line >= 4 && grub_strcasecmp (end - 4, ".c32") == 0) + menu->entries->entry_type = KERNEL_COM32; + + if (end - line >= 4 && grub_strcasecmp (end - 4, ".cbt") == 0) + menu->entries->entry_type = KERNEL_COM; + + if (end - line >= 4 && grub_strcasecmp (end - 4, ".com") == 0) + menu->entries->entry_type = KERNEL_COM; + + if (end - line >= 4 && grub_strcasecmp (end - 4, ".img") == 0) + menu->entries->entry_type = KERNEL_IMG; + + return GRUB_ERR_NONE; +} + +static grub_err_t +cmd_linux (const char *line, struct syslinux_menu *menu) +{ + if (!menu->entries) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); + + menu->entries->kernel_file = grub_strdup (line); + if (!menu->entries->kernel_file) + return grub_errno; + menu->entries->entry_type = KERNEL_LINUX; + + return GRUB_ERR_NONE; +} + +static grub_err_t +cmd_boot (const char *line, struct syslinux_menu *menu) +{ + if (!menu->entries) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); + + menu->entries->kernel_file = grub_strdup (line); + if (!menu->entries->kernel_file) + return grub_errno; + menu->entries->entry_type = KERNEL_CHAINLOADER; + + return GRUB_ERR_NONE; +} + +static grub_err_t +cmd_bss (const char *line, struct syslinux_menu *menu) +{ + if (!menu->entries) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); + + menu->entries->kernel_file = grub_strdup (line); + if (!menu->entries->kernel_file) + return grub_errno; + menu->entries->entry_type = KERNEL_CHAINLOADER_BPB; + + return GRUB_ERR_NONE; +} + +static grub_err_t +cmd_pxe (const char *line, struct syslinux_menu *menu) +{ + if (!menu->entries) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); + + menu->entries->kernel_file = grub_strdup (line); + if (!menu->entries->kernel_file) + return grub_errno; + menu->entries->entry_type = KERNEL_PXE; + + return GRUB_ERR_NONE; +} + +static grub_err_t +cmd_fdimage (const char *line, struct syslinux_menu *menu) +{ + if (!menu->entries) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); + + menu->entries->kernel_file = grub_strdup (line); + if (!menu->entries->kernel_file) + return grub_errno; + menu->entries->entry_type = KERNEL_IMG; + + return GRUB_ERR_NONE; +} + +static grub_err_t +cmd_comboot (const char *line, struct syslinux_menu *menu) +{ + if (!menu->entries) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); + + menu->entries->kernel_file = grub_strdup (line); + if (!menu->entries->kernel_file) + return grub_errno; + menu->entries->entry_type = KERNEL_COM; + + return GRUB_ERR_NONE; +} + +static grub_err_t +cmd_com32 (const char *line, struct syslinux_menu *menu) +{ + if (!menu->entries) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); + + menu->entries->kernel_file = grub_strdup (line); + if (!menu->entries->kernel_file) + return grub_errno; + menu->entries->entry_type = KERNEL_COM32; + + return GRUB_ERR_NONE; +} + +static grub_err_t +cmd_config (const char *line, struct syslinux_menu *menu) +{ + const char *space; + if (!menu->entries) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); + + for (space = line; *space && !grub_isspace (*space); space++); + menu->entries->kernel_file = grub_strndup (line, space - line); + if (!menu->entries->kernel_file) + return grub_errno; + for (; *space && grub_isspace (*space); space++); + if (*space) + { + menu->entries->argument = grub_strdup (space); + if (!menu->entries->argument) + return grub_errno; + } + menu->entries->entry_type = KERNEL_CONFIG; + + return GRUB_ERR_NONE; +} + +static grub_err_t +cmd_append (const char *line, struct syslinux_menu *menu) +{ + if (!menu->entries) + return GRUB_ERR_NONE; + //return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); + + menu->entries->append = grub_strdup (line); + if (!menu->entries->append) + return grub_errno; + + return GRUB_ERR_NONE; +} + +static grub_err_t +cmd_initrd (const char *line, struct syslinux_menu *menu) +{ + struct initrd_list *ninitrd; + const char *comma; + if (!menu->entries) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); + + while (*line) + { + for (comma = line; *comma && *comma != ','; comma++); + + ninitrd = grub_malloc (sizeof (*ninitrd)); + if (!ninitrd) + return grub_errno; + ninitrd->file = grub_strndup (line, comma - line); + if (!ninitrd->file) + { + grub_free (ninitrd); + return grub_errno; + } + ninitrd->next = NULL; + if (menu->entries->initrds_last) + menu->entries->initrds_last->next = ninitrd; + else + { + menu->entries->initrds_last = ninitrd; + menu->entries->initrds = ninitrd; + } + + line = comma; + while (*line == ',') + line++; + } + + return GRUB_ERR_NONE; +} + +static grub_err_t +cmd_default (const char *line, struct syslinux_menu *menu) +{ + menu->def = grub_strdup (line); + if (!menu->def) + return grub_errno; + + return GRUB_ERR_NONE; +} + +static grub_err_t +cmd_timeout (const char *line, struct syslinux_menu *menu) +{ + menu->timeout = grub_strtoul (line, NULL, 0); + return GRUB_ERR_NONE; +} + +static grub_err_t +cmd_menudefault (const char *line __attribute__ ((unused)), + struct syslinux_menu *menu) +{ + if (!menu->entries) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); + + menu->entries->make_default = 1; + return GRUB_ERR_NONE; +} + +static grub_err_t +cmd_menubackground (const char *line, + struct syslinux_menu *menu) +{ + menu->background = grub_strdup (line); + return GRUB_ERR_NONE; +} + +static grub_err_t +cmd_localboot (const char *line, + struct syslinux_menu *menu) +{ + if (!menu->entries) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); + + menu->entries->kernel_file = grub_strdup (line); + if (!menu->entries->kernel_file) + return grub_errno; + menu->entries->entry_type = LOCALBOOT; + + return GRUB_ERR_NONE; +} + +static grub_err_t +cmd_extlabel (const char *line, struct syslinux_menu *menu) +{ + const char *in; + char *out; + + if (!menu->entries) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); + + menu->entries->extlabel = grub_malloc (grub_strlen (line) + 1); + if (!menu->entries->extlabel) + return grub_errno; + in = line; + out = menu->entries->extlabel; + while (*in) + { + if (in[0] == '^' && in[1]) + { + menu->entries->hotkey = grub_tolower (in[1]); + in++; + } + *out++ = *in++; + } + *out = 0; + + return GRUB_ERR_NONE; +} + + +static grub_err_t +cmd_say (const char *line, struct syslinux_menu *menu) +{ + struct syslinux_say *nsay; + nsay = grub_malloc (sizeof (*nsay) + grub_strlen (line) + 1); + if (!nsay) + return grub_errno; + nsay->prev = NULL; + if (menu->entries) + { + nsay->next = menu->entries->say; + menu->entries->say = nsay; + } + else + { + nsay->next = menu->say; + menu->say = nsay; + } + + if (nsay->next) + nsay->next->prev = nsay; + + grub_memcpy (nsay->msg, line, grub_strlen (line) + 1); + return GRUB_ERR_NONE; +} + +static char * +get_read_filename (struct syslinux_menu *menu, + const char *filename) +{ + return grub_xasprintf ("%s/%s", + filename[0] == '/' ? menu->root_read_directory + : menu->current_read_directory, filename); +} + +static char * +get_target_filename (struct syslinux_menu *menu, + const char *filename) +{ + return grub_xasprintf ("%s/%s", + filename[0] == '/' ? menu->root_target_directory + : menu->current_target_directory, filename); +} + +static grub_err_t +syslinux_parse (const char *filename, + struct syslinux_menu *menu) +{ + const char *old_filename = menu->filename; + grub_err_t ret; + char *nf; + nf = get_read_filename (menu, filename); + if (!nf) + return grub_errno; + menu->filename = nf; + ret = syslinux_parse_real (menu); + if (ret == GRUB_ERR_FILE_NOT_FOUND + || ret == GRUB_ERR_BAD_FILENAME) + { + grub_errno = ret = GRUB_ERR_NONE; + add_comment (menu, "# File ", 0); + add_comment (menu, nf, 0); + add_comment (menu, " not found", 1); + } + grub_free (nf); + menu->filename = old_filename; + return ret; +} + +struct +{ + const char *name1; + const char *name2; + grub_err_t (*parse) (const char *line, struct syslinux_menu *menu); +} commands[] = { + /* FIXME: support tagname. */ + {"include", NULL, syslinux_parse}, + {"menu", "include", syslinux_parse}, + {"label", NULL, label}, + {"kernel", NULL, kernel}, + {"linux", NULL, cmd_linux}, + {"boot", NULL, cmd_boot}, + {"bss", NULL, cmd_bss}, + {"pxe", NULL, cmd_pxe}, + {"fdimage", NULL, cmd_fdimage}, + {"comboot", NULL, cmd_comboot}, + {"com32", NULL, cmd_com32}, + {"config", NULL, cmd_config}, + {"append", NULL, cmd_append}, + /* FIXME: ipappend not supported. */ + {"localboot", NULL, cmd_localboot}, + {"initrd", NULL, cmd_initrd}, + {"default", NULL, cmd_default}, + {"menu", "label", cmd_extlabel}, + /* FIXME: MENU LABEL not supported. */ + /* FIXME: MENU HIDDEN not supported. */ + /* FIXME: MENU SEPARATOR not supported. */ + /* FIXME: MENU INDENT not supported. */ + /* FIXME: MENU DISABLE not supported. */ + /* FIXME: MENU HIDE not supported. */ + {"menu", "default", cmd_menudefault}, + /* FIXME: MENU PASSWD not supported. */ + /* FIXME: MENU MASTER PASSWD not supported. */ + {"menu", "background", cmd_menubackground}, + /* FIXME: MENU BEGIN not supported. */ + /* FIXME: MENU GOTO not supported. */ + /* FIXME: MENU EXIT not supported. */ + /* FIXME: MENU QUIT not supported. */ + /* FIXME: MENU START not supported. */ + /* FIXME: MENU AUTOBOOT not supported. */ + /* FIXME: MENU TABMSG not supported. */ + /* FIXME: MENU NOTABMSG not supported. */ + /* FIXME: MENU PASSPROMPT not supported. */ + /* FIXME: MENU COLOR not supported. */ + /* FIXME: MENU MSGCOLOR not supported. */ + /* FIXME: MENU WIDTH not supported. */ + /* FIXME: MENU MARGIN not supported. */ + /* FIXME: MENU PASSWORDMARGIN not supported. */ + /* FIXME: MENU ROWS not supported. */ + /* FIXME: MENU TABMSGROW not supported. */ + /* FIXME: MENU CMDLINEROW not supported. */ + /* FIXME: MENU ENDROW not supported. */ + /* FIXME: MENU PASSWORDROW not supported. */ + /* FIXME: MENU TIMEOUTROW not supported. */ + /* FIXME: MENU HELPMSGROW not supported. */ + /* FIXME: MENU HELPMSGENDROW not supported. */ + /* FIXME: MENU HIDDENROW not supported. */ + /* FIXME: MENU HSHIFT not supported. */ + /* FIXME: MENU VSHIFT not supported. */ + {"timeout", NULL, cmd_timeout}, + /* FIXME: TOTALTIMEOUT not supported. */ + /* FIXME: ONTIMEOUT not supported. */ + /* FIXME: ONERROR not supported. */ + /* FIXME: SERIAL not supported. */ + /* FIXME: CONSOLE not supported. */ + /* FIXME: FONT not supported. */ + /* FIXME: KBDMAP not supported. */ + {"say", NULL, cmd_say}, + /* FIXME: DISPLAY not supported. */ + /* FIXME: F* not supported. */ + + /* Commands to control interface behaviour which aren't needed with GRUB. + If they are important in your environment please contact GRUB team. + */ + {"prompt", NULL, NULL}, + {"nocomplete", NULL, NULL}, + {"noescape", NULL, NULL}, + {"implicit", NULL, NULL}, + {"allowoptions", NULL, NULL} +}; + +static grub_err_t +helptext (const char *line, grub_file_t file, struct syslinux_menu *menu) +{ + char *help; + char *buf = NULL; + grub_size_t helplen, alloclen = 0; + + help = grub_strdup (line); + if (!help) + return grub_errno; + helplen = grub_strlen (line); + while ((grub_free (buf), buf = grub_file_getline (file))) + { + char *ptr; + grub_size_t needlen; + for (ptr = buf; *ptr && grub_isspace (*ptr); ptr++); + if (grub_strncasecmp (ptr, "endtext", sizeof ("endtext") - 1) == 0) + { + ptr += sizeof ("endtext") - 1; + for (; *ptr && (grub_isspace (*ptr) || *ptr == '\n' || *ptr == '\r'); + ptr++); + if (!*ptr) + { + menu->entries->help = help; + grub_free (buf); + return GRUB_ERR_NONE; + } + } + needlen = helplen + 1 + grub_strlen (buf); + if (alloclen < needlen) + { + alloclen = 2 * needlen; + help = grub_realloc (help, alloclen); + if (!help) + { + grub_free (buf); + return grub_errno; + } + } + helplen += grub_stpcpy (help + helplen, buf) - (help + helplen); + } + + grub_free (buf); + grub_free (help); + return grub_errno; +} + + +static grub_err_t +syslinux_parse_real (struct syslinux_menu *menu) +{ + grub_file_t file; + char *buf = NULL; + grub_err_t err = GRUB_ERR_NONE; + + file = grub_file_open (menu->filename, GRUB_FILE_TYPE_CONFIG); + if (!file) + return grub_errno; + while ((grub_free (buf), buf = grub_file_getline (file))) + { + const char *ptr1, *ptr2, *ptr3, *ptr4, *ptr5; + char *end; + unsigned i; + end = buf + grub_strlen (buf); + while (end > buf && (end[-1] == '\n' || end[-1] == '\r')) + end--; + *end = 0; + for (ptr1 = buf; *ptr1 && grub_isspace (*ptr1); ptr1++); + if (*ptr1 == '#' || *ptr1 == 0) + { + err = add_comment (menu, ptr1, 1); + if (err) + goto fail; + continue; + } + for (ptr2 = ptr1; !grub_isspace (*ptr2) && *ptr2; ptr2++); + for (ptr3 = ptr2; grub_isspace (*ptr3) && *ptr3; ptr3++); + for (ptr4 = ptr3; !grub_isspace (*ptr4) && *ptr4; ptr4++); + for (ptr5 = ptr4; grub_isspace (*ptr5) && *ptr5; ptr5++); + for (i = 0; i < ARRAY_SIZE(commands); i++) + if (grub_strlen (commands[i].name1) == (grub_size_t) (ptr2 - ptr1) + && grub_strncasecmp (commands[i].name1, ptr1, ptr2 - ptr1) == 0 + && (commands[i].name2 == NULL + || (grub_strlen (commands[i].name2) + == (grub_size_t) (ptr4 - ptr3) + && grub_strncasecmp (commands[i].name2, ptr3, ptr4 - ptr3) + == 0))) + break; + if (i == ARRAY_SIZE(commands)) + { + if (sizeof ("text") - 1 == ptr2 - ptr1 + && grub_strncasecmp ("text", ptr1, ptr2 - ptr1) == 0 + && (sizeof ("help") - 1 == ptr4 - ptr3 + && grub_strncasecmp ("help", ptr3, ptr4 - ptr3) == 0)) + { + if (helptext (ptr5, file, menu)) + return 1; + continue; + } + + add_comment (menu, " # UNSUPPORTED command '", 0); + add_comment (menu, ptr1, 0); + add_comment (menu, "'", 1); + + continue; + } + if (commands[i].parse) + { + err = commands[i].parse (commands[i].name2 + ? ptr5 : ptr3, menu); + if (err) + goto fail; + } + } + fail: + grub_file_close (file); + return err; +} + +static grub_err_t +print_escaped (struct output_buffer *outbuf, + const char *from, const char *to) +{ + const char *ptr; + grub_err_t err; + if (!to) + to = from + grub_strlen (from); + err = ensure_space (outbuf, (to - from) * 4 + 2); + if (err) + return err; + outbuf->buf[outbuf->ptr++] = '\''; + for (ptr = from; *ptr && ptr < to; ptr++) + { + if (*ptr == '\'') + { + outbuf->buf[outbuf->ptr++] = '\''; + outbuf->buf[outbuf->ptr++] = '\\'; + outbuf->buf[outbuf->ptr++] = '\''; + outbuf->buf[outbuf->ptr++] = '\''; + } + else + outbuf->buf[outbuf->ptr++] = *ptr; + } + outbuf->buf[outbuf->ptr++] = '\''; + return GRUB_ERR_NONE; +} + +static grub_err_t +print_file (struct output_buffer *outbuf, + struct syslinux_menu *menu, const char *from, const char *to) +{ + grub_err_t err; + if (!to) + to = from + grub_strlen (from); + err = print_escaped (outbuf, from[0] == '/' + ? menu->root_target_directory + : menu->current_target_directory, NULL); + if (err) + return err; + + err = print (outbuf, "/", 1); + if (err) + return err; + return print_escaped (outbuf, from, to); +} + +/* + * Makefile.am mimics this when generating tests/syslinux/ubuntu10.04_grub.cfg, + * so changes here may need to be reflected there too. + */ +static void +simplify_filename (char *str) +{ + char *iptr, *optr = str; + for (iptr = str; *iptr; iptr++) + { + if (*iptr == '/' && optr != str && optr[-1] == '/') + continue; + if (iptr[0] == '/' && iptr[1] == '.' && iptr[2] == '/') + { + iptr += 2; + continue; + } + if (iptr[0] == '/' && iptr[1] == '.' && iptr[2] == '.' + && iptr[3] == '/') + { + iptr += 3; + while (optr >= str && *optr != '/') + optr--; + if (optr < str) + { + str[0] = '/'; + optr = str; + } + optr++; + continue; + } + *optr++ = *iptr; + } + *optr = '\0'; +} + +static grub_err_t +print_config (struct output_buffer *outbuf, + struct syslinux_menu *menu, + const char *filename, const char *basedir) +{ + struct syslinux_menu *menuptr; + grub_err_t err = GRUB_ERR_NONE; + char *new_cwd = NULL; + char *new_target_cwd = NULL; + char *newname = NULL; + int depth = 0; + + new_cwd = get_read_filename (menu, basedir); + if (!new_cwd) + { + err = grub_errno; + goto out; + } + new_target_cwd = get_target_filename (menu, basedir); + if (!new_target_cwd) + { + err = grub_errno; + goto out; + } + newname = get_read_filename (menu, filename); + if (!newname) + { + err = grub_errno; + goto out; + } + simplify_filename (newname); + + print_string ("#"); + print_file (outbuf, menu, filename, NULL); + print_string (" "); + err = print (outbuf, newname, grub_strlen (newname)); + if (err) + return err; + print_string (":\n"); + + for (menuptr = menu; menuptr; menuptr = menuptr->parent, depth++) + if (grub_strcmp (menuptr->filename, newname) == 0 + || depth > 20) + break; + if (menuptr) + { + print_string (" syslinux_configfile -r "); + print_file (outbuf, menu, "/", NULL); + print_string (" -c "); + print_file (outbuf, menu, basedir, NULL); + print_string (" "); + print_file (outbuf, menu, filename, NULL); + print_string ("\n"); + } + else + { + err = config_file (outbuf, menu->root_read_directory, + menu->root_target_directory, new_cwd, new_target_cwd, + newname, menu, menu->flavour); + if (err == GRUB_ERR_FILE_NOT_FOUND + || err == GRUB_ERR_BAD_FILENAME) + { + grub_errno = err = GRUB_ERR_NONE; + print_string ("# File "); + err = print (outbuf, newname, grub_strlen (newname)); + if (err) + goto out; + print_string (" not found\n"); + } + } + + out: + grub_free (newname); + grub_free (new_cwd); + grub_free (new_target_cwd); + return err; +} + +static grub_err_t +write_entry (struct output_buffer *outbuf, + struct syslinux_menu *menu, + struct syslinux_menuentry *curentry) +{ + grub_err_t err; + if (curentry->comments) + { + err = print (outbuf, curentry->comments, + grub_strlen (curentry->comments)); + if (err) + return err; + } + { + struct syslinux_say *say; + for (say = curentry->say; say && say->next; say = say->next); + for (; say && say->prev; say = say->prev) + { + print_string ("echo "); + if (print_escaped (outbuf, say->msg, NULL)) return grub_errno; + print_string ("\n"); + } + } + + /* FIXME: support help text. */ + switch (curentry->entry_type) + { + case KERNEL_LINUX: + { + const char *ptr; + const char *initrd = NULL, *initrde= NULL; + for (ptr = curentry->append; ptr && *ptr; ptr++) + if ((ptr == curentry->append || grub_isspace (ptr[-1])) + && grub_strncasecmp (ptr, "initrd=", sizeof ("initrd=") - 1) + == 0) + break; + if (ptr && *ptr) + { + initrd = ptr + sizeof ("initrd=") - 1; + for (initrde = initrd; *initrde && !grub_isspace (*initrde); initrde++); + } + print_string (" if test x$ventoy_linux_16 = x1; then " + "linux_suffix=16; else linux_suffix= ; fi\n"); + print_string (" linux$linux_suffix "); + print_file (outbuf, menu, curentry->kernel_file, NULL); + print_string (" "); + if (curentry->append) + { + err = print (outbuf, curentry->append, grub_strlen (curentry->append)); + if (err) + return err; + } + print_string ("\n"); + if (initrd || curentry->initrds) + { + struct initrd_list *lst; + print_string (" initrd$linux_suffix "); + if (initrd) + { + print_file (outbuf, menu, initrd, initrde); + print_string (" "); + } + for (lst = curentry->initrds; lst; lst = lst->next) + { + print_file (outbuf, menu, lst->file, NULL); + print_string (" "); + } + + print_string ("\n"); + } + print_string ("boot\n"); + } + break; + case KERNEL_CHAINLOADER: + print_string (" chainloader "); + print_file (outbuf, menu, curentry->kernel_file, NULL); + print_string ("\n"); + break; + case KERNEL_CHAINLOADER_BPB: + print_string (" chainloader --bpb "); + print_file (outbuf, menu, curentry->kernel_file, NULL); + print_string ("\n"); + break; + case LOCALBOOT: + /* FIXME: support -1. */ + /* FIXME: PXELINUX. */ + { + int n = grub_strtol (curentry->kernel_file, NULL, 0); + if (n >= 0 && n <= 0x02) + { + print_string (" root=fd"); + if (print_num (outbuf, n)) + return grub_errno; + print_string (";\n chainloader +1;\n"); + + break; + } + if (n >= 0x80 && n < 0x8a) + { + print_string (" root=hd"); + if (print_num (outbuf, n - 0x80)) + return grub_errno; + print_string (";\n chainloader +1;\n"); + break; + } + print_string (" # UNSUPPORTED localboot type "); + print_string ("\ntrue;\n"); + if (print_num (outbuf, n)) + return grub_errno; + print_string ("\n"); + break; + } + case KERNEL_COM32: + case KERNEL_COM: + { + char *basename = NULL; + + { + char *ptr; + for (ptr = curentry->kernel_file; *ptr; ptr++) + if (*ptr == '/' || *ptr == '\\') + basename = ptr; + } + if (!basename) + basename = curentry->kernel_file; + else + basename++; + if (grub_strcasecmp (basename, "chain.c32") == 0) + { + char *file = NULL; + int is_fd = -1, devn = 0; + int part = -1; + int swap = 0; + char *ptr; + for (ptr = curentry->append; *ptr; ) + { + while (grub_isspace (*ptr)) + ptr++; + /* FIXME: support mbr: and boot. */ + if (ptr[0] == 'h' && ptr[1] == 'd') + { + is_fd = 0; + devn = grub_strtoul (ptr + 2, &ptr, 0); + continue; + } + if (grub_strncasecmp (ptr, "file=", 5) == 0) + { + file = ptr + 5; + for (ptr = file; *ptr && !grub_isspace (*ptr); ptr++); + if (*ptr) + { + *ptr = 0; + ptr++; + } + continue; + } + if (grub_strncasecmp (ptr, "swap", sizeof ("swap") - 1) == 0) + { + swap = 1; + ptr += sizeof ("swap") - 1; + continue; + } + + if (ptr[0] == 'f' && ptr[1] == 'd') + { + is_fd = 1; + devn = grub_strtoul (ptr + 2, &ptr, 0); + continue; + } + if (grub_isdigit (ptr[0])) + { + part = grub_strtoul (ptr, &ptr, 0); + continue; + } + /* FIXME: isolinux, ntldr, cmldr, *dos, seg, hide + FIXME: sethidden. */ + print_string (" # UNSUPPORTED option "); + if (print (outbuf, ptr, grub_strlen (ptr))) + return 0; + print_string ("\n"); + break; + } + if (is_fd == -1) + { + print_string (" # no drive specified\n"); + break; + } + if (!*ptr) + { + print_string (is_fd ? " root=fd": " root=hd"); + if (print_num (outbuf, devn)) + return grub_errno; + if (part != -1) + { + print_string (","); + if (print_num (outbuf, part + 1)) + return grub_errno; + } + print_string (";\n"); + if (file) + { + print_string (" chainloader "); + print_file (outbuf, menu, file, NULL); + print_string (";\n"); + } + else + print_string (" chainloader +1;\n"); + if (swap) + print_string (" drivemap -s hd0 \"root\";\n"); + } + break; + } + + if (grub_strcasecmp (basename, "mboot.c32") == 0) + { + char *ptr; + int first = 1; + int is_kernel = 1; + for (ptr = curentry->append; *ptr; ) + { + char *ptrr = ptr; + while (*ptr && !grub_isspace (*ptr)) + ptr++; + if (ptrr + 2 == ptr && ptrr[0] == '-' && ptrr[1] == '-') + { + print_string ("\n"); + first = 1; + continue; + } + if (first) + { + if (is_kernel) + print_string (" multiboot "); + else + print_string (" module "); + first = 0; + is_kernel = 0; + if (print_file (outbuf, menu, ptrr, ptr)) + return grub_errno; + continue; + } + if (print_escaped (outbuf, ptrr, ptr)) + return grub_errno; + } + break; + } + + if (grub_strcasecmp (basename, "ifcpu64.c32") == 0) + { + char *lm, *lme, *pae = 0, *paee = 0, *i386s = 0, *i386e = 0; + char *ptr; + ptr = curentry->append; + while (grub_isspace (*ptr)) + ptr++; + lm = ptr; + while (*ptr && !grub_isspace (*ptr)) + ptr++; + lme = ptr; + while (grub_isspace (*ptr)) + ptr++; + if (ptr[0] == '-' && ptr[1] == '-') + { + ptr += 2; + while (grub_isspace (*ptr)) + ptr++; + pae = ptr; + while (*ptr && !grub_isspace (*ptr)) + ptr++; + paee = ptr; + } + while (grub_isspace (*ptr)) + ptr++; + if (ptr[0] == '-' && ptr[1] == '-') + { + ptr += 2; + while (grub_isspace (*ptr)) + ptr++; + i386s = ptr; + while (*ptr && !grub_isspace (*ptr)) + ptr++; + i386e = ptr; + } + *lme = '\0'; + if (paee) + *paee = '\0'; + if (i386e) + *i386e = '\0'; + if (!i386s) + { + i386s = pae; + pae = 0; + } + print_string ("if cpuid --long-mode; then true;\n"); + if (print_entry (outbuf, menu, lm)) + return grub_errno; + if (pae) + { + print_string ("elif cpuid --pae; then true;\n"); + if (print_entry (outbuf, menu, pae)) + return grub_errno; + } + print_string ("else\n"); + if (print_entry (outbuf, menu, i386s)) + return grub_errno; + print_string ("fi\n"); + break; + } + + if (grub_strcasecmp (basename, "reboot.c32") == 0) + { + print_string (" reboot\n"); + break; + } + + if (grub_strcasecmp (basename, "poweroff.com") == 0) + { + print_string (" halt\n"); + break; + } + + if (grub_strcasecmp (basename, "whichsys.c32") == 0) + { + grub_syslinux_flavour_t flavour = GRUB_SYSLINUX_ISOLINUX; + const char *flav[] = + { + [GRUB_SYSLINUX_ISOLINUX] = "iso", + [GRUB_SYSLINUX_PXELINUX] = "pxe", + [GRUB_SYSLINUX_SYSLINUX] = "sys" + }; + char *ptr; + for (ptr = curentry->append; *ptr; ) + { + char *bptr, c; + while (grub_isspace (*ptr)) + ptr++; + if (grub_strncasecmp (ptr, "-iso-", 5) == 0) + { + ptr += sizeof ("-iso-") - 1; + flavour = GRUB_SYSLINUX_ISOLINUX; + continue; + } + if (grub_strncasecmp (ptr, "-pxe-", 5) == 0) + { + ptr += sizeof ("-pxe-") - 1; + flavour = GRUB_SYSLINUX_PXELINUX; + continue; + } + if (grub_strncasecmp (ptr, "-sys-", 5) == 0) + { + ptr += sizeof ("-sys-") - 1; + flavour = GRUB_SYSLINUX_SYSLINUX; + continue; + } + bptr = ptr; + while (*ptr && !grub_isspace (*ptr)) + ptr++; + c = *ptr; + *ptr = '\0'; + if (menu->flavour == GRUB_SYSLINUX_UNKNOWN + && flavour == GRUB_SYSLINUX_ISOLINUX) + { + print_string ("if [ x$syslinux_flavour = xiso -o x$syslinux_flavour = x ]; then true;\n"); + menu->flavour = GRUB_SYSLINUX_ISOLINUX; + print_entry (outbuf, menu, bptr); + menu->flavour = GRUB_SYSLINUX_UNKNOWN; + print_string ("fi\n"); + } + else if (menu->flavour == GRUB_SYSLINUX_UNKNOWN) + { + print_string ("if [ x$syslinux_flavour = x"); + err = print (outbuf, flav[flavour], grub_strlen (flav[flavour])); + if (err) + return err; + print_string (" ]; then true;\n"); + menu->flavour = flavour; + print_entry (outbuf, menu, bptr); + menu->flavour = GRUB_SYSLINUX_UNKNOWN; + print_string ("fi\n"); + } + if (menu->flavour != GRUB_SYSLINUX_UNKNOWN + && menu->flavour == flavour) + print_entry (outbuf, menu, bptr); + *ptr = c; + } + break; + } + + if (grub_strcasecmp (basename, "menu.c32") == 0 || + grub_strcasecmp (basename, "vesamenu.c32") == 0) + { + char *ptr; + char *end; + + ptr = curentry->append; + if (!ptr) + return grub_errno; + + while (*ptr) + { + end = ptr; + for (end = ptr; *end && !grub_isspace (*end); end++); + if (*end) + *end++ = '\0'; + + /* "~" is supposed to be current file, so let's skip it */ + if (grub_strcmp (ptr, "~") != 0) + { + err = print_config (outbuf, menu, ptr, ""); + if (err != GRUB_ERR_NONE) + break; + } + for (ptr = end; *ptr && grub_isspace (*ptr); ptr++); + } + err = GRUB_ERR_NONE; + break; + } + + /* FIXME: gdb, GFXBoot, Hdt, Ifcpu, Ifplop, Kbdmap, + FIXME: Linux, Lua, Meminfo, rosh, Sanbboot */ + + print_string (" # UNSUPPORTED com(32) "); + err = print (outbuf, basename, grub_strlen (basename)); + if (err) + return err; + print_string ("\ntrue;\n"); + break; + } + case KERNEL_CONFIG: + { + const char *ap; + ap = curentry->append; + if (!ap) + ap = curentry->argument; + if (!ap) + ap = ""; + print_config (outbuf, menu, curentry->kernel_file, ap); + } + break; + case KERNEL_NO_KERNEL: + /* FIXME: support this. */ + case KERNEL_BIN: + case KERNEL_PXE: + case KERNEL_IMG: + print_string (" # UNSUPPORTED entry type "); + if (print_num (outbuf, curentry->entry_type)) + return grub_errno; + print_string ("\ntrue;\n"); + break; + } + return GRUB_ERR_NONE; +} + +static grub_err_t +print_entry (struct output_buffer *outbuf, + struct syslinux_menu *menu, + const char *str) +{ + struct syslinux_menuentry *curentry; + for (curentry = menu->entries; curentry; curentry = curentry->next) + if (grub_strcasecmp (curentry->label, str) == 0) + { + grub_err_t err; + err = write_entry (outbuf, menu, curentry); + if (err) + return err; + } + return GRUB_ERR_NONE; +} + +static void +free_menu (struct syslinux_menu *menu) +{ + struct syslinux_say *say, *nsay; + struct syslinux_menuentry *entry, *nentry; + + grub_free (menu->def); + grub_free (menu->comments); + grub_free (menu->background); + for (say = menu->say; say ; say = nsay) + { + nsay = say->next; + grub_free (say); + } + + for (entry = menu->entries; entry ; entry = nentry) + { + nentry = entry->next; + struct initrd_list *initrd, *ninitrd; + + for (initrd = entry->initrds; initrd ; initrd = ninitrd) + { + ninitrd = initrd->next; + grub_free (initrd->file); + grub_free (initrd); + } + + grub_free (entry->comments); + grub_free (entry->kernel_file); + grub_free (entry->label); + grub_free (entry->extlabel); + grub_free (entry->append); + grub_free (entry->help); + grub_free (entry); + } +} + +static grub_err_t +config_file (struct output_buffer *outbuf, + const char *root, const char *target_root, + const char *cwd, const char *target_cwd, + const char *fname, struct syslinux_menu *parent, + grub_syslinux_flavour_t flav) +{ + const char *data; + grub_err_t err; + struct syslinux_menu menu; + struct syslinux_menuentry *curentry, *lentry; + struct syslinux_say *say; + + grub_memset (&menu, 0, sizeof (menu)); + menu.flavour = flav; + menu.root_read_directory = root; + menu.root_target_directory = target_root; + menu.current_read_directory = cwd; + menu.current_target_directory = target_cwd; + + menu.filename = fname; + menu.parent = parent; + + data = grub_env_get("vtdebug_flag"); + if (data && data[0]) + { + menu.timeout = 100; + } + + err = syslinux_parse_real (&menu); + if (err) + return err; + + for (say = menu.say; say && say->next; say = say->next); + for (; say && say->prev; say = say->prev) + { + print_string ("echo "); + err = print_escaped (outbuf, say->msg, NULL); + if (err) + return err; + print_string ("\n"); + } + + if (menu.background) + { + print_string (" background_image "); + err = print_file (outbuf, &menu, menu.background, NULL); + if (err) + return err; + print_string ("\n"); + } + + if (menu.comments) + { + err = print (outbuf, menu.comments, grub_strlen (menu.comments)); + if (err) + return err; + } + + if (menu.timeout == 0 && menu.entries && menu.def) + { + err = print_entry (outbuf, &menu, menu.def); + if (err) + return err; + } + else if (menu.entries) + { + for (curentry = menu.entries; curentry->next; curentry = curentry->next); + lentry = curentry; + + print_string ("set timeout="); + err = print_num (outbuf, (menu.timeout + 9) / 10); + if (err) + return err; + print_string ("\n"); + + if (menu.def) + { + print_string (" default="); + err = print_escaped (outbuf, menu.def, NULL); + if (err) + return err; + print_string ("\n"); + } + for (curentry = lentry; curentry; curentry = curentry->prev) + { + print_string ("menuentry "); + err = print_escaped (outbuf, + curentry->extlabel ? : curentry->label, NULL); + if (err) + return err; + if (curentry->hotkey) + { + char hk[] = { curentry->hotkey, '\0' }; + print_string (" --hotkey '"); + print_string (hk); + print_string ("'"); + } + print_string (" --id "); + err = print_escaped (outbuf, curentry->label, NULL); + if (err) + return err; + print_string (" {\n"); + + err = write_entry (outbuf, &menu, curentry); + if (err) + return err; + + print_string ("}\n"); + } + } + free_menu (&menu); + return GRUB_ERR_NONE; +} + +char * +grub_syslinux_config_file (const char *base, const char *target_base, + const char *cwd, const char *target_cwd, + const char *fname, grub_syslinux_flavour_t flav) +{ + struct output_buffer outbuf = { 0, 0, 0 }; + grub_err_t err; + err = config_file (&outbuf, base, target_base, cwd, target_cwd, + fname, NULL, flav); + if (err) + return NULL; + err = print (&outbuf, "\0", 1); + if (err) + return NULL; + return outbuf.buf; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/loader/arm64/linux.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/loader/arm64/linux.c new file mode 100644 index 0000000..f2c40d0 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/loader/arm64/linux.c @@ -0,0 +1,859 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +static grub_dl_t my_mod; +static int loaded; + +static void *kernel_addr; +static grub_uint64_t kernel_size; + +static char *linux_args; +static grub_uint32_t cmdline_size; + +static grub_addr_t initrd_start; +static grub_addr_t initrd_end; + +#define LINUX_MAX_ARGC 1024 +static int ventoy_debug = 0; +static int ventoy_initrd_called = 0; +static int ventoy_linux_argc = 0; +static char **ventoy_linux_args = NULL; +static int ventoy_extra_initrd_num = 0; +static char *ventoy_extra_initrd_list[256]; +static grub_err_t +grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]); + +grub_err_t +grub_arch_efi_linux_check_image (struct linux_arch_kernel_header * lh) +{ + if (lh->magic != GRUB_LINUX_ARMXX_MAGIC_SIGNATURE) + return grub_error(GRUB_ERR_BAD_OS, "invalid magic number"); + + if ((lh->code0 & 0xffff) != GRUB_PE32_MAGIC) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + N_("plain image kernel not supported - rebuild with CONFIG_(U)EFI_STUB enabled")); + + grub_dprintf ("linux", "UEFI stub kernel:\n"); + grub_dprintf ("linux", "PE/COFF header @ %08x\n", lh->hdr_offset); + + return GRUB_ERR_NONE; +} + +static grub_err_t +finalize_params_linux (void) +{ + int node, retval; + + void *fdt; + + fdt = grub_fdt_load (GRUB_EFI_LINUX_FDT_EXTRA_SPACE); + + if (!fdt) + goto failure; + + node = grub_fdt_find_subnode (fdt, 0, "chosen"); + if (node < 0) + node = grub_fdt_add_subnode (fdt, 0, "chosen"); + + if (node < 1) + goto failure; + + /* Set initrd info */ + if (initrd_start && initrd_end > initrd_start) + { + grub_dprintf ("linux", "Initrd @ %p-%p\n", + (void *) initrd_start, (void *) initrd_end); + + retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-start", + initrd_start); + if (retval) + goto failure; + retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-end", + initrd_end); + if (retval) + goto failure; + } + + if (grub_fdt_install() != GRUB_ERR_NONE) + goto failure; + + return GRUB_ERR_NONE; + +failure: + grub_fdt_unload(); + return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT"); +} + +grub_err_t +grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args) +{ + grub_efi_memory_mapped_device_path_t *mempath; + grub_efi_handle_t image_handle; + grub_efi_boot_services_t *b; + grub_efi_status_t status; + grub_efi_loaded_image_t *loaded_image; + int len; + + mempath = grub_malloc (2 * sizeof (grub_efi_memory_mapped_device_path_t)); + if (!mempath) + return grub_errno; + + mempath[0].header.type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE; + mempath[0].header.subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE; + mempath[0].header.length = grub_cpu_to_le16_compile_time (sizeof (*mempath)); + mempath[0].memory_type = GRUB_EFI_LOADER_DATA; + mempath[0].start_address = addr; + mempath[0].end_address = addr + size; + + mempath[1].header.type = GRUB_EFI_END_DEVICE_PATH_TYPE; + mempath[1].header.subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; + mempath[1].header.length = sizeof (grub_efi_device_path_t); + + b = grub_efi_system_table->boot_services; + status = b->load_image (0, grub_efi_image_handle, + (grub_efi_device_path_t *) mempath, + (void *) addr, size, &image_handle); + if (status != GRUB_EFI_SUCCESS) + return grub_error (GRUB_ERR_BAD_OS, "cannot load image"); + + grub_dprintf ("linux", "linux command line: '%s'\n", args); + + /* Convert command line to UCS-2 */ + loaded_image = grub_efi_get_loaded_image (image_handle); + loaded_image->load_options_size = len = + (grub_strlen (args) + 1) * sizeof (grub_efi_char16_t); + loaded_image->load_options = + grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size)); + if (!loaded_image->load_options) + return grub_errno; + + loaded_image->load_options_size = + 2 * grub_utf8_to_utf16 (loaded_image->load_options, len, + (grub_uint8_t *) args, len, NULL); + + grub_dprintf ("linux", "starting image %p\n", image_handle); + status = b->start_image (image_handle, 0, NULL); + + /* When successful, not reached */ + b->unload_image (image_handle); + grub_efi_free_pages ((grub_addr_t) loaded_image->load_options, + GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size)); + + return grub_errno; +} + + +static void ventoy_debug_pause(void) +{ + char key; + + if (0 == ventoy_debug) + { + return; + } + + grub_printf("press Enter to continue ......\n"); + while (1) + { + key = grub_getkey(); + if (key == '\n' || key == '\r') + { + break; + } + } +} + +static int ventoy_preboot(void) +{ + int i; + const char *file; + char buf[128]; + + if (ventoy_debug) + { + grub_printf("ventoy_preboot %d %d\n", ventoy_linux_argc, ventoy_initrd_called); + ventoy_debug_pause(); + } + + if (ventoy_linux_argc == 0) + { + return 0; + } + + if (ventoy_initrd_called) + { + ventoy_initrd_called = 0; + return 0; + } + + grub_snprintf(buf, sizeof(buf), "mem:%s:size:%s", grub_env_get("ventoy_cpio_addr"), grub_env_get("ventoy_cpio_size")); + + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(buf); + + file = grub_env_get("vtoy_img_part_file"); + if (file) + { + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(file); + } + + if (ventoy_debug) + { + grub_printf("========== initrd list ==========\n"); + for (i = 0; i < ventoy_extra_initrd_num; i++) + { + grub_printf("%s\n", ventoy_extra_initrd_list[i]); + } + grub_printf("=================================\n"); + + ventoy_debug_pause(); + } + + grub_cmd_initrd(NULL, ventoy_extra_initrd_num, ventoy_extra_initrd_list); + + return 0; +} + +static int ventoy_boot_opt_filter(char *opt) +{ + if (grub_strcmp(opt, "noinitrd") == 0) + { + return 1; + } + + if (grub_strcmp(opt, "vga=current") == 0) + { + return 1; + } + + if (grub_strncmp(opt, "rdinit=", 7) == 0) + { + if (grub_strcmp(opt, "rdinit=/vtoy/vtoy") != 0) + { + opt[0] = 'v'; + opt[1] = 't'; + } + return 0; + } + + if (grub_strncmp(opt, "init=", 5) == 0) + { + opt[0] = 'v'; + opt[1] = 't'; + return 0; + } + + if (grub_strncmp(opt, "dm=", 3) == 0) + { + opt[0] = 'D'; + opt[1] = 'M'; + return 0; + } + + if (ventoy_debug) + { + if (grub_strcmp(opt, "quiet") == 0) + { + return 1; + } + + if (grub_strncmp(opt, "loglevel=", 9) == 0) + { + return 1; + } + + if (grub_strcmp(opt, "splash") == 0) + { + return 1; + } + } + + return 0; +} + +static int ventoy_bootopt_hook(int argc, char *argv[]) +{ + int i; + int TmpIdx; + int count = 0; + const char *env; + char c; + char *newenv; + char *last, *pos; + + //grub_printf("ventoy_bootopt_hook: %d %d\n", argc, ventoy_linux_argc); + + if (ventoy_linux_argc == 0) + { + return 0; + } + + /* To avoid --- parameter, we split two parts */ + for (TmpIdx = 0; TmpIdx < argc; TmpIdx++) + { + if (ventoy_boot_opt_filter(argv[TmpIdx])) + { + continue; + } + + if (grub_strncmp(argv[TmpIdx], "--", 2) == 0) + { + break; + } + + ventoy_linux_args[count++] = grub_strdup(argv[TmpIdx]); + } + + for (i = 0; i < ventoy_linux_argc; i++) + { + ventoy_linux_args[count] = ventoy_linux_args[i + (LINUX_MAX_ARGC / 2)]; + ventoy_linux_args[i + (LINUX_MAX_ARGC / 2)] = NULL; + + if (ventoy_linux_args[count][0] == '@') + { + env = grub_env_get(ventoy_linux_args[count] + 1); + if (env) + { + grub_free(ventoy_linux_args[count]); + + newenv = grub_strdup(env); + last = newenv; + + while (*last) + { + while (*last) + { + if (*last != ' ' && *last != '\t') + { + break; + } + last++; + } + + if (*last == 0) + { + break; + } + + for (pos = last; *pos; pos++) + { + if (*pos == ' ' || *pos == '\t') + { + c = *pos; + *pos = 0; + if (0 == ventoy_boot_opt_filter(last)) + { + ventoy_linux_args[count++] = grub_strdup(last); + } + *pos = c; + break; + } + } + + if (*pos == 0) + { + if (0 == ventoy_boot_opt_filter(last)) + { + ventoy_linux_args[count++] = grub_strdup(last); + } + break; + } + + last = pos + 1; + } + } + else + { + count++; + } + } + else + { + count++; + } + } + + while (TmpIdx < argc) + { + if (ventoy_boot_opt_filter(argv[TmpIdx])) + { + continue; + } + + ventoy_linux_args[count++] = grub_strdup(argv[TmpIdx]); + TmpIdx++; + } + + if (ventoy_debug) + { + ventoy_linux_args[count++] = grub_strdup("loglevel=7"); + } + + ventoy_linux_argc = count; + + if (ventoy_debug) + { + grub_printf("========== bootoption ==========\n"); + for (i = 0; i < count; i++) + { + grub_printf("%s ", ventoy_linux_args[i]); + } + grub_printf("\n================================\n"); + } + + return 0; +} + +static grub_err_t +grub_cmd_set_boot_opt (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int i; + const char *vtdebug; + + for (i = 0; i < argc; i++) + { + ventoy_linux_args[ventoy_linux_argc + (LINUX_MAX_ARGC / 2) ] = grub_strdup(argv[i]); + ventoy_linux_argc++; + } + + vtdebug = grub_env_get("vtdebug_flag"); + if (vtdebug && vtdebug[0]) + { + ventoy_debug = 1; + } + + if (ventoy_debug) grub_printf("ventoy set boot opt %d\n", ventoy_linux_argc); + + return 0; +} + +static grub_err_t +grub_cmd_unset_boot_opt (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int i; + + (void)argc; + (void)argv; + + for (i = 0; i < LINUX_MAX_ARGC; i++) + { + if (ventoy_linux_args[i]) + { + grub_free(ventoy_linux_args[i]); + } + } + + ventoy_debug = 0; + ventoy_linux_argc = 0; + ventoy_initrd_called = 0; + grub_memset(ventoy_linux_args, 0, sizeof(char *) * LINUX_MAX_ARGC); + return 0; +} + +static grub_err_t +grub_cmd_extra_initrd_append (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int newclen = 0; + char *pos = NULL; + char *end = NULL; + char buf[256] = {0}; + + if (argc != 1) + { + return 1; + } + + for (pos = argv[0]; *pos; pos++) + { + if (*pos == '/') + { + end = pos; + } + } + + if (end) + { + /* grub2 newc bug workaround */ + newclen = (int)grub_strlen(end + 1); + if ((110 + newclen) % 4 == 0) + { + grub_snprintf(buf, sizeof(buf), "newc:.%s:%s", end + 1, argv[0]); + } + else + { + grub_snprintf(buf, sizeof(buf), "newc:%s:%s", end + 1, argv[0]); + } + + if (ventoy_extra_initrd_num < 256) + { + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(buf); + } + } + + return 0; +} + +static grub_err_t +grub_cmd_extra_initrd_reset (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int i; + + (void)argc; + (void)argv; + + for (i = 0; i < ventoy_extra_initrd_num; i++) + { + if (ventoy_extra_initrd_list[i]) + { + grub_free(ventoy_extra_initrd_list[i]); + } + } + + grub_memset(ventoy_extra_initrd_list, 0, sizeof(ventoy_extra_initrd_list)); + + return 0; +} + + +static grub_err_t +grub_linux_boot (void) +{ + ventoy_preboot(); + + if (finalize_params_linux () != GRUB_ERR_NONE) + return grub_errno; + + return (grub_arch_efi_linux_boot_image((grub_addr_t)kernel_addr, + kernel_size, linux_args)); +} + +static grub_err_t +grub_linux_unload (void) +{ + grub_dl_unref (my_mod); + loaded = 0; + if (initrd_start) + grub_efi_free_pages ((grub_efi_physical_address_t) initrd_start, + GRUB_EFI_BYTES_TO_PAGES (initrd_end - initrd_start)); + initrd_start = initrd_end = 0; + grub_free (linux_args); + if (kernel_addr) + grub_efi_free_pages ((grub_addr_t) kernel_addr, + GRUB_EFI_BYTES_TO_PAGES (kernel_size)); + grub_fdt_unload (); + return GRUB_ERR_NONE; +} + +/* + * As per linux/Documentation/arm/Booting + * ARM initrd needs to be covered by kernel linear mapping, + * so place it in the first 512MB of DRAM. + * + * As per linux/Documentation/arm64/booting.txt + * ARM64 initrd needs to be contained entirely within a 1GB aligned window + * of up to 32GB of size that covers the kernel image as well. + * Since the EFI stub loader will attempt to load the kernel near start of + * RAM, place the buffer in the first 32GB of RAM. + */ +#ifdef __arm__ +#define INITRD_MAX_ADDRESS_OFFSET (512U * 1024 * 1024) +#else /* __aarch64__ */ +#define INITRD_MAX_ADDRESS_OFFSET (32ULL * 1024 * 1024 * 1024) +#endif + +/* + * This function returns a pointer to a legally allocated initrd buffer, + * or NULL if unsuccessful + */ +static void * +allocate_initrd_mem (int initrd_pages) +{ + grub_addr_t max_addr; + + if (grub_efi_get_ram_base (&max_addr) != GRUB_ERR_NONE) + return NULL; + + max_addr += INITRD_MAX_ADDRESS_OFFSET - 1; + + return grub_efi_allocate_pages_real (max_addr, initrd_pages, + GRUB_EFI_ALLOCATE_MAX_ADDRESS, + GRUB_EFI_LOADER_DATA); +} + +static grub_err_t +grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 }; + int initrd_size, initrd_pages; + void *initrd_mem = NULL; + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + goto fail; + } + + if (!loaded) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("you need to load the kernel first")); + goto fail; + } + + if (grub_initrd_init (argc, argv, &initrd_ctx)) + goto fail; + + initrd_size = grub_get_initrd_size (&initrd_ctx); + grub_dprintf ("linux", "Loading initrd\n"); + + initrd_pages = (GRUB_EFI_BYTES_TO_PAGES (initrd_size)); + initrd_mem = allocate_initrd_mem (initrd_pages); + + if (!initrd_mem) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + goto fail; + } + + if (grub_initrd_load (&initrd_ctx, argv, initrd_mem)) + goto fail; + + initrd_start = (grub_addr_t) initrd_mem; + initrd_end = initrd_start + initrd_size; + grub_dprintf ("linux", "[addr=%p, size=0x%x]\n", + (void *) initrd_start, initrd_size); + + fail: + grub_initrd_close (&initrd_ctx); + if (initrd_mem && !initrd_start) + grub_efi_free_pages ((grub_addr_t) initrd_mem, initrd_pages); + + return grub_errno; +} + +static grub_err_t +grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + grub_file_t file = 0; + struct linux_arch_kernel_header lh; + grub_err_t err; + + grub_dl_ref (my_mod); + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + goto fail; + } + + file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL); + if (!file) + goto fail; + + kernel_size = grub_file_size (file); + + if (grub_file_read (file, &lh, sizeof (lh)) < (long) sizeof (lh)) + return grub_errno; + + if (grub_arch_efi_linux_check_image (&lh) != GRUB_ERR_NONE) + goto fail; + + grub_loader_unset(); + + grub_dprintf ("linux", "kernel file size: %lld\n", (long long) kernel_size); + kernel_addr = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (kernel_size)); + grub_dprintf ("linux", "kernel numpages: %lld\n", + (long long) GRUB_EFI_BYTES_TO_PAGES (kernel_size)); + if (!kernel_addr) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + goto fail; + } + + grub_file_seek (file, 0); + if (grub_file_read (file, kernel_addr, kernel_size) + < (grub_int64_t) kernel_size) + { + if (!grub_errno) + grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), argv[0]); + goto fail; + } + + grub_dprintf ("linux", "kernel @ %p\n", kernel_addr); + + cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE); + linux_args = grub_malloc (cmdline_size); + if (!linux_args) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + goto fail; + } + grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE)); + + if (ventoy_linux_argc) + { + ventoy_bootopt_hook(argc, argv); + err = grub_create_loader_cmdline (ventoy_linux_argc, ventoy_linux_args, + linux_args + sizeof (LINUX_IMAGE) - 1, + cmdline_size, + GRUB_VERIFY_KERNEL_CMDLINE); } + else + { + err = grub_create_loader_cmdline (argc, argv, + linux_args + sizeof (LINUX_IMAGE) - 1, + cmdline_size, + GRUB_VERIFY_KERNEL_CMDLINE); + } + + if (err) + goto fail; + + if (grub_errno == GRUB_ERR_NONE) + { + grub_loader_set (grub_linux_boot, grub_linux_unload, 0); + loaded = 1; + } + +fail: + if (file) + grub_file_close (file); + + if (grub_errno != GRUB_ERR_NONE) + { + grub_dl_unref (my_mod); + loaded = 0; + } + + if (linux_args && !loaded) + grub_free (linux_args); + + if (kernel_addr && !loaded) + grub_efi_free_pages ((grub_addr_t) kernel_addr, + GRUB_EFI_BYTES_TO_PAGES (kernel_size)); + + return grub_errno; +} + +static grub_err_t +ventoy_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int i; + const char *file; + char buf[64]; + + if (ventoy_debug) grub_printf("ventoy_cmd_initrd %d\n", ventoy_linux_argc); + + if (ventoy_linux_argc == 0) + { + return grub_cmd_initrd(cmd, argc, argv); + } + + grub_snprintf(buf, sizeof(buf), "mem:%s:size:%s", grub_env_get("ventoy_cpio_addr"), grub_env_get("ventoy_cpio_size")); + + if (ventoy_debug) grub_printf("membuf=%s\n", buf); + + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(buf); + + file = grub_env_get("vtoy_img_part_file"); + if (file) + { + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(file); + } + + for (i = 0; i < argc; i++) + { + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(argv[i]); + } + + ventoy_initrd_called = 1; + + if (ventoy_debug) + { + grub_printf("========== initrd list ==========\n"); + for (i = 0; i < ventoy_extra_initrd_num; i++) + { + grub_printf("%s\n", ventoy_extra_initrd_list[i]); + } + grub_printf("=================================\n"); + } + + return grub_cmd_initrd(cmd, ventoy_extra_initrd_num, ventoy_extra_initrd_list); +} + + +static grub_command_t cmd_linux, cmd_initrd, cmd_linuxefi, cmd_initrdefi; +static grub_command_t cmd_set_bootopt, cmd_unset_bootopt, cmd_extra_initrd_append, cmd_extra_initrd_reset; + + +GRUB_MOD_INIT (linux) +{ + cmd_linux = grub_register_command ("linux", grub_cmd_linux, 0, + N_("Load Linux.")); + cmd_initrd = grub_register_command ("initrd", ventoy_cmd_initrd, 0, + N_("Load initrd.")); + + cmd_linuxefi = grub_register_command ("linuxefi", grub_cmd_linux, + 0, N_("Load Linux.")); + cmd_initrdefi = grub_register_command ("initrdefi", ventoy_cmd_initrd, + 0, N_("Load initrd.")); + + cmd_set_bootopt = grub_register_command ("vt_set_boot_opt", grub_cmd_set_boot_opt, 0, N_("set ext boot opt")); + cmd_unset_bootopt = grub_register_command ("vt_unset_boot_opt", grub_cmd_unset_boot_opt, 0, N_("unset ext boot opt")); + + cmd_extra_initrd_append = grub_register_command ("vt_img_extra_initrd_append", grub_cmd_extra_initrd_append, 0, N_("")); + cmd_extra_initrd_reset = grub_register_command ("vt_img_extra_initrd_reset", grub_cmd_extra_initrd_reset, 0, N_("")); + + ventoy_linux_args = grub_zalloc(sizeof(char *) * LINUX_MAX_ARGC); + + my_mod = mod; +} + +GRUB_MOD_FINI (linux) +{ + grub_unregister_command (cmd_linux); + grub_unregister_command (cmd_initrd); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/loader/efi/chainloader.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/loader/efi/chainloader.c new file mode 100644 index 0000000..4e82092 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/loader/efi/chainloader.c @@ -0,0 +1,418 @@ +/* chainloader.c - boot another boot loader */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2004,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +/* TODO: support load options. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if defined (__i386__) || defined (__x86_64__) +#include +#include +#endif + +GRUB_MOD_LICENSE ("GPLv3+"); + +static grub_dl_t my_mod; + +static grub_efi_physical_address_t address; +static grub_efi_uintn_t pages; +static grub_efi_device_path_t *file_path; +static grub_efi_handle_t image_handle; +static grub_efi_char16_t *cmdline; + +static grub_err_t +grub_chainloader_unload (void) +{ + grub_efi_boot_services_t *b; + + b = grub_efi_system_table->boot_services; + efi_call_1 (b->unload_image, image_handle); + efi_call_2 (b->free_pages, address, pages); + + grub_free (file_path); + grub_free (cmdline); + cmdline = 0; + file_path = 0; + + grub_dl_unref (my_mod); + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_chainloader_boot (void) +{ + grub_efi_boot_services_t *b; + grub_efi_status_t status; + grub_efi_uintn_t exit_data_size; + grub_efi_char16_t *exit_data = NULL; + + b = grub_efi_system_table->boot_services; + status = efi_call_3 (b->start_image, image_handle, &exit_data_size, &exit_data); + if (status != GRUB_EFI_SUCCESS) + { + if (exit_data) + { + char *buf; + + buf = grub_malloc (exit_data_size * 4 + 1); + if (buf) + { + *grub_utf16_to_utf8 ((grub_uint8_t *) buf, + exit_data, exit_data_size) = 0; + + grub_error (GRUB_ERR_BAD_OS, buf); + grub_free (buf); + } + } + else + grub_error (GRUB_ERR_BAD_OS, "unknown error"); + } + + if (exit_data) + efi_call_1 (b->free_pool, exit_data); + + grub_loader_unset (); + + return grub_errno; +} + +static void +copy_file_path (grub_efi_file_path_device_path_t *fp, + const char *str, grub_efi_uint16_t len) +{ + grub_efi_char16_t *p, *path_name; + grub_efi_uint16_t size; + + fp->header.type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE; + fp->header.subtype = GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE; + + path_name = grub_malloc (len * GRUB_MAX_UTF16_PER_UTF8 * sizeof (*path_name)); + if (!path_name) + return; + + size = grub_utf8_to_utf16 (path_name, len * GRUB_MAX_UTF16_PER_UTF8, + (const grub_uint8_t *) str, len, 0); + for (p = path_name; p < path_name + size; p++) + if (*p == '/') + *p = '\\'; + + grub_memcpy (fp->path_name, path_name, size * sizeof (*fp->path_name)); + /* File Path is NULL terminated */ + fp->path_name[size++] = '\0'; + fp->header.length = size * sizeof (grub_efi_char16_t) + sizeof (*fp); + grub_free (path_name); +} + +static grub_efi_device_path_t * +make_file_path (grub_efi_device_path_t *dp, const char *filename) +{ + char *dir_start; + char *dir_end; + grub_size_t size; + grub_efi_device_path_t *d; + + dir_start = grub_strchr (filename, ')'); + if (! dir_start) + dir_start = (char *) filename; + else + dir_start++; + + dir_end = grub_strrchr (dir_start, '/'); + if (! dir_end) + { + grub_error (GRUB_ERR_BAD_FILENAME, "invalid EFI file path"); + return 0; + } + + size = 0; + d = dp; + while (1) + { + size += GRUB_EFI_DEVICE_PATH_LENGTH (d); + if ((GRUB_EFI_END_ENTIRE_DEVICE_PATH (d))) + break; + d = GRUB_EFI_NEXT_DEVICE_PATH (d); + } + + /* File Path is NULL terminated. Allocate space for 2 extra characters */ + /* FIXME why we split path in two components? */ + file_path = grub_malloc (size + + ((grub_strlen (dir_start) + 2) + * GRUB_MAX_UTF16_PER_UTF8 + * sizeof (grub_efi_char16_t)) + + sizeof (grub_efi_file_path_device_path_t) * 2); + if (! file_path) + return 0; + + grub_memcpy (file_path, dp, size); + + /* Fill the file path for the directory. */ + d = (grub_efi_device_path_t *) ((char *) file_path + + ((char *) d - (char *) dp)); + //grub_efi_print_device_path (d); + copy_file_path ((grub_efi_file_path_device_path_t *) d, + dir_start, dir_end - dir_start); + + /* Fill the file path for the file. */ + d = GRUB_EFI_NEXT_DEVICE_PATH (d); + copy_file_path ((grub_efi_file_path_device_path_t *) d, + dir_end + 1, grub_strlen (dir_end + 1)); + + /* Fill the end of device path nodes. */ + d = GRUB_EFI_NEXT_DEVICE_PATH (d); + d->type = GRUB_EFI_END_DEVICE_PATH_TYPE; + d->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; + d->length = sizeof (*d); + + return file_path; +} + +static grub_err_t +grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + grub_file_t file = 0; + grub_ssize_t size; + grub_efi_status_t status; + grub_efi_boot_services_t *b; + grub_device_t dev = 0; + grub_efi_device_path_t *dp = 0; + grub_efi_loaded_image_t *loaded_image; + char *filename; + void *boot_image = 0; + grub_efi_handle_t dev_handle = 0; + + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + filename = argv[0]; + + grub_dl_ref (my_mod); + + /* Initialize some global variables. */ + address = 0; + image_handle = 0; + file_path = 0; + + b = grub_efi_system_table->boot_services; + + file = grub_file_open (filename, GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE); + if (! file) + goto fail; + + dev = file->device; + + if (dev->disk) + dev_handle = grub_efidisk_get_device_handle (dev->disk); + else if (dev->net && dev->net->server) + { + grub_net_network_level_address_t addr; + struct grub_net_network_level_interface *inf; + grub_net_network_level_address_t gateway; + grub_err_t err; + + err = grub_net_resolve_address (dev->net->server, &addr); + if (err) + goto fail; + + err = grub_net_route_address (addr, &gateway, &inf); + if (err) + goto fail; + + dev_handle = grub_efinet_get_device_handle (inf->card); + } + + if (dev_handle) + dp = grub_efi_get_device_path (dev_handle); + + if (dp != NULL) + { + file_path = make_file_path (dp, filename); + if (! file_path) + goto fail; + } + + //grub_printf ("file path: "); + //grub_efi_print_device_path (file_path); + + size = grub_file_size (file); + if (!size) + { + grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), + filename); + goto fail; + } + pages = (((grub_efi_uintn_t) size + ((1 << 12) - 1)) >> 12); + + status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ANY_PAGES, + GRUB_EFI_LOADER_CODE, + pages, &address); + if (status != GRUB_EFI_SUCCESS) + { + grub_dprintf ("chain", "Failed to allocate %u pages\n", + (unsigned int) pages); + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + goto fail; + } + + boot_image = (void *) ((grub_addr_t) address); + if (grub_file_read (file, boot_image, size) != size) + { + if (grub_errno == GRUB_ERR_NONE) + grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), + filename); + + goto fail; + } + +#if defined (__i386__) || defined (__x86_64__) + if (size >= (grub_ssize_t) sizeof (struct grub_macho_fat_header)) + { + struct grub_macho_fat_header *head = boot_image; + if (head->magic + == grub_cpu_to_le32_compile_time (GRUB_MACHO_FAT_EFI_MAGIC)) + { + grub_uint32_t i; + struct grub_macho_fat_arch *archs + = (struct grub_macho_fat_arch *) (head + 1); + for (i = 0; i < grub_cpu_to_le32 (head->nfat_arch); i++) + { + if (GRUB_MACHO_CPUTYPE_IS_HOST_CURRENT (archs[i].cputype)) + break; + } + if (i == grub_cpu_to_le32 (head->nfat_arch)) + { + grub_error (GRUB_ERR_BAD_OS, "no compatible arch found"); + goto fail; + } + if (grub_cpu_to_le32 (archs[i].offset) + > ~grub_cpu_to_le32 (archs[i].size) + || grub_cpu_to_le32 (archs[i].offset) + + grub_cpu_to_le32 (archs[i].size) + > (grub_size_t) size) + { + grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), + filename); + goto fail; + } + boot_image = (char *) boot_image + grub_cpu_to_le32 (archs[i].offset); + size = grub_cpu_to_le32 (archs[i].size); + } + } +#endif + + status = efi_call_6 (b->load_image, 0, grub_efi_image_handle, file_path, + boot_image, size, + &image_handle); + if (status != GRUB_EFI_SUCCESS) + { + if (status == GRUB_EFI_OUT_OF_RESOURCES) + grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of resources"); + else + grub_error (GRUB_ERR_BAD_OS, "cannot load image"); + + goto fail; + } + + /* LoadImage does not set a device handler when the image is + loaded from memory, so it is necessary to set it explicitly here. + This is a mess. */ + loaded_image = grub_efi_get_loaded_image (image_handle); + if (! loaded_image) + { + grub_error (GRUB_ERR_BAD_OS, "no loaded image available"); + goto fail; + } + loaded_image->device_handle = dev_handle; + + if (argc > 1) + { + int i, len; + grub_efi_char16_t *p16; + + for (i = 1, len = 0; i < argc; i++) + len += grub_strlen (argv[i]) + 1; + + len *= sizeof (grub_efi_char16_t); + cmdline = p16 = grub_malloc (len); + if (! cmdline) + goto fail; + + for (i = 1; i < argc; i++) + { + char *p8; + + p8 = argv[i]; + while (*p8) + *(p16++) = *(p8++); + + *(p16++) = ' '; + } + *(--p16) = 0; + + loaded_image->load_options = cmdline; + loaded_image->load_options_size = len; + } + + grub_file_close (file); + + grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0); + return 0; + + fail: + + if (file) + grub_file_close (file); + + grub_free (file_path); + + if (address) + efi_call_2 (b->free_pages, address, pages); + + grub_dl_unref (my_mod); + + return grub_errno; +} + +static grub_command_t cmd; + +GRUB_MOD_INIT(chainloader) +{ + cmd = grub_register_command ("chainloader", grub_cmd_chainloader, + 0, N_("Load another boot loader.")); + my_mod = mod; +} + +GRUB_MOD_FINI(chainloader) +{ + grub_unregister_command (cmd); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/loader/i386/linux.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/loader/i386/linux.c new file mode 100644 index 0000000..f4cf201 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/loader/i386/linux.c @@ -0,0 +1,1661 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +#ifdef GRUB_MACHINE_PCBIOS +#include +#endif + +#ifdef GRUB_MACHINE_EFI +#include +#define HAS_VGA_TEXT 0 +#define DEFAULT_VIDEO_MODE "auto" +#define ACCEPTS_PURE_TEXT 0 +#elif defined (GRUB_MACHINE_IEEE1275) +#include +#define HAS_VGA_TEXT 0 +#define DEFAULT_VIDEO_MODE "text" +#define ACCEPTS_PURE_TEXT 1 +#else +#include +#include +#define HAS_VGA_TEXT 1 +#define DEFAULT_VIDEO_MODE "text" +#define ACCEPTS_PURE_TEXT 1 +#endif + +static grub_dl_t my_mod; + +static grub_size_t linux_mem_size; +static int loaded; +static void *prot_mode_mem; +static grub_addr_t prot_mode_target; +static void *initrd_mem; +static grub_addr_t initrd_mem_target; +static grub_size_t prot_init_space; +static struct grub_relocator *relocator = NULL; +static void *efi_mmap_buf; +static grub_size_t maximal_cmdline_size; +static struct linux_kernel_params linux_params; +static char *linux_cmdline; +#ifdef GRUB_MACHINE_EFI +static grub_efi_uintn_t efi_mmap_size; +#else +static const grub_size_t efi_mmap_size = 0; +#endif + +#define LINUX_MAX_ARGC 1024 +static int ventoy_debug = 0; +static int ventoy_initrd_called = 0; +static int ventoy_linux_argc = 0; +static char **ventoy_linux_args = NULL; +static int ventoy_extra_initrd_num = 0; +static char *ventoy_extra_initrd_list[256]; +static grub_command_func_t ventoy_linux16_func = NULL; +static grub_command_func_t ventoy_initrd16_func = NULL; +static grub_err_t +grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]); + +/* FIXME */ +#if 0 +struct idt_descriptor +{ + grub_uint16_t limit; + void *base; +} GRUB_PACKED; + +static struct idt_descriptor idt_desc = + { + 0, + 0 + }; +#endif + +static inline grub_size_t +page_align (grub_size_t size) +{ + return (size + (1 << 12) - 1) & (~((1 << 12) - 1)); +} + +/* Helper for find_mmap_size. */ +static int +count_hook (grub_uint64_t addr __attribute__ ((unused)), + grub_uint64_t size __attribute__ ((unused)), + grub_memory_type_t type __attribute__ ((unused)), void *data) +{ + grub_size_t *count = data; + + (*count)++; + return 0; +} + +/* Find the optimal number of pages for the memory map. */ +static grub_size_t +find_mmap_size (void) +{ + grub_size_t count = 0, mmap_size; + + grub_mmap_iterate (count_hook, &count); + + mmap_size = count * sizeof (struct grub_e820_mmap); + + /* Increase the size a bit for safety, because GRUB allocates more on + later. */ + mmap_size += (1 << 12); + + return page_align (mmap_size); +} + +static void +free_pages (void) +{ + grub_relocator_unload (relocator); + relocator = NULL; + prot_mode_mem = initrd_mem = 0; + prot_mode_target = initrd_mem_target = 0; +} + +/* Allocate pages for the real mode code and the protected mode code + for linux as well as a memory map buffer. */ +static grub_err_t +allocate_pages (grub_size_t prot_size, grub_size_t *align, + grub_size_t min_align, int relocatable, + grub_uint64_t preferred_address) +{ + grub_err_t err; + + if (prot_size == 0) + prot_size = 1; + + prot_size = page_align (prot_size); + + /* Initialize the memory pointers with NULL for convenience. */ + free_pages (); + + relocator = grub_relocator_new (); + if (!relocator) + { + err = grub_errno; + goto fail; + } + + /* FIXME: Should request low memory from the heap when this feature is + implemented. */ + + { + grub_relocator_chunk_t ch; + if (relocatable) + { + err = grub_relocator_alloc_chunk_align (relocator, &ch, + preferred_address, + preferred_address, + prot_size, 1, + GRUB_RELOCATOR_PREFERENCE_LOW, + 1); + for (; err && *align + 1 > min_align; (*align)--) + { + grub_errno = GRUB_ERR_NONE; + err = grub_relocator_alloc_chunk_align (relocator, &ch, + 0x1000000, + 0xffffffff & ~prot_size, + prot_size, 1 << *align, + GRUB_RELOCATOR_PREFERENCE_LOW, + 1); + } + if (err) + goto fail; + } + else + err = grub_relocator_alloc_chunk_addr (relocator, &ch, + preferred_address, + prot_size); + if (err) + goto fail; + prot_mode_mem = get_virtual_current_address (ch); + prot_mode_target = get_physical_target_address (ch); + } + + grub_dprintf ("linux", "prot_mode_mem = %p, prot_mode_target = %lx, prot_size = %x\n", + prot_mode_mem, (unsigned long) prot_mode_target, + (unsigned) prot_size); + return GRUB_ERR_NONE; + + fail: + free_pages (); + return err; +} + +static grub_err_t +grub_e820_add_region (struct grub_e820_mmap *e820_map, int *e820_num, + grub_uint64_t start, grub_uint64_t size, + grub_uint32_t type) +{ + int n = *e820_num; + + if ((n > 0) && (e820_map[n - 1].addr + e820_map[n - 1].size == start) && + (e820_map[n - 1].type == type)) + e820_map[n - 1].size += size; + else + { + e820_map[n].addr = start; + e820_map[n].size = size; + e820_map[n].type = type; + (*e820_num)++; + } + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_linux_setup_video (struct linux_kernel_params *params) +{ + struct grub_video_mode_info mode_info; + void *framebuffer; + grub_err_t err; + grub_video_driver_id_t driver_id; + const char *gfxlfbvar = grub_env_get ("gfxpayloadforcelfb"); + + driver_id = grub_video_get_driver_id (); + + if (driver_id == GRUB_VIDEO_DRIVER_NONE) + return 1; + + err = grub_video_get_info_and_fini (&mode_info, &framebuffer); + + if (err) + { + grub_errno = GRUB_ERR_NONE; + return 1; + } + + params->lfb_width = mode_info.width; + params->lfb_height = mode_info.height; + params->lfb_depth = mode_info.bpp; + params->lfb_line_len = mode_info.pitch; + + params->lfb_base = (grub_size_t) framebuffer; + +#if defined (GRUB_MACHINE_EFI) && defined (__x86_64__) + params->ext_lfb_base = (grub_size_t) (((grub_uint64_t)(grub_size_t) framebuffer) >> 32); + params->capabilities |= VIDEO_CAPABILITY_64BIT_BASE; +#endif + + params->lfb_size = ALIGN_UP (params->lfb_line_len * params->lfb_height, 65536); + + params->red_mask_size = mode_info.red_mask_size; + params->red_field_pos = mode_info.red_field_pos; + params->green_mask_size = mode_info.green_mask_size; + params->green_field_pos = mode_info.green_field_pos; + params->blue_mask_size = mode_info.blue_mask_size; + params->blue_field_pos = mode_info.blue_field_pos; + params->reserved_mask_size = mode_info.reserved_mask_size; + params->reserved_field_pos = mode_info.reserved_field_pos; + + if (gfxlfbvar && (gfxlfbvar[0] == '1' || gfxlfbvar[0] == 'y')) + params->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE; + else + { + switch (driver_id) + { + case GRUB_VIDEO_DRIVER_VBE: + params->lfb_size >>= 16; + params->have_vga = GRUB_VIDEO_LINUX_TYPE_VESA; + break; + + case GRUB_VIDEO_DRIVER_EFI_UGA: + case GRUB_VIDEO_DRIVER_EFI_GOP: + params->have_vga = GRUB_VIDEO_LINUX_TYPE_EFIFB; + break; + + /* FIXME: check if better id is available. */ + case GRUB_VIDEO_DRIVER_SM712: + case GRUB_VIDEO_DRIVER_SIS315PRO: + case GRUB_VIDEO_DRIVER_VGA: + case GRUB_VIDEO_DRIVER_CIRRUS: + case GRUB_VIDEO_DRIVER_BOCHS: + case GRUB_VIDEO_DRIVER_RADEON_FULOONG2E: + case GRUB_VIDEO_DRIVER_RADEON_YEELOONG3A: + case GRUB_VIDEO_DRIVER_IEEE1275: + case GRUB_VIDEO_DRIVER_COREBOOT: + /* Make gcc happy. */ + case GRUB_VIDEO_DRIVER_XEN: + case GRUB_VIDEO_DRIVER_SDL: + case GRUB_VIDEO_DRIVER_NONE: + case GRUB_VIDEO_ADAPTER_CAPTURE: + params->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE; + break; + } + } + +#ifdef GRUB_MACHINE_PCBIOS + /* VESA packed modes may come with zeroed mask sizes, which need + to be set here according to DAC Palette width. If we don't, + this results in Linux displaying a black screen. */ + if (driver_id == GRUB_VIDEO_DRIVER_VBE && mode_info.bpp <= 8) + { + struct grub_vbe_info_block controller_info; + int status; + int width = 8; + + status = grub_vbe_bios_get_controller_info (&controller_info); + + if (status == GRUB_VBE_STATUS_OK && + (controller_info.capabilities & GRUB_VBE_CAPABILITY_DACWIDTH)) + status = grub_vbe_bios_set_dac_palette_width (&width); + + if (status != GRUB_VBE_STATUS_OK) + /* 6 is default after mode reset. */ + width = 6; + + params->red_mask_size = params->green_mask_size + = params->blue_mask_size = width; + params->reserved_mask_size = 0; + } +#endif + + return GRUB_ERR_NONE; +} + +/* Context for grub_linux_boot. */ +struct grub_linux_boot_ctx +{ + grub_addr_t real_mode_target; + grub_size_t real_size; + struct linux_kernel_params *params; + int e820_num; +}; + +/* Helper for grub_linux_boot. */ +static int +grub_linux_boot_mmap_find (grub_uint64_t addr, grub_uint64_t size, + grub_memory_type_t type, void *data) +{ + struct grub_linux_boot_ctx *ctx = data; + + /* We must put real mode code in the traditional space. */ + if (type != GRUB_MEMORY_AVAILABLE || addr > 0x90000) + return 0; + + if (addr + size < 0x10000) + return 0; + + if (addr < 0x10000) + { + size += addr - 0x10000; + addr = 0x10000; + } + + if (addr + size > 0x90000) + size = 0x90000 - addr; + + if (ctx->real_size + efi_mmap_size > size) + return 0; + + grub_dprintf ("linux", "addr = %lx, size = %x, need_size = %x\n", + (unsigned long) addr, + (unsigned) size, + (unsigned) (ctx->real_size + efi_mmap_size)); + ctx->real_mode_target = ((addr + size) - (ctx->real_size + efi_mmap_size)); + return 1; +} + +/* GRUB types conveniently match E820 types. */ +static int +grub_linux_boot_mmap_fill (grub_uint64_t addr, grub_uint64_t size, + grub_memory_type_t type, void *data) +{ + struct grub_linux_boot_ctx *ctx = data; + + if (grub_e820_add_region (ctx->params->e820_map, &ctx->e820_num, + addr, size, type)) + return 1; + + return 0; +} + +static void ventoy_debug_pause(void) +{ + char key; + + if (0 == ventoy_debug) + { + return; + } + + grub_printf("press Enter to continue ......\n"); + while (1) + { + key = grub_getkey(); + if (key == '\n' || key == '\r') + { + break; + } + } +} + +static int ventoy_preboot(void) +{ + int i; + const char *file; + char buf[128]; + + if (ventoy_debug) + { + grub_printf("ventoy_preboot %d %d\n", ventoy_linux_argc, ventoy_initrd_called); + ventoy_debug_pause(); + } + + if (ventoy_linux_argc == 0) + { + return 0; + } + + if (ventoy_initrd_called) + { + ventoy_initrd_called = 0; + return 0; + } + + grub_snprintf(buf, sizeof(buf), "mem:%s:size:%s", grub_env_get("ventoy_cpio_addr"), grub_env_get("ventoy_cpio_size")); + + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(buf); + + file = grub_env_get("vtoy_img_part_file"); + if (file) + { + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(file); + } + + if (ventoy_debug) + { + grub_printf("========== initrd list ==========\n"); + for (i = 0; i < ventoy_extra_initrd_num; i++) + { + grub_printf("%s\n", ventoy_extra_initrd_list[i]); + } + grub_printf("=================================\n"); + + ventoy_debug_pause(); + } + + grub_cmd_initrd(NULL, ventoy_extra_initrd_num, ventoy_extra_initrd_list); + + return 0; +} + +static int ventoy_boot_opt_filter(char *opt) +{ + if (grub_strcmp(opt, "noinitrd") == 0) + { + return 1; + } + + if (grub_strcmp(opt, "vga=current") == 0) + { + return 1; + } + + if (grub_strncmp(opt, "rdinit=", 7) == 0) + { + if (grub_strcmp(opt, "rdinit=/vtoy/vtoy") != 0) + { + opt[0] = 'v'; + opt[1] = 't'; + } + return 0; + } + + if (grub_strncmp(opt, "init=", 5) == 0) + { + opt[0] = 'v'; + opt[1] = 't'; + return 0; + } + + if (grub_strncmp(opt, "dm=", 3) == 0) + { + opt[0] = 'D'; + opt[1] = 'M'; + return 0; + } + + if (ventoy_debug) + { + if (grub_strcmp(opt, "quiet") == 0) + { + return 1; + } + + if (grub_strncmp(opt, "loglevel=", 9) == 0) + { + return 1; + } + + if (grub_strcmp(opt, "splash") == 0) + { + return 1; + } + } + + return 0; +} + +static int ventoy_bootopt_hook(int argc, char *argv[]) +{ + int i; + int TmpIdx; + int count = 0; + const char *env; + char c; + char *newenv; + char *last, *pos; + + //grub_printf("ventoy_bootopt_hook: %d %d\n", argc, ventoy_linux_argc); + + if (ventoy_linux_argc == 0) + { + return 0; + } + + /* To avoid --- parameter, we split two parts */ + for (TmpIdx = 0; TmpIdx < argc; TmpIdx++) + { + if (ventoy_boot_opt_filter(argv[TmpIdx])) + { + continue; + } + + if (grub_strncmp(argv[TmpIdx], "--", 2) == 0) + { + break; + } + + ventoy_linux_args[count++] = grub_strdup(argv[TmpIdx]); + } + + for (i = 0; i < ventoy_linux_argc; i++) + { + ventoy_linux_args[count] = ventoy_linux_args[i + (LINUX_MAX_ARGC / 2)]; + ventoy_linux_args[i + (LINUX_MAX_ARGC / 2)] = NULL; + + if (ventoy_linux_args[count][0] == '@') + { + env = grub_env_get(ventoy_linux_args[count] + 1); + if (env) + { + grub_free(ventoy_linux_args[count]); + + newenv = grub_strdup(env); + last = newenv; + + while (*last) + { + while (*last) + { + if (*last != ' ' && *last != '\t') + { + break; + } + last++; + } + + if (*last == 0) + { + break; + } + + for (pos = last; *pos; pos++) + { + if (*pos == ' ' || *pos == '\t') + { + c = *pos; + *pos = 0; + if (0 == ventoy_boot_opt_filter(last)) + { + ventoy_linux_args[count++] = grub_strdup(last); + } + *pos = c; + break; + } + } + + if (*pos == 0) + { + if (0 == ventoy_boot_opt_filter(last)) + { + ventoy_linux_args[count++] = grub_strdup(last); + } + break; + } + + last = pos + 1; + } + } + else + { + count++; + } + } + else + { + count++; + } + } + + while (TmpIdx < argc) + { + if (ventoy_boot_opt_filter(argv[TmpIdx])) + { + continue; + } + + ventoy_linux_args[count++] = grub_strdup(argv[TmpIdx]); + TmpIdx++; + } + + if (ventoy_debug) + { + ventoy_linux_args[count++] = grub_strdup("loglevel=7"); + } + + ventoy_linux_argc = count; + + if (ventoy_debug) + { + grub_printf("========== bootoption ==========\n"); + for (i = 0; i < count; i++) + { + grub_printf("%s ", ventoy_linux_args[i]); + } + grub_printf("\n================================\n"); + } + + return 0; +} + +static grub_err_t +grub_cmd_extra_initrd_append (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int newclen = 0; + char *pos = NULL; + char *end = NULL; + char buf[256] = {0}; + + if (argc != 1) + { + return 1; + } + + for (pos = argv[0]; *pos; pos++) + { + if (*pos == '/') + { + end = pos; + } + } + + if (end) + { + /* grub2 newc bug workaround */ + newclen = (int)grub_strlen(end + 1); + if ((110 + newclen) % 4 == 0) + { + grub_snprintf(buf, sizeof(buf), "newc:.%s:%s", end + 1, argv[0]); + } + else + { + grub_snprintf(buf, sizeof(buf), "newc:%s:%s", end + 1, argv[0]); + } + + if (ventoy_extra_initrd_num < 256) + { + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(buf); + } + } + + return 0; +} + +static grub_err_t +grub_cmd_extra_initrd_reset (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int i; + + (void)argc; + (void)argv; + + for (i = 0; i < ventoy_extra_initrd_num; i++) + { + if (ventoy_extra_initrd_list[i]) + { + grub_free(ventoy_extra_initrd_list[i]); + } + } + + grub_memset(ventoy_extra_initrd_list, 0, sizeof(ventoy_extra_initrd_list)); + + return 0; +} + + +static grub_err_t +grub_linux_boot (void) +{ + grub_err_t err = 0; + const char *modevar; + char *tmp; + struct grub_relocator32_state state; + void *real_mode_mem; + struct grub_linux_boot_ctx ctx = { + .real_mode_target = 0 + }; + grub_size_t mmap_size; + grub_size_t cl_offset; + + /* To be simple, just deny to boot linux kernel when SecureBoot is enabled and Policy is check */ + if (g_sys_sb && g_sb_policy == VTOY_SB_POLICY_CHECK) + { + grub_printf("\n\n ######### Can not do linux boot in SecureBoot Policy Check #######\n\n"); + grub_refresh(); + grub_sleep(5); + grub_errno = GRUB_ERR_BAD_SIGNATURE; + return 0; + } + + ventoy_preboot(); + +#ifdef GRUB_MACHINE_IEEE1275 + { + const char *bootpath; + grub_ssize_t len; + + bootpath = grub_env_get ("root"); + if (bootpath) + grub_ieee1275_set_property (grub_ieee1275_chosen, + "bootpath", bootpath, + grub_strlen (bootpath) + 1, + &len); + linux_params.ofw_signature = GRUB_LINUX_OFW_SIGNATURE; + linux_params.ofw_num_items = 1; + linux_params.ofw_cif_handler = (grub_uint32_t) grub_ieee1275_entry_fn; + linux_params.ofw_idt = 0; + } +#endif + + modevar = grub_env_get ("gfxpayload"); + + /* Now all graphical modes are acceptable. + May change in future if we have modes without framebuffer. */ + if (modevar && *modevar != 0) + { + tmp = grub_xasprintf ("%s;" DEFAULT_VIDEO_MODE, modevar); + if (! tmp) + return grub_errno; +#if ACCEPTS_PURE_TEXT + err = grub_video_set_mode (tmp, 0, 0); +#else + err = grub_video_set_mode (tmp, GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0); +#endif + grub_free (tmp); + } + else /* We can't go back to text mode from coreboot fb. */ +#ifdef GRUB_MACHINE_COREBOOT + if (grub_video_get_driver_id () == GRUB_VIDEO_DRIVER_COREBOOT) + err = GRUB_ERR_NONE; + else +#endif + { +#if ACCEPTS_PURE_TEXT + err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0, 0); +#else + err = grub_video_set_mode (DEFAULT_VIDEO_MODE, + GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0); +#endif + } + + if (err) + { + grub_print_error (); + grub_puts_ (N_("Booting in blind mode")); + grub_errno = GRUB_ERR_NONE; + } + + if (grub_linux_setup_video (&linux_params)) + { +#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) + linux_params.have_vga = GRUB_VIDEO_LINUX_TYPE_TEXT; + linux_params.video_mode = 0x3; +#else + linux_params.have_vga = 0; + linux_params.video_mode = 0; + linux_params.video_width = 0; + linux_params.video_height = 0; +#endif + } + + +#ifndef GRUB_MACHINE_IEEE1275 + if (linux_params.have_vga == GRUB_VIDEO_LINUX_TYPE_TEXT) +#endif + { + grub_term_output_t term; + int found = 0; + FOR_ACTIVE_TERM_OUTPUTS(term) + if (grub_strcmp (term->name, "vga_text") == 0 + || grub_strcmp (term->name, "console") == 0 + || grub_strcmp (term->name, "ofconsole") == 0) + { + struct grub_term_coordinate pos = grub_term_getxy (term); + linux_params.video_cursor_x = pos.x; + linux_params.video_cursor_y = pos.y; + linux_params.video_width = grub_term_width (term); + linux_params.video_height = grub_term_height (term); + found = 1; + break; + } + if (!found) + { + linux_params.video_cursor_x = 0; + linux_params.video_cursor_y = 0; + linux_params.video_width = 80; + linux_params.video_height = 25; + } + } + +#ifdef GRUB_KERNEL_USE_RSDP_ADDR + linux_params.acpi_rsdp_addr = grub_le_to_cpu64 (grub_rsdp_addr); +#endif + + mmap_size = find_mmap_size (); + /* Make sure that each size is aligned to a page boundary. */ + cl_offset = ALIGN_UP (mmap_size + sizeof (linux_params), 4096); + if (cl_offset < ((grub_size_t) linux_params.setup_sects << GRUB_DISK_SECTOR_BITS)) + cl_offset = ALIGN_UP ((grub_size_t) (linux_params.setup_sects + << GRUB_DISK_SECTOR_BITS), 4096); + ctx.real_size = ALIGN_UP (cl_offset + maximal_cmdline_size, 4096); + +#ifdef GRUB_MACHINE_EFI + efi_mmap_size = grub_efi_find_mmap_size (); + if (efi_mmap_size == 0) + return grub_errno; +#endif + + grub_dprintf ("linux", "real_size = %x, mmap_size = %x\n", + (unsigned) ctx.real_size, (unsigned) mmap_size); + +#ifdef GRUB_MACHINE_EFI + grub_efi_mmap_iterate (grub_linux_boot_mmap_find, &ctx, 1); + if (! ctx.real_mode_target) + grub_efi_mmap_iterate (grub_linux_boot_mmap_find, &ctx, 0); +#else + grub_mmap_iterate (grub_linux_boot_mmap_find, &ctx); +#endif + grub_dprintf ("linux", "real_mode_target = %lx, real_size = %x, efi_mmap_size = %x\n", + (unsigned long) ctx.real_mode_target, + (unsigned) ctx.real_size, + (unsigned) efi_mmap_size); + + if (! ctx.real_mode_target) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode pages"); + + { + grub_relocator_chunk_t ch; + err = grub_relocator_alloc_chunk_addr (relocator, &ch, + ctx.real_mode_target, + (ctx.real_size + efi_mmap_size)); + if (err) + return err; + real_mode_mem = get_virtual_current_address (ch); + } + efi_mmap_buf = (grub_uint8_t *) real_mode_mem + ctx.real_size; + + grub_dprintf ("linux", "real_mode_mem = %p\n", + real_mode_mem); + + ctx.params = real_mode_mem; + + *ctx.params = linux_params; + ctx.params->cmd_line_ptr = ctx.real_mode_target + cl_offset; + grub_memcpy ((char *) ctx.params + cl_offset, linux_cmdline, + maximal_cmdline_size); + + grub_dprintf ("linux", "code32_start = %x\n", + (unsigned) ctx.params->code32_start); + + ctx.e820_num = 0; + if (grub_mmap_iterate (grub_linux_boot_mmap_fill, &ctx)) + return grub_errno; + ctx.params->mmap_size = ctx.e820_num; + +#ifdef GRUB_MACHINE_EFI + { + grub_efi_uintn_t efi_desc_size; + grub_size_t efi_mmap_target; + grub_efi_uint32_t efi_desc_version; + err = grub_efi_finish_boot_services (&efi_mmap_size, efi_mmap_buf, NULL, + &efi_desc_size, &efi_desc_version); + if (err) + return err; + + /* Note that no boot services are available from here. */ + efi_mmap_target = ctx.real_mode_target + + ((grub_uint8_t *) efi_mmap_buf - (grub_uint8_t *) real_mode_mem); + /* Pass EFI parameters. */ + if (grub_le_to_cpu16 (ctx.params->version) >= 0x0208) + { + ctx.params->v0208.efi_mem_desc_size = efi_desc_size; + ctx.params->v0208.efi_mem_desc_version = efi_desc_version; + ctx.params->v0208.efi_mmap = efi_mmap_target; + ctx.params->v0208.efi_mmap_size = efi_mmap_size; + +#ifdef __x86_64__ + ctx.params->v0208.efi_mmap_hi = (efi_mmap_target >> 32); +#endif + } + else if (grub_le_to_cpu16 (ctx.params->version) >= 0x0206) + { + ctx.params->v0206.efi_mem_desc_size = efi_desc_size; + ctx.params->v0206.efi_mem_desc_version = efi_desc_version; + ctx.params->v0206.efi_mmap = efi_mmap_target; + ctx.params->v0206.efi_mmap_size = efi_mmap_size; + } + else if (grub_le_to_cpu16 (ctx.params->version) >= 0x0204) + { + ctx.params->v0204.efi_mem_desc_size = efi_desc_size; + ctx.params->v0204.efi_mem_desc_version = efi_desc_version; + ctx.params->v0204.efi_mmap = efi_mmap_target; + ctx.params->v0204.efi_mmap_size = efi_mmap_size; + } + } +#endif + + /* FIXME. */ + /* asm volatile ("lidt %0" : : "m" (idt_desc)); */ + state.ebp = state.edi = state.ebx = 0; + state.esi = ctx.real_mode_target; + state.esp = ctx.real_mode_target; + state.eip = ctx.params->code32_start; + return grub_relocator32_boot (relocator, state, 0); +} + +static grub_err_t +grub_linux_unload (void) +{ + grub_dl_unref (my_mod); + loaded = 0; + grub_free (linux_cmdline); + linux_cmdline = 0; + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + grub_file_t file = 0; + struct linux_i386_kernel_header lh; + grub_uint8_t setup_sects; + grub_size_t real_size, prot_size, prot_file_size; + grub_ssize_t len; + int i; + grub_size_t align, min_align; + int relocatable; + grub_uint64_t preferred_address = GRUB_LINUX_BZIMAGE_ADDR; + + grub_dl_ref (my_mod); + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + goto fail; + } + + file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL); + if (! file) + goto fail; + + if (ventoy_linux_argc) + { + const char *tip = grub_env_get("ventoy_loading_tip"); + if (tip) + { + grub_printf("%s\n", tip); + grub_refresh(); + } + } + + if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh)) + { + if (!grub_errno) + grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), + argv[0]); + goto fail; + } + + if (lh.boot_flag != grub_cpu_to_le16_compile_time (0xaa55)) + { + grub_error (GRUB_ERR_BAD_OS, "invalid magic number"); + goto fail; + } + + if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS) + { + grub_error (GRUB_ERR_BAD_OS, "too many setup sectors"); + goto fail; + } + + /* FIXME: 2.03 is not always good enough (Linux 2.4 can be 2.03 and + still not support 32-bit boot. */ + if (lh.header != grub_cpu_to_le32_compile_time (GRUB_LINUX_I386_MAGIC_SIGNATURE) + || grub_le_to_cpu16 (lh.version) < 0x0203) + { + grub_error (GRUB_ERR_BAD_OS, "version too old for 32-bit boot" +#ifdef GRUB_MACHINE_PCBIOS + " (try with `linux16')" +#endif + ); + goto fail; + } + + if (! (lh.loadflags & GRUB_LINUX_FLAG_BIG_KERNEL)) + { + grub_error (GRUB_ERR_BAD_OS, "zImage doesn't support 32-bit boot" +#ifdef GRUB_MACHINE_PCBIOS + " (try with `linux16')" +#endif + ); + goto fail; + } + + if (grub_le_to_cpu16 (lh.version) >= 0x0206) + maximal_cmdline_size = grub_le_to_cpu32 (lh.cmdline_size) + 1; + else + maximal_cmdline_size = 256; + + if (maximal_cmdline_size < 128) + maximal_cmdline_size = 128; + + setup_sects = lh.setup_sects; + + /* If SETUP_SECTS is not set, set it to the default (4). */ + if (! setup_sects) + setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS; + + real_size = setup_sects << GRUB_DISK_SECTOR_BITS; + prot_file_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE; + + if (grub_le_to_cpu16 (lh.version) >= 0x205 + && lh.kernel_alignment != 0 + && ((lh.kernel_alignment - 1) & lh.kernel_alignment) == 0) + { + for (align = 0; align < 32; align++) + if (grub_le_to_cpu32 (lh.kernel_alignment) & (1 << align)) + break; + relocatable = grub_le_to_cpu32 (lh.relocatable); + } + else + { + align = 0; + relocatable = 0; + } + + if (grub_le_to_cpu16 (lh.version) >= 0x020a) + { + min_align = lh.min_alignment; + prot_size = grub_le_to_cpu32 (lh.init_size); + prot_init_space = page_align (prot_size); + if (relocatable) + preferred_address = grub_le_to_cpu64 (lh.pref_address); + else + preferred_address = GRUB_LINUX_BZIMAGE_ADDR; + } + else + { + min_align = align; + prot_size = prot_file_size; + preferred_address = GRUB_LINUX_BZIMAGE_ADDR; + /* Usually, the compression ratio is about 50%. */ + prot_init_space = page_align (prot_size) * 3; + } + + if (allocate_pages (prot_size, &align, + min_align, relocatable, + preferred_address)) + goto fail; + + grub_memset (&linux_params, 0, sizeof (linux_params)); + grub_memcpy (&linux_params.setup_sects, &lh.setup_sects, sizeof (lh) - 0x1F1); + + linux_params.code32_start = prot_mode_target + lh.code32_start - GRUB_LINUX_BZIMAGE_ADDR; + linux_params.kernel_alignment = (1 << align); + linux_params.ps_mouse = linux_params.padding10 = 0; + + /* + * The Linux 32-bit boot protocol defines the setup header end + * to be at 0x202 + the byte value at 0x201. + */ + len = 0x202 + *((char *) &linux_params.jump + 1); + + /* Verify the struct is big enough so we do not write past the end. */ + if (len > (char *) &linux_params.edd_mbr_sig_buffer - (char *) &linux_params) { + grub_error (GRUB_ERR_BAD_OS, "Linux setup header too big"); + goto fail; + } + + /* We've already read lh so there is no need to read it second time. */ + len -= sizeof(lh); + + if (grub_file_read (file, (char *) &linux_params + sizeof (lh), len) != len) + { + if (!grub_errno) + grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), + argv[0]); + goto fail; + } + + linux_params.type_of_loader = GRUB_LINUX_BOOT_LOADER_TYPE; + + /* These two are used (instead of cmd_line_ptr) by older versions of Linux, + and otherwise ignored. */ + linux_params.cl_magic = GRUB_LINUX_CL_MAGIC; + linux_params.cl_offset = 0x1000; + + linux_params.ramdisk_image = 0; + linux_params.ramdisk_size = 0; + + linux_params.heap_end_ptr = GRUB_LINUX_HEAP_END_OFFSET; + linux_params.loadflags |= GRUB_LINUX_FLAG_CAN_USE_HEAP; + + /* These are not needed to be precise, because Linux uses these values + only to raise an error when the decompression code cannot find good + space. */ + linux_params.ext_mem = ((32 * 0x100000) >> 10); + linux_params.alt_mem = ((32 * 0x100000) >> 10); + + /* Ignored by Linux. */ + linux_params.video_page = 0; + + /* Only used when `video_mode == 0x7', otherwise ignored. */ + linux_params.video_ega_bx = 0; + + linux_params.font_size = 16; /* XXX */ + +#ifdef GRUB_MACHINE_EFI +#ifdef __x86_64__ + if (grub_le_to_cpu16 (linux_params.version) < 0x0208 && + ((grub_addr_t) grub_efi_system_table >> 32) != 0) + return grub_error(GRUB_ERR_BAD_OS, + "kernel does not support 64-bit addressing"); +#endif + + if (grub_le_to_cpu16 (linux_params.version) >= 0x0208) + { + linux_params.v0208.efi_signature = GRUB_LINUX_EFI_SIGNATURE; + linux_params.v0208.efi_system_table = (grub_uint32_t) (grub_addr_t) grub_efi_system_table; +#ifdef __x86_64__ + linux_params.v0208.efi_system_table_hi = (grub_uint32_t) ((grub_uint64_t) grub_efi_system_table >> 32); +#endif + } + else if (grub_le_to_cpu16 (linux_params.version) >= 0x0206) + { + linux_params.v0206.efi_signature = GRUB_LINUX_EFI_SIGNATURE; + linux_params.v0206.efi_system_table = (grub_uint32_t) (grub_addr_t) grub_efi_system_table; + } + else if (grub_le_to_cpu16 (linux_params.version) >= 0x0204) + { + linux_params.v0204.efi_signature = GRUB_LINUX_EFI_SIGNATURE_0204; + linux_params.v0204.efi_system_table = (grub_uint32_t) (grub_addr_t) grub_efi_system_table; + } +#endif + + /* The other parameters are filled when booting. */ + + grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE); + + grub_dprintf ("linux", "bzImage, setup=0x%x, size=0x%x\n", + (unsigned) real_size, (unsigned) prot_size); + + /* Look for memory size and video mode specified on the command line. */ + linux_mem_size = 0; + for (i = 1; i < argc; i++) +#ifdef GRUB_MACHINE_PCBIOS + if (grub_memcmp (argv[i], "vga=", 4) == 0 && (grub_memcmp (argv[i], "vga=current", 11) != 0)) + { + /* Video mode selection support. */ + char *val = argv[i] + 4; + unsigned vid_mode = GRUB_LINUX_VID_MODE_NORMAL; + struct grub_vesa_mode_table_entry *linux_mode; + grub_err_t err; + char *buf; + + grub_dl_load ("vbe"); + + if (grub_strcmp (val, "normal") == 0) + vid_mode = GRUB_LINUX_VID_MODE_NORMAL; + else if (grub_strcmp (val, "ext") == 0) + vid_mode = GRUB_LINUX_VID_MODE_EXTENDED; + else if (grub_strcmp (val, "ask") == 0) + { + grub_puts_ (N_("Legacy `ask' parameter no longer supported.")); + + /* We usually would never do this in a loader, but "vga=ask" means user + requested interaction, so it can't hurt to request keyboard input. */ + grub_wait_after_message (); + + goto fail; + } + else + vid_mode = (grub_uint16_t) grub_strtoul (val, 0, 0); + + switch (vid_mode) + { + case 0: + case GRUB_LINUX_VID_MODE_NORMAL: + grub_env_set ("gfxpayload", "text"); + grub_printf_ (N_("%s is deprecated. " + "Use set gfxpayload=%s before " + "linux command instead.\n"), + argv[i], "text"); + break; + + case 1: + case GRUB_LINUX_VID_MODE_EXTENDED: + /* FIXME: support 80x50 text. */ + grub_env_set ("gfxpayload", "text"); + grub_printf_ (N_("%s is deprecated. " + "Use set gfxpayload=%s before " + "linux command instead.\n"), + argv[i], "text"); + break; + default: + /* Ignore invalid values. */ + if (vid_mode < GRUB_VESA_MODE_TABLE_START || + vid_mode > GRUB_VESA_MODE_TABLE_END) + { + grub_env_set ("gfxpayload", "text"); + /* TRANSLATORS: "x" has to be entered in, like an identifier, + so please don't use better Unicode codepoints. */ + grub_printf_ (N_("%s is deprecated. VGA mode %d isn't recognized. " + "Use set gfxpayload=WIDTHxHEIGHT[xDEPTH] " + "before linux command instead.\n"), + argv[i], vid_mode); + break; + } + + linux_mode = &grub_vesa_mode_table[vid_mode + - GRUB_VESA_MODE_TABLE_START]; + + buf = grub_xasprintf ("%ux%ux%u,%ux%u", + linux_mode->width, linux_mode->height, + linux_mode->depth, + linux_mode->width, linux_mode->height); + if (! buf) + goto fail; + + grub_printf_ (N_("%s is deprecated. " + "Use set gfxpayload=%s before " + "linux command instead.\n"), + argv[i], buf); + err = grub_env_set ("gfxpayload", buf); + grub_free (buf); + if (err) + goto fail; + } + } + else +#endif /* GRUB_MACHINE_PCBIOS */ + if (grub_memcmp (argv[i], "mem=", 4) == 0) + { + char *val = argv[i] + 4; + + linux_mem_size = grub_strtoul (val, &val, 0); + + if (grub_errno) + { + grub_errno = GRUB_ERR_NONE; + linux_mem_size = 0; + } + else + { + int shift = 0; + + switch (grub_tolower (val[0])) + { + case 'g': + shift += 10; + /* FALLTHROUGH */ + case 'm': + shift += 10; + /* FALLTHROUGH */ + case 'k': + shift += 10; + /* FALLTHROUGH */ + default: + break; + } + + /* Check an overflow. */ + if (linux_mem_size > (~0UL >> shift)) + linux_mem_size = 0; + else + linux_mem_size <<= shift; + } + } + else if (grub_memcmp (argv[i], "quiet", sizeof ("quiet") - 1) == 0) + { + linux_params.loadflags |= GRUB_LINUX_FLAG_QUIET; + } + + /* Create kernel command line. */ + linux_cmdline = grub_zalloc (maximal_cmdline_size + 1); + if (!linux_cmdline) + goto fail; + grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); + { + grub_err_t err; + + if (ventoy_linux_argc) + { + ventoy_bootopt_hook(argc, argv); + err = grub_create_loader_cmdline (ventoy_linux_argc, ventoy_linux_args, + linux_cmdline + + sizeof (LINUX_IMAGE) - 1, + maximal_cmdline_size + - (sizeof (LINUX_IMAGE) - 1), + GRUB_VERIFY_KERNEL_CMDLINE); + } + else + { + err = grub_create_loader_cmdline (argc, argv, + linux_cmdline + + sizeof (LINUX_IMAGE) - 1, + maximal_cmdline_size + - (sizeof (LINUX_IMAGE) - 1), + GRUB_VERIFY_KERNEL_CMDLINE); + } + + if (err) + goto fail; + } + + len = prot_file_size; + if (grub_file_read (file, prot_mode_mem, len) != len && !grub_errno) + grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), + argv[0]); + + if (grub_errno == GRUB_ERR_NONE) + { + grub_loader_set (grub_linux_boot, grub_linux_unload, + 0 /* set noreturn=0 in order to avoid grub_console_fini() */); + loaded = 1; + } + + fail: + + if (file) + grub_file_close (file); + + if (grub_errno != GRUB_ERR_NONE) + { + grub_dl_unref (my_mod); + loaded = 0; + } + + return grub_errno; +} + +static grub_err_t +grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + grub_size_t size = 0, aligned_size = 0; + grub_addr_t addr_min, addr_max; + grub_addr_t addr; + grub_err_t err; + struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 }; + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + goto fail; + } + + if (! loaded) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first")); + goto fail; + } + + if (grub_initrd_init (argc, argv, &initrd_ctx)) + goto fail; + + size = grub_get_initrd_size (&initrd_ctx); + aligned_size = ALIGN_UP (size, 4096); + + /* Get the highest address available for the initrd. */ + if (grub_le_to_cpu16 (linux_params.version) >= 0x0203) + { + addr_max = grub_cpu_to_le32 (linux_params.initrd_addr_max); + + /* XXX in reality, Linux specifies a bogus value, so + it is necessary to make sure that ADDR_MAX does not exceed + 0x3fffffff. */ + if (addr_max > GRUB_LINUX_INITRD_MAX_ADDRESS) + addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS; + } + else + addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS; + + if (linux_mem_size != 0 && linux_mem_size < addr_max) + addr_max = linux_mem_size; + + /* Linux 2.3.xx has a bug in the memory range check, so avoid + the last page. + Linux 2.2.xx has a bug in the memory range check, which is + worse than that of Linux 2.3.xx, so avoid the last 64kb. */ + addr_max -= 0x10000; + + addr_min = (grub_addr_t) prot_mode_target + prot_init_space; + + /* Put the initrd as high as possible, 4KiB aligned. */ + addr = (addr_max - aligned_size) & ~0xFFF; + + if (addr < addr_min) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, "the initrd is too big"); + goto fail; + } + + { + grub_relocator_chunk_t ch; + err = grub_relocator_alloc_chunk_align (relocator, &ch, + addr_min, addr, aligned_size, + 0x1000, + GRUB_RELOCATOR_PREFERENCE_HIGH, + 1); + if (err) + return err; + initrd_mem = get_virtual_current_address (ch); + initrd_mem_target = get_physical_target_address (ch); + } + + if (grub_initrd_load (&initrd_ctx, argv, initrd_mem)) + goto fail; + + grub_dprintf ("linux", "Initrd, addr=0x%x, size=0x%x\n", + (unsigned) addr, (unsigned) size); + + linux_params.ramdisk_image = initrd_mem_target; + linux_params.ramdisk_size = size; + linux_params.root_dev = 0x0100; /* XXX */ + + fail: + grub_initrd_close (&initrd_ctx); + + return grub_errno; +} + +static grub_err_t +ventoy_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int i; + const char *file; + char buf[64]; + + if (ventoy_debug) grub_printf("ventoy_cmd_initrd %d\n", ventoy_linux_argc); + + if (ventoy_linux_argc == 0) + { + return grub_cmd_initrd(cmd, argc, argv); + } + + grub_snprintf(buf, sizeof(buf), "mem:%s:size:%s", grub_env_get("ventoy_cpio_addr"), grub_env_get("ventoy_cpio_size")); + + if (ventoy_debug) grub_printf("membuf=%s\n", buf); + + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(buf); + + file = grub_env_get("vtoy_img_part_file"); + if (file) + { + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(file); + } + + for (i = 0; i < argc; i++) + { + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(argv[i]); + } + + ventoy_initrd_called = 1; + + if (ventoy_debug) + { + grub_printf("========== initrd list ==========\n"); + for (i = 0; i < ventoy_extra_initrd_num; i++) + { + grub_printf("%s\n", ventoy_extra_initrd_list[i]); + } + grub_printf("=================================\n"); + } + + return grub_cmd_initrd(cmd, ventoy_extra_initrd_num, ventoy_extra_initrd_list); +} + +static grub_err_t +grub_cmd_set_boot_opt (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int i; + const char *vtdebug; + grub_command_t regcmd; + + for (i = 0; i < argc; i++) + { + ventoy_linux_args[ventoy_linux_argc + (LINUX_MAX_ARGC / 2) ] = grub_strdup(argv[i]); + ventoy_linux_argc++; + } + + vtdebug = grub_env_get("vtdebug_flag"); + if (vtdebug && vtdebug[0]) + { + ventoy_debug = 1; + } + + if (ventoy_debug) grub_printf("ventoy set boot opt %d\n", ventoy_linux_argc); + + ventoy_linux16_func = ventoy_initrd16_func = NULL; + regcmd = grub_command_find("linux16"); + if (regcmd) + { + ventoy_linux16_func = regcmd->func; + regcmd->func = grub_cmd_linux; + } + + regcmd = grub_command_find("initrd16"); + if (regcmd) + { + ventoy_initrd16_func = regcmd->func; + regcmd->func = ventoy_cmd_initrd; + } + + return 0; +} + +static grub_err_t +grub_cmd_unset_boot_opt (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int i; + grub_command_t regcmd; + + (void)argc; + (void)argv; + + for (i = 0; i < LINUX_MAX_ARGC; i++) + { + if (ventoy_linux_args[i]) + { + grub_free(ventoy_linux_args[i]); + } + } + + ventoy_debug = 0; + ventoy_linux_argc = 0; + ventoy_initrd_called = 0; + grub_memset(ventoy_linux_args, 0, sizeof(char *) * LINUX_MAX_ARGC); + + if (ventoy_linux16_func) + { + regcmd = grub_command_find("linux16"); + if (regcmd) + { + regcmd->func = ventoy_linux16_func; + } + ventoy_linux16_func = NULL; + } + + if (ventoy_initrd16_func) + { + regcmd = grub_command_find("initrd16"); + if (regcmd) + { + regcmd->func = ventoy_initrd16_func; + } + ventoy_initrd16_func = NULL; + } + + return 0; +} + + +static grub_command_t cmd_linux, cmd_initrd, cmd_linuxefi, cmd_initrdefi; +static grub_command_t cmd_set_bootopt, cmd_unset_bootopt, cmd_extra_initrd_append, cmd_extra_initrd_reset; + +GRUB_MOD_INIT(linux) +{ + cmd_linux = grub_register_command ("linux", grub_cmd_linux, + 0, N_("Load Linux.")); + cmd_initrd = grub_register_command ("initrd", ventoy_cmd_initrd, + 0, N_("Load initrd.")); + + cmd_linuxefi = grub_register_command ("linuxefi", grub_cmd_linux, + 0, N_("Load Linux.")); + cmd_initrdefi = grub_register_command ("initrdefi", ventoy_cmd_initrd, + 0, N_("Load initrd.")); + cmd_set_bootopt = grub_register_command ("vt_set_boot_opt", grub_cmd_set_boot_opt, 0, N_("set ext boot opt")); + cmd_unset_bootopt = grub_register_command ("vt_unset_boot_opt", grub_cmd_unset_boot_opt, 0, N_("unset ext boot opt")); + + cmd_extra_initrd_append = grub_register_command ("vt_img_extra_initrd_append", grub_cmd_extra_initrd_append, 0, N_("")); + cmd_extra_initrd_reset = grub_register_command ("vt_img_extra_initrd_reset", grub_cmd_extra_initrd_reset, 0, N_("")); + + ventoy_linux_args = grub_zalloc(sizeof(char *) * LINUX_MAX_ARGC); + + my_mod = mod; +} + +GRUB_MOD_FINI(linux) +{ + grub_unregister_command (cmd_linux); + grub_unregister_command (cmd_initrd); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/loader/linux.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/loader/linux.c new file mode 100644 index 0000000..b23e071 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/loader/linux.c @@ -0,0 +1,327 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +struct newc_head +{ + char magic[6]; + char ino[8]; + char mode[8]; + char uid[8]; + char gid[8]; + char nlink[8]; + char mtime[8]; + char filesize[8]; + char devmajor[8]; + char devminor[8]; + char rdevmajor[8]; + char rdevminor[8]; + char namesize[8]; + char check[8]; +} GRUB_PACKED; + +struct grub_linux_initrd_component +{ + grub_file_t file; + char *newc_name; + grub_off_t size; +}; + +struct dir +{ + char *name; + struct dir *next; + struct dir *child; +}; + +static char +hex (grub_uint8_t val) +{ + if (val < 10) + return '0' + val; + return 'a' + val - 10; +} + +static void +set_field (char *var, grub_uint32_t val) +{ + int i; + char *ptr = var; + for (i = 28; i >= 0; i -= 4) + *ptr++ = hex((val >> i) & 0xf); +} + +static grub_uint8_t * +make_header (grub_uint8_t *ptr, + const char *name, grub_size_t len, + grub_uint32_t mode, + grub_off_t fsize) +{ + struct newc_head *head = (struct newc_head *) ptr; + grub_uint8_t *optr; + grub_size_t oh = 0; + grub_memcpy (head->magic, "070701", 6); + set_field (head->ino, 0); + set_field (head->mode, mode); + set_field (head->uid, 0); + set_field (head->gid, 0); + set_field (head->nlink, 1); + set_field (head->mtime, 0); + set_field (head->filesize, fsize); + set_field (head->devmajor, 0); + set_field (head->devminor, 0); + set_field (head->rdevmajor, 0); + set_field (head->rdevminor, 0); + set_field (head->namesize, len); + set_field (head->check, 0); + optr = ptr; + ptr += sizeof (struct newc_head); + grub_memcpy (ptr, name, len); + ptr += len; + oh = ALIGN_UP_OVERHEAD (ptr - optr, 4); + grub_memset (ptr, 0, oh); + ptr += oh; + return ptr; +} + +static void +free_dir (struct dir *root) +{ + if (!root) + return; + free_dir (root->next); + free_dir (root->child); + grub_free (root->name); + grub_free (root); +} + +static grub_size_t +insert_dir (const char *name, struct dir **root, + grub_uint8_t *ptr) +{ + struct dir *cur, **head = root; + const char *cb, *ce = name; + grub_size_t size = 0; + while (1) + { + for (cb = ce; *cb == '/'; cb++); + for (ce = cb; *ce && *ce != '/'; ce++); + if (!*ce) + break; + + for (cur = *root; cur; cur = cur->next) + if (grub_memcmp (cur->name, cb, ce - cb) + && cur->name[ce - cb] == 0) + break; + if (!cur) + { + struct dir *n; + n = grub_zalloc (sizeof (*n)); + if (!n) + return 0; + n->next = *head; + n->name = grub_strndup (cb, ce - cb); + if (ptr) + { + /* + * Create the substring with the trailing NUL byte + * to be included in the cpio header. + */ + char *tmp_name = grub_strndup (name, ce - name); + if (!tmp_name) { + grub_free (n->name); + grub_free (n); + return grub_errno; + } + grub_dprintf ("linux", "Creating directory %s, %s\n", name, ce); + ptr = make_header (ptr, tmp_name, ce - name + 1, + 040777, 0); + grub_free (tmp_name); + } + size += ALIGN_UP ((ce - (char *) name + 1) + + sizeof (struct newc_head), 4); + *head = n; + cur = n; + } + root = &cur->next; + } + return size; +} + +grub_err_t +grub_initrd_init (int argc, char *argv[], + struct grub_linux_initrd_context *initrd_ctx) +{ + int i; + int newc = 0; + struct dir *root = 0; + + initrd_ctx->nfiles = 0; + initrd_ctx->components = 0; + + initrd_ctx->components = grub_zalloc (argc + * sizeof (initrd_ctx->components[0])); + if (!initrd_ctx->components) + return grub_errno; + + initrd_ctx->size = 0; + + for (i = 0; i < argc; i++) + { + const char *fname = argv[i]; + + initrd_ctx->size = ALIGN_UP (initrd_ctx->size, 4); + + if (grub_memcmp (argv[i], "newc:", 5) == 0) + { + const char *ptr, *eptr; + ptr = argv[i] + 5; + while (*ptr == '/') + ptr++; + eptr = grub_strchr (ptr, ':'); + if (eptr) + { + initrd_ctx->components[i].newc_name = grub_strndup (ptr, eptr - ptr); + if (!initrd_ctx->components[i].newc_name) + { + grub_initrd_close (initrd_ctx); + return grub_errno; + } + initrd_ctx->size + += ALIGN_UP (sizeof (struct newc_head) + + grub_strlen (initrd_ctx->components[i].newc_name) + 1, + 4); + initrd_ctx->size += insert_dir (initrd_ctx->components[i].newc_name, + &root, 0); + newc = 1; + fname = eptr + 1; + } + } + else if (newc) + { + initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head) + + sizeof ("TRAILER!!!"), 4); + free_dir (root); + root = 0; + newc = 0; + } + initrd_ctx->components[i].file = grub_file_open (fname, + GRUB_FILE_TYPE_LINUX_INITRD + | GRUB_FILE_TYPE_NO_DECOMPRESS); + if (!initrd_ctx->components[i].file) + { + grub_initrd_close (initrd_ctx); + return grub_errno; + } + initrd_ctx->nfiles++; + initrd_ctx->components[i].size + = grub_file_size (initrd_ctx->components[i].file); + initrd_ctx->size += initrd_ctx->components[i].size; + } + + if (newc) + { + initrd_ctx->size = ALIGN_UP (initrd_ctx->size, 4); + initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head) + + sizeof ("TRAILER!!!"), 4); + free_dir (root); + root = 0; + } + + return GRUB_ERR_NONE; +} + +grub_size_t +grub_get_initrd_size (struct grub_linux_initrd_context *initrd_ctx) +{ + return initrd_ctx->size; +} + +void +grub_initrd_close (struct grub_linux_initrd_context *initrd_ctx) +{ + int i; + if (!initrd_ctx->components) + return; + for (i = 0; i < initrd_ctx->nfiles; i++) + { + grub_free (initrd_ctx->components[i].newc_name); + grub_file_close (initrd_ctx->components[i].file); + } + grub_free (initrd_ctx->components); + initrd_ctx->components = 0; +} + +extern int ventoy_need_prompt_load_file(void); +extern grub_ssize_t ventoy_load_file_with_prompt(grub_file_t file, void *buf, grub_ssize_t size); +grub_err_t +grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx, + char *argv[], void *target) +{ + grub_uint8_t *ptr = target; + int i; + int newc = 0; + struct dir *root = 0; + grub_ssize_t cursize = 0; + grub_ssize_t readsize = 0; + + for (i = 0; i < initrd_ctx->nfiles; i++) + { + grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); + ptr += ALIGN_UP_OVERHEAD (cursize, 4); + + if (initrd_ctx->components[i].newc_name) + { + ptr += insert_dir (initrd_ctx->components[i].newc_name, + &root, ptr); + ptr = make_header (ptr, initrd_ctx->components[i].newc_name, + grub_strlen (initrd_ctx->components[i].newc_name) + 1, + 0100777, + initrd_ctx->components[i].size); + newc = 1; + } + else if (newc) + { + ptr = make_header (ptr, "TRAILER!!!", sizeof ("TRAILER!!!"), + 0, 0); + free_dir (root); + root = 0; + newc = 0; + } + + cursize = initrd_ctx->components[i].size; + if (ventoy_need_prompt_load_file() && initrd_ctx->components[i].newc_name && + grub_strcmp(initrd_ctx->components[i].newc_name, "boot.wim") == 0) + { + readsize = ventoy_load_file_with_prompt(initrd_ctx->components[i].file, ptr, cursize); + } + else + { + readsize = grub_file_read (initrd_ctx->components[i].file, ptr, cursize); + } + + if (readsize != cursize) + { + if (!grub_errno) + grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), + argv[i]); + grub_initrd_close (initrd_ctx); + return grub_errno; + } + ptr += cursize; + } + if (newc) + { + grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); + ptr += ALIGN_UP_OVERHEAD (cursize, 4); + ptr = make_header (ptr, "TRAILER!!!", sizeof ("TRAILER!!!"), 0, 0); + } + free_dir (root); + root = 0; + return GRUB_ERR_NONE; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/loader/mips64/linux.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/loader/mips64/linux.c new file mode 100644 index 0000000..d81cc3c --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/loader/mips64/linux.c @@ -0,0 +1,1041 @@ +/* linux.c - boot Linux */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2007,2009,2010,2017 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +GRUB_MOD_LICENSE ("GPLv3+"); + +#define _ull unsigned long long +#pragma GCC diagnostic ignored "-Wcast-align" + +typedef unsigned long size_t; + +static grub_dl_t my_mod; + +static int loaded; + +static grub_uint32_t tmp_index = 0; +static grub_size_t linux_size; + +static struct grub_relocator *relocator; +static grub_addr_t target_addr, entry_addr; +static int linux_argc; +static grub_uint8_t *linux_args_addr; +static grub_off_t rd_addr_arg_off, rd_size_arg_off; +static int initrd_loaded = 0; + + +static grub_uint32_t j = 0; +static grub_uint32_t t = 0; +grub_uint64_t tempMemsize = 0; +grub_uint32_t free_index = 0; +grub_uint32_t reserve_index = 0; +grub_uint32_t acpi_table_index = 0; +grub_uint32_t acpi_nvs_index = 0; + +#define LINUX_MAX_ARGC 1024 +static int ventoy_debug = 0; +static int ventoy_initrd_called = 0; +static int ventoy_linux_argc = 0; +static char **ventoy_linux_args = NULL; +static int ventoy_extra_initrd_num = 0; +static char *ventoy_extra_initrd_list[256]; +static grub_err_t +grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]); + + + +static inline grub_size_t +page_align (grub_size_t size) +{ + return (size + (1 << 12) - 1) & (~((1 << 12) - 1)); +} + +/* Find the optimal number of pages for the memory map. Is it better to + move this code to efi/mm.c? */ +static grub_efi_uintn_t +find_mmap_size (void) +{ + static grub_efi_uintn_t mmap_size = 0; + + if (mmap_size != 0) + return mmap_size; + + mmap_size = (1 << 12); + while (1) + { + int ret; + grub_efi_memory_descriptor_t *mmap; + grub_efi_uintn_t desc_size; + + mmap = grub_malloc (mmap_size); + if (! mmap) + return 0; + + ret = grub_efi_get_memory_map (&mmap_size, mmap, 0, &desc_size, 0); + grub_free (mmap); + + if (ret < 0) + { + grub_error (GRUB_ERR_IO, "cannot get memory map"); + return 0; + } + else if (ret > 0) + break; + + mmap_size += (1 << 12); + } + + + /* Increase the size a bit for safety, because GRUB allocates more on + later, and EFI itself may allocate more. */ + mmap_size += (1 << 12); + + return page_align (mmap_size); +} + + +static void ventoy_debug_pause(void) +{ + char key; + + if (0 == ventoy_debug) + { + return; + } + + grub_printf("press Enter to continue ......\n"); + while (1) + { + key = grub_getkey(); + if (key == '\n' || key == '\r') + { + break; + } + } +} + +static int ventoy_preboot(void) +{ + int i; + const char *file; + char buf[128]; + + if (ventoy_debug) + { + grub_printf("ventoy_preboot %d %d\n", ventoy_linux_argc, ventoy_initrd_called); + ventoy_debug_pause(); + } + + if (ventoy_linux_argc == 0) + { + return 0; + } + + if (ventoy_initrd_called) + { + ventoy_initrd_called = 0; + return 0; + } + + grub_snprintf(buf, sizeof(buf), "mem:%s:size:%s", grub_env_get("ventoy_cpio_addr"), grub_env_get("ventoy_cpio_size")); + + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(buf); + + file = grub_env_get("vtoy_img_part_file"); + if (file) + { + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(file); + } + + if (ventoy_debug) + { + grub_printf("========== initrd list ==========\n"); + for (i = 0; i < ventoy_extra_initrd_num; i++) + { + grub_printf("%s\n", ventoy_extra_initrd_list[i]); + } + grub_printf("=================================\n"); + + ventoy_debug_pause(); + } + + grub_cmd_initrd(NULL, ventoy_extra_initrd_num, ventoy_extra_initrd_list); + + return 0; +} + +static int ventoy_boot_opt_filter(char *opt) +{ + if (grub_strcmp(opt, "noinitrd") == 0) + { + return 1; + } + + if (grub_strcmp(opt, "vga=current") == 0) + { + return 1; + } + + if (grub_strncmp(opt, "rdinit=", 7) == 0) + { + if (grub_strcmp(opt, "rdinit=/vtoy/vtoy") != 0) + { + opt[0] = 'v'; + opt[1] = 't'; + } + return 0; + } + + if (grub_strncmp(opt, "init=", 5) == 0) + { + opt[0] = 'v'; + opt[1] = 't'; + return 0; + } + + if (grub_strncmp(opt, "dm=", 3) == 0) + { + opt[0] = 'D'; + opt[1] = 'M'; + return 0; + } + + if (ventoy_debug) + { + if (grub_strcmp(opt, "quiet") == 0) + { + return 1; + } + + if (grub_strncmp(opt, "loglevel=", 9) == 0) + { + return 1; + } + + if (grub_strcmp(opt, "splash") == 0) + { + return 1; + } + } + + return 0; +} + +static int ventoy_bootopt_hook(int argc, char *argv[]) +{ + int i; + int TmpIdx; + int count = 0; + const char *env; + char c; + char *newenv; + char *last, *pos; + + //grub_printf("ventoy_bootopt_hook: %d %d\n", argc, ventoy_linux_argc); + + if (ventoy_linux_argc == 0) + { + return 0; + } + + /* To avoid --- parameter, we split two parts */ + for (TmpIdx = 0; TmpIdx < argc; TmpIdx++) + { + if (ventoy_boot_opt_filter(argv[TmpIdx])) + { + continue; + } + + if (grub_strncmp(argv[TmpIdx], "--", 2) == 0) + { + break; + } + + ventoy_linux_args[count++] = grub_strdup(argv[TmpIdx]); + } + + for (i = 0; i < ventoy_linux_argc; i++) + { + ventoy_linux_args[count] = ventoy_linux_args[i + (LINUX_MAX_ARGC / 2)]; + ventoy_linux_args[i + (LINUX_MAX_ARGC / 2)] = NULL; + + if (ventoy_linux_args[count][0] == '@') + { + env = grub_env_get(ventoy_linux_args[count] + 1); + if (env) + { + grub_free(ventoy_linux_args[count]); + + newenv = grub_strdup(env); + last = newenv; + + while (*last) + { + while (*last) + { + if (*last != ' ' && *last != '\t') + { + break; + } + last++; + } + + if (*last == 0) + { + break; + } + + for (pos = last; *pos; pos++) + { + if (*pos == ' ' || *pos == '\t') + { + c = *pos; + *pos = 0; + if (0 == ventoy_boot_opt_filter(last)) + { + ventoy_linux_args[count++] = grub_strdup(last); + } + *pos = c; + break; + } + } + + if (*pos == 0) + { + if (0 == ventoy_boot_opt_filter(last)) + { + ventoy_linux_args[count++] = grub_strdup(last); + } + break; + } + + last = pos + 1; + } + } + else + { + count++; + } + } + else + { + count++; + } + } + + while (TmpIdx < argc) + { + if (ventoy_boot_opt_filter(argv[TmpIdx])) + { + continue; + } + + ventoy_linux_args[count++] = grub_strdup(argv[TmpIdx]); + TmpIdx++; + } + + if (ventoy_debug) + { + ventoy_linux_args[count++] = grub_strdup("loglevel=7"); + } + + ventoy_linux_argc = count; + + if (ventoy_debug) + { + grub_printf("========== bootoption ==========\n"); + for (i = 0; i < count; i++) + { + grub_printf("%s ", ventoy_linux_args[i]); + } + grub_printf("\n================================\n"); + } + + return 0; +} + +static grub_err_t +grub_cmd_set_boot_opt (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int i; + const char *vtdebug; + + for (i = 0; i < argc; i++) + { + ventoy_linux_args[ventoy_linux_argc + (LINUX_MAX_ARGC / 2) ] = grub_strdup(argv[i]); + ventoy_linux_argc++; + } + + vtdebug = grub_env_get("vtdebug_flag"); + if (vtdebug && vtdebug[0]) + { + ventoy_debug = 1; + } + + if (ventoy_debug) grub_printf("ventoy set boot opt %d\n", ventoy_linux_argc); + + return 0; +} + +static grub_err_t +grub_cmd_unset_boot_opt (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int i; + + (void)argc; + (void)argv; + + for (i = 0; i < LINUX_MAX_ARGC; i++) + { + if (ventoy_linux_args[i]) + { + grub_free(ventoy_linux_args[i]); + } + } + + ventoy_debug = 0; + ventoy_linux_argc = 0; + ventoy_initrd_called = 0; + grub_memset(ventoy_linux_args, 0, sizeof(char *) * LINUX_MAX_ARGC); + return 0; +} + +static grub_err_t +grub_cmd_extra_initrd_append (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int newclen = 0; + char *pos = NULL; + char *end = NULL; + char buf[256] = {0}; + + if (argc != 1) + { + return 1; + } + + for (pos = argv[0]; *pos; pos++) + { + if (*pos == '/') + { + end = pos; + } + } + + if (end) + { + /* grub2 newc bug workaround */ + newclen = (int)grub_strlen(end + 1); + if ((110 + newclen) % 4 == 0) + { + grub_snprintf(buf, sizeof(buf), "newc:.%s:%s", end + 1, argv[0]); + } + else + { + grub_snprintf(buf, sizeof(buf), "newc:%s:%s", end + 1, argv[0]); + } + + if (ventoy_extra_initrd_num < 256) + { + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(buf); + } + } + + return 0; +} + +static grub_err_t +grub_cmd_extra_initrd_reset (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int i; + + (void)argc; + (void)argv; + + for (i = 0; i < ventoy_extra_initrd_num; i++) + { + if (ventoy_extra_initrd_list[i]) + { + grub_free(ventoy_extra_initrd_list[i]); + } + } + + grub_memset(ventoy_extra_initrd_list, 0, sizeof(ventoy_extra_initrd_list)); + + return 0; +} + + +static grub_err_t +grub_linux_boot (void) +{ + struct grub_relocator64_state state; + grub_int8_t checksum = 0; + grub_efi_memory_descriptor_t * lsdesc = NULL; + + ventoy_preboot(); + + grub_memset (&state, 0, sizeof (state)); + + /* Boot the kernel. */ + state.gpr[1] = entry_addr; + grub_dprintf("loongson", "entry_addr is 0x%llx\n", (_ull)state.gpr[1]); + state.gpr[4] = linux_argc; + grub_dprintf("loongson", "linux_argc is %lld\n", (_ull)state.gpr[4]); + state.gpr[5] = (grub_addr_t) linux_args_addr; + grub_dprintf("loongson", "args_addr is 0x%llx\n", (_ull)state.gpr[5]); + + if(grub_efi_is_loongson ()) + { + grub_efi_uintn_t mmap_size; + grub_efi_uintn_t desc_size; + grub_efi_memory_descriptor_t *mmap_buf; + grub_err_t err; + struct bootparamsinterface * boot_params; + void * tmp_boot_params = NULL; + grub_efi_uint8_t new_interface_flag = 0; + mem_map * new_interface_mem = NULL; + char *p = NULL; + + struct memmap reserve_mem[GRUB_EFI_LOONGSON_MMAP_MAX]; + struct memmap free_mem[GRUB_EFI_LOONGSON_MMAP_MAX]; + struct memmap acpi_table_mem[GRUB_EFI_LOONGSON_MMAP_MAX]; + struct memmap acpi_nvs_mem[GRUB_EFI_LOONGSON_MMAP_MAX]; + + grub_memset(reserve_mem, 0, sizeof(struct memmap) * GRUB_EFI_LOONGSON_MMAP_MAX); + grub_memset(free_mem, 0, sizeof(struct memmap) * GRUB_EFI_LOONGSON_MMAP_MAX); + grub_memset(acpi_table_mem, 0, sizeof(struct memmap) * GRUB_EFI_LOONGSON_MMAP_MAX); + grub_memset(acpi_nvs_mem, 0, sizeof(struct memmap) * GRUB_EFI_LOONGSON_MMAP_MAX); + + tmp_boot_params = grub_efi_loongson_get_boot_params(); + if(tmp_boot_params == NULL) + { + grub_printf("not find param\n"); + return -1; + } + + boot_params = (struct bootparamsinterface *)tmp_boot_params; + p = (char *)&(boot_params->signature); + if(grub_strncmp(p, "BPI", 3) == 0) + { + /* Check extlist headers */ + ext_list * listpointer = NULL; + listpointer = boot_params->extlist; + for( ;listpointer != NULL; listpointer = listpointer->next) + { + char *pl= (char *)&(listpointer->signature); + if(grub_strncmp(pl, "MEM", 3) == 0) + { + new_interface_mem = (mem_map *)listpointer; + } + } + + new_interface_flag = 1; + grub_dprintf("loongson", "get new parameter interface\n"); + }else{ + new_interface_flag = 0; + grub_dprintf("loongson", "get old parameter interface\n"); + + } + state.gpr[6] = (grub_uint64_t)tmp_boot_params; + grub_dprintf("loongson", "boot_params is 0x%llx\n", (_ull)state.gpr[6]); + + mmap_size = find_mmap_size (); + if (! mmap_size) + return grub_errno; + mmap_buf = grub_efi_allocate_any_pages (page_align (mmap_size) >> 12); + if (! mmap_buf) + return grub_error (GRUB_ERR_IO, "cannot allocate memory map"); + err = grub_efi_finish_boot_services (&mmap_size, mmap_buf, NULL, + &desc_size, NULL); + //grub_printf("%s-%d\n", __func__, __LINE__); + if (err) + return err; + + if(new_interface_flag) + { + if (!mmap_buf || !mmap_size || !desc_size) + return -1; + + tmp_index = new_interface_mem -> mapcount; + //grub_printf("%s-%d mapcount %d\n", __func__, __LINE__, tmp_index); + + /* + According to UEFI SPEC,mmap_buf is the accurate Memory Map array \ + now we can fill platform specific memory structure. + */ + for(lsdesc = mmap_buf; lsdesc < (grub_efi_memory_descriptor_t *)((char *)mmap_buf + mmap_size); lsdesc = (grub_efi_memory_descriptor_t *)((char *)lsdesc + desc_size)) + { + /* Recovery */ + if((lsdesc->type != GRUB_EFI_ACPI_RECLAIM_MEMORY) && \ + (lsdesc->type != GRUB_EFI_ACPI_MEMORY_NVS) && \ + (lsdesc->type != GRUB_EFI_RUNTIME_SERVICES_DATA) && \ + (lsdesc->type != GRUB_EFI_RUNTIME_SERVICES_CODE) && \ + (lsdesc->type != GRUB_EFI_RESERVED_MEMORY_TYPE) && \ + (lsdesc->type != GRUB_EFI_PAL_CODE)) + { + + free_mem[free_index].memtype = GRUB_EFI_LOONGSON_SYSTEM_RAM_LOW; + free_mem[free_index].memstart = (lsdesc->physical_start) & 0xffffffffffff; + free_mem[free_index].memsize = lsdesc->num_pages * 4096; + free_index++; + /*ACPI*/ + }else if((lsdesc->type == GRUB_EFI_ACPI_RECLAIM_MEMORY)){ + acpi_table_mem[acpi_table_index].memtype = GRUB_EFI_LOONGSON_ACPI_TABLE; + acpi_table_mem[acpi_table_index].memstart = (lsdesc->physical_start) & 0xffffffffffff; + acpi_table_mem[acpi_table_index].memsize = lsdesc->num_pages * 4096; + acpi_table_index++; + + }else if((lsdesc->type == GRUB_EFI_ACPI_MEMORY_NVS)){ + acpi_nvs_mem[acpi_nvs_index].memtype = GRUB_EFI_LOONGSON_ACPI_NVS; + acpi_nvs_mem[acpi_nvs_index].memstart = (lsdesc->physical_start) & 0xffffffffffff; + acpi_nvs_mem[acpi_nvs_index].memsize = lsdesc->num_pages * 4096; + acpi_nvs_index++; + + /* Reserve */ + }else{ + reserve_mem[reserve_index].memtype = GRUB_EFI_LOONGSON_MEMORY_RESERVED; + reserve_mem[reserve_index].memstart = (lsdesc->physical_start) & 0xffffffffffff; + reserve_mem[reserve_index].memsize = lsdesc->num_pages * 4096; + reserve_index++; + } + } + + /* Recovery sort */ + for(j = 0; j < free_index;) + { + tempMemsize = free_mem[j].memsize; + for(t = j + 1; t < free_index; t++) + { + if((free_mem[j].memstart + tempMemsize == free_mem[t].memstart) && (free_mem[j].memtype == free_mem[t].memtype)) + { + tempMemsize += free_mem[t].memsize; + }else{ + break; + } + } + if(free_mem[j].memstart >= 0x10000000) /*HIGH MEM*/ + new_interface_mem->map[tmp_index].memtype = GRUB_EFI_LOONGSON_SYSTEM_RAM_HIGH; + else + new_interface_mem->map[tmp_index].memtype = GRUB_EFI_LOONGSON_SYSTEM_RAM_LOW; + new_interface_mem->map[tmp_index].memstart = free_mem[j].memstart; + new_interface_mem->map[tmp_index].memsize = tempMemsize; + grub_dprintf("loongson", "map[%d]:type %x, start 0x%llx, end 0x%llx\n", + tmp_index, + new_interface_mem->map[tmp_index].memtype, + (_ull)new_interface_mem->map[tmp_index].memstart, + (_ull)new_interface_mem->map[tmp_index].memstart+ new_interface_mem->map[tmp_index].memsize + ); + j = t; + tmp_index++; + } + + /*ACPI Sort*/ + tmp_index = grub_efi_loongson_memmap_sort(acpi_table_mem, acpi_table_index, new_interface_mem, tmp_index, GRUB_EFI_LOONGSON_ACPI_TABLE); + tmp_index = grub_efi_loongson_memmap_sort(acpi_nvs_mem, acpi_nvs_index, new_interface_mem, tmp_index, GRUB_EFI_LOONGSON_ACPI_NVS); + /*Reserve Sort*/ + tmp_index = grub_efi_loongson_memmap_sort(reserve_mem, reserve_index, new_interface_mem, tmp_index, GRUB_EFI_LOONGSON_MEMORY_RESERVED); + + new_interface_mem->mapcount = tmp_index; + new_interface_mem->header.checksum = 0; + //grub_printf("%s-%d mapcount %d\n", __func__, __LINE__, tmp_index); + + checksum = grub_efi_loongson_grub_calculatechecksum8((grub_uint8_t *)new_interface_mem, new_interface_mem->header.length); + new_interface_mem->header.checksum = checksum; + } + } + + state.jumpreg = 1; + grub_relocator64_boot (relocator, state); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_linux_unload (void) +{ + grub_relocator_unload (relocator); + grub_dl_unref (my_mod); + + loaded = 0; + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_linux_load32 (grub_elf_t elf, const char *filename) +{ + Elf32_Addr base; + grub_err_t err; + grub_uint8_t *playground; + + /* Linux's entry point incorrectly contains a virtual address. */ + entry_addr = elf->ehdr.ehdr32.e_entry; + + linux_size = grub_elf32_size (elf, &base, 0); + if (linux_size == 0) + return grub_errno; + target_addr = base; + linux_size = ALIGN_UP (base + linux_size - base, 8); + + relocator = grub_relocator_new (); + if (!relocator) + return grub_errno; + + { + grub_relocator_chunk_t ch; + err = grub_relocator_alloc_chunk_addr (relocator, &ch, + grub_vtop ((void *) target_addr), + linux_size); + if (err) + return err; + playground = get_virtual_current_address (ch); + } + + /* Now load the segments into the area we claimed. */ + return grub_elf32_load (elf, filename, playground - base, GRUB_ELF_LOAD_FLAGS_NONE, 0, 0); +} + +static grub_err_t +grub_linux_load64 (grub_elf_t elf, const char *filename) +{ + Elf64_Addr base; + grub_err_t err; + grub_uint8_t *playground; + + /* Linux's entry point incorrectly contains a virtual address. */ + entry_addr = elf->ehdr.ehdr64.e_entry; + grub_dprintf("loongson", "entry address = 0x%llx\n", (_ull)entry_addr); + + linux_size = grub_elf64_size (elf, &base, 0); + grub_dprintf("loongson", "base = 0x%llx\n", (_ull)base); + + if (linux_size == 0) + return grub_errno; + target_addr = base; + linux_size = ALIGN_UP (base + linux_size - base, 8); + + relocator = grub_relocator_new (); + if (!relocator) + return grub_errno; + + { + grub_relocator_chunk_t ch; + err = grub_relocator_alloc_chunk_addr (relocator, &ch, + grub_vtop ((void *) target_addr), + linux_size); + if (err) + return err; + playground = get_virtual_current_address (ch); + //playground = 0xffffffff81ee0000; //½«ÄںËֱ½Óloadµ½elfͷָ¶¨Äڴ棬¶ø·Çgrub·ÖÅäµĿռä + //playground = 0xffffffff80200000; + } + + grub_printf("playground:0x%llx\n", (_ull)playground); + + /* Now load the segments into the area we claimed. */ + return grub_elf64_load (elf, filename, playground - base, GRUB_ELF_LOAD_FLAGS_NONE, 0, 0); +} + +static grub_err_t +grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + grub_elf_t elf = 0; + int size; + int i; + grub_uint32_t *linux_argv; + char *linux_args; + grub_err_t err; + + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + + if (ventoy_linux_argc) + { + ventoy_bootopt_hook(argc, argv); + argc = ventoy_linux_argc; + argv = ventoy_linux_args; + } + + elf = grub_elf_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL); + if (! elf) + return grub_errno; + + if (elf->ehdr.ehdr32.e_type != ET_EXEC) + { + grub_elf_close (elf); + return grub_error (GRUB_ERR_UNKNOWN_OS, + N_("this ELF file is not of the right type")); + } + + /* Release the previously used memory. */ + grub_loader_unset (); + loaded = 0; + + /* For arguments. */ + linux_argc = argc; + /* Main arguments. */ + size = (linux_argc) * sizeof (grub_uint32_t); + /* Initrd address and size. */ + size += 2 * sizeof (grub_uint32_t); + /* NULL terminator. */ + size += sizeof (grub_uint32_t); + /* First argument is always "a0". */ + size += ALIGN_UP (sizeof ("a0"), 4); + /* Normal arguments. */ + for (i = 1; i < argc; i++) + size += ALIGN_UP (grub_strlen (argv[i]) + 1, 4); + + /* rd arguments. */ + size += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4); + size += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4); + + size = ALIGN_UP (size, 8); + + if (grub_elf_is_elf32 (elf)) + err = grub_linux_load32 (elf, argv[0]); + else + if (grub_elf_is_elf64 (elf)) + err = grub_linux_load64 (elf, argv[0]); + else + err = grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-dependent ELF magic")); + + grub_elf_close (elf); + + if (err) + return err; + + { + grub_relocator_chunk_t ch; + err = grub_relocator_alloc_chunk_align (relocator, &ch, + 0, (0xffffffff - size) + 1, + size, 8, + GRUB_RELOCATOR_PREFERENCE_HIGH, 0); + if (err) + return err; + linux_args_addr = get_virtual_current_address (ch); + } + + linux_argv = (grub_uint32_t *) linux_args_addr; + linux_args = (char *) (linux_argv + (linux_argc + 1 + 2)); + + grub_memcpy (linux_args, "a0", sizeof ("a0")); + *linux_argv = (grub_uint32_t) (grub_addr_t) linux_args; + linux_argv++; + linux_args += ALIGN_UP (sizeof ("a0"), 4); + + for (i = 1; i < argc; i++) + { + grub_memcpy (linux_args, argv[i], grub_strlen (argv[i]) + 1); + *linux_argv = (grub_uint32_t) (grub_addr_t) linux_args; + linux_argv++; + linux_args += ALIGN_UP (grub_strlen (argv[i]) + 1, 4); + } + + /* Reserve space for rd arguments. */ + rd_addr_arg_off = (grub_uint8_t *) linux_args - linux_args_addr; + linux_args += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4); + *linux_argv = 0; + linux_argv++; + + rd_size_arg_off = (grub_uint8_t *) linux_args - linux_args_addr; + linux_args += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4); + *linux_argv = 0; + linux_argv++; + + *linux_argv = 0; + + //wake up other cores + { + __asm__( + "dli $8, 0x900000003ff01000\n\t" + "dli $11, 0 \n\t" + "dsll $11, 8 \n\t" + "or $8, $8,$11 \n\t" + "li $9, 0x5a5a \n\t" + "sw $9, 32($8) \n\t" + "nop \n\t" + : + : + ); + } + grub_loader_set (grub_linux_boot, grub_linux_unload, 0); + initrd_loaded = 0; + loaded = 1; + grub_dl_ref (my_mod); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + grub_size_t size = 0; + void *initrd_dest; + grub_err_t err; + struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 }; + + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + + if (!loaded) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first")); + + if (initrd_loaded) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "only one initrd command can be issued."); + + if (grub_initrd_init (argc, argv, &initrd_ctx)) + goto fail; + + size = grub_get_initrd_size (&initrd_ctx); + + { + grub_relocator_chunk_t ch; + err = grub_relocator_alloc_chunk_align (relocator, &ch, + 0, (0xffffffff - size) + 1, + size, 0x10000, + GRUB_RELOCATOR_PREFERENCE_HIGH, 0); + + if (err) + goto fail; + initrd_dest = get_virtual_current_address (ch); + } + + if (grub_initrd_load (&initrd_ctx, argv, initrd_dest)) + goto fail; + + grub_snprintf ((char *) linux_args_addr + rd_addr_arg_off, + sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), "rd_start=0x%lx", + (grub_uint64_t) initrd_dest); + ((grub_uint32_t *) linux_args_addr)[linux_argc] + = (grub_uint32_t) ((grub_addr_t) linux_args_addr + rd_addr_arg_off); + linux_argc++; + + grub_snprintf ((char *) linux_args_addr + rd_size_arg_off, + sizeof ("rd_size=0xXXXXXXXXXXXXXXXXX"), "rd_size=0x%lx", + (grub_uint64_t) size); + ((grub_uint32_t *) linux_args_addr)[linux_argc] + = (grub_uint32_t) ((grub_addr_t) linux_args_addr + rd_size_arg_off); + linux_argc++; + + initrd_loaded = 1; + + fail: + grub_initrd_close (&initrd_ctx); + + return grub_errno; +} + +static grub_err_t +ventoy_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int i; + const char *file; + char buf[64]; + + if (ventoy_debug) grub_printf("ventoy_cmd_initrd %d\n", ventoy_linux_argc); + + if (ventoy_linux_argc == 0) + { + return grub_cmd_initrd(cmd, argc, argv); + } + + grub_snprintf(buf, sizeof(buf), "mem:%s:size:%s", grub_env_get("ventoy_cpio_addr"), grub_env_get("ventoy_cpio_size")); + + if (ventoy_debug) grub_printf("membuf=%s\n", buf); + + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(buf); + + file = grub_env_get("vtoy_img_part_file"); + if (file) + { + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(file); + } + + for (i = 0; i < argc; i++) + { + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(argv[i]); + } + + ventoy_initrd_called = 1; + + if (ventoy_debug) + { + grub_printf("========== initrd list ==========\n"); + for (i = 0; i < ventoy_extra_initrd_num; i++) + { + grub_printf("%s\n", ventoy_extra_initrd_list[i]); + } + grub_printf("=================================\n"); + } + + return grub_cmd_initrd(cmd, ventoy_extra_initrd_num, ventoy_extra_initrd_list); +} + +static grub_command_t cmd_linux, cmd_initrd; +static grub_command_t cmd_set_bootopt, cmd_unset_bootopt, cmd_extra_initrd_append, cmd_extra_initrd_reset; + +GRUB_MOD_INIT(linux) +{ + cmd_linux = grub_register_command ("linux", grub_cmd_linux, + 0, N_("Load Linux.")); + cmd_initrd = grub_register_command ("initrd", ventoy_cmd_initrd, + 0, N_("Load initrd.")); + + cmd_set_bootopt = grub_register_command ("vt_set_boot_opt", grub_cmd_set_boot_opt, 0, N_("set ext boot opt")); + cmd_unset_bootopt = grub_register_command ("vt_unset_boot_opt", grub_cmd_unset_boot_opt, 0, N_("unset ext boot opt")); + + cmd_extra_initrd_append = grub_register_command ("vt_img_extra_initrd_append", grub_cmd_extra_initrd_append, 0, N_("")); + cmd_extra_initrd_reset = grub_register_command ("vt_img_extra_initrd_reset", grub_cmd_extra_initrd_reset, 0, N_("")); + + ventoy_linux_args = grub_zalloc(sizeof(char *) * LINUX_MAX_ARGC); + + my_mod = mod; +} + +GRUB_MOD_FINI(linux) +{ + grub_unregister_command (cmd_linux); + grub_unregister_command (cmd_initrd); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/charset.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/charset.c new file mode 100644 index 0000000..ef9f046 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/charset.c @@ -0,0 +1,1352 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +/* + Current problems with Unicode rendering: + - B and BN bidi type characters (ignored) + - Mc type characters with combining class 0 (poorly combined) + - Mn type characters with combining class 0 (poorly combined) + - Me type characters with combining class 0 (poorly combined) + - Cf type characters (ignored) + - Cc type characters (ignored) + - Line-breaking rules (e.g. Zs type characters) + - Indic languages + - non-Semitic shaping (rarely used) + - Zl and Zp characters + - Combining characters of types 7, 8, 9, 21, 35, 36, 84, 91, 103, 107, + 118, 122, 129, 130, 132, 218, 224, 226, 233, 234 + - Private use characters (not really a problem) + - Variations (no font support) + - Vertical text + - Ligatures + Font information ignored: + - Kerning + - Justification data + - Glyph posititioning + - Baseline data + Most underline diacritics aren't displayed in gfxterm + */ + +#include +#include +#include +#include +#include +#include + +#if HAVE_FONT_SOURCE +#include "widthspec.h" +#endif + +/* Returns -2 if not enough space, -1 on invalid character. */ +grub_ssize_t +grub_encode_utf8_character (grub_uint8_t *dest, grub_uint8_t *destend, + grub_uint32_t code) +{ + if (dest >= destend) + return -2; + if (code <= 0x007F) + { + *dest++ = code; + return 1; + } + if (code <= 0x07FF) + { + if (dest + 1 >= destend) + return -2; + *dest++ = (code >> 6) | 0xC0; + *dest++ = (code & 0x3F) | 0x80; + return 2; + } + if ((code >= 0xDC00 && code <= 0xDFFF) + || (code >= 0xD800 && code <= 0xDBFF)) + { + /* No surrogates in UCS-4... */ + return -1; + } + if (code < 0x10000) + { + if (dest + 2 >= destend) + return -2; + *dest++ = (code >> 12) | 0xE0; + *dest++ = ((code >> 6) & 0x3F) | 0x80; + *dest++ = (code & 0x3F) | 0x80; + return 3; + } + { + if (dest + 3 >= destend) + return -2; + *dest++ = (code >> 18) | 0xF0; + *dest++ = ((code >> 12) & 0x3F) | 0x80; + *dest++ = ((code >> 6) & 0x3F) | 0x80; + *dest++ = (code & 0x3F) | 0x80; + return 4; + } + +} + +/* Convert UCS-4 to UTF-8. */ +grub_size_t +grub_ucs4_to_utf8 (const grub_uint32_t *src, grub_size_t size, + grub_uint8_t *dest, grub_size_t destsize) +{ + /* Keep last char for \0. */ + grub_uint8_t *destend = dest + destsize - 1; + grub_uint8_t *dest0 = dest; + + while (size-- && dest < destend) + { + grub_uint32_t code = *src++; + grub_ssize_t s; + s = grub_encode_utf8_character (dest, destend, code); + if (s == -2) + break; + if (s == -1) + { + *dest++ = '?'; + continue; + } + dest += s; + } + *dest = 0; + return dest - dest0; +} + +/* Returns the number of bytes the string src would occupy is converted + to UTF-8, excluding trailing \0. */ +grub_size_t +grub_get_num_of_utf8_bytes (const grub_uint32_t *src, grub_size_t size) +{ + grub_size_t remaining; + const grub_uint32_t *ptr; + grub_size_t cnt = 0; + + remaining = size; + ptr = src; + while (remaining--) + { + grub_uint32_t code = *ptr++; + + if (code <= 0x007F) + cnt++; + else if (code <= 0x07FF) + cnt += 2; + else if ((code >= 0xDC00 && code <= 0xDFFF) + || (code >= 0xD800 && code <= 0xDBFF)) + /* No surrogates in UCS-4... */ + cnt++; + else if (code < 0x10000) + cnt += 3; + else + cnt += 4; + } + return cnt; +} + +/* Convert UCS-4 to UTF-8. */ +char * +grub_ucs4_to_utf8_alloc (const grub_uint32_t *src, grub_size_t size) +{ + grub_uint8_t *ret; + grub_size_t cnt = grub_get_num_of_utf8_bytes (src, size) + 1; + + ret = grub_malloc (cnt); + if (!ret) + return 0; + + grub_ucs4_to_utf8 (src, size, ret, cnt); + + return (char *) ret; +} + +int +grub_is_valid_utf8 (const grub_uint8_t *src, grub_size_t srcsize) +{ + int count = 0; + grub_uint32_t code = 0; + + while (srcsize) + { + if (srcsize != (grub_size_t)-1) + srcsize--; + if (!grub_utf8_process (*src++, &code, &count)) + return 0; + if (count != 0) + continue; + if (code == 0) + return 1; + if (code > GRUB_UNICODE_LAST_VALID) + return 0; + } + + return 1; +} + +grub_ssize_t +grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg, + grub_uint32_t **last_position) +{ + grub_size_t msg_len = grub_strlen (msg); + + *unicode_msg = grub_malloc (msg_len * sizeof (grub_uint32_t)); + + if (!*unicode_msg) + return -1; + + msg_len = grub_utf8_to_ucs4 (*unicode_msg, msg_len, + (grub_uint8_t *) msg, -1, 0); + + if (last_position) + *last_position = *unicode_msg + msg_len; + + return msg_len; +} + +/* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE + bytes (if SRCSIZE is -1, it is ignored) in length to a UCS-4 string. + Return the number of characters converted. DEST must be able to hold + at least DESTSIZE characters. + If SRCEND is not NULL, then *SRCEND is set to the next byte after the + last byte used in SRC. */ +grub_size_t +grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize, + const grub_uint8_t *src, grub_size_t srcsize, + const grub_uint8_t **srcend) +{ + grub_uint32_t *p = dest; + int count = 0; + grub_uint32_t code = 0; + + if (srcend) + *srcend = src; + + while (srcsize && destsize) + { + int was_count = count; + if (srcsize != (grub_size_t)-1) + srcsize--; + if (!grub_utf8_process (*src++, &code, &count)) + { + code = '?'; + count = 0; + /* Character c may be valid, don't eat it. */ + if (was_count) + src--; + } + if (count != 0) + continue; + if (code == 0) + break; + *p++ = code; + destsize--; + } + + if (srcend) + *srcend = src; + return p - dest; +} + +static grub_uint8_t *join_types = NULL; + +static void +unpack_join (void) +{ + unsigned i; + struct grub_unicode_compact_range *cur; + + join_types = grub_zalloc (GRUB_UNICODE_MAX_CACHED_CHAR); + if (!join_types) + { + grub_errno = GRUB_ERR_NONE; + return; + } + for (cur = grub_unicode_compact; cur->len; cur++) + for (i = cur->start; i < cur->start + (unsigned) cur->len + && i < GRUB_UNICODE_MAX_CACHED_CHAR; i++) + join_types[i] = cur->join_type; +} + +static grub_uint8_t *bidi_types = NULL; + +static void +unpack_bidi (void) +{ + unsigned i; + struct grub_unicode_compact_range *cur; + + bidi_types = grub_zalloc (GRUB_UNICODE_MAX_CACHED_CHAR); + if (!bidi_types) + { + grub_errno = GRUB_ERR_NONE; + return; + } + for (cur = grub_unicode_compact; cur->len; cur++) + for (i = cur->start; i < cur->start + (unsigned) cur->len + && i < GRUB_UNICODE_MAX_CACHED_CHAR; i++) + if (cur->bidi_mirror) + bidi_types[i] = cur->bidi_type | 0x80; + else + bidi_types[i] = cur->bidi_type | 0x00; +} + +static inline enum grub_bidi_type +get_bidi_type (grub_uint32_t c) +{ + struct grub_unicode_compact_range *cur; + + if (!bidi_types) + unpack_bidi (); + + if (bidi_types && c < GRUB_UNICODE_MAX_CACHED_CHAR) + return bidi_types[c] & 0x7f; + + for (cur = grub_unicode_compact; cur->len; cur++) + if (cur->start <= c && c < cur->start + (unsigned) cur->len) + return cur->bidi_type; + + return GRUB_BIDI_TYPE_L; +} + +static inline enum grub_join_type +get_join_type (grub_uint32_t c) +{ + struct grub_unicode_compact_range *cur; + + if (!join_types) + unpack_join (); + + if (join_types && c < GRUB_UNICODE_MAX_CACHED_CHAR) + return join_types[c]; + + for (cur = grub_unicode_compact; cur->len; cur++) + if (cur->start <= c && c < cur->start + (unsigned) cur->len) + return cur->join_type; + + return GRUB_JOIN_TYPE_NONJOINING; +} + +static inline int +is_mirrored (grub_uint32_t c) +{ + struct grub_unicode_compact_range *cur; + + if (!bidi_types) + unpack_bidi (); + + if (bidi_types && c < GRUB_UNICODE_MAX_CACHED_CHAR) + return !!(bidi_types[c] & 0x80); + + for (cur = grub_unicode_compact; cur->len; cur++) + if (cur->start <= c && c < cur->start + (unsigned) cur->len) + return cur->bidi_mirror; + + return 0; +} + +enum grub_comb_type +grub_unicode_get_comb_type (grub_uint32_t c) +{ + static grub_uint8_t *comb_types = NULL; + struct grub_unicode_compact_range *cur; + + if (!comb_types) + { + unsigned i; + comb_types = grub_zalloc (GRUB_UNICODE_MAX_CACHED_CHAR); + if (comb_types) + for (cur = grub_unicode_compact; cur->len; cur++) + for (i = cur->start; i < cur->start + (unsigned) cur->len + && i < GRUB_UNICODE_MAX_CACHED_CHAR; i++) + comb_types[i] = cur->comb_type; + else + grub_errno = GRUB_ERR_NONE; + } + + if (comb_types && c < GRUB_UNICODE_MAX_CACHED_CHAR) + return comb_types[c]; + + for (cur = grub_unicode_compact; cur->len; cur++) + if (cur->start <= c && c < cur->start + (unsigned) cur->len) + return cur->comb_type; + + return GRUB_UNICODE_COMB_NONE; +} + +#if HAVE_FONT_SOURCE + +grub_size_t +grub_unicode_estimate_width (const struct grub_unicode_glyph *c) +{ + if (grub_unicode_get_comb_type (c->base)) + return 0; + if (widthspec[c->base >> 3] & (1 << (c->base & 7))) + return 2; + else + return 1; +} + +#endif + +static inline int +is_type_after (enum grub_comb_type a, enum grub_comb_type b) +{ + /* Shadda is numerically higher than most of Arabic diacritics but has + to be rendered before them. */ + if (a == GRUB_UNICODE_COMB_ARABIC_SHADDA + && b <= GRUB_UNICODE_COMB_ARABIC_KASRA + && b >= GRUB_UNICODE_COMB_ARABIC_FATHATAN) + return 0; + if (b == GRUB_UNICODE_COMB_ARABIC_SHADDA + && a <= GRUB_UNICODE_COMB_ARABIC_KASRA + && a >= GRUB_UNICODE_COMB_ARABIC_FATHATAN) + return 1; + return a > b; +} + +grub_size_t +grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, + struct grub_unicode_glyph *out) +{ + int haveout = 0; + const grub_uint32_t *ptr; + unsigned last_comb_pointer = 0; + + grub_memset (out, 0, sizeof (*out)); + + if (inlen && grub_iscntrl (*in)) + { + out->base = *in; + out->variant = 0; + out->attributes = 0; + out->ncomb = 0; + out->estimated_width = 1; + return 1; + } + + for (ptr = in; ptr < in + inlen; ptr++) + { + /* Variation selectors >= 17 are outside of BMP and SMP. + Handle variation selectors first to avoid potentially costly lookups. + */ + if (*ptr >= GRUB_UNICODE_VARIATION_SELECTOR_1 + && *ptr <= GRUB_UNICODE_VARIATION_SELECTOR_16) + { + if (haveout) + out->variant = *ptr - GRUB_UNICODE_VARIATION_SELECTOR_1 + 1; + continue; + } + if (*ptr >= GRUB_UNICODE_VARIATION_SELECTOR_17 + && *ptr <= GRUB_UNICODE_VARIATION_SELECTOR_256) + { + if (haveout) + out->variant = *ptr - GRUB_UNICODE_VARIATION_SELECTOR_17 + 17; + continue; + } + + enum grub_comb_type comb_type; + comb_type = grub_unicode_get_comb_type (*ptr); + if (comb_type) + { + struct grub_unicode_combining *n; + unsigned j; + + if (!haveout) + continue; + + if (comb_type == GRUB_UNICODE_COMB_MC + || comb_type == GRUB_UNICODE_COMB_ME + || comb_type == GRUB_UNICODE_COMB_MN) + last_comb_pointer = out->ncomb; + + if (out->ncomb + 1 <= (int) ARRAY_SIZE (out->combining_inline)) + n = out->combining_inline; + else if (out->ncomb > (int) ARRAY_SIZE (out->combining_inline)) + { + n = grub_realloc (out->combining_ptr, + sizeof (n[0]) * (out->ncomb + 1)); + if (!n) + { + grub_errno = GRUB_ERR_NONE; + continue; + } + out->combining_ptr = n; + } + else + { + n = grub_malloc (sizeof (n[0]) * (out->ncomb + 1)); + if (!n) + { + grub_errno = GRUB_ERR_NONE; + continue; + } + grub_memcpy (n, out->combining_inline, + sizeof (out->combining_inline)); + out->combining_ptr = n; + } + + for (j = last_comb_pointer; j < out->ncomb; j++) + if (is_type_after (n[j].type, comb_type)) + break; + grub_memmove (n + j + 1, + n + j, + (out->ncomb - j) + * sizeof (n[0])); + n[j].code = *ptr; + n[j].type = comb_type; + out->ncomb++; + continue; + } + if (haveout) + return ptr - in; + haveout = 1; + out->base = *ptr; + out->variant = 0; + out->attributes = 0; + out->ncomb = 0; + out->estimated_width = 1; + } + return ptr - in; +} + +static void +revert (struct grub_unicode_glyph *visual, + struct grub_term_pos *pos, + unsigned start, unsigned end) +{ + struct grub_unicode_glyph t; + unsigned i; + int a = 0, b = 0; + if (pos) + { + a = pos[visual[start].orig_pos].x; + b = pos[visual[end].orig_pos].x; + } + for (i = 0; i < (end - start) / 2 + 1; i++) + { + t = visual[start + i]; + visual[start + i] = visual[end - i]; + visual[end - i] = t; + + if (pos) + { + pos[visual[start + i].orig_pos].x = a + b - pos[visual[start + i].orig_pos].x; + pos[visual[end - i].orig_pos].x = a + b - pos[visual[end - i].orig_pos].x; + } + } +} + + +static grub_ssize_t +bidi_line_wrap (struct grub_unicode_glyph *visual_out, + struct grub_unicode_glyph *visual, + grub_size_t visual_len, + grub_size_t (*getcharwidth) (const struct grub_unicode_glyph *visual, void *getcharwidth_arg), + void *getcharwidth_arg, + grub_size_t maxwidth, grub_size_t startwidth, + grub_uint32_t contchar, + struct grub_term_pos *pos, int primitive_wrap, + grub_size_t log_end) +{ + struct grub_unicode_glyph *outptr = visual_out; + unsigned line_start = 0; + grub_ssize_t line_width; + unsigned k; + grub_ssize_t last_space = -1; + grub_ssize_t last_space_width = 0; + int lines = 0; + + if (!visual_len) + return 0; + + if (startwidth >= maxwidth && (grub_ssize_t) maxwidth > 0) + { + if (contchar) + { + grub_memset (outptr, 0, sizeof (visual[0])); + outptr->base = contchar; + outptr++; + } + grub_memset (outptr, 0, sizeof (visual[0])); + outptr->base = '\n'; + outptr++; + startwidth = 0; + } + + line_width = startwidth; + + for (k = 0; k <= visual_len; k++) + { + grub_ssize_t last_width = 0; + + if (pos && k != visual_len) + { + pos[visual[k].orig_pos].x = line_width; + pos[visual[k].orig_pos].y = lines; + pos[visual[k].orig_pos].valid = 1; + } + + if (k == visual_len && pos) + { + pos[log_end].x = line_width; + pos[log_end].y = lines; + pos[log_end].valid = 1; + } + + if (getcharwidth && k != visual_len) + line_width += last_width = getcharwidth (&visual[k], getcharwidth_arg); + + if (k != visual_len && (visual[k].base == ' ' + || visual[k].base == '\t') + && !primitive_wrap) + { + last_space = k; + last_space_width = line_width; + } + + if (((grub_ssize_t) maxwidth > 0 + && line_width > (grub_ssize_t) maxwidth) || k == visual_len) + { + unsigned min_odd_level = 0xffffffff; + unsigned max_level = 0; + unsigned kk = k; + + lines++; + + if (k != visual_len && last_space > (signed) line_start) + { + kk = last_space; + line_width -= last_space_width; + } + else if (k != visual_len && line_start == 0 && startwidth != 0 + && !primitive_wrap && lines == 1 + && line_width - startwidth < maxwidth) + { + kk = 0; + line_width -= startwidth; + } + else + line_width = last_width; + + { + unsigned i; + for (i = line_start; i < kk; i++) + { + if (visual[i].bidi_level > max_level) + max_level = visual[i].bidi_level; + if (visual[i].bidi_level < min_odd_level && (visual[i].bidi_level & 1)) + min_odd_level = visual[i].bidi_level; + } + } + + { + unsigned j; + /* FIXME: can be optimized. */ + for (j = max_level; j > min_odd_level - 1; j--) + { + unsigned in = line_start; + unsigned i; + for (i = line_start; i < kk; i++) + { + if (i != line_start && visual[i].bidi_level >= j + && visual[i-1].bidi_level < j) + in = i; + if (visual[i].bidi_level >= j && (i + 1 == kk + || visual[i+1].bidi_level < j)) + revert (visual, pos, in, i); + } + } + } + + { + unsigned i; + for (i = line_start; i < kk; i++) + { + if (is_mirrored (visual[i].base) && visual[i].bidi_level) + visual[i].attributes |= GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR; + if ((visual[i].attributes & GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN) + && visual[i].bidi_level) + { + int left, right; + left = visual[i].attributes + & (GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED + | GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED_EXPLICIT); + right = visual[i].attributes + & (GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED + | GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED_EXPLICIT); + visual[i].attributes &= ~GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN; + left <<= GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN_LEFT_TO_RIGHT_SHIFT; + right >>= GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN_LEFT_TO_RIGHT_SHIFT; + visual[i].attributes |= (left | right); + } + } + } + + { + int left_join = 0; + unsigned i; + for (i = line_start; i < kk; i++) + { + enum grub_join_type join_type = get_join_type (visual[i].base); + if (!(visual[i].attributes + & GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED_EXPLICIT) + && (join_type == GRUB_JOIN_TYPE_LEFT + || join_type == GRUB_JOIN_TYPE_DUAL)) + { + if (left_join) + visual[i].attributes + |= GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED; + else + visual[i].attributes + &= ~GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED; + } + if (join_type == GRUB_JOIN_TYPE_NONJOINING + || join_type == GRUB_JOIN_TYPE_LEFT) + left_join = 0; + if (join_type == GRUB_JOIN_TYPE_RIGHT + || join_type == GRUB_JOIN_TYPE_DUAL + || join_type == GRUB_JOIN_TYPE_CAUSING) + left_join = 1; + } + } + + { + int right_join = 0; + signed i; + for (i = kk - 1; i >= 0 && (unsigned) i + 1 > line_start; + i--) + { + enum grub_join_type join_type = get_join_type (visual[i].base); + if (!(visual[i].attributes + & GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED_EXPLICIT) + && (join_type == GRUB_JOIN_TYPE_RIGHT + || join_type == GRUB_JOIN_TYPE_DUAL)) + { + if (right_join) + visual[i].attributes + |= GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED; + else + visual[i].attributes + &= ~GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED; + } + if (join_type == GRUB_JOIN_TYPE_NONJOINING + || join_type == GRUB_JOIN_TYPE_RIGHT) + right_join = 0; + if (join_type == GRUB_JOIN_TYPE_LEFT + || join_type == GRUB_JOIN_TYPE_DUAL + || join_type == GRUB_JOIN_TYPE_CAUSING) + right_join = 1; + } + } + + grub_memcpy (outptr, &visual[line_start], + (kk - line_start) * sizeof (visual[0])); + outptr += kk - line_start; + if (kk != visual_len) + { + if (contchar) + { + grub_memset (outptr, 0, sizeof (visual[0])); + outptr->base = contchar; + outptr++; + } + grub_memset (outptr, 0, sizeof (visual[0])); + outptr->base = '\n'; + outptr++; + } + + if ((signed) kk == last_space) + kk++; + + line_start = kk; + if (pos && kk != visual_len) + { + pos[visual[kk].orig_pos].x = 0; + pos[visual[kk].orig_pos].y = lines; + } + } + } + + return outptr - visual_out; +} + + +static grub_ssize_t +grub_bidi_line_logical_to_visual (const grub_uint32_t *logical, + grub_size_t logical_len, + struct grub_unicode_glyph *visual_out, + grub_size_t (*getcharwidth) (const struct grub_unicode_glyph *visual, void *getcharwidth_arg), + void *getcharwidth_arg, + grub_size_t maxwidth, grub_size_t startwidth, + grub_uint32_t contchar, + struct grub_term_pos *pos, + int primitive_wrap, + grub_size_t log_end) +{ + enum grub_bidi_type type = GRUB_BIDI_TYPE_L; + enum override_status {OVERRIDE_NEUTRAL = 0, OVERRIDE_R, OVERRIDE_L}; + unsigned base_level; + enum override_status cur_override; + unsigned i; + unsigned stack_level[GRUB_BIDI_MAX_EXPLICIT_LEVEL + 3]; + enum override_status stack_override[GRUB_BIDI_MAX_EXPLICIT_LEVEL + 3]; + unsigned stack_depth = 0; + unsigned invalid_pushes = 0; + unsigned visual_len = 0; + unsigned run_start, run_end; + struct grub_unicode_glyph *visual; + unsigned cur_level; + int bidi_needed = 0; + +#define push_stack(new_override, new_level) \ + { \ + if (new_level > GRUB_BIDI_MAX_EXPLICIT_LEVEL) \ + { \ + invalid_pushes++; \ + } \ + else \ + { \ + stack_level[stack_depth] = cur_level; \ + stack_override[stack_depth] = cur_override; \ + stack_depth++; \ + cur_level = new_level; \ + cur_override = new_override; \ + } \ + } + +#define pop_stack() \ + { \ + if (invalid_pushes) \ + { \ + invalid_pushes--; \ + } \ + else if (stack_depth) \ + { \ + stack_depth--; \ + cur_level = stack_level[stack_depth]; \ + cur_override = stack_override[stack_depth]; \ + } \ + } + + visual = grub_malloc (sizeof (visual[0]) * logical_len); + if (!visual) + return -1; + + for (i = 0; i < logical_len; i++) + { + type = get_bidi_type (logical[i]); + if (type == GRUB_BIDI_TYPE_L || type == GRUB_BIDI_TYPE_AL + || type == GRUB_BIDI_TYPE_R) + break; + } + if (type == GRUB_BIDI_TYPE_R || type == GRUB_BIDI_TYPE_AL) + base_level = 1; + else + base_level = 0; + + cur_level = base_level; + cur_override = OVERRIDE_NEUTRAL; + { + const grub_uint32_t *lptr; + enum {JOIN_DEFAULT, NOJOIN, JOIN_FORCE} join_state = JOIN_DEFAULT; + int zwj_propagate_to_previous = 0; + for (lptr = logical; lptr < logical + logical_len;) + { + grub_size_t p; + + if (*lptr == GRUB_UNICODE_ZWJ) + { + if (zwj_propagate_to_previous) + { + visual[visual_len - 1].attributes + |= GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED_EXPLICIT + | GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED; + } + zwj_propagate_to_previous = 0; + join_state = JOIN_FORCE; + lptr++; + continue; + } + + if (*lptr == GRUB_UNICODE_ZWNJ) + { + if (zwj_propagate_to_previous) + { + visual[visual_len - 1].attributes + |= GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED_EXPLICIT; + visual[visual_len - 1].attributes + &= ~GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED; + } + zwj_propagate_to_previous = 0; + join_state = NOJOIN; + lptr++; + continue; + } + + /* The tags: deprecated, never used. */ + if (*lptr >= GRUB_UNICODE_TAG_START && *lptr <= GRUB_UNICODE_TAG_END) + continue; + + p = grub_unicode_aglomerate_comb (lptr, logical + logical_len - lptr, + &visual[visual_len]); + visual[visual_len].orig_pos = lptr - logical; + type = get_bidi_type (visual[visual_len].base); + switch (type) + { + case GRUB_BIDI_TYPE_RLE: + bidi_needed = 1; + push_stack (cur_override, (cur_level | 1) + 1); + break; + case GRUB_BIDI_TYPE_RLO: + bidi_needed = 1; + push_stack (OVERRIDE_R, (cur_level | 1) + 1); + break; + case GRUB_BIDI_TYPE_LRE: + push_stack (cur_override, (cur_level & ~1) + 2); + break; + case GRUB_BIDI_TYPE_LRO: + push_stack (OVERRIDE_L, (cur_level & ~1) + 2); + break; + case GRUB_BIDI_TYPE_PDF: + pop_stack (); + break; + case GRUB_BIDI_TYPE_BN: + break; + case GRUB_BIDI_TYPE_R: + case GRUB_BIDI_TYPE_AL: + bidi_needed = 1; + /* Fallthrough. */ + default: + { + if (join_state == JOIN_FORCE) + { + visual[visual_len].attributes + |= GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED_EXPLICIT + | GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED; + } + + if (join_state == NOJOIN) + { + visual[visual_len].attributes + |= GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED_EXPLICIT; + visual[visual_len].attributes + &= ~GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED; + } + + join_state = JOIN_DEFAULT; + zwj_propagate_to_previous = 1; + + visual[visual_len].bidi_level = cur_level; + if (cur_override != OVERRIDE_NEUTRAL) + visual[visual_len].bidi_type = + (cur_override == OVERRIDE_L) ? GRUB_BIDI_TYPE_L + : GRUB_BIDI_TYPE_R; + else + visual[visual_len].bidi_type = type; + visual_len++; + } + } + lptr += p; + } + } + + if (bidi_needed) + { + for (run_start = 0; run_start < visual_len; run_start = run_end) + { + unsigned prev_level, next_level, cur_run_level; + unsigned last_type, last_strong_type; + for (run_end = run_start; run_end < visual_len && + visual[run_end].bidi_level == visual[run_start].bidi_level; run_end++); + if (run_start == 0) + prev_level = base_level; + else + prev_level = visual[run_start - 1].bidi_level; + if (run_end == visual_len) + next_level = base_level; + else + next_level = visual[run_end].bidi_level; + cur_run_level = visual[run_start].bidi_level; + if (prev_level & 1) + last_type = GRUB_BIDI_TYPE_R; + else + last_type = GRUB_BIDI_TYPE_L; + last_strong_type = last_type; + for (i = run_start; i < run_end; i++) + { + switch (visual[i].bidi_type) + { + case GRUB_BIDI_TYPE_NSM: + visual[i].bidi_type = last_type; + break; + case GRUB_BIDI_TYPE_EN: + if (last_strong_type == GRUB_BIDI_TYPE_AL) + visual[i].bidi_type = GRUB_BIDI_TYPE_AN; + break; + case GRUB_BIDI_TYPE_L: + case GRUB_BIDI_TYPE_R: + last_strong_type = visual[i].bidi_type; + break; + case GRUB_BIDI_TYPE_ES: + if (last_type == GRUB_BIDI_TYPE_EN + && i + 1 < run_end + && visual[i + 1].bidi_type == GRUB_BIDI_TYPE_EN) + visual[i].bidi_type = GRUB_BIDI_TYPE_EN; + else + visual[i].bidi_type = GRUB_BIDI_TYPE_ON; + break; + case GRUB_BIDI_TYPE_ET: + { + unsigned j; + if (last_type == GRUB_BIDI_TYPE_EN) + { + visual[i].bidi_type = GRUB_BIDI_TYPE_EN; + break; + } + for (j = i; j < run_end + && visual[j].bidi_type == GRUB_BIDI_TYPE_ET; j++); + if (j != run_end && visual[j].bidi_type == GRUB_BIDI_TYPE_EN) + { + for (; i < run_end + && visual[i].bidi_type == GRUB_BIDI_TYPE_ET; i++) + visual[i].bidi_type = GRUB_BIDI_TYPE_EN; + i--; + break; + } + for (; i < run_end + && visual[i].bidi_type == GRUB_BIDI_TYPE_ET; i++) + visual[i].bidi_type = GRUB_BIDI_TYPE_ON; + i--; + break; + } + break; + case GRUB_BIDI_TYPE_CS: + if (last_type == GRUB_BIDI_TYPE_EN + && i + 1 < run_end + && visual[i + 1].bidi_type == GRUB_BIDI_TYPE_EN) + { + visual[i].bidi_type = GRUB_BIDI_TYPE_EN; + break; + } + if (last_type == GRUB_BIDI_TYPE_AN + && i + 1 < run_end + && (visual[i + 1].bidi_type == GRUB_BIDI_TYPE_AN + || (visual[i + 1].bidi_type == GRUB_BIDI_TYPE_EN + && last_strong_type == GRUB_BIDI_TYPE_AL))) + { + visual[i].bidi_type = GRUB_BIDI_TYPE_EN; + break; + } + visual[i].bidi_type = GRUB_BIDI_TYPE_ON; + break; + case GRUB_BIDI_TYPE_AL: + last_strong_type = visual[i].bidi_type; + visual[i].bidi_type = GRUB_BIDI_TYPE_R; + break; + default: /* Make GCC happy. */ + break; + } + last_type = visual[i].bidi_type; + if (visual[i].bidi_type == GRUB_BIDI_TYPE_EN + && last_strong_type == GRUB_BIDI_TYPE_L) + visual[i].bidi_type = GRUB_BIDI_TYPE_L; + } + if (prev_level & 1) + last_type = GRUB_BIDI_TYPE_R; + else + last_type = GRUB_BIDI_TYPE_L; + for (i = run_start; i < run_end; ) + { + unsigned j; + unsigned next_type; + for (j = i; j < run_end && + (visual[j].bidi_type == GRUB_BIDI_TYPE_B + || visual[j].bidi_type == GRUB_BIDI_TYPE_S + || visual[j].bidi_type == GRUB_BIDI_TYPE_WS + || visual[j].bidi_type == GRUB_BIDI_TYPE_ON); j++); + if (j == i) + { + if (visual[i].bidi_type == GRUB_BIDI_TYPE_L) + last_type = GRUB_BIDI_TYPE_L; + else + last_type = GRUB_BIDI_TYPE_R; + i++; + continue; + } + if (j == run_end) + next_type = (next_level & 1) ? GRUB_BIDI_TYPE_R : GRUB_BIDI_TYPE_L; + else + { + if (visual[j].bidi_type == GRUB_BIDI_TYPE_L) + next_type = GRUB_BIDI_TYPE_L; + else + next_type = GRUB_BIDI_TYPE_R; + } + if (next_type == last_type) + for (; i < j; i++) + visual[i].bidi_type = last_type; + else + for (; i < j; i++) + visual[i].bidi_type = (cur_run_level & 1) ? GRUB_BIDI_TYPE_R + : GRUB_BIDI_TYPE_L; + } + } + + for (i = 0; i < visual_len; i++) + { + if (!(visual[i].bidi_level & 1) && visual[i].bidi_type == GRUB_BIDI_TYPE_R) + { + visual[i].bidi_level++; + continue; + } + if (!(visual[i].bidi_level & 1) && (visual[i].bidi_type == GRUB_BIDI_TYPE_AN + || visual[i].bidi_type == GRUB_BIDI_TYPE_EN)) + { + visual[i].bidi_level += 2; + continue; + } + if ((visual[i].bidi_level & 1) && (visual[i].bidi_type == GRUB_BIDI_TYPE_L + || visual[i].bidi_type == GRUB_BIDI_TYPE_AN + || visual[i].bidi_type == GRUB_BIDI_TYPE_EN)) + { + visual[i].bidi_level++; + continue; + } + } + } + else + { + for (i = 0; i < visual_len; i++) + visual[i].bidi_level = 0; + } + + { + grub_ssize_t ret; + ret = bidi_line_wrap (visual_out, visual, visual_len, + getcharwidth, getcharwidth_arg, maxwidth, startwidth, contchar, + pos, primitive_wrap, log_end); + grub_free (visual); + return ret; + } +} + +static int +is_visible (const struct grub_unicode_glyph *gl) +{ + if (gl->ncomb) + return 1; + if (gl->base == GRUB_UNICODE_LRM || gl->base == GRUB_UNICODE_RLM) + return 0; + return 1; +} + +grub_ssize_t +grub_bidi_logical_to_visual (const grub_uint32_t *logical, + grub_size_t logical_len, + struct grub_unicode_glyph **visual_out, + grub_size_t (*getcharwidth) (const struct grub_unicode_glyph *visual, void *getcharwidth_arg), + void *getcharwidth_arg, + grub_size_t max_length, grub_size_t startwidth, + grub_uint32_t contchar, struct grub_term_pos *pos, int primitive_wrap) +{ + const grub_uint32_t *line_start = logical, *ptr; + struct grub_unicode_glyph *visual_ptr; + *visual_out = visual_ptr = grub_malloc (3 * sizeof (visual_ptr[0]) + * (logical_len + 2)); + if (!visual_ptr) + return -1; + for (ptr = logical; ptr <= logical + logical_len; ptr++) + { + if (ptr == logical + logical_len || *ptr == '\n') + { + grub_ssize_t ret; + grub_ssize_t i, j; + ret = grub_bidi_line_logical_to_visual (line_start, + ptr - line_start, + visual_ptr, + getcharwidth, + getcharwidth_arg, + max_length, + startwidth, + contchar, + pos, + primitive_wrap, + logical_len); + startwidth = 0; + + if (ret < 0) + { + grub_free (*visual_out); + return ret; + } + for (i = 0, j = 0; i < ret; i++) + if (is_visible(&visual_ptr[i])) + visual_ptr[j++] = visual_ptr[i]; + visual_ptr += j; + line_start = ptr; + if (ptr != logical + logical_len) + { + grub_memset (visual_ptr, 0, sizeof (visual_ptr[0])); + visual_ptr->base = '\n'; + visual_ptr++; + line_start++; + } + } + } + return visual_ptr - *visual_out; +} + +grub_uint32_t +grub_unicode_mirror_code (grub_uint32_t in) +{ + int i; + for (i = 0; grub_unicode_bidi_pairs[i].key; i++) + if (grub_unicode_bidi_pairs[i].key == in) + return grub_unicode_bidi_pairs[i].replace; + return in; +} + +grub_uint32_t +grub_unicode_shape_code (grub_uint32_t in, grub_uint8_t attr) +{ + int i; + if (!(in >= GRUB_UNICODE_ARABIC_START + && in < GRUB_UNICODE_ARABIC_END)) + return in; + + for (i = 0; grub_unicode_arabic_shapes[i].code; i++) + if (grub_unicode_arabic_shapes[i].code == in) + { + grub_uint32_t out = 0; + switch (attr & (GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED + | GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED)) + { + case 0: + out = grub_unicode_arabic_shapes[i].isolated; + break; + case GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED: + out = grub_unicode_arabic_shapes[i].right_linked; + break; + case GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED: + out = grub_unicode_arabic_shapes[i].left_linked; + break; + case GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED + |GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED: + out = grub_unicode_arabic_shapes[i].both_linked; + break; + } + if (out) + return out; + } + + return in; +} + +const grub_uint32_t * +grub_unicode_get_comb_start (const grub_uint32_t *str, + const grub_uint32_t *cur) +{ + const grub_uint32_t *ptr; + for (ptr = cur; ptr >= str; ptr--) + { + if (*ptr >= GRUB_UNICODE_VARIATION_SELECTOR_1 + && *ptr <= GRUB_UNICODE_VARIATION_SELECTOR_16) + continue; + + if (*ptr >= GRUB_UNICODE_VARIATION_SELECTOR_17 + && *ptr <= GRUB_UNICODE_VARIATION_SELECTOR_256) + continue; + + enum grub_comb_type comb_type; + comb_type = grub_unicode_get_comb_type (*ptr); + if (comb_type) + continue; + return ptr; + } + return str; +} + +const grub_uint32_t * +grub_unicode_get_comb_end (const grub_uint32_t *end, + const grub_uint32_t *cur) +{ + const grub_uint32_t *ptr; + for (ptr = cur; ptr < end; ptr++) + { + if (*ptr >= GRUB_UNICODE_VARIATION_SELECTOR_1 + && *ptr <= GRUB_UNICODE_VARIATION_SELECTOR_16) + continue; + + if (*ptr >= GRUB_UNICODE_VARIATION_SELECTOR_17 + && *ptr <= GRUB_UNICODE_VARIATION_SELECTOR_256) + continue; + + enum grub_comb_type comb_type; + comb_type = grub_unicode_get_comb_type (*ptr); + if (comb_type) + continue; + return ptr; + } + return end; +} + +int +grub_utf8_get_num_code (const char *src, grub_size_t srcsize) +{ + int count = 0; + grub_uint32_t code = 0; + int num = 0; + + while (srcsize) + { + if (srcsize != (grub_size_t) -1) + srcsize--; + if (!grub_utf8_process ((grub_uint8_t)*src++, &code, &count)) + return 0; + if (count != 0) + continue; + if (code == 0 || code > GRUB_UNICODE_LAST_VALID) + return num; + ++num; + } + return num; +} + +const char * +grub_utf8_offset_code (const char *src, grub_size_t srcsize, int num) +{ + int count = 0; + grub_uint32_t code = 0; + + while (srcsize && num) + { + if (srcsize != (grub_size_t) -1) + srcsize--; + if (!grub_utf8_process ((grub_uint8_t)*src++, &code, &count)) + return 0; + if (count != 0) + continue; + if (code == 0 || code > GRUB_UNICODE_LAST_VALID) + return 0; + --num; + } + + if (!num) + return src; + + return 0; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/context.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/context.c new file mode 100644 index 0000000..9ed3c8d --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/context.c @@ -0,0 +1,214 @@ +/* env.c - Environment variables */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +struct menu_pointer +{ + grub_menu_t menu; + struct menu_pointer *prev; +}; + +static struct menu_pointer initial_menu; +static struct menu_pointer *current_menu = &initial_menu; + +void +grub_env_unset_menu (void) +{ + current_menu->menu = NULL; +} + +grub_menu_t +grub_env_get_menu (void) +{ + return current_menu->menu; +} + +void +grub_env_set_menu (grub_menu_t nmenu) +{ + current_menu->menu = nmenu; +} + +static grub_err_t +grub_env_new_context (int export_all) +{ + struct grub_env_context *context; + int i; + struct menu_pointer *menu; + + context = grub_zalloc (sizeof (*context)); + if (! context) + return grub_errno; + menu = grub_zalloc (sizeof (*menu)); + if (! menu) + { + grub_free (context); + return grub_errno; + } + + context->prev = grub_current_context; + grub_current_context = context; + + menu->prev = current_menu; + current_menu = menu; + + /* Copy exported variables. */ + for (i = 0; i < HASHSZ; i++) + { + struct grub_env_var *var; + + for (var = context->prev->vars[i]; var; var = var->next) + if (var->global || export_all) + { + if (grub_env_set (var->name, var->value) != GRUB_ERR_NONE) + { + grub_env_context_close (); + return grub_errno; + } + grub_env_export (var->name); + grub_register_variable_hook (var->name, var->read_hook, var->write_hook); + } + } + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_env_context_open (void) +{ + return grub_env_new_context (grub_env_get("ventoy_new_context") ? 0 : 1); +} + +int grub_extractor_level = 0; + +grub_err_t +grub_env_extractor_open (int source) +{ + grub_extractor_level++; + return grub_env_new_context (source); +} + +grub_err_t +grub_env_context_close (void) +{ + struct grub_env_context *context; + int i; + struct menu_pointer *menu; + + if (! grub_current_context->prev) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "cannot close the initial context"); + + /* Free the variables associated with this context. */ + for (i = 0; i < HASHSZ; i++) + { + struct grub_env_var *p, *q; + + for (p = grub_current_context->vars[i]; p; p = q) + { + q = p->next; + grub_free (p->name); + grub_free (p->value); + grub_free (p); + } + } + + /* Restore the previous context. */ + context = grub_current_context->prev; + grub_free (grub_current_context); + grub_current_context = context; + + menu = current_menu->prev; + if (current_menu->menu) + grub_normal_free_menu (current_menu->menu); + grub_free (current_menu); + current_menu = menu; + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_env_extractor_close (int source) +{ + grub_menu_t menu = NULL; + grub_menu_entry_t *last; + grub_err_t err; + + if (source) + { + menu = grub_env_get_menu (); + grub_env_unset_menu (); + } + err = grub_env_context_close (); + + if (source && menu) + { + grub_menu_t menu2; + menu2 = grub_env_get_menu (); + + last = &menu2->entry_list; + while (*last) + last = &(*last)->next; + + *last = menu->entry_list; + menu2->size += menu->size; + } + + grub_extractor_level--; + return err; +} + +static grub_command_t export_cmd; + +static grub_err_t +grub_cmd_export (struct grub_command *cmd __attribute__ ((unused)), + int argc, char **args) +{ + int i; + + if (argc < 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("one argument expected")); + + for (i = 0; i < argc; i++) + grub_env_export (args[i]); + + return 0; +} + +void +grub_context_init (void) +{ + export_cmd = grub_register_command ("export", grub_cmd_export, + N_("ENVVAR [ENVVAR] ..."), + N_("Export variables.")); +} + +void +grub_context_fini (void) +{ + grub_unregister_command (export_cmd); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/main.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/main.c new file mode 100644 index 0000000..bc29d3b --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/main.c @@ -0,0 +1,575 @@ +/* main.c - the normal mode main routine */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2000,2001,2002,2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +#define GRUB_DEFAULT_HISTORY_SIZE 50 + +static int nested_level = 0; +int grub_normal_exit_level = 0; + +void +grub_normal_free_menu (grub_menu_t menu) +{ + grub_menu_entry_t entry = menu->entry_list; + + while (entry) + { + grub_menu_entry_t next_entry = entry->next; + grub_size_t i; + + if (entry->classes) + { + struct grub_menu_entry_class *class; + for (class = entry->classes; class; class = class->next) + grub_free (class->name); + grub_free (entry->classes); + } + + if (entry->args) + { + for (i = 0; entry->args[i]; i++) + grub_free (entry->args[i]); + grub_free (entry->args); + } + + if (entry->bls) + { + entry->bls->visible = 0; + } + + grub_free ((void *) entry->id); + grub_free ((void *) entry->users); + grub_free ((void *) entry->title); + grub_free ((void *) entry->sourcecode); + grub_free (entry); + entry = next_entry; + } + + grub_free (menu); + grub_env_unset_menu (); +} + +/* Helper for read_config_file. */ +static grub_err_t +read_config_file_getline (char **line, int cont __attribute__ ((unused)), + void *data) +{ + grub_file_t file = data; + + while (1) + { + char *buf; + + *line = buf = grub_file_getline (file); + if (! buf) + return grub_errno; + + if (buf[0] == '#') + grub_free (*line); + else + break; + } + + return GRUB_ERR_NONE; +} + +static grub_menu_t +read_config_file (const char *config) +{ + grub_file_t rawfile, file; + char *old_file = 0, *old_dir = 0; + char *config_dir, *ptr = 0; + const char *ctmp; + + grub_menu_t newmenu; + + newmenu = grub_env_get_menu (); + if (! newmenu) + { + newmenu = grub_zalloc (sizeof (*newmenu)); + if (! newmenu) + return 0; + + grub_env_set_menu (newmenu); + } + + /* Try to open the config file. */ + rawfile = grub_file_open (config, GRUB_FILE_TYPE_CONFIG); + if (! rawfile) + return 0; + + file = grub_bufio_open (rawfile, 0); + if (! file) + { + grub_file_close (rawfile); + return 0; + } + + ctmp = grub_env_get ("config_file"); + if (ctmp) + old_file = grub_strdup (ctmp); + ctmp = grub_env_get ("config_directory"); + if (ctmp) + old_dir = grub_strdup (ctmp); + if (*config == '(') + { + grub_env_set ("config_file", config); + config_dir = grub_strdup (config); + } + else + { + /* $root is guranteed to be defined, otherwise open above would fail */ + config_dir = grub_xasprintf ("(%s)%s", grub_env_get ("root"), config); + if (config_dir) + grub_env_set ("config_file", config_dir); + } + if (config_dir) + { + ptr = grub_strrchr (config_dir, '/'); + if (ptr) + *ptr = 0; + grub_env_set ("config_directory", config_dir); + grub_free (config_dir); + } + + grub_env_export ("config_file"); + grub_env_export ("config_directory"); + + while (1) + { + char *line; + + /* Print an error, if any. */ + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + + if ((read_config_file_getline (&line, 0, file)) || (! line)) + break; + + grub_normal_parse_line (line, read_config_file_getline, file); + grub_free (line); + } + + if (old_file) + grub_env_set ("config_file", old_file); + else + grub_env_unset ("config_file"); + if (old_dir) + grub_env_set ("config_directory", old_dir); + else + grub_env_unset ("config_directory"); + grub_free (old_file); + grub_free (old_dir); + + grub_file_close (file); + + return newmenu; +} + +/* Initialize the screen. */ +void +grub_normal_init_page (struct grub_term_output *term, + int y) +{ + grub_ssize_t msg_len; + int posx; + char *msg_formatted; + grub_uint32_t *unicode_msg; + grub_uint32_t *last_position; + + grub_term_cls (term); + + msg_formatted = grub_xasprintf (_("GNU GRUB version %s"), PACKAGE_VERSION); + if (!msg_formatted) + return; + + msg_len = grub_utf8_to_ucs4_alloc (msg_formatted, + &unicode_msg, &last_position); + grub_free (msg_formatted); + + if (msg_len < 0) + { + return; + } + + posx = grub_getstringwidth (unicode_msg, last_position, term); + posx = ((int) grub_term_width (term) - posx) / 2; + if (posx < 0) + posx = 0; + grub_term_gotoxy (term, (struct grub_term_coordinate) { posx, y }); + + grub_print_ucs4 (unicode_msg, last_position, 0, 0, term); + grub_putcode ('\n', term); + grub_putcode ('\n', term); + grub_free (unicode_msg); +} + +static void +read_lists (const char *val) +{ + if (! grub_no_modules) + { + read_command_list (val); + read_fs_list (val); + read_crypto_list (val); + read_terminal_list (val); + } + grub_gettext_reread_prefix (val); +} + +static char * +read_lists_hook (struct grub_env_var *var __attribute__ ((unused)), + const char *val) +{ + read_lists (val); + return val ? grub_strdup (val) : NULL; +} + +/* Read the config file CONFIG and execute the menu interface or + the command line interface if BATCH is false. */ +void +grub_normal_execute (const char *config, int nested, int batch) +{ + grub_menu_t menu = 0; + const char *prefix; + + if (! nested) + { + prefix = grub_env_get ("prefix"); + read_lists (prefix); + grub_register_variable_hook ("prefix", NULL, read_lists_hook); + } + + grub_boot_time ("Executing config file"); + + if (config) + { + menu = read_config_file (config); + + /* Ignore any error. */ + grub_errno = GRUB_ERR_NONE; + } + + grub_boot_time ("Executed config file"); + + if (! batch) + { + if (menu && menu->size) + { + + grub_boot_time ("Entering menu"); + grub_show_menu (menu, nested, 0); + if (nested) + grub_normal_free_menu (menu); + } + } +} + +/* This starts the normal mode. */ +void +grub_enter_normal_mode (const char *config) +{ + grub_boot_time ("Entering normal mode"); + nested_level++; + grub_normal_execute (config, 0, 0); + grub_boot_time ("Entering shell"); + grub_cmdline_run (0, 1); + nested_level--; + if (grub_normal_exit_level) + grub_normal_exit_level--; + grub_boot_time ("Exiting normal mode"); +} + +/* Enter normal mode from rescue mode. */ +static grub_err_t +grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + if (argc == 0) + { + /* Guess the config filename. It is necessary to make CONFIG static, + so that it won't get broken by longjmp. */ + char *config; + const char *prefix; + + prefix = grub_env_get ("prefix"); + if (prefix) + { + config = grub_xasprintf ("%s/grub.cfg", prefix); + if (! config) + goto quit; + + grub_enter_normal_mode (config); + grub_free (config); + } + else + grub_enter_normal_mode (0); + } + else + grub_enter_normal_mode (argv[0]); + +quit: + return 0; +} + +/* Exit from normal mode to rescue mode. */ +static grub_err_t +grub_cmd_normal_exit (struct grub_command *cmd __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char *argv[] __attribute__ ((unused))) +{ + if (nested_level <= grub_normal_exit_level) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "not in normal environment"); + grub_normal_exit_level++; + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_normal_reader_init (int nested) +{ + struct grub_term_output *term; + const char *msg_esc = _("ESC at any time exits."); + char *msg_formatted; + + msg_formatted = grub_xasprintf (_("Minimal BASH-like line editing is supported. For " + "the first word, TAB lists possible command completions. Anywhere " + "else TAB lists possible device or file completions. %s"), + nested ? msg_esc : ""); + if (!msg_formatted) + return grub_errno; + + FOR_ACTIVE_TERM_OUTPUTS(term) + { + grub_normal_init_page (term, 1); + grub_term_setcursor (term, 1); + + if (grub_term_width (term) > 3 + STANDARD_MARGIN + 20) + grub_print_message_indented (msg_formatted, 3, STANDARD_MARGIN, term); + else + grub_print_message_indented (msg_formatted, 0, 0, term); + grub_putcode ('\n', term); + grub_putcode ('\n', term); + grub_putcode ('\n', term); + } + grub_free (msg_formatted); + + return 0; +} + +static grub_err_t +grub_normal_read_line_real (char **line, int cont, int nested) +{ + const char *prompt; + + if (cont) + /* TRANSLATORS: it's command line prompt. */ + prompt = _(">"); + else + /* TRANSLATORS: it's command line prompt. */ + prompt = _("grub>"); + + if (!prompt) + return grub_errno; + + while (1) + { + *line = grub_cmdline_get (prompt); + if (*line) + return 0; + + if (cont || nested) + { + grub_free (*line); + *line = 0; + return grub_errno; + } + } + +} + +static grub_err_t +grub_normal_read_line (char **line, int cont, + void *data __attribute__ ((unused))) +{ + return grub_normal_read_line_real (line, cont, 0); +} + +void +grub_cmdline_run (int nested, int force_auth) +{ + grub_err_t err = GRUB_ERR_NONE; + + do + { + err = grub_auth_check_authentication (NULL); + } + while (err && force_auth); + + if (err) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + return; + } + + grub_normal_reader_init (nested); + + while (1) + { + char *line = NULL; + + if (grub_normal_exit_level) + break; + + /* Print an error, if any. */ + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + + grub_normal_read_line_real (&line, 0, nested); + if (! line) + break; + + grub_normal_parse_line (line, grub_normal_read_line, NULL); + grub_free (line); + } +} + +static char * +grub_env_write_pager (struct grub_env_var *var __attribute__ ((unused)), + const char *val) +{ + grub_set_more ((*val == '1')); + return grub_strdup (val); +} + +/* clear */ +static grub_err_t +grub_mini_cmd_clear (struct grub_command *cmd __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char *argv[] __attribute__ ((unused))) +{ + grub_cls (); + return 0; +} + +static grub_command_t cmd_clear; + +static void (*grub_xputs_saved) (const char *str); +static const char *features[] = { + "feature_chainloader_bpb", "feature_ntldr", "feature_platform_search_hint", + "feature_default_font_path", "feature_all_video_module", + "feature_menuentry_id", "feature_menuentry_options", "feature_200_final", + "feature_nativedisk_cmd", "feature_timeout_style" +}; + +GRUB_MOD_INIT(normal) +{ + unsigned i; + + grub_boot_time ("Preparing normal module"); + + /* Previously many modules depended on gzio. Be nice to user and load it. */ + grub_dl_load ("gzio"); + grub_errno = 0; + + grub_normal_auth_init (); + grub_context_init (); + grub_script_init (); + grub_menu_init (); + + grub_xputs_saved = grub_xputs; + grub_xputs = grub_xputs_normal; + + /* Normal mode shouldn't be unloaded. */ + if (mod) + grub_dl_ref (mod); + + cmd_clear = + grub_register_command ("clear", grub_mini_cmd_clear, + 0, N_("Clear the screen.")); + + grub_set_history (GRUB_DEFAULT_HISTORY_SIZE); + + grub_register_variable_hook ("pager", 0, grub_env_write_pager); + grub_env_export ("pager"); + + /* Register a command "normal" for the rescue mode. */ + grub_register_command ("normal", grub_cmd_normal, + 0, N_("Enter normal mode.")); + grub_register_command ("normal_exit", grub_cmd_normal_exit, + 0, N_("Exit from normal mode.")); + + /* Reload terminal colors when these variables are written to. */ + grub_register_variable_hook ("color_normal", NULL, grub_env_write_color_normal); + grub_register_variable_hook ("color_highlight", NULL, grub_env_write_color_highlight); + + /* Preserve hooks after context changes. */ + grub_env_export ("color_normal"); + grub_env_export ("color_highlight"); + + /* Set default color names. */ + grub_env_set ("color_normal", "light-gray/black"); + grub_env_set ("color_highlight", "black/light-gray"); + + for (i = 0; i < ARRAY_SIZE (features); i++) + { + grub_env_set (features[i], "y"); + grub_env_export (features[i]); + } + grub_env_set ("grub_cpu", GRUB_TARGET_CPU); + grub_env_export ("grub_cpu"); + grub_env_set ("grub_platform", GRUB_PLATFORM); + grub_env_export ("grub_platform"); + + grub_boot_time ("Normal module prepared"); +} + +GRUB_MOD_FINI(normal) +{ + grub_context_fini (); + grub_script_fini (); + grub_menu_fini (); + grub_normal_auth_fini (); + + grub_xputs = grub_xputs_saved; + + grub_set_history (0); + grub_register_variable_hook ("pager", 0, 0); + grub_fs_autoload_hook = 0; + grub_unregister_command (cmd_clear); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/menu.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/menu.c new file mode 100644 index 0000000..d493479 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/menu.c @@ -0,0 +1,1234 @@ +/* menu.c - General supporting functionality for menus. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ventoy/ventoy_def.h" + +int g_ventoy_menu_refresh = 0; +int g_ventoy_memdisk_mode = 0; +int g_ventoy_iso_raw = 0; +int g_ventoy_grub2_mode = 0; +int g_ventoy_wimboot_mode = 0; +int g_ventoy_iso_uefi_drv = 0; +int g_ventoy_last_entry = -1; +int g_ventoy_suppress_esc = 0; +int g_ventoy_suppress_esc_default = 1; +int g_ventoy_menu_esc = 0; +int g_ventoy_fn_mutex = 0; +int g_ventoy_secondary_menu_on = 0; +int g_ventoy_terminal_output = 0; +char g_ventoy_hotkey_tip[256]; + +static int g_vt_key_num = 0; +static int g_vt_key_code[128]; + +static int ventoy_menu_pop_key(void) +{ + if (g_vt_key_num > 0 && g_vt_key_num < (int)(sizeof(g_vt_key_code) / sizeof(g_vt_key_code[0]))) + { + g_vt_key_num--; + return g_vt_key_code[g_vt_key_num]; + } + return -1; +} + +int ventoy_menu_push_key(int code) +{ + if (g_vt_key_num >= 0 && g_vt_key_num < (int)(sizeof(g_vt_key_code) / sizeof(g_vt_key_code[0]))) + { + g_vt_key_code[g_vt_key_num++] = code; + return 0; + } + return -1; +} + +#define VTOY_COMM_HOTKEY(cmdkey) \ +if (0 == g_ventoy_fn_mutex && 0 == g_ventoy_secondary_menu_on) { \ + cmdstr = grub_env_get(cmdkey); \ + if (cmdstr) \ + { \ + menu_fini (); \ + g_ventoy_fn_mutex = 1; \ + grub_script_execute_sourcecode(cmdstr); \ + g_ventoy_fn_mutex = 0; \ + goto refresh; \ + } \ +} + +/* Time to delay after displaying an error message about a default/fallback + entry failing to boot. */ +#define DEFAULT_ENTRY_ERROR_DELAY_MS 2500 + +grub_err_t (*grub_gfxmenu_try_hook) (int entry, grub_menu_t menu, + int nested) = NULL; + +enum timeout_style { + TIMEOUT_STYLE_MENU, + TIMEOUT_STYLE_COUNTDOWN, + TIMEOUT_STYLE_HIDDEN +}; + +struct timeout_style_name { + const char *name; + enum timeout_style style; +} timeout_style_names[] = { + {"menu", TIMEOUT_STYLE_MENU}, + {"countdown", TIMEOUT_STYLE_COUNTDOWN}, + {"hidden", TIMEOUT_STYLE_HIDDEN}, + {NULL, 0} +}; + +/* Wait until the user pushes any key so that the user + can see what happened. */ +void +grub_wait_after_message (void) +{ + grub_uint64_t endtime; + grub_xputs ("\n"); + grub_printf_ (N_("Press any key to continue...")); + grub_refresh (); + + endtime = grub_get_time_ms () + 10000; + + while (grub_get_time_ms () < endtime + && grub_getkey_noblock () == GRUB_TERM_NO_KEY); + + grub_xputs ("\n"); +} + +/* Get a menu entry by its index in the entry list. */ +grub_menu_entry_t +grub_menu_get_entry (grub_menu_t menu, int no) +{ + grub_menu_entry_t e; + + for (e = menu->entry_list; e && no > 0; e = e->next, no--) + ; + + return e; +} + +/* Get the index of a menu entry associated with a given hotkey, or -1. */ +static int +get_entry_index_by_hotkey (grub_menu_t menu, int hotkey) +{ + grub_menu_entry_t entry; + int i; + + for (i = 0, entry = menu->entry_list; i < menu->size; + i++, entry = entry->next) + if (entry->hotkey == hotkey) + return i; + + return -1; +} + +/* Return the timeout style. If the variable "timeout_style" is not set or + invalid, default to TIMEOUT_STYLE_MENU. */ +static enum timeout_style +get_timeout_style (void) +{ + const char *val; + struct timeout_style_name *style_name; + + val = grub_env_get ("timeout_style"); + if (!val) + return TIMEOUT_STYLE_MENU; + + for (style_name = timeout_style_names; style_name->name; style_name++) + if (grub_strcmp (style_name->name, val) == 0) + return style_name->style; + + return TIMEOUT_STYLE_MENU; +} + +/* Return the current timeout. If the variable "timeout" is not set or + invalid, return -1. */ +int +grub_menu_get_timeout (void) +{ + const char *val; + int timeout; + + val = grub_env_get ("timeout"); + if (! val) + return -1; + + grub_error_push (); + + timeout = (int) grub_strtoul (val, 0, 0); + + /* If the value is invalid, unset the variable. */ + if (grub_errno != GRUB_ERR_NONE) + { + grub_env_unset ("timeout"); + grub_errno = GRUB_ERR_NONE; + timeout = -1; + } + + grub_error_pop (); + + return timeout; +} + +/* Set current timeout in the variable "timeout". */ +void +grub_menu_set_timeout (int timeout) +{ + /* Ignore TIMEOUT if it is zero, because it will be unset really soon. */ + if (timeout > 0) + { + char buf[16]; + + grub_snprintf (buf, sizeof (buf), "%d", timeout); + grub_env_set ("timeout", buf); + } +} + +/* Get the first entry number from the value of the environment variable NAME, + which is a space-separated list of non-negative integers. The entry number + which is returned is stripped from the value of NAME. If no entry number + can be found, -1 is returned. */ +static int +get_and_remove_first_entry_number (const char *name) +{ + const char *val; + char *tail; + int entry; + + val = grub_env_get (name); + if (! val) + return -1; + + grub_error_push (); + + entry = (int) grub_strtoul (val, &tail, 0); + + if (grub_errno == GRUB_ERR_NONE) + { + /* Skip whitespace to find the next digit. */ + while (*tail && grub_isspace (*tail)) + tail++; + grub_env_set (name, tail); + } + else + { + grub_env_unset (name); + grub_errno = GRUB_ERR_NONE; + entry = -1; + } + + grub_error_pop (); + + return entry; +} + +/* Run a menu entry. */ +static void +grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot) +{ + grub_err_t err = GRUB_ERR_NONE; + int errs_before; + grub_menu_t menu = NULL; + char *optr, *buf, *oldchosen = NULL, *olddefault = NULL; + const char *ptr, *chosen, *def; + grub_size_t sz = 0; + + if (entry->restricted) + err = grub_auth_check_authentication (entry->users); + + if (err) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + return; + } + + errs_before = grub_err_printed_errors; + + chosen = grub_env_get ("chosen"); + def = grub_env_get ("default"); + + if (entry->submenu) + { + grub_env_context_open (); + menu = grub_zalloc (sizeof (*menu)); + if (! menu) + return; + grub_env_set_menu (menu); + if (auto_boot) + grub_env_set ("timeout", "0"); + } + + for (ptr = entry->id; *ptr; ptr++) + sz += (*ptr == '>') ? 2 : 1; + if (chosen) + { + oldchosen = grub_strdup (chosen); + if (!oldchosen) + grub_print_error (); + } + if (def) + { + olddefault = grub_strdup (def); + if (!olddefault) + grub_print_error (); + } + sz++; + if (chosen) + sz += grub_strlen (chosen); + sz++; + buf = grub_malloc (sz); + if (!buf) + grub_print_error (); + else + { + optr = buf; + if (chosen) + { + optr = grub_stpcpy (optr, chosen); + *optr++ = '>'; + } + for (ptr = entry->id; *ptr; ptr++) + { + if (*ptr == '>') + *optr++ = '>'; + *optr++ = *ptr; + } + *optr = 0; + grub_env_set ("chosen", buf); + grub_env_export ("chosen"); + grub_free (buf); + } + + for (ptr = def; ptr && *ptr; ptr++) + { + if (ptr[0] == '>' && ptr[1] == '>') + { + ptr++; + continue; + } + if (ptr[0] == '>') + break; + } + + if (ptr && ptr[0] && ptr[1]) + grub_env_set ("default", ptr + 1); + else + grub_env_unset ("default"); + + grub_script_execute_new_scope (entry->sourcecode, entry->argc, entry->args); + + if (errs_before != grub_err_printed_errors) + grub_wait_after_message (); + + errs_before = grub_err_printed_errors; + + if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ()) + /* Implicit execution of boot, only if something is loaded. */ + grub_command_execute ("boot", 0, 0); + + if (errs_before != grub_err_printed_errors) + grub_wait_after_message (); + + if (entry->submenu) + { + if (menu && menu->size) + { + grub_show_menu (menu, 1, auto_boot); + grub_normal_free_menu (menu); + } + grub_env_context_close (); + } + if (oldchosen) + grub_env_set ("chosen", oldchosen); + else + grub_env_unset ("chosen"); + if (olddefault) + grub_env_set ("default", olddefault); + else + grub_env_unset ("default"); + grub_env_unset ("timeout"); +} + +/* Execute ENTRY from the menu MENU, falling back to entries specified + in the environment variable "fallback" if it fails. CALLBACK is a + pointer to a struct of function pointers which are used to allow the + caller provide feedback to the user. */ +static void +grub_menu_execute_with_fallback (grub_menu_t menu, + grub_menu_entry_t entry, + int autobooted, + grub_menu_execute_callback_t callback, + void *callback_data) +{ + int fallback_entry; + + callback->notify_booting (entry, callback_data); + + grub_menu_execute_entry (entry, 1); + + /* Deal with fallback entries. */ + while ((fallback_entry = get_and_remove_first_entry_number ("fallback")) + >= 0) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + + entry = grub_menu_get_entry (menu, fallback_entry); + callback->notify_fallback (entry, callback_data); + grub_menu_execute_entry (entry, 1); + /* If the function call to execute the entry returns at all, then this is + taken to indicate a boot failure. For menu entries that do something + other than actually boot an operating system, this could assume + incorrectly that something failed. */ + } + + if (!autobooted) + callback->notify_failure (callback_data); +} + +static struct grub_menu_viewer *viewers; + +int g_menu_update_mode = 0; +int g_ventoy_tip_label_enable = 0; +const char * g_ventoy_tip_msg1 = NULL; +const char * g_ventoy_tip_msg2 = NULL; +char g_ventoy_theme_path[256] = {0}; +static const char *g_ventoy_cur_img_path = NULL; +static void menu_set_chosen_tip(grub_menu_t menu, int entry) +{ + int i; + img_info *img; + menu_tip *tip; + grub_menu_entry_t e = grub_menu_get_entry (menu, entry); + + if (g_ventoy_theme_path[0]) + { + grub_env_set("theme", g_ventoy_theme_path); + } + + g_ventoy_tip_msg1 = g_ventoy_tip_msg2 = NULL; + if (e && e->id && grub_strncmp(e->id, "VID_", 4) == 0) + { + g_ventoy_theme_path[0] = 0; + img = (img_info *)(void *)grub_strtoul(e->id + 4, NULL, 16); + if (img) + { + g_ventoy_tip_msg1 = img->tip1; + g_ventoy_tip_msg2 = img->tip2; + g_ventoy_cur_img_path = img->path; + } + } + else if (e && e->id && grub_strncmp(e->id, "DIR_", 4) == 0) + { + g_ventoy_theme_path[0] = 0; + for (i = 0; i < e->argc; i++) + { + if (e->args[i] && grub_strncmp(e->args[i], "_VTIP_", 6) == 0) + { + break; + } + } + + if (i < e->argc) + { + tip = (menu_tip *)(void *)grub_strtoul(e->args[i] + 6, NULL, 16); + if (tip) + { + g_ventoy_tip_msg1 = tip->tip1; + g_ventoy_tip_msg2 = tip->tip2; + } + } + } +} + +static void +menu_set_chosen_entry (grub_menu_t menu, int entry) +{ + struct grub_menu_viewer *cur; + + menu_set_chosen_tip(menu, entry); + for (cur = viewers; cur; cur = cur->next) + cur->set_chosen_entry (entry, cur->data); +} + +static void +menu_scroll_chosen_entry (int diren) +{ + struct grub_menu_viewer *cur; + for (cur = viewers; cur; cur = cur->next) + if (cur->scroll_chosen_entry) + cur->scroll_chosen_entry (cur->data, diren); +} + +static void +menu_print_timeout (int timeout) +{ + struct grub_menu_viewer *cur; + for (cur = viewers; cur; cur = cur->next) + cur->print_timeout (timeout, cur->data); +} + +static void +menu_fini (void) +{ + struct grub_menu_viewer *cur, *next; + for (cur = viewers; cur; cur = next) + { + next = cur->next; + cur->fini (cur->data); + grub_free (cur); + } + viewers = NULL; +} + +static void +menu_init (int entry, grub_menu_t menu, int nested) +{ + struct grub_term_output *term; + int gfxmenu = 0; + + FOR_ACTIVE_TERM_OUTPUTS(term) + if (term->fullscreen) + { + if (grub_env_get ("theme")) + { + if (!grub_gfxmenu_try_hook) + { + grub_dl_load ("gfxmenu"); + grub_print_error (); + } + if (grub_gfxmenu_try_hook) + { + grub_err_t err; + err = grub_gfxmenu_try_hook (entry, menu, nested); + if(!err) + { + gfxmenu = 1; + break; + } + } + else + grub_error (GRUB_ERR_BAD_MODULE, + N_("module `%s' isn't loaded"), + "gfxmenu"); + grub_print_error (); + grub_wait_after_message (); + } + grub_errno = GRUB_ERR_NONE; + term->fullscreen (); + break; + } + + FOR_ACTIVE_TERM_OUTPUTS(term) + { + grub_err_t err; + + if (grub_strcmp (term->name, "gfxterm") == 0 && gfxmenu) + continue; + + err = grub_menu_try_text (term, entry, menu, nested); + if(!err) + continue; + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + } +} + +static void +clear_timeout (void) +{ + struct grub_menu_viewer *cur; + for (cur = viewers; cur; cur = cur->next) + cur->clear_timeout (cur->data); +} + +void +grub_menu_register_viewer (struct grub_menu_viewer *viewer) +{ + viewer->next = viewers; + viewers = viewer; +} + +static int +menuentry_eq (const char *id, const char *spec) +{ + const char *ptr1, *ptr2; + ptr1 = id; + ptr2 = spec; + while (1) + { + if (*ptr2 == '>' && ptr2[1] != '>' && *ptr1 == 0) + return 1; + if (*ptr2 == '>' && ptr2[1] != '>') + return 0; + if (*ptr2 == '>') + ptr2++; + if (*ptr1 != *ptr2) + return 0; + if (*ptr1 == 0) + return 1; + ptr1++; + ptr2++; + } +} + + +/* Get the entry number from the variable NAME. */ +static int +get_entry_number (grub_menu_t menu, const char *name) +{ + const char *val; + int entry; + + val = grub_env_get (name); + if (! val) + return -1; + + grub_error_push (); + + entry = (int) grub_strtoul (val, 0, 0); + + if (grub_errno == GRUB_ERR_BAD_NUMBER) + { + /* See if the variable matches the title of a menu entry. */ + grub_menu_entry_t e = menu->entry_list; + int i; + + grub_errno = GRUB_ERR_NONE; + + for (i = 0; e; i++) + { + if (menuentry_eq (e->title, val) + || menuentry_eq (e->id, val)) + { + entry = i; + break; + } + e = e->next; + } + + if (! e) + entry = -1; + } + + if (grub_errno != GRUB_ERR_NONE) + { + grub_errno = GRUB_ERR_NONE; + entry = -1; + } + + grub_error_pop (); + + return entry; +} + +/* Check whether a second has elapsed since the last tick. If so, adjust + the timer and return 1; otherwise, return 0. */ +static int +has_second_elapsed (grub_uint64_t *saved_time) +{ + grub_uint64_t current_time; + + current_time = grub_get_time_ms (); + if (current_time - *saved_time >= 1000) + { + *saved_time = current_time; + return 1; + } + else + return 0; +} + +static void +print_countdown (struct grub_term_coordinate *pos, int n) +{ + grub_term_restore_pos (pos); + /* NOTE: Do not remove the trailing space characters. + They are required to clear the line. */ + grub_printf ("%d ", n); + grub_refresh (); +} + +#define GRUB_MENU_PAGE_SIZE 10 + +/* Show the menu and handle menu entry selection. Returns the menu entry + index that should be executed or -1 if no entry should be executed (e.g., + Esc pressed to exit a sub-menu or switching menu viewers). + If the return value is not -1, then *AUTO_BOOT is nonzero iff the menu + entry to be executed is a result of an automatic default selection because + of the timeout. */ +static int +run_menu (grub_menu_t menu, int nested, int *auto_boot) +{ + const char *cmdstr; + grub_uint64_t saved_time; + int default_entry,current_entry; + int timeout; + enum timeout_style timeout_style; + + default_entry = get_entry_number (menu, "default"); + + if (g_ventoy_suppress_esc) + default_entry = g_ventoy_suppress_esc_default; + + /* If DEFAULT_ENTRY is not within the menu entries, fall back to + the first entry. */ + else if (default_entry < 0 || default_entry >= menu->size) + default_entry = 0; + + timeout = grub_menu_get_timeout (); + if (timeout < 0) + /* If there is no timeout, the "countdown" and "hidden" styles result in + the system doing nothing and providing no or very little indication + why. Technically this is what the user asked for, but it's not very + useful and likely to be a source of confusion, so we disallow this. */ + grub_env_unset ("timeout_style"); + + timeout_style = get_timeout_style (); + + if (timeout_style == TIMEOUT_STYLE_COUNTDOWN + || timeout_style == TIMEOUT_STYLE_HIDDEN) + { + static struct grub_term_coordinate *pos; + int entry = -1; + + if (timeout_style == TIMEOUT_STYLE_COUNTDOWN && timeout) + { + pos = grub_term_save_pos (); + print_countdown (pos, timeout); + } + + /* Enter interruptible sleep until Escape or a menu hotkey is pressed, + or the timeout expires. */ + saved_time = grub_get_time_ms (); + while (1) + { + int key; + + key = grub_getkey_noblock (); + if (key != GRUB_TERM_NO_KEY) + { + entry = get_entry_index_by_hotkey (menu, key); + if (entry >= 0) + break; + } + if (key == GRUB_TERM_ESC) + { + timeout = -1; + break; + } + + if (timeout > 0 && has_second_elapsed (&saved_time)) + { + timeout--; + if (timeout_style == TIMEOUT_STYLE_COUNTDOWN) + print_countdown (pos, timeout); + } + + if (timeout == 0) + /* We will fall through to auto-booting the default entry. */ + break; + } + + grub_env_unset ("timeout"); + grub_env_unset ("timeout_style"); + if (entry >= 0) + { + *auto_boot = 0; + return entry; + } + } + + /* If timeout is 0, drawing is pointless (and ugly). */ + if (timeout == 0) + { + *auto_boot = 1; + return default_entry; + } + + current_entry = default_entry; + + refresh: + menu_set_chosen_tip(menu, current_entry); + menu_init (current_entry, menu, nested); + + /* Initialize the time. */ + saved_time = grub_get_time_ms (); + + timeout = grub_menu_get_timeout (); + + if (timeout > 0) + menu_print_timeout (timeout); + else + clear_timeout (); + + while (1) + { + int c; + timeout = grub_menu_get_timeout (); + + if (grub_normal_exit_level) + return -1; + + if (timeout > 0 && has_second_elapsed (&saved_time)) + { + timeout--; + grub_menu_set_timeout (timeout); + menu_print_timeout (timeout); + } + + if (timeout == 0) + { + grub_env_unset ("timeout"); + *auto_boot = 1; + menu_fini (); + return default_entry; + } + + if (g_vt_key_num > 0) { + c = ventoy_menu_pop_key(); + } else { + c = grub_getkey_noblock (); + } + + /* Negative values are returned on error. */ + if ((c != GRUB_TERM_NO_KEY) && (c > 0)) + { + if (timeout >= 0) + { + grub_env_unset ("timeout"); + grub_env_unset ("fallback"); + clear_timeout (); + } + + switch (c) + { + case GRUB_TERM_KEY_HOME: + case GRUB_TERM_CTRL | 'a': + current_entry = 0; + menu_set_chosen_entry (menu, current_entry); + break; + + case GRUB_TERM_KEY_END: + case GRUB_TERM_CTRL | 'e': + current_entry = menu->size - 1; + menu_set_chosen_entry (menu, current_entry); + break; + + case GRUB_TERM_KEY_UP: + case GRUB_TERM_CTRL | 'p': + case '^': + if (current_entry > 0) + current_entry--; + menu_set_chosen_entry (menu, current_entry); + break; + + case GRUB_TERM_CTRL | 'n': + case GRUB_TERM_KEY_DOWN: + case 'v': + if (current_entry < menu->size - 1) + current_entry++; + menu_set_chosen_entry (menu, current_entry); + break; + + case GRUB_TERM_CTRL | 'g': + case GRUB_TERM_KEY_PPAGE: + if (current_entry < GRUB_MENU_PAGE_SIZE) + current_entry = 0; + else + current_entry -= GRUB_MENU_PAGE_SIZE; + menu_set_chosen_entry (menu, current_entry); + break; + + case GRUB_TERM_CTRL | 'c': + case GRUB_TERM_KEY_NPAGE: + if (current_entry + GRUB_MENU_PAGE_SIZE < menu->size) + current_entry += GRUB_MENU_PAGE_SIZE; + else + current_entry = menu->size - 1; + menu_set_chosen_entry (menu, current_entry); + break; + + case GRUB_TERM_KEY_RIGHT: + menu_scroll_chosen_entry (1); + break; + case GRUB_TERM_KEY_LEFT: + menu_scroll_chosen_entry (-1); + break; + case GRUB_TERM_CTRL | GRUB_TERM_KEY_RIGHT: + menu_scroll_chosen_entry (1000000); + break; + case GRUB_TERM_CTRL | GRUB_TERM_KEY_LEFT: + menu_scroll_chosen_entry (-1000000); + break; + + case '\n': + case '\r': + // case GRUB_TERM_KEY_RIGHT: + case GRUB_TERM_CTRL | 'f': + menu_fini (); + *auto_boot = 0; + return current_entry; + + case GRUB_TERM_ESC: + if (nested && 0 == g_ventoy_suppress_esc) + { + menu_fini (); + return -1; + } + break; + + case 'c': + menu_fini (); + grub_cmdline_run (1, 0); + goto refresh; + + case 'e': + menu_fini (); + { + grub_menu_entry_t e = grub_menu_get_entry (menu, current_entry); + if (e) + grub_menu_entry_run (e); + } + goto refresh; + + case GRUB_TERM_KEY_F2: + case '2': + VTOY_COMM_HOTKEY("VTOY_F2_CMD"); + break; + case GRUB_TERM_KEY_F3: + case '3': + VTOY_COMM_HOTKEY("VTOY_F3_CMD"); + break; + case GRUB_TERM_KEY_F4: + case '4': + VTOY_COMM_HOTKEY("VTOY_F4_CMD"); + break; + case GRUB_TERM_KEY_F5: + case '5': + VTOY_COMM_HOTKEY("VTOY_F5_CMD"); + break; + case GRUB_TERM_KEY_F6: + case '6': + VTOY_COMM_HOTKEY("VTOY_F6_CMD"); + break; + case GRUB_TERM_KEY_F7: + menu_fini (); + if (g_ventoy_terminal_output == 0) + { + grub_script_execute_sourcecode("vt_push_menu_lang en_US\nterminal_output console"); + g_ventoy_terminal_output = 1; + } + else + { + grub_script_execute_sourcecode("terminal_output gfxterm\nvt_pop_menu_lang"); + g_ventoy_terminal_output = 0; + } + goto refresh; + case GRUB_TERM_KEY_F1: + case '1': + if (0 == g_ventoy_secondary_menu_on) + { + cmdstr = grub_env_get("VTOY_HELP_CMD"); + if (cmdstr) + { + grub_script_execute_sourcecode(cmdstr); + while (grub_getkey() != GRUB_TERM_ESC) + ; + menu_fini (); + goto refresh; + } + } + break; + case (GRUB_TERM_CTRL | 'd'): + case 'd': + if (0 == g_ventoy_secondary_menu_on) + { + menu_fini (); + g_ventoy_memdisk_mode = 1 - g_ventoy_memdisk_mode; + g_ventoy_menu_refresh = 1; + goto refresh; + } + break; + case (GRUB_TERM_CTRL | 'i'): + case 'i': + if (0 == g_ventoy_secondary_menu_on) + { + menu_fini (); + g_ventoy_iso_raw = 1 - g_ventoy_iso_raw; + g_ventoy_menu_refresh = 1; + goto refresh; + } + break; + case (GRUB_TERM_CTRL | 'r'): + case 'r': + if (0 == g_ventoy_secondary_menu_on) + { + menu_fini (); + g_ventoy_grub2_mode = 1 - g_ventoy_grub2_mode; + g_ventoy_menu_refresh = 1; + goto refresh; + } + break; + case (GRUB_TERM_CTRL | 'w'): + case 'w': + if (0 == g_ventoy_secondary_menu_on) + { + menu_fini (); + g_ventoy_wimboot_mode = 1 - g_ventoy_wimboot_mode; + g_ventoy_menu_refresh = 1; + goto refresh; + } + break; + case (GRUB_TERM_CTRL | 'u'): + case 'u': + if (0 == g_ventoy_secondary_menu_on) + { + menu_fini (); + g_ventoy_iso_uefi_drv = 1 - g_ventoy_iso_uefi_drv; + g_ventoy_menu_refresh = 1; + goto refresh; + } + break; + case (GRUB_TERM_CTRL | 'l'): + case (GRUB_TERM_CTRL | 'L'): + case (GRUB_TERM_SHIFT | 'l'): + case (GRUB_TERM_SHIFT | 'L'): + case 'l': + case 'L': + { + VTOY_COMM_HOTKEY("VTOY_LANG_CMD"); + break; + } + case (GRUB_TERM_CTRL | 'm'): + case 'm': + { + if (0 == g_ventoy_secondary_menu_on) + { + if (g_ventoy_cur_img_path) + { + grub_env_set("VTOY_CHKSUM_FILE_PATH", g_ventoy_cur_img_path); + cmdstr = grub_env_get("VTOY_CHKSUM_CMD"); + if (cmdstr) + { + menu_fini(); + grub_script_execute_sourcecode(cmdstr); + goto refresh; + } + } + else + { + grub_env_set("VTOY_CHKSUM_FILE_PATH", "X"); + } + } + break; + } + default: + { + int entry; + + entry = get_entry_index_by_hotkey (menu, c); + if (entry >= 0) + { + menu_fini (); + *auto_boot = 0; + return entry; + } + } + break; + } + } + } + + /* Never reach here. */ +} + +/* Callback invoked immediately before a menu entry is executed. */ +static void +notify_booting (grub_menu_entry_t entry, + void *userdata __attribute__((unused))) +{ + grub_printf (" "); + grub_printf_ (N_("Booting `%s'"), entry->title); + grub_printf ("\n\n"); +} + +/* Callback invoked when a default menu entry executed because of a timeout + has failed and an attempt will be made to execute the next fallback + entry, ENTRY. */ +static void +notify_fallback (grub_menu_entry_t entry, + void *userdata __attribute__((unused))) +{ + grub_printf ("\n "); + grub_printf_ (N_("Falling back to `%s'"), entry->title); + grub_printf ("\n\n"); + grub_millisleep (DEFAULT_ENTRY_ERROR_DELAY_MS); +} + +/* Callback invoked when a menu entry has failed and there is no remaining + fallback entry to attempt. */ +static void +notify_execution_failure (void *userdata __attribute__((unused))) +{ + if (grub_errno != GRUB_ERR_NONE) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + } + grub_printf ("\n "); + grub_printf_ (N_("Failed to boot both default and fallback entries.\n")); + grub_wait_after_message (); +} + +/* Callbacks used by the text menu to provide user feedback when menu entries + are executed. */ +static struct grub_menu_execute_callback execution_callback = +{ + .notify_booting = notify_booting, + .notify_fallback = notify_fallback, + .notify_failure = notify_execution_failure +}; + +static grub_err_t +show_menu (grub_menu_t menu, int nested, int autobooted) +{ + const char *def; + def = grub_env_get("VTOY_DEFAULT_IMAGE"); + + while (1) + { + int ndown; + char *pos = NULL; + int boot_entry; + grub_menu_entry_t e; + int auto_boot; + + boot_entry = run_menu (menu, nested, &auto_boot); + if (boot_entry < 0) + break; + + if (auto_boot && def && grub_strcmp(def, "VTOY_EXIT") == 0) { + grub_exit(); + } + + if (autobooted == 0 && auto_boot == 0) { + g_ventoy_last_entry = boot_entry; + if (g_ventoy_menu_esc) + break; + } + + if (autobooted == 0 && g_ventoy_menu_esc && auto_boot) { + g_ventoy_last_entry = boot_entry; + break; + } + + e = grub_menu_get_entry (menu, boot_entry); + if (! e) + continue; /* Menu is empty. */ + + if (2 == e->argc && e->args && e->args[1] && grub_strncmp(e->args[1], "VTOY_RET", 8) == 0) + break; + + grub_cls (); + + if (auto_boot) + grub_menu_execute_with_fallback (menu, e, autobooted, + &execution_callback, 0); + else + grub_menu_execute_entry (e, 0); + if (autobooted) + break; + + if (2 == e->argc && e->args && e->args[1] && grub_strncmp(e->args[1], "VTOY_RUN_RET", 12) == 0) + break; + else if (2 == e->argc && e->args && e->args[1] && grub_strncmp(e->args[1], "VTOY_RUN_SET_", 13) == 0) { + pos = NULL; + ndown = (int)grub_strtol(e->args[1] + 13, &pos, 10); + while (ndown > 0) + { + ventoy_menu_push_key(GRUB_TERM_KEY_DOWN); + ndown--; + } + + ventoy_menu_push_key('\n'); + + if (pos && *pos == '_') + { + ndown = (int)grub_strtol(pos + 1, NULL, 10); + while (ndown > 0) + { + ventoy_menu_push_key(GRUB_TERM_KEY_DOWN); + ndown--; + } + } + + break; + } + } + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_show_menu (grub_menu_t menu, int nested, int autoboot) +{ + grub_err_t err1, err2; + + while (1) + { + err1 = show_menu (menu, nested, autoboot); + autoboot = 0; + grub_print_error (); + + if (grub_normal_exit_level) + break; + + err2 = grub_auth_check_authentication (NULL); + if (err2) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + continue; + } + + break; + } + + return err1; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/menu_text.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/menu_text.c new file mode 100644 index 0000000..549d902 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/menu_text.c @@ -0,0 +1,655 @@ +/* menu_text.c - Basic text menu implementation. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static grub_uint8_t grub_color_menu_normal; +static grub_uint8_t grub_color_menu_highlight; + +extern char g_ventoy_hotkey_tip[256]; + +struct menu_viewer_data +{ + int first, offset; + struct grub_term_screen_geometry geo; + enum { + TIMEOUT_UNKNOWN, + TIMEOUT_NORMAL, + TIMEOUT_TERSE, + TIMEOUT_TERSE_NO_MARGIN + } timeout_msg; + grub_menu_t menu; + int *menu_title_offset; + struct grub_term_output *term; +}; + +static inline int +grub_term_cursor_x (const struct grub_term_screen_geometry *geo) +{ + return (geo->first_entry_x + geo->entry_width); +} + +grub_size_t +grub_getstringwidth (grub_uint32_t * str, const grub_uint32_t * last_position, + struct grub_term_output *term) +{ + grub_ssize_t width = 0; + + while (str < last_position) + { + struct grub_unicode_glyph glyph; + glyph.ncomb = 0; + str += grub_unicode_aglomerate_comb (str, last_position - str, &glyph); + width += grub_term_getcharwidth (term, &glyph); + grub_unicode_destroy_glyph (&glyph); + } + return width; +} + +static int +grub_print_message_indented_real (const char *msg, int margin_left, + int margin_right, + struct grub_term_output *term, int dry_run) +{ + grub_uint32_t *unicode_msg; + grub_uint32_t *last_position; + grub_size_t msg_len = grub_strlen (msg) + 2; + int ret = 0; + + unicode_msg = grub_malloc (msg_len * sizeof (grub_uint32_t)); + + if (!unicode_msg) + return 0; + + msg_len = grub_utf8_to_ucs4 (unicode_msg, msg_len, + (grub_uint8_t *) msg, -1, 0); + + last_position = unicode_msg + msg_len; + *last_position = 0; + + if (dry_run) + ret = grub_ucs4_count_lines (unicode_msg, last_position, margin_left, + margin_right, term); + else + grub_print_ucs4_menu (unicode_msg, last_position, margin_left, + margin_right, term, 0, -1, 0, 0); + + grub_free (unicode_msg); + + return ret; +} + +void +grub_print_message_indented (const char *msg, int margin_left, int margin_right, + struct grub_term_output *term) +{ + grub_print_message_indented_real (msg, margin_left, margin_right, term, 0); +} + +static void +draw_border (struct grub_term_output *term, const struct grub_term_screen_geometry *geo) +{ + int i; + + grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL); + + grub_term_gotoxy (term, (struct grub_term_coordinate) { geo->first_entry_x - 1, + geo->first_entry_y - 1 }); + grub_putcode (GRUB_UNICODE_CORNER_UL, term); + for (i = 0; i < geo->entry_width + 1; i++) + grub_putcode (GRUB_UNICODE_HLINE, term); + grub_putcode (GRUB_UNICODE_CORNER_UR, term); + + for (i = 0; i < geo->num_entries; i++) + { + grub_term_gotoxy (term, (struct grub_term_coordinate) { geo->first_entry_x - 1, + geo->first_entry_y + i }); + grub_putcode (GRUB_UNICODE_VLINE, term); + grub_term_gotoxy (term, + (struct grub_term_coordinate) { geo->first_entry_x + geo->entry_width + 1, + geo->first_entry_y + i }); + grub_putcode (GRUB_UNICODE_VLINE, term); + } + + grub_term_gotoxy (term, + (struct grub_term_coordinate) { geo->first_entry_x - 1, + geo->first_entry_y - 1 + geo->num_entries + 1 }); + grub_putcode (GRUB_UNICODE_CORNER_LL, term); + for (i = 0; i < geo->entry_width + 1; i++) + grub_putcode (GRUB_UNICODE_HLINE, term); + grub_putcode (GRUB_UNICODE_CORNER_LR, term); + + grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL); + + grub_term_gotoxy (term, + (struct grub_term_coordinate) { geo->first_entry_x - 1, + (geo->first_entry_y - 1 + geo->num_entries + + GRUB_TERM_MARGIN + 1) }); +} + +static int +print_message (int nested, int edit, struct grub_term_output *term, int dry_run) +{ + int ret = 0; + grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL); + + if (edit) + { + ret += grub_print_message_indented_real (_("Minimum Emacs-like screen editing is \ +supported. TAB lists completions. Press Ctrl-x or F10 to boot, Ctrl-c or F2 for a \ +command-line or ESC to discard edits and return to the GRUB menu."), + STANDARD_MARGIN, STANDARD_MARGIN, + term, dry_run); + } + else + { + char *msg_translated; + + msg_translated = grub_xasprintf (_("Use the %C and %C keys to select which " + "entry is highlighted."), + GRUB_UNICODE_UPARROW, + GRUB_UNICODE_DOWNARROW); + if (!msg_translated) + return 0; + ret += grub_print_message_indented_real (msg_translated, STANDARD_MARGIN, + STANDARD_MARGIN, term, dry_run); + + grub_free (msg_translated); + + if (nested) + { + #if 0 + ret += grub_print_message_indented_real + (_("Press enter to boot the selected OS, " + "`e' to edit the commands before booting " + "or `c' for a command-line. ESC to return previous menu."), + STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run); + #endif + } + else + { + char szLine[128]; + const char *checkret = grub_env_get("VTOY_CHKDEV_RESULT_STRING"); + if (checkret == NULL || checkret[0] != '0') { + grub_snprintf(szLine, sizeof(szLine), "%s [Unofficial Ventoy]", grub_env_get("VTOY_TEXT_MENU_VER")); + } else { + grub_snprintf(szLine, sizeof(szLine), "%s", grub_env_get("VTOY_TEXT_MENU_VER")); + } + + ret += grub_print_message_indented_real("\n", STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run); + + ret += grub_print_message_indented_real(szLine, STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run); + + ret += grub_print_message_indented_real("\n", STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run); + ret += grub_print_message_indented_real(g_ventoy_hotkey_tip, + 3, 6, term, dry_run); + } + } + return ret; +} + +static void +print_entry (int y, int highlight, grub_menu_entry_t entry, + const struct menu_viewer_data *data) +{ + const char *title; + grub_size_t title_len; + grub_ssize_t len; + grub_uint32_t *unicode_title; + grub_ssize_t i; + grub_uint8_t old_color_normal, old_color_highlight; + + title = entry ? entry->title : ""; + title_len = grub_strlen (title); + unicode_title = grub_malloc (title_len * sizeof (*unicode_title)); + if (! unicode_title) + /* XXX How to show this error? */ + return; + + len = grub_utf8_to_ucs4 (unicode_title, title_len, + (grub_uint8_t *) title, -1, 0); + if (len < 0) + { + /* It is an invalid sequence. */ + grub_free (unicode_title); + return; + } + + old_color_normal = grub_term_normal_color; + old_color_highlight = grub_term_highlight_color; + grub_term_normal_color = grub_color_menu_normal; + grub_term_highlight_color = grub_color_menu_highlight; + grub_term_setcolorstate (data->term, highlight + ? GRUB_TERM_COLOR_HIGHLIGHT + : GRUB_TERM_COLOR_NORMAL); + + grub_term_gotoxy (data->term, (struct grub_term_coordinate) { + data->geo.first_entry_x, y }); + + for (i = 0; i < len; i++) + if (unicode_title[i] == '\n' || unicode_title[i] == '\b' + || unicode_title[i] == '\r' || unicode_title[i] == '\e') + unicode_title[i] = ' '; + + if (data->geo.num_entries > 1) + grub_putcode (highlight ? '*' : ' ', data->term); + + grub_print_ucs4_menu (unicode_title, + unicode_title + len, + 0, + data->geo.right_margin, + data->term, 0, 1, + GRUB_UNICODE_RIGHTARROW, 0); + + grub_term_setcolorstate (data->term, GRUB_TERM_COLOR_NORMAL); + grub_term_gotoxy (data->term, + (struct grub_term_coordinate) { + grub_term_cursor_x (&data->geo), y }); + + grub_term_normal_color = old_color_normal; + grub_term_highlight_color = old_color_highlight; + + grub_term_setcolorstate (data->term, GRUB_TERM_COLOR_NORMAL); + grub_free (unicode_title); +} + +static void +print_entries (grub_menu_t menu, const struct menu_viewer_data *data) +{ + grub_menu_entry_t e; + int i; + + grub_term_gotoxy (data->term, + (struct grub_term_coordinate) { + data->geo.first_entry_x + data->geo.entry_width + + data->geo.border + 1, + data->geo.first_entry_y }); + + if (data->geo.num_entries != 1) + { + if (data->first) + grub_putcode (GRUB_UNICODE_UPARROW, data->term); + else + grub_putcode (' ', data->term); + } + e = grub_menu_get_entry (menu, data->first); + + for (i = 0; i < data->geo.num_entries; i++) + { + print_entry (data->geo.first_entry_y + i, data->offset == i, + e, data); + if (e) + e = e->next; + } + + grub_term_gotoxy (data->term, + (struct grub_term_coordinate) { data->geo.first_entry_x + data->geo.entry_width + + data->geo.border + 1, + data->geo.first_entry_y + data->geo.num_entries - 1 }); + if (data->geo.num_entries == 1) + { + if (data->first && e) + grub_putcode (GRUB_UNICODE_UPDOWNARROW, data->term); + else if (data->first) + grub_putcode (GRUB_UNICODE_UPARROW, data->term); + else if (e) + grub_putcode (GRUB_UNICODE_DOWNARROW, data->term); + else + grub_putcode (' ', data->term); + } + else + { + if (e) + grub_putcode (GRUB_UNICODE_DOWNARROW, data->term); + else + grub_putcode (' ', data->term); + } + + grub_term_gotoxy (data->term, + (struct grub_term_coordinate) { grub_term_cursor_x (&data->geo), + data->geo.first_entry_y + data->offset }); +} + +/* Initialize the screen. If NESTED is non-zero, assume that this menu + is run from another menu or a command-line. If EDIT is non-zero, show + a message for the menu entry editor. */ +void +grub_menu_init_page (int nested, int edit, + struct grub_term_screen_geometry *geo, + struct grub_term_output *term) +{ + grub_uint8_t old_color_normal, old_color_highlight; + int msg_num_lines; + int bottom_message = 1; + int empty_lines = 1; + int version_msg = 1; + + geo->border = 1; + geo->first_entry_x = 1 /* margin */ + 1 /* border */; + geo->entry_width = grub_term_width (term) - 5; + + geo->first_entry_y = 2 /* two empty lines*/ + + 1 /* GNU GRUB version text */ + 1 /* top border */; + + geo->timeout_lines = 2; + + /* 3 lines for timeout message and bottom margin. 2 lines for the border. */ + geo->num_entries = grub_term_height (term) - geo->first_entry_y + - 1 /* bottom border */ + - 1 /* empty line before info message*/ + - geo->timeout_lines /* timeout */ + - 1 /* empty final line */; + msg_num_lines = print_message (nested, edit, term, 1); + if (geo->num_entries - msg_num_lines < 3 + || geo->entry_width < 10) + { + geo->num_entries += 4; + geo->first_entry_y -= 2; + empty_lines = 0; + geo->first_entry_x -= 1; + geo->entry_width += 1; + } + if (geo->num_entries - msg_num_lines < 3 + || geo->entry_width < 10) + { + geo->num_entries += 2; + geo->first_entry_y -= 1; + geo->first_entry_x -= 1; + geo->entry_width += 2; + geo->border = 0; + } + + if (geo->entry_width <= 0) + geo->entry_width = 1; + + if (geo->num_entries - msg_num_lines < 3 + && geo->timeout_lines == 2) + { + geo->timeout_lines = 1; + geo->num_entries++; + } + + if (geo->num_entries - msg_num_lines < 3) + { + geo->num_entries += 1; + geo->first_entry_y -= 1; + version_msg = 0; + } + + if (geo->num_entries - msg_num_lines >= 2) + geo->num_entries -= msg_num_lines; + else + bottom_message = 0; + + /* By default, use the same colors for the menu. */ + old_color_normal = grub_term_normal_color; + old_color_highlight = grub_term_highlight_color; + grub_color_menu_normal = grub_term_normal_color; + grub_color_menu_highlight = grub_term_highlight_color; + + /* Then give user a chance to replace them. */ + grub_parse_color_name_pair (&grub_color_menu_normal, + grub_env_get ("menu_color_normal")); + grub_parse_color_name_pair (&grub_color_menu_highlight, + grub_env_get ("menu_color_highlight")); + + if (version_msg) + grub_normal_init_page (term, empty_lines); + else + grub_term_cls (term); + + grub_term_normal_color = grub_color_menu_normal; + grub_term_highlight_color = grub_color_menu_highlight; + if (geo->border) + draw_border (term, geo); + grub_term_normal_color = old_color_normal; + grub_term_highlight_color = old_color_highlight; + geo->timeout_y = geo->first_entry_y + geo->num_entries + + geo->border + empty_lines; + if (bottom_message) + { + grub_term_gotoxy (term, + (struct grub_term_coordinate) { GRUB_TERM_MARGIN, + geo->timeout_y }); + + print_message (nested, edit, term, 0); + geo->timeout_y += msg_num_lines; + } + geo->right_margin = grub_term_width (term) + - geo->first_entry_x + - geo->entry_width - 1; +} + +static void +menu_text_print_timeout (int timeout, void *dataptr) +{ + struct menu_viewer_data *data = dataptr; + char *msg_translated = 0; + + grub_term_gotoxy (data->term, + (struct grub_term_coordinate) { 0, data->geo.timeout_y }); + + if (data->timeout_msg == TIMEOUT_TERSE + || data->timeout_msg == TIMEOUT_TERSE_NO_MARGIN) + msg_translated = grub_xasprintf (_("%ds"), timeout); + else + msg_translated = grub_xasprintf (_("The highlighted entry will be executed automatically in %ds."), timeout); + if (!msg_translated) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + return; + } + + if (data->timeout_msg == TIMEOUT_UNKNOWN) + { + data->timeout_msg = grub_print_message_indented_real (msg_translated, + 3, 1, data->term, 1) + <= data->geo.timeout_lines ? TIMEOUT_NORMAL : TIMEOUT_TERSE; + if (data->timeout_msg == TIMEOUT_TERSE) + { + grub_free (msg_translated); + msg_translated = grub_xasprintf (_("%ds"), timeout); + if (grub_term_width (data->term) < 10) + data->timeout_msg = TIMEOUT_TERSE_NO_MARGIN; + } + } + + grub_print_message_indented (msg_translated, + data->timeout_msg == TIMEOUT_TERSE_NO_MARGIN ? 0 : 3, + data->timeout_msg == TIMEOUT_TERSE_NO_MARGIN ? 0 : 1, + data->term); + grub_free (msg_translated); + + grub_term_gotoxy (data->term, + (struct grub_term_coordinate) { + grub_term_cursor_x (&data->geo), + data->geo.first_entry_y + data->offset }); + grub_term_refresh (data->term); +} + +static void +menu_text_set_chosen_entry (int entry, void *dataptr) +{ + struct menu_viewer_data *data = dataptr; + int oldoffset = data->offset; + int complete_redraw = 0; + + data->offset = entry - data->first; + if (data->offset > data->geo.num_entries - 1) + { + data->first = entry - (data->geo.num_entries - 1); + data->offset = data->geo.num_entries - 1; + complete_redraw = 1; + } + if (data->offset < 0) + { + data->offset = 0; + data->first = entry; + complete_redraw = 1; + } + if (complete_redraw) + print_entries (data->menu, data); + else + { + print_entry (data->geo.first_entry_y + oldoffset, 0, + grub_menu_get_entry (data->menu, data->first + oldoffset), + data); + print_entry (data->geo.first_entry_y + data->offset, 1, + grub_menu_get_entry (data->menu, data->first + data->offset), + data); + } + grub_term_refresh (data->term); +} + +static void +menu_text_scroll_chosen_entry (void *dataptr, int diren) +{ + struct menu_viewer_data *data = dataptr; + const char *orig_title, *scrolled_title; + int off; + int selected; + grub_menu_entry_t entry; + + if (!data->menu->size) + return; + + selected = data->first + data->offset; + entry = grub_menu_get_entry (data->menu, selected); + orig_title = entry->title; + off = data->menu_title_offset[selected] + diren; + if (off < 0 + || off > grub_utf8_get_num_code (orig_title, grub_strlen(orig_title))) + return; + + scrolled_title = + grub_utf8_offset_code (orig_title, grub_strlen (orig_title), off); + if (scrolled_title) + entry->title = scrolled_title; + print_entry (data->geo.first_entry_y + data->offset, 1, entry, data); + + entry->title = orig_title; + data->menu_title_offset[selected] = off; + grub_term_refresh (data->term); +} + +static void +menu_text_fini (void *dataptr) +{ + struct menu_viewer_data *data = dataptr; + + grub_term_setcursor (data->term, 1); + grub_term_cls (data->term); + if (data->menu_title_offset) + grub_free (data->menu_title_offset); + grub_free (data); +} + +static void +menu_text_clear_timeout (void *dataptr) +{ + struct menu_viewer_data *data = dataptr; + int i; + + for (i = 0; i < data->geo.timeout_lines;i++) + { + grub_term_gotoxy (data->term, (struct grub_term_coordinate) { + 0, data->geo.timeout_y + i }); + grub_print_spaces (data->term, grub_term_width (data->term) - 1); + } + if (data->geo.num_entries <= 5 && !data->geo.border) + { + grub_term_gotoxy (data->term, + (struct grub_term_coordinate) { + data->geo.first_entry_x + data->geo.entry_width + + data->geo.border + 1, + data->geo.first_entry_y + data->geo.num_entries - 1 + }); + grub_putcode (' ', data->term); + + data->geo.timeout_lines = 0; + data->geo.num_entries++; + print_entries (data->menu, data); + } + grub_term_gotoxy (data->term, + (struct grub_term_coordinate) { + grub_term_cursor_x (&data->geo), + data->geo.first_entry_y + data->offset }); + grub_term_refresh (data->term); +} + +grub_err_t +grub_menu_try_text (struct grub_term_output *term, + int entry, grub_menu_t menu, int nested) +{ + struct menu_viewer_data *data; + struct grub_menu_viewer *instance; + + instance = grub_zalloc (sizeof (*instance)); + if (!instance) + return grub_errno; + + data = grub_zalloc (sizeof (*data)); + if (!data) + { + grub_free (instance); + return grub_errno; + } + + if (menu->size) + data->menu_title_offset = grub_zalloc (sizeof (*data->menu_title_offset) * menu->size); + + data->term = term; + instance->data = data; + instance->set_chosen_entry = menu_text_set_chosen_entry; + if (data->menu_title_offset) + instance->scroll_chosen_entry = menu_text_scroll_chosen_entry; + instance->print_timeout = menu_text_print_timeout; + instance->clear_timeout = menu_text_clear_timeout; + instance->fini = menu_text_fini; + + data->menu = menu; + + data->offset = entry; + data->first = 0; + + grub_term_setcursor (data->term, 0); + grub_menu_init_page (nested, 0, &data->geo, data->term); + + if (data->offset > data->geo.num_entries - 1) + { + data->first = data->offset - (data->geo.num_entries - 1); + data->offset = data->geo.num_entries - 1; + } + + print_entries (menu, data); + grub_term_refresh (data->term); + grub_menu_register_viewer (instance); + + return GRUB_ERR_NONE; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/misc.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/misc.c new file mode 100644 index 0000000..56629a8 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/misc.c @@ -0,0 +1,194 @@ +/* misc.c - miscellaneous functions */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const char *grub_human_sizes[3][6] = + { + /* This algorithm in reality would work only up to (2^64) / 100 B = 81 PiB. + Put here all possible suffixes it can produce so no array bounds check + is needed. + */ + /* TRANSLATORS: that's the list of binary unit prefixes. */ + { N_("B"), N_("KiB"), N_("MiB"), N_("GiB"), N_("TiB"), N_("PiB")}, + /* TRANSLATORS: that's the list of binary unit prefixes. */ + { "", N_("KB"), N_("MB"), N_("GB"), N_("TB"), N_("PB") }, + /* TRANSLATORS: that's the list of binary unit prefixes. */ + { N_("B/s"), N_("KiB/s"), N_("MiB/s"), N_("GiB/s"), N_("TiB/s"), N_("PiB/s"), }, + }; + +const char * +grub_get_human_size (grub_uint64_t size, enum grub_human_size_type type) +{ + grub_uint64_t fsize; + unsigned units = 0; + static char buf[30]; + const char *umsg; + + if (type != GRUB_HUMAN_SIZE_SPEED) + fsize = size * 100ULL; + else + fsize = size; + + /* Since 2^64 / 1024^5 < 102400, this can give at most 5 iterations. + So units <=5, so impossible to go past the end of array. + */ + while (fsize >= 102400) + { + fsize = (fsize + 512) / 1024; + units++; + } + + umsg = _(grub_human_sizes[type][units]); + + if (units || type == GRUB_HUMAN_SIZE_SPEED) + { + grub_uint64_t whole, fraction; + + whole = grub_divmod64 (fsize, 100, &fraction); + grub_snprintf (buf, sizeof (buf), + "%" PRIuGRUB_UINT64_T + ".%02" PRIuGRUB_UINT64_T "%s", whole, fraction, + umsg); + } + else + grub_snprintf (buf, sizeof (buf), "%llu%s", (unsigned long long) size, + umsg); + return buf; +} + +/* Print the information on the device NAME. */ +grub_err_t +grub_normal_print_device_info (const char *name) +{ + grub_device_t dev; + char *p; + + p = grub_strchr (name, ','); + if (p) + { + grub_xputs ("\t"); + grub_printf_ (N_("Partition %s:"), name); + grub_xputs (" "); + } + else + { + grub_printf_ (N_("Device %s:"), name); + grub_xputs (" "); + } + + dev = grub_device_open (name); + if (! dev) + grub_printf ("%s", _("Filesystem cannot be accessed")); + else if (dev->disk) + { + grub_fs_t fs; + + fs = grub_fs_probe (dev); + /* Ignore all errors. */ + grub_errno = 0; + + if (fs) + { + const char *fsname = fs->name; + if (grub_strcmp (fsname, "ext2") == 0) + fsname = "ext*"; + grub_printf_ (N_("Filesystem type %s"), fsname); + if (fs->fs_label) + { + char *label; + (fs->fs_label) (dev, &label); + if (grub_errno == GRUB_ERR_NONE) + { + if (label && grub_strlen (label)) + { + grub_xputs (" "); + grub_printf_ (N_("- Label `%s'"), label); + } + grub_free (label); + } + grub_errno = GRUB_ERR_NONE; + } + if (fs->fs_mtime) + { + grub_int32_t tm; + struct grub_datetime datetime; + (fs->fs_mtime) (dev, &tm); + if (grub_errno == GRUB_ERR_NONE) + { + grub_unixtime2datetime (tm, &datetime); + grub_xputs (" "); + /* TRANSLATORS: Arguments are year, month, day, hour, minute, + second, day of the week (translated). */ + grub_printf_ (N_("- Last modification time %d-%02d-%02d " + "%02d:%02d:%02d %s"), + datetime.year, datetime.month, datetime.day, + datetime.hour, datetime.minute, datetime.second, + grub_get_weekday_name (&datetime)); + + } + grub_errno = GRUB_ERR_NONE; + } + if (fs->fs_uuid) + { + char *uuid; + (fs->fs_uuid) (dev, &uuid); + if (grub_errno == GRUB_ERR_NONE) + { + if (uuid && grub_strlen (uuid)) + grub_printf (", UUID %s", uuid); + grub_free (uuid); + } + grub_errno = GRUB_ERR_NONE; + } + } + else + grub_printf ("%s", _("No known filesystem detected")); + + if (dev->disk->partition) + grub_printf (_(" - Partition start at %llu%sKiB"), + (unsigned long long) (grub_partition_get_start (dev->disk->partition) >> 1), + (grub_partition_get_start (dev->disk->partition) & 1) ? ".5" : "" ); + else + grub_printf_ (N_(" - Sector size %uB"), 1 << dev->disk->log_sector_size); + if (grub_disk_get_size (dev->disk) == GRUB_DISK_SIZE_UNKNOWN) + grub_puts_ (N_(" - Total size unknown")); + else + grub_printf (_(" - Total size %llu%sKiB"), + (unsigned long long) (grub_disk_get_size (dev->disk) >> 1), + /* TRANSLATORS: Replace dot with appropriate decimal separator for + your language. */ + (grub_disk_get_size (dev->disk) & 1) ? _(".5") : ""); + } + + if (dev) + grub_device_close (dev); + + grub_xputs ("\n"); + return grub_errno; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/partmap/gpt.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/partmap/gpt.c new file mode 100644 index 0000000..2975ad4 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/partmap/gpt.c @@ -0,0 +1,232 @@ +/* gpt.c - Read GUID Partition Tables (GPT). */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +static grub_uint8_t grub_gpt_magic[8] = + { + 0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54 + }; + +static const grub_gpt_part_guid_t grub_gpt_partition_type_empty = GRUB_GPT_PARTITION_TYPE_EMPTY; + +#ifdef GRUB_UTIL +static const grub_gpt_part_guid_t grub_gpt_partition_type_bios_boot = GRUB_GPT_PARTITION_TYPE_BIOS_BOOT; +#endif + +/* 512 << 7 = 65536 byte sectors. */ +#define MAX_SECTOR_LOG 7 + +static struct grub_partition_map grub_gpt_partition_map; + + + +grub_err_t +grub_gpt_partition_map_iterate (grub_disk_t disk, + grub_partition_iterate_hook_t hook, + void *hook_data) +{ + struct grub_partition part; + struct grub_gpt_header gpt; + struct grub_gpt_partentry entry; + struct grub_msdos_partition_mbr mbr; + grub_uint64_t entries; + unsigned int i; + int last_offset = 0; + int sector_log = 0; + + /* Read the protective MBR. */ + if (grub_disk_read (disk, 0, 0, sizeof (mbr), &mbr)) + return grub_errno; + + /* Check if it is valid. */ + if (mbr.signature != grub_cpu_to_le16_compile_time (GRUB_PC_PARTITION_SIGNATURE)) + return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature"); + + /* Make sure the MBR is a protective MBR and not a normal MBR. */ + for (i = 0; i < 4; i++) + if (mbr.entries[i].type == GRUB_PC_PARTITION_TYPE_GPT_DISK) + break; + if (i == 4) + return grub_error (GRUB_ERR_BAD_PART_TABLE, "no GPT partition map found"); + + /* Read the GPT header. */ + for (sector_log = 0; sector_log < MAX_SECTOR_LOG; sector_log++) + { + if (grub_disk_read (disk, 1 << sector_log, 0, sizeof (gpt), &gpt)) + return grub_errno; + + if (grub_memcmp (gpt.magic, grub_gpt_magic, sizeof (grub_gpt_magic)) == 0) + break; + } + if (sector_log == MAX_SECTOR_LOG) + return grub_error (GRUB_ERR_BAD_PART_TABLE, "no valid GPT header"); + + grub_dprintf ("gpt", "Read a valid GPT header\n"); + + entries = grub_le_to_cpu64 (gpt.partitions) << sector_log; + for (i = 0; i < grub_le_to_cpu32 (gpt.maxpart); i++) + { + if (grub_disk_read (disk, entries, last_offset, + sizeof (entry), &entry)) + return grub_errno; + + if (grub_memcmp (&grub_gpt_partition_type_empty, &entry.type, + sizeof (grub_gpt_partition_type_empty))) + { + /* Calculate the first block and the size of the partition. */ + part.start = grub_le_to_cpu64 (entry.start) << sector_log; + part.len = (grub_le_to_cpu64 (entry.end) + - grub_le_to_cpu64 (entry.start) + 1) << sector_log; + part.offset = entries; + part.number = i; + part.index = last_offset; + part.partmap = &grub_gpt_partition_map; + part.parent = disk->partition; + part.gpt_attrib = entry.attrib; + + grub_dprintf ("gpt", "GPT entry %d: start=%lld, length=%lld\n", i, + (unsigned long long) part.start, + (unsigned long long) part.len); + + if (hook (disk, &part, hook_data)) + return grub_errno; + } + + last_offset += grub_le_to_cpu32 (gpt.partentry_size); + if (last_offset == GRUB_DISK_SECTOR_SIZE) + { + last_offset = 0; + entries++; + } + } + + return GRUB_ERR_NONE; +} + +#ifdef GRUB_UTIL +/* Context for gpt_partition_map_embed. */ +struct gpt_partition_map_embed_ctx +{ + grub_disk_addr_t start, len; +}; + +/* Helper for gpt_partition_map_embed. */ +static int +find_usable_region (grub_disk_t disk __attribute__ ((unused)), + const grub_partition_t p, void *data) +{ + struct gpt_partition_map_embed_ctx *ctx = data; + struct grub_gpt_partentry gptdata; + grub_partition_t p2; + + p2 = disk->partition; + disk->partition = p->parent; + if (grub_disk_read (disk, p->offset, p->index, + sizeof (gptdata), &gptdata)) + { + disk->partition = p2; + return 0; + } + disk->partition = p2; + + /* If there's an embed region, it is in a dedicated partition. */ + if (! grub_memcmp (&gptdata.type, &grub_gpt_partition_type_bios_boot, 16)) + { + ctx->start = p->start; + ctx->len = p->len; + return 1; + } + + return 0; +} + +static grub_err_t +gpt_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors, + unsigned int max_nsectors, + grub_embed_type_t embed_type, + grub_disk_addr_t **sectors) +{ + struct gpt_partition_map_embed_ctx ctx = { + .start = 0, + .len = 0 + }; + unsigned i; + grub_err_t err; + + if (embed_type != GRUB_EMBED_PCBIOS) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "GPT currently supports only PC-BIOS embedding"); + + err = grub_gpt_partition_map_iterate (disk, find_usable_region, &ctx); + if (err) + return err; + + if (ctx.len == 0) + return grub_error (GRUB_ERR_FILE_NOT_FOUND, + N_("this GPT partition label contains no BIOS Boot Partition;" + " embedding won't be possible")); + + if (ctx.len < *nsectors) + return grub_error (GRUB_ERR_OUT_OF_RANGE, + N_("your BIOS Boot Partition is too small;" + " embedding won't be possible")); + + *nsectors = ctx.len; + if (*nsectors > max_nsectors) + *nsectors = max_nsectors; + *sectors = grub_malloc (*nsectors * sizeof (**sectors)); + if (!*sectors) + return grub_errno; + for (i = 0; i < *nsectors; i++) + (*sectors)[i] = ctx.start + i; + + return GRUB_ERR_NONE; +} +#endif + + +/* Partition map type. */ +static struct grub_partition_map grub_gpt_partition_map = + { + .name = "gpt", + .iterate = grub_gpt_partition_map_iterate, +#ifdef GRUB_UTIL + .embed = gpt_partition_map_embed +#endif + }; + +GRUB_MOD_INIT(part_gpt) +{ + grub_partition_map_register (&grub_gpt_partition_map); +} + +GRUB_MOD_FINI(part_gpt) +{ + grub_partition_map_unregister (&grub_gpt_partition_map); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/script/function.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/script/function.c new file mode 100644 index 0000000..fc10ac4 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/script/function.c @@ -0,0 +1,113 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +grub_script_function_t grub_script_function_list; + +grub_script_function_t +grub_script_function_create (struct grub_script_arg *functionname_arg, + struct grub_script *cmd) +{ + grub_script_function_t func; + grub_script_function_t *p; + + func = (grub_script_function_t) grub_malloc (sizeof (*func)); + if (! func) + return 0; + + func->name = grub_strdup (functionname_arg->str); + if (! func->name) + { + grub_free (func); + return 0; + } + + func->func = cmd; + + /* Keep the list sorted for simplicity. */ + p = &grub_script_function_list; + while (*p) + { + if (grub_strcmp ((*p)->name, func->name) >= 0) + break; + + p = &((*p)->next); + } + + /* If the function already exists, overwrite the old function. */ + if (*p && grub_strcmp ((*p)->name, func->name) == 0) + { + grub_script_function_t q; + + q = *p; + grub_script_free (q->func); + q->func = cmd; + grub_free (func); + func = q; + } + else + { + func->next = *p; + *p = func; + } + + return func; +} + +void +grub_script_function_remove (const char *name) +{ + grub_script_function_t *p, q; + + for (p = &grub_script_function_list, q = *p; q; p = &(q->next), q = q->next) + if (grub_strcmp (name, q->name) == 0) + { + *p = q->next; + grub_free (q->name); + grub_script_free (q->func); + grub_free (q); + break; + } +} + +grub_script_function_t +grub_script_function_find (char *functionname) +{ + grub_script_function_t func; + + for (func = grub_script_function_list; func; func = func->next) + if (grub_strcmp (functionname, func->name) == 0) + break; + + if (! func) + { + char tmp[64]; + grub_strncpy (tmp, functionname, 63); + tmp[63] = 0; + /* Avoid truncating inside UTF-8 character. */ + tmp[grub_getend (tmp, tmp + grub_strlen (tmp))] = 0; + grub_error (GRUB_ERR_UNKNOWN_COMMAND, N_("can't find command `%s'"), tmp); + } + + return func; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/term/efi/mouse.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/term/efi/mouse.c new file mode 100644 index 0000000..0d39817 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/term/efi/mouse.c @@ -0,0 +1,260 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2022 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +#define GRUB_EFI_SIMPLE_POINTER_GUID \ + { 0x31878c87, 0x0b75, 0x11d5, \ + { 0x9a, 0x4f, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +typedef struct +{ + grub_efi_int32_t x; + grub_efi_int32_t y; + grub_efi_int32_t z; + grub_efi_boolean_t left; + grub_efi_boolean_t right; +} grub_efi_mouse_state; + +grub_efi_mouse_state no_move = {0, 0, 0, 0, 0}; + +typedef struct +{ + grub_efi_uint64_t x; + grub_efi_uint64_t y; + grub_efi_uint64_t z; + grub_efi_boolean_t left; + grub_efi_boolean_t right; +} grub_efi_mouse_mode; + +struct grub_efi_simple_pointer_protocol +{ + grub_efi_status_t (*reset) (struct grub_efi_simple_pointer_protocol *this, + grub_efi_boolean_t extended_verification); + grub_efi_status_t (*get_state) (struct grub_efi_simple_pointer_protocol *this, + grub_efi_mouse_state *state); + grub_efi_event_t *wait_for_input; + grub_efi_mouse_mode *mode; +}; +typedef struct grub_efi_simple_pointer_protocol grub_efi_simple_pointer_protocol_t; + +typedef struct +{ + grub_efi_uintn_t count; + grub_efi_simple_pointer_protocol_t **mouse; +} grub_efi_mouse_prot_t; + +static grub_int32_t +mouse_div (grub_int32_t a, grub_uint64_t b) +{ + grub_int32_t s = 1, q, ret; + grub_uint64_t n = a; + if (!b) + return 0; + if (a < 0) + { + s = -1; + n = -a; + } + q = grub_divmod64 (n, b, NULL); + ret = s * (q > 0 ? q : -q); + return ret; +} + +static grub_efi_mouse_prot_t * +grub_efi_mouse_prot_init (void) +{ + grub_efi_status_t status; + grub_efi_guid_t mouse_guid = GRUB_EFI_SIMPLE_POINTER_GUID; + grub_efi_mouse_prot_t *mouse_input = NULL; + grub_efi_boot_services_t *b = grub_efi_system_table->boot_services; + grub_efi_handle_t *buf; + grub_efi_uintn_t count; + grub_efi_uintn_t i; + + status = efi_call_5 (b->locate_handle_buffer, GRUB_EFI_BY_PROTOCOL, + &mouse_guid, NULL, &count, &buf); + if (status != GRUB_EFI_SUCCESS) + { +#ifdef MOUSE_DEBUG + grub_printf ("ERROR: SimplePointerProtocol not found.\n"); +#endif + return NULL; + } + + mouse_input = grub_malloc (sizeof (grub_efi_mouse_prot_t)); + if (!mouse_input) + goto end; + mouse_input->mouse = grub_malloc (count + * sizeof (grub_efi_simple_pointer_protocol_t *)); + if (!mouse_input->mouse) + { + grub_free (mouse_input); + mouse_input = NULL; + goto end; + } + mouse_input->count = count; + for (i = 0; i < count; i++) + { + efi_call_3 (b->handle_protocol, + buf[i], &mouse_guid, (void **)&mouse_input->mouse[i]); +#ifdef MOUSE_DEBUG + grub_printf ("%d %p ", (int)i, mouse_input->mouse[i]); +#endif + efi_call_2 (mouse_input->mouse[i]->reset, mouse_input->mouse[i], 1); +#ifdef MOUSE_DEBUG + grub_printf + ("[%"PRIuGRUB_UINT64_T"] [%"PRIuGRUB_UINT64_T"] [%"PRIuGRUB_UINT64_T"]\n", + mouse_input->mouse[i]->mode->x, + mouse_input->mouse[i]->mode->y, mouse_input->mouse[i]->mode->z); +#endif + } + +end: + efi_call_1(b->free_pool, buf); + + return mouse_input; +} + +static grub_err_t +grub_efi_mouse_input_init (struct grub_term_input *term) +{ + grub_efi_mouse_prot_t *mouse_input = NULL; + if (term->data) + return 0; + mouse_input = grub_efi_mouse_prot_init (); + if (!mouse_input) + return GRUB_ERR_BAD_OS; + + term->data = (void *)mouse_input; + + return 0; +} + +static int +grub_mouse_getkey (struct grub_term_input *term) +{ + grub_efi_mouse_state cur; + grub_efi_mouse_prot_t *mouse = term->data; + //int x; + int y; + int delta = 0; + const char *env; + grub_efi_uintn_t i; + if (!mouse) + return GRUB_TERM_NO_KEY; + + env = grub_env_get("mouse_delta"); + if (env) + delta = (int)grub_strtol(env, NULL, 10); + + for (i = 0; i < mouse->count; i++) + { + efi_call_2 (mouse->mouse[i]->get_state, mouse->mouse[i], &cur); + if (grub_memcmp (&cur, &no_move, sizeof (grub_efi_mouse_state)) != 0) + { + y = mouse_div (cur.y, mouse->mouse[i]->mode->y); + if (cur.left) + return 0x0d; + if (cur.right) + return GRUB_TERM_ESC; + if (y > delta) + return GRUB_TERM_KEY_DOWN; + if (y < -delta) + return GRUB_TERM_KEY_UP; + } + } + return GRUB_TERM_NO_KEY; +} + +#ifdef MOUSE_DEBUG +static grub_err_t +grub_cmd_mouse_test (grub_command_t cmd __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) + +{ + grub_efi_mouse_state cur; + int x = 0, y = 0, z = 0; + grub_efi_uintn_t i; + grub_efi_mouse_prot_t *mouse = NULL; + + mouse = grub_efi_mouse_prot_init (); + if (!mouse) + return grub_error (GRUB_ERR_BAD_OS, "mouse not found.\n"); + grub_printf ("Press [1] to exit.\n"); + while (1) + { + if (grub_getkey_noblock () == '1') + break; + for (i = 0; i < mouse->count; i++) + { + efi_call_2 (mouse->mouse[i]->get_state, mouse->mouse[i], &cur); + if (grub_memcmp (&cur, &no_move, sizeof (grub_efi_mouse_state)) != 0) + { + x = mouse_div (cur.x, mouse->mouse[i]->mode->x); + y = mouse_div (cur.y, mouse->mouse[i]->mode->y); + z = mouse_div (cur.z, mouse->mouse[i]->mode->z); + grub_printf ("[ID=%d] X=%d Y=%d Z=%d L=%d R=%d\n", + (int)i, x, y, z, cur.left, cur.right); + } + } + grub_refresh (); + } + grub_free (mouse->mouse); + grub_free (mouse); + return GRUB_ERR_NONE; +} +static grub_command_t cmd; +#endif + +static struct grub_term_input grub_mouse_term_input = +{ + .name = "mouse", + .getkey = grub_mouse_getkey, + .init = grub_efi_mouse_input_init, +}; + +GRUB_MOD_INIT(mouse) +{ + grub_term_register_input ("mouse", &grub_mouse_term_input); +#ifdef MOUSE_DEBUG + cmd = grub_register_command ("mouse_test", grub_cmd_mouse_test, 0, + N_("UEFI mouse test.")); +#endif +} + +GRUB_MOD_FINI(mouse) +{ + grub_term_unregister_input (&grub_mouse_term_input); +#ifdef MOUSE_DEBUG + grub_unregister_command (cmd); +#endif +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/term/keyboard_layout.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/term/keyboard_layout.c new file mode 100644 index 0000000..8d139b5 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/term/keyboard_layout.c @@ -0,0 +1,795 @@ + +#define ventoy_keyboard_set_layout(name) if (grub_strcmp(layout, #name) == 0) return ventoy_keyboard_layout_##name() + +static void ventoy_keyboard_layout_QWERTY_USA(void) { + grub_keymap_reset(); + grub_keymap_disable(); +} +static void ventoy_keyboard_layout_AZERTY(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("a", "q"); +grub_keymap_add_by_string("A", "Q"); +grub_keymap_add_by_string("z", "w"); +grub_keymap_add_by_string("Z", "W"); +grub_keymap_add_by_string("q", "a"); +grub_keymap_add_by_string("Q", "A"); +grub_keymap_add_by_string("m", "semicolon"); +grub_keymap_add_by_string("M", "colon"); +grub_keymap_add_by_string("w", "z"); +grub_keymap_add_by_string("W", "Z"); +grub_keymap_add_by_string("comma", "m"); +grub_keymap_add_by_string("question", "M"); +grub_keymap_add_by_string("semicolon", "comma"); +grub_keymap_add_by_string("period", "less"); +grub_keymap_add_by_string("colon", "period"); +grub_keymap_add_by_string("slash", "greater"); +grub_keymap_add_by_string("exclam", "slash"); +grub_keymap_add_by_string("dollar", "bracketright"); +grub_keymap_add_by_string("asterisk", "backslash"); +grub_keymap_add_by_string("percent", "doublequote"); +grub_keymap_add_by_string("ampersand", "1"); +grub_keymap_add_by_string("1", "exclam"); +grub_keymap_add_by_string("tilde", "2"); +grub_keymap_add_by_string("2", "at"); +grub_keymap_add_by_string("doublequote", "3"); +grub_keymap_add_by_string("3", "numbersign"); +grub_keymap_add_by_string("quote", "4"); +grub_keymap_add_by_string("4", "dollar"); +grub_keymap_add_by_string("parenleft", "5"); +grub_keymap_add_by_string("5", "percent"); +grub_keymap_add_by_string("minus", "6"); +grub_keymap_add_by_string("6", "caret"); +grub_keymap_add_by_string("backquote", "7"); +grub_keymap_add_by_string("7", "ampersand"); +grub_keymap_add_by_string("underscore", "8"); +grub_keymap_add_by_string("8", "asterisk"); +grub_keymap_add_by_string("caret", "9"); +grub_keymap_add_by_string("9", "parenleft"); +grub_keymap_add_by_string("at", "0"); +grub_keymap_add_by_string("0", "parenright"); +grub_keymap_add_by_string("parenright", "minus"); +grub_keymap_add_by_string("less", "backquote"); +grub_keymap_add_by_string("greater", "tilde"); +grub_keymap_add_by_string("numbersign", "braceright"); +grub_keymap_add_by_string("backslash", "question"); +grub_keymap_add_by_string("bracketright", "braceleft"); +grub_keymap_add_by_string("braceleft", "quote"); +grub_keymap_add_by_string("braceright", "underscore"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_CZECH_QWERTY(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("semicolon", "backquote"); +grub_keymap_add_by_string("plus", "1"); +grub_keymap_add_by_string("equal", "minus"); +grub_keymap_add_by_string("quote", "equal"); +grub_keymap_add_by_string("parenright", "bracketright"); +grub_keymap_add_by_string("doublequote", "backslash"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("1", "exclam"); +grub_keymap_add_by_string("2", "at"); +grub_keymap_add_by_string("3", "numbersign"); +grub_keymap_add_by_string("4", "dollar"); +grub_keymap_add_by_string("5", "percent"); +grub_keymap_add_by_string("6", "caret"); +grub_keymap_add_by_string("7", "ampersand"); +grub_keymap_add_by_string("8", "asterisk"); +grub_keymap_add_by_string("9", "parenleft"); +grub_keymap_add_by_string("0", "parenright"); +grub_keymap_add_by_string("percent", "underscore"); +grub_keymap_add_by_string("slash", "braceleft"); +grub_keymap_add_by_string("parenleft", "braceright"); +grub_keymap_add_by_string("doublequote", "colon"); +grub_keymap_add_by_string("exclam", "doublequote"); +grub_keymap_add_by_string("quote", "bar"); +grub_keymap_add_by_string("question", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("backquote", "Abackquote"); +grub_keymap_add_by_string("exclam", "A1"); +grub_keymap_add_by_string("at", "A2"); +grub_keymap_add_by_string("numbersign", "A3"); +grub_keymap_add_by_string("dollar", "A4"); +grub_keymap_add_by_string("percent", "A5"); +grub_keymap_add_by_string("caret", "A6"); +grub_keymap_add_by_string("ampersand", "A7"); +grub_keymap_add_by_string("asterisk", "A8"); +grub_keymap_add_by_string("parenleft", "A9"); +grub_keymap_add_by_string("parenright", "A0"); +grub_keymap_add_by_string("minus", "Aminus"); +grub_keymap_add_by_string("equal", "Aequal"); +grub_keymap_add_by_string("bracketleft", "Abracketleft"); +grub_keymap_add_by_string("bracketright", "Abracketright"); +grub_keymap_add_by_string("semicolon", "Asemicolon"); +grub_keymap_add_by_string("backslash", "Abackslash"); +grub_keymap_add_by_string("less", "Acomma"); +grub_keymap_add_by_string("greater", "Aperiod"); +grub_keymap_add_by_string("slash", "Aslash"); +grub_keymap_add_by_string("tilde", "Atilde"); +grub_keymap_add_by_string("underscore", "Aunderscore"); +grub_keymap_add_by_string("plus", "Aplus"); +grub_keymap_add_by_string("braceleft", "Abraceleft"); +grub_keymap_add_by_string("braceright", "Abraceright"); +grub_keymap_add_by_string("caret", "Adoublequote"); +grub_keymap_add_by_string("colon", "Acolon"); +grub_keymap_add_by_string("question", "Aquestion"); +grub_keymap_add_by_string("bar", "Abar"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_CZECH_QWERTZ(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("y", "z"); +grub_keymap_add_by_string("z", "y"); +grub_keymap_add_by_string("Y", "Z"); +grub_keymap_add_by_string("Z", "Y"); +grub_keymap_add_by_string("semicolon", "backquote"); +grub_keymap_add_by_string("plus", "1"); +grub_keymap_add_by_string("equal", "minus"); +grub_keymap_add_by_string("quote", "equal"); +grub_keymap_add_by_string("parenright", "bracketright"); +grub_keymap_add_by_string("doublequote", "backslash"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("1", "exclam"); +grub_keymap_add_by_string("2", "at"); +grub_keymap_add_by_string("3", "numbersign"); +grub_keymap_add_by_string("4", "dollar"); +grub_keymap_add_by_string("5", "percent"); +grub_keymap_add_by_string("6", "caret"); +grub_keymap_add_by_string("7", "ampersand"); +grub_keymap_add_by_string("8", "asterisk"); +grub_keymap_add_by_string("9", "parenleft"); +grub_keymap_add_by_string("0", "parenright"); +grub_keymap_add_by_string("percent", "underscore"); +grub_keymap_add_by_string("slash", "braceleft"); +grub_keymap_add_by_string("parenleft", "braceright"); +grub_keymap_add_by_string("doublequote", "colon"); +grub_keymap_add_by_string("exclam", "doublequote"); +grub_keymap_add_by_string("quote", "bar"); +grub_keymap_add_by_string("question", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("tilde", "A1"); +grub_keymap_add_by_string("caret", "A3"); +grub_keymap_add_by_string("backslash", "Aq"); +grub_keymap_add_by_string("bar", "Aw"); +grub_keymap_add_by_string("bracketleft", "Af"); +grub_keymap_add_by_string("bracketright", "Ag"); +grub_keymap_add_by_string("dollar", "Asemicolon"); +grub_keymap_add_by_string("numbersign", "Ax"); +grub_keymap_add_by_string("ampersand", "Ac"); +grub_keymap_add_by_string("at", "Av"); +grub_keymap_add_by_string("braceleft", "Ab"); +grub_keymap_add_by_string("braceright", "An"); +grub_keymap_add_by_string("less", "Acomma"); +grub_keymap_add_by_string("greater", "Aperiod"); +grub_keymap_add_by_string("asterisk", "Aslash"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_DANISH(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("plus", "minus"); +grub_keymap_add_by_string("quote", "equal"); +grub_keymap_add_by_string("doublequote", "bracketright"); +grub_keymap_add_by_string("quote", "backslash"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("caret", "braceright"); +grub_keymap_add_by_string("asterisk", "bar"); +grub_keymap_add_by_string("backquote", "plus"); +grub_keymap_add_by_string("semicolon", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("bar", "Atilde"); +grub_keymap_add_by_string("backslash", "Abackquote"); +grub_keymap_add_by_string("greater", "tilde"); +grub_keymap_add_by_string("at", "A2"); +grub_keymap_add_by_string("dollar", "A4"); +grub_keymap_add_by_string("braceleft", "A7"); +grub_keymap_add_by_string("bracketleft", "A8"); +grub_keymap_add_by_string("bracketright", "A9"); +grub_keymap_add_by_string("braceright", "A0"); +grub_keymap_add_by_string("backslash", "Aminus"); +grub_keymap_add_by_string("less", "quote"); +grub_keymap_add_by_string("greater", "doublequote"); +grub_keymap_add_by_string("tilde", "Abracketright"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_DVORAK_USA(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("[", "minus"); +grub_keymap_add_by_string("braceleft", "underscore"); +grub_keymap_add_by_string("quote", "q"); +grub_keymap_add_by_string("doublequote", "Q"); +grub_keymap_add_by_string("comma", "w"); +grub_keymap_add_by_string("less", "W"); +grub_keymap_add_by_string("s", "semicolon"); +grub_keymap_add_by_string("S", "colon"); +grub_keymap_add_by_string("semicolon", "z"); +grub_keymap_add_by_string("colon", "Z"); +grub_keymap_add_by_string("w", "comma"); +grub_keymap_add_by_string("W", "less"); +grub_keymap_add_by_string("v", "period"); +grub_keymap_add_by_string("z", "greater"); +grub_keymap_add_by_string("z", "slash"); +grub_keymap_add_by_string("equal", "bracketright"); +grub_keymap_add_by_string("backslash", "backslash"); +grub_keymap_add_by_string("underscore", "doublequote"); +grub_keymap_add_by_string("quote", "q"); +grub_keymap_add_by_string("doublequote", "Q"); +grub_keymap_add_by_string("comma", "w"); +grub_keymap_add_by_string("less", "W"); +grub_keymap_add_by_string("period", "e"); +grub_keymap_add_by_string("greater", "E"); +grub_keymap_add_by_string("p", "r"); +grub_keymap_add_by_string("P", "R"); +grub_keymap_add_by_string("y", "t"); +grub_keymap_add_by_string("Y", "T"); +grub_keymap_add_by_string("f", "y"); +grub_keymap_add_by_string("F", "Y"); +grub_keymap_add_by_string("g", "u"); +grub_keymap_add_by_string("G", "U"); +grub_keymap_add_by_string("c", "c"); +grub_keymap_add_by_string("C", "I"); +grub_keymap_add_by_string("r", "o"); +grub_keymap_add_by_string("R", "O"); +grub_keymap_add_by_string("l", "p"); +grub_keymap_add_by_string("L", "P"); +grub_keymap_add_by_string("bracketright", "equal"); +grub_keymap_add_by_string("braceright", "plus"); +grub_keymap_add_by_string("a", "a"); +grub_keymap_add_by_string("A", "A"); +grub_keymap_add_by_string("o", "s"); +grub_keymap_add_by_string("O", "S"); +grub_keymap_add_by_string("e", "d"); +grub_keymap_add_by_string("E", "D"); +grub_keymap_add_by_string("u", "f"); +grub_keymap_add_by_string("U", "F"); +grub_keymap_add_by_string("i", "g"); +grub_keymap_add_by_string("I", "G"); +grub_keymap_add_by_string("d", "h"); +grub_keymap_add_by_string("D", "H"); +grub_keymap_add_by_string("h", "j"); +grub_keymap_add_by_string("H", "J"); +grub_keymap_add_by_string("t", "k"); +grub_keymap_add_by_string("T", "K"); +grub_keymap_add_by_string("n", "l"); +grub_keymap_add_by_string("N", "L"); +grub_keymap_add_by_string("s", "semicolon"); +grub_keymap_add_by_string("S", "colon"); +grub_keymap_add_by_string("minus", "quote"); +grub_keymap_add_by_string("underscore", "doublequote"); +grub_keymap_add_by_string("semicolon", "z"); +grub_keymap_add_by_string("colon", "Z"); +grub_keymap_add_by_string("q", "x"); +grub_keymap_add_by_string("Q", "X"); +grub_keymap_add_by_string("j", "c"); +grub_keymap_add_by_string("J", "C"); +grub_keymap_add_by_string("k", "v"); +grub_keymap_add_by_string("K", "V"); +grub_keymap_add_by_string("x", "b"); +grub_keymap_add_by_string("X", "B"); +grub_keymap_add_by_string("b", "n"); +grub_keymap_add_by_string("B", "N"); +grub_keymap_add_by_string("w", "comma"); +grub_keymap_add_by_string("W", "less"); +grub_keymap_add_by_string("v", "period"); +grub_keymap_add_by_string("V", "greater"); +grub_keymap_add_by_string("z", "slash"); +grub_keymap_add_by_string("Z", "question"); +grub_keymap_add_by_string("slash", "bracketleft"); +grub_keymap_add_by_string("question", "braceleft"); +grub_keymap_add_by_string("equal", "bracketright"); +grub_keymap_add_by_string("plus", "braceright"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_FRENCH(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("less", "backquote"); +grub_keymap_add_by_string("greater", "tilde"); +grub_keymap_add_by_string("ampersand", "1"); +grub_keymap_add_by_string("1", "exclam"); +grub_keymap_add_by_string("tilde", "2"); +grub_keymap_add_by_string("2", "at"); +grub_keymap_add_by_string("doublequote", "3"); +grub_keymap_add_by_string("3", "numbersign"); +grub_keymap_add_by_string("quote", "4"); +grub_keymap_add_by_string("4", "dollar"); +grub_keymap_add_by_string("parenleft", "5"); +grub_keymap_add_by_string("5", "percent"); +grub_keymap_add_by_string("minus", "6"); +grub_keymap_add_by_string("6", "caret"); +grub_keymap_add_by_string("backquote", "7"); +grub_keymap_add_by_string("7", "ampersand"); +grub_keymap_add_by_string("underscore", "8"); +grub_keymap_add_by_string("8", "asterisk"); +grub_keymap_add_by_string("backslash", "9"); +grub_keymap_add_by_string("9", "parenleft"); +grub_keymap_add_by_string("at", "0"); +grub_keymap_add_by_string("0", "parenright"); +grub_keymap_add_by_string("parenright", "minus"); +grub_keymap_add_by_string("numbersign", "underscore"); +grub_keymap_add_by_string("a", "q"); +grub_keymap_add_by_string("A", "Q"); +grub_keymap_add_by_string("z", "w"); +grub_keymap_add_by_string("Z", "W"); +grub_keymap_add_by_string("caret", "bracketleft"); +grub_keymap_add_by_string("dollar", "bracketright"); +grub_keymap_add_by_string("q", "a"); +grub_keymap_add_by_string("Q", "A"); +grub_keymap_add_by_string("m", "semicolon"); +grub_keymap_add_by_string("M", "colon"); +grub_keymap_add_by_string("bracketleft", "quote"); +grub_keymap_add_by_string("percent", "doublequote"); +grub_keymap_add_by_string("asterisk", "backslash"); +grub_keymap_add_by_string("bracketright", "bar"); +grub_keymap_add_by_string("w", "z"); +grub_keymap_add_by_string("W", "Z"); +grub_keymap_add_by_string("comma", "m"); +grub_keymap_add_by_string("question", "M"); +grub_keymap_add_by_string("semicolon", "comma"); +grub_keymap_add_by_string("period", "less"); +grub_keymap_add_by_string("colon", "period"); +grub_keymap_add_by_string("slash", "greater"); +grub_keymap_add_by_string("exclam", "slash"); +grub_keymap_add_by_string("bar", "question"); +grub_keymap_add_by_string("tilde", "A2"); +grub_keymap_add_by_string("numbersign", "A3"); +grub_keymap_add_by_string("braceleft", "A4"); +grub_keymap_add_by_string("bracketleft", "A5"); +grub_keymap_add_by_string("bar", "A6"); +grub_keymap_add_by_string("quote", "A7"); +grub_keymap_add_by_string("backslash", "A8"); +grub_keymap_add_by_string("caret", "A9"); +grub_keymap_add_by_string("at", "A0"); +grub_keymap_add_by_string("bracketright", "Aminus"); +grub_keymap_add_by_string("braceright", "Aequal"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_GERMAN(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("backslash", "minus"); +grub_keymap_add_by_string("z", "y"); +grub_keymap_add_by_string("Z", "Y"); +grub_keymap_add_by_string("y", "z"); +grub_keymap_add_by_string("Y", "Z"); +grub_keymap_add_by_string("plus", "bracketright"); +grub_keymap_add_by_string("asterisk", "braceright"); +grub_keymap_add_by_string("semicolon", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("backslash", "Aminus"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("caret", "backquote"); +grub_keymap_add_by_string("quote", "equal"); +grub_keymap_add_by_string("backquote", "plus"); +grub_keymap_add_by_string("braceright", "doublequote"); +grub_keymap_add_by_string("bar", "bracketleft"); +grub_keymap_add_by_string("at", "braceleft"); +grub_keymap_add_by_string("numbersign", "backslash"); +grub_keymap_add_by_string("at", "Aq"); +grub_keymap_add_by_string("less", "backquote"); +grub_keymap_add_by_string("greater", "tilde"); +grub_keymap_add_by_string("braceleft", "A7"); +grub_keymap_add_by_string("bracketleft", "A8"); +grub_keymap_add_by_string("bracketright", "A9"); +grub_keymap_add_by_string("braceright", "A0"); +grub_keymap_add_by_string("tilde", "Abracketright"); +grub_keymap_add_by_string("backslash", "Aminus"); +grub_keymap_add_by_string("quote", "bar"); +grub_keymap_add_by_string("greater", "semicolon"); +grub_keymap_add_by_string("less", "colon"); +grub_keymap_add_by_string("bar", "quote"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_ITALIANO(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("backslash", "backquote"); +grub_keymap_add_by_string("bar", "tilde"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("tilde", "numbersign"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("quote", "minus"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("caret", "plus"); +grub_keymap_add_by_string("bracketleft", "bracketleft"); +grub_keymap_add_by_string("bracketright", "braceleft"); +grub_keymap_add_by_string("plus", "bracketright"); +grub_keymap_add_by_string("asterisk", "braceright"); +grub_keymap_add_by_string("at", "semicolon"); +grub_keymap_add_by_string("braceleft", "colon"); +grub_keymap_add_by_string("numbersign", "quote"); +grub_keymap_add_by_string("braceright", "doublequote"); +grub_keymap_add_by_string("less", "backslash"); +grub_keymap_add_by_string("greater", "bar"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("semicolon", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("bracketleft", "Abracketleft"); +grub_keymap_add_by_string("bracketright", "Abracketright"); +grub_keymap_add_by_string("at", "Asemicolon"); +grub_keymap_add_by_string("numbersign", "Aquote"); +grub_keymap_add_by_string("braceright", "Abraceright"); +grub_keymap_add_by_string("braceleft", "Abraceleft"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_JAPAN_106(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("at", "bracketleft"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("quote", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("underscore", "parenright"); +grub_keymap_add_by_string("equal", "underscore"); +grub_keymap_add_by_string("plus", "colon"); +grub_keymap_add_by_string("colon", "quote"); +grub_keymap_add_by_string("asterisk", "doublequote"); +grub_keymap_add_by_string("bracketleft", "bracketright"); +grub_keymap_add_by_string("braceleft", "braceright"); +grub_keymap_add_by_string("bracketright", "backslash"); +grub_keymap_add_by_string("braceright", "bar"); +grub_keymap_add_by_string("backslash", "backquote"); +grub_keymap_add_by_string("tilde", "plus"); +grub_keymap_add_by_string("caret", "equal"); +grub_keymap_add_by_string("backquote", "braceleft"); +grub_keymap_add_by_string("bar", "tilde"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_LATIN_USA(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("bar", "backquote"); +grub_keymap_add_by_string("quote", "minus"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("backquote", "bracketleft"); +grub_keymap_add_by_string("plus", "bracketright"); +grub_keymap_add_by_string("braceleft", "quote"); +grub_keymap_add_by_string("braceright", "backslash"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("asterisk", "braceright"); +grub_keymap_add_by_string("bracketleft", "doublequote"); +grub_keymap_add_by_string("bracketright", "bar"); +grub_keymap_add_by_string("semicolon", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("caret", "Aquote"); +grub_keymap_add_by_string("doublequote", "braceleft"); +grub_keymap_add_by_string("at", "Aq"); +grub_keymap_add_by_string("backquote", "Abackslash"); +grub_keymap_add_by_string("backslash", "Aminus"); +grub_keymap_add_by_string("greater", "plus"); +grub_keymap_add_by_string("less", "equal"); +grub_keymap_add_by_string("backslash", "Aminus"); +grub_keymap_add_by_string("backquote", "Abackslash"); +grub_keymap_add_by_string("tilde", "Abracketright"); +grub_keymap_add_by_string("caret", "Aquote"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_PORTU_BRAZIL(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("quote", "backquote"); +grub_keymap_add_by_string("quote", "bracketleft"); +grub_keymap_add_by_string("bracketleft", "bracketright"); +grub_keymap_add_by_string("tilde", "quote"); +grub_keymap_add_by_string("bracketright", "backslash"); +grub_keymap_add_by_string("semicolon", "slash"); +grub_keymap_add_by_string("bar", "colon"); +grub_keymap_add_by_string("doublequote", "tilde"); +grub_keymap_add_by_string("backquote", "braceleft"); +grub_keymap_add_by_string("braceleft", "braceright"); +grub_keymap_add_by_string("caret", "doublequote"); +grub_keymap_add_by_string("braceright", "bar"); +grub_keymap_add_by_string("colon", "question"); +grub_keymap_add_by_string("backslash", "semicolon"); +grub_keymap_add_by_string("bar", "Atilde"); +grub_keymap_add_by_string("backslash", "Abackquote"); +grub_keymap_add_by_string("slash", "Aq"); +grub_keymap_add_by_string("question", "Aw"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_QWERTY_UK(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("at", "doublequote"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("tilde", "bar"); +grub_keymap_add_by_string("numbersign", "backslash"); +grub_keymap_add_by_string("backslash", "numbersign"); +grub_keymap_add_by_string("bar", "tilde"); +grub_keymap_add_by_string("backslash", "Atilde"); +grub_keymap_add_by_string("backslash", "Abackquote"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_QWERTZ(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("ampersand", "percent"); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("backslash", "minus"); +grub_keymap_add_by_string("z", "y"); +grub_keymap_add_by_string("Z", "Y"); +grub_keymap_add_by_string("y", "z"); +grub_keymap_add_by_string("Y", "Z"); +grub_keymap_add_by_string("plus", "bracketright"); +grub_keymap_add_by_string("asterisk", "braceright"); +grub_keymap_add_by_string("semicolon", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("caret", "backquote"); +grub_keymap_add_by_string("backquote", "equal"); +grub_keymap_add_by_string("numbersign", "backslash"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("percent", "caret"); +grub_keymap_add_by_string("less", "numbersign"); +grub_keymap_add_by_string("greater", "bar"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_QWERTZ_HUN(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("y", "z"); +grub_keymap_add_by_string("z", "y"); +grub_keymap_add_by_string("Y", "Z"); +grub_keymap_add_by_string("Z", "Y"); +grub_keymap_add_by_string("0", "backquote"); +grub_keymap_add_by_string("quote", "exclam"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("plus", "numbersign"); +grub_keymap_add_by_string("exclam", "dollar"); +grub_keymap_add_by_string("slash", "caret"); +grub_keymap_add_by_string("equal", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("backslash", "Aq"); +grub_keymap_add_by_string("bar", "Aw"); +grub_keymap_add_by_string("bracketleft", "Af"); +grub_keymap_add_by_string("bracketright", "Ag"); +grub_keymap_add_by_string("greater", "Az"); +grub_keymap_add_by_string("numbersign", "Ax"); +grub_keymap_add_by_string("ampersand", "Ac"); +grub_keymap_add_by_string("at", "Av"); +grub_keymap_add_by_string("braceleft", "Ab"); +grub_keymap_add_by_string("braceright", "An"); +grub_keymap_add_by_string("less", "Am"); +grub_keymap_add_by_string("dollar", "colon"); +grub_keymap_add_by_string("question", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("at", "doublequote"); +grub_keymap_add_by_string("tilde", "A1"); +grub_keymap_add_by_string("caret", "A3"); +grub_keymap_add_by_string("backquote", "A7"); +grub_keymap_add_by_string("asterisk", "0"); +grub_keymap_add_by_string("dollar", "Asemicolon"); +grub_keymap_add_by_string("semicolon", "Acomma"); +grub_keymap_add_by_string("greater", "Aperiod"); +grub_keymap_add_by_string("asterisk", "Aslash"); +grub_keymap_add_by_string("backquote", "A9"); +grub_keymap_add_by_string("doublequote", "A0"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_QWERTZ_SLOV_CROAT(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("quote", "minus"); +grub_keymap_add_by_string("plus", "equal"); +grub_keymap_add_by_string("y", "z"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("doublequote", "tilde"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("asterisk", "plus"); +grub_keymap_add_by_string("Y", "Z"); +grub_keymap_add_by_string("semicolon", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("tilde", "A1"); +grub_keymap_add_by_string("caret", "A3"); +grub_keymap_add_by_string("backquote", "A7"); +grub_keymap_add_by_string("backslash", "Aq"); +grub_keymap_add_by_string("bar", "Aw"); +grub_keymap_add_by_string("bracketleft", "Af"); +grub_keymap_add_by_string("bracketright", "Ag"); +grub_keymap_add_by_string("at", "Av"); +grub_keymap_add_by_string("braceleft", "Ab"); +grub_keymap_add_by_string("braceright", "An"); +grub_keymap_add_by_string("less", "Acomma"); +grub_keymap_add_by_string("greater", "Aperiod"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_SPANISH(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("caret", "braceleft"); +grub_keymap_add_by_string("asterisk", "braceright"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("quote", "minus"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("greater", "bar"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("backslash", "backquote"); +grub_keymap_add_by_string("less", "backslash"); +grub_keymap_add_by_string("semicolon", "less"); +grub_keymap_add_by_string("backquote", "bracketleft"); +grub_keymap_add_by_string("plus", "bracketright"); +grub_keymap_add_by_string("plus", "colon"); +grub_keymap_add_by_string("at", "semicolon"); +grub_keymap_add_by_string("bar", "A1"); +grub_keymap_add_by_string("at", "A2"); +grub_keymap_add_by_string("numbersign", "A3"); +grub_keymap_add_by_string("tilde", "A4"); +grub_keymap_add_by_string("bracketleft", "Abracketleft"); +grub_keymap_add_by_string("bracketright", "Abracketright"); +grub_keymap_add_by_string("braceleft", "Aquote"); +grub_keymap_add_by_string("braceright", "Abackslash"); +grub_keymap_add_by_string("greater", "bar"); +grub_keymap_add_by_string("less", "backslash"); +grub_keymap_add_by_string("backslash", "Abackquote"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_SWEDISH(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("plus", "minus"); +grub_keymap_add_by_string("quote", "equal"); +grub_keymap_add_by_string("doublequote", "bracketright"); +grub_keymap_add_by_string("quote", "backslash"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("caret", "braceright"); +grub_keymap_add_by_string("asterisk", "bar"); +grub_keymap_add_by_string("backquote", "plus"); +grub_keymap_add_by_string("semicolon", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("bar", "Atilde"); +grub_keymap_add_by_string("backslash", "Abackquote"); +grub_keymap_add_by_string("greater", "tilde"); +grub_keymap_add_by_string("at", "A2"); +grub_keymap_add_by_string("dollar", "A4"); +grub_keymap_add_by_string("braceleft", "A7"); +grub_keymap_add_by_string("bracketleft", "A8"); +grub_keymap_add_by_string("bracketright", "A9"); +grub_keymap_add_by_string("braceright", "A0"); +grub_keymap_add_by_string("backslash", "Aminus"); +grub_keymap_add_by_string("less", "quote"); +grub_keymap_add_by_string("greater", "doublequote"); +grub_keymap_add_by_string("tilde", "Abracketright"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_TURKISH_Q(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("doublequote", "backquote"); +grub_keymap_add_by_string("asterisk", "minus"); +grub_keymap_add_by_string("minus", "equal"); +grub_keymap_add_by_string("comma", "backslash"); +grub_keymap_add_by_string("period", "slash"); +grub_keymap_add_by_string("quote", "at"); +grub_keymap_add_by_string("caret", "numbersign"); +grub_keymap_add_by_string("plus", "dollar"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("underscore", "plus"); +grub_keymap_add_by_string("semicolon", "bar"); +grub_keymap_add_by_string("colon", "question"); +grub_keymap_add_by_string("less", "Abackquote"); +grub_keymap_add_by_string("greater", "A1"); +grub_keymap_add_by_string("numbersign", "A3"); +grub_keymap_add_by_string("dollar", "A4"); +grub_keymap_add_by_string("braceleft", "A7"); +grub_keymap_add_by_string("bracketleft", "A8"); +grub_keymap_add_by_string("bracketright", "A9"); +grub_keymap_add_by_string("braceright", "A0"); +grub_keymap_add_by_string("backslash", "Aminus"); +grub_keymap_add_by_string("bar", "Aequal"); +grub_keymap_add_by_string("at", "Aq"); +grub_keymap_add_by_string("doublequote", "Abracketleft"); +grub_keymap_add_by_string("tilde", "Abracketright"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_VIETNAMESE(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("exclam", "A1"); +grub_keymap_add_by_string("at", "A2"); +grub_keymap_add_by_string("numbersign", "A3"); +grub_keymap_add_by_string("dollar", "A4"); +grub_keymap_add_by_string("percent", "A5"); +grub_keymap_add_by_string("caret", "A6"); +grub_keymap_add_by_string("ampersand", "A7"); +grub_keymap_add_by_string("asterisk", "A8"); +grub_keymap_add_by_string("parenleft", "A9"); +grub_keymap_add_by_string("parenright", "A0"); +grub_keymap_add_by_string("plus", "Aplus"); +grub_keymap_add_by_string("equal", "Aequal"); +grub_keymap_add_by_string("braceleft", "Abraceleft"); +grub_keymap_add_by_string("braceright", "Abraceright"); +grub_keymap_add_by_string("colon", "Acolon"); +grub_keymap_add_by_string("semicolon", "Asemicolon"); +grub_keymap_add_by_string("quote", "Aquote"); +grub_keymap_add_by_string("backslash", "Abackslash"); +grub_keymap_add_by_string("less", "Aless"); +grub_keymap_add_by_string("greater", "Agreater"); +grub_keymap_add_by_string("comma", "Acomma"); +grub_keymap_add_by_string("period", "Aperiod"); +grub_keymap_add_by_string("question", "Aquestion"); +grub_keymap_add_by_string("slash", "Aslash"); +grub_keymap_add_by_string("tilde", "Atilde"); +grub_keymap_add_by_string("backquote", "Abackquote"); +grub_keymap_add_by_string("bracketright", "Abracketright"); +grub_keymap_add_by_string("bracketleft", "Abracketleft"); +grub_keymap_add_by_string("bar", "Abar"); +grub_keymap_add_by_string("doublequote", "Adoublequote"); +grub_keymap_add_by_string("colon", "Acolon"); +grub_keymap_add_by_string("minus", "Aminus"); +grub_keymap_add_by_string("underscore", "Aunderscore"); +grub_keymap_enable(); +} +void ventoy_set_keyboard_layout(const char *layout); +void ventoy_set_keyboard_layout(const char *layout) { +ventoy_keyboard_set_layout(QWERTY_USA); +ventoy_keyboard_set_layout(AZERTY); +ventoy_keyboard_set_layout(CZECH_QWERTY); +ventoy_keyboard_set_layout(CZECH_QWERTZ); +ventoy_keyboard_set_layout(DANISH); +ventoy_keyboard_set_layout(DVORAK_USA); +ventoy_keyboard_set_layout(FRENCH); +ventoy_keyboard_set_layout(GERMAN); +ventoy_keyboard_set_layout(ITALIANO); +ventoy_keyboard_set_layout(JAPAN_106); +ventoy_keyboard_set_layout(LATIN_USA); +ventoy_keyboard_set_layout(PORTU_BRAZIL); +ventoy_keyboard_set_layout(QWERTY_UK); +ventoy_keyboard_set_layout(QWERTZ); +ventoy_keyboard_set_layout(QWERTZ_HUN); +ventoy_keyboard_set_layout(QWERTZ_SLOV_CROAT); +ventoy_keyboard_set_layout(SPANISH); +ventoy_keyboard_set_layout(SWEDISH); +ventoy_keyboard_set_layout(TURKISH_Q); +ventoy_keyboard_set_layout(VIETNAMESE); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/term/serial.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/term/serial.c new file mode 100644 index 0000000..3b2e01c --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/term/serial.c @@ -0,0 +1,463 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#if !defined (GRUB_MACHINE_EMU) && ((defined(__mips__) && _MIPS_SIM != _ABI64) || defined (__i386__) || defined (__x86_64__)) +#include +#endif +#include +#include +#include +#ifdef GRUB_MACHINE_MIPS_LOONGSON +#include +#endif +#ifdef GRUB_MACHINE_IEEE1275 +#include +#endif + +GRUB_MOD_LICENSE ("GPLv3+"); + +#define FOR_SERIAL_PORTS(var) FOR_LIST_ELEMENTS((var), (grub_serial_ports)) + +enum + { + OPTION_UNIT, + OPTION_PORT, + OPTION_SPEED, + OPTION_WORD, + OPTION_PARITY, + OPTION_STOP, + OPTION_BASE_CLOCK, + OPTION_RTSCTS + }; + +/* Argument options. */ +static const struct grub_arg_option options[] = +{ + {"unit", 'u', 0, N_("Set the serial unit."), 0, ARG_TYPE_INT}, + {"port", 'p', 0, N_("Set the serial port address."), 0, ARG_TYPE_STRING}, + {"speed", 's', 0, N_("Set the serial port speed."), 0, ARG_TYPE_INT}, + {"word", 'w', 0, N_("Set the serial port word length."), 0, ARG_TYPE_INT}, + {"parity", 'r', 0, N_("Set the serial port parity."), 0, ARG_TYPE_STRING}, + {"stop", 't', 0, N_("Set the serial port stop bits."), 0, ARG_TYPE_INT}, + {"base-clock", 'b', 0, N_("Set the base frequency."), 0, ARG_TYPE_STRING}, + {"rtscts", 'f', 0, N_("Enable/disable RTS/CTS."), "on|off", ARG_TYPE_STRING}, + {0, 0, 0, 0, 0, 0} +}; + +static struct grub_serial_port *grub_serial_ports; + +struct grub_serial_output_state +{ + struct grub_terminfo_output_state tinfo; + struct grub_serial_port *port; +}; + +struct grub_serial_input_state +{ + struct grub_terminfo_input_state tinfo; + struct grub_serial_port *port; +}; + +static void +serial_put (grub_term_output_t term, const int c) +{ + struct grub_serial_output_state *data = term->data; + data->port->driver->put (data->port, c); +} + +static int +serial_fetch (grub_term_input_t term) +{ + struct grub_serial_input_state *data = term->data; + return data->port->driver->fetch (data->port); +} + +static const struct grub_serial_input_state grub_serial_terminfo_input_template = + { + .tinfo = + { + .readkey = serial_fetch + } + }; + +static const struct grub_serial_output_state grub_serial_terminfo_output_template = + { + .tinfo = + { + .put = serial_put, + .size = { 80, 24 } + } + }; + +static struct grub_serial_input_state grub_serial_terminfo_input; + +static struct grub_serial_output_state grub_serial_terminfo_output; + +static int registered = 0; + +static struct grub_term_input grub_serial_term_input = +{ + .name = "serial", + .init = grub_terminfo_input_init, + .getkey = grub_terminfo_getkey, + .data = &grub_serial_terminfo_input +}; + +static struct grub_term_output grub_serial_term_output = +{ + .name = "serial", + .init = grub_terminfo_output_init, + .putchar = grub_terminfo_putchar, + .getwh = grub_terminfo_getwh, + .getxy = grub_terminfo_getxy, + .gotoxy = grub_terminfo_gotoxy, + .cls = grub_terminfo_cls, + .setcolorstate = grub_terminfo_setcolorstate, + .setcursor = grub_terminfo_setcursor, + .flags = GRUB_TERM_CODE_TYPE_ASCII, + .data = &grub_serial_terminfo_output, + .progress_update_divisor = GRUB_PROGRESS_SLOW +}; + + + +struct grub_serial_port * +grub_serial_find (const char *name) +{ + struct grub_serial_port *port; + + FOR_SERIAL_PORTS (port) + if (grub_strcmp (port->name, name) == 0) + break; + +#if ((defined(__mips__) && _MIPS_SIM != _ABI64) || defined (__i386__) || defined (__x86_64__)) && !defined(GRUB_MACHINE_EMU) && !defined(GRUB_MACHINE_ARC) + if (!port && grub_memcmp (name, "port", sizeof ("port") - 1) == 0 + && grub_isxdigit (name [sizeof ("port") - 1])) + { + name = grub_serial_ns8250_add_port (grub_strtoul (&name[sizeof ("port") - 1], + 0, 16)); + if (!name) + return NULL; + + FOR_SERIAL_PORTS (port) + if (grub_strcmp (port->name, name) == 0) + break; + } +#endif + +#ifdef GRUB_MACHINE_IEEE1275 + if (!port && grub_memcmp (name, "ieee1275/", sizeof ("ieee1275/") - 1) == 0) + { + name = grub_ofserial_add_port (&name[sizeof ("ieee1275/") - 1]); + if (!name) + return NULL; + + FOR_SERIAL_PORTS (port) + if (grub_strcmp (port->name, name) == 0) + break; + } +#endif + + return port; +} + +static grub_err_t +grub_cmd_serial (grub_extcmd_context_t ctxt, int argc, char **args) +{ + struct grub_arg_list *state = ctxt->state; + char pname[40]; + const char *name = NULL; + struct grub_serial_port *port; + struct grub_serial_config config; + grub_err_t err; + + if (state[OPTION_UNIT].set) + { + grub_snprintf (pname, sizeof (pname), "com%ld", + grub_strtoul (state[0].arg, 0, 0)); + name = pname; + } + + if (state[OPTION_PORT].set) + { + grub_snprintf (pname, sizeof (pname), "port%lx", + grub_strtoul (state[1].arg, 0, 0)); + name = pname; + } + + if (argc >= 1) + name = args[0]; + + if (!name) + name = "com0"; + + port = grub_serial_find (name); + if (!port) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("serial port `%s' isn't found"), + name); + + config = port->config; + + if (state[OPTION_SPEED].set) { + config.speed = grub_strtoul (state[OPTION_SPEED].arg, 0, 0); + if (config.speed == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("unsupported serial port parity")); + } + + if (state[OPTION_WORD].set) + config.word_len = grub_strtoul (state[OPTION_WORD].arg, 0, 0); + + if (state[OPTION_PARITY].set) + { + if (! grub_strcmp (state[OPTION_PARITY].arg, "no")) + config.parity = GRUB_SERIAL_PARITY_NONE; + else if (! grub_strcmp (state[OPTION_PARITY].arg, "odd")) + config.parity = GRUB_SERIAL_PARITY_ODD; + else if (! grub_strcmp (state[OPTION_PARITY].arg, "even")) + config.parity = GRUB_SERIAL_PARITY_EVEN; + else + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("unsupported serial port parity")); + } + + if (state[OPTION_RTSCTS].set) + { + if (grub_strcmp (state[OPTION_RTSCTS].arg, "on") == 0) + config.rtscts = 1; + else if (grub_strcmp (state[OPTION_RTSCTS].arg, "off") == 0) + config.rtscts = 0; + else + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("unsupported serial port flow control")); + } + + if (state[OPTION_STOP].set) + { + if (! grub_strcmp (state[OPTION_STOP].arg, "1")) + config.stop_bits = GRUB_SERIAL_STOP_BITS_1; + else if (! grub_strcmp (state[OPTION_STOP].arg, "2")) + config.stop_bits = GRUB_SERIAL_STOP_BITS_2; + else if (! grub_strcmp (state[OPTION_STOP].arg, "1.5")) + config.stop_bits = GRUB_SERIAL_STOP_BITS_1_5; + else + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("unsupported serial port stop bits number")); + } + + if (state[OPTION_BASE_CLOCK].set) + { + char *ptr; + config.base_clock = grub_strtoull (state[OPTION_BASE_CLOCK].arg, &ptr, 0); + if (grub_errno) + return grub_errno; + if (ptr && *ptr == 'M') + config.base_clock *= 1000000; + if (ptr && (*ptr == 'k' || *ptr == 'K')) + config.base_clock *= 1000; + } + + if (config.speed == 0) + config.speed = 9600; + + /* Initialize with new settings. */ + err = port->driver->configure (port, &config); + if (err) + return err; +#if !defined (GRUB_MACHINE_EMU) && !defined(GRUB_MACHINE_ARC) && ((defined(__mips__) && _MIPS_SIM != _ABI64) || defined (__i386__) || defined (__x86_64__)) + + /* Compatibility kludge. */ + if (port->driver == &grub_ns8250_driver) + { + if (!registered) + { + grub_terminfo_output_register (&grub_serial_term_output, "vt100"); + + grub_term_register_input ("serial", &grub_serial_term_input); + grub_term_register_output ("serial", &grub_serial_term_output); + } + grub_serial_terminfo_output.port = port; + grub_serial_terminfo_input.port = port; + registered = 1; + } +#endif + return GRUB_ERR_NONE; +} + +#ifdef GRUB_MACHINE_MIPS_LOONGSON +const char loongson_defserial[][6] = + { + [GRUB_ARCH_MACHINE_YEELOONG] = "com0", + [GRUB_ARCH_MACHINE_FULOONG2F] = "com2", + [GRUB_ARCH_MACHINE_FULOONG2E] = "com1" + }; +#endif + +grub_err_t +grub_serial_register (struct grub_serial_port *port) +{ + struct grub_term_input *in; + struct grub_term_output *out; + struct grub_serial_input_state *indata; + struct grub_serial_output_state *outdata; + + in = grub_malloc (sizeof (*in)); + if (!in) + return grub_errno; + + indata = grub_malloc (sizeof (*indata)); + if (!indata) + { + grub_free (in); + return grub_errno; + } + + grub_memcpy (in, &grub_serial_term_input, sizeof (*in)); + in->data = indata; + in->name = grub_xasprintf ("serial_%s", port->name); + grub_memcpy (indata, &grub_serial_terminfo_input, sizeof (*indata)); + + if (!in->name) + { + grub_free (in); + grub_free (indata); + return grub_errno; + } + + out = grub_zalloc (sizeof (*out)); + if (!out) + { + grub_free (indata); + grub_free ((char *) in->name); + grub_free (in); + return grub_errno; + } + + outdata = grub_malloc (sizeof (*outdata)); + if (!outdata) + { + grub_free (indata); + grub_free ((char *) in->name); + grub_free (out); + grub_free (in); + return grub_errno; + } + + grub_memcpy (out, &grub_serial_term_output, sizeof (*out)); + out->data = outdata; + out->name = in->name; + grub_memcpy (outdata, &grub_serial_terminfo_output, sizeof (*outdata)); + + grub_list_push (GRUB_AS_LIST_P (&grub_serial_ports), GRUB_AS_LIST (port)); + ((struct grub_serial_input_state *) in->data)->port = port; + ((struct grub_serial_output_state *) out->data)->port = port; + port->term_in = in; + port->term_out = out; + grub_terminfo_output_register (out, "vt100"); +#ifdef GRUB_MACHINE_MIPS_LOONGSON + if (grub_strcmp (port->name, loongson_defserial[grub_arch_machine]) == 0) + { + grub_term_register_input_active ("serial_*", in); + grub_term_register_output_active ("serial_*", out); + } + else + { + grub_term_register_input_inactive ("serial_*", in); + grub_term_register_output_inactive ("serial_*", out); + } +#else + grub_term_register_input ("serial_*", in); + grub_term_register_output ("serial_*", out); +#endif + + return GRUB_ERR_NONE; +} + +void +grub_serial_unregister (struct grub_serial_port *port) +{ + if (port->driver->fini) + port->driver->fini (port); + + if (port->term_in) + grub_term_unregister_input (port->term_in); + if (port->term_out) + grub_term_unregister_output (port->term_out); + + grub_list_remove (GRUB_AS_LIST (port)); +} + +void +grub_serial_unregister_driver (struct grub_serial_driver *driver) +{ + struct grub_serial_port *port, *next; + for (port = grub_serial_ports; port; port = next) + { + next = port->next; + if (port->driver == driver) + grub_serial_unregister (port); + } +} + +static grub_extcmd_t cmd; + +GRUB_MOD_INIT(serial) +{ + cmd = grub_register_extcmd ("serial", grub_cmd_serial, 0, + N_("[OPTIONS...]"), + N_("Configure serial port."), options); + grub_memcpy (&grub_serial_terminfo_output, + &grub_serial_terminfo_output_template, + sizeof (grub_serial_terminfo_output)); + + grub_memcpy (&grub_serial_terminfo_input, + &grub_serial_terminfo_input_template, + sizeof (grub_serial_terminfo_input)); + +#if !defined (GRUB_MACHINE_EMU) && !defined(GRUB_MACHINE_ARC) && ((defined(__mips__) && _MIPS_SIM != _ABI64) || defined (__i386__) || defined (__x86_64__)) + grub_ns8250_init (); +#endif +#ifdef GRUB_MACHINE_IEEE1275 + grub_ofserial_init (); +#endif +#ifdef GRUB_MACHINE_EFI + grub_efiserial_init (); +#endif +#ifdef GRUB_MACHINE_ARC + grub_arcserial_init (); +#endif +} + +GRUB_MOD_FINI(serial) +{ + while (grub_serial_ports) + grub_serial_unregister (grub_serial_ports); + if (registered) + { + grub_term_unregister_input (&grub_serial_term_input); + grub_term_unregister_output (&grub_serial_term_output); + } + grub_unregister_extcmd (cmd); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/term/setkey.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/term/setkey.c new file mode 100644 index 0000000..a096352 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/term/setkey.c @@ -0,0 +1,388 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2020 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +#define MAX_KEYMAP 255 + +struct keymap +{ + int cnt; + int in[MAX_KEYMAP]; + int out[MAX_KEYMAP]; +}; + +static struct keymap setkey_keymap; + +struct keysym +{ + const char *name; /* the name in unshifted state */ + int code; /* scan code */ +}; + +/* The table for key symbols. (from GRUB4DOS) */ +static struct keysym keysym_table[] = +{ + {"escape", GRUB_TERM_ESC}, // ESC + {"exclam", 0x21}, // '!' + {"at", 0x40}, // '@' + {"numbersign", 0x23}, // '#' + {"dollar", 0x24}, // '$' + {"percent", 0x25}, // '%' + {"caret", 0x5E}, // '^' + {"ampersand", 0x26}, // '&' + {"asterisk", 0x2A}, // '*' + {"parenleft", 0x28}, // '(' + {"parenright", 0x29}, // ')' + {"minus", 0x2D}, // '-' + {"underscore", 0x5F}, // '_' + {"equal", 0x3D}, // '=' + {"plus", 0x2B}, // '+' + {"backspace", GRUB_TERM_BACKSPACE}, // BS + {"ctrlbackspace", GRUB_TERM_CTRL | GRUB_TERM_BACKSPACE}, // (DEL) + {"tab", GRUB_TERM_TAB}, // Tab + {"bracketleft", 0x5B}, // '[' + {"braceleft", 0x7B}, // '{' + {"bracketright", 0x5D}, // ']' + {"braceright", 0x7D}, // '}' + {"enter", 0x0D}, // Enter + {"semicolon", 0x3B}, // ';' + {"colon", 0x3A}, // ':' + {"quote", 0x27}, // '\'' + {"doublequote", 0x22}, // '"' + {"backquote", 0x60}, // '`' + {"tilde", 0x7E}, // '~' + {"backslash", 0x5C}, // '\\' + {"bar", 0x7C}, // '|' + {"comma", 0x2C}, // ',' + {"less", 0x3C}, // '<' + {"period", 0x2E}, // '.' + {"greater", 0x3E}, // '>' + {"slash", 0x2F}, // '/' + {"question", 0x3F}, // '?' + {"space", 0x20}, // Space + {"F1", GRUB_TERM_KEY_F1}, + {"F2", GRUB_TERM_KEY_F2}, + {"F3", GRUB_TERM_KEY_F3}, + {"F4", GRUB_TERM_KEY_F4}, + {"F5", GRUB_TERM_KEY_F5}, + {"F6", GRUB_TERM_KEY_F6}, + {"F7", GRUB_TERM_KEY_F7}, + {"F8", GRUB_TERM_KEY_F8}, + {"F9", GRUB_TERM_KEY_F9}, + {"F10", GRUB_TERM_KEY_F10}, + {"F11", GRUB_TERM_KEY_F11}, + {"F12", GRUB_TERM_KEY_F12}, + {"home", GRUB_TERM_KEY_HOME}, + {"uparrow", GRUB_TERM_KEY_UP}, + {"pageup", GRUB_TERM_KEY_NPAGE}, // PgUp + {"leftarrow", GRUB_TERM_KEY_LEFT}, + {"center", GRUB_TERM_KEY_CENTER}, // keypad center key + {"rightarrow", GRUB_TERM_KEY_RIGHT}, + {"end", GRUB_TERM_KEY_END}, + {"downarrow", GRUB_TERM_KEY_DOWN}, + {"pagedown", GRUB_TERM_KEY_PPAGE}, // PgDn + {"insert", GRUB_TERM_KEY_INSERT}, // Insert + {"delete", GRUB_TERM_KEY_DC}, // Delete + {"shiftF1", GRUB_TERM_SHIFT | GRUB_TERM_KEY_F1}, + {"shiftF2", GRUB_TERM_SHIFT | GRUB_TERM_KEY_F2}, + {"shiftF3", GRUB_TERM_SHIFT | GRUB_TERM_KEY_F3}, + {"shiftF4", GRUB_TERM_SHIFT | GRUB_TERM_KEY_F4}, + {"shiftF5", GRUB_TERM_SHIFT | GRUB_TERM_KEY_F5}, + {"shiftF6", GRUB_TERM_SHIFT | GRUB_TERM_KEY_F6}, + {"shiftF7", GRUB_TERM_SHIFT | GRUB_TERM_KEY_F7}, + {"shiftF8", GRUB_TERM_SHIFT | GRUB_TERM_KEY_F8}, + {"shiftF9", GRUB_TERM_SHIFT | GRUB_TERM_KEY_F9}, + {"shiftF10", GRUB_TERM_SHIFT | GRUB_TERM_KEY_F10}, + {"shiftF11", GRUB_TERM_SHIFT | GRUB_TERM_KEY_F11}, + {"shiftF12", GRUB_TERM_SHIFT | GRUB_TERM_KEY_F12}, + {"ctrlF1", GRUB_TERM_CTRL | GRUB_TERM_KEY_F1}, + {"ctrlF2", GRUB_TERM_CTRL | GRUB_TERM_KEY_F2}, + {"ctrlF3", GRUB_TERM_CTRL | GRUB_TERM_KEY_F3}, + {"ctrlF4", GRUB_TERM_CTRL | GRUB_TERM_KEY_F4}, + {"ctrlF5", GRUB_TERM_CTRL | GRUB_TERM_KEY_F5}, + {"ctrlF6", GRUB_TERM_CTRL | GRUB_TERM_KEY_F6}, + {"ctrlF7", GRUB_TERM_CTRL | GRUB_TERM_KEY_F7}, + {"ctrlF8", GRUB_TERM_CTRL | GRUB_TERM_KEY_F8}, + {"ctrlF9", GRUB_TERM_CTRL | GRUB_TERM_KEY_F9}, + {"ctrlF10", GRUB_TERM_CTRL | GRUB_TERM_KEY_F10}, + {"ctrlF11", GRUB_TERM_CTRL | GRUB_TERM_KEY_F11}, + {"ctrlF12", GRUB_TERM_CTRL | GRUB_TERM_KEY_F12}, + // A=Alt or AltGr. Provided by steve. + {"Aq", GRUB_TERM_ALT | 0x71}, + {"Aw", GRUB_TERM_ALT | 0x77}, + {"Ae", GRUB_TERM_ALT | 0x65}, + {"Ar", GRUB_TERM_ALT | 0x72}, + {"At", GRUB_TERM_ALT | 0x74}, + {"Ay", GRUB_TERM_ALT | 0x79}, + {"Au", GRUB_TERM_ALT | 0x75}, + {"Ai", GRUB_TERM_ALT | 0x69}, + {"Ao", GRUB_TERM_ALT | 0x6F}, + {"Ap", GRUB_TERM_ALT | 0x70}, + {"Aa", GRUB_TERM_ALT | 0x61}, + {"As", GRUB_TERM_ALT | 0x73}, + {"Ad", GRUB_TERM_ALT | 0x64}, + {"Af", GRUB_TERM_ALT | 0x66}, + {"Ag", GRUB_TERM_ALT | 0x67}, + {"Ah", GRUB_TERM_ALT | 0x68}, + {"Aj", GRUB_TERM_ALT | 0x6A}, + {"Ak", GRUB_TERM_ALT | 0x6B}, + {"Al", GRUB_TERM_ALT | 0x6C}, + {"Az", GRUB_TERM_ALT | 0x7A}, + {"Ax", GRUB_TERM_ALT | 0x78}, + {"Ac", GRUB_TERM_ALT | 0x63}, + {"Av", GRUB_TERM_ALT | 0x76}, + {"Ab", GRUB_TERM_ALT | 0x62}, + {"An", GRUB_TERM_ALT | 0x6E}, + {"Am", GRUB_TERM_ALT | 0x6D}, + {"A1", GRUB_TERM_ALT | 0x31}, + {"A2", GRUB_TERM_ALT | 0x32}, + {"A3", GRUB_TERM_ALT | 0x33}, + {"A4", GRUB_TERM_ALT | 0x34}, + {"A5", GRUB_TERM_ALT | 0x35}, + {"A6", GRUB_TERM_ALT | 0x36}, + {"A7", GRUB_TERM_ALT | 0x37}, + {"A8", GRUB_TERM_ALT | 0x38}, + {"A9", GRUB_TERM_ALT | 0x39}, + {"A0", GRUB_TERM_ALT | 0x30}, + //{"oem102", 0x5c}, + //{"shiftoem102", 0x7c}, + {"Aminus", GRUB_TERM_ALT | 0x2D}, + {"Aequal", GRUB_TERM_ALT | 0x3D}, + {"Abracketleft", GRUB_TERM_ALT | 0x5B}, + {"Abracketright", GRUB_TERM_ALT | 0x5D}, + {"Asemicolon", GRUB_TERM_ALT | 0x3B}, + {"Aquote", GRUB_TERM_ALT | 0x27}, + {"Abackquote", GRUB_TERM_ALT | 0x60}, + {"Abackslash", GRUB_TERM_ALT | 0x5C}, + {"Acomma", GRUB_TERM_ALT | 0x2C}, + {"Aperiod", GRUB_TERM_ALT | 0x2E}, + {"Aslash", GRUB_TERM_ALT | 0x2F}, + {"Acolon", GRUB_TERM_ALT | 0x3A}, + {"Aplus", GRUB_TERM_ALT | 0x2B}, + {"Aless", GRUB_TERM_ALT | 0x3C}, + {"Aunderscore", GRUB_TERM_ALT | 0x5F}, + {"Agreater", GRUB_TERM_ALT | 0x3E}, + {"Aquestion", GRUB_TERM_ALT | 0x3F}, + {"Atilde", GRUB_TERM_ALT | 0x7E}, + {"Abraceleft", GRUB_TERM_ALT | 0x7B}, + {"Abar", GRUB_TERM_ALT | 0x7C}, + {"Abraceright", GRUB_TERM_ALT | 0x7D}, + {"Adoublequote", GRUB_TERM_ALT | 0x22}, +}; + +static int grub_keymap_getkey (int key) +{ + int i; + if (key == GRUB_TERM_NO_KEY) + return key; + if (setkey_keymap.cnt > MAX_KEYMAP) + setkey_keymap.cnt = MAX_KEYMAP; + for (i = 0; i < setkey_keymap.cnt; i++) + { + if (key == setkey_keymap.in[i]) + { + key = setkey_keymap.out[i]; + break; + } + } + return key; +} + +static void +grub_keymap_reset (void) +{ + grub_memset (&setkey_keymap, 0, sizeof (struct keymap)); +} + +static grub_err_t +grub_keymap_add (int in, int out) +{ + if (in == GRUB_TERM_NO_KEY || out == GRUB_TERM_NO_KEY) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid key: %d -> %d", in, out); + if (setkey_keymap.cnt >= MAX_KEYMAP) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + "keymap FULL %d", setkey_keymap.cnt); + setkey_keymap.in[setkey_keymap.cnt] = in; + setkey_keymap.out[setkey_keymap.cnt] = out; + setkey_keymap.cnt++; + return GRUB_ERR_NONE; +} + +static void +grub_keymap_enable (void) +{ + grub_key_remap = grub_keymap_getkey; +} + +static void +grub_keymap_disable (void) +{ + grub_key_remap = NULL; +} + +static void +grub_keymap_status (void) +{ + int i; + if (setkey_keymap.cnt > MAX_KEYMAP) + setkey_keymap.cnt = MAX_KEYMAP; + for (i = 0; i < setkey_keymap.cnt; i++) + { + grub_printf ("0x%x -> 0x%x\n", setkey_keymap.in[i], setkey_keymap.out[i]); + } +} + +static const struct grub_arg_option options[] = +{ + {"reset", 'r', 0, N_("Reset keymap."), 0, 0}, + {"enable", 'e', 0, N_("Enable keymap."), 0, 0}, + {"disable", 'd', 0, N_("Disable keymap."), 0, 0}, + {"status", 's', 0, N_("Display keymap."), 0, 0}, + {0, 0, 0, 0, 0, 0} +}; + +enum options +{ + SETKEY_RESET, + SETKEY_ENABLE, + SETKEY_DISABLE, + SETKEY_STATUS, +}; + +static int +ishex (const char *str) +{ + if (grub_strlen (str) < 3 || str[0] != '0') + return 0; + if (str[1] != 'x' && str[1] != 'X') + return 0; + return 1; +} + +static int +parse_key (const char *str) +{ + int i; + if (ishex (str)) + return grub_strtol (str, NULL, 16); + if (grub_strlen (str) == 1) + return (int) str[0]; + for (i = 0; i < (int) (sizeof (keysym_table) / sizeof (keysym_table[0])); i++) + { + if (grub_strcmp (str, keysym_table[i].name) == 0) + return keysym_table[i].code; + } + grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid key %s", str); + return 0; +} + +static grub_err_t +grub_cmd_setkey (grub_extcmd_context_t ctxt, int argc, char **args) +{ + struct grub_arg_list *state = ctxt->state; + int in, out; + if (state[SETKEY_ENABLE].set) + { + grub_keymap_enable (); + goto out; + } + if (state[SETKEY_DISABLE].set) + { + grub_keymap_disable (); + goto out; + } + if (state[SETKEY_RESET].set) + { + grub_keymap_reset (); + goto out; + } + if (state[SETKEY_STATUS].set) + { + grub_keymap_status (); + goto out; + } + if (argc != 2) + { + grub_printf + ("Key names: 0-9, A-Z, a-z or escape, exclam, at, numbersign, dollar," + "percent, caret, ampersand, asterisk, parenleft, parenright, minus," + "underscore, equal, plus, backspace, tab, bracketleft, braceleft," + "bracketright, braceright, enter, semicolon, colon, quote, doublequote," + "backquote, tilde, backslash, bar, comma, less, period, greater," + "slash, question, alt, space, delete, [ctrl|shift]F1-12." + "For Alt+ prefix with A, e.g. \'setkey at Aequal\'."); + goto out; + } + in = parse_key (args[1]); + out = parse_key (args[0]); + if (!in || !out) + goto out; + grub_keymap_add (in, out); +out: + return grub_errno; +} + +static void grub_keymap_add_by_string(const char *src, const char *dst) +{ + int in = 0; + int out = 0; + + in = parse_key(dst); + out = parse_key(src); + + if (in && out) + { + grub_keymap_add (in, out); + } +} + +#include "keyboard_layout.c" + +static grub_err_t grub_cmd_set_keylayout (grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + ventoy_set_keyboard_layout(args[0]); + return 0; +} + +static grub_extcmd_t cmd, setcmd; + +GRUB_MOD_INIT(setkey) +{ + cmd = grub_register_extcmd ("setkey", grub_cmd_setkey, 0, N_("NEW_KEY USA_KEY"), + N_("Map default USA_KEY to NEW_KEY."), options); + setcmd = grub_register_extcmd ("set_keyboard_layout", grub_cmd_set_keylayout, 0, N_("layout"), + N_("Set keyboard layout."), NULL); +} + +GRUB_MOD_FINI(setkey) +{ + grub_unregister_extcmd (cmd); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/huffman.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/huffman.c new file mode 100644 index 0000000..1680056 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/huffman.c @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2014 Michael Brown . + * + * 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. + */ + +/** + * @file + * + * Huffman alphabets + * + */ + +#include "wimboot.h" +#include "huffman.h" + +/** + * Transcribe binary value (for debugging) + * + * @v value Value + * @v bits Length of value (in bits) + * @ret string Transcribed value + */ +const char * huffman_bin ( unsigned long value, unsigned int bits ) { + static char buf[ ( 8 * sizeof ( value ) ) + 1 /* NUL */ ]; + char *out = buf; + + /* Sanity check */ + assert ( bits < sizeof ( buf ) ); + + /* Transcribe value */ + while ( bits-- ) + *(out++) = ( ( value & ( 1 << bits ) ) ? '1' : '0' ); + *out = '\0'; + + return buf; +} + +/** + * Dump Huffman alphabet (for debugging) + * + * @v alphabet Huffman alphabet + */ +static void __attribute__ (( unused )) +huffman_dump_alphabet ( struct huffman_alphabet *alphabet ) { + struct huffman_symbols *sym; + unsigned int bits; + unsigned int huf; + unsigned int i; + + (void)huf; + + /* Dump symbol table for each utilised length */ + for ( bits = 1 ; bits <= ( sizeof ( alphabet->huf ) / + sizeof ( alphabet->huf[0] ) ) ; bits++ ) { + sym = &alphabet->huf[ bits - 1 ]; + if ( sym->freq == 0 ) + continue; + huf = ( sym->start >> sym->shift ); + DBG ( "Huffman length %d start \"%s\" freq %d:", bits, + huffman_bin ( huf, sym->bits ), sym->freq ); + for ( i = 0 ; i < sym->freq ; i++ ) { + DBG ( " %03x", sym->raw[ huf + i ] ); + } + DBG ( "\n" ); + } + + /* Dump quick lookup table */ + DBG ( "Huffman quick lookup:" ); + for ( i = 0 ; i < ( sizeof ( alphabet->lookup ) / + sizeof ( alphabet->lookup[0] ) ) ; i++ ) { + DBG ( " %d", ( alphabet->lookup[i] + 1 ) ); + } + DBG ( "\n" ); +} + +/** + * Construct Huffman alphabet + * + * @v alphabet Huffman alphabet + * @v lengths Symbol length table + * @v count Number of symbols + * @ret rc Return status code + */ +int huffman_alphabet ( struct huffman_alphabet *alphabet, + uint8_t *lengths, unsigned int count ) { + struct huffman_symbols *sym; + unsigned int huf; + unsigned int cum_freq; + unsigned int bits; + unsigned int raw; + unsigned int adjustment; + unsigned int prefix; + int empty; + int complete; + + /* Clear symbol table */ + memset ( alphabet->huf, 0, sizeof ( alphabet->huf ) ); + + /* Count number of symbols with each Huffman-coded length */ + empty = 1; + for ( raw = 0 ; raw < count ; raw++ ) { + bits = lengths[raw]; + if ( bits ) { + alphabet->huf[ bits - 1 ].freq++; + empty = 0; + } + } + + /* In the degenerate case of having no symbols (i.e. an unused + * alphabet), generate a trivial alphabet with exactly two + * single-bit codes. This allows callers to avoid having to + * check for this special case. + */ + if ( empty ) + alphabet->huf[0].freq = 2; + + /* Populate Huffman-coded symbol table */ + huf = 0; + cum_freq = 0; + for ( bits = 1 ; bits <= ( sizeof ( alphabet->huf ) / + sizeof ( alphabet->huf[0] ) ) ; bits++ ) { + sym = &alphabet->huf[ bits - 1 ]; + sym->bits = bits; + sym->shift = ( HUFFMAN_BITS - bits ); + sym->start = ( huf << sym->shift ); + sym->raw = &alphabet->raw[cum_freq]; + huf += sym->freq; + if ( huf > ( 1U << bits ) ) { + DBG ( "Huffman alphabet has too many symbols with " + "lengths <=%d\n", bits ); + return -1; + } + huf <<= 1; + cum_freq += sym->freq; + } + complete = ( huf == ( 1U << bits ) ); + + /* Populate raw symbol table */ + for ( raw = 0 ; raw < count ; raw++ ) { + bits = lengths[raw]; + if ( bits ) { + sym = &alphabet->huf[ bits - 1 ]; + *(sym->raw++) = raw; + } + } + + /* Adjust Huffman-coded symbol table raw pointers and populate + * quick lookup table. + */ + for ( bits = 1 ; bits <= ( sizeof ( alphabet->huf ) / + sizeof ( alphabet->huf[0] ) ) ; bits++ ) { + sym = &alphabet->huf[ bits - 1 ]; + + /* Adjust raw pointer */ + sym->raw -= sym->freq; /* Reset to first symbol */ + adjustment = ( sym->start >> sym->shift ); + sym->raw -= adjustment; /* Adjust for quick indexing */ + + /* Populate quick lookup table */ + for ( prefix = ( sym->start >> HUFFMAN_QL_SHIFT ) ; + prefix < ( 1 << HUFFMAN_QL_BITS ) ; prefix++ ) { + alphabet->lookup[prefix] = ( bits - 1 ); + } + } + + /* Check that there are no invalid codes */ + if ( ! complete ) { + DBG ( "Huffman alphabet is incomplete\n" ); + return -1; + } + + return 0; +} + +/** + * Get Huffman symbol set + * + * @v alphabet Huffman alphabet + * @v huf Raw input value (normalised to HUFFMAN_BITS bits) + * @ret sym Huffman symbol set + */ +struct huffman_symbols * huffman_sym ( struct huffman_alphabet *alphabet, + unsigned int huf ) { + struct huffman_symbols *sym; + unsigned int lookup_index; + + /* Find symbol set for this length */ + lookup_index = ( huf >> HUFFMAN_QL_SHIFT ); + sym = &alphabet->huf[ alphabet->lookup[ lookup_index ] ]; + while ( huf < sym->start ) + sym--; + return sym; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/huffman.h b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/huffman.h new file mode 100644 index 0000000..95bbae8 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/huffman.h @@ -0,0 +1,108 @@ +#ifndef _HUFFMAN_H +#define _HUFFMAN_H + +/* + * Copyright (C) 2014 Michael Brown . + * + * 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. + */ + +/** + * @file + * + * Huffman alphabets + * + */ + +/** Maximum length of a Huffman symbol (in bits) */ +#define HUFFMAN_BITS 16 + +/** Raw huffman symbol */ +typedef uint16_t huffman_raw_symbol_t; + +/** Quick lookup length for a Huffman symbol (in bits) + * + * This is a policy decision. + */ +#define HUFFMAN_QL_BITS 7 + +/** Quick lookup shift */ +#define HUFFMAN_QL_SHIFT ( HUFFMAN_BITS - HUFFMAN_QL_BITS ) + +/** A Huffman-coded set of symbols of a given length */ +struct huffman_symbols { + /** Length of Huffman-coded symbols (in bits) */ + uint8_t bits; + /** Shift to normalise symbols of this length to HUFFMAN_BITS bits */ + uint8_t shift; + /** Number of Huffman-coded symbols having this length */ + uint16_t freq; + /** First symbol of this length (normalised to HUFFMAN_BITS bits) + * + * Stored as a 32-bit value to allow the value + * (1<bits; +} + +/** + * Get Huffman symbol value + * + * @v sym Huffman symbol set + * @v huf Raw input value (normalised to HUFFMAN_BITS bits) + * @ret raw Raw symbol value + */ +static inline __attribute__ (( always_inline )) huffman_raw_symbol_t +huffman_raw ( struct huffman_symbols *sym, unsigned int huf ) { + + return sym->raw[ huf >> sym->shift ]; +} + +extern int huffman_alphabet ( struct huffman_alphabet *alphabet, + uint8_t *lengths, unsigned int count ); +extern struct huffman_symbols * +huffman_sym ( struct huffman_alphabet *alphabet, unsigned int huf ); + +#endif /* _HUFFMAN_H */ diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/lzx.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/lzx.c new file mode 100644 index 0000000..732a96f --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/lzx.c @@ -0,0 +1,668 @@ +/* + * Copyright (C) 2014 Michael Brown . + * + * 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. + */ + +/** + * @file + * + * LZX decompression + * + * This algorithm is derived jointly from the document "[MS-PATCH]: + * LZX DELTA Compression and Decompression", available from + * + * http://msdn.microsoft.com/en-us/library/cc483133.aspx + * + * and from the file lzx-decompress.c in the wimlib source code. + * + */ + +#include "wimboot.h" +#include "huffman.h" +#include "lzx.h" + +/** Base positions, indexed by position slot */ +static unsigned int lzx_position_base[LZX_POSITION_SLOTS]; + +/** + * Attempt to accumulate bits from LZX bitstream + * + * @v lzx Decompressor + * @v bits Number of bits to accumulate + * @v norm_value Accumulated value (normalised to 16 bits) + * + * Note that there may not be sufficient accumulated bits in the + * bitstream; callers must check that sufficient bits are available + * before using the value. + */ +static int lzx_accumulate ( struct lzx *lzx, unsigned int bits ) { + const uint16_t *src16; + + /* Accumulate more bits if required */ + if ( ( lzx->bits < bits ) && + ( lzx->input.offset < lzx->input.len ) ) { + src16 = (const uint16_t *)( ( char * ) lzx->input.data + lzx->input.offset ); + lzx->input.offset += sizeof ( *src16 ); + lzx->accumulator |= ( *src16 << ( 16 - lzx->bits ) ); + lzx->bits += 16; + } + + return ( lzx->accumulator >> 16 ); +} + +/** + * Consume accumulated bits from LZX bitstream + * + * @v lzx Decompressor + * @v bits Number of bits to consume + * @ret rc Return status code + */ +static int lzx_consume ( struct lzx *lzx, unsigned int bits ) { + + /* Fail if insufficient bits are available */ + if ( lzx->bits < bits ) { + DBG ( "LZX input overrun in %#zx/%#zx out %#zx)\n", + lzx->input.offset, lzx->input.len, lzx->output.offset ); + return -1; + } + + /* Consume bits */ + lzx->accumulator <<= bits; + lzx->bits -= bits; + + return 0; +} + +/** + * Get bits from LZX bitstream + * + * @v lzx Decompressor + * @v bits Number of bits to fetch + * @ret value Value, or negative error + */ +static int lzx_getbits ( struct lzx *lzx, unsigned int bits ) { + int norm_value; + int rc; + + /* Accumulate more bits if required */ + norm_value = lzx_accumulate ( lzx, bits ); + + /* Consume bits */ + if ( ( rc = lzx_consume ( lzx, bits ) ) != 0 ) + return rc; + + return ( norm_value >> ( 16 - bits ) ); +} + +/** + * Align LZX bitstream for byte access + * + * @v lzx Decompressor + * @v bits Minimum number of padding bits + * @ret rc Return status code + */ +static int lzx_align ( struct lzx *lzx, unsigned int bits ) { + int pad; + + /* Get padding bits */ + pad = lzx_getbits ( lzx, bits ); + if ( pad < 0 ) + return pad; + + /* Consume all accumulated bits */ + lzx_consume ( lzx, lzx->bits ); + + return 0; +} + +/** + * Get bytes from LZX bitstream + * + * @v lzx Decompressor + * @v data Data buffer, or NULL + * @v len Length of data buffer + * @ret rc Return status code + */ +static int lzx_getbytes ( struct lzx *lzx, void *data, size_t len ) { + + /* Sanity check */ + if ( ( lzx->input.offset + len ) > lzx->input.len ) { + DBG ( "LZX input overrun in %#zx/%#zx out %#zx)\n", + lzx->input.offset, lzx->input.len, lzx->output.offset ); + return -1; + } + + /* Copy data */ + if ( data ) + memcpy ( data, ( lzx->input.data + lzx->input.offset ), len ); + lzx->input.offset += len; + + return 0; +} + +/** + * Decode LZX Huffman-coded symbol + * + * @v lzx Decompressor + * @v alphabet Huffman alphabet + * @ret raw Raw symbol, or negative error + */ +static int lzx_decode ( struct lzx *lzx, struct huffman_alphabet *alphabet ) { + struct huffman_symbols *sym; + int huf; + int rc; + + /* Accumulate sufficient bits */ + huf = lzx_accumulate ( lzx, HUFFMAN_BITS ); + if ( huf < 0 ) + return huf; + + /* Decode symbol */ + sym = huffman_sym ( alphabet, huf ); + + /* Consume bits */ + if ( ( rc = lzx_consume ( lzx, huffman_len ( sym ) ) ) != 0 ) + return rc; + + return huffman_raw ( sym, huf ); +} + +/** + * Generate Huffman alphabet from raw length table + * + * @v lzx Decompressor + * @v count Number of symbols + * @v bits Length of each length (in bits) + * @v lengths Lengths table to fill in + * @v alphabet Huffman alphabet to fill in + * @ret rc Return status code + */ +static int lzx_raw_alphabet ( struct lzx *lzx, unsigned int count, + unsigned int bits, uint8_t *lengths, + struct huffman_alphabet *alphabet ) { + unsigned int i; + int len; + int rc; + + /* Read lengths */ + for ( i = 0 ; i < count ; i++ ) { + len = lzx_getbits ( lzx, bits ); + if ( len < 0 ) + return len; + lengths[i] = len; + } + + /* Generate Huffman alphabet */ + if ( ( rc = huffman_alphabet ( alphabet, lengths, count ) ) != 0 ) + return rc; + + return 0; +} + +/** + * Generate pretree + * + * @v lzx Decompressor + * @v count Number of symbols + * @v lengths Lengths table to fill in + * @ret rc Return status code + */ +static int lzx_pretree ( struct lzx *lzx, unsigned int count, + uint8_t *lengths ) { + unsigned int i; + unsigned int length; + int dup = 0; + int code; + int rc; + + /* Generate pretree alphabet */ + if ( ( rc = lzx_raw_alphabet ( lzx, LZX_PRETREE_CODES, + LZX_PRETREE_BITS, lzx->pretree_lengths, + &lzx->pretree ) ) != 0 ) + return rc; + + /* Read lengths */ + for ( i = 0 ; i < count ; i++ ) { + + if ( dup ) { + + /* Duplicate previous length */ + lengths[i] = lengths[ i - 1 ]; + dup--; + + } else { + + /* Get next code */ + code = lzx_decode ( lzx, &lzx->pretree ); + if ( code < 0 ) + return code; + + /* Interpret code */ + if ( code <= 16 ) { + length = ( ( lengths[i] - code + 17 ) % 17 ); + } else if ( code == 17 ) { + length = 0; + dup = lzx_getbits ( lzx, 4 ); + if ( dup < 0 ) + return dup; + dup += 3; + } else if ( code == 18 ) { + length = 0; + dup = lzx_getbits ( lzx, 5 ); + if ( dup < 0 ) + return dup; + dup += 19; + } else if ( code == 19 ) { + length = 0; + dup = lzx_getbits ( lzx, 1 ); + if ( dup < 0 ) + return dup; + dup += 3; + code = lzx_decode ( lzx, &lzx->pretree ); + if ( code < 0 ) + return code; + length = ( ( lengths[i] - code + 17 ) % 17 ); + } else { + DBG ( "Unrecognised pretree code %d\n", code ); + return -1; + } + lengths[i] = length; + } + } + + /* Sanity check */ + if ( dup ) { + DBG ( "Pretree duplicate overrun\n" ); + return -1; + } + + return 0; +} + +/** + * Generate aligned offset Huffman alphabet + * + * @v lzx Decompressor + * @ret rc Return status code + */ +static int lzx_alignoffset_alphabet ( struct lzx *lzx ) { + int rc; + + /* Generate aligned offset alphabet */ + if ( ( rc = lzx_raw_alphabet ( lzx, LZX_ALIGNOFFSET_CODES, + LZX_ALIGNOFFSET_BITS, + lzx->alignoffset_lengths, + &lzx->alignoffset ) ) != 0 ) + return rc; + + return 0; +} + +/** + * Generate main Huffman alphabet + * + * @v lzx Decompressor + * @ret rc Return status code + */ +static int lzx_main_alphabet ( struct lzx *lzx ) { + int rc; + + /* Generate literal symbols pretree */ + if ( ( rc = lzx_pretree ( lzx, LZX_MAIN_LIT_CODES, + lzx->main_lengths.literals ) ) != 0 ) { + DBG ( "Could not construct main literal pretree\n" ); + return rc; + } + + /* Generate remaining symbols pretree */ + if ( ( rc = lzx_pretree ( lzx, ( LZX_MAIN_CODES - LZX_MAIN_LIT_CODES ), + lzx->main_lengths.remainder ) ) != 0 ) { + DBG ( "Could not construct main remainder pretree\n" ); + return rc; + } + + /* Generate Huffman alphabet */ + if ( ( rc = huffman_alphabet ( &lzx->main, lzx->main_lengths.literals, + LZX_MAIN_CODES ) ) != 0 ) { + DBG ( "Could not generate main alphabet\n" ); + return rc; + } + + return 0; +} + +/** + * Generate length Huffman alphabet + * + * @v lzx Decompressor + * @ret rc Return status code + */ +static int lzx_length_alphabet ( struct lzx *lzx ) { + int rc; + + /* Generate pretree */ + if ( ( rc = lzx_pretree ( lzx, LZX_LENGTH_CODES, + lzx->length_lengths ) ) != 0 ) { + DBG ( "Could not generate length pretree\n" ); + return rc; + } + + /* Generate Huffman alphabet */ + if ( ( rc = huffman_alphabet ( &lzx->length, lzx->length_lengths, + LZX_LENGTH_CODES ) ) != 0 ) { + DBG ( "Could not generate length alphabet\n" ); + return rc; + } + + return 0; +} + +/** + * Process LZX block header + * + * @v lzx Decompressor + * @ret rc Return status code + */ +static int lzx_block_header ( struct lzx *lzx ) { + size_t block_len; + int block_type; + int default_len; + int len_high; + int len_low; + int rc; + + /* Get block type */ + block_type = lzx_getbits ( lzx, LZX_BLOCK_TYPE_BITS ); + if ( block_type < 0 ) + return block_type; + lzx->block_type = block_type; + + /* Check block length */ + default_len = lzx_getbits ( lzx, 1 ); + if ( default_len < 0 ) + return default_len; + if ( default_len ) { + block_len = LZX_DEFAULT_BLOCK_LEN; + } else { + len_high = lzx_getbits ( lzx, 8 ); + if ( len_high < 0 ) + return len_high; + len_low = lzx_getbits ( lzx, 8 ); + if ( len_low < 0 ) + return len_low; + block_len = ( ( len_high << 8 ) | len_low ); + } + lzx->output.threshold = ( lzx->output.offset + block_len ); + + /* Handle block type */ + switch ( block_type ) { + case LZX_BLOCK_ALIGNOFFSET : + /* Generated aligned offset alphabet */ + if ( ( rc = lzx_alignoffset_alphabet ( lzx ) ) != 0 ) + return rc; + /* Fall through */ + case LZX_BLOCK_VERBATIM : + /* Generate main alphabet */ + if ( ( rc = lzx_main_alphabet ( lzx ) ) != 0 ) + return rc; + /* Generate lengths alphabet */ + if ( ( rc = lzx_length_alphabet ( lzx ) ) != 0 ) + return rc; + break; + case LZX_BLOCK_UNCOMPRESSED : + /* Align input stream */ + if ( ( rc = lzx_align ( lzx, 1 ) ) != 0 ) + return rc; + /* Read new repeated offsets */ + if ( ( rc = lzx_getbytes ( lzx, &lzx->repeated_offset, + sizeof ( lzx->repeated_offset )))!=0) + return rc; + break; + default: + DBG ( "Unrecognised block type %d\n", block_type ); + return -1; + } + + return 0; +} + +/** + * Process uncompressed data + * + * @v lzx Decompressor + * @ret rc Return status code + */ +static int lzx_uncompressed ( struct lzx *lzx ) { + void *data; + size_t len; + int rc; + + /* Copy bytes */ + data = ( lzx->output.data ? + ( lzx->output.data + lzx->output.offset ) : NULL ); + len = ( lzx->output.threshold - lzx->output.offset ); + if ( ( rc = lzx_getbytes ( lzx, data, len ) ) != 0 ) + return rc; + + /* Align input stream */ + if ( len % 2 ) + lzx->input.offset++; + + lzx->output.offset += len; + + return 0; +} + +/** + * Process an LZX token + * + * @v lzx Decompressor + * @ret rc Return status code + * + * Variable names are chosen to match the LZX specification + * pseudo-code. + */ +static int lzx_token ( struct lzx *lzx ) { + unsigned int length_header; + unsigned int position_slot; + unsigned int offset_bits; + unsigned int i; + size_t match_offset; + size_t match_length; + int verbatim_bits; + int aligned_bits; + int maindata; + int length; + uint8_t *copy; + + /* Get maindata symelse*/ + maindata = lzx_decode ( lzx, &lzx->main ); + if ( maindata < 0 ) + return maindata; + + /* Check for literals */ + if ( maindata < LZX_MAIN_LIT_CODES ) { + if ( lzx->output.data ) + lzx->output.data[lzx->output.offset] = maindata; + lzx->output.offset++; + return 0; + } + maindata -= LZX_MAIN_LIT_CODES; + + /* Calculate the match length */ + length_header = ( maindata & 7 ); + if ( length_header == 7 ) { + length = lzx_decode ( lzx, &lzx->length ); + if ( length < 0 ) + return length; + } else { + length = 0; + } + match_length = ( length_header + 2 + length ); + + /* Calculate the position slot */ + position_slot = ( maindata >> 3 ); + if ( position_slot < LZX_REPEATED_OFFSETS ) { + + /* Repeated offset */ + match_offset = lzx->repeated_offset[position_slot]; + lzx->repeated_offset[position_slot] = lzx->repeated_offset[0]; + lzx->repeated_offset[0] = match_offset; + + } else { + + /* Non-repeated offset */ + offset_bits = lzx_footer_bits ( position_slot ); + if ( ( lzx->block_type == LZX_BLOCK_ALIGNOFFSET ) && + ( offset_bits >= 3 ) ) { + verbatim_bits = lzx_getbits ( lzx, ( offset_bits - 3 )); + if ( verbatim_bits < 0 ) + return verbatim_bits; + verbatim_bits <<= 3; + aligned_bits = lzx_decode ( lzx, &lzx->alignoffset ); + if ( aligned_bits < 0 ) + return aligned_bits; + } else { + verbatim_bits = lzx_getbits ( lzx, offset_bits ); + if ( verbatim_bits < 0 ) + return verbatim_bits; + aligned_bits = 0; + } + match_offset = ( lzx_position_base[position_slot] + + verbatim_bits + aligned_bits - 2 ); + + /* Update repeated offset list */ + for ( i = ( LZX_REPEATED_OFFSETS - 1 ) ; i > 0 ; i-- ) + lzx->repeated_offset[i] = lzx->repeated_offset[ i - 1 ]; + lzx->repeated_offset[0] = match_offset; + } + + /* Copy data */ + if ( match_offset > lzx->output.offset ) { + DBG ( "LZX match underrun out 0x%x offset 0x%x len 0x%x\n", + lzx->output.offset, match_offset, match_length ); + return -1; + } + if ( lzx->output.data ) { + copy = &lzx->output.data[lzx->output.offset]; + for ( i = 0 ; i < match_length ; i++ ) + copy[i] = copy[ i - match_offset ]; + } + lzx->output.offset += match_length; + + return 0; +} + +/** + * Translate E8 jump addresses + * + * @v lzx Decompressor + */ +static void lzx_translate_jumps ( struct lzx *lzx ) { + size_t offset; + int32_t *target; + + /* Sanity check */ + if ( lzx->output.offset < 10 ) + return; + + /* Scan for jump instructions */ + for ( offset = 0 ; offset < ( lzx->output.offset - 10 ) ; offset++ ) { + + /* Check for jump instruction */ + if ( lzx->output.data[offset] != 0xe8 ) + continue; + + /* Translate jump target */ + target = ( ( int32_t * ) &lzx->output.data[ offset + 1 ] ); + if ( *target >= 0 ) { + if ( *target < LZX_WIM_MAGIC_FILESIZE ) + *target -= offset; + } else { + if ( *target >= -( ( int32_t ) offset ) ) + *target += LZX_WIM_MAGIC_FILESIZE; + } + offset += sizeof ( *target ); + } +} + +/** + * Decompress LZX-compressed data + * + * @v data Compressed data + * @v len Length of compressed data + * @v buf Decompression buffer, or NULL + * @ret out_len Length of decompressed data, or negative error + */ +ssize_t lzx_decompress ( const void *data, size_t len, void *buf ) { + struct lzx lzx; + unsigned int i; + int rc; + + /* Sanity check */ + if ( len % 2 ) { + DBG ( "LZX cannot handle odd-length input data\n" ); + //return -1; + } + + /* Initialise global state, if required */ + if ( ! lzx_position_base[ LZX_POSITION_SLOTS - 1 ] ) { + for ( i = 1 ; i < LZX_POSITION_SLOTS ; i++ ) { + lzx_position_base[i] = + ( lzx_position_base[i-1] + + ( 1 << lzx_footer_bits ( i - 1 ) ) ); + } + } + + /* Initialise decompressor */ + memset ( &lzx, 0, sizeof ( lzx ) ); + lzx.input.data = data; + lzx.input.len = len; + lzx.output.data = buf; + for ( i = 0 ; i < LZX_REPEATED_OFFSETS ; i++ ) + lzx.repeated_offset[i] = 1; + + /* Process blocks */ + while ( lzx.input.offset < lzx.input.len ) { + + /* Process block header */ + if ( ( rc = lzx_block_header ( &lzx ) ) != 0 ) + return rc; + + /* Process block contents */ + if ( lzx.block_type == LZX_BLOCK_UNCOMPRESSED ) { + + /* Copy uncompressed data */ + if ( ( rc = lzx_uncompressed ( &lzx ) ) != 0 ) + return rc; + + } else { + + /* Process token stream */ + while ( lzx.output.offset < lzx.output.threshold ) { + if ( ( rc = lzx_token ( &lzx ) ) != 0 ) + return rc; + } + } + } + + /* Postprocess to undo E8 jump compression */ + if ( lzx.output.data ) + lzx_translate_jumps ( &lzx ); + + return lzx.output.offset; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/lzx.h b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/lzx.h new file mode 100644 index 0000000..6a4ed8f --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/lzx.h @@ -0,0 +1,179 @@ +#ifndef _LZX_H +#define _LZX_H + +/* + * Copyright (C) 2014 Michael Brown . + * + * 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. + */ + +/** + * @file + * + * LZX decompression + * + */ + +#include "huffman.h" + +/** Number of aligned offset codes */ +#define LZX_ALIGNOFFSET_CODES 8 + +/** Aligned offset code length (in bits) */ +#define LZX_ALIGNOFFSET_BITS 3 + +/** Number of pretree codes */ +#define LZX_PRETREE_CODES 20 + +/** Pretree code length (in bits) */ +#define LZX_PRETREE_BITS 4 + +/** Number of literal main codes */ +#define LZX_MAIN_LIT_CODES 256 + +/** Number of position slots */ +#define LZX_POSITION_SLOTS 30 + +/** Number of main codes */ +#define LZX_MAIN_CODES ( LZX_MAIN_LIT_CODES + ( 8 * LZX_POSITION_SLOTS ) ) + +/** Number of length codes */ +#define LZX_LENGTH_CODES 249 + +/** Block type length (in bits) */ +#define LZX_BLOCK_TYPE_BITS 3 + +/** Default block length */ +#define LZX_DEFAULT_BLOCK_LEN 32768 + +/** Number of repeated offsets */ +#define LZX_REPEATED_OFFSETS 3 + +/** Don't ask */ +#define LZX_WIM_MAGIC_FILESIZE 12000000 + +/** Block types */ +enum lzx_block_type { + /** Verbatim block */ + LZX_BLOCK_VERBATIM = 1, + /** Aligned offset block */ + LZX_BLOCK_ALIGNOFFSET = 2, + /** Uncompressed block */ + LZX_BLOCK_UNCOMPRESSED = 3, +}; + +/** An LZX input stream */ +struct lzx_input_stream { + /** Data */ + const uint8_t *data; + /** Length */ + size_t len; + /** Offset within stream */ + size_t offset; +}; + +/** An LZX output stream */ +struct lzx_output_stream { + /** Data, or NULL */ + uint8_t *data; + /** Offset within stream */ + size_t offset; + /** End of current block within stream */ + size_t threshold; +}; + +/** LZX decompressor */ +struct lzx { + /** Input stream */ + struct lzx_input_stream input; + /** Output stream */ + struct lzx_output_stream output; + /** Accumulator */ + uint32_t accumulator; + /** Number of bits in accumulator */ + unsigned int bits; + /** Block type */ + enum lzx_block_type block_type; + /** Repeated offsets */ + unsigned int repeated_offset[LZX_REPEATED_OFFSETS]; + + /** Aligned offset Huffman alphabet */ + struct huffman_alphabet alignoffset; + /** Aligned offset raw symbols + * + * Must immediately follow the aligned offset Huffman + * alphabet. + */ + huffman_raw_symbol_t alignoffset_raw[LZX_ALIGNOFFSET_CODES]; + /** Aligned offset code lengths */ + uint8_t alignoffset_lengths[LZX_ALIGNOFFSET_CODES]; + + /** Pretree Huffman alphabet */ + struct huffman_alphabet pretree; + /** Pretree raw symbols + * + * Must immediately follow the pretree Huffman alphabet. + */ + huffman_raw_symbol_t pretree_raw[LZX_PRETREE_CODES]; + /** Preetree code lengths */ + uint8_t pretree_lengths[LZX_PRETREE_CODES]; + + /** Main Huffman alphabet */ + struct huffman_alphabet main; + /** Main raw symbols + * + * Must immediately follow the main Huffman alphabet. + */ + huffman_raw_symbol_t main_raw[LZX_MAIN_CODES]; + /** Main code lengths */ + struct { + /** Literals */ + uint8_t literals[LZX_MAIN_LIT_CODES]; + /** Remaining symbols */ + uint8_t remainder[ LZX_MAIN_CODES - LZX_MAIN_LIT_CODES ]; + } __attribute__ (( packed )) main_lengths; + + /** Length Huffman alphabet */ + struct huffman_alphabet length; + /** Length raw symbols + * + * Must immediately follow the length Huffman alphabet. + */ + huffman_raw_symbol_t length_raw[LZX_LENGTH_CODES]; + /** Length code lengths */ + uint8_t length_lengths[LZX_LENGTH_CODES]; +}; + +/** + * Calculate number of footer bits for a given position slot + * + * @v position_slot Position slot + * @ret footer_bits Number of footer bits + */ +static inline unsigned int lzx_footer_bits ( unsigned int position_slot ) { + + if ( position_slot < 2 ) { + return 0; + } else if ( position_slot < 38 ) { + return ( ( position_slot / 2 ) - 1 ); + } else { + return 17; + } +} + +extern ssize_t lzx_decompress ( const void *data, size_t len, void *buf ); + +#endif /* _LZX_H */ diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/miniz.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/miniz.c new file mode 100644 index 0000000..60312a9 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/miniz.c @@ -0,0 +1,2587 @@ +/* miniz.c v1.12 - public domain deflate/inflate + See "unlicense" statement at the end of this file. + Rich Geldreich , last updated April 12, 2012 + Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt + + * Change History + 4/12/12 v1.12 - More comments, added low-level example5.c, fixed a couple minor level_and_flags issues in the archive API's. + level_and_flags can now be set to MZ_DEFAULT_COMPRESSION. Thanks to Bruce Dawson for the feedback/bug report. + 5/28/11 v1.11 - Added statement from unlicense.org + 5/27/11 v1.10 - Substantial compressor optimizations: + Level 1 is now ~4x faster than before. The L1 compressor's throughput now varies between 70-110MB/sec. on a + Core i7 (actual throughput varies depending on the type of data, and x64 vs. x86). + Improved baseline L2-L9 compression perf. Also, greatly improved compression perf. issues on some file types. + Refactored the compression code for better readability and maintainability. + Added level 10 compression level (L10 has slightly better ratio than level 9, but could have a potentially large + drop in throughput on some files). + 5/15/11 v1.09 - Initial stable release. + + * Low-level Deflate/Inflate implementation notes: + + Compression: Use the "tdefl" API's. The compressor supports raw, static, and dynamic blocks, lazy or + greedy parsing, match length filtering, RLE-only, and Huffman-only streams. It performs and compresses + approximately as well as zlib. + + Decompression: Use the "tinfl" API's. The entire decompressor is implemented as a single function + coroutine: see tinfl_decompress(). It supports decompression into a 32KB (or larger power of 2) wrapping buffer, or into a memory + block large enough to hold the entire file. + + The low-level tdefl/tinfl API's do not make any use of dynamic memory allocation. + + * zlib-style API notes: + + miniz.c implements a fairly large subset of zlib. There's enough functionality present for it to be a drop-in + zlib replacement in many apps: + The z_stream struct, optional memory allocation callbacks + deflateInit/deflateInit2/deflate/deflateReset/deflateEnd/deflateBound + inflateInit/inflateInit2/inflate/inflateEnd + compress, compress2, compressBound, uncompress + CRC-32, Adler-32 - Using modern, minimal code size, CPU cache friendly routines. + Supports raw deflate streams or standard zlib streams with adler-32 checking. + + Limitations: + The callback API's are not implemented yet. No support for gzip headers or zlib static dictionaries. + I've tried to closely emulate zlib's various flavors of stream flushing and return status codes, but + there are no guarantees that miniz.c pulls this off perfectly. + + * PNG writing: See the tdefl_write_image_to_png_file_in_memory() function, originally written by + Alex Evans. Supports 1-4 bytes/pixel images. + + * This is a header file library, like stb_image.c. To get only a header file, either cut and paste the + below header, or create miniz.h, #define MINIZ_HEADER_FILE_ONLY, and then include miniz.c from it. + + * Important: For best perf. be sure to customize the below macros for your target platform: + #define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 0 + #define MINIZ_LITTLE_ENDIAN 1 + #define MINIZ_HAS_64BIT_REGISTERS 1 +*/ + +#ifndef MINIZ_HEADER_INCLUDED +#define MINIZ_HEADER_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wundef" + +#define size_t grub_size_t +#define uint8_t grub_uint8_t +#define uint16_t grub_uint16_t +#define uint32_t grub_uint32_t +#define uint64_t grub_uint64_t + +#define assert(a) + +#define memset grub_memset +#define memcpy grub_memcpy +#define memcmp grub_memcmp + +// Defines to completely disable specific portions of miniz.c: +// If all macros here are defined the only functionality remaining will be CRC-32, adler-32, tinfl, and tdefl. + +// Define MINIZ_NO_ZLIB_APIS to remove all ZLIB-style compression/decompression API's. +//#define MINIZ_NO_ZLIB_APIS + +// Define MINIZ_NO_ZLIB_COMPATIBLE_NAME to disable zlib names, to prevent conflicts against stock zlib. +//#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES + +// Define MINIZ_NO_MALLOC to disable all calls to malloc, free, and realloc. +// Note if MINIZ_NO_MALLOC is defined then the user must always provide custom user alloc/free/realloc +// callbacks to the zlib and archive API's, and a few stand-alone helper API's which don't provide custom user +// functions (such as tdefl_compress_mem_to_heap() and tinfl_decompress_mem_to_heap()) won't work. +//#define MINIZ_NO_MALLOC + +#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i486) || defined(i386) || defined(__ia64__) || defined(__x86_64__) +// MINIZ_X86_OR_X64_CPU is only used to help set the below macros. +#define MINIZ_X86_OR_X64_CPU 1 +#endif + +#if (__BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__) || MINIZ_X86_OR_X64_CPU +// Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian. +#define MINIZ_LITTLE_ENDIAN 1 +#else +#error ("Not little endian") +#endif + +#if MINIZ_X86_OR_X64_CPU +// Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 on CPU's that permit efficient integer loads and stores from unaligned addresses. +#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1 +#endif + +#define MINIZ_HAS_64BIT_REGISTERS 1 + +// ------------------- zlib-style API Definitions. + +// For more compatibility with zlib, miniz.c uses unsigned long for some parameters/struct members. +typedef unsigned long mz_ulong; + +// Heap allocation callbacks. +// Note that mz_alloc_func parameter types purpsosely differ from zlib's: items/size is size_t, not unsigned long. +typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size); +typedef void (*mz_free_func)(void *opaque, void *address); +typedef void *(*mz_realloc_func)(void *opaque, void *address, size_t items, size_t size); + +#define MZ_ADLER32_INIT (1) +// mz_adler32() returns the initial adler-32 value to use when called with ptr==NULL. +mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len); + +#define MZ_CRC32_INIT (0) +// mz_crc32() returns the initial CRC-32 value to use when called with ptr==NULL. +mz_ulong mz_crc32(mz_ulong crc, const unsigned char *ptr, size_t buf_len); + +// Compression strategies. +enum { MZ_DEFAULT_STRATEGY = 0, MZ_FILTERED = 1, MZ_HUFFMAN_ONLY = 2, MZ_RLE = 3, MZ_FIXED = 4 }; + +// Method +#define MZ_DEFLATED 8 + +#ifndef MINIZ_NO_ZLIB_APIS + +#define MZ_VERSION "9.1.12" +#define MZ_VERNUM 0x91C0 +#define MZ_VER_MAJOR 9 +#define MZ_VER_MINOR 1 +#define MZ_VER_REVISION 12 +#define MZ_VER_SUBREVISION 0 + +// Flush values. For typical usage you only need MZ_NO_FLUSH and MZ_FINISH. The other values are for advanced use (refer to the zlib docs). +enum { MZ_NO_FLUSH = 0, MZ_PARTIAL_FLUSH = 1, MZ_SYNC_FLUSH = 2, MZ_FULL_FLUSH = 3, MZ_FINISH = 4, MZ_BLOCK = 5 }; + +// Return status codes. MZ_PARAM_ERROR is non-standard. +enum { MZ_OK = 0, MZ_STREAM_END = 1, MZ_NEED_DICT = 2, MZ_ERRNO = -1, MZ_STREAM_ERROR = -2, MZ_DATA_ERROR = -3, MZ_MEM_ERROR = -4, MZ_BUF_ERROR = -5, MZ_VERSION_ERROR = -6, MZ_PARAM_ERROR = -10000 }; + +// Compression levels: 0-9 are the standard zlib-style levels, 10 is best possible compression (not zlib compatible, and may be very slow), MZ_DEFAULT_COMPRESSION=MZ_DEFAULT_LEVEL. +enum { MZ_NO_COMPRESSION = 0, MZ_BEST_SPEED = 1, MZ_BEST_COMPRESSION = 9, MZ_UBER_COMPRESSION = 10, MZ_DEFAULT_LEVEL = 6, MZ_DEFAULT_COMPRESSION = -1 }; + +// Window bits +#define MZ_DEFAULT_WINDOW_BITS 15 + +struct mz_internal_state; + +// Compression/decompression stream struct. +typedef struct mz_stream_s +{ + const unsigned char *next_in; // pointer to next byte to read + unsigned int avail_in; // number of bytes available at next_in + mz_ulong total_in; // total number of bytes consumed so far + + unsigned char *next_out; // pointer to next byte to write + unsigned int avail_out; // number of bytes that can be written to next_out + mz_ulong total_out; // total number of bytes produced so far + + char *msg; // error msg (unused) + struct mz_internal_state *state; // internal state, allocated by zalloc/zfree + + mz_alloc_func zalloc; // optional heap allocation function (defaults to malloc) + mz_free_func zfree; // optional heap free function (defaults to free) + void *opaque; // heap alloc function user pointer + + int data_type; // data_type (unused) + mz_ulong adler; // adler32 of the source or uncompressed data + mz_ulong crc32; // crc32 of the source or uncompressed data + mz_ulong reserved; +} mz_stream; + +typedef mz_stream *mz_streamp; + +// Returns the version string of miniz.c. +const char *mz_version(void); + +// mz_deflateInit() initializes a compressor with default options: +// Parameters: +// pStream must point to an initialized mz_stream struct. +// level must be between [MZ_NO_COMPRESSION, MZ_BEST_COMPRESSION]. +// level 1 enables a specially optimized compression function that's been optimized purely for performance, not ratio. +// (This special func. is currently only enabled when MINIZ_USE_UNALIGNED_LOADS_AND_STORES and MINIZ_LITTLE_ENDIAN are defined.) +// Return values: +// MZ_OK on success. +// MZ_STREAM_ERROR if the stream is bogus. +// MZ_PARAM_ERROR if the input parameters are bogus. +// MZ_MEM_ERROR on out of memory. +int mz_deflateInit(mz_streamp pStream, int level); + +// mz_deflateInit2() is like mz_deflate(), except with more control: +// Additional parameters: +// method must be MZ_DEFLATED +// window_bits must be MZ_DEFAULT_WINDOW_BITS (to wrap the deflate stream with zlib header/adler-32 footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate/no header or footer) +// mem_level must be between [1, 9] (it's checked but ignored by miniz.c) +int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy); + +// Quickly resets a compressor without having to reallocate anything. Same as calling mz_deflateEnd() followed by mz_deflateInit()/mz_deflateInit2(). +int mz_deflateReset(mz_streamp pStream); + +// mz_deflate() compresses the input to output, consuming as much of the input and producing as much output as possible. +// Parameters: +// pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members. +// flush may be MZ_NO_FLUSH, MZ_PARTIAL_FLUSH/MZ_SYNC_FLUSH, MZ_FULL_FLUSH, or MZ_FINISH. +// Return values: +// MZ_OK on success (when flushing, or if more input is needed but not available, and/or there's more output to be written but the output buffer is full). +// MZ_STREAM_END if all input has been consumed and all output bytes have been written. Don't call mz_deflate() on the stream anymore. +// MZ_STREAM_ERROR if the stream is bogus. +// MZ_PARAM_ERROR if one of the parameters is invalid. +// MZ_BUF_ERROR if no forward progress is possible because the input and/or output buffers are empty. (Fill up the input buffer or free up some output space and try again.) +int mz_deflate(mz_streamp pStream, int flush); + +// mz_deflateEnd() deinitializes a compressor: +// Return values: +// MZ_OK on success. +// MZ_STREAM_ERROR if the stream is bogus. +int mz_deflateEnd(mz_streamp pStream); + +// mz_deflateBound() returns a (very) conservative upper bound on the amount of data that could be generated by deflate(), assuming flush is set to only MZ_NO_FLUSH or MZ_FINISH. +mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len); + +// Single-call compression functions mz_compress() and mz_compress2(): +// Returns MZ_OK on success, or one of the error codes from mz_deflate() on failure. +int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len); +int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level); + +// mz_compressBound() returns a (very) conservative upper bound on the amount of data that could be generated by calling mz_compress(). +mz_ulong mz_compressBound(mz_ulong source_len); + +// Initializes a decompressor. +int mz_inflateInit(mz_streamp pStream); + +// mz_inflateInit2() is like mz_inflateInit() with an additional option that controls the window size and whether or not the stream has been wrapped with a zlib header/footer: +// window_bits must be MZ_DEFAULT_WINDOW_BITS (to parse zlib header/footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate). +int mz_inflateInit2(mz_streamp pStream, int window_bits); + +// Decompresses the input stream to the output, consuming only as much of the input as needed, and writing as much to the output as possible. +// Parameters: +// pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members. +// flush may be MZ_NO_FLUSH, MZ_SYNC_FLUSH, or MZ_FINISH. +// On the first call, if flush is MZ_FINISH it's assumed the input and output buffers are both sized large enough to decompress the entire stream in a single call (this is slightly faster). +// MZ_FINISH implies that there are no more source bytes available beside what's already in the input buffer, and that the output buffer is large enough to hold the rest of the decompressed data. +// Return values: +// MZ_OK on success. Either more input is needed but not available, and/or there's more output to be written but the output buffer is full. +// MZ_STREAM_END if all needed input has been consumed and all output bytes have been written. For zlib streams, the adler-32 of the decompressed data has also been verified. +// MZ_STREAM_ERROR if the stream is bogus. +// MZ_DATA_ERROR if the deflate stream is invalid. +// MZ_PARAM_ERROR if one of the parameters is invalid. +// MZ_BUF_ERROR if no forward progress is possible because the input buffer is empty but the inflater needs more input to continue, or if the output buffer is not large enough. Call mz_inflate() again +// with more input data, or with more room in the output buffer (except when using single call decompression, described above). +int mz_inflate(mz_streamp pStream, int flush); + +// Deinitializes a decompressor. +int mz_inflateEnd(mz_streamp pStream); + +// Single-call decompression. +// Returns MZ_OK on success, or one of the error codes from mz_inflate() on failure. +int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len); + +// Returns a string description of the specified error code, or NULL if the error code is invalid. +const char *mz_error(int err); + +// Redefine zlib-compatible names to miniz equivalents, so miniz.c can be used as a drop-in replacement for the subset of zlib that miniz.c supports. +// Define MINIZ_NO_ZLIB_COMPATIBLE_NAMES to disable zlib-compatibility if you use zlib in the same project. +#ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES + typedef unsigned char Byte; + typedef unsigned int uInt; + typedef mz_ulong uLong; + typedef Byte Bytef; + typedef uInt uIntf; + typedef char charf; + typedef int intf; + typedef void *voidpf; + typedef uLong uLongf; + typedef void *voidp; + typedef void *const voidpc; + #define Z_NULL 0 + #define Z_NO_FLUSH MZ_NO_FLUSH + #define Z_PARTIAL_FLUSH MZ_PARTIAL_FLUSH + #define Z_SYNC_FLUSH MZ_SYNC_FLUSH + #define Z_FULL_FLUSH MZ_FULL_FLUSH + #define Z_FINISH MZ_FINISH + #define Z_BLOCK MZ_BLOCK + #define Z_OK MZ_OK + #define Z_STREAM_END MZ_STREAM_END + #define Z_NEED_DICT MZ_NEED_DICT + #define Z_ERRNO MZ_ERRNO + #define Z_STREAM_ERROR MZ_STREAM_ERROR + #define Z_DATA_ERROR MZ_DATA_ERROR + #define Z_MEM_ERROR MZ_MEM_ERROR + #define Z_BUF_ERROR MZ_BUF_ERROR + #define Z_VERSION_ERROR MZ_VERSION_ERROR + #define Z_PARAM_ERROR MZ_PARAM_ERROR + #define Z_NO_COMPRESSION MZ_NO_COMPRESSION + #define Z_BEST_SPEED MZ_BEST_SPEED + #define Z_BEST_COMPRESSION MZ_BEST_COMPRESSION + #define Z_DEFAULT_COMPRESSION MZ_DEFAULT_COMPRESSION + #define Z_DEFAULT_STRATEGY MZ_DEFAULT_STRATEGY + #define Z_FILTERED MZ_FILTERED + #define Z_HUFFMAN_ONLY MZ_HUFFMAN_ONLY + #define Z_RLE MZ_RLE + #define Z_FIXED MZ_FIXED + #define Z_DEFLATED MZ_DEFLATED + #define Z_DEFAULT_WINDOW_BITS MZ_DEFAULT_WINDOW_BITS + #define alloc_func mz_alloc_func + #define free_func mz_free_func + #define internal_state mz_internal_state + #define z_stream mz_stream + #define deflateInit mz_deflateInit + #define deflateInit2 mz_deflateInit2 + #define deflateReset mz_deflateReset + #define deflate mz_deflate + #define deflateEnd mz_deflateEnd + #define deflateBound mz_deflateBound + #define compress mz_compress + #define compress2 mz_compress2 + #define compressBound mz_compressBound + #define inflateInit mz_inflateInit + #define inflateInit2 mz_inflateInit2 + #define inflate mz_inflate + #define inflateEnd mz_inflateEnd + #define uncompress mz_uncompress + #define z_crc32 mz_crc32 + #define z_adler32 mz_adler32 + #define MAX_WBITS 15 + #define MAX_MEM_LEVEL 9 + #define zError mz_error + #define ZLIB_VERSION MZ_VERSION + #define ZLIB_VERNUM MZ_VERNUM + #define ZLIB_VER_MAJOR MZ_VER_MAJOR + #define ZLIB_VER_MINOR MZ_VER_MINOR + #define ZLIB_VER_REVISION MZ_VER_REVISION + #define ZLIB_VER_SUBREVISION MZ_VER_SUBREVISION + #define zlibVersion mz_version + #define zlib_version mz_version() +#endif // #ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES + +#endif // MINIZ_NO_ZLIB_APIS + +// ------------------- Types and macros + +typedef unsigned char mz_uint8; +typedef signed short mz_int16; +typedef unsigned short mz_uint16; +typedef unsigned int mz_uint32; +typedef unsigned int mz_uint; +typedef long long mz_int64; +typedef unsigned long long mz_uint64; +typedef int mz_bool; + +#define MZ_FALSE (0) +#define MZ_TRUE (1) + +#ifndef __WIN__ +#define MZ_MACRO_END while (0) +#else +// Works around MSVC's spammy "warning C4127: conditional expression is constant" message. +#define MZ_MACRO_END while (0, 0) +#endif + +// ------------------- Low-level Decompression API Definitions + +// Decompression flags used by tinfl_decompress(). +// TINFL_FLAG_PARSE_ZLIB_HEADER: If set, the input has a valid zlib header and ends with an adler32 checksum (it's a valid zlib stream). Otherwise, the input is a raw deflate stream. +// TINFL_FLAG_HAS_MORE_INPUT: If set, there are more input bytes available beyond the end of the supplied input buffer. If clear, the input buffer contains all remaining input. +// TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF: If set, the output buffer is large enough to hold the entire decompressed stream. If clear, the output buffer is at least the size of the dictionary (typically 32KB). +// TINFL_FLAG_COMPUTE_ADLER32: Force adler-32 checksum computation of the decompressed bytes. +enum +{ + TINFL_FLAG_PARSE_ZLIB_HEADER = 1, + TINFL_FLAG_HAS_MORE_INPUT = 2, + TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF = 4, + TINFL_FLAG_COMPUTE_ADLER32 = 8 +}; + +// High level decompression functions: +// tinfl_decompress_mem_to_heap() decompresses a block in memory to a heap block allocated via malloc(). +// On entry: +// pSrc_buf, src_buf_len: Pointer and size of the Deflate or zlib source data to decompress. +// On return: +// Function returns a pointer to the decompressed data, or NULL on failure. +// *pOut_len will be set to the decompressed data's size, which could be larger than src_buf_len on uncompressible data. +// The caller must free() the returned block when it's no longer needed. +void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags); + +// tinfl_decompress_mem_to_mem() decompresses a block in memory to another block in memory. +// Returns TINFL_DECOMPRESS_MEM_TO_MEM_FAILED on failure, or the number of bytes written on success. +#define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1)) +size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags); + +// tinfl_decompress_mem_to_callback() decompresses a block in memory to an internal 32KB buffer, and a user provided callback function will be called to flush the buffer. +// Returns 1 on success or 0 on failure. +typedef int (*tinfl_put_buf_func_ptr)(const void* pBuf, int len, void *pUser); +int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags); + +struct tinfl_decompressor_tag; typedef struct tinfl_decompressor_tag tinfl_decompressor; + +// Max size of LZ dictionary. +#define TINFL_LZ_DICT_SIZE 32768 + +// Return status. +typedef enum +{ + TINFL_STATUS_BAD_PARAM = -3, + TINFL_STATUS_ADLER32_MISMATCH = -2, + TINFL_STATUS_FAILED = -1, + TINFL_STATUS_DONE = 0, + TINFL_STATUS_NEEDS_MORE_INPUT = 1, + TINFL_STATUS_HAS_MORE_OUTPUT = 2 +} tinfl_status; + +// Initializes the decompressor to its initial state. +#define tinfl_init(r) do { (r)->m_state = 0; } MZ_MACRO_END +#define tinfl_get_adler32(r) (r)->m_check_adler32 +#define tinfl_get_crc32(r) (r)->m_check_crc32 + +// Main low-level decompressor coroutine function. This is the only function actually needed for decompression. All the other functions are just high-level helpers for improved usability. +// This is a universal API, i.e. it can be used as a building block to build any desired higher level decompression API. In the limit case, it can be called once per every byte input or output. +tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags); + +// Internal/private bits follow. +enum +{ + TINFL_MAX_HUFF_TABLES = 3, TINFL_MAX_HUFF_SYMBOLS_0 = 288, TINFL_MAX_HUFF_SYMBOLS_1 = 32, TINFL_MAX_HUFF_SYMBOLS_2 = 19, + TINFL_FAST_LOOKUP_BITS = 10, TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS +}; + +typedef struct +{ + mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0]; + mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE], m_tree[TINFL_MAX_HUFF_SYMBOLS_0 * 2]; +} tinfl_huff_table; + +#if MINIZ_HAS_64BIT_REGISTERS + #define TINFL_USE_64BIT_BITBUF 1 +#endif + +#if TINFL_USE_64BIT_BITBUF + typedef mz_uint64 tinfl_bit_buf_t; + #define TINFL_BITBUF_SIZE (64) +#else + typedef mz_uint32 tinfl_bit_buf_t; + #define TINFL_BITBUF_SIZE (32) +#endif + +struct tinfl_decompressor_tag +{ + mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_z_crc32, m_final, m_type, m_check_adler32, m_check_crc32, m_dist, m_counter, m_num_extra, m_table_sizes[TINFL_MAX_HUFF_TABLES]; + tinfl_bit_buf_t m_bit_buf; + size_t m_dist_from_out_buf_start; + tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES]; + mz_uint8 m_raw_header[4], m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137]; +}; + +// ------------------- Low-level Compression API Definitions + +// Set TDEFL_LESS_MEMORY to 1 to use less memory (compression will be slightly slower, and raw/dynamic blocks will be output more frequently). +#define TDEFL_LESS_MEMORY 0 + +// tdefl_init() compression flags logically OR'd together (low 12 bits contain the max. number of probes per dictionary search): +// TDEFL_DEFAULT_MAX_PROBES: The compressor defaults to 128 dictionary probes per dictionary search. 0=Huffman only, 1=Huffman+LZ (fastest/crap compression), 4095=Huffman+LZ (slowest/best compression). +enum +{ + TDEFL_HUFFMAN_ONLY = 0, TDEFL_DEFAULT_MAX_PROBES = 128, TDEFL_MAX_PROBES_MASK = 0xFFF +}; + +// TDEFL_WRITE_ZLIB_HEADER: If set, the compressor outputs a zlib header before the deflate data, and the Adler-32 of the source data at the end. Otherwise, you'll get raw deflate data. +// TDEFL_COMPUTE_ADLER32: Always compute the adler-32 of the input data (even when not writing zlib headers). +// TDEFL_COMPUTE_CRC32: Always compute the crc-32 of the input data. +// TDEFL_GREEDY_PARSING_FLAG: Set to use faster greedy parsing, instead of more efficient lazy parsing. +// TDEFL_NONDETERMINISTIC_PARSING_FLAG: Enable to decrease the compressor's initialization time to the minimum, but the output may vary from run to run given the same input (depending on the contents of memory). +// TDEFL_RLE_MATCHES: Only look for RLE matches (matches with a distance of 1) +// TDEFL_FILTER_MATCHES: Discards matches <= 5 chars if enabled. +// TDEFL_FORCE_ALL_STATIC_BLOCKS: Disable usage of optimized Huffman tables. +// TDEFL_FORCE_ALL_RAW_BLOCKS: Only use raw (uncompressed) deflate blocks. +enum +{ + TDEFL_WRITE_ZLIB_HEADER = 0x001000, + TDEFL_COMPUTE_ADLER32 = 0x002000, + TDEFL_COMPUTE_CRC32 = 0x004000, + TDEFL_GREEDY_PARSING_FLAG = 0x008000, + TDEFL_NONDETERMINISTIC_PARSING_FLAG = 0x010000, + TDEFL_RLE_MATCHES = 0x020000, + TDEFL_FILTER_MATCHES = 0x040000, + TDEFL_FORCE_ALL_STATIC_BLOCKS = 0x080000, + TDEFL_FORCE_ALL_RAW_BLOCKS = 0x100000, +}; + +// High level compression functions: +// tdefl_compress_mem_to_heap() compresses a block in memory to a heap block allocated via malloc(). +// On entry: +// pSrc_buf, src_buf_len: Pointer and size of source block to compress. +// flags: The max match finder probes (default is 128) logically OR'd against the above flags. Higher probes are slower but improve compression. +// On return: +// Function returns a pointer to the compressed data, or NULL on failure. +// *pOut_len will be set to the compressed data's size, which could be larger than src_buf_len on uncompressible data. +// The caller must free() the returned block when it's no longer needed. +void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags); + +// tdefl_compress_mem_to_mem() compresses a block in memory to another block in memory. +// Returns 0 on failure. +size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags); + +// Compresses an image to a compressed PNG file in memory. +// On entry: +// pImage, w, h, and num_chans describe the image to compress. num_chans may be 1, 2, 3, or 4. +// On return: +// Function returns a pointer to the compressed data, or NULL on failure. +// *pLen_out will be set to the size of the PNG image file. +// The caller must free() the returned heap block (which will typically be larger than *pLen_out) when it's no longer needed. +void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out); + +// Output stream interface. The compressor uses this interface to write compressed data. It'll typically be called TDEFL_OUT_BUF_SIZE at a time. +typedef mz_bool (*tdefl_put_buf_func_ptr)(const void* pBuf, int len, void *pUser); + +// tdefl_compress_mem_to_output() compresses a block to an output stream. The above helpers use this function internally. +mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags); + +enum { TDEFL_MAX_HUFF_TABLES = 3, TDEFL_MAX_HUFF_SYMBOLS_0 = 288, TDEFL_MAX_HUFF_SYMBOLS_1 = 32, TDEFL_MAX_HUFF_SYMBOLS_2 = 19, TDEFL_LZ_DICT_SIZE = 32768, TDEFL_LZ_DICT_SIZE_MASK = TDEFL_LZ_DICT_SIZE - 1, TDEFL_MIN_MATCH_LEN = 3, TDEFL_MAX_MATCH_LEN = 258 }; + +// TDEFL_OUT_BUF_SIZE MUST be large enough to hold a single entire compressed output block (using static/fixed Huffman codes). +#if TDEFL_LESS_MEMORY +enum { TDEFL_LZ_CODE_BUF_SIZE = 24 * 1024, TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13 ) / 10, TDEFL_MAX_HUFF_SYMBOLS = 288, TDEFL_LZ_HASH_BITS = 12, TDEFL_LEVEL1_HASH_SIZE_MASK = 4095, TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3, TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS }; +#else +enum { TDEFL_LZ_CODE_BUF_SIZE = 64 * 1024, TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13 ) / 10, TDEFL_MAX_HUFF_SYMBOLS = 288, TDEFL_LZ_HASH_BITS = 15, TDEFL_LEVEL1_HASH_SIZE_MASK = 4095, TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3, TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS }; +#endif + +// The low-level tdefl functions below may be used directly if the above helper functions aren't flexible enough. The low-level functions don't make any heap allocations, unlike the above helper functions. +typedef enum +{ + TDEFL_STATUS_BAD_PARAM = -2, + TDEFL_STATUS_PUT_BUF_FAILED = -1, + TDEFL_STATUS_OKAY = 0, + TDEFL_STATUS_DONE = 1, +} tdefl_status; + +// Must map to MZ_NO_FLUSH, MZ_SYNC_FLUSH, etc. enums +typedef enum +{ + TDEFL_NO_FLUSH = 0, + TDEFL_SYNC_FLUSH = 2, + TDEFL_FULL_FLUSH = 3, + TDEFL_FINISH = 4 +} tdefl_flush; + +// tdefl's compression state structure. +typedef struct +{ + tdefl_put_buf_func_ptr m_pPut_buf_func; + void *m_pPut_buf_user; + mz_uint m_flags, m_max_probes[2]; + int m_greedy_parsing; + mz_uint m_adler32, m_crc32, m_lookahead_pos, m_lookahead_size, m_dict_size; + mz_uint8 *m_pLZ_code_buf, *m_pLZ_flags, *m_pOutput_buf, *m_pOutput_buf_end; + mz_uint m_num_flags_left, m_total_lz_bytes, m_lz_code_buf_dict_pos, m_bits_in, m_bit_buffer; + mz_uint m_saved_match_dist, m_saved_match_len, m_saved_lit, m_output_flush_ofs, m_output_flush_remaining, m_finished, m_block_index, m_wants_to_finish; + tdefl_status m_prev_return_status; + const void *m_pIn_buf; + void *m_pOut_buf; + size_t *m_pIn_buf_size, *m_pOut_buf_size; + tdefl_flush m_flush; + const mz_uint8 *m_pSrc; + size_t m_src_buf_left, m_out_buf_ofs; + mz_uint8 m_dict[TDEFL_LZ_DICT_SIZE + TDEFL_MAX_MATCH_LEN - 1]; + mz_uint16 m_huff_count[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]; + mz_uint16 m_huff_codes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]; + mz_uint8 m_huff_code_sizes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]; + mz_uint8 m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE]; + mz_uint16 m_next[TDEFL_LZ_DICT_SIZE]; + mz_uint16 m_hash[TDEFL_LZ_HASH_SIZE]; + mz_uint8 m_output_buf[TDEFL_OUT_BUF_SIZE]; +} tdefl_compressor; + +// Initializes the compressor. +// There is no corresponding deinit() function because the tdefl API's do not dynamically allocate memory. +// pBut_buf_func: If NULL, output data will be supplied to the specified callback. In this case, the user should call the tdefl_compress_buffer() API for compression. +// If pBut_buf_func is NULL the user should always call the tdefl_compress() API. +// flags: See the above enums (TDEFL_HUFFMAN_ONLY, TDEFL_WRITE_ZLIB_HEADER, etc.) +tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags); + +// Compresses a block of data, consuming as much of the specified input buffer as possible, and writing as much compressed data to the specified output buffer as possible. +tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush); + +// tdefl_compress_buffer() is only usable when the tdefl_init() is called with a non-NULL tdefl_put_buf_func_ptr. +// tdefl_compress_buffer() always consumes the entire input buffer. +tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush); + +tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d); +mz_uint32 tdefl_get_adler32(tdefl_compressor *d); +mz_uint32 tdefl_get_crc32(tdefl_compressor *d); + +// Create tdefl_compress() flags given zlib-style compression parameters. +// level may range from [0,10] (where 10 is absolute max compression, but may be much slower on some files) +// window_bits may be -15 (raw deflate) or 15 (zlib) +// strategy may be either MZ_DEFAULT_STRATEGY, MZ_FILTERED, MZ_HUFFMAN_ONLY, MZ_RLE, or MZ_FIXED +mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy); + +#endif // MINIZ_HEADER_INCLUDED + +// ------------------- End of Header: Implementation follows. (If you only want the header, define MINIZ_HEADER_FILE_ONLY.) + +#ifndef MINIZ_HEADER_FILE_ONLY + +typedef unsigned char mz_validate_uint16[sizeof(mz_uint16)==2 ? 1 : -1]; +typedef unsigned char mz_validate_uint32[sizeof(mz_uint32)==4 ? 1 : -1]; +typedef unsigned char mz_validate_uint64[sizeof(mz_uint64)==8 ? 1 : -1]; + +#define MZ_ASSERT(x) assert(x) + +#ifdef MINIZ_NO_MALLOC + #define MZ_MALLOC(x) NULL + #define MZ_FREE(x) x, ((void)0) + #define MZ_REALLOC(p, x) NULL +#else + #define MZ_MALLOC(x) grub_malloc(x) + #define MZ_FREE(x) grub_free(x) + #define MZ_REALLOC(p, x) grub_realloc(p, x) +#endif + +#define MZ_MAX(a,b) (((a)>(b))?(a):(b)) +#define MZ_MIN(a,b) (((a)<(b))?(a):(b)) +#define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj)) + +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN + #define MZ_READ_LE16(p) *((const mz_uint16 *)(p)) + #define MZ_READ_LE32(p) *((const mz_uint32 *)(p)) +#else + #define MZ_READ_LE16(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U)) + #define MZ_READ_LE32(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U) | ((mz_uint32)(((const mz_uint8 *)(p))[2]) << 16U) | ((mz_uint32)(((const mz_uint8 *)(p))[3]) << 24U)) +#endif + +#if !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__MINGW64__) && !defined(__forceinline) + #define __forceinline +#endif + +// ------------------- zlib-style API's + +static void *def_alloc_func(void *opaque, size_t items, size_t size) { (void)opaque; return MZ_MALLOC(items * size); } +static void def_free_func(void *opaque, void *address) { (void)opaque, MZ_FREE(address); } + +mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len) +{ + mz_uint32 i, s1 = (mz_uint32)(adler & 0xffff), s2 = (mz_uint32)(adler >> 16); size_t block_len = buf_len % 5552; + if (!ptr) return MZ_ADLER32_INIT; + while (buf_len) { + for (i = 0; i + 7 < block_len; i += 8, ptr += 8) { + s1 += ptr[0], s2 += s1; s1 += ptr[1], s2 += s1; s1 += ptr[2], s2 += s1; s1 += ptr[3], s2 += s1; + s1 += ptr[4], s2 += s1; s1 += ptr[5], s2 += s1; s1 += ptr[6], s2 += s1; s1 += ptr[7], s2 += s1; + } + for ( ; i < block_len; ++i) s1 += *ptr++, s2 += s1; + s1 %= 65521U, s2 %= 65521U; buf_len -= block_len; block_len = 5552; + } + return (s2 << 16) + s1; +} + +// Karl Malbrain's compact CRC-32. See "A compact CCITT crc16 and crc32 C implementation that balances processor cache usage against speed": http://www.geocities.com/malbrain/ +mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len) +{ + static const mz_uint32 s_crc32[16] = { 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, + 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c }; + if (!ptr) return MZ_CRC32_INIT; + crc = ~crc; while (buf_len--) { mz_uint8 b = *ptr++; crc = (crc >> 4) ^ s_crc32[(crc & 0xF) ^ (b & 0xF)]; crc = (crc >> 4) ^ s_crc32[(crc & 0xF) ^ (b >> 4)]; } return ~crc; +} + +#ifndef MINIZ_NO_ZLIB_APIS + +const char *mz_version(void) +{ + return MZ_VERSION; +} + +int mz_deflateInit(mz_streamp pStream, int level) +{ + return mz_deflateInit2(pStream, level, MZ_DEFLATED, MZ_DEFAULT_WINDOW_BITS, 9, MZ_DEFAULT_STRATEGY); +} + +int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy) +{ + tdefl_compressor *pComp; + mz_uint comp_flags = TDEFL_COMPUTE_ADLER32 | TDEFL_COMPUTE_CRC32 | tdefl_create_comp_flags_from_zip_params(level, window_bits, strategy); + + if (!pStream) return MZ_STREAM_ERROR; + if ((method != MZ_DEFLATED) || ((mem_level < 1) || (mem_level > 9)) || ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS))) return MZ_PARAM_ERROR; + + pStream->data_type = 0; + pStream->adler = MZ_ADLER32_INIT; + pStream->crc32 = MZ_CRC32_INIT; + pStream->msg = NULL; + pStream->reserved = 0; + pStream->total_in = 0; + pStream->total_out = 0; + if (!pStream->zalloc) pStream->zalloc = def_alloc_func; + if (!pStream->zfree) pStream->zfree = def_free_func; + + pComp = (tdefl_compressor *)pStream->zalloc(pStream->opaque, 1, sizeof(tdefl_compressor)); + if (!pComp) + return MZ_MEM_ERROR; + + pStream->state = (struct mz_internal_state *)pComp; + + if (tdefl_init(pComp, NULL, NULL, comp_flags) != TDEFL_STATUS_OKAY) + { + mz_deflateEnd(pStream); + return MZ_PARAM_ERROR; + } + + return MZ_OK; +} + +int mz_deflateReset(mz_streamp pStream) +{ + if ((!pStream) || (!pStream->state) || (!pStream->zalloc) || (!pStream->zfree)) return MZ_STREAM_ERROR; + pStream->total_in = pStream->total_out = 0; + tdefl_init((tdefl_compressor*)pStream->state, NULL, NULL, ((tdefl_compressor*)pStream->state)->m_flags); + return MZ_OK; +} + +int mz_deflate(mz_streamp pStream, int flush) +{ + size_t in_bytes, out_bytes; + mz_ulong orig_total_in, orig_total_out; + int mz_status = MZ_OK; + + if ((!pStream) || (!pStream->state) || (flush < 0) || (flush > MZ_FINISH) || (!pStream->next_out)) return MZ_STREAM_ERROR; + if (!pStream->avail_out) return MZ_BUF_ERROR; + + if (flush == MZ_PARTIAL_FLUSH) flush = MZ_SYNC_FLUSH; + + if (((tdefl_compressor*)pStream->state)->m_prev_return_status == TDEFL_STATUS_DONE) + return (flush == MZ_FINISH) ? MZ_STREAM_END : MZ_BUF_ERROR; + + orig_total_in = pStream->total_in; orig_total_out = pStream->total_out; + for ( ; ; ) + { + tdefl_status defl_status; + in_bytes = pStream->avail_in; out_bytes = pStream->avail_out; + + defl_status = tdefl_compress((tdefl_compressor*)pStream->state, pStream->next_in, &in_bytes, pStream->next_out, &out_bytes, (tdefl_flush)flush); + pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes; + pStream->total_in += (mz_uint)in_bytes; pStream->adler = tdefl_get_adler32((tdefl_compressor*)pStream->state); pStream->crc32 = tdefl_get_crc32((tdefl_compressor*)pStream->state); + + pStream->next_out += (mz_uint)out_bytes; pStream->avail_out -= (mz_uint)out_bytes; + pStream->total_out += (mz_uint)out_bytes; + + if (defl_status < 0) + { + mz_status = MZ_STREAM_ERROR; + break; + } + else if (defl_status == TDEFL_STATUS_DONE) + { + mz_status = MZ_STREAM_END; + break; + } + else if (!pStream->avail_out) + break; + else if ((!pStream->avail_in) && (flush != MZ_FINISH)) + { + if ((flush) || (pStream->total_in != orig_total_in) || (pStream->total_out != orig_total_out)) + break; + return MZ_BUF_ERROR; // Can't make forward progress without some input. + } + } + return mz_status; +} + +int mz_deflateEnd(mz_streamp pStream) +{ + if (!pStream) return MZ_STREAM_ERROR; + if (pStream->state) + { + pStream->zfree(pStream->opaque, pStream->state); + pStream->state = NULL; + } + return MZ_OK; +} + +mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len) +{ + (void)pStream; + // This is really over conservative. (And lame, but it's actually pretty tricky to compute a true upper bound given the way tdefl's blocking works.) + return MZ_MAX(128 + (source_len * 110) / 100, 128 + source_len + ((source_len / (31 * 1024)) + 1) * 5); +} + +int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level) +{ + int status; + mz_stream stream; + memset(&stream, 0, sizeof(stream)); + + // In case mz_ulong is 64-bits (argh I hate longs). + if ((source_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR; + + stream.next_in = pSource; + stream.avail_in = (mz_uint32)source_len; + stream.next_out = pDest; + stream.avail_out = (mz_uint32)*pDest_len; + + status = mz_deflateInit(&stream, level); + if (status != MZ_OK) return status; + + status = mz_deflate(&stream, MZ_FINISH); + if (status != MZ_STREAM_END) + { + mz_deflateEnd(&stream); + return (status == MZ_OK) ? MZ_BUF_ERROR : status; + } + + *pDest_len = stream.total_out; + return mz_deflateEnd(&stream); +} + +int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len) +{ + return mz_compress2(pDest, pDest_len, pSource, source_len, MZ_DEFAULT_COMPRESSION); +} + +mz_ulong mz_compressBound(mz_ulong source_len) +{ + return mz_deflateBound(NULL, source_len); +} + +typedef struct +{ + tinfl_decompressor m_decomp; + mz_uint m_dict_ofs, m_dict_avail, m_first_call, m_has_flushed; int m_window_bits; + mz_uint8 m_dict[TINFL_LZ_DICT_SIZE]; + tinfl_status m_last_status; +} inflate_state; + +int mz_inflateInit2(mz_streamp pStream, int window_bits) +{ + inflate_state *pDecomp; + if (!pStream) return MZ_STREAM_ERROR; + if ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS)) return MZ_PARAM_ERROR; + + pStream->data_type = 0; + pStream->adler = 0; + pStream->crc32 = 0; + pStream->msg = NULL; + pStream->total_in = 0; + pStream->total_out = 0; + pStream->reserved = 0; + if (!pStream->zalloc) pStream->zalloc = def_alloc_func; + if (!pStream->zfree) pStream->zfree = def_free_func; + + pDecomp = (inflate_state*)pStream->zalloc(pStream->opaque, 1, sizeof(inflate_state)); + if (!pDecomp) return MZ_MEM_ERROR; + + pStream->state = (struct mz_internal_state *)pDecomp; + + tinfl_init(&pDecomp->m_decomp); + pDecomp->m_dict_ofs = 0; + pDecomp->m_dict_avail = 0; + pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT; + pDecomp->m_first_call = 1; + pDecomp->m_has_flushed = 0; + pDecomp->m_window_bits = window_bits; + + return MZ_OK; +} + +int mz_inflateInit(mz_streamp pStream) +{ + return mz_inflateInit2(pStream, MZ_DEFAULT_WINDOW_BITS); +} + +int mz_inflate(mz_streamp pStream, int flush) +{ + inflate_state* pState; + mz_uint n, first_call, decomp_flags = TINFL_FLAG_COMPUTE_ADLER32; + size_t in_bytes, out_bytes, orig_avail_in; + tinfl_status status; + + if ((!pStream) || (!pStream->state)) return MZ_STREAM_ERROR; + if (flush == MZ_PARTIAL_FLUSH) flush = MZ_SYNC_FLUSH; + if ((flush) && (flush != MZ_SYNC_FLUSH) && (flush != MZ_FINISH)) return MZ_STREAM_ERROR; + + pState = (inflate_state*)pStream->state; + if (pState->m_window_bits > 0) decomp_flags |= TINFL_FLAG_PARSE_ZLIB_HEADER; + orig_avail_in = pStream->avail_in; + + first_call = pState->m_first_call; pState->m_first_call = 0; + if (pState->m_last_status < 0) return MZ_DATA_ERROR; + + if (pState->m_has_flushed && (flush != MZ_FINISH)) return MZ_STREAM_ERROR; + pState->m_has_flushed |= (flush == MZ_FINISH); + + if ((flush == MZ_FINISH) && (first_call)) + { + // MZ_FINISH on the first call implies that the input and output buffers are large enough to hold the entire compressed/decompressed file. + decomp_flags |= TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF; + in_bytes = pStream->avail_in; out_bytes = pStream->avail_out; + status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pStream->next_out, pStream->next_out, &out_bytes, decomp_flags); + pState->m_last_status = status; + pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes; pStream->total_in += (mz_uint)in_bytes; + pStream->adler = tinfl_get_adler32(&pState->m_decomp); + pStream->crc32 = tinfl_get_crc32(&pState->m_decomp); + pStream->next_out += (mz_uint)out_bytes; pStream->avail_out -= (mz_uint)out_bytes; pStream->total_out += (mz_uint)out_bytes; + + if (status < 0) + return MZ_DATA_ERROR; + else if (status != TINFL_STATUS_DONE) + { + pState->m_last_status = TINFL_STATUS_FAILED; + return MZ_BUF_ERROR; + } + return MZ_STREAM_END; + } + // flush != MZ_FINISH then we must assume there's more input. + if (flush != MZ_FINISH) decomp_flags |= TINFL_FLAG_HAS_MORE_INPUT; + + if (pState->m_dict_avail) + { + n = MZ_MIN(pState->m_dict_avail, pStream->avail_out); + memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n); + pStream->next_out += n; pStream->avail_out -= n; pStream->total_out += n; + pState->m_dict_avail -= n; pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1); + return ((pState->m_last_status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK; + } + + for ( ; ; ) + { + in_bytes = pStream->avail_in; + out_bytes = TINFL_LZ_DICT_SIZE - pState->m_dict_ofs; + + status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pState->m_dict, pState->m_dict + pState->m_dict_ofs, &out_bytes, decomp_flags); + pState->m_last_status = status; + + pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes; + pStream->total_in += (mz_uint)in_bytes; pStream->adler = tinfl_get_adler32(&pState->m_decomp); pStream->crc32 = tinfl_get_crc32(&pState->m_decomp); + + pState->m_dict_avail = (mz_uint)out_bytes; + + n = MZ_MIN(pState->m_dict_avail, pStream->avail_out); + memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n); + pStream->next_out += n; pStream->avail_out -= n; pStream->total_out += n; + pState->m_dict_avail -= n; pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1); + + if (status < 0) + return MZ_DATA_ERROR; // Stream is corrupted (there could be some uncompressed data left in the output dictionary - oh well). + else if ((status == TINFL_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in)) + return MZ_BUF_ERROR; // Signal caller that we can't make forward progress without supplying more input or by setting flush to MZ_FINISH. + else if (flush == MZ_FINISH) + { + // The output buffer MUST be large to hold the remaining uncompressed data when flush==MZ_FINISH. + if (status == TINFL_STATUS_DONE) + return pState->m_dict_avail ? MZ_BUF_ERROR : MZ_STREAM_END; + // status here must be TINFL_STATUS_HAS_MORE_OUTPUT, which means there's at least 1 more byte on the way. If there's no more room left in the output buffer then something is wrong. + else if (!pStream->avail_out) + return MZ_BUF_ERROR; + } + else if ((status == TINFL_STATUS_DONE) || (!pStream->avail_in) || (!pStream->avail_out) || (pState->m_dict_avail)) + break; + } + + return ((status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK; +} + +int mz_inflateEnd(mz_streamp pStream) +{ + if (!pStream) + return MZ_STREAM_ERROR; + if (pStream->state) + { + pStream->zfree(pStream->opaque, pStream->state); + pStream->state = NULL; + } + return MZ_OK; +} + +int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len) +{ + mz_stream stream; + int status; + memset(&stream, 0, sizeof(stream)); + + // In case mz_ulong is 64-bits (argh I hate longs). + if ((source_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR; + + stream.next_in = pSource; + stream.avail_in = (mz_uint32)source_len; + stream.next_out = pDest; + stream.avail_out = (mz_uint32)*pDest_len; + + status = mz_inflateInit(&stream); + if (status != MZ_OK) + return status; + + status = mz_inflate(&stream, MZ_FINISH); + if (status != MZ_STREAM_END) + { + mz_inflateEnd(&stream); + return ((status == MZ_BUF_ERROR) && (!stream.avail_in)) ? MZ_DATA_ERROR : status; + } + *pDest_len = stream.total_out; + + return mz_inflateEnd(&stream); +} + +const char *mz_error(int err) +{ + static struct { int m_err; const char *m_pDesc; } s_error_descs[] = + { + { MZ_OK, "" }, { MZ_STREAM_END, "stream end" }, { MZ_NEED_DICT, "need dictionary" }, { MZ_ERRNO, "file error" }, { MZ_STREAM_ERROR, "stream error" }, + { MZ_DATA_ERROR, "data error" }, { MZ_MEM_ERROR, "out of memory" }, { MZ_BUF_ERROR, "buf error" }, { MZ_VERSION_ERROR, "version error" }, { MZ_PARAM_ERROR, "parameter error" } + }; + mz_uint i; for (i = 0; i < sizeof(s_error_descs) / sizeof(s_error_descs[0]); ++i) if (s_error_descs[i].m_err == err) return s_error_descs[i].m_pDesc; + return NULL; +} + +#endif //MINIZ_NO_ZLIB_APIS + +// ------------------- Low-level Decompression (completely independent from all compression API's) + +#define TINFL_MEMCPY(d, s, l) memcpy(d, s, l) +#define TINFL_MEMSET(p, c, l) memset(p, c, l) + +#define TINFL_CR_BEGIN switch(r->m_state) { case 0: +#define TINFL_CR_RETURN(state_index, result) do { status = result; r->m_state = state_index; goto common_exit; case state_index:; } MZ_MACRO_END +#define TINFL_CR_RETURN_FOREVER(state_index, result) do { for ( ; ; ) { TINFL_CR_RETURN(state_index, result); } } MZ_MACRO_END +#define TINFL_CR_FINISH } + +// TODO: If the caller has indicated that there's no more input, and we attempt to read beyond the input buf, then something is wrong with the input because the inflator never +// reads ahead more than it needs to. Currently TINFL_GET_BYTE() pads the end of the stream with 0's in this scenario. +#define TINFL_GET_BYTE(state_index, c) do { \ + if (pIn_buf_cur >= pIn_buf_end) { \ + for ( ; ; ) { \ + if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) { \ + TINFL_CR_RETURN(state_index, TINFL_STATUS_NEEDS_MORE_INPUT); \ + if (pIn_buf_cur < pIn_buf_end) { \ + c = *pIn_buf_cur++; \ + break; \ + } \ + } else { \ + c = 0; \ + break; \ + } \ + } \ + } else c = *pIn_buf_cur++; } MZ_MACRO_END + +#define TINFL_NEED_BITS(state_index, n) do { mz_uint c; TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; } while (num_bits < (mz_uint)(n)) +#define TINFL_SKIP_BITS(state_index, n) do { if (num_bits < (mz_uint)(n)) { TINFL_NEED_BITS(state_index, n); } bit_buf >>= (n); num_bits -= (n); } MZ_MACRO_END +#define TINFL_GET_BITS(state_index, b, n) do { if (num_bits < (mz_uint)(n)) { TINFL_NEED_BITS(state_index, n); } b = bit_buf & ((1 << (n)) - 1); bit_buf >>= (n); num_bits -= (n); } MZ_MACRO_END + +// TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes remaining in the input buffer falls below 2. +// It reads just enough bytes from the input stream that are needed to decode the next Huffman code (and absolutely no more). It works by trying to fully decode a +// Huffman code by using whatever bits are currently present in the bit buffer. If this fails, it reads another byte, and tries again until it succeeds or until the +// bit buffer contains >=15 bits (deflate's max. Huffman code size). +#define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \ + do { \ + temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \ + if (temp >= 0) { \ + code_len = temp >> 9; \ + if ((code_len) && (num_bits >= code_len)) \ + break; \ + } else if (num_bits > TINFL_FAST_LOOKUP_BITS) { \ + code_len = TINFL_FAST_LOOKUP_BITS; \ + do { \ + temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \ + } while ((temp < 0) && (num_bits >= (code_len + 1))); if (temp >= 0) break; \ + } TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; \ + } while (num_bits < 15); + +// TINFL_HUFF_DECODE() decodes the next Huffman coded symbol. It's more complex than you would initially expect because the zlib API expects the decompressor to never read +// beyond the final byte of the deflate stream. (In other words, when this macro wants to read another byte from the input, it REALLY needs another byte in order to fully +// decode the next Huffman code.) Handling this properly is particularly important on raw deflate (non-zlib) streams, which aren't followed by a byte aligned adler-32. +// The slow path is only executed at the very end of the input buffer. +#define TINFL_HUFF_DECODE(state_index, sym, pHuff) do { \ + int temp; mz_uint code_len, c; \ + if (num_bits < 15) { \ + if ((pIn_buf_end - pIn_buf_cur) < 2) { \ + TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \ + } else { \ + bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); pIn_buf_cur += 2; num_bits += 16; \ + } \ + } \ + if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \ + code_len = temp >> 9, temp &= 511; \ + else { \ + code_len = TINFL_FAST_LOOKUP_BITS; do { temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; } while (temp < 0); \ + } sym = temp; bit_buf >>= code_len; num_bits -= code_len; } MZ_MACRO_END + +#if defined(__aarch64__) || defined(__arm__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmisleading-indentation" +#endif + +tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags) +{ + static const int s_length_base[31] = { 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 int s_length_extra[31]= { 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,0,0 }; + static const int s_dist_base[32] = { 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 int s_dist_extra[32] = { 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}; + static const mz_uint8 s_length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; + static const int s_min_table_sizes[3] = { 257, 1, 4 }; + + tinfl_status status = TINFL_STATUS_FAILED; mz_uint32 num_bits, dist, counter, num_extra; tinfl_bit_buf_t bit_buf; + const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = pIn_buf_next + *pIn_buf_size; + mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = pOut_buf_next + *pOut_buf_size; + size_t out_buf_size_mask = (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF) ? (size_t)-1 : ((pOut_buf_next - pOut_buf_start) + *pOut_buf_size) - 1, dist_from_out_buf_start; + + // Ensure the output buffer's size is a power of 2, unless the output buffer is large enough to hold the entire output file (in which case it doesn't matter). + if (((out_buf_size_mask + 1) & out_buf_size_mask) || (pOut_buf_next < pOut_buf_start)) { *pIn_buf_size = *pOut_buf_size = 0; return TINFL_STATUS_BAD_PARAM; } + + num_bits = r->m_num_bits; bit_buf = r->m_bit_buf; dist = r->m_dist; counter = r->m_counter; num_extra = r->m_num_extra; dist_from_out_buf_start = r->m_dist_from_out_buf_start; + TINFL_CR_BEGIN + + bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0; r->m_z_adler32 = r->m_check_adler32 = 1; + if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) + { + TINFL_GET_BYTE(1, r->m_zhdr0); TINFL_GET_BYTE(2, r->m_zhdr1); + counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8)); + if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || ((out_buf_size_mask + 1) < (size_t)(1U << (8U + (r->m_zhdr0 >> 4))))); + if (counter) { TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED); } + } + + do + { + TINFL_GET_BITS(3, r->m_final, 3); r->m_type = r->m_final >> 1; + if (r->m_type == 0) + { + TINFL_SKIP_BITS(5, num_bits & 7); + for (counter = 0; counter < 4; ++counter) { if (num_bits) TINFL_GET_BITS(6, r->m_raw_header[counter], 8); else TINFL_GET_BYTE(7, r->m_raw_header[counter]); } + if ((counter = (r->m_raw_header[0] | (r->m_raw_header[1] << 8))) != (mz_uint)(0xFFFF ^ (r->m_raw_header[2] | (r->m_raw_header[3] << 8)))) { TINFL_CR_RETURN_FOREVER(39, TINFL_STATUS_FAILED); } + while ((counter) && (num_bits)) + { + TINFL_GET_BITS(51, dist, 8); + while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT); } + *pOut_buf_cur++ = (mz_uint8)dist; + counter--; + } + while (counter) + { + size_t n; while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT); } + while (pIn_buf_cur >= pIn_buf_end) + { + if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) + { + TINFL_CR_RETURN(38, TINFL_STATUS_NEEDS_MORE_INPUT); + } + else + { + TINFL_CR_RETURN_FOREVER(40, TINFL_STATUS_FAILED); + } + } + n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), (size_t)(pIn_buf_end - pIn_buf_cur)), counter); + TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n); pIn_buf_cur += n; pOut_buf_cur += n; counter -= (mz_uint)n; + } + } + else if (r->m_type == 3) + { + TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED); + } + else + { + if (r->m_type == 1) + { + mz_uint8 *p = r->m_tables[0].m_code_size; mz_uint i; + r->m_table_sizes[0] = 288; r->m_table_sizes[1] = 32; TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32); + for ( i = 0; i <= 143; ++i) *p++ = 8; for ( ; i <= 255; ++i) *p++ = 9; for ( ; i <= 279; ++i) *p++ = 7; for ( ; i <= 287; ++i) *p++ = 8; + } + else + { + for (counter = 0; counter < 3; counter++) { TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]); r->m_table_sizes[counter] += s_min_table_sizes[counter]; } + MZ_CLEAR_OBJ(r->m_tables[2].m_code_size); for (counter = 0; counter < r->m_table_sizes[2]; counter++) { mz_uint s; TINFL_GET_BITS(14, s, 3); r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s; } + r->m_table_sizes[2] = 19; + } + for ( ; (int)r->m_type >= 0; r->m_type--) + { + int tree_next, tree_cur; tinfl_huff_table *pTable; + mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16]; pTable = &r->m_tables[r->m_type]; MZ_CLEAR_OBJ(total_syms); MZ_CLEAR_OBJ(pTable->m_look_up); MZ_CLEAR_OBJ(pTable->m_tree); + for (i = 0; i < r->m_table_sizes[r->m_type]; ++i) total_syms[pTable->m_code_size[i]]++; + used_syms = 0, total = 0; next_code[0] = next_code[1] = 0; + for (i = 1; i <= 15; ++i) { used_syms += total_syms[i]; next_code[i + 1] = (total = ((total + total_syms[i]) << 1)); } + if ((65536 != total) && (used_syms > 1)) + { + TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED); + } + for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index) + { + mz_uint rev_code = 0, l, cur_code, code_size = pTable->m_code_size[sym_index]; if (!code_size) continue; + cur_code = next_code[code_size]++; for (l = code_size; l > 0; l--, cur_code >>= 1) rev_code = (rev_code << 1) | (cur_code & 1); + if (code_size <= TINFL_FAST_LOOKUP_BITS) { mz_int16 k = (mz_int16)((code_size << 9) | sym_index); while (rev_code < TINFL_FAST_LOOKUP_SIZE) { pTable->m_look_up[rev_code] = k; rev_code += (1 << code_size); } continue; } + if (0 == (tree_cur = pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)])) { pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; } + rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1); + for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--) + { + tree_cur -= ((rev_code >>= 1) & 1); + if (!pTable->m_tree[-tree_cur - 1]) { pTable->m_tree[-tree_cur - 1] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; } else tree_cur = pTable->m_tree[-tree_cur - 1]; + } + tree_cur -= ((rev_code >>= 1) & 1); pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index; + } + if (r->m_type == 2) + { + for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]); ) + { + mz_uint s; TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]); if (dist < 16) { r->m_len_codes[counter++] = (mz_uint8)dist; continue; } + if ((dist == 16) && (!counter)) + { + TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED); + } + num_extra = "\02\03\07"[dist - 16]; TINFL_GET_BITS(18, s, num_extra); s += "\03\03\013"[dist - 16]; + TINFL_MEMSET(r->m_len_codes + counter, (dist == 16) ? r->m_len_codes[counter - 1] : 0, s); counter += s; + } + if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter) + { + TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED); + } + TINFL_MEMCPY(r->m_tables[0].m_code_size, r->m_len_codes, r->m_table_sizes[0]); TINFL_MEMCPY(r->m_tables[1].m_code_size, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]); + } + } + for ( ; ; ) + { + mz_uint8 *pSrc; + for ( ; ; ) + { + if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2)) + { + TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]); + if (counter >= 256) + break; + while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT); } + *pOut_buf_cur++ = (mz_uint8)counter; + } + else + { + int sym2; mz_uint code_len; +#if TINFL_USE_64BIT_BITBUF + if (num_bits < 30) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE32(pIn_buf_cur)) << num_bits); pIn_buf_cur += 4; num_bits += 32; } +#else + if (num_bits < 15) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); pIn_buf_cur += 2; num_bits += 16; } +#endif + if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) + code_len = sym2 >> 9; + else + { + code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0); + } + counter = sym2; bit_buf >>= code_len; num_bits -= code_len; + if (counter & 256) + break; + +#if !TINFL_USE_64BIT_BITBUF + if (num_bits < 15) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); pIn_buf_cur += 2; num_bits += 16; } +#endif + if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) + code_len = sym2 >> 9; + else + { + code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0); + } + bit_buf >>= code_len; num_bits -= code_len; + + pOut_buf_cur[0] = (mz_uint8)counter; + if (sym2 & 256) + { + pOut_buf_cur++; + counter = sym2; + break; + } + pOut_buf_cur[1] = (mz_uint8)sym2; + pOut_buf_cur += 2; + } + } + if ((counter &= 511) == 256) break; + + num_extra = s_length_extra[counter - 257]; counter = s_length_base[counter - 257]; + if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(25, extra_bits, num_extra); counter += extra_bits; } + + TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]); + num_extra = s_dist_extra[dist]; dist = s_dist_base[dist]; + if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(27, extra_bits, num_extra); dist += extra_bits; } + + dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start; + if ((dist > dist_from_out_buf_start) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) + { + TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED); + } + + pSrc = pOut_buf_start + ((dist_from_out_buf_start - dist) & out_buf_size_mask); + + if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end) + { + while (counter--) + { + while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT); } + *pOut_buf_cur++ = pOut_buf_start[(dist_from_out_buf_start++ - dist) & out_buf_size_mask]; + } + continue; + } +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES + else if ((counter >= 9) && (counter <= dist)) + { + const mz_uint8 *pSrc_end = pSrc + (counter & ~7); + do + { + ((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0]; + ((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1]; + pOut_buf_cur += 8; + } while ((pSrc += 8) < pSrc_end); + if ((counter &= 7) < 3) + { + if (counter) + { + pOut_buf_cur[0] = pSrc[0]; + if (counter > 1) + pOut_buf_cur[1] = pSrc[1]; + pOut_buf_cur += counter; + } + continue; + } + } +#endif + do + { + pOut_buf_cur[0] = pSrc[0]; + pOut_buf_cur[1] = pSrc[1]; + pOut_buf_cur[2] = pSrc[2]; + pOut_buf_cur += 3; pSrc += 3; + } while ((int)(counter -= 3) > 2); + if ((int)counter > 0) + { + pOut_buf_cur[0] = pSrc[0]; + if ((int)counter > 1) + pOut_buf_cur[1] = pSrc[1]; + pOut_buf_cur += counter; + } + } + } + } while (!(r->m_final & 1)); + if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) + { + TINFL_SKIP_BITS(32, num_bits & 7); for (counter = 0; counter < 4; ++counter) { mz_uint s; if (num_bits) TINFL_GET_BITS(41, s, 8); else TINFL_GET_BYTE(42, s); r->m_z_adler32 = (r->m_z_adler32 << 8) | s; } + } + TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE); + TINFL_CR_FINISH + +common_exit: + r->m_num_bits = num_bits; r->m_bit_buf = bit_buf; r->m_dist = dist; r->m_counter = counter; r->m_num_extra = num_extra; r->m_dist_from_out_buf_start = dist_from_out_buf_start; + *pIn_buf_size = pIn_buf_cur - pIn_buf_next; *pOut_buf_size = pOut_buf_cur - pOut_buf_next; + if ((decomp_flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && (status >= 0)) + { + const mz_uint8 *ptr = pOut_buf_next; size_t buf_len = *pOut_buf_size; + mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, s2 = r->m_check_adler32 >> 16; size_t block_len = buf_len % 5552; + while (buf_len) + { + for (i = 0; i + 7 < block_len; i += 8, ptr += 8) + { + s1 += ptr[0], s2 += s1; s1 += ptr[1], s2 += s1; s1 += ptr[2], s2 += s1; s1 += ptr[3], s2 += s1; + s1 += ptr[4], s2 += s1; s1 += ptr[5], s2 += s1; s1 += ptr[6], s2 += s1; s1 += ptr[7], s2 += s1; + } + for ( ; i < block_len; ++i) s1 += *ptr++, s2 += s1; + s1 %= 65521U, s2 %= 65521U; buf_len -= block_len; block_len = 5552; + } + r->m_check_adler32 = (s2 << 16) + s1; if ((status == TINFL_STATUS_DONE) && (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) && (r->m_check_adler32 != r->m_z_adler32)) status = TINFL_STATUS_ADLER32_MISMATCH; + } + return status; +} + +#if defined(__aarch64__) || defined(__arm__) +#pragma GCC diagnostic pop +#endif + +// Higher level helper functions. +void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags) +{ + tinfl_decompressor decomp; void *pBuf = NULL, *pNew_buf; size_t src_buf_ofs = 0, out_buf_capacity = 0; + *pOut_len = 0; + tinfl_init(&decomp); + for ( ; ; ) + { + size_t src_buf_size = src_buf_len - src_buf_ofs, dst_buf_size = out_buf_capacity - *pOut_len, new_out_buf_capacity; + tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8*)pSrc_buf + src_buf_ofs, &src_buf_size, (mz_uint8*)pBuf, pBuf ? (mz_uint8*)pBuf + *pOut_len : NULL, &dst_buf_size, + (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF); + if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT)) + { + MZ_FREE(pBuf); *pOut_len = 0; return NULL; + } + src_buf_ofs += src_buf_size; + *pOut_len += dst_buf_size; + if (status == TINFL_STATUS_DONE) break; + new_out_buf_capacity = out_buf_capacity * 2; if (new_out_buf_capacity < 128) new_out_buf_capacity = 128; + pNew_buf = MZ_REALLOC(pBuf, new_out_buf_capacity); + if (!pNew_buf) + { + MZ_FREE(pBuf); *pOut_len = 0; return NULL; + } + pBuf = pNew_buf; out_buf_capacity = new_out_buf_capacity; + } + return pBuf; +} + +size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags) +{ + tinfl_decompressor decomp; tinfl_status status; tinfl_init(&decomp); + status = tinfl_decompress(&decomp, (const mz_uint8*)pSrc_buf, &src_buf_len, (mz_uint8*)pOut_buf, (mz_uint8*)pOut_buf, &out_buf_len, (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF); + return (status != TINFL_STATUS_DONE) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED : out_buf_len; +} + +int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags) +{ + int result = 0; + tinfl_decompressor decomp; + mz_uint8 *pDict = (mz_uint8*)MZ_MALLOC(TINFL_LZ_DICT_SIZE); size_t in_buf_ofs = 0, dict_ofs = 0; + if (!pDict) + return TINFL_STATUS_FAILED; + tinfl_init(&decomp); + for ( ; ; ) + { + size_t in_buf_size = *pIn_buf_size - in_buf_ofs, dst_buf_size = TINFL_LZ_DICT_SIZE - dict_ofs; + tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8*)pIn_buf + in_buf_ofs, &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size, + (flags & ~(TINFL_FLAG_HAS_MORE_INPUT | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))); + in_buf_ofs += in_buf_size; + if ((dst_buf_size) && (!(*pPut_buf_func)(pDict + dict_ofs, (int)dst_buf_size, pPut_buf_user))) + break; + if (status != TINFL_STATUS_HAS_MORE_OUTPUT) + { + result = (status == TINFL_STATUS_DONE); + break; + } + dict_ofs = (dict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1); + } + MZ_FREE(pDict); + *pIn_buf_size = in_buf_ofs; + return result; +} + +// ------------------- Low-level Compression (independent from all decompression API's) + +// Purposely making these tables static for faster init and thread safety. +static const mz_uint16 s_tdefl_len_sym[256] = { + 257,258,259,260,261,262,263,264,265,265,266,266,267,267,268,268,269,269,269,269,270,270,270,270,271,271,271,271,272,272,272,272, + 273,273,273,273,273,273,273,273,274,274,274,274,274,274,274,274,275,275,275,275,275,275,275,275,276,276,276,276,276,276,276,276, + 277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278, + 279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280, + 281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281, + 282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282, + 283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283, + 284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,285 }; + +static const mz_uint8 s_tdefl_len_extra[256] = { + 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0 }; + +static const mz_uint8 s_tdefl_small_dist_sym[512] = { + 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,16,16,16,16,16,16,16,16,16,16,16,16,16, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,17,17,17,17,17,17, + 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, + 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, + 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17 }; + +static const mz_uint8 s_tdefl_small_dist_extra[512] = { + 0,0,0,0,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7 }; + +static const mz_uint8 s_tdefl_large_dist_sym[128] = { + 0,0,18,19,20,20,21,21,22,22,22,22,23,23,23,23,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,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,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 }; + +static const mz_uint8 s_tdefl_large_dist_extra[128] = { + 0,0,8,8,9,9,9,9,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, + 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 }; + +// Radix sorts tdefl_sym_freq[] array by 16-bit key m_key. Returns ptr to sorted values. +typedef struct { mz_uint16 m_key, m_sym_index; } tdefl_sym_freq; +static tdefl_sym_freq* tdefl_radix_sort_syms(mz_uint num_syms, tdefl_sym_freq* pSyms0, tdefl_sym_freq* pSyms1) +{ + mz_uint32 total_passes = 2, pass_shift, pass, i, hist[256 * 2]; tdefl_sym_freq* pCur_syms = pSyms0, *pNew_syms = pSyms1; MZ_CLEAR_OBJ(hist); + for (i = 0; i < num_syms; i++) { mz_uint freq = pSyms0[i].m_key; hist[freq & 0xFF]++; hist[256 + ((freq >> 8) & 0xFF)]++; } + while ((total_passes > 1) && (num_syms == hist[(total_passes - 1) * 256])) total_passes--; + for (pass_shift = 0, pass = 0; pass < total_passes; pass++, pass_shift += 8) + { + const mz_uint32* pHist = &hist[pass << 8]; + mz_uint offsets[256], cur_ofs = 0; + for (i = 0; i < 256; i++) { offsets[i] = cur_ofs; cur_ofs += pHist[i]; } + for (i = 0; i < num_syms; i++) pNew_syms[offsets[(pCur_syms[i].m_key >> pass_shift) & 0xFF]++] = pCur_syms[i]; + { tdefl_sym_freq* t = pCur_syms; pCur_syms = pNew_syms; pNew_syms = t; } + } + return pCur_syms; +} + +// tdefl_calculate_minimum_redundancy() originally written by: Alistair Moffat, alistair@cs.mu.oz.au, Jyrki Katajainen, jyrki@diku.dk, November 1996. +static void tdefl_calculate_minimum_redundancy(tdefl_sym_freq *A, int n) +{ + int root, leaf, next, avbl, used, dpth; + if (n==0) return; else if (n==1) { A[0].m_key = 1; return; } + A[0].m_key += A[1].m_key; root = 0; leaf = 2; + for (next=1; next < n-1; next++) + { + if (leaf>=n || A[root].m_key=n || (root=0; next--) A[next].m_key = A[A[next].m_key].m_key+1; + avbl = 1; used = dpth = 0; root = n-2; next = n-1; + while (avbl>0) + { + while (root>=0 && (int)A[root].m_key==dpth) { used++; root--; } + while (avbl>used) { A[next--].m_key = (mz_uint16)(dpth); avbl--; } + avbl = 2*used; dpth++; used = 0; + } +} + +// Limits canonical Huffman code table's max code size. +enum { TDEFL_MAX_SUPPORTED_HUFF_CODESIZE = 32 }; +static void tdefl_huffman_enforce_max_code_size(int *pNum_codes, int code_list_len, int max_code_size) +{ + int i; mz_uint32 total = 0; if (code_list_len <= 1) return; + for (i = max_code_size + 1; i <= TDEFL_MAX_SUPPORTED_HUFF_CODESIZE; i++) pNum_codes[max_code_size] += pNum_codes[i]; + for (i = max_code_size; i > 0; i--) total += (((mz_uint32)pNum_codes[i]) << (max_code_size - i)); + while (total != (1UL << max_code_size)) + { + pNum_codes[max_code_size]--; + for (i = max_code_size - 1; i > 0; i--) if (pNum_codes[i]) { pNum_codes[i]--; pNum_codes[i + 1] += 2; break; } + total--; + } +} + +static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num, int table_len, int code_size_limit, int static_table) +{ + int i, j, l, num_codes[1 + TDEFL_MAX_SUPPORTED_HUFF_CODESIZE]; mz_uint next_code[TDEFL_MAX_SUPPORTED_HUFF_CODESIZE + 1]; MZ_CLEAR_OBJ(num_codes); + if (static_table) + { + for (i = 0; i < table_len; i++) num_codes[d->m_huff_code_sizes[table_num][i]]++; + } + else + { + tdefl_sym_freq syms0[TDEFL_MAX_HUFF_SYMBOLS], syms1[TDEFL_MAX_HUFF_SYMBOLS], *pSyms; + int num_used_syms = 0; + const mz_uint16 *pSym_count = &d->m_huff_count[table_num][0]; + for (i = 0; i < table_len; i++) if (pSym_count[i]) { syms0[num_used_syms].m_key = (mz_uint16)pSym_count[i]; syms0[num_used_syms++].m_sym_index = (mz_uint16)i; } + + pSyms = tdefl_radix_sort_syms(num_used_syms, syms0, syms1); tdefl_calculate_minimum_redundancy(pSyms, num_used_syms); + + for (i = 0; i < num_used_syms; i++) num_codes[pSyms[i].m_key]++; + + tdefl_huffman_enforce_max_code_size(num_codes, num_used_syms, code_size_limit); + + MZ_CLEAR_OBJ(d->m_huff_code_sizes[table_num]); MZ_CLEAR_OBJ(d->m_huff_codes[table_num]); + for (i = 1, j = num_used_syms; i <= code_size_limit; i++) + for (l = num_codes[i]; l > 0; l--) d->m_huff_code_sizes[table_num][pSyms[--j].m_sym_index] = (mz_uint8)(i); + } + + next_code[1] = 0; for (j = 0, i = 2; i <= code_size_limit; i++) next_code[i] = j = ((j + num_codes[i - 1]) << 1); + + for (i = 0; i < table_len; i++) + { + mz_uint rev_code = 0, code, code_size; if ((code_size = d->m_huff_code_sizes[table_num][i]) == 0) continue; + code = next_code[code_size]++; for (l = code_size; l > 0; l--, code >>= 1) rev_code = (rev_code << 1) | (code & 1); + d->m_huff_codes[table_num][i] = (mz_uint16)rev_code; + } +} + +#define TDEFL_PUT_BITS(b, l) do { \ + mz_uint bits = b; mz_uint len = l; MZ_ASSERT(bits <= ((1U << len) - 1U)); \ + d->m_bit_buffer |= (bits << d->m_bits_in); d->m_bits_in += len; \ + while (d->m_bits_in >= 8) { \ + if (d->m_pOutput_buf < d->m_pOutput_buf_end) \ + *d->m_pOutput_buf++ = (mz_uint8)(d->m_bit_buffer); \ + d->m_bit_buffer >>= 8; \ + d->m_bits_in -= 8; \ + } \ +} MZ_MACRO_END + +#define TDEFL_RLE_PREV_CODE_SIZE() { if (rle_repeat_count) { \ + if (rle_repeat_count < 3) { \ + d->m_huff_count[2][prev_code_size] = (mz_uint16)(d->m_huff_count[2][prev_code_size] + rle_repeat_count); \ + while (rle_repeat_count--) packed_code_sizes[num_packed_code_sizes++] = prev_code_size; \ + } else { \ + d->m_huff_count[2][16] = (mz_uint16)(d->m_huff_count[2][16] + 1); packed_code_sizes[num_packed_code_sizes++] = 16; packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_repeat_count - 3); \ +} rle_repeat_count = 0; } } + +#define TDEFL_RLE_ZERO_CODE_SIZE() { if (rle_z_count) { \ + if (rle_z_count < 3) { \ + d->m_huff_count[2][0] = (mz_uint16)(d->m_huff_count[2][0] + rle_z_count); while (rle_z_count--) packed_code_sizes[num_packed_code_sizes++] = 0; \ + } else if (rle_z_count <= 10) { \ + d->m_huff_count[2][17] = (mz_uint16)(d->m_huff_count[2][17] + 1); packed_code_sizes[num_packed_code_sizes++] = 17; packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 3); \ + } else { \ + d->m_huff_count[2][18] = (mz_uint16)(d->m_huff_count[2][18] + 1); packed_code_sizes[num_packed_code_sizes++] = 18; packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 11); \ +} rle_z_count = 0; } } + +static mz_uint8 s_tdefl_packed_code_size_syms_swizzle[] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; + +static void tdefl_start_dynamic_block(tdefl_compressor *d) +{ + int num_lit_codes, num_dist_codes, num_bit_lengths; mz_uint i, total_code_sizes_to_pack, num_packed_code_sizes, rle_z_count, rle_repeat_count, packed_code_sizes_index; + mz_uint8 code_sizes_to_pack[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], packed_code_sizes[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], prev_code_size = 0xFF; + + d->m_huff_count[0][256] = 1; + + tdefl_optimize_huffman_table(d, 0, TDEFL_MAX_HUFF_SYMBOLS_0, 15, MZ_FALSE); + tdefl_optimize_huffman_table(d, 1, TDEFL_MAX_HUFF_SYMBOLS_1, 15, MZ_FALSE); + + for (num_lit_codes = 286; num_lit_codes > 257; num_lit_codes--) if (d->m_huff_code_sizes[0][num_lit_codes - 1]) break; + for (num_dist_codes = 30; num_dist_codes > 1; num_dist_codes--) if (d->m_huff_code_sizes[1][num_dist_codes - 1]) break; + + memcpy(code_sizes_to_pack, &d->m_huff_code_sizes[0][0], num_lit_codes); + memcpy(code_sizes_to_pack + num_lit_codes, &d->m_huff_code_sizes[1][0], num_dist_codes); + total_code_sizes_to_pack = num_lit_codes + num_dist_codes; num_packed_code_sizes = 0; rle_z_count = 0; rle_repeat_count = 0; + + memset(&d->m_huff_count[2][0], 0, sizeof(d->m_huff_count[2][0]) * TDEFL_MAX_HUFF_SYMBOLS_2); + for (i = 0; i < total_code_sizes_to_pack; i++) + { + mz_uint8 code_size = code_sizes_to_pack[i]; + if (!code_size) + { + TDEFL_RLE_PREV_CODE_SIZE(); + if (++rle_z_count == 138) { TDEFL_RLE_ZERO_CODE_SIZE(); } + } + else + { + TDEFL_RLE_ZERO_CODE_SIZE(); + if (code_size != prev_code_size) + { + TDEFL_RLE_PREV_CODE_SIZE(); + d->m_huff_count[2][code_size] = (mz_uint16)(d->m_huff_count[2][code_size] + 1); packed_code_sizes[num_packed_code_sizes++] = code_size; + } + else if (++rle_repeat_count == 6) + { + TDEFL_RLE_PREV_CODE_SIZE(); + } + } + prev_code_size = code_size; + } + if (rle_repeat_count) { TDEFL_RLE_PREV_CODE_SIZE(); } else { TDEFL_RLE_ZERO_CODE_SIZE(); } + + tdefl_optimize_huffman_table(d, 2, TDEFL_MAX_HUFF_SYMBOLS_2, 7, MZ_FALSE); + + TDEFL_PUT_BITS(2, 2); + + TDEFL_PUT_BITS(num_lit_codes - 257, 5); + TDEFL_PUT_BITS(num_dist_codes - 1, 5); + + for (num_bit_lengths = 18; num_bit_lengths >= 0; num_bit_lengths--) if (d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[num_bit_lengths]]) break; + num_bit_lengths = MZ_MAX(4, (num_bit_lengths + 1)); TDEFL_PUT_BITS(num_bit_lengths - 4, 4); + for (i = 0; (int)i < num_bit_lengths; i++) TDEFL_PUT_BITS(d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[i]], 3); + + for (packed_code_sizes_index = 0; packed_code_sizes_index < num_packed_code_sizes; ) + { + mz_uint code = packed_code_sizes[packed_code_sizes_index++]; MZ_ASSERT(code < TDEFL_MAX_HUFF_SYMBOLS_2); + TDEFL_PUT_BITS(d->m_huff_codes[2][code], d->m_huff_code_sizes[2][code]); + if (code >= 16) TDEFL_PUT_BITS(packed_code_sizes[packed_code_sizes_index++], "\02\03\07"[code - 16]); + } +} + +static void tdefl_start_static_block(tdefl_compressor *d) +{ + mz_uint i; + mz_uint8 *p = &d->m_huff_code_sizes[0][0]; + + for (i = 0; i <= 143; ++i) *p++ = 8; + for ( ; i <= 255; ++i) *p++ = 9; + for ( ; i <= 279; ++i) *p++ = 7; + for ( ; i <= 287; ++i) *p++ = 8; + + memset(d->m_huff_code_sizes[1], 5, 32); + + tdefl_optimize_huffman_table(d, 0, 288, 15, MZ_TRUE); + tdefl_optimize_huffman_table(d, 1, 32, 15, MZ_TRUE); + + TDEFL_PUT_BITS(1, 2); +} + +static const mz_uint mz_bitmasks[17] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF }; + +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS +static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d) +{ + mz_uint flags; + mz_uint8 *pLZ_codes; + mz_uint8 *pOutput_buf = d->m_pOutput_buf; + mz_uint8 *pLZ_code_buf_end = d->m_pLZ_code_buf; + mz_uint64 bit_buffer = d->m_bit_buffer; + mz_uint bits_in = d->m_bits_in; + +#define TDEFL_PUT_BITS_FAST(b, l) { bit_buffer |= (((mz_uint64)(b)) << bits_in); bits_in += (l); } + + flags = 1; + for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < pLZ_code_buf_end; flags >>= 1) + { + if (flags == 1) + flags = *pLZ_codes++ | 0x100; + + if (flags & 1) + { + mz_uint s0, s1, n0, n1, sym, num_extra_bits; + mz_uint match_len = pLZ_codes[0], match_dist = *(const mz_uint16 *)(pLZ_codes + 1); pLZ_codes += 3; + + MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); + TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); + TDEFL_PUT_BITS_FAST(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]); + + // This sequence coaxes MSVC into using cmov's vs. jmp's. + s0 = s_tdefl_small_dist_sym[match_dist & 511]; + n0 = s_tdefl_small_dist_extra[match_dist & 511]; + s1 = s_tdefl_large_dist_sym[match_dist >> 8]; + n1 = s_tdefl_large_dist_extra[match_dist >> 8]; + sym = (match_dist < 512) ? s0 : s1; + num_extra_bits = (match_dist < 512) ? n0 : n1; + + MZ_ASSERT(d->m_huff_code_sizes[1][sym]); + TDEFL_PUT_BITS_FAST(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]); + TDEFL_PUT_BITS_FAST(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits); + } + else + { + mz_uint lit = *pLZ_codes++; + MZ_ASSERT(d->m_huff_code_sizes[0][lit]); + TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); + + if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end)) + { + flags >>= 1; + lit = *pLZ_codes++; + MZ_ASSERT(d->m_huff_code_sizes[0][lit]); + TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); + + if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end)) + { + flags >>= 1; + lit = *pLZ_codes++; + MZ_ASSERT(d->m_huff_code_sizes[0][lit]); + TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); + } + } + } + + if (pOutput_buf >= d->m_pOutput_buf_end) + return MZ_FALSE; + + *(mz_uint64*)pOutput_buf = bit_buffer; + pOutput_buf += (bits_in >> 3); + bit_buffer >>= (bits_in & ~7); + bits_in &= 7; + } + +#undef TDEFL_PUT_BITS_FAST + + d->m_pOutput_buf = pOutput_buf; + d->m_bits_in = 0; + d->m_bit_buffer = 0; + + while (bits_in) + { + mz_uint32 n = MZ_MIN(bits_in, 16); + TDEFL_PUT_BITS((mz_uint)bit_buffer & mz_bitmasks[n], n); + bit_buffer >>= n; + bits_in -= n; + } + + TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]); + + return (d->m_pOutput_buf < d->m_pOutput_buf_end); +} +#else +static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d) +{ + mz_uint flags; + mz_uint8 *pLZ_codes; + + flags = 1; + for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < d->m_pLZ_code_buf; flags >>= 1) + { + if (flags == 1) + flags = *pLZ_codes++ | 0x100; + if (flags & 1) + { + mz_uint sym, num_extra_bits; + mz_uint match_len = pLZ_codes[0], match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8)); pLZ_codes += 3; + + MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); + TDEFL_PUT_BITS(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); + TDEFL_PUT_BITS(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]); + + if (match_dist < 512) + { + sym = s_tdefl_small_dist_sym[match_dist]; num_extra_bits = s_tdefl_small_dist_extra[match_dist]; + } + else + { + sym = s_tdefl_large_dist_sym[match_dist >> 8]; num_extra_bits = s_tdefl_large_dist_extra[match_dist >> 8]; + } + MZ_ASSERT(d->m_huff_code_sizes[1][sym]); + TDEFL_PUT_BITS(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]); + TDEFL_PUT_BITS(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits); + } + else + { + mz_uint lit = *pLZ_codes++; + MZ_ASSERT(d->m_huff_code_sizes[0][lit]); + TDEFL_PUT_BITS(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); + } + } + + TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]); + + return (d->m_pOutput_buf < d->m_pOutput_buf_end); +} +#endif // MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS + +static mz_bool tdefl_compress_block(tdefl_compressor *d, mz_bool static_block) +{ + if (static_block) + tdefl_start_static_block(d); + else + tdefl_start_dynamic_block(d); + return tdefl_compress_lz_codes(d); +} + +static int tdefl_flush_block(tdefl_compressor *d, int flush) +{ + mz_uint saved_bit_buf, saved_bits_in; + mz_uint8 *pSaved_output_buf; + mz_bool comp_block_succeeded = MZ_FALSE; + int n, use_raw_block = ((d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS) != 0) && (d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size; + mz_uint8 *pOutput_buf_start = ((d->m_pPut_buf_func == NULL) && ((*d->m_pOut_buf_size - d->m_out_buf_ofs) >= TDEFL_OUT_BUF_SIZE)) ? ((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs) : d->m_output_buf; + + d->m_pOutput_buf = pOutput_buf_start; + d->m_pOutput_buf_end = d->m_pOutput_buf + TDEFL_OUT_BUF_SIZE - 16; + + MZ_ASSERT(!d->m_output_flush_remaining); + d->m_output_flush_ofs = 0; + d->m_output_flush_remaining = 0; + + *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> d->m_num_flags_left); + d->m_pLZ_code_buf -= (d->m_num_flags_left == 8); + + if ((d->m_flags & TDEFL_WRITE_ZLIB_HEADER) && (!d->m_block_index)) + { + TDEFL_PUT_BITS(0x78, 8); TDEFL_PUT_BITS(0x01, 8); + } + + TDEFL_PUT_BITS(flush == TDEFL_FINISH, 1); + + pSaved_output_buf = d->m_pOutput_buf; saved_bit_buf = d->m_bit_buffer; saved_bits_in = d->m_bits_in; + + if (!use_raw_block) + comp_block_succeeded = tdefl_compress_block(d, (d->m_flags & TDEFL_FORCE_ALL_STATIC_BLOCKS) || (d->m_total_lz_bytes < 48)); + + // If the block gets expanded, forget the current contents of the output buffer and send a raw block instead. + if ( ((use_raw_block) || ((d->m_total_lz_bytes) && ((d->m_pOutput_buf - pSaved_output_buf + 1U) >= d->m_total_lz_bytes))) && + ((d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size) ) + { + mz_uint i; d->m_pOutput_buf = pSaved_output_buf; d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in; + TDEFL_PUT_BITS(0, 2); + if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); } + for (i = 2; i; --i, d->m_total_lz_bytes ^= 0xFFFF) + { + TDEFL_PUT_BITS(d->m_total_lz_bytes & 0xFFFF, 16); + } + for (i = 0; i < d->m_total_lz_bytes; ++i) + { + TDEFL_PUT_BITS(d->m_dict[(d->m_lz_code_buf_dict_pos + i) & TDEFL_LZ_DICT_SIZE_MASK], 8); + } + } + // Check for the extremely unlikely (if not impossible) case of the compressed block not fitting into the output buffer when using dynamic codes. + else if (!comp_block_succeeded) + { + d->m_pOutput_buf = pSaved_output_buf; d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in; + tdefl_compress_block(d, MZ_TRUE); + } + + if (flush) + { + if (flush == TDEFL_FINISH) + { + if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); } + if (d->m_flags & TDEFL_WRITE_ZLIB_HEADER) { mz_uint i, a = d->m_adler32; for (i = 0; i < 4; i++) { TDEFL_PUT_BITS((a >> 24) & 0xFF, 8); a <<= 8; } } + } + else + { + mz_uint i, z = 0; TDEFL_PUT_BITS(0, 3); if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); } for (i = 2; i; --i, z ^= 0xFFFF) { TDEFL_PUT_BITS(z & 0xFFFF, 16); } + } + } + + MZ_ASSERT(d->m_pOutput_buf < d->m_pOutput_buf_end); + + memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0); + memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1); + + d->m_pLZ_code_buf = d->m_lz_code_buf + 1; d->m_pLZ_flags = d->m_lz_code_buf; d->m_num_flags_left = 8; d->m_lz_code_buf_dict_pos += d->m_total_lz_bytes; d->m_total_lz_bytes = 0; d->m_block_index++; + + if ((n = (int)(d->m_pOutput_buf - pOutput_buf_start)) != 0) + { + if (d->m_pPut_buf_func) + { + *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf; + if (!(*d->m_pPut_buf_func)(d->m_output_buf, n, d->m_pPut_buf_user)) + return (d->m_prev_return_status = TDEFL_STATUS_PUT_BUF_FAILED); + } + else if (pOutput_buf_start == d->m_output_buf) + { + int bytes_to_copy = (int)MZ_MIN((size_t)n, (size_t)(*d->m_pOut_buf_size - d->m_out_buf_ofs)); + memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf, bytes_to_copy); + d->m_out_buf_ofs += bytes_to_copy; + if ((n -= bytes_to_copy) != 0) + { + d->m_output_flush_ofs = bytes_to_copy; + d->m_output_flush_remaining = n; + } + } + else + { + d->m_out_buf_ofs += n; + } + } + + return d->m_output_flush_remaining; +} + +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-aliasing" + +#define TDEFL_READ_UNALIGNED_WORD(p) *(const mz_uint16*)(p) +static __forceinline void tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len) + +{ + mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len; + mz_uint num_probes_left = d->m_max_probes[match_len >= 32]; + const mz_uint16 *s = (const mz_uint16*)(d->m_dict + pos), *p, *q; + mz_uint16 c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]), s01 = TDEFL_READ_UNALIGNED_WORD(s); + MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN); if (max_match_len <= match_len) return; + for ( ; ; ) + { + for ( ; ; ) + { + if (--num_probes_left == 0) return; + #define TDEFL_PROBE \ + next_probe_pos = d->m_next[probe_pos]; \ + if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) return; \ + probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \ + if (TDEFL_READ_UNALIGNED_WORD(&d->m_dict[probe_pos + match_len - 1]) == c01) break; + TDEFL_PROBE; TDEFL_PROBE; TDEFL_PROBE; + } + if (!dist) break; q = (const mz_uint16*)(d->m_dict + probe_pos); if (TDEFL_READ_UNALIGNED_WORD(q) != s01) continue; p = s; probe_len = 32; + do { } while ( (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && + (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (--probe_len > 0) ); + if (!probe_len) + { + *pMatch_dist = dist; *pMatch_len = MZ_MIN(max_match_len, TDEFL_MAX_MATCH_LEN); break; + } + else if ((probe_len = ((mz_uint)(p - s) * 2) + (mz_uint)(*(const mz_uint8*)p == *(const mz_uint8*)q)) > match_len) + { + *pMatch_dist = dist; if ((*pMatch_len = match_len = MZ_MIN(max_match_len, probe_len)) == max_match_len) break; + c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]); + } + } +} + +#pragma GCC diagnostic pop + +#else + +#if defined(__aarch64__) || defined(__arm__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmisleading-indentation" +#endif + +static __forceinline void tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len) +{ + mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len; + mz_uint num_probes_left = d->m_max_probes[match_len >= 32]; + const mz_uint8 *s = d->m_dict + pos, *p, *q; + mz_uint8 c0 = d->m_dict[pos + match_len], c1 = d->m_dict[pos + match_len - 1]; + MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN); if (max_match_len <= match_len) return; + for ( ; ; ) + { + for ( ; ; ) + { + if (--num_probes_left == 0) return; + #define TDEFL_PROBE \ + next_probe_pos = d->m_next[probe_pos]; \ + if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) return; \ + probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \ + if ((d->m_dict[probe_pos + match_len] == c0) && (d->m_dict[probe_pos + match_len - 1] == c1)) break; + TDEFL_PROBE; TDEFL_PROBE; TDEFL_PROBE; + } + if (!dist) break; p = s; q = d->m_dict + probe_pos; for (probe_len = 0; probe_len < max_match_len; probe_len++) if (*p++ != *q++) break; + if (probe_len > match_len) + { + *pMatch_dist = dist; if ((*pMatch_len = match_len = probe_len) == max_match_len) return; + c0 = d->m_dict[pos + match_len]; c1 = d->m_dict[pos + match_len - 1]; + } + } +} + +#if defined(__aarch64__) || defined(__arm__) +#pragma GCC diagnostic pop +#endif + +#endif // #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES + +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-aliasing" +static mz_bool tdefl_compress_fast(tdefl_compressor *d) +{ + // Faster, minimally featured LZRW1-style match+parse loop with better register utilization. Intended for applications where raw throughput is valued more highly than ratio. + mz_uint lookahead_pos = d->m_lookahead_pos, lookahead_size = d->m_lookahead_size, dict_size = d->m_dict_size, total_lz_bytes = d->m_total_lz_bytes, num_flags_left = d->m_num_flags_left; + mz_uint8 *pLZ_code_buf = d->m_pLZ_code_buf, *pLZ_flags = d->m_pLZ_flags; + mz_uint cur_pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK; + + while ((d->m_src_buf_left) || ((d->m_flush) && (lookahead_size))) + { + const mz_uint TDEFL_COMP_FAST_LOOKAHEAD_SIZE = 4096; + mz_uint dst_pos = (lookahead_pos + lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK; + mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(d->m_src_buf_left, TDEFL_COMP_FAST_LOOKAHEAD_SIZE - lookahead_size); + d->m_src_buf_left -= num_bytes_to_process; + lookahead_size += num_bytes_to_process; + + while (num_bytes_to_process) + { + mz_uint32 n = MZ_MIN(TDEFL_LZ_DICT_SIZE - dst_pos, num_bytes_to_process); + memcpy(d->m_dict + dst_pos, d->m_pSrc, n); + if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) + memcpy(d->m_dict + TDEFL_LZ_DICT_SIZE + dst_pos, d->m_pSrc, MZ_MIN(n, (TDEFL_MAX_MATCH_LEN - 1) - dst_pos)); + d->m_pSrc += n; + dst_pos = (dst_pos + n) & TDEFL_LZ_DICT_SIZE_MASK; + num_bytes_to_process -= n; + } + + dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - lookahead_size, dict_size); + if ((!d->m_flush) && (lookahead_size < TDEFL_COMP_FAST_LOOKAHEAD_SIZE)) break; + + while (lookahead_size >= 4) + { + mz_uint cur_match_dist, cur_match_len = 1; + mz_uint8 *pCur_dict = d->m_dict + cur_pos; + mz_uint first_trigram = (*(const mz_uint32 *)pCur_dict) & 0xFFFFFF; + mz_uint hash = (first_trigram ^ (first_trigram >> (24 - (TDEFL_LZ_HASH_BITS - 8)))) & TDEFL_LEVEL1_HASH_SIZE_MASK; + mz_uint probe_pos = d->m_hash[hash]; + d->m_hash[hash] = (mz_uint16)lookahead_pos; + + if (((cur_match_dist = (mz_uint16)(lookahead_pos - probe_pos)) <= dict_size) && ((*(const mz_uint32 *)(d->m_dict + (probe_pos &= TDEFL_LZ_DICT_SIZE_MASK)) & 0xFFFFFF) == first_trigram)) + { + const mz_uint16 *p = (const mz_uint16 *)pCur_dict; + const mz_uint16 *q = (const mz_uint16 *)(d->m_dict + probe_pos); + mz_uint32 probe_len = 32; + do { } while ( (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && + (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (--probe_len > 0) ); + cur_match_len = ((mz_uint)(p - (const mz_uint16 *)pCur_dict) * 2) + (mz_uint)(*(const mz_uint8 *)p == *(const mz_uint8 *)q); + if (!probe_len) + cur_match_len = cur_match_dist ? TDEFL_MAX_MATCH_LEN : 0; + + if ((cur_match_len < TDEFL_MIN_MATCH_LEN) || ((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U*1024U))) + { + cur_match_len = 1; + *pLZ_code_buf++ = (mz_uint8)first_trigram; + *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1); + d->m_huff_count[0][(mz_uint8)first_trigram]++; + } + else + { + mz_uint32 s0, s1; + cur_match_len = MZ_MIN(cur_match_len, lookahead_size); + + MZ_ASSERT((cur_match_len >= TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 1) && (cur_match_dist <= TDEFL_LZ_DICT_SIZE)); + + cur_match_dist--; + + pLZ_code_buf[0] = (mz_uint8)(cur_match_len - TDEFL_MIN_MATCH_LEN); + *(mz_uint16 *)(&pLZ_code_buf[1]) = (mz_uint16)cur_match_dist; + pLZ_code_buf += 3; + *pLZ_flags = (mz_uint8)((*pLZ_flags >> 1) | 0x80); + + s0 = s_tdefl_small_dist_sym[cur_match_dist & 511]; + s1 = s_tdefl_large_dist_sym[cur_match_dist >> 8]; + d->m_huff_count[1][(cur_match_dist < 512) ? s0 : s1]++; + + d->m_huff_count[0][s_tdefl_len_sym[cur_match_len - TDEFL_MIN_MATCH_LEN]]++; + } + } + else + { + *pLZ_code_buf++ = (mz_uint8)first_trigram; + *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1); + d->m_huff_count[0][(mz_uint8)first_trigram]++; + } + + if (--num_flags_left == 0) { num_flags_left = 8; pLZ_flags = pLZ_code_buf++; } + + total_lz_bytes += cur_match_len; + lookahead_pos += cur_match_len; + dict_size = MZ_MIN(dict_size + cur_match_len, TDEFL_LZ_DICT_SIZE); + cur_pos = (cur_pos + cur_match_len) & TDEFL_LZ_DICT_SIZE_MASK; + MZ_ASSERT(lookahead_size >= cur_match_len); + lookahead_size -= cur_match_len; + + if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) + { + int n; + d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size; + d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left; + if ((n = tdefl_flush_block(d, 0)) != 0) + return (n < 0) ? MZ_FALSE : MZ_TRUE; + total_lz_bytes = d->m_total_lz_bytes; pLZ_code_buf = d->m_pLZ_code_buf; pLZ_flags = d->m_pLZ_flags; num_flags_left = d->m_num_flags_left; + } + } + + while (lookahead_size) + { + mz_uint8 lit = d->m_dict[cur_pos]; + + total_lz_bytes++; + *pLZ_code_buf++ = lit; + *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1); + if (--num_flags_left == 0) { num_flags_left = 8; pLZ_flags = pLZ_code_buf++; } + + d->m_huff_count[0][lit]++; + + lookahead_pos++; + dict_size = MZ_MIN(dict_size + 1, TDEFL_LZ_DICT_SIZE); + cur_pos = (cur_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK; + lookahead_size--; + + if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) + { + int n; + d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size; + d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left; + if ((n = tdefl_flush_block(d, 0)) != 0) + return (n < 0) ? MZ_FALSE : MZ_TRUE; + total_lz_bytes = d->m_total_lz_bytes; pLZ_code_buf = d->m_pLZ_code_buf; pLZ_flags = d->m_pLZ_flags; num_flags_left = d->m_num_flags_left; + } + } + } + + d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size; + d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left; + return MZ_TRUE; +} +#pragma GCC diagnostic pop +#endif // MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN + +static __forceinline void tdefl_record_literal(tdefl_compressor *d, mz_uint8 lit) +{ + d->m_total_lz_bytes++; + *d->m_pLZ_code_buf++ = lit; + *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> 1); if (--d->m_num_flags_left == 0) { d->m_num_flags_left = 8; d->m_pLZ_flags = d->m_pLZ_code_buf++; } + d->m_huff_count[0][lit]++; +} + +static __forceinline void tdefl_record_match(tdefl_compressor *d, mz_uint match_len, mz_uint match_dist) +{ + mz_uint32 s0, s1; + + MZ_ASSERT((match_len >= TDEFL_MIN_MATCH_LEN) && (match_dist >= 1) && (match_dist <= TDEFL_LZ_DICT_SIZE)); + + d->m_total_lz_bytes += match_len; + + d->m_pLZ_code_buf[0] = (mz_uint8)(match_len - TDEFL_MIN_MATCH_LEN); + + match_dist -= 1; + d->m_pLZ_code_buf[1] = (mz_uint8)(match_dist & 0xFF); + d->m_pLZ_code_buf[2] = (mz_uint8)(match_dist >> 8); d->m_pLZ_code_buf += 3; + + *d->m_pLZ_flags = (mz_uint8)((*d->m_pLZ_flags >> 1) | 0x80); if (--d->m_num_flags_left == 0) { d->m_num_flags_left = 8; d->m_pLZ_flags = d->m_pLZ_code_buf++; } + + s0 = s_tdefl_small_dist_sym[match_dist & 511]; s1 = s_tdefl_large_dist_sym[match_dist >> 8]; + d->m_huff_count[1][(match_dist < 512) ? s0 : s1]++; + + d->m_huff_count[0][s_tdefl_len_sym[match_len - TDEFL_MIN_MATCH_LEN]]++; +} + +static mz_bool tdefl_compress_normal(tdefl_compressor *d) +{ + const mz_uint8 *pSrc = d->m_pSrc; size_t src_buf_left = d->m_src_buf_left; + tdefl_flush flush = d->m_flush; + + while ((src_buf_left) || ((flush) && (d->m_lookahead_size))) + { + mz_uint len_to_move, cur_match_dist, cur_match_len, cur_pos; + // Update dictionary and hash chains. Keeps the lookahead size equal to TDEFL_MAX_MATCH_LEN. + if ((d->m_lookahead_size + d->m_dict_size) >= (TDEFL_MIN_MATCH_LEN - 1)) + { + mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK, ins_pos = d->m_lookahead_pos + d->m_lookahead_size - 2; + mz_uint hash = (d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK]; + mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(src_buf_left, TDEFL_MAX_MATCH_LEN - d->m_lookahead_size); + const mz_uint8 *pSrc_end = pSrc + num_bytes_to_process; + src_buf_left -= num_bytes_to_process; + d->m_lookahead_size += num_bytes_to_process; + while (pSrc != pSrc_end) + { + mz_uint8 c = *pSrc++; d->m_dict[dst_pos] = c; if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c; + hash = ((hash << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1); + d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash]; d->m_hash[hash] = (mz_uint16)(ins_pos); + dst_pos = (dst_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK; ins_pos++; + } + } + else + { + while ((src_buf_left) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN)) + { + mz_uint8 c = *pSrc++; + mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK; + src_buf_left--; + d->m_dict[dst_pos] = c; + if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) + d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c; + if ((++d->m_lookahead_size + d->m_dict_size) >= TDEFL_MIN_MATCH_LEN) + { + mz_uint ins_pos = d->m_lookahead_pos + (d->m_lookahead_size - 1) - 2; + mz_uint hash = ((d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << (TDEFL_LZ_HASH_SHIFT * 2)) ^ (d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1); + d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash]; d->m_hash[hash] = (mz_uint16)(ins_pos); + } + } + } + d->m_dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - d->m_lookahead_size, d->m_dict_size); + if ((!flush) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN)) + break; + + // Simple lazy/greedy parsing state machine. + len_to_move = 1; cur_match_dist = 0; cur_match_len = d->m_saved_match_len ? d->m_saved_match_len : (TDEFL_MIN_MATCH_LEN - 1); cur_pos = d->m_lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK; + if (d->m_flags & (TDEFL_RLE_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS)) + { + if ((d->m_dict_size) && (!(d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS))) + { + mz_uint8 c = d->m_dict[(cur_pos - 1) & TDEFL_LZ_DICT_SIZE_MASK]; + cur_match_len = 0; while (cur_match_len < d->m_lookahead_size) { if (d->m_dict[cur_pos + cur_match_len] != c) break; cur_match_len++; } + if (cur_match_len < TDEFL_MIN_MATCH_LEN) cur_match_len = 0; else cur_match_dist = 1; + } + } + else + { + tdefl_find_match(d, d->m_lookahead_pos, d->m_dict_size, d->m_lookahead_size, &cur_match_dist, &cur_match_len); + } + if (((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U*1024U)) || (cur_pos == cur_match_dist) || ((d->m_flags & TDEFL_FILTER_MATCHES) && (cur_match_len <= 5))) + { + cur_match_dist = cur_match_len = 0; + } + if (d->m_saved_match_len) + { + if (cur_match_len > d->m_saved_match_len) + { + tdefl_record_literal(d, (mz_uint8)d->m_saved_lit); + if (cur_match_len >= 128) + { + tdefl_record_match(d, cur_match_len, cur_match_dist); + d->m_saved_match_len = 0; len_to_move = cur_match_len; + } + else + { + d->m_saved_lit = d->m_dict[cur_pos]; d->m_saved_match_dist = cur_match_dist; d->m_saved_match_len = cur_match_len; + } + } + else + { + tdefl_record_match(d, d->m_saved_match_len, d->m_saved_match_dist); + len_to_move = d->m_saved_match_len - 1; d->m_saved_match_len = 0; + } + } + else if (!cur_match_dist) + tdefl_record_literal(d, d->m_dict[cur_pos]); + else if ((d->m_greedy_parsing) || (d->m_flags & TDEFL_RLE_MATCHES) || (cur_match_len >= 128)) + { + tdefl_record_match(d, cur_match_len, cur_match_dist); + len_to_move = cur_match_len; + } + else + { + d->m_saved_lit = d->m_dict[cur_pos]; d->m_saved_match_dist = cur_match_dist; d->m_saved_match_len = cur_match_len; + } + // Move the lookahead forward by len_to_move bytes. + d->m_lookahead_pos += len_to_move; + MZ_ASSERT(d->m_lookahead_size >= len_to_move); + d->m_lookahead_size -= len_to_move; + d->m_dict_size = MZ_MIN(d->m_dict_size + len_to_move, TDEFL_LZ_DICT_SIZE); + // Check if it's time to flush the current LZ codes to the internal output buffer. + if ( (d->m_pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) || + ( (d->m_total_lz_bytes > 31*1024) && (((((mz_uint)(d->m_pLZ_code_buf - d->m_lz_code_buf) * 115) >> 7) >= d->m_total_lz_bytes) || (d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS))) ) + { + int n; + d->m_pSrc = pSrc; d->m_src_buf_left = src_buf_left; + if ((n = tdefl_flush_block(d, 0)) != 0) + return (n < 0) ? MZ_FALSE : MZ_TRUE; + } + } + + d->m_pSrc = pSrc; d->m_src_buf_left = src_buf_left; + return MZ_TRUE; +} + +static tdefl_status tdefl_flush_output_buffer(tdefl_compressor *d) +{ + if (d->m_pIn_buf_size) + { + *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf; + } + + if (d->m_pOut_buf_size) + { + size_t n = MZ_MIN(*d->m_pOut_buf_size - d->m_out_buf_ofs, d->m_output_flush_remaining); + memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf + d->m_output_flush_ofs, n); + d->m_output_flush_ofs += (mz_uint)n; + d->m_output_flush_remaining -= (mz_uint)n; + d->m_out_buf_ofs += n; + + *d->m_pOut_buf_size = d->m_out_buf_ofs; + } + + return (d->m_finished && !d->m_output_flush_remaining) ? TDEFL_STATUS_DONE : TDEFL_STATUS_OKAY; +} + +tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush) +{ + if (!d) + { + if (pIn_buf_size) *pIn_buf_size = 0; + if (pOut_buf_size) *pOut_buf_size = 0; + return TDEFL_STATUS_BAD_PARAM; + } + + d->m_pIn_buf = pIn_buf; d->m_pIn_buf_size = pIn_buf_size; + d->m_pOut_buf = pOut_buf; d->m_pOut_buf_size = pOut_buf_size; + d->m_pSrc = (const mz_uint8 *)(pIn_buf); d->m_src_buf_left = pIn_buf_size ? *pIn_buf_size : 0; + d->m_out_buf_ofs = 0; + d->m_flush = flush; + + if ( ((d->m_pPut_buf_func != NULL) == ((pOut_buf != NULL) || (pOut_buf_size != NULL))) || (d->m_prev_return_status != TDEFL_STATUS_OKAY) || + (d->m_wants_to_finish && (flush != TDEFL_FINISH)) || (pIn_buf_size && *pIn_buf_size && !pIn_buf) || (pOut_buf_size && *pOut_buf_size && !pOut_buf) ) + { + if (pIn_buf_size) *pIn_buf_size = 0; + if (pOut_buf_size) *pOut_buf_size = 0; + return (d->m_prev_return_status = TDEFL_STATUS_BAD_PARAM); + } + d->m_wants_to_finish |= (flush == TDEFL_FINISH); + + if ((d->m_output_flush_remaining) || (d->m_finished)) + return (d->m_prev_return_status = tdefl_flush_output_buffer(d)); + +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN + if (((d->m_flags & TDEFL_MAX_PROBES_MASK) == 1) && + ((d->m_flags & TDEFL_GREEDY_PARSING_FLAG) != 0) && + ((d->m_flags & (TDEFL_FILTER_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS | TDEFL_RLE_MATCHES)) == 0)) + { + if (!tdefl_compress_fast(d)) + return d->m_prev_return_status; + } + else +#endif // #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN + { + if (!tdefl_compress_normal(d)) + return d->m_prev_return_status; + } + + if ((d->m_flags & (TDEFL_WRITE_ZLIB_HEADER | TDEFL_COMPUTE_ADLER32)) && (pIn_buf)) + d->m_adler32 = (mz_uint32)mz_adler32(d->m_adler32, (const mz_uint8 *)pIn_buf, d->m_pSrc - (const mz_uint8 *)pIn_buf); + + if (d->m_flags & TDEFL_COMPUTE_CRC32) + d->m_crc32 = (mz_uint32)mz_crc32(d->m_crc32, (const mz_uint8 *)pIn_buf, d->m_pSrc - (const mz_uint8 *)pIn_buf); + + if ((flush) && (!d->m_lookahead_size) && (!d->m_src_buf_left) && (!d->m_output_flush_remaining)) + { + if (tdefl_flush_block(d, flush) < 0) + return d->m_prev_return_status; + d->m_finished = (flush == TDEFL_FINISH); + if (flush == TDEFL_FULL_FLUSH) { MZ_CLEAR_OBJ(d->m_hash); MZ_CLEAR_OBJ(d->m_next); d->m_dict_size = 0; } + } + + return (d->m_prev_return_status = tdefl_flush_output_buffer(d)); +} + +tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush) +{ + MZ_ASSERT(d->m_pPut_buf_func); return tdefl_compress(d, pIn_buf, &in_buf_size, NULL, NULL, flush); +} + +tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags) +{ + d->m_pPut_buf_func = pPut_buf_func; d->m_pPut_buf_user = pPut_buf_user; + d->m_flags = (mz_uint)(flags); d->m_max_probes[0] = 1 + ((flags & 0xFFF) + 2) / 3; d->m_greedy_parsing = (flags & TDEFL_GREEDY_PARSING_FLAG) != 0; + d->m_max_probes[1] = 1 + (((flags & 0xFFF) >> 2) + 2) / 3; + if (!(flags & TDEFL_NONDETERMINISTIC_PARSING_FLAG)) MZ_CLEAR_OBJ(d->m_hash); + d->m_lookahead_pos = d->m_lookahead_size = d->m_dict_size = d->m_total_lz_bytes = d->m_lz_code_buf_dict_pos = d->m_bits_in = 0; + d->m_output_flush_ofs = d->m_output_flush_remaining = d->m_finished = d->m_block_index = d->m_bit_buffer = d->m_wants_to_finish = 0; + d->m_pLZ_code_buf = d->m_lz_code_buf + 1; d->m_pLZ_flags = d->m_lz_code_buf; d->m_num_flags_left = 8; + d->m_pOutput_buf = d->m_output_buf; d->m_pOutput_buf_end = d->m_output_buf; d->m_prev_return_status = TDEFL_STATUS_OKAY; + d->m_saved_match_dist = d->m_saved_match_len = d->m_saved_lit = 0; d->m_adler32 = 1; d->m_crc32 = 1; + d->m_pIn_buf = NULL; d->m_pOut_buf = NULL; + d->m_pIn_buf_size = NULL; d->m_pOut_buf_size = NULL; + d->m_flush = TDEFL_NO_FLUSH; d->m_pSrc = NULL; d->m_src_buf_left = 0; d->m_out_buf_ofs = 0; + memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0); + memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1); + return TDEFL_STATUS_OKAY; +} + +tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d) +{ + return d->m_prev_return_status; +} + +mz_uint32 tdefl_get_adler32(tdefl_compressor *d) +{ + return d->m_adler32; +} + +mz_uint32 tdefl_get_crc32(tdefl_compressor *d) +{ + return d->m_crc32; +} + +mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags) +{ + tdefl_compressor *pComp; mz_bool succeeded; if (((buf_len) && (!pBuf)) || (!pPut_buf_func)) return MZ_FALSE; + pComp = (tdefl_compressor*)MZ_MALLOC(sizeof(tdefl_compressor)); if (!pComp) return MZ_FALSE; + succeeded = (tdefl_init(pComp, pPut_buf_func, pPut_buf_user, flags) == TDEFL_STATUS_OKAY); + succeeded = succeeded && (tdefl_compress_buffer(pComp, pBuf, buf_len, TDEFL_FINISH) == TDEFL_STATUS_DONE); + MZ_FREE(pComp); return succeeded; +} + +typedef struct +{ + size_t m_size, m_capacity; + mz_uint8 *m_pBuf; + mz_bool m_expandable; +} tdefl_output_buffer; + +static mz_bool tdefl_output_buffer_putter(const void *pBuf, int len, void *pUser) +{ + tdefl_output_buffer *p = (tdefl_output_buffer *)pUser; + size_t new_size = p->m_size + len; + if (new_size > p->m_capacity) + { + size_t new_capacity = p->m_capacity; mz_uint8 *pNew_buf; if (!p->m_expandable) return MZ_FALSE; + do { new_capacity = MZ_MAX(128U, new_capacity << 1U); } while (new_size > new_capacity); + pNew_buf = (mz_uint8*)MZ_REALLOC(p->m_pBuf, new_capacity); if (!pNew_buf) return MZ_FALSE; + p->m_pBuf = pNew_buf; p->m_capacity = new_capacity; + } + memcpy((mz_uint8*)p->m_pBuf + p->m_size, pBuf, len); p->m_size = new_size; + return MZ_TRUE; +} + +void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags) +{ + tdefl_output_buffer out_buf; MZ_CLEAR_OBJ(out_buf); + if (!pOut_len) return MZ_FALSE; else *pOut_len = 0; + out_buf.m_expandable = MZ_TRUE; + if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags)) return NULL; + *pOut_len = out_buf.m_size; return out_buf.m_pBuf; +} + +size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags) +{ + tdefl_output_buffer out_buf; MZ_CLEAR_OBJ(out_buf); + if (!pOut_buf) return 0; + out_buf.m_pBuf = (mz_uint8*)pOut_buf; out_buf.m_capacity = out_buf_len; + if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags)) return 0; + return out_buf.m_size; +} + +static const mz_uint s_tdefl_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 }; + +// level may actually range from [0,10] (10 is a "hidden" max level, where we want a bit more compression and it's fine if throughput to fall off a cliff on some files). +mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy) +{ + mz_uint comp_flags = s_tdefl_num_probes[(level >= 0) ? MZ_MIN(10, level) : MZ_DEFAULT_LEVEL] | ((level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0); + if (window_bits > 0) comp_flags |= TDEFL_WRITE_ZLIB_HEADER; + + if (!level) comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS; + else if (strategy == MZ_FILTERED) comp_flags |= TDEFL_FILTER_MATCHES; + else if (strategy == MZ_HUFFMAN_ONLY) comp_flags &= ~TDEFL_MAX_PROBES_MASK; + else if (strategy == MZ_FIXED) comp_flags |= TDEFL_FORCE_ALL_STATIC_BLOCKS; + else if (strategy == MZ_RLE) comp_flags |= TDEFL_RLE_MATCHES; + + return comp_flags; +} + +#ifdef _MSC_VER +#pragma warning (push) +#pragma warning (disable:4204) // nonstandard extension used : non-constant aggregate initializer (also supported by GNU C and C99, so no big deal) +#endif + +// Simple PNG writer function by Alex Evans, 2011. Released into the public domain: https://gist.github.com/908299, more context at +// http://altdevblogaday.org/2011/04/06/a-smaller-jpg-encoder/. +void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out) +{ + tdefl_compressor *pComp = (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor)); tdefl_output_buffer out_buf; int i, bpl = w * num_chans, y, z; mz_uint32 c; *pLen_out = 0; + if (!pComp) return NULL; + MZ_CLEAR_OBJ(out_buf); out_buf.m_expandable = MZ_TRUE; out_buf.m_capacity = 57+MZ_MAX(64, (1+bpl)*h); if (NULL == (out_buf.m_pBuf = (mz_uint8*)MZ_MALLOC(out_buf.m_capacity))) { MZ_FREE(pComp); return NULL; } + // write dummy header + for (z = 41; z; --z) tdefl_output_buffer_putter(&z, 1, &out_buf); + // compress image data + tdefl_init(pComp, tdefl_output_buffer_putter, &out_buf, TDEFL_DEFAULT_MAX_PROBES | TDEFL_WRITE_ZLIB_HEADER); + for (y = 0; y < h; ++y) { tdefl_compress_buffer(pComp, &z, 1, TDEFL_NO_FLUSH); tdefl_compress_buffer(pComp, (mz_uint8*)pImage + y * bpl, bpl, TDEFL_NO_FLUSH); } + if (tdefl_compress_buffer(pComp, NULL, 0, TDEFL_FINISH) != TDEFL_STATUS_DONE) { MZ_FREE(pComp); MZ_FREE(out_buf.m_pBuf); return NULL; } + // write real header + *pLen_out = out_buf.m_size-41; + { + mz_uint8 pnghdr[41]={0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52, + 0,0,(mz_uint8)(w>>8),(mz_uint8)w,0,0,(mz_uint8)(h>>8),(mz_uint8)h,8,"\0\0\04\02\06"[num_chans],0,0,0,0,0,0,0, + (mz_uint8)(*pLen_out>>24),(mz_uint8)(*pLen_out>>16),(mz_uint8)(*pLen_out>>8),(mz_uint8)*pLen_out,0x49,0x44,0x41,0x54}; + c=(mz_uint32)mz_crc32(MZ_CRC32_INIT,pnghdr+12,17); for (i=0; i<4; ++i, c<<=8) ((mz_uint8*)(pnghdr+29))[i]=(mz_uint8)(c>>24); + memcpy(out_buf.m_pBuf, pnghdr, 41); + } + // write footer (IDAT CRC-32, followed by IEND chunk) + if (!tdefl_output_buffer_putter("\0\0\0\0\0\0\0\0\x49\x45\x4e\x44\xae\x42\x60\x82", 16, &out_buf)) { *pLen_out = 0; MZ_FREE(pComp); MZ_FREE(out_buf.m_pBuf); return NULL; } + c = (mz_uint32)mz_crc32(MZ_CRC32_INIT,out_buf.m_pBuf+41-4, *pLen_out+4); for (i=0; i<4; ++i, c<<=8) (out_buf.m_pBuf+out_buf.m_size-16)[i] = (mz_uint8)(c >> 24); + // compute final size of file, grab compressed data buffer and return + *pLen_out += 57; MZ_FREE(pComp); return out_buf.m_pBuf; +} + +#ifdef _MSC_VER +#pragma warning (pop) +#endif + +#pragma GCC diagnostic pop + +#endif // MINIZ_HEADER_FILE_ONLY + +/* + This is free and unencumbered software released into the public domain. + + Anyone is free to copy, modify, publish, use, compile, sell, or + distribute this software, either in source code form or as a compiled + binary, for any purpose, commercial or non-commercial, and by any + means. + + In jurisdictions that recognize copyright laws, the author or authors + of this software dedicate any and all copyright interest in the + software to the public domain. We make this dedication for the benefit + of the public at large and to the detriment of our heirs and + successors. We intend this dedication to be an overt act of + relinquishment in perpetuity of all present and future rights to this + software under copyright law. + + 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 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. + + For more information, please refer to +*/ diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/miniz.h b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/miniz.h new file mode 100644 index 0000000..971d34e --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/miniz.h @@ -0,0 +1,2 @@ +#define MINIZ_HEADER_FILE_ONLY +#include "miniz.c" diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c new file mode 100644 index 0000000..f48c68d --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c @@ -0,0 +1,650 @@ +/****************************************************************************** + * ventoy.c + * + * Copyright (c) 2020, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef GRUB_MACHINE_EFI +#include +#include +#endif +#include +#include "ventoy_def.h" + +GRUB_MOD_LICENSE ("GPLv3+"); + +int g_ventoy_debug = 0; +static int g_efi_os = 0xFF; +grub_uint32_t g_ventoy_plat_data; + +#ifdef GRUB_MACHINE_EFI +static VTOY_SHIM *g_vtoy_shim = NULL; +#endif + +void ventoy_debug(const char *fmt, ...) +{ + va_list args; + + va_start (args, fmt); + grub_vprintf (fmt, args); + va_end (args); +} + +void ventoy_str_tolower(char *str) +{ + while (*str) + { + *str = grub_tolower(*str); + str++; + } +} + +void ventoy_str_toupper(char *str) +{ + while (*str) + { + *str = grub_toupper(*str); + str++; + } +} + +char *ventoy_str_last(char *str, char ch) +{ + char *pos = NULL; + char *last = NULL; + + if (!str) + { + return NULL; + } + + for (pos = str; *pos; pos++) + { + if (*pos == ch) + { + last = pos; + } + } + + return last; +} + +int ventoy_str_all_digit(const char *str) +{ + if (NULL == str || 0 == *str) + { + return 0; + } + + while (*str) + { + if (*str < '0' || *str > '9') + { + return 0; + } + } + + return 1; +} + +int ventoy_str_all_alnum(const char *str) +{ + if (NULL == str || 0 == *str) + { + return 0; + } + + while (*str) + { + if (!grub_isalnum(*str)) + { + return 0; + } + } + + return 1; +} + +int ventoy_str_len_alnum(const char *str, int len) +{ + int i; + int slen; + + if (NULL == str || 0 == *str) + { + return 0; + } + + slen = grub_strlen(str); + if (slen <= len) + { + return 0; + } + + for (i = 0; i < len; i++) + { + if (!grub_isalnum(str[i])) + { + return 0; + } + } + + if (str[len] == 0 || grub_isspace(str[len])) + { + return 1; + } + + return 0; +} + +char * ventoy_str_basename(char *path) +{ + char *pos = NULL; + + pos = grub_strrchr(path, '/'); + if (pos) + { + pos++; + } + else + { + pos = path; + } + + return pos; +} + +int ventoy_str_chrcnt(const char *str, char c) +{ + int n = 0; + + if (str) + { + while (*str) + { + if (*str == c) + { + n++; + } + str++; + } + } + + return n; +} + +int ventoy_strcmp(const char *pattern, const char *str) +{ + while (*pattern && *str) + { + if ((*pattern != *str) && (*pattern != '*')) + break; + + pattern++; + str++; + } + + return (int)(grub_uint8_t)*pattern - (int)(grub_uint8_t)*str; +} + +int ventoy_strncmp (const char *pattern, const char *str, grub_size_t n) +{ + if (n == 0) + return 0; + + while (*pattern && *str && --n) + { + if ((*pattern != *str) && (*pattern != '*')) + break; + + pattern++; + str++; + } + + return (int)(grub_uint8_t)*pattern - (int)(grub_uint8_t)*str; +} + +grub_err_t ventoy_env_int_set(const char *name, int value) +{ + char buf[16]; + + grub_snprintf(buf, sizeof(buf), "%d", value); + return grub_env_set(name, buf); +} + +void ventoy_debug_dump_guid(const char *prefix, grub_uint8_t *guid) +{ + int i; + + if (!g_ventoy_debug) + { + return; + } + + debug("%s", prefix); + for (i = 0; i < 16; i++) + { + grub_printf("%02x ", guid[i]); + } + grub_printf("\n"); +} + +int ventoy_is_efi_os(void) +{ + if (g_efi_os > 1) + { + g_efi_os = (grub_strstr(GRUB_PLATFORM, "efi")) ? 1 : 0; + } + + return g_efi_os; +} + +void * ventoy_alloc_chain(grub_size_t size) +{ + void *p = NULL; + + p = grub_malloc(size); +#ifdef GRUB_MACHINE_EFI + if (!p) + { + p = grub_efi_allocate_any_pages(GRUB_EFI_BYTES_TO_PAGES(size)); + } +#endif + + return p; +} + +void ventoy_memfile_env_set(const char *prefix, const void *buf, unsigned long long len) +{ + char name[128]; + char val[64]; + + grub_snprintf(name, sizeof(name), "%s_addr", prefix); + grub_snprintf(val, sizeof(val), "0x%llx", (ulonglong)(ulong)buf); + grub_env_set(name, val); + + grub_snprintf(name, sizeof(name), "%s_size", prefix); + grub_snprintf(val, sizeof(val), "%llu", len); + grub_env_set(name, val); + + return; +} + +#ifdef GRUB_MACHINE_EFI +static void ventoy_get_uefi_version(char *str, grub_size_t len) +{ + grub_efi_uint8_t uefi_minor_1, uefi_minor_2; + + uefi_minor_1 = (grub_efi_system_table->hdr.revision & 0xffff) / 10; + uefi_minor_2 = (grub_efi_system_table->hdr.revision & 0xffff) % 10; + grub_snprintf(str, len, "%d.%d", (grub_efi_system_table->hdr.revision >> 16), uefi_minor_1); + if (uefi_minor_2) + grub_snprintf(str, len, "%s.%d", str, uefi_minor_2); +} + +static void ventoy_get_pi_version(char *str, grub_size_t len) +{ + grub_uint32_t data = 0; + grub_efi_uintn_t i = 0; + grub_efi_guid_t dxest = + { 0x05ad34ba, 0x6f02, 0x4214, {0x95, 0x2e, 0x4d, 0xa0, 0x39, 0x8e, 0x2b, 0xb9 } }; + + for (i = 0; i < grub_efi_system_table->num_table_entries; i++) + { + if (grub_memcmp(&dxest, &grub_efi_system_table->configuration_table[i].vendor_guid, 16) == 0) + { + grub_memcpy(&data, (char *)grub_efi_system_table->configuration_table[i].vendor_table + 8, 4); + break; + } + } + + grub_snprintf(str, len, "%d.%d", (data >> 16) & 0xFFFF, (data & 0xFFFF) / 10); +} + +int ventoy_set_sb_policy(void) +{ + const char *env = NULL; + static int set_once = 0; + + /* no need when SecureBoot is disabled */ + if (g_sys_sb == 0) + { + return 0; + } + + /* can only set once */ + if (set_once > 0) + { + return 0; + } + set_once = 1; + + /* VTOY_SECURE_BOOT_POLICY only take affect once during init */ + env = grub_env_get("VTOY_SECURE_BOOT_POLICY"); + if (env) + { + g_sb_policy = (grub_uint8_t)(env[0] - '0'); + } + + if (g_sb_policy == VTOY_SB_POLICY_BYPASS) + { + if (g_vtoy_shim && g_vtoy_shim->ByPassSB) + { + g_vtoy_shim->ByPassSB(); + } + } + else if (g_sb_policy == VTOY_SB_POLICY_CHECK) + { + if (g_vtoy_shim && g_vtoy_shim->CheckSB) + { + g_vtoy_shim->CheckSB(); + } + } + + return 0; +} + +static void ventoy_get_uefi_sb(void) +{ + grub_uint8_t secure_boot = 0; + grub_uint8_t setup_mode = 0; + grub_uint8_t *var = NULL; + grub_size_t size = 0; + grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; + + var = grub_efi_get_variable("SecureBoot", &global, &size); + if (var && size == 1 && *var == 1) + { + secure_boot = 1; + } + grub_check_free(var); + + size = 0; + var = grub_efi_get_variable("SetupMode", &global, &size); + if (var && size == 1 && *var == 1) + { + setup_mode = 1; + } + + if (secure_boot == 1 && setup_mode == 0) + { + g_sys_sb = 1; + } + + grub_check_free(var); +} + +static int ventoy_secure_boot_init(void) +{ + grub_efi_guid_t ProtGuid = VTOY_SHIM_POLICY_GUID; + + ventoy_get_uefi_sb(); + + if (g_sys_sb == 0) + { + return 0; + } + + + if (g_ventoy_plat_data == VTOY_PLAT_X86_64_UEFI) + { + g_vtoy_shim = grub_efi_locate_protocol(&ProtGuid, NULL); + if (g_vtoy_shim == NULL || g_vtoy_shim->ByPassSB == NULL || + g_vtoy_shim->CheckSB == NULL || g_vtoy_shim->Launched == NULL) + { + /* + * Generally when SecureBoot enabled, Ventoy grub must be launched by Ventoy Shim. + * But there are some exceptions: + * 1. Ventoy key was enrolled directly to the UEFI DB + * 2. Some UEFI firmware (MSI) has Image Execution Policy as Always Execute which + * means Secure Boot is effectively disabled. + */ + } + else + { + g_vtoy_shim->Launched(); + } + } + + return 0; +} + + +#endif + +static int ventoy_arch_mode_init(void) +{ + #ifdef GRUB_MACHINE_EFI + + if (grub_strcmp(GRUB_TARGET_CPU, "i386") == 0) + { + g_ventoy_plat_data = VTOY_PLAT_I386_UEFI; + grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "ia32"); + } + else if (grub_strcmp(GRUB_TARGET_CPU, "arm64") == 0) + { + g_ventoy_plat_data = VTOY_PLAT_ARM64_UEFI; + grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "aa64"); + } + else if (grub_strcmp(GRUB_TARGET_CPU, "mips64el") == 0) + { + g_ventoy_plat_data = VTOY_PLAT_MIPS_UEFI; + grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "mips"); + } + else + { + g_ventoy_plat_data = VTOY_PLAT_X86_64_UEFI; + grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "uefi"); + } +#else + g_ventoy_plat_data = VTOY_PLAT_X86_LEGACY; + grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "legacy"); +#endif + + return 0; +} + +static int ventoy_calc_totalmem(grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type, void *data) +{ + grub_uint64_t *total_mem = (grub_uint64_t *)data; + + (void)addr; + (void)type; + + *total_mem += size; + + return 0; +} + +static int ventoy_hwinfo_init(void) +{ + char str[256]; + grub_uint64_t total_mem = 0; + + grub_machine_mmap_iterate(ventoy_calc_totalmem, &total_mem); + + grub_snprintf(str, sizeof(str), "%ld", (long)(total_mem / VTOY_SIZE_1MB)); + ventoy_env_export("grub_total_ram", str); + +#ifdef GRUB_MACHINE_EFI + ventoy_get_uefi_version(str, sizeof(str)); + ventoy_env_export("grub_uefi_version", str); + + ventoy_get_pi_version(str, sizeof(str)); + ventoy_env_export("grub_pi_version", str); +#else + ventoy_env_export("grub_uefi_version", "NA"); + ventoy_env_export("grub_pi_version", "NA"); +#endif + + return 0; +} + +static global_var_cfg g_global_vars[] = +{ + { "gfxmode", "1024x768", NULL }, + { ventoy_left_key, "5%", NULL }, + { ventoy_top_key, "95%", NULL }, + { ventoy_color_key, "#0000ff", NULL }, + { NULL, NULL, NULL } +}; + +static const char * ventoy_global_var_read_hook(struct grub_env_var *var, const char *val) +{ + int i; + + for (i = 0; g_global_vars[i].name; i++) + { + if (grub_strcmp(g_global_vars[i].name, var->name) == 0) + { + return g_global_vars[i].value; + } + } + + return val; +} + +static char * ventoy_global_var_write_hook(struct grub_env_var *var, const char *val) +{ + int i; + + for (i = 0; g_global_vars[i].name; i++) + { + if (grub_strcmp(g_global_vars[i].name, var->name) == 0) + { + grub_check_free(g_global_vars[i].value); + g_global_vars[i].value = grub_strdup(val); + break; + } + } + + return grub_strdup(val); +} + +int ventoy_global_var_init(void) +{ + int i; + + for (i = 0; g_global_vars[i].name; i++) + { + g_global_vars[i].value = grub_strdup(g_global_vars[i].defval); + ventoy_env_export(g_global_vars[i].name, g_global_vars[i].defval); + grub_register_variable_hook(g_global_vars[i].name, ventoy_global_var_read_hook, ventoy_global_var_write_hook); + } + + return 0; +} + +static ctrl_var_cfg g_ctrl_vars[] = +{ + { "VTOY_WIN11_BYPASS_CHECK", "1" }, + { "VTOY_WIN11_BYPASS_NRO", "1" }, + { "VTOY_LINUX_REMOUNT", "0" }, + { "VTOY_SECONDARY_BOOT_MENU", "1" }, + { "VTOY_WIN_UEFI_RES_LOCK", "3" }, + { NULL, "" } +}; + +static const char * ventoy_ctrl_var_read_hook(struct grub_env_var *var, const char *val) +{ + int i; + + for (i = 0; g_ctrl_vars[i].name; i++) + { + if (grub_strcmp(g_ctrl_vars[i].name, var->name) == 0) + { + return g_ctrl_vars[i].szval; + } + } + + return val; +} + +static char * ventoy_ctrl_var_write_hook(struct grub_env_var *var, const char *val) +{ + int i; + + for (i = 0; g_ctrl_vars[i].name; i++) + { + if (grub_strcmp(g_ctrl_vars[i].name, var->name) == 0) + { + if (val && grub_isdigit(val[0]) && val[1] == 0) + { + g_ctrl_vars[i].szval[0] = val[0]; + return grub_strdup(val); + } + else + { + g_ctrl_vars[i].szval[0] = '0'; + return grub_strdup("0"); + } + } + } + + return grub_strdup(val); +} + +int ventoy_ctrl_var_init(void) +{ + ctrl_var_cfg *cfg = g_ctrl_vars; + + while (cfg->name) + { + ventoy_env_export(cfg->name, cfg->szval); + grub_register_variable_hook(cfg->name, ventoy_ctrl_var_read_hook, ventoy_ctrl_var_write_hook); + cfg++; + } + + return 0; +} + +GRUB_MOD_INIT(ventoy) +{ + ventoy_hwinfo_init(); + ventoy_env_init(); + ventoy_arch_mode_init(); + +#ifdef GRUB_MACHINE_EFI + ventoy_secure_boot_init(); +#endif + + ventoy_register_all_cmd(); +} + +GRUB_MOD_FINI(ventoy) +{ + ventoy_unregister_all_cmd(); +} + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_browser.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_browser.c new file mode 100644 index 0000000..6224a64 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_browser.c @@ -0,0 +1,652 @@ +/****************************************************************************** + * ventoy_browser.c + * + * Copyright (c) 2022, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ventoy_def.h" + +GRUB_MOD_LICENSE ("GPLv3+"); + +#define BROWSER_MENU_BUF 65536 + +static const char *g_vtoy_dev = NULL; +static grub_fs_t g_menu_fs = NULL; +static char *g_menu_device = NULL; +static grub_device_t g_menu_dev = NULL; +static char g_menu_path_buf[1024]; +static int g_menu_path_len = 0; +static browser_node *g_browser_list = NULL; + +static int ventoy_browser_strcmp(char *str1, char *str2) +{ + char *s1, *s2; + int c1 = 0; + int c2 = 0; + + for (s1 = str1, s2 = str2; *s1 && *s2; s1++, s2++) + { + c1 = *s1; + c2 = *s2; + + if (0 == g_sort_case_sensitive) + { + if (grub_islower(c1)) + { + c1 = c1 - 'a' + 'A'; + } + + if (grub_islower(c2)) + { + c2 = c2 - 'a' + 'A'; + } + } + + if (c1 != c2) + { + break; + } + } + + return (c1 - c2); +} + +static int ventoy_browser_mbuf_alloc(browser_mbuf *mbuf) +{ + grub_memset(mbuf, 0, sizeof(browser_mbuf)); + mbuf->buf = grub_malloc(BROWSER_MENU_BUF); + if (!mbuf->buf) + { + return 0; + } + + mbuf->pos = 0; + mbuf->max = BROWSER_MENU_BUF; + return 1; +} + +static inline void ventoy_browser_mbuf_free(browser_mbuf *mbuf) +{ + if (mbuf) + grub_check_free(mbuf->buf) +} + +static inline int ventoy_browser_mbuf_extend(browser_mbuf *mbuf) +{ + if (mbuf->max - mbuf->pos <= VTOY_SIZE_1KB) + { + mbuf->max += BROWSER_MENU_BUF; + mbuf->buf = grub_realloc(mbuf->buf, mbuf->max); + } + + return 0; +} + +static browser_node * ventoy_browser_find_top_node(int dir) +{ + browser_node *node = NULL; + browser_node *sel = NULL; + + for (node = g_browser_list; node; node = node->next) + { + if (node->dir == dir) + { + if (sel) + { + if (ventoy_browser_strcmp(sel->filename, node->filename) > 0) + { + sel = node; + } + } + else + { + sel = node; + } + } + } + + return sel; +} + +static int ventoy_browser_iterate_partition(struct grub_disk *disk, const grub_partition_t partition, void *data) +{ + char partname[64]; + char title[256]; + grub_device_t dev; + grub_fs_t fs; + char *Label = NULL; + browser_mbuf *mbuf = (browser_mbuf *)data; + + (void)data; + + if (partition->number == 1 && g_vtoy_dev && grub_strcmp(disk->name, g_vtoy_dev) == 0) + { + return 0; + } + + grub_snprintf(partname, sizeof(partname) - 1, "%s,%d", disk->name, partition->number + 1); + + dev = grub_device_open(partname); + if (!dev) + { + return 0; + } + + fs = grub_fs_probe(dev); + if (!fs) + { + grub_device_close(dev); + return 0; + } + + fs->fs_label(dev, &Label); + + if (ventoy_check_file_exist("(%s)/.ventoyignore", partname)) + { + return 0; + } + + if (g_tree_view_menu_style == 0) + { + grub_snprintf(title, sizeof(title), "%-10s (%s,%s%d) [%s] %s %s", + "DISK", disk->name, partition->msdostype == 0xee ? "gpt" : "msdos", + partition->number + 1, (Label ? Label : ""), fs->name, + grub_get_human_size(partition->len << disk->log_sector_size, GRUB_HUMAN_SIZE_SHORT)); + } + else + { + grub_snprintf(title, sizeof(title), "(%s,%s%d) [%s] %s %s", + disk->name, partition->msdostype == 0xee ? "gpt" : "msdos", + partition->number + 1, (Label ? Label : ""), fs->name, + grub_get_human_size(partition->len << disk->log_sector_size, GRUB_HUMAN_SIZE_SHORT)); + } + + if (ventoy_get_fs_type(fs->name) >= ventoy_fs_max) + { + browser_ssprintf(mbuf, "menuentry \"%s\" --class=vtoydisk {\n" + " echo \"unsupported file system type!\" \n" + " ventoy_pause\n" + "}\n", + title); + } + else + { + browser_ssprintf(mbuf, "menuentry \"%s\" --class=vtoydisk {\n" + " vt_browser_dir %s,%d 0x%lx /\n" + "}\n", + title, disk->name, partition->number + 1, (ulong)fs); + } + + ventoy_browser_mbuf_extend(mbuf); + + return 0; +} + +static int ventoy_browser_iterate_disk(const char *name, void *data) +{ + grub_disk_t disk; + + if (name[0] != 'h') + { + return 0; + } + + disk = grub_disk_open(name); + if (disk) + { + grub_partition_iterate(disk, ventoy_browser_iterate_partition, data); + grub_disk_close(disk); + } + + return 0; +} + +static int ventoy_browser_valid_dirname(const char *name, int len) +{ + if ((len == 1 && name[0] == '.') || + (len == 2 && name[0] == '.' && name[1] == '.')) + { + return 0; + } + + if (!ventoy_img_name_valid(name, len)) + { + return 0; + } + + if (g_filt_trash_dir) + { + if (0 == grub_strncmp(name, ".trash-", 7) || + 0 == grub_strcmp(name, ".Trashes")) + { + return 0; + } + } + + if (name[0] == '$') + { + if (0 == grub_strncmp(name, "$RECYCLE.BIN", 12) || + 0 == grub_strncasecmp(name, "$Extend", 7)) + { + return 0; + } + } + + if (len == 25 && grub_strncmp(name, "System Volume Information", 25) == 0) + { + return 0; + } + + return 1; +} + +static int ventoy_browser_valid_filename(const char *filename, int len, int *type) +{ + if (len < 4) + { + return 0; + } + + if (FILE_FLT(ISO) && 0 == grub_strcasecmp(filename + len - 4, ".iso")) + { + *type = img_type_iso; + } + else if (FILE_FLT(WIM) && g_wimboot_enable && (0 == grub_strcasecmp(filename + len - 4, ".wim"))) + { + *type = img_type_wim; + } + else if (FILE_FLT(VHD) && g_vhdboot_enable && (0 == grub_strcasecmp(filename + len - 4, ".vhd") || + (len >= 5 && 0 == grub_strcasecmp(filename + len - 5, ".vhdx")))) + { + *type = img_type_vhd; + } + #ifdef GRUB_MACHINE_EFI + else if (FILE_FLT(EFI) && 0 == grub_strcasecmp(filename + len - 4, ".efi")) + { + *type = img_type_efi; + } + #endif + else if (FILE_FLT(IMG) && 0 == grub_strcasecmp(filename + len - 4, ".img")) + { + if (len == 18 && grub_strncmp(filename, "ventoy_", 7) == 0) + { + if (grub_strncmp(filename + 7, "wimboot", 7) == 0 || + grub_strncmp(filename + 7, "vhdboot", 7) == 0) + { + return 0; + } + } + *type = img_type_img; + } + else if (FILE_FLT(VTOY) && len >= 5 && 0 == grub_strcasecmp(filename + len - 5, ".vtoy")) + { + *type = img_type_vtoy; + } + else + { + return 0; + } + + if (g_filt_dot_underscore_file && filename[0] == '.' && filename[1] == '_') + { + return 0; + } + + return 1; +} + +static int ventoy_browser_check_ignore(const char *device, const char *root, const char *dir) +{ + grub_file_t file; + char fullpath[1024] = {0}; + + grub_snprintf(fullpath, 1023, "(%s)%s/%s/.ventoyignore", device, root, dir); + file = grub_file_open(fullpath, GRUB_FILE_TYPE_NONE); + if (!file) + { + grub_errno = 0; + return 0; + } + else + { + grub_file_close(file); + return 1; + } +} + +static int ventoy_browser_iterate_dir(const char *filename, const struct grub_dirhook_info *info, void *data) +{ + int type; + int len; + browser_node *node; + + (void)data; + + len = grub_strlen(filename); + + if (info->dir) + { + if (!ventoy_browser_valid_dirname(filename, len)) + { + return 0; + } + + if (ventoy_browser_check_ignore(g_menu_device, g_menu_path_buf, filename)) + { + return 0; + } + + node = grub_zalloc(sizeof(browser_node)); + if (!node) + { + return 0; + } + + node->dir = 1; + grub_strncpy(node->filename, filename, sizeof(node->filename)); + + if (g_tree_view_menu_style == 0) + { + grub_snprintf(node->menuentry, sizeof(node->menuentry), + "menuentry \"%-10s [%s]\" --class=vtoydir {\n" + " vt_browser_dir %s 0x%lx \"%s/%s\"\n" + "}\n", + "DIR", filename, g_menu_device, (ulong)g_menu_fs, g_menu_path_buf, filename); + } + else + { + grub_snprintf(node->menuentry, sizeof(node->menuentry), + "menuentry \"[%s]\" --class=vtoydir {\n" + " vt_browser_dir %s 0x%lx \"%s/%s\"\n" + "}\n", + filename, g_menu_device, (ulong)g_menu_fs, g_menu_path_buf, filename); + } + } + else + { + grub_uint64_t fsize = info->size; + + if (!ventoy_browser_valid_filename(filename, len, &type)) + { + return 0; + } + + if (grub_file_is_vlnk_suffix(filename, len)) + { + return 0; + } + + node = grub_zalloc(sizeof(browser_node)); + if (!node) + { + return 0; + } + + if (fsize == 0) + { + struct grub_file file; + + grub_memset(&file, 0, sizeof(file)); + file.device = g_menu_dev; + grub_snprintf(node->menuentry, sizeof(node->menuentry), "%s/%s", g_menu_path_buf, filename); + if (g_menu_fs->fs_open(&file, node->menuentry) == GRUB_ERR_NONE) + { + fsize = file.size; + g_menu_fs->fs_close(&file); + } + } + + node->dir = 0; + grub_strncpy(node->filename, filename, sizeof(node->filename)); + + if (g_tree_view_menu_style == 0) + { + grub_snprintf(node->menuentry, sizeof(node->menuentry), + "menuentry \"%-10s %s\" --class=%s {\n" + " vt_set_fake_vlnk \"(%s)%s/%s\" %s %llu\n" + " %s_common_menuentry\n" + " vt_reset_fake_vlnk\n" + "}\n", + grub_get_human_size(fsize, GRUB_HUMAN_SIZE_SHORT), filename, g_menu_class[type], + g_menu_device, g_menu_path_buf, filename, g_menu_prefix[type], (ulonglong)fsize, + g_menu_prefix[type]); + } + else + { + grub_snprintf(node->menuentry, sizeof(node->menuentry), + "menuentry \"%s\" --class=%s {\n" + " vt_set_fake_vlnk \"(%s)%s/%s\" %s %llu\n" + " %s_common_menuentry\n" + " vt_reset_fake_vlnk\n" + "}\n", + filename, g_menu_class[type], + g_menu_device, g_menu_path_buf, filename, g_menu_prefix[type], (ulonglong)fsize, + g_menu_prefix[type]); + } + } + + node->prev = NULL; + node->next = g_browser_list; + if (g_browser_list) + { + g_browser_list->prev = node; + } + g_browser_list = node; + + return 0; +} + +static grub_err_t ventoy_browser_iso_part(void) +{ + char cfgfile[64]; + char *buffer = NULL; + int pos = 0; + int buflen = 0; + int cfglen = 0; + + cfglen = g_tree_script_pos - g_tree_script_pre; + buflen = cfglen + 512; + buffer = grub_malloc(buflen); + if (!buffer) + { + return 1; + } + + if (g_tree_view_menu_style == 0) + { + pos = grub_snprintf(buffer, buflen, "menuentry \"%-10s [../]\" --class=\"vtoyret\" VTOY_RET {\n " + " echo 'return ...' \n}\n", "<--"); + } + else + { + pos = grub_snprintf(buffer, buflen, "menuentry \"[../]\" --class=\"vtoyret\" VTOY_RET {\n " + " echo 'return ...' \n}\n"); + } + + grub_memcpy(buffer + pos, g_tree_script_buf + g_tree_script_pre, cfglen); + pos += cfglen; + + grub_snprintf(cfgfile, sizeof(cfgfile), "configfile mem:0x%lx:size:%d", (ulong)buffer, pos); + grub_script_execute_sourcecode(cfgfile); + + grub_free(buffer); + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_browser_dir(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + grub_fs_t fs; + grub_device_t dev; + char cfgfile[64]; + browser_node *node; + browser_mbuf mbuf; + + (void)ctxt; + (void)argc; + + if (args[2][0] == '/' && args[2][1] == 0) + { + grub_snprintf(cfgfile, sizeof(cfgfile), "(%s)", args[0]); + if (grub_strcmp(cfgfile, g_iso_path) == 0) + { + return ventoy_browser_iso_part(); + } + } + + if (!ventoy_browser_mbuf_alloc(&mbuf)) + { + return 1; + } + + fs = (grub_fs_t)grub_strtoul(args[1], NULL, 16); + if (!fs) + { + debug("Invalid fs %s\n", args[1]); + return 1; + } + + dev = grub_device_open(args[0]); + if (!dev) + { + debug("Failed to open device %s\n", args[0]); + return 1; + } + + g_menu_fs = fs; + g_menu_device = args[0]; + g_menu_dev = dev; + g_browser_list = NULL; + + if (args[2][0] == '/' && args[2][1] == 0) + { + g_menu_path_len = 0; + g_menu_path_buf[0] = 0; + fs->fs_dir(dev, "/", ventoy_browser_iterate_dir, NULL); + } + else + { + g_menu_path_len = grub_snprintf(g_menu_path_buf, sizeof(g_menu_path_buf), "%s", args[2]); + fs->fs_dir(dev, g_menu_path_buf, ventoy_browser_iterate_dir, NULL); + } + grub_device_close(dev); + + if (g_tree_view_menu_style == 0) + { + browser_ssprintf(&mbuf, "menuentry \"%-10s [(%s)%s/..]\" --class=\"vtoyret\" VTOY_RET {\n " + " echo 'return ...' \n}\n", "<--", args[0], g_menu_path_buf); + } + else + { + browser_ssprintf(&mbuf, "menuentry \"[(%s)%s/..]\" --class=\"vtoyret\" VTOY_RET {\n " + " echo 'return ...' \n}\n", args[0], g_menu_path_buf); + } + + for (i = 1; i >= 0; i--) + { + while (1) + { + node = ventoy_browser_find_top_node(i); + if (node) + { + browser_ssprintf(&mbuf, "%s", node->menuentry); + ventoy_browser_mbuf_extend(&mbuf); + + if (node->prev) + { + node->prev->next = node->next; + } + if (node->next) + { + node->next->prev = node->prev; + } + + if (node == g_browser_list) + { + g_browser_list = node->next; + } + grub_free(node); + } + else + { + break; + } + } + } + g_browser_list = NULL; + + grub_snprintf(cfgfile, sizeof(cfgfile), "configfile mem:0x%lx:size:%d", (ulong)mbuf.buf, mbuf.pos); + grub_script_execute_sourcecode(cfgfile); + + ventoy_browser_mbuf_free(&mbuf); + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_browser_disk(grub_extcmd_context_t ctxt, int argc, char **args) +{ + char cfgfile[64]; + browser_mbuf mbuf; + + (void)ctxt; + (void)argc; + (void)args; + + if (!ventoy_browser_mbuf_alloc(&mbuf)) + { + return 1; + } + + g_vtoy_dev = grub_env_get("vtoydev"); + + if (g_tree_view_menu_style == 0) + { + browser_ssprintf(&mbuf, "menuentry \"%-10s [%s]\" --class=\"vtoyret\" VTOY_RET {\n " + " echo 'return ...' \n}\n", "<--", + ventoy_get_vmenu_title("VTLANG_BROWER_RETURN")); + } + else + { + browser_ssprintf(&mbuf, "menuentry \"[%s]\" --class=\"vtoyret\" VTOY_RET {\n " + " echo 'return ...' \n}\n", + ventoy_get_vmenu_title("VTLANG_BROWER_RETURN")); + } + + grub_disk_dev_iterate(ventoy_browser_iterate_disk, &mbuf); + + grub_snprintf(cfgfile, sizeof(cfgfile), "configfile mem:0x%lx:size:%d", (ulong)mbuf.buf, mbuf.pos); + grub_script_execute_sourcecode(cfgfile); + + ventoy_browser_mbuf_free(&mbuf); + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c new file mode 100644 index 0000000..9b12342 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c @@ -0,0 +1,7166 @@ +/****************************************************************************** + * ventoy_cmd.c + * + * Copyright (c) 2021, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef GRUB_MACHINE_EFI +#include +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include "ventoy_def.h" +#include "miniz.h" + +GRUB_MOD_LICENSE ("GPLv3+"); + +static grub_uint8_t g_check_mbr_data[] = { + 0xEB, 0x63, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x56, 0x54, 0x00, 0x47, 0x65, 0x00, 0x48, 0x44, 0x00, 0x52, 0x64, 0x00, 0x20, 0x45, 0x72, 0x0D, +}; + +initrd_info *g_initrd_img_list = NULL; +initrd_info *g_initrd_img_tail = NULL; +int g_initrd_img_count = 0; +int g_valid_initrd_count = 0; +int g_default_menu_mode = 0; +int g_filt_dot_underscore_file = 0; +int g_filt_trash_dir = 1; +int g_sort_case_sensitive = 0; +int g_tree_view_menu_style = 0; +static grub_file_t g_old_file; +static int g_ventoy_last_entry_back; + +char g_iso_path[256]; +char g_img_swap_tmp_buf[1024]; +img_info g_img_swap_tmp; +img_info *g_ventoy_img_list = NULL; + +int g_ventoy_img_count = 0; + +grub_device_t g_enum_dev = NULL; +grub_fs_t g_enum_fs = NULL; +int g_img_max_search_level = -1; +img_iterator_node g_img_iterator_head; +img_iterator_node *g_img_iterator_tail = NULL; + +grub_uint8_t g_ventoy_break_level = 0; +grub_uint8_t g_ventoy_debug_level = 0; +grub_uint8_t g_ventoy_chain_type = 0; + +grub_uint8_t *g_ventoy_cpio_buf = NULL; +grub_uint32_t g_ventoy_cpio_size = 0; +cpio_newc_header *g_ventoy_initrd_head = NULL; +grub_uint8_t *g_ventoy_runtime_buf = NULL; + +int g_plugin_image_list = 0; + +ventoy_grub_param *g_grub_param = NULL; + +ventoy_guid g_ventoy_guid = VENTOY_GUID; + +ventoy_img_chunk_list g_img_chunk_list; + +int g_wimboot_enable = 0; +ventoy_img_chunk_list g_wimiso_chunk_list; +char *g_wimiso_path = NULL; +grub_uint32_t g_wimiso_size = 0; + +int g_vhdboot_enable = 0; + +grub_uint64_t g_svd_replace_offset = 0; + +int g_conf_replace_count = 0; +grub_uint64_t g_conf_replace_offset[VTOY_MAX_CONF_REPLACE] = { 0 }; +conf_replace *g_conf_replace_node[VTOY_MAX_CONF_REPLACE] = { NULL }; +grub_uint8_t *g_conf_replace_new_buf[VTOY_MAX_CONF_REPLACE] = { NULL }; +int g_conf_replace_new_len[VTOY_MAX_CONF_REPLACE] = { 0 }; +int g_conf_replace_new_len_align[VTOY_MAX_CONF_REPLACE] = { 0 }; + +int g_ventoy_disk_bios_id = 0; +ventoy_gpt_info *g_ventoy_part_info = NULL; +grub_uint64_t g_ventoy_disk_size = 0; +grub_uint64_t g_ventoy_disk_part_size[2]; + +char *g_tree_script_buf = NULL; +int g_tree_script_pos = 0; +int g_tree_script_pre = 0; + +static char *g_list_script_buf = NULL; +static int g_list_script_pos = 0; + +static char *g_part_list_buf = NULL; +static int g_part_list_pos = 0; +static grub_uint64_t g_part_end_max = 0; + +static int g_video_mode_max = 0; +static int g_video_mode_num = 0; +static ventoy_video_mode *g_video_mode_list = NULL; + +static int g_enumerate_time_checked = 0; +static grub_uint64_t g_enumerate_start_time_ms; +static grub_uint64_t g_enumerate_finish_time_ms; +int g_vtoy_file_flt[VTOY_FILE_FLT_BUTT] = {0}; + +static char g_iso_vd_id_publisher[130]; +static char g_iso_vd_id_prepare[130]; +static char g_iso_vd_id_application[130]; + +static int g_pager_flag = 0; +static char g_old_pager[32]; + +const char *g_menu_class[img_type_max] = +{ + "vtoyiso", "vtoywim", "vtoyefi", "vtoyimg", "vtoyvhd", "vtoyvtoy" +}; + +const char *g_menu_prefix[img_type_max] = +{ + "iso", "wim", "efi", "img", "vhd", "vtoy" +}; + +static const char *g_lower_chksum_name[VTOY_CHKSUM_NUM] = { "md5", "sha1", "sha256", "sha512" }; +static int g_lower_chksum_namelen[VTOY_CHKSUM_NUM] = { 3, 4, 6, 6 }; +static int g_chksum_retlen[VTOY_CHKSUM_NUM] = { 32, 40, 64, 128 }; + +static int g_vtoy_secondary_need_recover = 0; + +static int g_vtoy_load_prompt = 0; +static char g_vtoy_prompt_msg[64]; + +static char g_json_case_mis_path[32]; + +static ventoy_vlnk_part *g_vlnk_part_list = NULL; + +int ventoy_get_fs_type(const char *fs) +{ + if (NULL == fs) + { + return ventoy_fs_max; + } + else if (grub_strncmp(fs, "exfat", 5) == 0) + { + return ventoy_fs_exfat; + } + else if (grub_strncmp(fs, "ntfs", 4) == 0) + { + return ventoy_fs_ntfs; + } + else if (grub_strncmp(fs, "ext", 3) == 0) + { + return ventoy_fs_ext; + } + else if (grub_strncmp(fs, "xfs", 3) == 0) + { + return ventoy_fs_xfs; + } + else if (grub_strncmp(fs, "udf", 3) == 0) + { + return ventoy_fs_udf; + } + else if (grub_strncmp(fs, "fat", 3) == 0) + { + return ventoy_fs_fat; + } + else if (grub_strncmp(fs, "btrfs", 5) == 0) + { + return ventoy_fs_btrfs; + } + + return ventoy_fs_max; +} + +static int ventoy_string_check(const char *str, grub_char_check_func check) +{ + if (!str) + { + return 0; + } + + for ( ; *str; str++) + { + if (!check(*str)) + { + return 0; + } + } + + return 1; +} + + +static grub_ssize_t ventoy_fs_read(grub_file_t file, char *buf, grub_size_t len) +{ + grub_memcpy(buf, (char *)file->data + file->offset, len); + return len; +} + +static int ventoy_control_get_flag(const char *key) +{ + const char *val = ventoy_get_env(key); + + if (val && val[0] == '1' && val[1] == 0) + { + return 1; + } + return 0; +} + +static grub_err_t ventoy_fs_close(grub_file_t file) +{ + grub_file_close(g_old_file); + grub_free(file->data); + + file->device = 0; + file->name = 0; + + return 0; +} + +static int ventoy_video_hook(const struct grub_video_mode_info *info, void *hook_arg) +{ + int i; + + (void)hook_arg; + + if (info->mode_type & GRUB_VIDEO_MODE_TYPE_PURE_TEXT) + { + return 0; + } + + for (i = 0; i < g_video_mode_num; i++) + { + if (g_video_mode_list[i].width == info->width && + g_video_mode_list[i].height == info->height && + g_video_mode_list[i].bpp == info->bpp) + { + return 0; + } + } + + g_video_mode_list[g_video_mode_num].width = info->width; + g_video_mode_list[g_video_mode_num].height = info->height; + g_video_mode_list[g_video_mode_num].bpp = info->bpp; + g_video_mode_num++; + + if (g_video_mode_num == g_video_mode_max) + { + g_video_mode_max *= 2; + g_video_mode_list = grub_realloc(g_video_mode_list, g_video_mode_max * sizeof(ventoy_video_mode)); + } + + return 0; +} + +static int ventoy_video_mode_cmp(ventoy_video_mode *v1, ventoy_video_mode *v2) +{ + if (v1->bpp == v2->bpp) + { + if (v1->width == v2->width) + { + if (v1->height == v2->height) + { + return 0; + } + else + { + return (v1->height < v2->height) ? -1 : 1; + } + } + else + { + return (v1->width < v2->width) ? -1 : 1; + } + } + else + { + return (v1->bpp < v2->bpp) ? -1 : 1; + } +} + +static int ventoy_enum_video_mode(void) +{ + int i, j; + grub_video_adapter_t adapter; + grub_video_driver_id_t id; + ventoy_video_mode mode; + + g_video_mode_num = 0; + g_video_mode_max = 1024; + g_video_mode_list = grub_malloc(sizeof(ventoy_video_mode) * g_video_mode_max); + if (!g_video_mode_list) + { + return 0; + } + + #ifdef GRUB_MACHINE_PCBIOS + grub_dl_load ("vbe"); + #endif + + id = grub_video_get_driver_id (); + + FOR_VIDEO_ADAPTERS (adapter) + { + if (!adapter->iterate || + (adapter->id != id && (id != GRUB_VIDEO_DRIVER_NONE || + adapter->init() != GRUB_ERR_NONE))) + { + continue; + } + + adapter->iterate(ventoy_video_hook, NULL); + + if (adapter->id != id) + { + adapter->fini(); + } + } + + /* sort video mode */ + for (i = 0; i < g_video_mode_num; i++) + for (j = i + 1; j < g_video_mode_num; j++) + { + if (ventoy_video_mode_cmp(g_video_mode_list + i, g_video_mode_list + j) < 0) + { + grub_memcpy(&mode, g_video_mode_list + i, sizeof(ventoy_video_mode)); + grub_memcpy(g_video_mode_list + i, g_video_mode_list + j, sizeof(ventoy_video_mode)); + grub_memcpy(g_video_mode_list + j, &mode, sizeof(ventoy_video_mode)); + } + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static int ventoy_pre_parse_data(char *src, int size) +{ + char c; + char *pos = NULL; + char buf[256]; + + if (size < 20 || grub_strncmp(src, "ventoy_left_top_color", 21)) + { + return 0; + } + + pos = src + 21; + while (*pos && *pos != '\r' && *pos != '\n') + { + pos++; + } + + c = *pos; + *pos = 0; + + if (grub_strlen(src) > 200) + { + goto end; + } + + grub_snprintf(buf, sizeof(buf), + "regexp -s 1:%s -s 2:%s -s 3:%s \"@([^@]*)@([^@]*)@([^@]*)@\" \"%s\"", + ventoy_left_key, ventoy_top_key, ventoy_color_key, src); + + grub_script_execute_sourcecode(buf); + +end: + *pos = c; + return 0; +} + +static grub_file_t ventoy_wrapper_open(grub_file_t rawFile, enum grub_file_type type) +{ + int len; + grub_file_t file; + static struct grub_fs vtoy_fs = + { + .name = "vtoy", + .fs_dir = 0, + .fs_open = 0, + .fs_read = ventoy_fs_read, + .fs_close = ventoy_fs_close, + .fs_label = 0, + .next = 0 + }; + + if (type != 52) + { + return rawFile; + } + + file = (grub_file_t)grub_zalloc(sizeof (*file)); + if (!file) + { + return 0; + } + + file->data = grub_malloc(rawFile->size + 4096); + if (!file->data) + { + return 0; + } + + grub_file_read(rawFile, file->data, rawFile->size); + ventoy_pre_parse_data((char *)file->data, (int)rawFile->size); + len = ventoy_fill_data(4096, (char *)file->data + rawFile->size); + + g_old_file = rawFile; + + file->size = rawFile->size + len; + file->device = rawFile->device; + file->fs = &vtoy_fs; + file->not_easily_seekable = 1; + + return file; +} + +static int ventoy_check_decimal_var(const char *name, long *value) +{ + const char *value_str = NULL; + + value_str = grub_env_get(name); + if (NULL == value_str) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Variable %s not found", name); + } + + if (!ventoy_is_decimal(value_str)) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Variable %s value '%s' is not an integer", name, value_str); + } + + *value = grub_strtol(value_str, NULL, 10); + + return GRUB_ERR_NONE; +} + +grub_uint64_t ventoy_get_vtoy_partsize(int part) +{ + grub_uint64_t sectors; + + if (grub_strncmp(g_ventoy_part_info->Head.Signature, "EFI PART", 8) == 0) + { + sectors = g_ventoy_part_info->PartTbl[part].LastLBA + 1 - g_ventoy_part_info->PartTbl[part].StartLBA; + } + else + { + sectors = g_ventoy_part_info->MBR.PartTbl[part].SectorCount; + } + + return sectors * 512; +} + +static int ventoy_load_efiboot_template(char **buf, int *datalen, int *direntoff) +{ + int len; + grub_file_t file; + char exec[128]; + char *data = NULL; + grub_uint32_t offset; + + file = ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD, "%s/ventoy/ventoy_efiboot.img.xz", ventoy_get_env("vtoy_efi_part")); + if (file == NULL) + { + debug("failed to open file <%s>\n", "ventoy_efiboot.img.xz"); + return 1; + } + + len = (int)file->size; + + data = (char *)grub_malloc(file->size); + if (!data) + { + return 1; + } + + grub_file_read(file, data, file->size); + grub_file_close(file); + + grub_snprintf(exec, sizeof(exec), "loopback efiboot mem:0x%llx:size:%d", (ulonglong)(ulong)data, len); + grub_script_execute_sourcecode(exec); + + file = grub_file_open("(efiboot)/EFI/BOOT/BOOTX64.EFI", GRUB_FILE_TYPE_LINUX_INITRD); + offset = (grub_uint32_t)grub_iso9660_get_last_file_dirent_pos(file); + grub_file_close(file); + + grub_script_execute_sourcecode("loopback -d efiboot"); + + *buf = data; + *datalen = len; + *direntoff = offset + 2; + + return 0; +} + +static int ventoy_set_check_result(int ret, const char *msg) +{ + char buf[32]; + + grub_snprintf(buf, sizeof(buf), "%d", (ret & 0x7FFF)); + grub_env_set("VTOY_CHKDEV_RESULT_STRING", buf); + grub_env_export("VTOY_CHKDEV_RESULT_STRING"); + + if (ret) + { + grub_cls(); + grub_printf(VTOY_WARNING"\n"); + grub_printf(VTOY_WARNING"\n"); + grub_printf(VTOY_WARNING"\n\n\n"); + + grub_printf("This is NOT a standard Ventoy device and is NOT supported (%d).\n", ret); + grub_printf("Error message: <%s>\n\n", msg); + grub_printf("You should follow the instructions in https://www.ventoy.net to use Ventoy.\n"); + grub_refresh(); + } + + return ret; +} + +static int ventoy_check_official_device(grub_device_t dev) +{ + int workaround = 0; + grub_file_t file; + grub_uint64_t offset; + char devname[64]; + grub_fs_t fs; + grub_uint8_t mbr[512]; + grub_disk_t disk; + grub_device_t dev2; + char *label = NULL; + struct grub_partition *partition; + + if (dev->disk == NULL || dev->disk->partition == NULL) + { + return ventoy_set_check_result(1 | 0x1000, "Internal Error"); + } + + if (0 == ventoy_check_file_exist("(%s,2)/ventoy/ventoy.cpio", dev->disk->name) || + 0 == ventoy_check_file_exist("(%s,2)/grub/localboot.cfg", dev->disk->name) || + 0 == ventoy_check_file_exist("(%s,2)/tool/mount.exfat-fuse_aarch64", dev->disk->name)) + { + #ifndef GRUB_MACHINE_EFI + if (0 == ventoy_check_file_exist("(ventoydisk)/ventoy/ventoy.cpio", dev->disk->name)) + { + return ventoy_set_check_result(2 | 0x1000, "File ventoy/ventoy.cpio missing in VTOYEFI partition"); + } + else if (0 == ventoy_check_file_exist("(ventoydisk)/grub/localboot.cfg", dev->disk->name)) + { + return ventoy_set_check_result(2 | 0x1000, "File grub/localboot.cfg missing in VTOYEFI partition"); + } + else if (0 == ventoy_check_file_exist("(ventoydisk)/tool/mount.exfat-fuse_aarch64", dev->disk->name)) + { + return ventoy_set_check_result(2 | 0x1000, "File tool/mount.exfat-fuse_aarch64 missing in VTOYEFI partition"); + } + else + { + workaround = 1; + } + #endif + } + + /* We must have partition 2 */ + if (workaround) + { + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", "(ventoydisk)/ventoy/ventoy.cpio"); + } + else + { + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(%s,2)/ventoy/ventoy.cpio", dev->disk->name); + } + if (!file) + { + return ventoy_set_check_result(3 | 0x1000, "File ventoy/ventoy.cpio open failed in VTOYEFI partition"); + } + + if (NULL == grub_strstr(file->fs->name, "fat")) + { + grub_file_close(file); + return ventoy_set_check_result(4 | 0x1000, "VTOYEFI partition is not FAT filesystem"); + } + + partition = dev->disk->partition; + if (partition->number != 0 || partition->start != 2048) + { + return ventoy_set_check_result(5, "Ventoy partition is not start at 1MB"); + } + + if (workaround) + { + if (grub_strncmp(g_ventoy_part_info->Head.Signature, "EFI PART", 8) == 0) + { + ventoy_gpt_part_tbl *PartTbl = g_ventoy_part_info->PartTbl; + if (PartTbl[1].StartLBA != PartTbl[0].LastLBA + 1 || + (PartTbl[1].LastLBA + 1 - PartTbl[1].StartLBA) != 65536) + { + grub_file_close(file); + return ventoy_set_check_result(6, "Disk partition layout check failed."); + } + } + else + { + ventoy_part_table *PartTbl = g_ventoy_part_info->MBR.PartTbl; + if (PartTbl[1].StartSectorId != PartTbl[0].StartSectorId + PartTbl[0].SectorCount || + PartTbl[1].SectorCount != 65536) + { + grub_file_close(file); + return ventoy_set_check_result(6, "Disk partition layout check failed."); + } + } + } + else + { + offset = partition->start + partition->len; + partition = file->device->disk->partition; + if ((partition->number != 1) || (partition->len != 65536) || (offset != partition->start)) + { + grub_file_close(file); + return ventoy_set_check_result(7, "Disk partition layout check failed."); + } + } + + grub_file_close(file); + + if (workaround == 0) + { + grub_snprintf(devname, sizeof(devname), "%s,2", dev->disk->name); + dev2 = grub_device_open(devname); + if (!dev2) + { + return ventoy_set_check_result(8, "Disk open failed"); + } + + fs = grub_fs_probe(dev2); + if (!fs) + { + grub_device_close(dev2); + return ventoy_set_check_result(9, "FS probe failed"); + } + + fs->fs_label(dev2, &label); + if ((!label) || grub_strncmp("VTOYEFI", label, 7)) + { + grub_device_close(dev2); + return ventoy_set_check_result(10, "Partition name is not VTOYEFI"); + } + + grub_device_close(dev2); + } + + /* MBR check */ + disk = grub_disk_open(dev->disk->name); + if (!disk) + { + return ventoy_set_check_result(11, "Disk open failed"); + } + + grub_memset(mbr, 0, 512); + grub_disk_read(disk, 0, 0, 512, mbr); + grub_disk_close(disk); + + if (grub_memcmp(g_check_mbr_data, mbr, 0x30) || grub_memcmp(g_check_mbr_data + 0x30, mbr + 0x190, 16)) + { + return ventoy_set_check_result(12, "MBR check failed"); + } + + return ventoy_set_check_result(0, NULL); +} + +static int ventoy_check_ignore_flag(const char *filename, const struct grub_dirhook_info *info, void *data) +{ + if (0 == info->dir) + { + if (filename && filename[0] == '.' && 0 == grub_strncmp(filename, ".ventoyignore", 13)) + { + *((int *)data) = 1; + return 0; + } + } + + return 0; +} + +grub_uint64_t ventoy_grub_get_file_size(const char *fmt, ...) +{ + grub_uint64_t size = 0; + grub_file_t file; + va_list ap; + char fullpath[256] = {0}; + + va_start (ap, fmt); + grub_vsnprintf(fullpath, 255, fmt, ap); + va_end (ap); + + file = grub_file_open(fullpath, VENTOY_FILE_TYPE); + if (!file) + { + debug("grub_file_open failed <%s>\n", fullpath); + grub_errno = 0; + return 0; + } + + size = file->size; + grub_file_close(file); + return size; +} + +grub_file_t ventoy_grub_file_open(enum grub_file_type type, const char *fmt, ...) +{ + va_list ap; + grub_file_t file; + char fullpath[512] = {0}; + + va_start (ap, fmt); + grub_vsnprintf(fullpath, 511, fmt, ap); + va_end (ap); + + file = grub_file_open(fullpath, type); + if (!file) + { + debug("grub_file_open failed <%s> %d\n", fullpath, grub_errno); + grub_errno = 0; + } + + return file; +} + +int ventoy_is_dir_exist(const char *fmt, ...) +{ + va_list ap; + int len; + char *pos = NULL; + char buf[512] = {0}; + + grub_snprintf(buf, sizeof(buf), "%s", "[ -d \""); + pos = buf + 6; + + va_start (ap, fmt); + len = grub_vsnprintf(pos, 511, fmt, ap); + va_end (ap); + + grub_strncpy(pos + len, "\" ]", 3); + + debug("script exec %s\n", buf); + + if (0 == grub_script_execute_sourcecode(buf)) + { + return 1; + } + + return 0; +} + +int ventoy_gzip_compress(void *mem_in, int mem_in_len, void *mem_out, int mem_out_len) +{ + mz_stream s; + grub_uint8_t *outbuf; + grub_uint8_t gzHdr[10] = + { + 0x1F, 0x8B, /* magic */ + 8, /* z method */ + 0, /* flags */ + 0,0,0,0, /* mtime */ + 4, /* xfl */ + 3, /* OS */ + }; + + grub_memset(&s, 0, sizeof(mz_stream)); + + mz_deflateInit2(&s, 1, MZ_DEFLATED, -MZ_DEFAULT_WINDOW_BITS, 6, MZ_DEFAULT_STRATEGY); + + outbuf = (grub_uint8_t *)mem_out; + + mem_out_len -= sizeof(gzHdr) + 8; + grub_memcpy(outbuf, gzHdr, sizeof(gzHdr)); + outbuf += sizeof(gzHdr); + + s.avail_in = mem_in_len; + s.next_in = mem_in; + + s.avail_out = mem_out_len; + s.next_out = outbuf; + + mz_deflate(&s, MZ_FINISH); + + mz_deflateEnd(&s); + + outbuf += s.total_out; + *(grub_uint32_t *)outbuf = grub_getcrc32c(0, outbuf, s.total_out); + *(grub_uint32_t *)(outbuf + 4) = (grub_uint32_t)(s.total_out); + + return s.total_out + sizeof(gzHdr) + 8; +} + + +#if 0 +ventoy grub cmds +#endif + +static grub_err_t ventoy_cmd_debug(grub_extcmd_context_t ctxt, int argc, char **args) +{ + if (argc != 1) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {on|off}", cmd_raw_name); + } + + if (0 == grub_strcmp(args[0], "on")) + { + g_ventoy_debug = 1; + grub_env_set("vtdebug_flag", "debug"); + } + else + { + g_ventoy_debug = 0; + grub_env_set("vtdebug_flag", ""); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_break(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + + if (argc < 1 || (args[0][0] != '0' && args[0][0] != '1')) + { + grub_printf("Usage: %s {level} [debug]\r\n", cmd_raw_name); + grub_printf(" level:\r\n"); + grub_printf(" 01/11: busybox / (+cat log)\r\n"); + grub_printf(" 02/12: initrd / (+cat log)\r\n"); + grub_printf(" 03/13: hook / (+cat log)\r\n"); + grub_printf("\r\n"); + grub_printf(" debug:\r\n"); + grub_printf(" 0: debug is off\r\n"); + grub_printf(" 1: debug is on\r\n"); + grub_printf("\r\n"); + VENTOY_CMD_RETURN(GRUB_ERR_NONE); + } + + g_ventoy_break_level = (grub_uint8_t)grub_strtoul(args[0], NULL, 16); + + if (argc > 1 && grub_strtoul(args[1], NULL, 10) > 0) + { + g_ventoy_debug_level = 1; + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_strstr(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + + if (argc != 2) + { + return 1; + } + + return (grub_strstr(args[0], args[1])) ? 0 : 1; +} + +static grub_err_t ventoy_cmd_istrstr(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_err_t ret = 1; + char *s1 = NULL; + char *s2 = NULL; + + (void)ctxt; + + if (argc != 2) + { + return 1; + } + + s1 = grub_strdup(args[0]); + s2 = grub_strdup(args[1]); + if (s1 == NULL || s2 == NULL) + { + goto end; + } + + ventoy_str_toupper(s1); + ventoy_str_toupper(s2); + ret = (grub_strstr(s1, s2)) ? 0 : 1; + +end: + grub_check_free(s1); + grub_check_free(s2); + return ret; +} + +static grub_err_t ventoy_cmd_strbegin(grub_extcmd_context_t ctxt, int argc, char **args) +{ + char *c0, *c1; + + (void)ctxt; + + if (argc != 2) + { + return 1; + } + + c0 = args[0]; + c1 = args[1]; + + while (*c0 && *c1) + { + if (*c0 != *c1) + { + return 1; + } + c0++; + c1++; + } + + if (*c1) + { + return 1; + } + + return 0; +} + +static grub_err_t ventoy_cmd_strcasebegin(grub_extcmd_context_t ctxt, int argc, char **args) +{ + char *c0, *c1; + + (void)ctxt; + + if (argc != 2) + { + return 1; + } + + c0 = args[0]; + c1 = args[1]; + + while (*c0 && *c1) + { + if ((*c0 != *c1) && (*c0 != grub_toupper(*c1))) + { + return 1; + } + c0++; + c1++; + } + + if (*c1) + { + return 1; + } + + return 0; +} + +static grub_err_t ventoy_cmd_incr(grub_extcmd_context_t ctxt, int argc, char **args) +{ + long value_long = 0; + char buf[32]; + + if ((argc != 2) || (!ventoy_is_decimal(args[1]))) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {Variable} {Int}", cmd_raw_name); + } + + if (GRUB_ERR_NONE != ventoy_check_decimal_var(args[0], &value_long)) + { + return grub_errno; + } + + value_long += grub_strtol(args[1], NULL, 10); + + grub_snprintf(buf, sizeof(buf), "%ld", value_long); + grub_env_set(args[0], buf); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_mod(grub_extcmd_context_t ctxt, int argc, char **args) +{ + ulonglong value1 = 0; + ulonglong value2 = 0; + char buf[32]; + + if (argc != 3) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {Int} {Int} {Variable}", cmd_raw_name); + } + + value1 = grub_strtoull(args[0], NULL, 10); + value2 = grub_strtoull(args[1], NULL, 10); + + grub_snprintf(buf, sizeof(buf), "%llu", (value1 & (value2 - 1))); + grub_env_set(args[2], buf); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_file_size(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int rc = 1; + char buf[32]; + grub_file_t file; + + (void)ctxt; + (void)argc; + (void)args; + + if (argc != 2) + { + return rc; + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (file == NULL) + { + debug("failed to open file <%s> for udf check\n", args[0]); + return 1; + } + + grub_snprintf(buf, sizeof(buf), "%llu", (unsigned long long)file->size); + + grub_env_set(args[1], buf); + + grub_file_close(file); + rc = 0; + + return rc; +} + +static grub_err_t ventoy_cmd_load_wimboot(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_file_t file; + + (void)ctxt; + (void)argc; + (void)args; + + g_wimboot_enable = 0; + g_wimiso_size = 0; + grub_check_free(g_wimiso_path); + grub_check_free(g_wimiso_chunk_list.chunk); + + file = grub_file_open(args[0], VENTOY_FILE_TYPE); + if (!file) + { + return 0; + } + + grub_memset(&g_wimiso_chunk_list, 0, sizeof(g_wimiso_chunk_list)); + g_wimiso_chunk_list.chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM); + if (NULL == g_wimiso_chunk_list.chunk) + { + return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Can't allocate image chunk memoty\n"); + } + + g_wimiso_chunk_list.max_chunk = DEFAULT_CHUNK_NUM; + g_wimiso_chunk_list.cur_chunk = 0; + + ventoy_get_block_list(file, &g_wimiso_chunk_list, file->device->disk->partition->start); + + g_wimboot_enable = 1; + g_wimiso_path = grub_strdup(args[0]); + g_wimiso_size = (grub_uint32_t)(file->size); + grub_file_close(file); + + return 0; +} + +static grub_err_t ventoy_cmd_concat_efi_iso(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int len = 0; + int totlen = 0; + int offset = 0; + grub_file_t file; + char *buf = NULL; + char *data = NULL; + ventoy_iso9660_override *dirent; + + (void)ctxt; + + if (argc != 2) + { + return 1; + } + + totlen = sizeof(ventoy_chain_head); + + if (ventoy_load_efiboot_template(&buf, &len, &offset)) + { + debug("failed to load efiboot template %d\n", len); + return 1; + } + + totlen += len; + + debug("efiboot template len:%d offset:%d\n", len, offset); + + file = ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD, "%s", args[0]); + if (file == NULL) + { + debug("failed to open file <%s>\n", args[0]); + return 1; + } + + if (grub_strncmp(args[0], g_iso_path, grub_strlen(g_iso_path))) + { + file->vlnk = 1; + } + + totlen += ventoy_align_2k(file->size); + + dirent = (ventoy_iso9660_override *)(buf + offset); + dirent->first_sector = len / 2048; + dirent->first_sector_be = grub_swap_bytes32(dirent->first_sector); + dirent->size = (grub_uint32_t)file->size; + dirent->size_be = grub_swap_bytes32(dirent->size); + + debug("rawiso len:%d efilen:%d total:%d\n", len, (int)file->size, totlen); + +#ifdef GRUB_MACHINE_EFI + data = (char *)grub_efi_allocate_iso_buf(totlen); +#else + data = (char *)grub_malloc(totlen); +#endif + + ventoy_fill_os_param(file, (ventoy_os_param *)data); + + grub_memcpy(data + sizeof(ventoy_chain_head), buf, len); + grub_check_free(buf); + + grub_file_read(file, data + sizeof(ventoy_chain_head) + len, file->size); + grub_file_close(file); + + ventoy_memfile_env_set(args[1], data, (ulonglong)totlen); + + return 0; +} + +grub_err_t ventoy_cmd_set_wim_prompt(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + g_vtoy_load_prompt = 0; + grub_memset(g_vtoy_prompt_msg, 0, sizeof(g_vtoy_prompt_msg)); + + if (argc == 2 && args[0][0] == '1') + { + g_vtoy_load_prompt = 1; + grub_snprintf(g_vtoy_prompt_msg, sizeof(g_vtoy_prompt_msg), "%s", args[1]); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +int ventoy_need_prompt_load_file(void) +{ + return g_vtoy_load_prompt; +} + +grub_ssize_t ventoy_load_file_with_prompt(grub_file_t file, void *buf, grub_ssize_t size) +{ + grub_uint64_t ro = 0; + grub_uint64_t div = 0; + grub_ssize_t left = size; + char *cur = (char *)buf; + + grub_printf("\r%s 1%% ", g_vtoy_prompt_msg); + grub_refresh(); + + while (left >= VTOY_SIZE_2MB) + { + grub_file_read(file, cur, VTOY_SIZE_2MB); + cur += VTOY_SIZE_2MB; + left -= VTOY_SIZE_2MB; + + div = grub_divmod64((grub_uint64_t)((size - left) * 100), (grub_uint64_t)size, &ro); + if (div < 1) + { + div = 1; + } + grub_printf("\r%s %d%% ", g_vtoy_prompt_msg, (int)div); + grub_refresh(); + } + + if (left > 0) + { + grub_file_read(file, cur, left); + } + + grub_printf("\r%s 100%% \n", g_vtoy_prompt_msg); + grub_refresh(); + + return size; +} + +static grub_err_t ventoy_cmd_load_file_to_mem(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int rc = 1; + char *buf = NULL; + grub_file_t file; + enum grub_file_type type; + + (void)ctxt; + (void)argc; + (void)args; + + if (argc != 3) + { + return rc; + } + + if (grub_strcmp(args[0], "nodecompress") == 0) + { + type = VENTOY_FILE_TYPE; + } + else + { + type = GRUB_FILE_TYPE_LINUX_INITRD; + } + + file = ventoy_grub_file_open(type, "%s", args[1]); + if (file == NULL) + { + debug("failed to open file <%s>\n", args[1]); + return 1; + } + +#ifdef GRUB_MACHINE_EFI + buf = (char *)grub_efi_allocate_chain_buf(file->size); +#else + buf = (char *)grub_malloc(file->size); +#endif + + if (!buf) + { + grub_file_close(file); + return 1; + } + + if (g_vtoy_load_prompt) + { + ventoy_load_file_with_prompt(file, buf, file->size); + } + else + { + grub_file_read(file, buf, file->size); + } + + ventoy_memfile_env_set(args[2], buf, (ulonglong)(file->size)); + + grub_file_close(file); + rc = 0; + + return rc; +} + +static grub_err_t ventoy_cmd_load_img_memdisk(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int rc = 1; + int headlen; + char *buf = NULL; + grub_file_t file; + + (void)ctxt; + (void)argc; + (void)args; + + if (argc != 2) + { + return rc; + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (file == NULL) + { + debug("failed to open file <%s> for udf check\n", args[0]); + return 1; + } + + headlen = sizeof(ventoy_chain_head); + +#ifdef GRUB_MACHINE_EFI + buf = (char *)grub_efi_allocate_iso_buf(headlen + file->size); +#else + buf = (char *)grub_malloc(headlen + file->size); +#endif + + ventoy_fill_os_param(file, (ventoy_os_param *)buf); + + grub_file_read(file, buf + headlen, file->size); + + ventoy_memfile_env_set(args[1], buf, (ulonglong)(file->size)); + + grub_file_close(file); + rc = 0; + + return rc; +} + +static grub_err_t ventoy_cmd_iso9660_is_joliet(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + if (grub_iso9660_is_joliet()) + { + debug("This time has joliet process\n"); + return 0; + } + else + { + return 1; + } +} + +static grub_err_t ventoy_cmd_iso9660_nojoliet(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + + if (argc != 1) + { + return 1; + } + + if (args[0][0] == '1') + { + grub_iso9660_set_nojoliet(1); + } + else + { + grub_iso9660_set_nojoliet(0); + } + + return 0; +} + +static grub_err_t ventoy_cmd_is_udf(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + int rc = 1; + grub_file_t file; + grub_uint8_t buf[32]; + + (void)ctxt; + (void)argc; + (void)args; + + if (argc != 1) + { + return rc; + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (file == NULL) + { + debug("failed to open file <%s> for udf check\n", args[0]); + return 1; + } + + for (i = 16; i < 32; i++) + { + grub_file_seek(file, i * 2048); + grub_file_read(file, buf, sizeof(buf)); + if (buf[0] == 255) + { + break; + } + } + + i++; + grub_file_seek(file, i * 2048); + grub_file_read(file, buf, sizeof(buf)); + + if (grub_memcmp(buf + 1, "BEA01", 5) == 0) + { + i++; + grub_file_seek(file, i * 2048); + grub_file_read(file, buf, sizeof(buf)); + + if (grub_memcmp(buf + 1, "NSR02", 5) == 0 || + grub_memcmp(buf + 1, "NSR03", 5) == 0) + { + rc = 0; + } + } + + grub_file_close(file); + + debug("ISO UDF: %s\n", rc ? "NO" : "YES"); + + return rc; +} + +static grub_err_t ventoy_cmd_cmp(grub_extcmd_context_t ctxt, int argc, char **args) +{ + long value_long1 = 0; + long value_long2 = 0; + + if ((argc != 3) || (!ventoy_is_decimal(args[0])) || (!ventoy_is_decimal(args[2]))) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {Int1} { eq|ne|gt|lt|ge|le } {Int2}", cmd_raw_name); + } + + value_long1 = grub_strtol(args[0], NULL, 10); + value_long2 = grub_strtol(args[2], NULL, 10); + + if (0 == grub_strcmp(args[1], "eq")) + { + grub_errno = (value_long1 == value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE; + } + else if (0 == grub_strcmp(args[1], "ne")) + { + grub_errno = (value_long1 != value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE; + } + else if (0 == grub_strcmp(args[1], "gt")) + { + grub_errno = (value_long1 > value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE; + } + else if (0 == grub_strcmp(args[1], "lt")) + { + grub_errno = (value_long1 < value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE; + } + else if (0 == grub_strcmp(args[1], "ge")) + { + grub_errno = (value_long1 >= value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE; + } + else if (0 == grub_strcmp(args[1], "le")) + { + grub_errno = (value_long1 <= value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE; + } + else + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {Int1} { eq ne gt lt ge le } {Int2}", cmd_raw_name); + } + + return grub_errno; +} + +static grub_err_t ventoy_cmd_device(grub_extcmd_context_t ctxt, int argc, char **args) +{ + char *pos = NULL; + char buf[128] = {0}; + + if (argc != 2) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s path var", cmd_raw_name); + } + + grub_strncpy(buf, (args[0][0] == '(') ? args[0] + 1 : args[0], sizeof(buf) - 1); + pos = grub_strstr(buf, ","); + if (pos) + { + *pos = 0; + } + + grub_env_set(args[1], buf); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_check_compatible(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + char buf[256]; + grub_disk_t disk; + char *pos = NULL; + const char *files[] = { "ventoy.dat", "VENTOY.DAT" }; + + (void)ctxt; + + if (argc != 1) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s (loop)", cmd_raw_name); + } + + for (i = 0; i < (int)ARRAY_SIZE(files); i++) + { + grub_snprintf(buf, sizeof(buf) - 1, "[ -e \"%s/%s\" ]", args[0], files[i]); + if (0 == grub_script_execute_sourcecode(buf)) + { + debug("file %s exist, ventoy_compatible YES\n", buf); + grub_env_set("ventoy_compatible", "YES"); + VENTOY_CMD_RETURN(GRUB_ERR_NONE); + } + else + { + debug("file %s NOT exist\n", buf); + } + } + + grub_snprintf(buf, sizeof(buf) - 1, "%s", args[0][0] == '(' ? (args[0] + 1) : args[0]); + pos = grub_strstr(buf, ")"); + if (pos) + { + *pos = 0; + } + + disk = grub_disk_open(buf); + if (disk) + { + grub_disk_read(disk, 16 << 2, 0, 1024, g_img_swap_tmp_buf); + grub_disk_close(disk); + + g_img_swap_tmp_buf[703] = 0; + for (i = 318; i < 703; i++) + { + if (g_img_swap_tmp_buf[i] == 'V' && + 0 == grub_strncmp(g_img_swap_tmp_buf + i, VENTOY_COMPATIBLE_STR, VENTOY_COMPATIBLE_STR_LEN)) + { + debug("Ventoy compatible string exist at %d, ventoy_compatible YES\n", i); + grub_env_set("ventoy_compatible", "YES"); + VENTOY_CMD_RETURN(GRUB_ERR_NONE); + } + } + } + else + { + debug("failed to open disk <%s>\n", buf); + } + + grub_env_set("ventoy_compatible", "NO"); + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +int ventoy_cmp_img(img_info *img1, img_info *img2) +{ + char *s1, *s2; + int c1 = 0; + int c2 = 0; + + if (g_plugin_image_list == VENTOY_IMG_WHITE_LIST) + { + return (img1->plugin_list_index - img2->plugin_list_index); + } + + for (s1 = img1->name, s2 = img2->name; *s1 && *s2; s1++, s2++) + { + c1 = *s1; + c2 = *s2; + + if (0 == g_sort_case_sensitive) + { + if (grub_islower(c1)) + { + c1 = c1 - 'a' + 'A'; + } + + if (grub_islower(c2)) + { + c2 = c2 - 'a' + 'A'; + } + } + + if (c1 != c2) + { + break; + } + } + + return (c1 - c2); +} + +static int ventoy_cmp_subdir(img_iterator_node *node1, img_iterator_node *node2) +{ + int i = 0; + int c1 = 0; + int c2 = 0; + int len = 0; + char *s1, *s2; + + if (g_plugin_image_list == VENTOY_IMG_WHITE_LIST) + { + return (node1->plugin_list_index - node2->plugin_list_index); + } + + s1 = node1->dir; + s2 = node2->dir; + len = grub_min(node1->dirlen, node2->dirlen); + + for (i = 0; i < len - 1; i++) + { + c1 = *s1++; + c2 = *s2++; + + if (0 == g_sort_case_sensitive) + { + if (grub_islower(c1)) + { + c1 = c1 - 'a' + 'A'; + } + + if (grub_islower(c2)) + { + c2 = c2 - 'a' + 'A'; + } + } + + if (c1 != c2) + { + return (c1 - c2); + } + } + + if (len == node1->dirlen) + { + c1 = 0; + } + + if (len == node2->dirlen) + { + c2 = 0; + } + + return (c1 - c2); +} + +void ventoy_swap_img(img_info *img1, img_info *img2) +{ + grub_memcpy(&g_img_swap_tmp, img1, sizeof(img_info)); + + grub_memcpy(img1, img2, sizeof(img_info)); + img1->next = g_img_swap_tmp.next; + img1->prev = g_img_swap_tmp.prev; + + g_img_swap_tmp.next = img2->next; + g_img_swap_tmp.prev = img2->prev; + grub_memcpy(img2, &g_img_swap_tmp, sizeof(img_info)); +} + +int ventoy_img_name_valid(const char *filename, grub_size_t namelen) +{ + (void)namelen; + + if (g_filt_dot_underscore_file && filename[0] == '.' && filename[1] == '_') + { + return 0; + } + + return 1; +} + +static int ventoy_vlnk_iterate_partition(struct grub_disk *disk, const grub_partition_t partition, void *data) +{ + ventoy_vlnk_part *node = NULL; + grub_uint32_t SelfSig; + grub_uint32_t *pSig = (grub_uint32_t *)data; + + /* skip Ventoy partition 1/2 */ + grub_memcpy(&SelfSig, g_ventoy_part_info->MBR.BootCode + 0x1b8, 4); + if (partition->number < 2 && SelfSig == *pSig) + { + return 0; + } + + node = grub_zalloc(sizeof(ventoy_vlnk_part)); + if (node) + { + node->disksig = *pSig; + node->partoffset = (partition->start << GRUB_DISK_SECTOR_BITS); + grub_snprintf(node->disk, sizeof(node->disk) - 1, "%s", disk->name); + grub_snprintf(node->device, sizeof(node->device) - 1, "%s,%d", disk->name, partition->number + 1); + + node->next = g_vlnk_part_list; + g_vlnk_part_list = node; + } + + return 0; +} + +static int ventoy_vlnk_iterate_disk(const char *name, void *data) +{ + grub_disk_t disk; + grub_uint32_t sig; + + (void)data; + + disk = grub_disk_open(name); + if (disk) + { + grub_disk_read(disk, 0, 0x1b8, 4, &sig); + grub_partition_iterate(disk, ventoy_vlnk_iterate_partition, &sig); + grub_disk_close(disk); + } + + return 0; +} + +static int ventoy_vlnk_probe_fs(ventoy_vlnk_part *cur) +{ + const char *fs[ventoy_fs_max + 1] = + { + "exfat", "ntfs", "ext2", "xfs", "udf", "fat", "btrfs", NULL + }; + + if (!cur->dev) + { + cur->dev = grub_device_open(cur->device); + } + + if (cur->dev) + { + cur->fs = grub_fs_list_probe(cur->dev, fs); + } + + return 0; +} + +static int ventoy_check_vlnk_data(ventoy_vlnk *vlnk, int print, char *dst, int size) +{ + int diskfind = 0; + int partfind = 0; + int filefind = 0; + char *disk, *device; + grub_uint32_t readcrc, calccrc; + ventoy_vlnk_part *cur; + grub_fs_t fs = NULL; + + if (grub_memcmp(&(vlnk->guid), &g_ventoy_guid, sizeof(ventoy_guid))) + { + if (print) + { + grub_printf("VLNK invalid guid\n"); + grub_refresh(); + } + return 1; + } + + readcrc = vlnk->crc32; + vlnk->crc32 = 0; + calccrc = grub_getcrc32c(0, vlnk, sizeof(ventoy_vlnk)); + if (readcrc != calccrc) + { + if (print) + { + grub_printf("VLNK invalid crc 0x%08x 0x%08x\n", calccrc, readcrc); + grub_refresh(); + } + return 1; + } + + if (!g_vlnk_part_list) + { + grub_disk_dev_iterate(ventoy_vlnk_iterate_disk, NULL); + } + + for (cur = g_vlnk_part_list; cur && filefind == 0; cur = cur->next) + { + if (cur->disksig == vlnk->disk_signature) + { + diskfind = 1; + disk = cur->disk; + if (cur->partoffset == vlnk->part_offset) + { + partfind = 1; + device = cur->device; + + if (cur->probe == 0) + { + cur->probe = 1; + ventoy_vlnk_probe_fs(cur); + } + + if (!fs) + { + fs = cur->fs; + } + + if (cur->fs) + { + struct grub_file file; + + grub_memset(&file, 0, sizeof(file)); + file.device = cur->dev; + if (cur->fs->fs_open(&file, vlnk->filepath) == GRUB_ERR_NONE) + { + filefind = 1; + cur->fs->fs_close(&file); + grub_snprintf(dst, size - 1, "(%s)%s", cur->device, vlnk->filepath); + } + else + { + grub_errno = 0; + } + } + } + } + } + + if (print) + { + grub_printf("\n==== VLNK Information ====\n" + "Disk Signature: %08x\n" + "Partition Offset: %llu\n" + "File Path: <%s>\n\n", + vlnk->disk_signature, (ulonglong)vlnk->part_offset, vlnk->filepath); + + if (diskfind) + { + grub_printf("Disk Find: [ YES ] [ %s ]\n", disk); + } + else + { + grub_printf("Disk Find: [ NO ]\n"); + } + + if (partfind) + { + grub_printf("Part Find: [ YES ] [ %s ] [ %s ]\n", device, fs ? fs->name : "N/A"); + } + else + { + grub_printf("Part Find: [ NO ]\n"); + } + grub_printf("File Find: [ %s ]\n", filefind ? "YES" : "NO"); + if (filefind) + { + grub_printf("VLNK File: <%s>\n", dst); + } + + grub_printf("\n"); + grub_refresh(); + } + + return (1 - filefind); +} + +int ventoy_add_vlnk_file(char *dir, const char *name) +{ + int rc = 1; + char src[512]; + char dst[512]; + grub_file_t file = NULL; + ventoy_vlnk vlnk; + + if (!dir) + { + grub_snprintf(src, sizeof(src), "%s%s", g_iso_path, name); + } + else if (dir[0] == '/') + { + grub_snprintf(src, sizeof(src), "%s%s%s", g_iso_path, dir, name); + } + else + { + grub_snprintf(src, sizeof(src), "%s/%s%s", g_iso_path, dir, name); + } + + file = grub_file_open(src, VENTOY_FILE_TYPE); + if (!file) + { + return 1; + } + + grub_memset(&vlnk, 0, sizeof(vlnk)); + grub_file_read(file, &vlnk, sizeof(vlnk)); + grub_file_close(file); + + if (ventoy_check_vlnk_data(&vlnk, 0, dst, sizeof(dst)) == 0) + { + rc = grub_file_add_vlnk(src, dst); + } + + return rc; +} + +static int ventoy_collect_img_files(const char *filename, const struct grub_dirhook_info *info, void *data) +{ + //int i = 0; + int type = 0; + int ignore = 0; + int index = 0; + int vlnk = 0; + grub_size_t len; + img_info *img; + img_info *tail; + const menu_tip *tip; + img_iterator_node *tmp; + img_iterator_node *new_node; + img_iterator_node *node = (img_iterator_node *)data; + + if (g_enumerate_time_checked == 0) + { + g_enumerate_finish_time_ms = grub_get_time_ms(); + if ((g_enumerate_finish_time_ms - g_enumerate_start_time_ms) >= 3000) + { + grub_cls(); + grub_printf("\n\n Ventoy scanning files, please wait...\n"); + grub_refresh(); + g_enumerate_time_checked = 1; + } + } + + len = grub_strlen(filename); + + if (info->dir) + { + if (node->level + 1 > g_img_max_search_level) + { + return 0; + } + + if ((len == 1 && filename[0] == '.') || + (len == 2 && filename[0] == '.' && filename[1] == '.')) + { + return 0; + } + + if (!ventoy_img_name_valid(filename, len)) + { + return 0; + } + + if (g_filt_trash_dir) + { + if (0 == grub_strncmp(filename, ".trash-", 7) || + 0 == grub_strcmp(filename, ".Trashes") || + 0 == grub_strncmp(filename, "$RECYCLE.BIN", 12)) + { + return 0; + } + } + + if (g_plugin_image_list == VENTOY_IMG_WHITE_LIST) + { + grub_snprintf(g_img_swap_tmp_buf, sizeof(g_img_swap_tmp_buf), "%s%s/", node->dir, filename); + index = ventoy_plugin_get_image_list_index(vtoy_class_directory, g_img_swap_tmp_buf); + if (index == 0) + { + debug("Directory %s not found in image_list plugin config...\n", g_img_swap_tmp_buf); + return 0; + } + } + + new_node = grub_zalloc(sizeof(img_iterator_node)); + if (new_node) + { + new_node->level = node->level + 1; + new_node->plugin_list_index = index; + new_node->dirlen = grub_snprintf(new_node->dir, sizeof(new_node->dir), "%s%s/", node->dir, filename); + + g_enum_fs->fs_dir(g_enum_dev, new_node->dir, ventoy_check_ignore_flag, &ignore); + if (ignore) + { + debug("Directory %s ignored...\n", new_node->dir); + grub_free(new_node); + return 0; + } + + new_node->tail = node->tail; + + new_node->parent = node; + if (!node->firstchild) + { + node->firstchild = new_node; + } + + if (g_img_iterator_tail) + { + g_img_iterator_tail->next = new_node; + g_img_iterator_tail = new_node; + } + else + { + g_img_iterator_head.next = new_node; + g_img_iterator_tail = new_node; + } + } + } + else + { + debug("Find a file %s\n", filename); + if (len < 4) + { + return 0; + } + + if (FILE_FLT(ISO) && 0 == grub_strcasecmp(filename + len - 4, ".iso")) + { + type = img_type_iso; + } + else if (FILE_FLT(WIM) && g_wimboot_enable && (0 == grub_strcasecmp(filename + len - 4, ".wim"))) + { + type = img_type_wim; + } + else if (FILE_FLT(VHD) && g_vhdboot_enable && (0 == grub_strcasecmp(filename + len - 4, ".vhd") || + (len >= 5 && 0 == grub_strcasecmp(filename + len - 5, ".vhdx")))) + { + type = img_type_vhd; + } + #ifdef GRUB_MACHINE_EFI + else if (FILE_FLT(EFI) && 0 == grub_strcasecmp(filename + len - 4, ".efi")) + { + type = img_type_efi; + } + #endif + else if (FILE_FLT(IMG) && 0 == grub_strcasecmp(filename + len - 4, ".img")) + { + if (len == 18 && grub_strncmp(filename, "ventoy_", 7) == 0) + { + if (grub_strncmp(filename + 7, "wimboot", 7) == 0 || + grub_strncmp(filename + 7, "vhdboot", 7) == 0) + { + return 0; + } + } + type = img_type_img; + } + else if (FILE_FLT(VTOY) && len >= 5 && 0 == grub_strcasecmp(filename + len - 5, ".vtoy")) + { + type = img_type_vtoy; + } + else if (len >= 9 && 0 == grub_strcasecmp(filename + len - 5, ".vcfg")) + { + if (filename[len - 9] == '.' || (len >= 10 && filename[len - 10] == '.')) + { + grub_snprintf(g_img_swap_tmp_buf, sizeof(g_img_swap_tmp_buf), "%s%s", node->dir, filename); + ventoy_plugin_add_custom_boot(g_img_swap_tmp_buf); + } + return 0; + } + else + { + return 0; + } + + if (g_filt_dot_underscore_file && filename[0] == '.' && filename[1] == '_') + { + return 0; + } + + if (g_plugin_image_list) + { + grub_snprintf(g_img_swap_tmp_buf, sizeof(g_img_swap_tmp_buf), "%s%s", node->dir, filename); + index = ventoy_plugin_get_image_list_index(vtoy_class_image_file, g_img_swap_tmp_buf); + if (VENTOY_IMG_WHITE_LIST == g_plugin_image_list && index == 0) + { + debug("File %s not found in image_list plugin config...\n", g_img_swap_tmp_buf); + return 0; + } + else if (VENTOY_IMG_BLACK_LIST == g_plugin_image_list && index > 0) + { + debug("File %s found in image_blacklist plugin config %d ...\n", g_img_swap_tmp_buf, index); + return 0; + } + } + + if (info->size == VTOY_FILT_MIN_FILE_SIZE || info->size == 0) + { + if (grub_file_is_vlnk_suffix(filename, len)) + { + vlnk = 1; + if (ventoy_add_vlnk_file(node->dir, filename) != 0) + { + return 0; + } + } + } + + img = grub_zalloc(sizeof(img_info)); + if (img) + { + img->type = type; + img->plugin_list_index = index; + grub_snprintf(img->name, sizeof(img->name), "%s", filename); + + img->pathlen = grub_snprintf(img->path, sizeof(img->path), "%s%s", node->dir, img->name); + + img->size = info->size; + if (vlnk || 0 == img->size) + { + if (node->dir[0] == '/') + { + img->size = ventoy_grub_get_file_size("%s%s%s", g_iso_path, node->dir, filename); + } + else + { + img->size = ventoy_grub_get_file_size("%s/%s%s", g_iso_path, node->dir, filename); + } + } + + if (img->size < VTOY_FILT_MIN_FILE_SIZE) + { + debug("img <%s> size too small %llu\n", img->name, (ulonglong)img->size); + grub_free(img); + return 0; + } + + if (g_ventoy_img_list) + { + tail = *(node->tail); + img->prev = tail; + tail->next = img; + } + else + { + g_ventoy_img_list = img; + } + + img->id = g_ventoy_img_count; + img->parent = node; + if (node && NULL == node->firstiso) + { + node->firstiso = img; + } + + node->isocnt++; + tmp = node->parent; + while (tmp) + { + tmp->isocnt++; + tmp = tmp->parent; + } + + *((img_info **)(node->tail)) = img; + g_ventoy_img_count++; + + img->alias = ventoy_plugin_get_menu_alias(vtoy_alias_image_file, img->path); + + tip = ventoy_plugin_get_menu_tip(vtoy_tip_image_file, img->path); + if (tip) + { + img->tip1 = tip->tip1; + img->tip2 = tip->tip2; + } + + img->class = ventoy_plugin_get_menu_class(vtoy_class_image_file, img->name, img->path); + if (!img->class) + { + img->class = g_menu_class[type]; + } + img->menu_prefix = g_menu_prefix[type]; + + if (img_type_iso == type) + { + if (ventoy_plugin_check_memdisk(img->path)) + { + img->menu_prefix = "miso"; + } + } + else if (img_type_img == type) + { + if (ventoy_plugin_check_memdisk(img->path)) + { + img->menu_prefix = "mimg"; + } + } + + debug("Add %s%s to list %d\n", node->dir, filename, g_ventoy_img_count); + } + } + + return 0; +} + +int ventoy_fill_data(grub_uint32_t buflen, char *buffer) +{ + int len = GRUB_UINT_MAX; + const char *value = NULL; + char name[32] = {0}; + char plat[32] = {0}; + char guidstr[32] = {0}; + ventoy_guid guid = VENTOY_GUID; + const char *fmt1 = NULL; + const char *fmt2 = NULL; + const char *fmt3 = NULL; + grub_uint32_t *puint = (grub_uint32_t *)name; + grub_uint32_t *puint2 = (grub_uint32_t *)plat; + const char fmtdata[]={ 0x39, 0x35, 0x25, 0x00, 0x35, 0x00, 0x23, 0x30, 0x30, 0x30, 0x30, 0x66, 0x66, 0x00 }; + const char fmtcode[]={ + 0x22, 0x0A, 0x2B, 0x20, 0x68, 0x62, 0x6F, 0x78, 0x20, 0x7B, 0x0A, 0x20, 0x20, 0x74, 0x6F, 0x70, + 0x20, 0x3D, 0x20, 0x25, 0x73, 0x0A, 0x20, 0x20, 0x6C, 0x65, 0x66, 0x74, 0x20, 0x3D, 0x20, 0x25, + 0x73, 0x0A, 0x20, 0x20, 0x2B, 0x20, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x7B, 0x74, 0x65, 0x78, + 0x74, 0x20, 0x3D, 0x20, 0x22, 0x25, 0x73, 0x20, 0x25, 0x73, 0x25, 0x73, 0x22, 0x20, 0x63, 0x6F, + 0x6C, 0x6F, 0x72, 0x20, 0x3D, 0x20, 0x22, 0x25, 0x73, 0x22, 0x20, 0x61, 0x6C, 0x69, 0x67, 0x6E, + 0x20, 0x3D, 0x20, 0x22, 0x6C, 0x65, 0x66, 0x74, 0x22, 0x7D, 0x0A, 0x7D, 0x0A, 0x22, 0x00 + }; + + grub_memset(name, 0, sizeof(name)); + puint[0] = grub_swap_bytes32(0x56454e54); + puint[3] = grub_swap_bytes32(0x4f4e0000); + puint[2] = grub_swap_bytes32(0x45525349); + puint[1] = grub_swap_bytes32(0x4f595f56); + value = ventoy_get_env(name); + + grub_memset(name, 0, sizeof(name)); + puint[1] = grub_swap_bytes32(0x5f544f50); + puint[0] = grub_swap_bytes32(0x56544c45); + fmt1 = ventoy_get_env(name); + if (!fmt1) + { + fmt1 = fmtdata; + } + + grub_memset(name, 0, sizeof(name)); + puint[1] = grub_swap_bytes32(0x5f4c4654); + puint[0] = grub_swap_bytes32(0x56544c45); + fmt2 = ventoy_get_env(name); + + grub_memset(name, 0, sizeof(name)); + puint[1] = grub_swap_bytes32(0x5f434c52); + puint[0] = grub_swap_bytes32(0x56544c45); + fmt3 = ventoy_get_env(name); + + grub_memcpy(guidstr, &guid, sizeof(guid)); + + puint2[0] = grub_swap_bytes32(g_ventoy_plat_data); + + /* Easter egg :) It will be appreciated if you reserve it, but NOT mandatory. */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wformat-nonliteral" + len = grub_snprintf(buffer, buflen, fmtcode, + fmt1 ? fmt1 : fmtdata, + fmt2 ? fmt2 : fmtdata + 4, + value ? value : "", plat, guidstr, + fmt3 ? fmt3 : fmtdata + 6); + #pragma GCC diagnostic pop + + grub_memset(name, 0, sizeof(name)); + puint[0] = grub_swap_bytes32(0x76746f79); + puint[2] = grub_swap_bytes32(0x656e7365); + puint[1] = grub_swap_bytes32(0x5f6c6963); + ventoy_set_env(name, guidstr); + + return len; +} + +static int +ventoy_password_get (char buf[], unsigned buf_size) +{ + unsigned i, cur_len = 0; + int key; + struct grub_term_coordinate *pos = grub_term_save_pos (); + + while (1) + { + key = grub_getkey (); + if (key == '\n' || key == '\r') + break; + + if (key == GRUB_TERM_ESC) + { + cur_len = 0; + break; + } + + if (key == '\b') + { + if (cur_len) + { + grub_term_restore_pos (pos); + for (i = 0; i < cur_len; i++) + grub_xputs (" "); + grub_term_restore_pos (pos); + cur_len--; + for (i = 0; i < cur_len; i++) + grub_xputs ("*"); + grub_refresh (); + } + continue; + } + + if (!grub_isprint (key)) + continue; + + if (cur_len + 2 < buf_size) + buf[cur_len++] = key; + grub_xputs ("*"); + grub_refresh (); + } + + grub_memset (buf + cur_len, 0, buf_size - cur_len); + + grub_xputs ("\n"); + grub_refresh (); + grub_free (pos); + + return (key != GRUB_TERM_ESC); +} + +static int ventoy_get_password(char buf[], unsigned buf_size) +{ + const char *env = NULL; + + env = grub_env_get("VTOY_SHOW_PASSWORD_ASTERISK"); + if (env && env[0] == '0' && env[1] == 0) + { + return grub_password_get(buf, buf_size); + } + else + { + return ventoy_password_get(buf, buf_size); + } +} + +int ventoy_check_password(const vtoy_password *pwd, int retry) +{ + int offset; + char input[256]; + grub_uint8_t md5[16]; + + while (retry--) + { + grub_memset(input, 0, sizeof(input)); + + grub_printf("Enter password: "); + grub_refresh(); + + if (pwd->type == VTOY_PASSWORD_TXT) + { + ventoy_get_password(input, 128); + if (grub_strcmp(pwd->text, input) == 0) + { + return 0; + } + } + else if (pwd->type == VTOY_PASSWORD_MD5) + { + ventoy_get_password(input, 128); + grub_crypto_hash(GRUB_MD_MD5, md5, input, grub_strlen(input)); + if (grub_memcmp(pwd->md5, md5, 16) == 0) + { + return 0; + } + } + else if (pwd->type == VTOY_PASSWORD_SALT_MD5) + { + offset = (int)grub_snprintf(input, 128, "%s", pwd->salt); + ventoy_get_password(input + offset, 128); + + grub_crypto_hash(GRUB_MD_MD5, md5, input, grub_strlen(input)); + if (grub_memcmp(pwd->md5, md5, 16) == 0) + { + return 0; + } + } + + grub_printf("Invalid password!\n\n"); + grub_refresh(); + } + + return 1; +} + +static img_info * ventoy_get_min_iso(img_iterator_node *node) +{ + img_info *minimg = NULL; + img_info *img = (img_info *)(node->firstiso); + + while (img && (img_iterator_node *)(img->parent) == node) + { + if (img->select == 0 && (NULL == minimg || ventoy_cmp_img(img, minimg) < 0)) + { + minimg = img; + } + img = img->next; + } + + if (minimg) + { + minimg->select = 1; + } + + return minimg; +} + +static img_iterator_node * ventoy_get_min_child(img_iterator_node *node) +{ + img_iterator_node *Minchild = NULL; + img_iterator_node *child = node->firstchild; + + while (child && child->parent == node) + { + if (child->select == 0 && (NULL == Minchild || ventoy_cmp_subdir(child, Minchild) < 0)) + { + Minchild = child; + } + child = child->next; + } + + if (Minchild) + { + Minchild->select = 1; + } + + return Minchild; +} + +static int ventoy_dynamic_tree_menu(img_iterator_node *node) +{ + int offset = 1; + img_info *img = NULL; + const char *dir_class = NULL; + const char *dir_alias = NULL; + img_iterator_node *child = NULL; + const menu_tip *tip = NULL; + + if (node->isocnt == 0 || node->done == 1) + { + return 0; + } + + if (node->parent && node->parent->dirlen < node->dirlen) + { + offset = node->parent->dirlen; + } + + if (node == &g_img_iterator_head) + { + if (g_default_menu_mode == 0) + { + if (g_tree_view_menu_style == 0) + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "menuentry \"%-10s [%s]\" --class=\"vtoyret\" VTOY_RET {\n " + " echo 'return ...' \n" + "}\n", "<--", ventoy_get_vmenu_title("VTLANG_RET_TO_LISTVIEW")); + } + else + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "menuentry \"[%s]\" --class=\"vtoyret\" VTOY_RET {\n " + " echo 'return ...' \n" + "}\n", ventoy_get_vmenu_title("VTLANG_RET_TO_LISTVIEW")); + } + } + + g_tree_script_pre = g_tree_script_pos; + } + else + { + node->dir[node->dirlen - 1] = 0; + dir_class = ventoy_plugin_get_menu_class(vtoy_class_directory, node->dir, node->dir); + if (!dir_class) + { + dir_class = "vtoydir"; + } + + tip = ventoy_plugin_get_menu_tip(vtoy_tip_directory, node->dir); + + dir_alias = ventoy_plugin_get_menu_alias(vtoy_alias_directory, node->dir); + if (dir_alias) + { + if (g_tree_view_menu_style == 0) + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "submenu \"%-10s %s\" --class=\"%s\" --id=\"DIR_%s\" _VTIP_%p {\n", + "DIR", dir_alias, dir_class, node->dir + offset, tip); + } + else + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "submenu \"%s\" --class=\"%s\" --id=\"DIR_%s\" _VTIP_%p {\n", + dir_alias, dir_class, node->dir + offset, tip); + } + } + else + { + dir_alias = node->dir + offset; + + if (g_tree_view_menu_style == 0) + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "submenu \"%-10s [%s]\" --class=\"%s\" --id=\"DIR_%s\" _VTIP_%p {\n", + "DIR", dir_alias, dir_class, node->dir + offset, tip); + } + else + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "submenu \"[%s]\" --class=\"%s\" --id=\"DIR_%s\" _VTIP_%p {\n", + dir_alias, dir_class, node->dir + offset, tip); + } + } + + if (g_tree_view_menu_style == 0) + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "menuentry \"%-10s [%s/..]\" --class=\"vtoyret\" VTOY_RET {\n " + " echo 'return ...' \n" + "}\n", "<--", node->dir); + } + else + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "menuentry \"[%s/..]\" --class=\"vtoyret\" VTOY_RET {\n " + " echo 'return ...' \n" + "}\n", node->dir); + } + } + + while ((child = ventoy_get_min_child(node)) != NULL) + { + ventoy_dynamic_tree_menu(child); + } + + while ((img = ventoy_get_min_iso(node)) != NULL) + { + if (g_tree_view_menu_style == 0) + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "menuentry \"%-10s %s%s\" --class=\"%s\" --id=\"VID_%p\" {\n" + " %s_%s \n" + "}\n", + grub_get_human_size(img->size, GRUB_HUMAN_SIZE_SHORT), + img->unsupport ? "[***********] " : "", + img->alias ? img->alias : img->name, img->class, img, + img->menu_prefix, + img->unsupport ? "unsupport_menuentry" : "common_menuentry"); + } + else + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "menuentry \"%s%s\" --class=\"%s\" --id=\"VID_%p\" {\n" + " %s_%s \n" + "}\n", + img->unsupport ? "[***********] " : "", + img->alias ? img->alias : img->name, img->class, img, + img->menu_prefix, + img->unsupport ? "unsupport_menuentry" : "common_menuentry"); + } + } + + if (node != &g_img_iterator_head) + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, "}\n"); + } + + node->done = 1; + return 0; +} + +static int ventoy_set_default_menu(void) +{ + int img_len = 0; + char *pos = NULL; + char *end = NULL; + char *def = NULL; + const char *strdata = NULL; + img_info *cur = NULL; + img_info *default_node = NULL; + const char *default_image = NULL; + + default_image = ventoy_get_env("VTOY_DEFAULT_IMAGE"); + if (default_image && default_image[0] == '/') + { + img_len = grub_strlen(default_image); + + for (cur = g_ventoy_img_list; cur; cur = cur->next) + { + if (img_len == cur->pathlen && grub_strcmp(default_image, cur->path) == 0) + { + default_node = cur; + break; + } + } + + if (!default_node) + { + return 1; + } + + if (0 == g_default_menu_mode) + { + vtoy_ssprintf(g_list_script_buf, g_list_script_pos, "set default='VID_%p'\n", default_node); + } + else + { + def = grub_strdup(default_image); + if (!def) + { + return 1; + } + + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, "set default=%c", '\''); + + strdata = ventoy_get_env("VTOY_DEFAULT_SEARCH_ROOT"); + if (strdata && strdata[0] == '/') + { + pos = def + grub_strlen(strdata); + if (*pos == '/') + { + pos++; + } + } + else + { + pos = def + 1; + } + + while ((end = grub_strchr(pos, '/')) != NULL) + { + *end = 0; + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, "DIR_%s>", pos); + pos = end + 1; + } + + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, "VID_%p'\n", default_node); + grub_free(def); + } + } + + return 0; +} + +static grub_err_t ventoy_cmd_clear_img(grub_extcmd_context_t ctxt, int argc, char **args) +{ + img_info *next = NULL; + img_info *cur = g_ventoy_img_list; + + (void)ctxt; + (void)argc; + (void)args; + + while (cur) + { + next = cur->next; + grub_free(cur); + cur = next; + } + + g_ventoy_img_list = NULL; + g_ventoy_img_count = 0; + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_img_name(grub_extcmd_context_t ctxt, int argc, char **args) +{ + long img_id = 0; + img_info *cur = g_ventoy_img_list; + + (void)ctxt; + + if (argc != 2 || (!ventoy_is_decimal(args[0]))) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {imageID} {var}", cmd_raw_name); + } + + img_id = grub_strtol(args[0], NULL, 10); + if (img_id >= g_ventoy_img_count) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "No such many images %ld %ld", img_id, g_ventoy_img_count); + } + + debug("Find image %ld name \n", img_id); + + while (cur && img_id > 0) + { + img_id--; + cur = cur->next; + } + + if (!cur) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "No such many images"); + } + + debug("image name is %s\n", cur->name); + + grub_env_set(args[1], cur->name); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_ext_select_img_path(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int len = 0; + char id[32] = {0}; + img_info *cur = g_ventoy_img_list; + + (void)ctxt; + + if (argc != 1) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {var}", cmd_raw_name); + } + + len = (int)grub_strlen(args[0]); + + while (cur) + { + if (len == cur->pathlen && 0 == grub_strcmp(args[0], cur->path)) + { + break; + } + cur = cur->next; + } + + if (!cur) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "No such image"); + } + + grub_snprintf(id, sizeof(id), "VID_%p", cur); + grub_env_set("chosen", id); + grub_env_export("chosen"); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static char g_fake_vlnk_src[512]; +static char g_fake_vlnk_dst[512]; +static grub_uint64_t g_fake_vlnk_size; +static grub_err_t ventoy_cmd_set_fake_vlnk(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + g_fake_vlnk_size = (grub_uint64_t)grub_strtoull(args[2], NULL, 10); + + grub_strncpy(g_fake_vlnk_dst, args[0], sizeof(g_fake_vlnk_dst)); + grub_snprintf(g_fake_vlnk_src, sizeof(g_fake_vlnk_src), "%s/________VENTOYVLNK.vlnk.%s", g_iso_path, args[1]); + + grub_file_vtoy_vlnk(g_fake_vlnk_src, g_fake_vlnk_dst); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_reset_fake_vlnk(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + g_fake_vlnk_src[0] = 0; + g_fake_vlnk_dst[0] = 0; + g_fake_vlnk_size = 0; + grub_file_vtoy_vlnk(NULL, NULL); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + + +static grub_err_t ventoy_cmd_chosen_img_path(grub_extcmd_context_t ctxt, int argc, char **args) +{ + char value[32]; + char *pos = NULL; + char *last = NULL; + const char *id = NULL; + img_info *cur = NULL; + + (void)ctxt; + + if (argc < 1 || argc > 3) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {var}", cmd_raw_name); + } + + if (g_fake_vlnk_src[0] && g_fake_vlnk_dst[0]) + { + pos = grub_strchr(g_fake_vlnk_src, '/'); + grub_env_set(args[0], pos); + if (argc > 1) + { + grub_snprintf(value, sizeof(value), "%llu", (ulonglong)(g_fake_vlnk_size)); + grub_env_set(args[1], value); + } + + if (argc > 2) + { + for (last = pos; *pos; pos++) + { + if (*pos == '/') + { + last = pos; + } + } + grub_env_set(args[2], last + 1); + } + + goto end; + } + + id = grub_env_get("chosen"); + + pos = grub_strstr(id, "VID_"); + if (pos) + { + cur = (img_info *)(void *)grub_strtoul(pos + 4, NULL, 16); + } + else + { + cur = g_ventoy_img_list; + } + + if (!cur) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "No such image"); + } + + grub_env_set(args[0], cur->path); + + if (argc > 1) + { + grub_snprintf(value, sizeof(value), "%llu", (ulonglong)(cur->size)); + grub_env_set(args[1], value); + } + + if (argc > 2) + { + grub_snprintf(value, sizeof(value), "%llu", (ulonglong)(cur->size)); + grub_env_set(args[2], cur->name); + } + +end: + g_svd_replace_offset = 0; + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + + +static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int len; + grub_fs_t fs; + grub_device_t dev = NULL; + img_info *cur = NULL; + img_info *tail = NULL; + img_info *min = NULL; + img_info *head = NULL; + const char *strdata = NULL; + char *device_name = NULL; + char buf[32]; + img_iterator_node *node = NULL; + img_iterator_node *tmp = NULL; + + (void)ctxt; + + if (argc != 2) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {device} {cntvar}", cmd_raw_name); + } + + if (g_ventoy_img_list || g_ventoy_img_count) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Must clear image before list"); + } + + VTOY_CMD_CHECK(1); + + g_enumerate_time_checked = 0; + g_enumerate_start_time_ms = grub_get_time_ms(); + + strdata = ventoy_get_env("VTOY_FILT_DOT_UNDERSCORE_FILE"); + if (strdata && strdata[0] == '1' && strdata[1] == 0) + { + g_filt_dot_underscore_file = 1; + } + + strdata = ventoy_get_env("VTOY_FILT_TRASH_DIR"); + if (strdata && strdata[0] == '0' && strdata[1] == 0) + { + g_filt_trash_dir = 0; + } + + strdata = ventoy_get_env("VTOY_SORT_CASE_SENSITIVE"); + if (strdata && strdata[0] == '1' && strdata[1] == 0) + { + g_sort_case_sensitive = 1; + } + + device_name = grub_file_get_device_name(args[0]); + if (!device_name) + { + goto fail; + } + + g_enum_dev = dev = grub_device_open(device_name); + if (!dev) + { + goto fail; + } + + g_enum_fs = fs = grub_fs_probe(dev); + if (!fs) + { + goto fail; + } + + if (ventoy_get_fs_type(fs->name) >= ventoy_fs_max) + { + debug("unsupported fs:<%s>\n", fs->name); + ventoy_set_env("VTOY_NO_ISO_TIP", "unsupported file system"); + goto fail; + } + + ventoy_set_env("vtoy_iso_fs", fs->name); + + strdata = ventoy_get_env("VTOY_DEFAULT_MENU_MODE"); + if (strdata && strdata[0] == '1') + { + g_default_menu_mode = 1; + } + + grub_memset(&g_img_iterator_head, 0, sizeof(g_img_iterator_head)); + + grub_snprintf(g_iso_path, sizeof(g_iso_path), "%s", args[0]); + + strdata = ventoy_get_env("VTOY_DEFAULT_SEARCH_ROOT"); + if (strdata && strdata[0] == '/') + { + len = grub_snprintf(g_img_iterator_head.dir, sizeof(g_img_iterator_head.dir) - 1, "%s", strdata); + if (g_img_iterator_head.dir[len - 1] != '/') + { + g_img_iterator_head.dir[len++] = '/'; + } + g_img_iterator_head.dirlen = len; + } + else + { + g_img_iterator_head.dirlen = 1; + grub_strcpy(g_img_iterator_head.dir, "/"); + } + + g_img_iterator_head.tail = &tail; + + if (g_img_max_search_level < 0) + { + g_img_max_search_level = GRUB_INT_MAX; + strdata = ventoy_get_env("VTOY_MAX_SEARCH_LEVEL"); + if (strdata && ventoy_is_decimal(strdata)) + { + g_img_max_search_level = (int)grub_strtoul(strdata, NULL, 10); + } + } + + g_vtoy_file_flt[VTOY_FILE_FLT_ISO] = ventoy_control_get_flag("VTOY_FILE_FLT_ISO"); + g_vtoy_file_flt[VTOY_FILE_FLT_WIM] = ventoy_control_get_flag("VTOY_FILE_FLT_WIM"); + g_vtoy_file_flt[VTOY_FILE_FLT_EFI] = ventoy_control_get_flag("VTOY_FILE_FLT_EFI"); + g_vtoy_file_flt[VTOY_FILE_FLT_IMG] = ventoy_control_get_flag("VTOY_FILE_FLT_IMG"); + g_vtoy_file_flt[VTOY_FILE_FLT_VHD] = ventoy_control_get_flag("VTOY_FILE_FLT_VHD"); + g_vtoy_file_flt[VTOY_FILE_FLT_VTOY] = ventoy_control_get_flag("VTOY_FILE_FLT_VTOY"); + + for (node = &g_img_iterator_head; node; node = node->next) + { + fs->fs_dir(dev, node->dir, ventoy_collect_img_files, node); + } + + strdata = ventoy_get_env("VTOY_TREE_VIEW_MENU_STYLE"); + if (strdata && strdata[0] == '1' && strdata[1] == 0) + { + g_tree_view_menu_style = 1; + } + + ventoy_set_default_menu(); + + for (node = &g_img_iterator_head; node; node = node->next) + { + ventoy_dynamic_tree_menu(node); + } + + /* free node */ + node = g_img_iterator_head.next; + while (node) + { + tmp = node->next; + grub_free(node); + node = tmp; + } + + /* sort image list by image name */ + while (g_ventoy_img_list) + { + min = g_ventoy_img_list; + for (cur = g_ventoy_img_list->next; cur; cur = cur->next) + { + if (ventoy_cmp_img(min, cur) > 0) + { + min = cur; + } + } + + if (min->prev) + { + min->prev->next = min->next; + } + + if (min->next) + { + min->next->prev = min->prev; + } + + if (min == g_ventoy_img_list) + { + g_ventoy_img_list = min->next; + } + + if (head == NULL) + { + head = tail = min; + min->prev = NULL; + min->next = NULL; + } + else + { + tail->next = min; + min->prev = tail; + min->next = NULL; + tail = min; + } + } + + g_ventoy_img_list = head; + + if (g_default_menu_mode == 1) + { + vtoy_ssprintf(g_list_script_buf, g_list_script_pos, + "menuentry \"%s [%s]\" --class=\"vtoyret\" VTOY_RET {\n " + " echo 'return ...' \n" + "}\n", "<--", ventoy_get_vmenu_title("VTLANG_RET_TO_TREEVIEW")); + } + + for (cur = g_ventoy_img_list; cur; cur = cur->next) + { + vtoy_ssprintf(g_list_script_buf, g_list_script_pos, + "menuentry \"%s%s\" --class=\"%s\" --id=\"VID_%p\" {\n" + " %s_%s \n" + "}\n", + cur->unsupport ? "[***********] " : "", + cur->alias ? cur->alias : cur->name, cur->class, cur, + cur->menu_prefix, + cur->unsupport ? "unsupport_menuentry" : "common_menuentry"); + } + + g_tree_script_buf[g_tree_script_pos] = 0; + g_list_script_buf[g_list_script_pos] = 0; + + grub_snprintf(buf, sizeof(buf), "%d", g_ventoy_img_count); + grub_env_set(args[1], buf); + +fail: + + check_free(device_name, grub_free); + check_free(dev, grub_device_close); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +int ventoy_get_disk_guid(const char *filename, grub_uint8_t *guid, grub_uint8_t *signature) +{ + grub_disk_t disk; + char *device_name; + char *pos; + char *pos2; + + device_name = grub_file_get_device_name(filename); + if (!device_name) + { + return 1; + } + + pos = device_name; + if (pos[0] == '(') + { + pos++; + } + + pos2 = grub_strstr(pos, ","); + if (!pos2) + { + pos2 = grub_strstr(pos, ")"); + } + + if (pos2) + { + *pos2 = 0; + } + + disk = grub_disk_open(pos); + if (disk) + { + grub_disk_read(disk, 0, 0x180, 16, guid); + grub_disk_read(disk, 0, 0x1b8, 4, signature); + grub_disk_close(disk); + } + else + { + return 1; + } + + grub_free(device_name); + return 0; +} + +grub_uint32_t ventoy_get_iso_boot_catlog(grub_file_t file) +{ + eltorito_descriptor desc; + + grub_memset(&desc, 0, sizeof(desc)); + grub_file_seek(file, 17 * 2048); + grub_file_read(file, &desc, sizeof(desc)); + + if (desc.type != 0 || desc.version != 1) + { + return 0; + } + + if (grub_strncmp((char *)desc.id, "CD001", 5) != 0 || + grub_strncmp((char *)desc.system_id, "EL TORITO SPECIFICATION", 23) != 0) + { + return 0; + } + + return desc.sector; +} + +static grub_uint32_t ventoy_get_bios_eltorito_rba(grub_file_t file, grub_uint32_t sector) +{ + grub_uint8_t buf[512]; + + grub_file_seek(file, sector * 2048); + grub_file_read(file, buf, sizeof(buf)); + + if (buf[0] == 0x01 && buf[1] == 0x00 && + buf[30] == 0x55 && buf[31] == 0xaa && buf[32] == 0x88) + { + return *((grub_uint32_t *)(buf + 40)); + } + + return 0; +} + +int ventoy_has_efi_eltorito(grub_file_t file, grub_uint32_t sector) +{ + int i; + int x86count = 0; + grub_uint8_t buf[512]; + grub_uint8_t parttype[] = { 0x04, 0x06, 0x0B, 0x0C }; + + grub_file_seek(file, sector * 2048); + grub_file_read(file, buf, sizeof(buf)); + + if (buf[0] == 0x01 && buf[1] == 0xEF) + { + debug("%s efi eltorito in Validation Entry\n", file->name); + return 1; + } + + if (buf[0] == 0x01 && buf[1] == 0x00) + { + x86count++; + } + + for (i = 64; i < (int)sizeof(buf); i += 32) + { + if ((buf[i] == 0x90 || buf[i] == 0x91) && buf[i + 1] == 0xEF) + { + debug("%s efi eltorito offset %d 0x%02x\n", file->name, i, buf[i]); + return 1; + } + + if ((buf[i] == 0x90 || buf[i] == 0x91) && buf[i + 1] == 0x00 && x86count == 1) + { + debug("0x9100 assume %s efi eltorito offset %d 0x%02x\n", file->name, i, buf[i]); + return 1; + } + } + + if (x86count && buf[32] == 0x88 && buf[33] == 0x04) + { + for (i = 0; i < (int)(ARRAY_SIZE(parttype)); i++) + { + if (buf[36] == parttype[i]) + { + debug("hard disk image assume %s efi eltorito, part type 0x%x\n", file->name, buf[36]); + return 1; + } + } + } + + debug("%s does not contain efi eltorito\n", file->name); + return 0; +} + +void ventoy_fill_os_param(grub_file_t file, ventoy_os_param *param) +{ + char *pos; + const char *fs = NULL; + const char *val = NULL; + const char *cdprompt = NULL; + grub_uint32_t i; + grub_uint8_t chksum = 0; + grub_disk_t disk; + + disk = file->device->disk; + grub_memcpy(¶m->guid, &g_ventoy_guid, sizeof(ventoy_guid)); + + param->vtoy_disk_size = disk->total_sectors * (1 << disk->log_sector_size); + param->vtoy_disk_part_id = disk->partition->number + 1; + param->vtoy_disk_part_type = ventoy_get_fs_type(file->fs->name); + + pos = grub_strstr(file->name, "/"); + if (!pos) + { + pos = file->name; + } + + grub_snprintf(param->vtoy_img_path, sizeof(param->vtoy_img_path), "%s", pos); + + ventoy_get_disk_guid(file->name, param->vtoy_disk_guid, param->vtoy_disk_signature); + + param->vtoy_img_size = file->size; + + param->vtoy_reserved[0] = g_ventoy_break_level; + param->vtoy_reserved[1] = g_ventoy_debug_level; + + param->vtoy_reserved[2] = g_ventoy_chain_type; + + /* Windows CD/DVD prompt 0:suppress 1:reserved */ + param->vtoy_reserved[4] = 0; + if (g_ventoy_chain_type == 1) /* Windows */ + { + cdprompt = ventoy_get_env("VTOY_WINDOWS_CD_PROMPT"); + if (cdprompt && cdprompt[0] == '1' && cdprompt[1] == 0) + { + param->vtoy_reserved[4] = 1; + } + } + + fs = ventoy_get_env("ventoy_fs_probe"); + if (fs && grub_strcmp(fs, "udf") == 0) + { + param->vtoy_reserved[3] = 1; + } + + param->vtoy_reserved[5] = 0; + val = ventoy_get_env("VTOY_LINUX_REMOUNT"); + if (val && val[0] == '1' && val[1] == 0) + { + param->vtoy_reserved[5] = 1; + } + + /* ventoy_disk_signature used for vlnk */ + param->vtoy_reserved[6] = file->vlnk; + grub_memcpy(param->vtoy_reserved + 7, g_ventoy_part_info->MBR.BootCode + 0x1b8, 4); + + + /* Windows UEFI force resolution lock */ + if (g_ventoy_chain_type == 1) /* Windows */ + { + val = ventoy_get_env("VTOY_WIN_UEFI_RES_LOCK"); + if (val && val[1] == 0) + { + if (val[0] == '1') + { + param->vtoy_reserved[11] = 1; + } + else if (val[0] == '2') + { + param->vtoy_reserved[11] = 2; + } + } + } + + + /* calculate checksum */ + for (i = 0; i < sizeof(ventoy_os_param); i++) + { + chksum += *((grub_uint8_t *)param + i); + } + param->chksum = (grub_uint8_t)(0x100 - chksum); + + return; +} + +static const char* g_chunk_err_msg[VTOY_CHUNK_ERR_MAX] = +{ + "success", + "File system use more than 1 disks! (maybe RAID)", + "File system enable RAID feature, this is NOT supported!", + "File is compressed in disk, this is not supported!", + "File not flat in disk! (maybe compressed)", + "Read buffer overflow!", +}; + +static const char * ventoy_get_chunk_err_msg(grub_uint32_t err) +{ + if (err < VTOY_CHUNK_ERR_MAX) + { + return g_chunk_err_msg[err]; + } + + return "XXXX"; +} + +int ventoy_check_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, +grub_disk_addr_t start, char *err, grub_uint32_t len) +{ + grub_uint32_t i = 0; + grub_uint64_t total = 0; + grub_uint64_t fileblk = 0; + ventoy_img_chunk *chunk = NULL; + + if (chunklist->err_code) + { + if (err) + { + grub_snprintf(err, len, "%s", ventoy_get_chunk_err_msg(chunklist->err_code)); + } + + return 1; + } + + if (err) + { + grub_snprintf(err, len, "Unsupported chunk list."); + } + + for (i = 0; i < chunklist->cur_chunk; i++) + { + chunk = chunklist->chunk + i; + + if (chunk->disk_start_sector <= start) + { + debug("%u disk start invalid %lu\n", i, (ulong)start); + return 1; + } + + total += chunk->disk_end_sector + 1 - chunk->disk_start_sector; + } + + fileblk = (file->size + 511) / 512; + + if (total != fileblk) + { + debug("Invalid total: %llu %llu\n", (ulonglong)total, (ulonglong)fileblk); + if ((file->size % 512) && (total + 1 == fileblk)) + { + debug("maybe img file to be processed.\n"); + return 0; + } + + return 1; + } + + return 0; +} + +int ventoy_get_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start) +{ + int fs_type; + int len; + grub_uint32_t i = 0; + grub_uint32_t sector = 0; + grub_uint32_t count = 0; + grub_off_t size = 0; + grub_off_t read = 0; + + fs_type = ventoy_get_fs_type(file->fs->name); + if (fs_type == ventoy_fs_exfat) + { + grub_fat_get_file_chunk(start, file, chunklist); + } + else if (fs_type == ventoy_fs_ext) + { + grub_ext_get_file_chunk(start, file, chunklist); + } + else if (fs_type == ventoy_fs_btrfs) + { + grub_btrfs_get_file_chunk(start, file, chunklist); + } + else + { + file->read_hook = (grub_disk_read_hook_t)(void *)grub_disk_blocklist_read; + file->read_hook_data = chunklist; + + for (size = file->size; size > 0; size -= read) + { + read = (size > VTOY_SIZE_1GB) ? VTOY_SIZE_1GB : size; + grub_file_read(file, NULL, read); + } + + for (i = 0; start > 0 && i < chunklist->cur_chunk; i++) + { + chunklist->chunk[i].disk_start_sector += start; + chunklist->chunk[i].disk_end_sector += start; + } + + if (ventoy_fs_udf == fs_type) + { + for (i = 0; i < chunklist->cur_chunk; i++) + { + count = (chunklist->chunk[i].disk_end_sector + 1 - chunklist->chunk[i].disk_start_sector) >> 2; + chunklist->chunk[i].img_start_sector = sector; + chunklist->chunk[i].img_end_sector = sector + count - 1; + sector += count; + } + } + } + + len = (int)grub_strlen(file->name); + if ((len > 4 && grub_strncasecmp(file->name + len - 4, ".img", 4) == 0) || + (len > 4 && grub_strncasecmp(file->name + len - 4, ".vhd", 4) == 0) || + (len > 5 && grub_strncasecmp(file->name + len - 5, ".vhdx", 5) == 0) || + (len > 5 && grub_strncasecmp(file->name + len - 5, ".vtoy", 5) == 0)) + { + for (i = 0; i < chunklist->cur_chunk; i++) + { + count = chunklist->chunk[i].disk_end_sector + 1 - chunklist->chunk[i].disk_start_sector; + if (count < 4) + { + count = 1; + } + else + { + count >>= 2; + } + + chunklist->chunk[i].img_start_sector = sector; + chunklist->chunk[i].img_end_sector = sector + count - 1; + sector += count; + } + } + + return 0; +} + +static grub_err_t ventoy_cmd_img_sector(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int rc; + int fs_type; + grub_file_t file; + grub_disk_addr_t start; + char errmsg[128]; + + (void)ctxt; + (void)argc; + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't open file %s\n", args[0]); + } + + g_conf_replace_count = 0; + grub_memset(g_conf_replace_node, 0, sizeof(g_conf_replace_node )); + grub_memset(g_conf_replace_offset, 0, sizeof(g_conf_replace_offset )); + + if (g_img_chunk_list.chunk) + { + grub_free(g_img_chunk_list.chunk); + } + + fs_type = ventoy_get_fs_type(file->fs->name); + if (fs_type >= ventoy_fs_max) + { + grub_file_close(file); + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Unsupported filesystem %s\n", file->fs->name); + } + + /* get image chunk data */ + grub_memset(&g_img_chunk_list, 0, sizeof(g_img_chunk_list)); + g_img_chunk_list.chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM); + if (NULL == g_img_chunk_list.chunk) + { + return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Can't allocate image chunk memoty\n"); + } + + g_img_chunk_list.max_chunk = DEFAULT_CHUNK_NUM; + g_img_chunk_list.cur_chunk = 0; + + start = file->device->disk->partition->start; + + ventoy_get_block_list(file, &g_img_chunk_list, start); + + rc = ventoy_check_block_list(file, &g_img_chunk_list, start, errmsg, sizeof(errmsg)); + grub_file_close(file); + + if (rc) + { + if (fs_type == ventoy_fs_btrfs) + { + vtoy_tip(10, "%s\n\nWill exit in 10 seconds...\n", errmsg); + grub_exit(); + } + return grub_error(GRUB_ERR_NOT_IMPLEMENTED_YET, "%s\n", errmsg); + } + + grub_memset(&g_grub_param->file_replace, 0, sizeof(g_grub_param->file_replace)); + grub_memset(&g_grub_param->img_replace, 0, sizeof(g_grub_param->img_replace)); + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_select_conf_replace(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + int n; + grub_uint64_t offset = 0; + grub_uint32_t align = 0; + grub_file_t file = NULL; + conf_replace *node = NULL; + conf_replace *nodes[VTOY_MAX_CONF_REPLACE] = { NULL }; + ventoy_grub_param_file_replace *replace = NULL; + + (void)ctxt; + (void)argc; + (void)args; + + debug("select conf replace argc:%d\n", argc); + + if (argc < 2) + { + return 0; + } + + n = ventoy_plugin_find_conf_replace(args[1], nodes); + if (!n) + { + debug("Conf replace not found for %s\n", args[1]); + goto end; + } + + debug("Find %d conf replace for %s\n", n, args[1]); + + g_conf_replace_count = n; + for (i = 0; i < n; i++) + { + node = nodes[i]; + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(loop)%s", node->orgconf); + if (file) + { + offset = grub_iso9660_get_last_file_dirent_pos(file); + grub_file_close(file); + } + else if (node->img > 0) + { + offset = 0; + } + else + { + debug("<(loop)%s> NOT exist\n", node->orgconf); + continue; + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", args[0], node->newconf); + if (!file) + { + debug("New config file <%s%s> NOT exist\n", args[0], node->newconf); + continue; + } + + align = ((int)file->size + 2047) / 2048 * 2048; + + if (align > vtoy_max_replace_file_size) + { + debug("New config file <%s%s> too big\n", args[0], node->newconf); + grub_file_close(file); + continue; + } + + grub_file_read(file, g_conf_replace_new_buf[i], file->size); + grub_file_close(file); + g_conf_replace_new_len[i] = (int)file->size; + g_conf_replace_new_len_align[i] = align; + + g_conf_replace_node[i] = node; + g_conf_replace_offset[i] = offset + 2; + + if (node->img > 0) + { + replace = &(g_grub_param->img_replace[i]); + replace->magic = GRUB_IMG_REPLACE_MAGIC; + grub_snprintf(replace->old_file_name[replace->old_name_cnt], 256, "%s", node->orgconf); + replace->old_name_cnt++; + } + + debug("conf_replace OK: newlen[%d]: %d img:%d\n", i, g_conf_replace_new_len[i], node->img); + } + +end: + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static int ventoy_var_expand(int *record, int *flag, const char *var, char *expand, int len) +{ + int i = 0; + int n = 0; + char c; + const char *ch = var; + + *record = 0; + expand[0] = 0; + + while (*ch) + { + if (*ch == '_' || (*ch >= '0' && *ch <= '9') || (*ch >= 'A' && *ch <= 'Z') || (*ch >= 'a' && *ch <= 'z')) + { + ch++; + n++; + } + else + { + debug("Invalid variable letter <%c>\n", *ch); + goto end; + } + } + + if (n > 32) + { + debug("Invalid variable length:%d <%s>\n", n, var); + goto end; + } + + if (grub_strncmp(var, "VT_", 3) == 0) /* built-in variables */ + { + + } + else + { + if (*flag == 0) + { + *flag = 1; + grub_printf("\n=================== Variables Expansion ===================\n\n"); + } + + grub_printf("<%s>: ", var); + grub_refresh(); + + while (i < (len - 1)) + { + c = grub_getkey(); + if ((c == '\n') || (c == '\r')) + { + if (i > 0) + { + grub_printf("\n"); + grub_refresh(); + *record = 1; + break; + } + } + else if (grub_isprint(c)) + { + if (i + 1 < (len - 1)) + { + grub_printf("%c", c); + grub_refresh(); + expand[i++] = c; + expand[i] = 0; + } + } + else if (c == '\b') + { + if (i > 0) + { + expand[i - 1] = ' '; + grub_printf("\r<%s>: %s", var, expand); + + expand[i - 1] = 0; + grub_printf("\r<%s>: %s", var, expand); + + grub_refresh(); + i--; + } + } + } + } + +end: + if (expand[0] == 0) + { + grub_snprintf(expand, len, "$$%s$$", var); + } + + return 0; +} + +static int ventoy_auto_install_var_expand(install_template *node) +{ + int pos = 0; + int flag = 0; + int record = 0; + int newlen = 0; + char *start = NULL; + char *end = NULL; + char *newbuf = NULL; + char *curline = NULL; + char *nextline = NULL; + grub_uint8_t *code = NULL; + char value[512]; + var_node *CurNode = NULL; + var_node *pVarList = NULL; + + code = (grub_uint8_t *)node->filebuf; + + if (node->filelen >= VTOY_SIZE_1MB) + { + debug("auto install script too long %d\n", node->filelen); + return 0; + } + + if ((code[0] == 0xff && code[1] == 0xfe) || (code[0] == 0xfe && code[1] == 0xff)) + { + debug("UCS-2 encoding NOT supported\n"); + return 0; + } + + start = grub_strstr(node->filebuf, "$$"); + if (!start) + { + debug("no need to expand variable, no start.\n"); + return 0; + } + + end = grub_strstr(start + 2, "$$"); + if (!end) + { + debug("no need to expand variable, no end.\n"); + return 0; + } + + newlen = grub_max(node->filelen * 10, VTOY_SIZE_128KB); + newbuf = grub_malloc(newlen); + if (!newbuf) + { + debug("Failed to alloc newbuf %d\n", newlen); + return 0; + } + + for (curline = node->filebuf; curline; curline = nextline) + { + nextline = ventoy_get_line(curline); + + start = grub_strstr(curline, "$$"); + if (start) + { + end = grub_strstr(start + 2, "$$"); + } + + if (start && end) + { + *start = *end = 0; + VTOY_APPEND_NEWBUF(curline); + + for (CurNode = pVarList; CurNode; CurNode = CurNode->next) + { + if (grub_strcmp(start + 2, CurNode->var) == 0) + { + grub_snprintf(value, sizeof(value) - 1, "%s", CurNode->val); + break; + } + } + + if (!CurNode) + { + value[sizeof(value) - 1] = 0; + ventoy_var_expand(&record, &flag, start + 2, value, sizeof(value) - 1); + + if (record) + { + CurNode = grub_zalloc(sizeof(var_node)); + if (CurNode) + { + grub_snprintf(CurNode->var, sizeof(CurNode->var), "%s", start + 2); + grub_snprintf(CurNode->val, sizeof(CurNode->val), "%s", value); + CurNode->next = pVarList; + pVarList = CurNode; + } + } + } + + VTOY_APPEND_NEWBUF(value); + + VTOY_APPEND_NEWBUF(end + 2); + } + else + { + VTOY_APPEND_NEWBUF(curline); + } + + if (pos > 0 && newbuf[pos - 1] == '\r') + { + newbuf[pos - 1] = '\n'; + } + else + { + newbuf[pos++] = '\n'; + } + } + + grub_free(node->filebuf); + node->filebuf = newbuf; + node->filelen = pos; + + while (pVarList) + { + CurNode = pVarList->next; + grub_free(pVarList); + pVarList = CurNode; + } + + return 0; +} + +static grub_err_t ventoy_cmd_sel_auto_install(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i = 0; + int pos = 0; + int defidx = 1; + char *buf = NULL; + grub_file_t file = NULL; + char configfile[128]; + install_template *node = NULL; + + (void)ctxt; + (void)argc; + (void)args; + + debug("select auto installation argc:%d\n", argc); + + if (argc < 1) + { + return 0; + } + + node = ventoy_plugin_find_install_template(args[0]); + if (!node) + { + debug("Auto install template not found for %s\n", args[0]); + return 0; + } + + if (node->autosel >= 0 && node->autosel <= node->templatenum) + { + defidx = node->autosel; + if (node->timeout < 0) + { + node->cursel = node->autosel - 1; + debug("Auto install template auto select %d\n", node->autosel); + goto load; + } + } + + buf = (char *)grub_malloc(VTOY_MAX_SCRIPT_BUF); + if (!buf) + { + return 0; + } + + if (node->timeout > 0) + { + vtoy_ssprintf(buf, pos, "set timeout=%d\n", node->timeout); + } + + vtoy_ssprintf(buf, pos, "menuentry \"$VTLANG_NO_AUTOINS_SCRIPT\" --class=\"sel_auto_install\" {\n" + " echo %s\n}\n", ""); + + for (i = 0; i < node->templatenum; i++) + { + vtoy_ssprintf(buf, pos, "menuentry \"%s %s\" --class=\"sel_auto_install\" {\n" + " echo \"\"\n}\n", + ventoy_get_vmenu_title("VTLANG_AUTOINS_USE"), + node->templatepath[i].path); + } + + g_ventoy_menu_esc = 1; + g_ventoy_suppress_esc = 1; + g_ventoy_suppress_esc_default = defidx; + g_ventoy_secondary_menu_on = 1; + + grub_snprintf(configfile, sizeof(configfile), "configfile mem:0x%llx:size:%d", (ulonglong)(ulong)buf, pos); + grub_script_execute_sourcecode(configfile); + + g_ventoy_menu_esc = 0; + g_ventoy_suppress_esc = 0; + g_ventoy_suppress_esc_default = 1; + g_ventoy_secondary_menu_on = 0; + + grub_free(buf); + + node->cursel = g_ventoy_last_entry - 1; + +load: + grub_check_free(node->filebuf); + node->filelen = 0; + + if (node->cursel >= 0 && node->cursel < node->templatenum) + { + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", ventoy_get_env("vtoy_iso_part"), + node->templatepath[node->cursel].path); + if (file) + { + node->filebuf = grub_malloc(file->size + 8); + if (node->filebuf) + { + grub_file_read(file, node->filebuf, file->size); + grub_file_close(file); + + grub_memset(node->filebuf + file->size, 0, 8); + node->filelen = (int)file->size; + + ventoy_auto_install_var_expand(node); + } + } + else + { + debug("Failed to open auto install script <%s%s>\n", + ventoy_get_env("vtoy_iso_part"), node->templatepath[node->cursel].path); + } + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_sel_persistence(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i = 0; + int pos = 0; + int defidx = 1; + char *buf = NULL; + char configfile[128]; + persistence_config *node; + + (void)ctxt; + (void)argc; + (void)args; + + debug("select persistence argc:%d\n", argc); + + if (argc < 1) + { + return 0; + } + + node = ventoy_plugin_find_persistent(args[0]); + if (!node) + { + debug("Persistence image not found for %s\n", args[0]); + return 0; + } + + if (node->autosel >= 0 && node->autosel <= node->backendnum) + { + defidx = node->autosel; + if (node->timeout < 0) + { + node->cursel = node->autosel - 1; + debug("Persistence image auto select %d\n", node->autosel); + return 0; + } + } + + buf = (char *)grub_malloc(VTOY_MAX_SCRIPT_BUF); + if (!buf) + { + return 0; + } + + if (node->timeout > 0) + { + vtoy_ssprintf(buf, pos, "set timeout=%d\n", node->timeout); + } + + vtoy_ssprintf(buf, pos, "menuentry \"$VTLANG_NO_PERSIST\" --class=\"sel_persistence\" {\n" + " echo %s\n}\n", ""); + + for (i = 0; i < node->backendnum; i++) + { + vtoy_ssprintf(buf, pos, "menuentry \"%s %s\" --class=\"sel_persistence\" {\n" + " echo \"\"\n}\n", + ventoy_get_vmenu_title("VTLANG_PERSIST_USE"), + node->backendpath[i].path); + + } + + g_ventoy_menu_esc = 1; + g_ventoy_suppress_esc = 1; + g_ventoy_suppress_esc_default = defidx; + g_ventoy_secondary_menu_on = 1; + + grub_snprintf(configfile, sizeof(configfile), "configfile mem:0x%llx:size:%d", (ulonglong)(ulong)buf, pos); + grub_script_execute_sourcecode(configfile); + + g_ventoy_menu_esc = 0; + g_ventoy_suppress_esc = 0; + g_ventoy_suppress_esc_default = 1; + g_ventoy_secondary_menu_on = 0; + + grub_free(buf); + + node->cursel = g_ventoy_last_entry - 1; + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_dump_img_sector(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_uint32_t i; + ventoy_img_chunk *cur; + + (void)ctxt; + (void)argc; + (void)args; + + for (i = 0; i < g_img_chunk_list.cur_chunk; i++) + { + cur = g_img_chunk_list.chunk + i; + grub_printf("image:[%u - %u] <==> disk:[%llu - %llu]\n", + cur->img_start_sector, cur->img_end_sector, + (unsigned long long)cur->disk_start_sector, (unsigned long long)cur->disk_end_sector + ); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_test_block_list(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_uint32_t i; + grub_file_t file; + ventoy_img_chunk_list chunklist; + char errmsg[128]; + + (void)ctxt; + (void)argc; + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't open file %s\n", args[0]); + } + + /* get image chunk data */ + grub_memset(&chunklist, 0, sizeof(chunklist)); + chunklist.chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM); + if (NULL == chunklist.chunk) + { + return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Can't allocate image chunk memoty\n"); + } + + chunklist.max_chunk = DEFAULT_CHUNK_NUM; + chunklist.cur_chunk = 0; + + ventoy_get_block_list(file, &chunklist, 0); + + if (0 != ventoy_check_block_list(file, &chunklist, 0, errmsg, sizeof(errmsg))) + { + grub_printf("%s\n", errmsg); + grub_printf("########## UNSUPPORTED ###############\n"); + } + + grub_printf("filesystem: <%s> entry number:<%u>\n", file->fs->name, chunklist.cur_chunk); + + for (i = 0; i < chunklist.cur_chunk; i++) + { + grub_printf("%llu+%llu,", (ulonglong)chunklist.chunk[i].disk_start_sector, + (ulonglong)(chunklist.chunk[i].disk_end_sector + 1 - chunklist.chunk[i].disk_start_sector)); + } + + grub_printf("\n==================================\n"); + + for (i = 0; i < chunklist.cur_chunk; i++) + { + grub_printf("%2u: [%llu %llu] - [%llu %llu]\n", i, + (ulonglong)chunklist.chunk[i].img_start_sector, + (ulonglong)chunklist.chunk[i].img_end_sector, + (ulonglong)chunklist.chunk[i].disk_start_sector, + (ulonglong)chunklist.chunk[i].disk_end_sector + ); + } + + grub_free(chunklist.chunk); + grub_file_close(file); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_add_replace_file(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + ventoy_grub_param_file_replace *replace = NULL; + + (void)ctxt; + (void)argc; + (void)args; + + if (argc >= 2) + { + replace = &(g_grub_param->file_replace); + replace->magic = GRUB_FILE_REPLACE_MAGIC; + + replace->old_name_cnt = 0; + for (i = 0; i < 4 && i + 1 < argc; i++) + { + replace->old_name_cnt++; + grub_snprintf(replace->old_file_name[i], sizeof(replace->old_file_name[i]), "%s", args[i + 1]); + } + + replace->new_file_virtual_id = (grub_uint32_t)grub_strtoul(args[0], NULL, 10); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_get_replace_file_cnt(grub_extcmd_context_t ctxt, int argc, char **args) +{ + char buf[32]; + ventoy_grub_param_file_replace *replace = &(g_grub_param->file_replace); + + (void)ctxt; + + if (argc >= 1) + { + grub_snprintf(buf, sizeof(buf), "%u", replace->old_name_cnt); + grub_env_set(args[0], buf); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_dump_menu(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + if (argc == 0) + { + grub_printf("List Mode: CurLen:%d MaxLen:%u\n", g_list_script_pos, VTOY_MAX_SCRIPT_BUF); + grub_printf("%s", g_list_script_buf); + } + else + { + grub_printf("Tree Mode: CurLen:%d MaxLen:%u\n", g_tree_script_pos, VTOY_MAX_SCRIPT_BUF); + grub_printf("%s", g_tree_script_buf); + } + + return 0; +} + +static grub_err_t ventoy_cmd_dump_img_list(grub_extcmd_context_t ctxt, int argc, char **args) +{ + img_info *cur = g_ventoy_img_list; + + (void)ctxt; + (void)argc; + (void)args; + + while (cur) + { + grub_printf("path:<%s> id=%d list_index=%d\n", cur->path, cur->id, cur->plugin_list_index); + grub_printf("name:<%s>\n\n", cur->name); + cur = cur->next; + } + + return 0; +} + +static grub_err_t ventoy_cmd_dump_injection(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + ventoy_plugin_dump_injection(); + + return 0; +} + +static grub_err_t ventoy_cmd_dump_auto_install(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + ventoy_plugin_dump_auto_install(); + + return 0; +} + +static grub_err_t ventoy_cmd_dump_persistence(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + ventoy_plugin_dump_persistence(); + + return 0; +} + +static int ventoy_check_mode_by_name(char *filename, const char *suffix) +{ + int i; + int len1; + int len2; + + len1 = (int)grub_strlen(filename); + len2 = (int)grub_strlen(suffix); + + if (len1 <= len2) + { + return 0; + } + + for (i = len1 - 1; i >= 0; i--) + { + if (filename[i] == '.') + { + break; + } + } + + if (i < len2 + 1) + { + return 0; + } + + if (filename[i - len2 - 1] != '_') + { + return 0; + } + + if (grub_strncasecmp(filename + (i - len2), suffix, len2) == 0) + { + return 1; + } + + return 0; +} + +static grub_err_t ventoy_cmd_check_mode(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + if (argc != 1 && argc != 2) + { + return 1; + } + + if (args[0][0] == '0') + { + if (g_ventoy_memdisk_mode) + { + return 0; + } + + if (argc == 2 && ventoy_check_mode_by_name(args[1], "vtmemdisk")) + { + return 0; + } + + return 1; + } + else if (args[0][0] == '1') + { + return g_ventoy_iso_raw ? 0 : 1; + } + else if (args[0][0] == '2') + { + return g_ventoy_iso_uefi_drv ? 0 : 1; + } + else if (args[0][0] == '3') + { + if (g_ventoy_grub2_mode) + { + return 0; + } + + if (argc == 2 && ventoy_check_mode_by_name(args[1], "vtgrub2")) + { + return 0; + } + + return 1; + } + else if (args[0][0] == '4') + { + if (g_ventoy_wimboot_mode) + { + return 0; + } + + if (argc == 2 && ventoy_check_mode_by_name(args[1], "vtwimboot")) + { + return 0; + } + + return 1; + } + + return 1; +} + +static grub_err_t ventoy_cmd_dynamic_menu(grub_extcmd_context_t ctxt, int argc, char **args) +{ + static int configfile_mode = 0; + char memfile[128] = {0}; + + (void)ctxt; + (void)argc; + (void)args; + + /* + * args[0]: 0:normal 1:configfile + * args[1]: 0:list_buf 1:tree_buf + */ + + if (argc != 2) + { + debug("Invalid argc %d\n", argc); + return 0; + } + + VTOY_CMD_CHECK(1); + + if (args[0][0] == '0') + { + if (args[1][0] == '0') + { + grub_script_execute_sourcecode(g_list_script_buf); + } + else + { + grub_script_execute_sourcecode(g_tree_script_buf); + } + } + else + { + if (configfile_mode) + { + debug("Now already in F3 mode %d\n", configfile_mode); + return 0; + } + + if (args[1][0] == '0') + { + grub_snprintf(memfile, sizeof(memfile), "configfile mem:0x%llx:size:%d", + (ulonglong)(ulong)g_list_script_buf, g_list_script_pos); + } + else + { + g_ventoy_last_entry = -1; + grub_snprintf(memfile, sizeof(memfile), "configfile mem:0x%llx:size:%d", + (ulonglong)(ulong)g_tree_script_buf, g_tree_script_pos); + } + + configfile_mode = 1; + grub_script_execute_sourcecode(memfile); + configfile_mode = 0; + } + + return 0; +} + +static grub_err_t ventoy_cmd_file_exist_nocase(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_file_t file; + + (void)ctxt; + + if (argc != 1) + { + return 1; + } + + g_ventoy_case_insensitive = 1; + file = grub_file_open(args[0], VENTOY_FILE_TYPE); + g_ventoy_case_insensitive = 0; + + grub_errno = 0; + + if (file) + { + grub_file_close(file); + return 0; + } + return 1; +} + +static grub_err_t ventoy_cmd_find_bootable_hdd(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int id = 0; + int find = 0; + grub_disk_t disk; + const char *isopath = NULL; + char hdname[32]; + ventoy_mbr_head mbr; + + (void)ctxt; + (void)argc; + + if (argc != 1) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s variable\n", cmd_raw_name); + } + + isopath = grub_env_get("vtoy_iso_part"); + if (!isopath) + { + debug("isopath is null %p\n", isopath); + return 0; + } + + debug("isopath is %s\n", isopath); + + for (id = 0; id < 30 && (find == 0); id++) + { + grub_snprintf(hdname, sizeof(hdname), "hd%d,", id); + if (grub_strstr(isopath, hdname)) + { + debug("skip %s ...\n", hdname); + continue; + } + + grub_snprintf(hdname, sizeof(hdname), "hd%d", id); + + disk = grub_disk_open(hdname); + if (!disk) + { + debug("%s not exist\n", hdname); + break; + } + + grub_memset(&mbr, 0, sizeof(mbr)); + if (0 == grub_disk_read(disk, 0, 0, 512, &mbr)) + { + if (mbr.Byte55 == 0x55 && mbr.ByteAA == 0xAA) + { + if (mbr.PartTbl[0].Active == 0x80 || mbr.PartTbl[1].Active == 0x80 || + mbr.PartTbl[2].Active == 0x80 || mbr.PartTbl[3].Active == 0x80) + { + + grub_env_set(args[0], hdname); + find = 1; + } + } + debug("%s is %s\n", hdname, find ? "bootable" : "NOT bootable"); + } + else + { + debug("read %s failed\n", hdname); + } + + grub_disk_close(disk); + } + + return 0; +} + +static grub_err_t ventoy_cmd_read_1st_line(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int len = 1024; + grub_file_t file; + char *buf = NULL; + + (void)ctxt; + (void)argc; + + if (argc != 2) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s file var \n", cmd_raw_name); + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + debug("failed to open file %s\n", args[0]); + return 0; + } + + buf = grub_malloc(len); + if (!buf) + { + goto end; + } + + buf[len - 1] = 0; + grub_file_read(file, buf, len - 1); + + ventoy_get_line(buf); + ventoy_set_env(args[1], buf); + +end: + + grub_check_free(buf); + grub_file_close(file); + + return 0; +} + +static int ventoy_img_partition_callback (struct grub_disk *disk, const grub_partition_t partition, void *data) +{ + grub_uint64_t end_max = 0; + int *pCnt = (int *)data; + + (void)disk; + + (*pCnt)++; + g_part_list_pos += grub_snprintf(g_part_list_buf + g_part_list_pos, VTOY_MAX_SCRIPT_BUF - g_part_list_pos, + "0 %llu linear /dev/ventoy %llu\n", + (ulonglong)partition->len, (ulonglong)partition->start); + + end_max = (partition->len + partition->start) * 512; + if (end_max > g_part_end_max) + { + g_part_end_max = end_max; + } + + return 0; +} + +static grub_err_t ventoy_cmd_img_part_info(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int cnt = 0; + char *device_name = NULL; + grub_device_t dev = NULL; + char buf[64]; + + (void)ctxt; + + g_part_list_pos = 0; + g_part_end_max = 0; + grub_env_unset("vtoy_img_part_file"); + + if (argc != 1) + { + return 1; + } + + device_name = grub_file_get_device_name(args[0]); + if (!device_name) + { + debug("ventoy_cmd_img_part_info failed, %s\n", args[0]); + goto end; + } + + dev = grub_device_open(device_name); + if (!dev) + { + debug("grub_device_open failed, %s\n", device_name); + goto end; + } + + grub_partition_iterate(dev->disk, ventoy_img_partition_callback, &cnt); + + grub_snprintf(buf, sizeof(buf), "newc:vtoy_dm_table:mem:0x%llx:size:%d", (ulonglong)(ulong)g_part_list_buf, g_part_list_pos); + grub_env_set("vtoy_img_part_file", buf); + + grub_snprintf(buf, sizeof(buf), "%d", cnt); + grub_env_set("vtoy_img_part_cnt", buf); + + grub_snprintf(buf, sizeof(buf), "%llu", (ulonglong)g_part_end_max); + grub_env_set("vtoy_img_max_part_end", buf); + +end: + + check_free(device_name, grub_free); + check_free(dev, grub_device_close); + + return 0; +} + + +static grub_err_t ventoy_cmd_file_strstr(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int rc = 1; + grub_file_t file; + char *buf = NULL; + + (void)ctxt; + (void)argc; + + if (argc != 2) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s file str \n", cmd_raw_name); + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + debug("failed to open file %s\n", args[0]); + return 1; + } + + buf = grub_malloc(file->size + 1); + if (!buf) + { + goto end; + } + + buf[file->size] = 0; + grub_file_read(file, buf, file->size); + + if (grub_strstr(buf, args[1])) + { + rc = 0; + } + +end: + + grub_check_free(buf); + grub_file_close(file); + + return rc; +} + +static grub_err_t ventoy_cmd_parse_volume(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int len; + grub_file_t file; + char buf[64]; + grub_uint64_t size; + ventoy_iso9660_vd pvd; + + (void)ctxt; + (void)argc; + + if (argc != 4) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s sysid volid space \n", cmd_raw_name); + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + debug("failed to open file %s\n", args[0]); + return 0; + } + + grub_file_seek(file, 16 * 2048); + len = (int)grub_file_read(file, &pvd, sizeof(pvd)); + if (len != sizeof(pvd)) + { + debug("failed to read pvd %d\n", len); + goto end; + } + + grub_memset(buf, 0, sizeof(buf)); + grub_memcpy(buf, pvd.sys, sizeof(pvd.sys)); + ventoy_set_env(args[1], buf); + + grub_memset(buf, 0, sizeof(buf)); + grub_memcpy(buf, pvd.vol, sizeof(pvd.vol)); + ventoy_set_env(args[2], buf); + + size = pvd.space; + size *= 2048; + grub_snprintf(buf, sizeof(buf), "%llu", (ulonglong)size); + ventoy_set_env(args[3], buf); + +end: + grub_file_close(file); + + return 0; +} + +static grub_err_t ventoy_cmd_parse_create_date(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int len; + grub_file_t file; + char buf[64]; + + (void)ctxt; + (void)argc; + + if (argc != 2) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s var \n", cmd_raw_name); + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + debug("failed to open file %s\n", args[0]); + return 0; + } + + grub_memset(buf, 0, sizeof(buf)); + grub_file_seek(file, 16 * 2048 + 813); + len = (int)grub_file_read(file, buf, 17); + if (len != 17) + { + debug("failed to read create date %d\n", len); + goto end; + } + + ventoy_set_env(args[1], buf); + +end: + grub_file_close(file); + + return 0; +} + +static grub_err_t ventoy_cmd_img_hook_root(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + ventoy_env_hook_root(1); + + return 0; +} + +static grub_err_t ventoy_cmd_img_unhook_root(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + ventoy_env_hook_root(0); + + return 0; +} + +#ifdef GRUB_MACHINE_EFI +static grub_err_t ventoy_cmd_check_secureboot_var(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + return g_sys_sb ? 0 : 1; +} +#else +static grub_err_t ventoy_cmd_check_secureboot_var(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + return 1; +} +#endif + +static grub_err_t ventoy_cmd_img_check_range(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + int ret = 1; + grub_file_t file; + grub_uint64_t FileSectors = 0; + ventoy_gpt_info *gpt = NULL; + ventoy_part_table *pt = NULL; + grub_uint8_t zeroguid[16] = {0}; + + (void)ctxt; + (void)argc; + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + debug("failed to open file %s\n", args[0]); + return 1; + } + + if (file->size % 512) + { + debug("unaligned file size: %llu\n", (ulonglong)file->size); + goto out; + } + + gpt = grub_zalloc(sizeof(ventoy_gpt_info)); + if (!gpt) + { + goto out; + } + + FileSectors = file->size / 512; + + grub_file_read(file, gpt, sizeof(ventoy_gpt_info)); + if (grub_strncmp(gpt->Head.Signature, "EFI PART", 8) == 0) + { + debug("This is EFI partition table\n"); + + for (i = 0; i < 128; i++) + { + if (grub_memcmp(gpt->PartTbl[i].PartGuid, zeroguid, 16)) + { + if (FileSectors < gpt->PartTbl[i].LastLBA) + { + debug("out of range: part[%d] LastLBA:%llu FileSectors:%llu\n", i, + (ulonglong)gpt->PartTbl[i].LastLBA, (ulonglong)FileSectors); + goto out; + } + } + } + } + else + { + debug("This is MBR partition table\n"); + + for (i = 0; i < 4; i++) + { + pt = gpt->MBR.PartTbl + i; + if (FileSectors < pt->StartSectorId + pt->SectorCount) + { + debug("out of range: part[%d] LastLBA:%llu FileSectors:%llu\n", i, + (ulonglong)(pt->StartSectorId + pt->SectorCount), + (ulonglong)FileSectors); + goto out; + } + } + } + + ret = 0; + +out: + grub_file_close(file); + grub_check_free(gpt); + grub_errno = GRUB_ERR_NONE; + return ret; +} + +static grub_err_t ventoy_cmd_clear_key(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + int ret; + + (void)ctxt; + (void)argc; + (void)args; + + for (i = 0; i < 500; i++) + { + ret = grub_getkey_noblock(); + if (ret == GRUB_TERM_NO_KEY) + { + break; + } + } + + if (i >= 500) + { + grub_cls(); + grub_printf("\n\n Still have key input after clear.\n"); + grub_refresh(); + grub_sleep(5); + } + + return 0; +} + +static grub_err_t ventoy_cmd_acpi_param(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + int buflen; + int datalen; + int loclen; + int img_chunk_num; + int image_sector_size; + char cmd[64]; + ventoy_chain_head *chain; + ventoy_img_chunk *chunk; + ventoy_os_param *osparam; + ventoy_image_location *location; + ventoy_image_disk_region *region; + struct grub_acpi_table_header *acpi; + + (void)ctxt; + + if (argc != 2) + { + return 1; + } + + debug("ventoy_cmd_acpi_param %s %s\n", args[0], args[1]); + + chain = (ventoy_chain_head *)(ulong)grub_strtoul(args[0], NULL, 16); + if (!chain) + { + return 1; + } + + image_sector_size = (int)grub_strtol(args[1], NULL, 10); + + if (grub_memcmp(&g_ventoy_guid, &(chain->os_param.guid), 16)) + { + debug("Invalid ventoy guid 0x%x\n", chain->os_param.guid.data1); + return 1; + } + + img_chunk_num = chain->img_chunk_num; + + loclen = sizeof(ventoy_image_location) + (img_chunk_num - 1) * sizeof(ventoy_image_disk_region); + datalen = sizeof(ventoy_os_param) + loclen; + + buflen = sizeof(struct grub_acpi_table_header) + datalen; + acpi = grub_zalloc(buflen); + if (!acpi) + { + return 1; + } + + /* Step1: Fill acpi table header */ + grub_memcpy(acpi->signature, "VTOY", 4); + acpi->length = buflen; + acpi->revision = 1; + grub_memcpy(acpi->oemid, "VENTOY", 6); + grub_memcpy(acpi->oemtable, "OSPARAMS", 8); + acpi->oemrev = 1; + acpi->creator_id[0] = 1; + acpi->creator_rev = 1; + + /* Step2: Fill data */ + osparam = (ventoy_os_param *)(acpi + 1); + grub_memcpy(osparam, &chain->os_param, sizeof(ventoy_os_param)); + osparam->vtoy_img_location_addr = 0; + osparam->vtoy_img_location_len = loclen; + osparam->chksum = 0; + osparam->chksum = 0x100 - grub_byte_checksum(osparam, sizeof(ventoy_os_param)); + + location = (ventoy_image_location *)(osparam + 1); + grub_memcpy(&location->guid, &osparam->guid, sizeof(ventoy_guid)); + location->image_sector_size = image_sector_size; + location->disk_sector_size = chain->disk_sector_size; + location->region_count = img_chunk_num; + + region = location->regions; + chunk = (ventoy_img_chunk *)((char *)chain + chain->img_chunk_offset); + if (512 == image_sector_size) + { + for (i = 0; i < img_chunk_num; i++) + { + region->image_sector_count = chunk->disk_end_sector - chunk->disk_start_sector + 1; + region->image_start_sector = chunk->img_start_sector * 4; + region->disk_start_sector = chunk->disk_start_sector; + region++; + chunk++; + } + } + else + { + for (i = 0; i < img_chunk_num; i++) + { + region->image_sector_count = chunk->img_end_sector - chunk->img_start_sector + 1; + region->image_start_sector = chunk->img_start_sector; + region->disk_start_sector = chunk->disk_start_sector; + region++; + chunk++; + } + } + + /* Step3: Fill acpi checksum */ + acpi->checksum = 0; + acpi->checksum = 0x100 - grub_byte_checksum(acpi, acpi->length); + + /* load acpi table */ + grub_snprintf(cmd, sizeof(cmd), "acpi mem:0x%lx:size:%d", (ulong)acpi, acpi->length); + grub_script_execute_sourcecode(cmd); + + grub_free(acpi); + + VENTOY_CMD_RETURN(0); +} + +static grub_err_t ventoy_cmd_push_last_entry(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + g_ventoy_last_entry_back = g_ventoy_last_entry; + g_ventoy_last_entry = -1; + + return 0; +} + +static grub_err_t ventoy_cmd_pop_last_entry(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + g_ventoy_last_entry = g_ventoy_last_entry_back; + + return 0; +} + +static int ventoy_lib_module_callback(const char *filename, const struct grub_dirhook_info *info, void *data) +{ + const char *pos = filename + 1; + + if (info->dir) + { + while (*pos) + { + if (*pos == '.') + { + if ((*(pos - 1) >= '0' && *(pos - 1) <= '9') && (*(pos + 1) >= '0' && *(pos + 1) <= '9')) + { + grub_strncpy((char *)data, filename, 128); + return 1; + } + } + pos++; + } + } + + return 0; +} + +static grub_err_t ventoy_cmd_lib_module_ver(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int rc = 1; + char *device_name = NULL; + grub_device_t dev = NULL; + grub_fs_t fs = NULL; + char buf[128] = {0}; + + (void)ctxt; + + if (argc != 3) + { + debug("ventoy_cmd_lib_module_ver, invalid param num %d\n", argc); + return 1; + } + + debug("ventoy_cmd_lib_module_ver %s %s %s\n", args[0], args[1], args[2]); + + device_name = grub_file_get_device_name(args[0]); + if (!device_name) + { + debug("grub_file_get_device_name failed, %s\n", args[0]); + goto end; + } + + dev = grub_device_open(device_name); + if (!dev) + { + debug("grub_device_open failed, %s\n", device_name); + goto end; + } + + fs = grub_fs_probe(dev); + if (!fs) + { + debug("grub_fs_probe failed, %s\n", device_name); + goto end; + } + + fs->fs_dir(dev, args[1], ventoy_lib_module_callback, buf); + + if (buf[0]) + { + ventoy_set_env(args[2], buf); + } + + rc = 0; + +end: + + check_free(device_name, grub_free); + check_free(dev, grub_device_close); + + return rc; +} + +int ventoy_load_part_table(const char *diskname) +{ + char name[64]; + int ret; + grub_disk_t disk; + grub_device_t dev; + + g_ventoy_part_info = grub_zalloc(sizeof(ventoy_gpt_info)); + if (!g_ventoy_part_info) + { + return 1; + } + + disk = grub_disk_open(diskname); + if (!disk) + { + debug("Failed to open disk %s\n", diskname); + return 1; + } + + g_ventoy_disk_size = disk->total_sectors * (1U << disk->log_sector_size); + + g_ventoy_disk_bios_id = disk->id; + + grub_disk_read(disk, 0, 0, sizeof(ventoy_gpt_info), g_ventoy_part_info); + grub_disk_close(disk); + + grub_snprintf(name, sizeof(name), "%s,1", diskname); + dev = grub_device_open(name); + if (dev) + { + /* Check for official Ventoy device */ + ret = ventoy_check_official_device(dev); + grub_device_close(dev); + + if (ret) + { + return 1; + } + } + + g_ventoy_disk_part_size[0] = ventoy_get_vtoy_partsize(0); + g_ventoy_disk_part_size[1] = ventoy_get_vtoy_partsize(1); + + return 0; +} + +void ventoy_prompt_end(void) +{ + int op = 0; + char c; + + grub_printf("\n\n\n"); + grub_printf(" 1 --- Exit grub\n"); + grub_printf(" 2 --- Reboot\n"); + grub_printf(" 3 --- Shut down\n"); + grub_printf("Please enter your choice: "); + grub_refresh(); + + while (1) + { + c = grub_getkey(); + if (c >= '1' && c <= '3') + { + if (op == 0) + { + op = c - '0'; + grub_printf("%c", c); + grub_refresh(); + } + } + else if (c == '\r' || c == '\n') + { + if (op) + { + if (op == 1) + { + grub_exit(); + } + else if (op == 2) + { + grub_reboot(); + } + else if (op == 3) + { + grub_script_execute_sourcecode("halt"); + } + } + } + else if (c == '\b') + { + if (op) + { + op = 0; + grub_printf("\rPlease enter your choice: "); + grub_printf("\rPlease enter your choice: "); + grub_refresh(); + } + } + } +} + +static grub_err_t ventoy_cmd_load_part_table(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int ret; + + (void)argc; + (void)ctxt; + + ret = ventoy_load_part_table(args[0]); + if (ret) + { + ventoy_prompt_end(); + } + + g_ventoy_disk_part_size[0] = ventoy_get_vtoy_partsize(0); + g_ventoy_disk_part_size[1] = ventoy_get_vtoy_partsize(1); + + return 0; +} + +static grub_err_t ventoy_cmd_check_custom_boot(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int ret = 1; + const char *vcfg = NULL; + + (void)argc; + (void)ctxt; + + vcfg = ventoy_plugin_get_custom_boot(args[0]); + if (vcfg) + { + debug("custom boot <%s>:<%s>\n", args[0], vcfg); + grub_env_set(args[1], vcfg); + ret = 0; + } + else + { + debug("custom boot <%s>:\n", args[0]); + } + + grub_errno = 0; + return ret; +} + + +static grub_err_t ventoy_cmd_part_exist(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int id; + grub_uint8_t zeroguid[16] = {0}; + + (void)argc; + (void)ctxt; + + id = (int)grub_strtoul(args[0], NULL, 10); + grub_errno = 0; + + if (grub_memcmp(g_ventoy_part_info->Head.Signature, "EFI PART", 8) == 0) + { + if (id >= 1 && id <= 128) + { + if (grub_memcmp(g_ventoy_part_info->PartTbl[id - 1].PartGuid, zeroguid, 16)) + { + return 0; + } + } + } + else + { + if (id >= 1 && id <= 4) + { + if (g_ventoy_part_info->MBR.PartTbl[id - 1].FsFlag) + { + return 0; + } + } + } + + return 1; +} + +static grub_err_t ventoy_cmd_get_fs_label(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int rc = 1; + char *device_name = NULL; + grub_device_t dev = NULL; + grub_fs_t fs = NULL; + char *label = NULL; + + (void)ctxt; + + debug("get fs label for %s\n", args[0]); + + if (argc != 2) + { + debug("ventoy_cmd_get_fs_label, invalid param num %d\n", argc); + return 1; + } + + device_name = grub_file_get_device_name(args[0]); + if (!device_name) + { + debug("grub_file_get_device_name failed, %s\n", args[0]); + goto end; + } + + dev = grub_device_open(device_name); + if (!dev) + { + debug("grub_device_open failed, %s\n", device_name); + goto end; + } + + fs = grub_fs_probe(dev); + if (NULL == fs || NULL == fs->fs_label) + { + debug("grub_fs_probe failed, %s %p %p\n", device_name, fs, fs->fs_label); + goto end; + } + + fs->fs_label(dev, &label); + if (label) + { + debug("label=<%s>\n", label); + ventoy_set_env(args[1], label); + grub_free(label); + } + + rc = 0; + +end: + + check_free(device_name, grub_free); + check_free(dev, grub_device_close); + + return rc; +} + +static int ventoy_fs_enum_1st_file(const char *filename, const struct grub_dirhook_info *info, void *data) +{ + if (!info->dir) + { + grub_snprintf((char *)data, 256, "%s", filename); + return 1; + } + + return 0; +} + +static int ventoy_fs_enum_1st_dir(const char *filename, const struct grub_dirhook_info *info, void *data) +{ + if (info->dir && filename && filename[0] != '.') + { + grub_snprintf((char *)data, 256, "%s", filename); + return 1; + } + + return 0; +} + +static grub_err_t ventoy_fs_enum_1st_child(int argc, char **args, grub_fs_dir_hook_t hook) +{ + int rc = 1; + char *device_name = NULL; + grub_device_t dev = NULL; + grub_fs_t fs = NULL; + char name[256] ={0}; + + if (argc != 3) + { + debug("ventoy_fs_enum_1st_child, invalid param num %d\n", argc); + return 1; + } + + device_name = grub_file_get_device_name(args[0]); + if (!device_name) + { + debug("grub_file_get_device_name failed, %s\n", args[0]); + goto end; + } + + dev = grub_device_open(device_name); + if (!dev) + { + debug("grub_device_open failed, %s\n", device_name); + goto end; + } + + fs = grub_fs_probe(dev); + if (!fs) + { + debug("grub_fs_probe failed, %s\n", device_name); + goto end; + } + + fs->fs_dir(dev, args[1], hook, name); + if (name[0]) + { + ventoy_set_env(args[2], name); + } + + rc = 0; + +end: + + check_free(device_name, grub_free); + check_free(dev, grub_device_close); + + return rc; +} + +static grub_err_t ventoy_cmd_fs_enum_1st_file(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + return ventoy_fs_enum_1st_child(argc, args, ventoy_fs_enum_1st_file); +} + +static grub_err_t ventoy_cmd_fs_enum_1st_dir(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + return ventoy_fs_enum_1st_child(argc, args, ventoy_fs_enum_1st_dir); +} + +static grub_err_t ventoy_cmd_basename(grub_extcmd_context_t ctxt, int argc, char **args) +{ + char c; + char *pos = NULL; + char *end = NULL; + + (void)ctxt; + + if (argc != 2) + { + debug("ventoy_cmd_basename, invalid param num %d\n", argc); + return 1; + } + + for (pos = args[0]; *pos; pos++) + { + if (*pos == '.') + { + end = pos; + } + } + + if (end) + { + c = *end; + *end = 0; + } + + grub_env_set(args[1], args[0]); + + if (end) + { + *end = c; + } + + return 0; +} + +static grub_err_t ventoy_cmd_basefile(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + int len; + const char *buf; + + (void)ctxt; + + if (argc != 2) + { + debug("ventoy_cmd_basefile, invalid param num %d\n", argc); + return 1; + } + + buf = args[0]; + len = (int)grub_strlen(buf); + for (i = len; i > 0; i--) + { + if (buf[i - 1] == '/') + { + grub_env_set(args[1], buf + i); + return 0; + } + } + + grub_env_set(args[1], buf); + + return 0; +} + +static grub_err_t ventoy_cmd_enum_video_mode(grub_extcmd_context_t ctxt, int argc, char **args) +{ + struct grub_video_mode_info info; + char buf[32]; + + (void)ctxt; + (void)argc; + (void)args; + + if (!g_video_mode_list) + { + ventoy_enum_video_mode(); + } + + if (grub_video_get_info(&info) == GRUB_ERR_NONE) + { + grub_snprintf(buf, sizeof(buf), "Resolution (%ux%u)", info.width, info.height); + } + else + { + grub_snprintf(buf, sizeof(buf), "Resolution (0x0)"); + } + + grub_env_set("VTOY_CUR_VIDEO_MODE", buf); + + grub_snprintf(buf, sizeof(buf), "%d", g_video_mode_num); + grub_env_set("VTOY_VIDEO_MODE_NUM", buf); + + VENTOY_CMD_RETURN(0); +} + +static grub_err_t vt_cmd_update_cur_video_mode(grub_extcmd_context_t ctxt, int argc, char **args) +{ + struct grub_video_mode_info info; + char buf[32]; + + (void)ctxt; + (void)argc; + (void)args; + + if (grub_video_get_info(&info) == GRUB_ERR_NONE) + { + grub_snprintf(buf, sizeof(buf), "%ux%ux%u", info.width, info.height, info.bpp); + } + else + { + grub_snprintf(buf, sizeof(buf), "0x0x0"); + } + + grub_env_set(args[0], buf); + + VENTOY_CMD_RETURN(0); +} + +static grub_err_t ventoy_cmd_get_video_mode(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int id; + char buf[32]; + + (void)ctxt; + (void)argc; + + if (!g_video_mode_list) + { + return 0; + } + + id = (int)grub_strtoul(args[0], NULL, 10); + if (id < g_video_mode_num) + { + grub_snprintf(buf, sizeof(buf), "%ux%ux%u", + g_video_mode_list[id].width, g_video_mode_list[id].height, g_video_mode_list[id].bpp); + } + + grub_env_set(args[1], buf); + + VENTOY_CMD_RETURN(0); +} + +static grub_err_t ventoy_cmd_get_efivdisk_offset(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_uint32_t i; + grub_uint32_t loadsector = 0; + grub_file_t file; + char value[32]; + grub_uint32_t boot_catlog = 0; + grub_uint8_t buf[512]; + + (void)ctxt; + + if (argc != 2) + { + debug("ventoy_cmd_get_efivdisk_offset, invalid param num %d\n", argc); + return 1; + } + + file = grub_file_open(args[0], VENTOY_FILE_TYPE); + if (!file) + { + debug("failed to open %s\n", args[0]); + return 1; + } + + boot_catlog = ventoy_get_iso_boot_catlog(file); + if (boot_catlog == 0) + { + debug("No bootcatlog found\n"); + grub_file_close(file); + return 1; + } + + grub_memset(buf, 0, sizeof(buf)); + grub_file_seek(file, boot_catlog * 2048); + grub_file_read(file, buf, sizeof(buf)); + grub_file_close(file); + + for (i = 0; i < sizeof(buf); i += 32) + { + if ((buf[i] == 0 || buf[i] == 0x90 || buf[i] == 0x91) && buf[i + 1] == 0xEF) + { + if (buf[i + 32] == 0x88) + { + loadsector = *(grub_uint32_t *)(buf + i + 32 + 8); + grub_snprintf(value, sizeof(value), "%u", loadsector * 4); //change to sector size 512 + break; + } + } + } + + if (loadsector == 0) + { + debug("No EFI eltorito info found\n"); + return 1; + } + + debug("ventoy_cmd_get_efivdisk_offset <%s>\n", value); + grub_env_set(args[1], value); + VENTOY_CMD_RETURN(0); +} + +static int ventoy_collect_replace_initrd(const char *filename, const struct grub_dirhook_info *info, void *data) +{ + int curpos; + int printlen; + grub_size_t len; + replace_fs_dir *pfsdir = (replace_fs_dir *)data; + + if (pfsdir->initrd[0]) + { + return 1; + } + + curpos = pfsdir->curpos; + len = grub_strlen(filename); + + if (info->dir) + { + if ((len == 1 && filename[0] == '.') || + (len == 2 && filename[0] == '.' && filename[1] == '.')) + { + return 0; + } + + //debug("#### [DIR] <%s> <%s>\n", pfsdir->fullpath, filename); + pfsdir->dircnt++; + + printlen = grub_snprintf(pfsdir->fullpath + curpos, 512 - curpos, "%s/", filename); + pfsdir->curpos = curpos + printlen; + pfsdir->fs->fs_dir(pfsdir->dev, pfsdir->fullpath, ventoy_collect_replace_initrd, pfsdir); + pfsdir->curpos = curpos; + pfsdir->fullpath[curpos] = 0; + } + else + { + //debug("#### [FILE] <%s> <%s>\n", pfsdir->fullpath, filename); + pfsdir->filecnt++; + + /* We consider the xxx.img file bigger than 32MB is the initramfs file */ + if (len > 4 && grub_strncmp(filename + len - 4, ".img", 4) == 0) + { + if (info->size > 32 * VTOY_SIZE_1MB) + { + grub_snprintf(pfsdir->initrd, sizeof(pfsdir->initrd), "%s%s", pfsdir->fullpath, filename); + return 1; + } + } + } + + return 0; +} + +static grub_err_t ventoy_cmd_search_replace_initrd(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + char *pos = NULL; + char *device_name = NULL; + grub_device_t dev = NULL; + grub_fs_t fs = NULL; + replace_fs_dir *pfsdir = NULL; + + (void)ctxt; + + if (argc != 2) + { + debug("ventoy_cmd_search_replace_initrd, invalid param num %d\n", argc); + return 1; + } + + pfsdir = grub_zalloc(sizeof(replace_fs_dir)); + if (!pfsdir) + { + return 1; + } + + device_name = grub_file_get_device_name(args[0]); + if (!device_name) + { + goto fail; + } + + dev = grub_device_open(device_name); + if (!dev) + { + goto fail; + } + + fs = grub_fs_probe(dev); + if (!fs) + { + goto fail; + } + + pfsdir->dev = dev; + pfsdir->fs = fs; + pfsdir->curpos = 1; + pfsdir->fullpath[0] = '/'; + fs->fs_dir(dev, "/", ventoy_collect_replace_initrd, pfsdir); + + if (pfsdir->initrd[0]) + { + debug("Replace initrd <%s> <%d %d>\n", pfsdir->initrd, pfsdir->dircnt, pfsdir->filecnt); + + for (i = 0; i < (int)sizeof(pfsdir->initrd) && pfsdir->initrd[i]; i++) + { + if (pfsdir->initrd[i] == '/') + { + pfsdir->initrd[i] = '\\'; + } + } + + pos = (pfsdir->initrd[0] == '\\') ? pfsdir->initrd + 1 : pfsdir->initrd; + grub_env_set(args[1], pos); + } + else + { + debug("Replace initrd NOT found <%s> <%d %d>\n", args[0], pfsdir->dircnt, pfsdir->filecnt); + } + +fail: + + grub_check_free(pfsdir); + grub_check_free(device_name); + check_free(dev, grub_device_close); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_push_pager(grub_extcmd_context_t ctxt, int argc, char **args) +{ + const char *pager = NULL; + + (void)ctxt; + (void)argc; + (void)args; + + pager = grub_env_get("pager"); + if (NULL == pager) + { + g_pager_flag = 1; + grub_env_set("pager", "1"); + } + else if (pager[0] == '1') + { + g_pager_flag = 0; + } + else + { + grub_snprintf(g_old_pager, sizeof(g_old_pager), "%s", pager); + g_pager_flag = 2; + grub_env_set("pager", "1"); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_pop_pager(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + if (g_pager_flag == 1) + { + grub_env_unset("pager"); + } + else if (g_pager_flag == 2) + { + grub_env_set("pager", g_old_pager); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static int ventoy_chk_case_file(const char *filename, const struct grub_dirhook_info *info, void *data) +{ + if (g_json_case_mis_path[0]) + { + return 1; + } + + if (0 == info->dir && grub_strcasecmp(filename, "ventoy.json") == 0) + { + grub_snprintf(g_json_case_mis_path, 32, "%s/%s", (char *)data, filename); + return 1; + } + return 0; +} + +static int ventoy_chk_case_dir(const char *filename, const struct grub_dirhook_info *info, void *data) +{ + char path[16]; + chk_case_fs_dir *fs_dir = (chk_case_fs_dir *)data; + + if (g_json_case_mis_path[0]) + { + return 1; + } + + if (info->dir && (filename[0] == 'v' || filename[0] == 'V')) + { + if (grub_strcasecmp(filename, "ventoy") == 0) + { + grub_snprintf(path, sizeof(path), "/%s", filename); + fs_dir->fs->fs_dir(fs_dir->dev, path, ventoy_chk_case_file, path); + if (g_json_case_mis_path[0]) + { + return 1; + } + } + } + + return 0; +} + +static grub_err_t ventoy_cmd_chk_json_pathcase(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int fstype = 0; + char *device_name = NULL; + grub_device_t dev = NULL; + grub_fs_t fs = NULL; + chk_case_fs_dir fs_dir; + + (void)ctxt; + (void)argc; + (void)args; + + device_name = grub_file_get_device_name(args[0]); + if (!device_name) + { + goto out; + } + + dev = grub_device_open(device_name); + if (!dev) + { + goto out; + } + + fs = grub_fs_probe(dev); + if (!fs) + { + goto out; + } + + fstype = ventoy_get_fs_type(fs->name); + if (fstype == ventoy_fs_fat || fstype == ventoy_fs_exfat || fstype >= ventoy_fs_max) + { + goto out; + } + + g_json_case_mis_path[0] = 0; + fs_dir.dev = dev; + fs_dir.fs = fs; + fs->fs_dir(dev, "/", ventoy_chk_case_dir, &fs_dir); + + if (g_json_case_mis_path[0]) + { + grub_env_set("VTOY_PLUGIN_PATH_CASE_MISMATCH", g_json_case_mis_path); + } + +out: + + grub_check_free(device_name); + check_free(dev, grub_device_close); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t grub_cmd_gptpriority(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_disk_t disk; + grub_partition_t part; + char priority_str[3]; /* Maximum value 15 */ + + (void)ctxt; + + if (argc < 2 || argc > 3) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "gptpriority DISKNAME PARTITIONNUM [VARNAME]"); + + /* Open the disk if it exists */ + disk = grub_disk_open (args[0]); + if (!disk) + { + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "Not a disk"); + } + + part = grub_partition_probe (disk, args[1]); + if (!part) + { + grub_disk_close (disk); + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "No such partition"); + } + + if (grub_strcmp (part->partmap->name, "gpt")) + { + grub_disk_close (disk); + return grub_error (GRUB_ERR_BAD_PART_TABLE, + "Not a GPT partition"); + } + + grub_snprintf (priority_str, sizeof(priority_str), "%u", + (grub_uint32_t)((part->gpt_attrib >> 48) & 0xfULL)); + + if (argc == 3) + { + grub_env_set (args[2], priority_str); + grub_env_export (args[2]); + } + else + { + grub_printf ("Priority is %s\n", priority_str); + } + + grub_disk_close (disk); + return GRUB_ERR_NONE; +} + + +static grub_err_t grub_cmd_syslinux_nojoliet(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int ret = 1; + int joliet = 0; + grub_file_t file = NULL; + grub_uint32_t loadrba = 0; + grub_uint32_t boot_catlog = 0; + grub_uint8_t sector[512]; + boot_info_table *info = NULL; + + (void)ctxt; + (void)argc; + + /* This also trigger a iso9660 fs parse */ + if (ventoy_check_file_exist("(loop)/isolinux/isolinux.cfg")) + { + return 0; + } + + joliet = grub_iso9660_is_joliet(); + if (joliet == 0) + { + return 1; + } + + file = grub_file_open(args[0], VENTOY_FILE_TYPE); + if (!file) + { + debug("failed to open %s\n", args[0]); + return 1; + } + + boot_catlog = ventoy_get_iso_boot_catlog(file); + if (boot_catlog == 0) + { + debug("no bootcatlog found %u\n", boot_catlog); + goto out; + } + + loadrba = ventoy_get_bios_eltorito_rba(file, boot_catlog); + if (loadrba == 0) + { + debug("no bios eltorito rba found %u\n", loadrba); + goto out; + } + + grub_file_seek(file, loadrba * 2048); + grub_file_read(file, sector, 512); + + info = (boot_info_table *)sector; + if (info->bi_data0 == 0x7c6ceafa && + info->bi_data1 == 0x90900000 && + info->bi_PrimaryVolumeDescriptor == 16 && + info->bi_BootFileLocation == loadrba) + { + debug("bootloader is syslinux, %u.\n", loadrba); + ret = 0; + } + +out: + + grub_file_close(file); + grub_errno = GRUB_ERR_NONE; + return ret; +} + +static grub_err_t grub_cmd_vlnk_dump_part(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int n = 0; + ventoy_vlnk_part *node; + + (void)ctxt; + (void)argc; + (void)args; + + for (node = g_vlnk_part_list; node; node = node->next) + { + grub_printf("[%d] %s disksig:%08x offset:%llu fs:%s\n", + ++n, node->device, node->disksig, + (ulonglong)node->partoffset, (node->fs ? node->fs->name : "N/A")); + } + + return 0; +} + +static grub_err_t grub_cmd_is_vlnk_name(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int len = 0; + + (void)ctxt; + + if (argc == 1) + { + len = (int)grub_strlen(args[0]); + if (grub_file_is_vlnk_suffix(args[0], len)) + { + return 0; + } + } + + return 1; +} + +static grub_err_t grub_cmd_get_vlnk_dst(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int vlnk = 0; + const char *name = NULL; + + (void)ctxt; + + if (argc == 2) + { + grub_env_unset(args[1]); + name = grub_file_get_vlnk(args[0], &vlnk); + if (vlnk) + { + debug("VLNK SRC: <%s>\n", args[0]); + debug("VLNK DST: <%s>\n", name); + grub_env_set(args[1], name); + return 0; + } + } + + return 1; +} + +static grub_err_t grub_cmd_check_vlnk(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int ret = 1; + int len = 0; + grub_file_t file = NULL; + ventoy_vlnk vlnk; + char dst[512]; + + (void)ctxt; + + if (argc != 1) + { + goto out; + } + + len = (int)grub_strlen(args[0]); + if (!grub_file_is_vlnk_suffix(args[0], len)) + { + grub_printf("Invalid vlnk suffix\n"); + goto out; + } + + file = grub_file_open(args[0], VENTOY_FILE_TYPE | GRUB_FILE_TYPE_NO_VLNK); + if (!file) + { + grub_printf("Failed to open %s\n", args[0]); + goto out; + } + + if (file->size != 32768) + { + grub_printf("Invalid vlnk file (size=%llu).\n", (ulonglong)file->size); + goto out; + } + + grub_memset(&vlnk, 0, sizeof(vlnk)); + grub_file_read(file, &vlnk, sizeof(vlnk)); + + ret = ventoy_check_vlnk_data(&vlnk, 1, dst, sizeof(dst)); + +out: + + grub_refresh(); + check_free(file, grub_file_close); + grub_errno = GRUB_ERR_NONE; + return ret; +} + +static grub_err_t ventoy_iso_vd_id_clear(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + g_iso_vd_id_publisher[0] = 0; + g_iso_vd_id_prepare[0] = 0; + g_iso_vd_id_application[0] = 0; + + return 0; +} + +static grub_err_t ventoy_cmd_iso_vd_id_parse(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int ret = 1; + int offset = 318; + grub_file_t file = NULL; + + (void)ctxt; + (void)argc; + + file = grub_file_open(args[0], VENTOY_FILE_TYPE); + if (!file) + { + grub_printf("Failed to open %s\n", args[0]); + goto out; + } + + grub_file_seek(file, 16 * 2048 + offset); + grub_file_read(file, g_iso_vd_id_publisher, 128); + + offset += 128; + grub_file_seek(file, 16 * 2048 + offset); + grub_file_read(file, g_iso_vd_id_prepare, 128); + + offset += 128; + grub_file_seek(file, 16 * 2048 + offset); + grub_file_read(file, g_iso_vd_id_application, 128); + +out: + + check_free(file, grub_file_close); + grub_errno = GRUB_ERR_NONE; + return ret; +} + +static grub_err_t ventoy_cmd_iso_vd_id_begin(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int ret = 1; + char *id = g_iso_vd_id_publisher; + + (void)ctxt; + (void)argc; + + if (args[0][0] == '1') + { + id = g_iso_vd_id_prepare; + } + else if (args[0][0] == '2') + { + id = g_iso_vd_id_application; + } + + if (args[1][0] == '0' && grub_strncasecmp(id, args[2], grub_strlen(args[2])) == 0) + { + ret = 0; + } + + if (args[1][0] == '1' && grub_strncmp(id, args[2], grub_strlen(args[2])) == 0) + { + ret = 0; + } + + grub_errno = GRUB_ERR_NONE; + return ret; +} + +static grub_err_t ventoy_cmd_fn_mutex_lock(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + + g_ventoy_fn_mutex = 0; + if (argc == 1 && args[0][0] == '1' && args[0][1] == 0) + { + g_ventoy_fn_mutex = 1; + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_dump_rsv_page(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_uint64_t total; + grub_uint64_t org_required; + grub_uint64_t new_required; + + (void)ctxt; + (void)argc; + (void)args; + +#ifdef GRUB_MACHINE_EFI + grub_efi_get_reserved_page_num(&total, &org_required, &new_required); + grub_printf("Total pages: %llu\n", (unsigned long long)total); + grub_printf("OrgReq pages: %llu\n", (unsigned long long)org_required); + grub_printf("NewReq pages: %llu\n", (unsigned long long)new_required); +#else + (void)total; + (void)org_required; + (void)new_required; + grub_printf("Non EFI mode!\n"); +#endif + + grub_refresh(); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_need_secondary_menu(grub_extcmd_context_t ctxt, int argc, char **args) +{ + const char *env = NULL; + + (void)ctxt; + (void)argc; + + if (g_ventoy_memdisk_mode || g_ventoy_grub2_mode || g_ventoy_wimboot_mode || g_ventoy_iso_raw) + { + return 1; + } + + if (ventoy_check_mode_by_name(args[0], "vtgrub2") || + ventoy_check_mode_by_name(args[0], "vtwimboot") || + ventoy_check_mode_by_name(args[0], "vtmemdisk") || + ventoy_check_mode_by_name(args[0], "vtnormal") + ) + { + return 1; + } + + env = grub_env_get("VTOY_SECONDARY_BOOT_MENU"); + if (env && env[0] == '0' && env[1] == 0) + { + return 1; + } + + return 0; +} + +static grub_err_t ventoy_cmd_show_secondary_menu(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int n = 0; + int pos = 0; + int len = 0; + int select = 0; + int timeout = 0; + char *cmd = NULL; + const char *env = NULL; + ulonglong fsize = 0; + char cfgfile[128]; + int seldata[16] = {0}; + + (void)ctxt; + (void)argc; + + len = 8 * VTOY_SIZE_1KB; + cmd = (char *)grub_malloc(len); + if (!cmd) + { + return 1; + } + + g_vtoy_secondary_need_recover = 0; + grub_env_unset("VTOY_SECOND_EXIT"); + grub_env_unset("VTOY_CHKSUM_FILE_PATH"); + + env = grub_env_get("VTOY_SECONDARY_TIMEOUT"); + if (env) + { + timeout = (int)grub_strtol(env, NULL, 10); + } + + if (timeout > 0) + { + vtoy_len_ssprintf(cmd, pos, len, "set timeout=%d\n", timeout); + } + + fsize = grub_strtoull(args[2], NULL, 10); + + vtoy_dummy_menuentry(cmd, pos, len, "$VTLANG_NORMAL_MODE", "second_normal"); seldata[n++] = 1; + + if (grub_strcmp(args[1], "Unix") != 0) + { + if (grub_strcmp(args[1], "Windows") == 0) + { + vtoy_dummy_menuentry(cmd, pos, len, "$VTLANG_WIMBOOT_MODE", "second_wimboot"); seldata[n++] = 2; + } + else + { + vtoy_dummy_menuentry(cmd, pos, len, "$VTLANG_GRUB2_MODE", "second_grub2"); seldata[n++] = 3; + } + + if (fsize <= VTOY_SIZE_1GB) + { + vtoy_dummy_menuentry(cmd, pos, len, "$VTLANG_MEMDISK_MODE", "second_memdisk"); seldata[n++] = 4; + } + } + + vtoy_dummy_menuentry(cmd, pos, len, "$VTLANG_FILE_CHKSUM", "second_checksum"); seldata[n++] = 5; + vtoy_dummy_menuentry(cmd, pos, len, "$VTLANG_RETURN_PRV_NOESC", "second_return"); seldata[n++] = 6; + + do { + grub_errno = GRUB_ERR_NONE; + g_ventoy_menu_esc = 1; + g_ventoy_suppress_esc = 1; + g_ventoy_suppress_esc_default = 0; + g_ventoy_secondary_menu_on = 1; + grub_snprintf(cfgfile, sizeof(cfgfile), "configfile mem:0x%llx:size:%d", (ulonglong)(ulong)cmd, pos); + grub_script_execute_sourcecode(cfgfile); + g_ventoy_menu_esc = 0; + g_ventoy_suppress_esc = 0; + g_ventoy_suppress_esc_default = 1; + g_ventoy_secondary_menu_on = 0; + + select = seldata[g_ventoy_last_entry]; + + if (select == 2) + { + g_ventoy_wimboot_mode = 1; + g_vtoy_secondary_need_recover = 1; + } + else if (select == 3) + { + g_ventoy_grub2_mode = 1; + g_vtoy_secondary_need_recover = 2; + } + else if (select == 4) + { + g_ventoy_memdisk_mode = 1; + g_vtoy_secondary_need_recover = 3; + } + else if (select == 5) + { + grub_env_set("VTOY_CHKSUM_FILE_PATH", args[0]); + grub_script_execute_sourcecode("configfile $vtoy_efi_part/grub/checksum.cfg"); + } + else if (select == 6) + { + grub_env_set("VTOY_SECOND_EXIT", "1"); + } + }while (select == 5); + + grub_free(cmd); + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_secondary_recover_mode(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + if (g_vtoy_secondary_need_recover == 1) + { + g_ventoy_wimboot_mode = 0; + } + else if (g_vtoy_secondary_need_recover == 2) + { + g_ventoy_grub2_mode = 0; + } + else if (g_vtoy_secondary_need_recover == 3) + { + g_ventoy_memdisk_mode = 0; + } + + g_vtoy_secondary_need_recover = 0; + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_fs_ignore_case(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + + if (args[0][0] == '0') + { + g_ventoy_case_insensitive = 0; + } + else + { + g_ventoy_case_insensitive = 1; + } + + return 0; +} + +static grub_err_t ventoy_cmd_init_menu_lang(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + + ventoy_plugin_load_menu_lang(1, args[0]); + VENTOY_CMD_RETURN(0); +} + +static grub_err_t ventoy_cmd_load_menu_lang(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + + ventoy_plugin_load_menu_lang(0, args[0]); + VENTOY_CMD_RETURN(0); +} + +static grub_err_t ventoy_cmd_update_sb_policy(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + +#ifdef GRUB_MACHINE_EFI + ventoy_set_sb_policy(); +#endif + + VENTOY_CMD_RETURN(0); +} + +static grub_err_t ventoy_cmd_sb_info(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + +#ifdef GRUB_MACHINE_EFI + const char *policy = NULL; + grub_efi_guid_t security = + { 0xA46423E3, 0x4617, 0x49f1, {0xB9, 0xFF, 0xD1, 0xBF, 0xA9, 0x11, 0x58, 0x39 } }; + grub_efi_guid_t security2 = + { 0x94ab2f58, 0x1438, 0x4ef1, {0x91, 0x52, 0x18, 0x94, 0x1a, 0x3a, 0x0e, 0x68 } }; + + if (g_sb_policy == VTOY_SB_POLICY_BYPASS) + { + policy = "ByPass"; + } + else if (g_sb_policy == VTOY_SB_POLICY_CHECK) + { + policy = "Check"; + } + else + { + policy = "XXX"; + } + + grub_printf("UEFI Security %s\n", grub_efi_locate_protocol(&security, NULL) ? "Yes" : "No"); + grub_printf("UEFI Security2 %s\n", grub_efi_locate_protocol(&security2, NULL) ? "Yes" : "No"); + grub_printf("Ventoy Secure Policy %s\n", policy); + +#else + grub_printf("Non EFI mode!\n"); +#endif + + grub_refresh(); + + VENTOY_CMD_RETURN(0); +} + +static int ventoy_chksum_pathcmp(int chktype, char *rlpath, char *rdpath) +{ + char *pos1 = NULL; + char *pos2 = NULL; + + if (chktype == 2) + { + pos1 = ventoy_str_basename(rlpath); + pos2 = ventoy_str_basename(rdpath); + return grub_strcmp(pos1, pos2); + } + else if (chktype == 3 || chktype == 4) + { + if (grub_strcmp(rlpath, rdpath) == 0 || grub_strcmp(rlpath + 1, rdpath) == 0) + { + return 0; + } + } + + return 1; +} + +static int ventoy_find_checksum +( + grub_file_t file, + const char *uname, + int retlen, + char *path, + int chktype, + char *chksum +) +{ + int ulen; + char *pos = NULL; + char *pos1 = NULL; + char *pos2 = NULL; + char *buf = NULL; + char *currline = NULL; + char *nextline = NULL; + + ulen = (int)grub_strlen(uname); + + /* read file to buffer */ + buf = grub_malloc(file->size + 4); + if (!buf) + { + return 1; + } + grub_file_read(file, buf, file->size); + buf[file->size] = 0; + + /* parse each line */ + for (currline = buf; currline; currline = nextline) + { + nextline = ventoy_get_line(currline); + VTOY_SKIP_SPACE(currline); + + if (grub_strncasecmp(currline, uname, ulen) == 0) + { + pos = grub_strchr(currline, '='); + pos1 = grub_strchr(currline, '('); + pos2 = grub_strchr(currline, ')'); + + if (pos && pos1 && pos2) + { + *pos2 = 0; + if (ventoy_chksum_pathcmp(chktype, path, pos1 + 1) == 0) + { + VTOY_SKIP_SPACE_NEXT(pos, 1); + grub_memcpy(chksum, pos, retlen); + goto end; + } + } + } + else if (ventoy_str_len_alnum(currline, retlen)) + { + VTOY_SKIP_SPACE_NEXT_EX(pos, currline, retlen); + if (ventoy_chksum_pathcmp(chktype, path, pos) == 0) + { + grub_memcpy(chksum, currline, retlen); + goto end; + } + } + } + +end: + grub_free(buf); + return 0; +} + +static int ventoy_check_chkfile(const char *isopart, char *path, const char *lchkname, grub_file_t *pfile) +{ + int ret = 0; + int cnt = 0; + char c = 0; + char *pos = NULL; + grub_file_t file = NULL; + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s.%s", isopart, path, lchkname); + if (file) + { + VTOY_GOTO_END(1); + } + + cnt = ventoy_str_chrcnt(path, '/'); + if (cnt > 1) + { + pos = grub_strrchr(path, '/'); + c = *pos; + *pos = 0; + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s/VENTOY_CHECKSUM", isopart, path); + if (file) + { + *pos = c; + VTOY_GOTO_END(2); + } + *pos = c; + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s/VENTOY_CHECKSUM", isopart); + if (file) + { + ret = (cnt > 1) ? 3 : 4; + } + +end: + + if (pfile) + { + *pfile = file; + } + else + { + check_free(file, grub_file_close); + } + return ret; +} + +static grub_err_t ventoy_cmd_cmp_checksum(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int index = 0; + int chktype = 0; + char *pos = NULL; + grub_file_t file = NULL; + const char *calc_value = NULL; + const char *isopart = NULL; + char fchksum[64]; + char readchk[256] = {0}; + char filebuf[512] = {0}; + char uchkname[16]; + + (void)ctxt; + + index = (int)grub_strtol(args[0], NULL, 10); + if (argc != 2 || index < 0 || index >= VTOY_CHKSUM_NUM) + { + return 1; + } + + grub_strncpy(uchkname, g_lower_chksum_name[index], sizeof(uchkname)); + ventoy_str_toupper(uchkname); + + isopart = grub_env_get("vtoy_iso_part"); + calc_value = grub_env_get("VT_LAST_CHECK_SUM"); + + chktype = ventoy_check_chkfile(isopart, args[1], g_lower_chksum_name[index], &file); + if (chktype <= 0) + { + grub_printf("\n\nNo checksum file found.\n"); + goto end; + } + + if (chktype == 1) + { + grub_snprintf(fchksum, sizeof(fchksum), ".%s", g_lower_chksum_name[index]); + grub_memset(filebuf, 0, sizeof(filebuf)); + grub_file_read(file, filebuf, 511); + + pos = grub_strchr(filebuf, '='); + if (pos) + { + VTOY_SKIP_SPACE_NEXT(pos, 1); + grub_memcpy(readchk, pos, g_chksum_retlen[index]); + } + else + { + grub_memcpy(readchk, filebuf, g_chksum_retlen[index]); + } + } + else if (chktype == 3 || chktype == 4) + { + grub_snprintf(fchksum, sizeof(fchksum), "global VENTOY_CHECKSUM"); + ventoy_find_checksum(file, uchkname, g_chksum_retlen[index], args[1], chktype, readchk); + if (readchk[0] == 0) + { + grub_printf("\n\n%s value not found in %s.\n", uchkname, fchksum); + goto end; + } + } + else + { + grub_snprintf(fchksum, sizeof(fchksum), "local VENTOY_CHECKSUM"); + ventoy_find_checksum(file, uchkname, g_chksum_retlen[index], args[1], chktype, readchk); + if (readchk[0] == 0) + { + grub_file_close(file); + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s/VENTOY_CHECKSUM", isopart); + if (file) + { + grub_snprintf(fchksum, sizeof(fchksum), "global VENTOY_CHECKSUM"); + ventoy_find_checksum(file, uchkname, g_chksum_retlen[index], args[1], 3, readchk); + if (readchk[0] == 0) + { + grub_printf("\n\n%s value not found in both local and global VENTOY_CHECKSUM.\n", uchkname); + goto end; + } + } + } + } + + if (grub_strcasecmp(calc_value, readchk) == 0) + { + grub_printf("\n\nCheck %s value with %s file. [ SUCCESS ]\n", uchkname, fchksum); + } + else + { + grub_printf("\n\nCheck %s value with %s file. [ ERROR ]\n", uchkname, fchksum); + grub_printf("The %s value in %s file is:\n%s\n", uchkname, fchksum, readchk); + } + +end: + grub_refresh(); + check_free(file, grub_file_close); + VENTOY_CMD_RETURN(0); +} + +static int ventoy_find_all_checksum +( + grub_file_t file, + char *path, + int chktype, + int exists[VTOY_CHKSUM_NUM], + int *ptotexist +) +{ + int i; + int ulen; + int tot = 0; + char c = 0; + char *pos = NULL; + char *pos1 = NULL; + char *pos2 = NULL; + char *buf = NULL; + char *currline = NULL; + char *nextline = NULL; + const char *uname = NULL; + + tot = *ptotexist; + + /* read file to buffer */ + buf = grub_malloc(file->size + 4); + if (!buf) + { + return 1; + } + grub_file_read(file, buf, file->size); + buf[file->size] = 0; + + /* parse each line */ + for (currline = buf; currline; currline = nextline) + { + nextline = ventoy_get_line(currline); + VTOY_SKIP_SPACE(currline); + + for (i = 0; i < VTOY_CHKSUM_NUM; i++) + { + if (exists[i]) + { + continue; + } + + uname = g_lower_chksum_name[i]; + ulen = g_lower_chksum_namelen[i]; + + if (grub_strncasecmp(currline, uname, ulen) == 0) + { + pos = grub_strchr(currline, '='); + pos1 = grub_strchr(currline, '('); + pos2 = grub_strchr(currline, ')'); + + if (pos && pos1 && pos2) + { + c = *pos2; + *pos2 = 0; + if (ventoy_chksum_pathcmp(chktype, path, pos1 + 1) == 0) + { + exists[i] = 1; + tot++; + } + *pos2 = c; + } + } + else if (ventoy_str_len_alnum(currline, g_chksum_retlen[i])) + { + VTOY_SKIP_SPACE_NEXT_EX(pos, currline, g_chksum_retlen[i]); + if (ventoy_chksum_pathcmp(chktype, path, pos) == 0) + { + exists[i] = 1; + tot++; + } + } + + if (tot >= VTOY_CHKSUM_NUM) + { + goto end; + } + } + } + +end: + + *ptotexist = tot; + grub_free(buf); + return 0; +} + +static grub_err_t ventoy_cmd_vtoychksum_exist(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i = 0; + int cnt = 0; + char c = 0; + int tip = 0; + char *pos = NULL; + grub_file_t file = NULL; + const char *isopart = NULL; + int exists[VTOY_CHKSUM_NUM] = { 0, 0, 0, 0 }; + int totexist = 0; + + (void)argc; + (void)ctxt; + + isopart = grub_env_get("vtoy_iso_part"); + + for (i = 0; i < VTOY_CHKSUM_NUM; i++) + { + if (ventoy_check_file_exist("%s%s.%s", isopart, args[0], g_lower_chksum_name[i])) + { + exists[i] = 1; + totexist++; + } + } + + if (totexist == VTOY_CHKSUM_NUM) + { + goto end; + } + + cnt = ventoy_str_chrcnt(args[0], '/'); + if (cnt > 1) + { + pos = grub_strrchr(args[0], '/'); + c = *pos; + *pos = 0; + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s/VENTOY_CHECKSUM", isopart, args[0]); + *pos = c; + + if (file) + { + if (tip == 0 && file->size > (32 * VTOY_SIZE_1KB)) + { + tip = 1; + grub_printf("Reading checksum file...\n"); + grub_refresh(); + } + + debug("parse local VENTOY_CHECKSUM\n"); + ventoy_find_all_checksum(file, args[0], 2, exists, &totexist); + grub_file_close(file); + } + } + + if (totexist == VTOY_CHKSUM_NUM) + { + goto end; + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s/VENTOY_CHECKSUM", isopart); + if (file) + { + if (tip == 0 && file->size > (32 * VTOY_SIZE_1KB)) + { + tip = 1; + grub_printf("Reading checksum file...\n"); + grub_refresh(); + } + + debug("parse global VENTOY_CHECKSUM\n"); + ventoy_find_all_checksum(file, args[0], (cnt > 1) ? 3 : 4, exists, &totexist); + grub_file_close(file); + } + +end: + + ventoy_env_int_set("VT_EXIST_MD5", exists[0]); + ventoy_env_int_set("VT_EXIST_SHA1", exists[1]); + ventoy_env_int_set("VT_EXIST_SHA256", exists[2]); + ventoy_env_int_set("VT_EXIST_SHA512", exists[3]); + + VENTOY_CMD_RETURN(0); +} + + +static const char * ventoy_menu_lang_read_hook(struct grub_env_var *var, const char *val) +{ + (void)var; + return ventoy_get_vmenu_title(val); +} + +int ventoy_env_init(void) +{ + int i; + char buf[64]; + + grub_env_set("vtdebug_flag", ""); + + grub_register_vtoy_menu_lang_hook(ventoy_menu_lang_read_hook); + ventoy_ctrl_var_init(); + ventoy_global_var_init(); + + g_part_list_buf = grub_malloc(VTOY_PART_BUF_LEN); + g_tree_script_buf = grub_malloc(VTOY_MAX_SCRIPT_BUF); + g_list_script_buf = grub_malloc(VTOY_MAX_SCRIPT_BUF); + for (i = 0; i < VTOY_MAX_CONF_REPLACE; i++) + { + g_conf_replace_new_buf[i] = grub_malloc(vtoy_max_replace_file_size); + } + + ventoy_filt_register(0, ventoy_wrapper_open); + + g_grub_param = (ventoy_grub_param *)grub_zalloc(sizeof(ventoy_grub_param)); + if (g_grub_param) + { + g_grub_param->grub_env_get = grub_env_get; + g_grub_param->grub_env_set = (grub_env_set_pf)grub_env_set; + g_grub_param->grub_env_printf = (grub_env_printf_pf)grub_printf; + grub_snprintf(buf, sizeof(buf), "%p", g_grub_param); + grub_env_set("env_param", buf); + grub_env_set("ventoy_env_param", buf); + + grub_env_export("env_param"); + grub_env_export("ventoy_env_param"); + } + + grub_env_export("vtoy_winpeshl_ini_addr"); + grub_env_export("vtoy_winpeshl_ini_size"); + + grub_snprintf(buf, sizeof(buf), "0x%lx", (ulong)ventoy_chain_file_size); + grub_env_set("vtoy_chain_file_size", buf); + grub_env_export("vtoy_chain_file_size"); + + grub_snprintf(buf, sizeof(buf), "0x%lx", (ulong)ventoy_chain_file_read); + grub_env_set("vtoy_chain_file_read", buf); + grub_env_export("vtoy_chain_file_read"); + + grub_snprintf(buf, sizeof(buf), "0x%lx", (ulong)ventoy_get_vmenu_title); + grub_env_set("VTOY_VMENU_FUNC_ADDR", buf); + grub_env_export("VTOY_VMENU_FUNC_ADDR"); + + grub_snprintf(buf, sizeof(buf), "%s-%s", GRUB_TARGET_CPU, GRUB_PLATFORM); + grub_env_set("grub_cpu_platform", buf); + grub_env_export("grub_cpu_platform"); + + return 0; +} + + + +static cmd_para ventoy_cmds[] = +{ + { "vt_browser_disk", ventoy_cmd_browser_disk, 0, NULL, "", "", NULL }, + { "vt_browser_dir", ventoy_cmd_browser_dir, 0, NULL, "", "", NULL }, + { "vt_incr", ventoy_cmd_incr, 0, NULL, "{Var} {INT}", "Increase integer variable", NULL }, + { "vt_mod", ventoy_cmd_mod, 0, NULL, "{Int} {Int} {Var}", "mod integer variable", NULL }, + { "vt_strstr", ventoy_cmd_strstr, 0, NULL, "", "", NULL }, + { "vt_istrstr", ventoy_cmd_istrstr, 0, NULL, "", "", NULL }, + { "vt_str_begin", ventoy_cmd_strbegin, 0, NULL, "", "", NULL }, + { "vt_str_casebegin", ventoy_cmd_strcasebegin, 0, NULL, "", "", NULL }, + { "vt_debug", ventoy_cmd_debug, 0, NULL, "{on|off}", "turn debug on/off", NULL }, + { "vtdebug", ventoy_cmd_debug, 0, NULL, "{on|off}", "turn debug on/off", NULL }, + { "vtbreak", ventoy_cmd_break, 0, NULL, "{level}", "set debug break", NULL }, + { "vt_cmp", ventoy_cmd_cmp, 0, NULL, "{Int1} { eq|ne|gt|lt|ge|le } {Int2}", "Comare two integers", NULL }, + { "vt_device", ventoy_cmd_device, 0, NULL, "path var", "", NULL }, + { "vt_check_compatible", ventoy_cmd_check_compatible, 0, NULL, "", "", NULL }, + { "vt_list_img", ventoy_cmd_list_img, 0, NULL, "{device} {cntvar}", "find all iso file in device", NULL }, + { "vt_clear_img", ventoy_cmd_clear_img, 0, NULL, "", "clear image list", NULL }, + { "vt_img_name", ventoy_cmd_img_name, 0, NULL, "{imageID} {var}", "get image name", NULL }, + { "vt_chosen_img_path", ventoy_cmd_chosen_img_path, 0, NULL, "{var}", "get chosen img path", NULL }, + { "vt_ext_select_img_path", ventoy_cmd_ext_select_img_path, 0, NULL, "{var}", "select chosen img path", NULL }, + { "vt_img_sector", ventoy_cmd_img_sector, 0, NULL, "{imageName}", "", NULL }, + { "vt_dump_img_sector", ventoy_cmd_dump_img_sector, 0, NULL, "", "", NULL }, + { "vt_load_wimboot", ventoy_cmd_load_wimboot, 0, NULL, "", "", NULL }, + { "vt_load_vhdboot", ventoy_cmd_load_vhdboot, 0, NULL, "", "", NULL }, + { "vt_patch_vhdboot", ventoy_cmd_patch_vhdboot, 0, NULL, "", "", NULL }, + { "vt_raw_chain_data", ventoy_cmd_raw_chain_data, 0, NULL, "", "", NULL }, + { "vt_get_vtoy_type", ventoy_cmd_get_vtoy_type, 0, NULL, "", "", NULL }, + { "vt_check_custom_boot", ventoy_cmd_check_custom_boot, 0, NULL, "", "", NULL }, + { "vt_dump_custom_boot", ventoy_cmd_dump_custom_boot, 0, NULL, "", "", NULL }, + + { "vt_skip_svd", ventoy_cmd_skip_svd, 0, NULL, "", "", NULL }, + { "vt_cpio_busybox64", ventoy_cmd_cpio_busybox_64, 0, NULL, "", "", NULL }, + { "vt_load_cpio", ventoy_cmd_load_cpio, 0, NULL, "", "", NULL }, + { "vt_trailer_cpio", ventoy_cmd_trailer_cpio, 0, NULL, "", "", NULL }, + { "vt_push_last_entry", ventoy_cmd_push_last_entry, 0, NULL, "", "", NULL }, + { "vt_pop_last_entry", ventoy_cmd_pop_last_entry, 0, NULL, "", "", NULL }, + { "vt_get_lib_module_ver", ventoy_cmd_lib_module_ver, 0, NULL, "", "", NULL }, + + { "vt_load_part_table", ventoy_cmd_load_part_table, 0, NULL, "", "", NULL }, + { "vt_check_part_exist", ventoy_cmd_part_exist, 0, NULL, "", "", NULL }, + { "vt_get_fs_label", ventoy_cmd_get_fs_label, 0, NULL, "", "", NULL }, + { "vt_fs_enum_1st_file", ventoy_cmd_fs_enum_1st_file, 0, NULL, "", "", NULL }, + { "vt_fs_enum_1st_dir", ventoy_cmd_fs_enum_1st_dir, 0, NULL, "", "", NULL }, + { "vt_file_basename", ventoy_cmd_basename, 0, NULL, "", "", NULL }, + { "vt_file_basefile", ventoy_cmd_basefile, 0, NULL, "", "", NULL }, + { "vt_enum_video_mode", ventoy_cmd_enum_video_mode, 0, NULL, "", "", NULL }, + { "vt_get_video_mode", ventoy_cmd_get_video_mode, 0, NULL, "", "", NULL }, + { "vt_update_cur_video_mode", vt_cmd_update_cur_video_mode, 0, NULL, "", "", NULL }, + + + { "vt_find_first_bootable_hd", ventoy_cmd_find_bootable_hdd, 0, NULL, "", "", NULL }, + { "vt_dump_menu", ventoy_cmd_dump_menu, 0, NULL, "", "", NULL }, + { "vt_dynamic_menu", ventoy_cmd_dynamic_menu, 0, NULL, "", "", NULL }, + { "vt_check_mode", ventoy_cmd_check_mode, 0, NULL, "", "", NULL }, + { "vt_dump_img_list", ventoy_cmd_dump_img_list, 0, NULL, "", "", NULL }, + { "vt_dump_injection", ventoy_cmd_dump_injection, 0, NULL, "", "", NULL }, + { "vt_dump_auto_install", ventoy_cmd_dump_auto_install, 0, NULL, "", "", NULL }, + { "vt_dump_persistence", ventoy_cmd_dump_persistence, 0, NULL, "", "", NULL }, + { "vt_select_auto_install", ventoy_cmd_sel_auto_install, 0, NULL, "", "", NULL }, + { "vt_select_persistence", ventoy_cmd_sel_persistence, 0, NULL, "", "", NULL }, + { "vt_select_conf_replace", ventoy_select_conf_replace, 0, NULL, "", "", NULL }, + + { "vt_iso9660_nojoliet", ventoy_cmd_iso9660_nojoliet, 0, NULL, "", "", NULL }, + { "vt_iso9660_isjoliet", ventoy_cmd_iso9660_is_joliet, 0, NULL, "", "", NULL }, + { "vt_is_udf", ventoy_cmd_is_udf, 0, NULL, "", "", NULL }, + { "vt_file_size", ventoy_cmd_file_size, 0, NULL, "", "", NULL }, + { "vt_load_file_to_mem", ventoy_cmd_load_file_to_mem, 0, NULL, "", "", NULL }, + { "vt_load_img_memdisk", ventoy_cmd_load_img_memdisk, 0, NULL, "", "", NULL }, + { "vt_concat_efi_iso", ventoy_cmd_concat_efi_iso, 0, NULL, "", "", NULL }, + + { "vt_linux_parse_initrd_isolinux", ventoy_cmd_isolinux_initrd_collect, 0, NULL, "{cfgfile}", "", NULL }, + { "vt_linux_parse_initrd_grub", ventoy_cmd_grub_initrd_collect, 0, NULL, "{cfgfile}", "", NULL }, + { "vt_linux_specify_initrd_file", ventoy_cmd_specify_initrd_file, 0, NULL, "", "", NULL }, + { "vt_linux_clear_initrd", ventoy_cmd_clear_initrd_list, 0, NULL, "", "", NULL }, + { "vt_linux_dump_initrd", ventoy_cmd_dump_initrd_list, 0, NULL, "", "", NULL }, + { "vt_linux_initrd_count", ventoy_cmd_initrd_count, 0, NULL, "", "", NULL }, + { "vt_linux_valid_initrd_count", ventoy_cmd_valid_initrd_count, 0, NULL, "", "", NULL }, + { "vt_linux_locate_initrd", ventoy_cmd_linux_locate_initrd, 0, NULL, "", "", NULL }, + { "vt_linux_chain_data", ventoy_cmd_linux_chain_data, 0, NULL, "", "", NULL }, + { "vt_linux_get_main_initrd_index", ventoy_cmd_linux_get_main_initrd_index, 0, NULL, "", "", NULL }, + + { "vt_windows_reset", ventoy_cmd_wimdows_reset, 0, NULL, "", "", NULL }, + { "vt_windows_chain_data", ventoy_cmd_windows_chain_data, 0, NULL, "", "", NULL }, + { "vt_windows_wimboot_data", ventoy_cmd_windows_wimboot_data, 0, NULL, "", "", NULL }, + { "vt_windows_collect_wim_patch", ventoy_cmd_collect_wim_patch, 0, NULL, "", "", NULL }, + { "vt_windows_locate_wim_patch", ventoy_cmd_locate_wim_patch, 0, NULL, "", "", NULL }, + { "vt_windows_count_wim_patch", ventoy_cmd_wim_patch_count, 0, NULL, "", "", NULL }, + { "vt_dump_wim_patch", ventoy_cmd_dump_wim_patch, 0, NULL, "", "", NULL }, + { "vt_wim_check_bootable", ventoy_cmd_wim_check_bootable, 0, NULL, "", "", NULL }, + { "vt_wim_chain_data", ventoy_cmd_wim_chain_data, 0, NULL, "", "", NULL }, + + { "vt_add_replace_file", ventoy_cmd_add_replace_file, 0, NULL, "", "", NULL }, + { "vt_get_replace_file_cnt", ventoy_cmd_get_replace_file_cnt, 0, NULL, "", "", NULL }, + { "vt_test_block_list", ventoy_cmd_test_block_list, 0, NULL, "", "", NULL }, + { "vt_file_exist_nocase", ventoy_cmd_file_exist_nocase, 0, NULL, "", "", NULL }, + + + { "vt_load_plugin", ventoy_cmd_load_plugin, 0, NULL, "", "", NULL }, + { "vt_check_plugin_json", ventoy_cmd_plugin_check_json, 0, NULL, "", "", NULL }, + { "vt_check_password", ventoy_cmd_check_password, 0, NULL, "", "", NULL }, + + { "vt_1st_line", ventoy_cmd_read_1st_line, 0, NULL, "", "", NULL }, + { "vt_file_strstr", ventoy_cmd_file_strstr, 0, NULL, "", "", NULL }, + { "vt_img_part_info", ventoy_cmd_img_part_info, 0, NULL, "", "", NULL }, + + + { "vt_parse_iso_volume", ventoy_cmd_parse_volume, 0, NULL, "", "", NULL }, + { "vt_parse_iso_create_date", ventoy_cmd_parse_create_date, 0, NULL, "", "", NULL }, + { "vt_parse_freenas_ver", ventoy_cmd_parse_freenas_ver, 0, NULL, "", "", NULL }, + { "vt_unix_parse_freebsd_ver", ventoy_cmd_unix_freebsd_ver, 0, NULL, "", "", NULL }, + { "vt_unix_parse_freebsd_ver_elf", ventoy_cmd_unix_freebsd_ver_elf, 0, NULL, "", "", NULL }, + { "vt_unix_reset", ventoy_cmd_unix_reset, 0, NULL, "", "", NULL }, + { "vt_unix_check_vlnk", ventoy_cmd_unix_check_vlnk, 0, NULL, "", "", NULL }, + { "vt_unix_replace_conf", ventoy_cmd_unix_replace_conf, 0, NULL, "", "", NULL }, + { "vt_unix_replace_grub_conf", ventoy_cmd_unix_replace_grub_conf, 0, NULL, "", "", NULL }, + { "vt_unix_replace_ko", ventoy_cmd_unix_replace_ko, 0, NULL, "", "", NULL }, + { "vt_unix_ko_fillmap", ventoy_cmd_unix_ko_fillmap, 0, NULL, "", "", NULL }, + { "vt_unix_fill_image_desc", ventoy_cmd_unix_fill_image_desc, 0, NULL, "", "", NULL }, + { "vt_unix_gzip_new_ko", ventoy_cmd_unix_gzip_newko, 0, NULL, "", "", NULL }, + { "vt_unix_chain_data", ventoy_cmd_unix_chain_data, 0, NULL, "", "", NULL }, + + { "vt_img_hook_root", ventoy_cmd_img_hook_root, 0, NULL, "", "", NULL }, + { "vt_img_unhook_root", ventoy_cmd_img_unhook_root, 0, NULL, "", "", NULL }, + { "vt_acpi_param", ventoy_cmd_acpi_param, 0, NULL, "", "", NULL }, + { "vt_check_secureboot_var", ventoy_cmd_check_secureboot_var, 0, NULL, "", "", NULL }, + { "vt_clear_key", ventoy_cmd_clear_key, 0, NULL, "", "", NULL }, + { "vt_img_check_range", ventoy_cmd_img_check_range, 0, NULL, "", "", NULL }, + { "vt_is_pe64", ventoy_cmd_is_pe64, 0, NULL, "", "", NULL }, + { "vt_sel_wimboot", ventoy_cmd_sel_wimboot, 0, NULL, "", "", NULL }, + { "vt_set_wim_load_prompt", ventoy_cmd_set_wim_prompt, 0, NULL, "", "", NULL }, + { "vt_set_theme", ventoy_cmd_set_theme, 0, NULL, "", "", NULL }, + { "vt_set_theme_path", ventoy_cmd_set_theme_path, 0, NULL, "", "", NULL }, + { "vt_select_theme_cfg", ventoy_cmd_select_theme_cfg, 0, NULL, "", "", NULL }, + + { "vt_get_efi_vdisk_offset", ventoy_cmd_get_efivdisk_offset, 0, NULL, "", "", NULL }, + { "vt_search_replace_initrd", ventoy_cmd_search_replace_initrd, 0, NULL, "", "", NULL }, + { "vt_push_pager", ventoy_cmd_push_pager, 0, NULL, "", "", NULL }, + { "vt_pop_pager", ventoy_cmd_pop_pager, 0, NULL, "", "", NULL }, + { "vt_check_json_path_case", ventoy_cmd_chk_json_pathcase, 0, NULL, "", "", NULL }, + { "vt_append_extra_sector", ventoy_cmd_append_ext_sector, 0, NULL, "", "", NULL }, + { "gptpriority", grub_cmd_gptpriority, 0, NULL, "", "", NULL }, + { "vt_syslinux_need_nojoliet", grub_cmd_syslinux_nojoliet, 0, NULL, "", "", NULL }, + { "vt_vlnk_check", grub_cmd_check_vlnk, 0, NULL, "", "", NULL }, + { "vt_vlnk_dump_part", grub_cmd_vlnk_dump_part, 0, NULL, "", "", NULL }, + { "vt_is_vlnk_name", grub_cmd_is_vlnk_name, 0, NULL, "", "", NULL }, + { "vt_get_vlnk_dst", grub_cmd_get_vlnk_dst, 0, NULL, "", "", NULL }, + { "vt_set_fake_vlnk", ventoy_cmd_set_fake_vlnk, 0, NULL, "", "", NULL }, + { "vt_reset_fake_vlnk", ventoy_cmd_reset_fake_vlnk, 0, NULL, "", "", NULL }, + { "vt_iso_vd_id_parse", ventoy_cmd_iso_vd_id_parse, 0, NULL, "", "", NULL }, + { "vt_iso_vd_id_clear", ventoy_iso_vd_id_clear, 0, NULL, "", "", NULL }, + { "vt_iso_vd_id_begin", ventoy_cmd_iso_vd_id_begin, 0, NULL, "", "", NULL }, + { "vt_fn_mutex_lock", ventoy_cmd_fn_mutex_lock, 0, NULL, "", "", NULL }, + { "vt_efi_dump_rsv_page", ventoy_cmd_dump_rsv_page, 0, NULL, "", "", NULL }, + { "vt_is_standard_winiso", ventoy_cmd_is_standard_winiso, 0, NULL, "", "", NULL }, + { "vt_sel_winpe_wim", ventoy_cmd_sel_winpe_wim, 0, NULL, "", "", NULL }, + { "vt_need_secondary_menu", ventoy_cmd_need_secondary_menu, 0, NULL, "", "", NULL }, + { "vt_show_secondary_menu", ventoy_cmd_show_secondary_menu, 0, NULL, "", "", NULL }, + { "vt_fs_ignore_case", ventoy_cmd_fs_ignore_case, 0, NULL, "", "", NULL }, + { "vt_systemd_menu", ventoy_cmd_linux_systemd_menu, 0, NULL, "", "", NULL }, + { "vt_limine_menu", ventoy_cmd_linux_limine_menu, 0, NULL, "", "", NULL }, + { "vt_secondary_recover_mode", ventoy_cmd_secondary_recover_mode, 0, NULL, "", "", NULL }, + { "vt_load_menu_lang", ventoy_cmd_load_menu_lang, 0, NULL, "", "", NULL }, + { "vt_init_menu_lang", ventoy_cmd_init_menu_lang, 0, NULL, "", "", NULL }, + { "vt_cur_menu_lang", ventoy_cmd_cur_menu_lang, 0, NULL, "", "", NULL }, + { "vt_vtoychksum_exist", ventoy_cmd_vtoychksum_exist, 0, NULL, "", "", NULL }, + { "vt_cmp_checksum", ventoy_cmd_cmp_checksum, 0, NULL, "", "", NULL }, + { "vt_push_menu_lang", ventoy_cmd_push_menulang, 0, NULL, "", "", NULL }, + { "vt_pop_menu_lang", ventoy_cmd_pop_menulang, 0, NULL, "", "", NULL }, + { "vt_linux_initrd", ventoy_cmd_linux_initrd, 0, NULL, "", "", NULL }, + + { "vt_sbinfo", ventoy_cmd_sb_info, 0, NULL, "", "", NULL }, + { "vt_update_sb_policy", ventoy_cmd_update_sb_policy, 0, NULL, "", "", NULL }, + +}; + +int ventoy_register_all_cmd(void) +{ + grub_uint32_t i; + cmd_para *cur = NULL; + + for (i = 0; i < ARRAY_SIZE(ventoy_cmds); i++) + { + cur = ventoy_cmds + i; + cur->cmd = grub_register_extcmd(cur->name, cur->func, cur->flags, + cur->summary, cur->description, cur->parser); + } + + return 0; +} + +int ventoy_unregister_all_cmd(void) +{ + grub_uint32_t i; + + for (i = 0; i < ARRAY_SIZE(ventoy_cmds); i++) + { + grub_unregister_extcmd(ventoy_cmds[i].cmd); + } + + return 0; +} + + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h new file mode 100644 index 0000000..22ece47 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h @@ -0,0 +1,1345 @@ +/****************************************************************************** + * ventoy_def.h + * + * Copyright (c) 2020, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#ifndef __VENTOY_DEF_H__ +#define __VENTOY_DEF_H__ + +#define VTOY_MAX_DIR_DEPTH 32 + +#define VTOY_MAX_SCRIPT_BUF (4 * 1024 * 1024) + +#define VTOY_PART_BUF_LEN (128 * 1024) + +#define VTOY_FILT_MIN_FILE_SIZE 32768 + +#define VTOY_LINUX_SYSTEMD_MENU_MAX_BUF 16384 + +#define VTOY_SIZE_1GB 1073741824 +#define VTOY_SIZE_1MB (1024 * 1024) +#define VTOY_SIZE_2MB (2 * 1024 * 1024) +#define VTOY_SIZE_4MB (4 * 1024 * 1024) +#define VTOY_SIZE_512KB (512 * 1024) +#define VTOY_SIZE_1KB 1024 +#define VTOY_SIZE_4KB 4096 +#define VTOY_SIZE_32KB (32 * 1024) +#define VTOY_SIZE_128KB (128 * 1024) + +#define JSON_SUCCESS 0 +#define JSON_FAILED 1 +#define JSON_NOT_FOUND 2 + +#define WINDATA_FLAG_TEMPLATE 1 + +#define ulong unsigned long +#define ulonglong unsigned long long + +#define vtoy_to_upper(c) (((char)(c) >= 'a' && (char)(c) <= 'z') ? ((char)(c) - 'a' + 'A') : (char)(c)) + +#define VENTOY_CMD_RETURN(err) grub_errno = (err); return (err) +#define VENTOY_FILE_TYPE (GRUB_FILE_TYPE_NO_DECOMPRESS | GRUB_FILE_TYPE_LINUX_INITRD) + +#define ventoy_env_op1(op, a) grub_env_##op(a) +#define ventoy_env_op2(op, a, b) grub_env_##op((a), (b)) + +#define ventoy_get_env(key) ventoy_env_op1(get, key) +#define ventoy_set_env(key, val) ventoy_env_op2(set, key, val) + +#define VTOY_WARNING "!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!" + +#define VTOY_CHKSUM_NUM 4 + +#define VTOY_PLAT_I386_UEFI 0x49413332 +#define VTOY_PLAT_ARM64_UEFI 0x41413634 +#define VTOY_PLAT_X86_64_UEFI 0x55454649 +#define VTOY_PLAT_X86_LEGACY 0x42494f53 +#define VTOY_PLAT_MIPS_UEFI 0x4D495053 + +#define VTOY_COMM_CPIO "ventoy.cpio" +#if defined(__arm__) || defined(__aarch64__) +#define VTOY_ARCH_CPIO "ventoy_arm64.cpio" +#elif defined(__mips__) +#define VTOY_ARCH_CPIO "ventoy_mips64.cpio" +#else +#define VTOY_ARCH_CPIO "ventoy_x86.cpio" +#endif + +#define ventoy_left_key "VTLE_LFT" +#define ventoy_top_key "VTLE_TOP" +#define ventoy_color_key "VTLE_CLR" + +#define ventoy_varg_4(arg) arg[0], arg[1], arg[2], arg[3] +#define ventoy_varg_8(arg) arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7] + +#define VTOY_PWD_CORRUPTED(err) \ +{\ + grub_printf("\n\n Password corrupted, will reboot after 5 seconds.\n\n"); \ + grub_refresh(); \ + grub_sleep(5); \ + grub_exit(); \ + return (err);\ +} + +#define vtoy_tip(wait_seconds, fmt, ...) \ + grub_printf(fmt, __VA_ARGS__); \ + grub_refresh(); \ + grub_sleep(wait_seconds) + + +#define VTOY_APPEND_NEWBUF(buf) \ +{\ + char *__c = buf;\ + while (*__c)\ + {\ + newbuf[pos++] = *__c;\ + __c++;\ + }\ +} + +#define VTOY_SKIP_SPACE(s) \ + while (ventoy_isspace(*s)) \ + {\ + s++;\ + } + +#define VTOY_SKIP_SPACE_NEXT(s, initial) \ + s += initial;\ + while (ventoy_isspace(*s)) \ + {\ + s++;\ + } + +#define VTOY_SKIP_SPACE_NEXT_EX(s, base, initial) \ + s = base + initial;\ + while (ventoy_isspace(*s)) \ + {\ + s++;\ + } + +#define VTOY_GOTO_END(v) ret = v; goto end + +typedef enum VTOY_FILE_FLT +{ + VTOY_FILE_FLT_ISO = 0, /* .iso */ + VTOY_FILE_FLT_WIM, /* .wim */ + VTOY_FILE_FLT_EFI, /* .efi */ + VTOY_FILE_FLT_IMG, /* .img */ + VTOY_FILE_FLT_VHD, /* .vhd(x) */ + VTOY_FILE_FLT_VTOY, /* .vtoy */ + + VTOY_FILE_FLT_BUTT +}VTOY_FILE_FLT; + +#define FILE_FLT(type) (0 == g_vtoy_file_flt[VTOY_FILE_FLT_##type]) + +typedef struct ventoy_initrd_ctx +{ + const char *path_prefix; + const char *dir_prefix; +}ventoy_initrd_ctx; + +typedef struct cmd_para +{ + const char *name; + grub_extcmd_func_t func; + grub_command_flags_t flags; + const struct grub_arg_option *parser; + + const char *summary; + const char *description; + + grub_extcmd_t cmd; +}cmd_para; + +#define ventoy_align_2k(value) ((value + 2047) / 2048 * 2048) +#define ventoy_align(value, align) (((value) + ((align) - 1)) & (~((align) - 1))) + +#pragma pack(1) +typedef struct cpio_newc_header +{ + char c_magic[6]; + char c_ino[8]; + char c_mode[8]; + char c_uid[8]; + char c_gid[8]; + char c_nlink[8]; + char c_mtime[8]; + char c_filesize[8]; + char c_devmajor[8]; + char c_devminor[8]; + char c_rdevmajor[8]; + char c_rdevminor[8]; + char c_namesize[8]; + char c_check[8]; +}cpio_newc_header; +#pragma pack() + + +#define cmd_raw_name ctxt->extcmd->cmd->name +#define check_free(p, func) if (p) { func(p); p = NULL; } +#define grub_check_free(p) if (p) { grub_free(p); p = NULL; } + +#define VTOY_SHIM_POLICY_GUID {0x90a29d14, 0x3968, 0x48fe, { 0x85, 0x81, 0x6b, 0x7f, 0x7d, 0xc4, 0x70, 0x55 }}; + +typedef void (*VTOY_BYPASS_SB)(void); +typedef void (*VTOY_CHECK_SB)(void); +typedef void (*VTOY_LAUNCHED)(void); +typedef struct _VTOY_SHIM{ + VTOY_BYPASS_SB ByPassSB; + VTOY_CHECK_SB CheckSB; + VTOY_LAUNCHED Launched; +} VTOY_SHIM; + + +typedef int (*grub_char_check_func)(int c); +#define ventoy_is_decimal(str) ventoy_string_check(str, grub_isdigit) + +#define OFFSET_OF(TYPE, MEMBER) ((grub_size_t) &((TYPE *)0)->MEMBER) + +#pragma pack(1) +typedef struct ventoy_patch_vhd +{ + grub_uint8_t part_offset_or_guid[16]; + grub_uint32_t reserved1; + grub_uint32_t part_type; + grub_uint8_t disk_signature_or_guid[16]; + grub_uint8_t reserved2[16]; + grub_uint8_t vhd_file_path[1]; +}ventoy_patch_vhd; +#pragma pack() + +// El Torito Boot Record Volume Descriptor +#pragma pack(1) +typedef struct eltorito_descriptor +{ + grub_uint8_t type; + grub_uint8_t id[5]; + grub_uint8_t version; + grub_uint8_t system_id[32]; + grub_uint8_t reserved[32]; + grub_uint32_t sector; +}eltorito_descriptor; + +typedef struct ventoy_iso9660_override +{ + grub_uint32_t first_sector; + grub_uint32_t first_sector_be; + grub_uint32_t size; + grub_uint32_t size_be; +}ventoy_iso9660_override; + +typedef struct ventoy_udf_override +{ + grub_uint32_t length; + grub_uint32_t position; +}ventoy_udf_override; + +typedef struct ventoy_iso9660_vd +{ + grub_uint8_t type; + grub_uint8_t id[5]; + grub_uint8_t ver; + grub_uint8_t res; + char sys[32]; + char vol[32]; + grub_uint8_t res2[8]; + grub_uint32_t space; +}ventoy_iso9660_vd; + +/* https://wiki.osdev.org/El-Torito */ +typedef struct boot_info_table +{ + grub_uint32_t bi_data0; + grub_uint32_t bi_data1; + grub_uint32_t bi_PrimaryVolumeDescriptor; + grub_uint32_t bi_BootFileLocation; + grub_uint32_t bi_BootFileLength; + grub_uint32_t bi_Checksum; + grub_uint8_t bi_Reserved[40]; +}boot_info_table; + +#pragma pack() + +#define img_type_start 0 +#define img_type_iso 0 +#define img_type_wim 1 +#define img_type_efi 2 +#define img_type_img 3 +#define img_type_vhd 4 +#define img_type_vtoy 5 +#define img_type_max 6 + +typedef struct img_info +{ + int pathlen; + char path[512]; + char name[256]; + + const char *alias; + const char *tip1; + const char *tip2; + const char *class; + const char *menu_prefix; + + int id; + int type; + int plugin_list_index; + grub_uint64_t size; + int select; + int unsupport; + + void *parent; + + struct img_info *next; + struct img_info *prev; +}img_info; + +typedef struct img_iterator_node +{ + struct img_iterator_node *next; + img_info **tail; + char dir[400]; + int dirlen; + int level; + int isocnt; + int done; + int select; + + int plugin_list_index; + + struct img_iterator_node *parent; + struct img_iterator_node *firstchild; + + void *firstiso; +}img_iterator_node; + + + +typedef struct initrd_info +{ + char name[256]; + + grub_uint64_t offset; + grub_uint64_t size; + + grub_uint8_t iso_type; // 0: iso9660 1:udf + grub_uint32_t udf_start_block; + + grub_uint64_t override_offset; + grub_uint32_t override_length; + char override_data[32]; + + struct initrd_info *next; + struct initrd_info *prev; +}initrd_info; + +extern initrd_info *g_initrd_img_list; +extern initrd_info *g_initrd_img_tail; +extern int g_initrd_img_count; +extern int g_valid_initrd_count; + +extern img_info *g_ventoy_img_list; +extern int g_ventoy_img_count; + +extern grub_uint8_t *g_ventoy_cpio_buf; +extern grub_uint32_t g_ventoy_cpio_size; +extern cpio_newc_header *g_ventoy_initrd_head; +extern grub_uint8_t *g_ventoy_runtime_buf; + +extern ventoy_guid g_ventoy_guid; + +extern ventoy_img_chunk_list g_img_chunk_list; +extern ventoy_img_chunk_list g_wimiso_chunk_list; +extern char *g_wimiso_path; +extern grub_uint32_t g_wimiso_size; +extern char g_arch_mode_suffix[64]; +extern const char *g_menu_prefix[img_type_max]; + +extern int g_ventoy_debug; +void ventoy_debug(const char *fmt, ...); +#define debug(fmt, args...) if (g_ventoy_debug) ventoy_debug("[VTOY]: "fmt, ##args) + +#define vtoy_ssprintf(buf, pos, fmt, args...) \ + pos += grub_snprintf(buf + pos, VTOY_MAX_SCRIPT_BUF - pos, fmt, ##args) + +#define vtoy_len_ssprintf(buf, pos, len, fmt, args...) \ + pos += grub_snprintf(buf + pos, len - pos, fmt, ##args) + +#define browser_ssprintf(mbuf, fmt, args...) \ + (mbuf)->pos += grub_snprintf((mbuf)->buf + (mbuf)->pos, (mbuf)->max - (mbuf)->pos, fmt, ##args) + +#define vtoy_dummy_menuentry(buf, pos, len, title, class) \ + vtoy_len_ssprintf(buf, pos, len, "menuentry \"%s\" --class=\"%s\" {\n echo \"\"\n}\n", title, class) + + +#define FLAG_HEADER_RESERVED 0x00000001 +#define FLAG_HEADER_COMPRESSION 0x00000002 +#define FLAG_HEADER_READONLY 0x00000004 +#define FLAG_HEADER_SPANNED 0x00000008 +#define FLAG_HEADER_RESOURCE_ONLY 0x00000010 +#define FLAG_HEADER_METADATA_ONLY 0x00000020 +#define FLAG_HEADER_WRITE_IN_PROGRESS 0x00000040 +#define FLAG_HEADER_RP_FIX 0x00000080 // reparse point fixup +#define FLAG_HEADER_COMPRESS_RESERVED 0x00010000 +#define FLAG_HEADER_COMPRESS_XPRESS 0x00020000 +#define FLAG_HEADER_COMPRESS_LZX 0x00040000 +#define FLAG_HEADER_COMPRESS_LZMS 0x00080000 + +#define RESHDR_FLAG_FREE 0x01 +#define RESHDR_FLAG_METADATA 0x02 +#define RESHDR_FLAG_COMPRESSED 0x04 +#define RESHDR_FLAG_SPANNED 0x08 + +#pragma pack(1) + +/* A WIM resource header */ +typedef struct wim_resource_header +{ + grub_uint64_t size_in_wim:56; /* Compressed length */ + grub_uint64_t flags:8; /* flags */ + grub_uint64_t offset; /* Offset */ + grub_uint64_t raw_size; /* Uncompressed length */ +}wim_resource_header; + +/* WIM resource header length mask */ +#define WIM_RESHDR_ZLEN_MASK 0x00ffffffffffffffULL + +/* WIM resource header flags */ +typedef enum wim_resource_header_flags +{ + WIM_RESHDR_METADATA = ( 0x02ULL << 56 ), /* Resource contains metadata */ + WIM_RESHDR_COMPRESSED = ( 0x04ULL << 56 ), /* Resource is compressed */ + WIM_RESHDR_PACKED_STREAMS = ( 0x10ULL << 56 ), /* Resource is compressed using packed streams */ +}wim_resource_header_flags; + +#define WIM_HEAD_SIGNATURE "MSWIM\0\0" + +/* WIM header */ +typedef struct wim_header +{ + grub_uint8_t signature[8]; /* Signature */ + grub_uint32_t header_len; /* Header length */ + grub_uint32_t version; /* Verson */ + grub_uint32_t flags; /* Flags */ + grub_uint32_t chunk_len; /* Chunk length */ + grub_uint8_t guid[16]; /* GUID */ + grub_uint16_t part; /* Part number */ + grub_uint16_t parts; /* Total number of parts */ + grub_uint32_t images; /* number of images */ + wim_resource_header lookup; /* Lookup table */ + wim_resource_header xml; /* XML data */ + wim_resource_header metadata; /* Boot metadata */ + grub_uint32_t boot_index; /* Boot index */ + wim_resource_header integrity; /* Integrity table */ + grub_uint8_t reserved[60]; /* Reserved */ +} wim_header; + +/* WIM header flags */ +typedef enum wim_header_flags +{ + WIM_HDR_XPRESS = 0x00020000, /* WIM uses Xpress compresson */ + WIM_HDR_LZX = 0x00040000, /* WIM uses LZX compression */ +}wim_header_flags; + +/* A WIM file hash */ +typedef struct wim_hash +{ + /* SHA-1 hash */ + grub_uint8_t sha1[20]; +}wim_hash; + +/* A WIM lookup table entry */ +typedef struct wim_lookup_entry +{ + wim_resource_header resource; /* Resource header */ + grub_uint16_t part; /* Part number */ + grub_uint32_t refcnt; /* Reference count */ + wim_hash hash; /* Hash */ +}wim_lookup_entry; + +/* WIM chunk length */ +#define WIM_CHUNK_LEN 32768 + +/* A WIM chunk buffer */ +typedef struct wim_chunk_buffer +{ + grub_uint8_t data[WIM_CHUNK_LEN]; /*Data */ +}wim_chunk_buffer; + +/* Security data */ +typedef struct wim_security_header +{ + grub_uint32_t len; /* Length */ + grub_uint32_t count; /* Number of entries */ +}wim_security_header; + +typedef struct wim_stream_entry +{ + grub_uint64_t len; + grub_uint64_t unused1; + wim_hash hash; + grub_uint16_t name_len; + /* name */ +}wim_stream_entry; + +/* Directory entry */ +typedef struct wim_directory_entry +{ + grub_uint64_t len; /* Length */ + grub_uint32_t attributes; /* Attributes */ + grub_uint32_t security; /* Security ID */ + grub_uint64_t subdir; /* Subdirectory offset */ + grub_uint8_t reserved1[16]; /* Reserved */ + grub_uint64_t created; /* Creation time */ + grub_uint64_t accessed; /* Last access time */ + grub_uint64_t written; /* Last written time */ + wim_hash hash; /* Hash */ + grub_uint8_t reserved2[12]; /* Reserved */ + grub_uint16_t streams; /* Streams */ + grub_uint16_t short_name_len; /* Short name length */ + grub_uint16_t name_len; /* Name length */ +}wim_directory_entry; + +/** Normal file */ +#define WIM_ATTR_NORMAL 0x00000080UL + +/** No security information exists for this file */ +#define WIM_NO_SECURITY 0xffffffffUL + +typedef struct reg_vk +{ + grub_uint32_t res1; + grub_uint16_t sig; + grub_uint16_t namesize; + grub_uint32_t datasize; + grub_uint32_t dataoffset; + grub_uint32_t datatype; + grub_uint16_t flag; + grub_uint16_t res2; +}reg_vk; + +#pragma pack() + + +typedef struct wim_tail +{ + grub_uint32_t wim_raw_size; + grub_uint32_t wim_align_size; + + grub_uint8_t iso_type; + grub_uint64_t file_offset; + grub_uint32_t udf_start_block; + grub_uint64_t fe_entry_size_offset; + grub_uint64_t override_offset; + grub_uint32_t override_len; + grub_uint8_t override_data[32]; + + wim_header wim_header; + + wim_hash bin_hash; + grub_uint32_t jump_exe_len; + grub_uint8_t *jump_bin_data; + grub_uint32_t bin_raw_len; + grub_uint32_t bin_align_len; + grub_uint32_t windata_flag; + + grub_uint8_t *new_meta_data; + grub_uint32_t new_meta_len; + grub_uint32_t new_meta_align_len; + + grub_uint8_t *new_lookup_data; + grub_uint32_t new_lookup_len; + grub_uint32_t new_lookup_align_len; +}wim_tail; + +typedef struct wim_patch +{ + int pathlen; + char path[256]; + + wim_hash old_hash; + wim_tail wim_data; + wim_lookup_entry *replace_look; + + int valid; + + struct wim_patch *next; +}wim_patch; + + +typedef enum _JSON_TYPE +{ + JSON_TYPE_NUMBER = 0, + JSON_TYPE_STRING, + JSON_TYPE_BOOL, + JSON_TYPE_ARRAY, + JSON_TYPE_OBJECT, + JSON_TYPE_NULL, + JSON_TYPE_BUTT +}JSON_TYPE; + + +typedef struct _VTOY_JSON +{ + struct _VTOY_JSON *pstPrev; + struct _VTOY_JSON *pstNext; + struct _VTOY_JSON *pstChild; + + JSON_TYPE enDataType; + union + { + char *pcStrVal; + int iNumVal; + grub_uint64_t lValue; + }unData; + + char *pcName; +}VTOY_JSON; + +typedef struct _JSON_PARSE +{ + char *pcKey; + void *pDataBuf; + grub_uint32_t uiBufSize; +}JSON_PARSE; + +#define JSON_NEW_ITEM(pstJson, ret) \ +{ \ + (pstJson) = (VTOY_JSON *)grub_zalloc(sizeof(VTOY_JSON)); \ + if (NULL == (pstJson)) \ + { \ + json_debug("Failed to alloc memory for json.\n"); \ + return (ret); \ + } \ +} + +typedef int (*ventoy_plugin_entry_pf)(VTOY_JSON *json, const char *isodisk); +typedef int (*ventoy_plugin_check_pf)(VTOY_JSON *json, const char *isodisk); + +typedef struct plugin_entry +{ + const char *key; + ventoy_plugin_entry_pf entryfunc; + ventoy_plugin_check_pf checkfunc; + int flag; +}plugin_entry; + +typedef struct replace_fs_dir +{ + grub_device_t dev; + grub_fs_t fs; + char fullpath[512]; + char initrd[512]; + int curpos; + int dircnt; + int filecnt; +}replace_fs_dir; + +typedef struct chk_case_fs_dir +{ + grub_device_t dev; + grub_fs_t fs; +}chk_case_fs_dir; + +int ventoy_str_all_digit(const char *str); +int ventoy_str_all_alnum(const char *str); +int ventoy_str_len_alnum(const char *str, int len); +char * ventoy_str_basename(char *path); +grub_err_t ventoy_env_int_set(const char *name, int value); +int ventoy_str_chrcnt(const char *str, char c); +int ventoy_strcmp(const char *pattern, const char *str); +int ventoy_strncmp (const char *pattern, const char *str, grub_size_t n); +void ventoy_fill_os_param(grub_file_t file, ventoy_os_param *param); +grub_err_t ventoy_cmd_isolinux_initrd_collect(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_grub_initrd_collect(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_specify_initrd_file(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_dump_initrd_list(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_clear_initrd_list(grub_extcmd_context_t ctxt, int argc, char **args); +grub_uint32_t ventoy_get_iso_boot_catlog(grub_file_t file); +int ventoy_has_efi_eltorito(grub_file_t file, grub_uint32_t sector); +grub_err_t ventoy_cmd_linux_chain_data(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_linux_systemd_menu(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_linux_initrd(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_linux_limine_menu(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_linux_locate_initrd(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_initrd_count(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_valid_initrd_count(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_append_ext_sector(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_skip_svd(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_cpio_busybox_64(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_trailer_cpio(grub_extcmd_context_t ctxt, int argc, char **args); +int ventoy_cpio_newc_fill_head(void *buf, int filesize, const void *filedata, const char *name); +grub_file_t ventoy_grub_file_open(enum grub_file_type type, const char *fmt, ...); +grub_uint64_t ventoy_grub_get_file_size(const char *fmt, ...); +int ventoy_is_dir_exist(const char *fmt, ...); +int ventoy_fill_data(grub_uint32_t buflen, char *buffer); +grub_err_t ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_wimdows_reset(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_is_pe64(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_windows_wimboot_data(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_wim_check_bootable(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_is_standard_winiso(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_dump_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_sel_wimboot(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_set_wim_prompt(grub_extcmd_context_t ctxt, int argc, char **args); +grub_ssize_t ventoy_load_file_with_prompt(grub_file_t file, void *buf, grub_ssize_t size); +int ventoy_need_prompt_load_file(void); + +VTOY_JSON *vtoy_json_find_item +( + VTOY_JSON *pstJson, + JSON_TYPE enDataType, + const char *szKey +); +int vtoy_json_parse_value +( + char *pcNewStart, + char *pcRawStart, + VTOY_JSON *pstJson, + const char *pcData, + const char **ppcEnd +); +VTOY_JSON * vtoy_json_create(void); +int vtoy_json_parse(VTOY_JSON *pstJson, const char *szJsonData); + +int vtoy_json_scan_parse +( + const VTOY_JSON *pstJson, + grub_uint32_t uiParseNum, + JSON_PARSE *pstJsonParse +); + +int vtoy_json_scan_array +( + VTOY_JSON *pstJson, + const char *szKey, + VTOY_JSON **ppstArrayItem +); + +int vtoy_json_scan_array_ex +( + VTOY_JSON *pstJson, + const char *szKey, + VTOY_JSON **ppstArrayItem +); +int vtoy_json_scan_object +( + VTOY_JSON *pstJson, + const char *szKey, + VTOY_JSON **ppstObjectItem +); +int vtoy_json_get_int +( + VTOY_JSON *pstJson, + const char *szKey, + int *piValue +); +int vtoy_json_get_uint +( + VTOY_JSON *pstJson, + const char *szKey, + grub_uint32_t *puiValue +); +int vtoy_json_get_uint64 +( + VTOY_JSON *pstJson, + const char *szKey, + grub_uint64_t *pui64Value +); +int vtoy_json_get_bool +( + VTOY_JSON *pstJson, + const char *szKey, + grub_uint8_t *pbValue +); +int vtoy_json_get_string +( + VTOY_JSON *pstJson, + const char *szKey, + grub_uint32_t uiBufLen, + char *pcBuf +); +const char * vtoy_json_get_string_ex(VTOY_JSON *pstJson, const char *szKey); +int vtoy_json_destroy(VTOY_JSON *pstJson); + + +grub_uint32_t CalculateCrc32 +( + const void *Buffer, + grub_uint32_t Length, + grub_uint32_t InitValue +); + +static inline int ventoy_isspace (int c) +{ + return (c == '\n' || c == '\r' || c == ' ' || c == '\t'); +} + +static inline int ventoy_is_word_end(int c) +{ + return (c == 0 || c == ',' || ventoy_isspace(c)); +} + +#pragma pack(1) +typedef struct ventoy_part_table +{ + grub_uint8_t Active; // 0x00 0x80 + + grub_uint8_t StartHead; + grub_uint16_t StartSector : 6; + grub_uint16_t StartCylinder : 10; + + grub_uint8_t FsFlag; + + grub_uint8_t EndHead; + grub_uint16_t EndSector : 6; + grub_uint16_t EndCylinder : 10; + + grub_uint32_t StartSectorId; + grub_uint32_t SectorCount; +}ventoy_part_table; + +typedef struct ventoy_mbr_head +{ + grub_uint8_t BootCode[446]; + ventoy_part_table PartTbl[4]; + grub_uint8_t Byte55; + grub_uint8_t ByteAA; +}ventoy_mbr_head; + +typedef struct ventoy_gpt_head +{ + char Signature[8]; /* EFI PART */ + grub_uint8_t Version[4]; + grub_uint32_t Length; + grub_uint32_t Crc; + grub_uint8_t Reserved1[4]; + grub_uint64_t EfiStartLBA; + grub_uint64_t EfiBackupLBA; + grub_uint64_t PartAreaStartLBA; + grub_uint64_t PartAreaEndLBA; + grub_uint8_t DiskGuid[16]; + grub_uint64_t PartTblStartLBA; + grub_uint32_t PartTblTotNum; + grub_uint32_t PartTblEntryLen; + grub_uint32_t PartTblCrc; + grub_uint8_t Reserved2[420]; +}ventoy_gpt_head; + +typedef struct ventoy_gpt_part_tbl +{ + grub_uint8_t PartType[16]; + grub_uint8_t PartGuid[16]; + grub_uint64_t StartLBA; + grub_uint64_t LastLBA; + grub_uint64_t Attr; + grub_uint16_t Name[36]; +}ventoy_gpt_part_tbl; + +typedef struct ventoy_gpt_info +{ + ventoy_mbr_head MBR; + ventoy_gpt_head Head; + ventoy_gpt_part_tbl PartTbl[128]; +}ventoy_gpt_info; + +typedef struct vhd_footer_t +{ + char cookie[8]; // Cookie + grub_uint32_t features; // Features + grub_uint32_t ffversion; // File format version + grub_uint32_t dataoffset; // Data offset + grub_uint32_t timestamp; // Timestamp + grub_uint32_t creatorapp; // Creator application + grub_uint32_t creatorver; // Creator version + grub_uint32_t creatorhos; // Creator host OS + grub_uint32_t origsize; // Original size + grub_uint32_t currsize; // Current size + grub_uint32_t diskgeom; // Disk geometry + grub_uint32_t disktype; // Disk type + grub_uint32_t checksum; // Checksum + grub_uint8_t uniqueid[16]; // Unique ID + grub_uint8_t savedst; // Saved state +}vhd_footer_t; + +#define VDI_IMAGE_FILE_INFO "<<< Oracle VM VirtualBox Disk Image >>>\n" +#define VDI_IMAGE_FILE_INFO2 "<<< Oracle VirtualBox Disk Image >>>\n" + +/** Image signature. */ +#define VDI_IMAGE_SIGNATURE (0xbeda107f) + +typedef struct VDIPREHEADER +{ + /** Just text info about image type, for eyes only. */ + char szFileInfo[64]; + /** The image signature (VDI_IMAGE_SIGNATURE). */ + grub_uint32_t u32Signature; + /** The image version (VDI_IMAGE_VERSION). */ + grub_uint32_t u32Version; +} VDIPREHEADER, *PVDIPREHEADER; + +#pragma pack() + +typedef struct ventoy_video_mode +{ + grub_uint32_t width; + grub_uint32_t height; + grub_uint32_t bpp; +}ventoy_video_mode; + + + +typedef struct file_fullpath +{ + char path[256]; + int vlnk_add; +}file_fullpath; + +typedef struct theme_list +{ + file_fullpath theme; + struct theme_list *next; +}theme_list; + +#define auto_install_type_file 0 +#define auto_install_type_parent 1 +typedef struct install_template +{ + int type; + int pathlen; + char isopath[256]; + + int timeout; + int autosel; + int cursel; + int templatenum; + file_fullpath *templatepath; + + char *filebuf; + int filelen; + + struct install_template *next; +}install_template; + +typedef struct dudfile +{ + int size; + char *buf; +}dudfile; + +typedef struct dud +{ + int pathlen; + char isopath[256]; + + int dudnum; + file_fullpath *dudpath; + dudfile *files; + + struct dud *next; +}dud; + +typedef struct persistence_config +{ + int pathlen; + char isopath[256]; + + int timeout; + int autosel; + int cursel; + int backendnum; + file_fullpath *backendpath; + + struct persistence_config *next; +}persistence_config; + +#define vtoy_alias_image_file 0 +#define vtoy_alias_directory 1 + +typedef struct menu_alias +{ + int type; + int pathlen; + char isopath[256]; + char alias[256]; + + struct menu_alias *next; +}menu_alias; + +#define vtoy_tip_image_file 0 +#define vtoy_tip_directory 1 +typedef struct menu_tip +{ + int type; + int pathlen; + char isopath[256]; + char tip1[1024]; + char tip2[1024]; + + struct menu_tip *next; +}menu_tip; + + +#define vtoy_class_image_file 0 +#define vtoy_class_directory 1 + +typedef struct menu_class +{ + int type; + int patlen; + int parent; + char pattern[256]; + char class[64]; + + struct menu_class *next; +}menu_class; + +#define vtoy_custom_boot_image_file 0 +#define vtoy_custom_boot_directory 1 + +typedef struct custom_boot +{ + int type; + int pathlen; + char path[256]; + char cfg[256]; + + struct custom_boot *next; +}custom_boot; + +#define vtoy_max_replace_file_size (1024 * 1024) +typedef struct conf_replace +{ + int pathlen; + int img; + char isopath[256]; + char orgconf[256]; + char newconf[256]; + + struct conf_replace *next; +}conf_replace; + +#define injection_type_file 0 +#define injection_type_parent 1 +typedef struct injection_config +{ + int type; + int pathlen; + char isopath[256]; + char archive[256]; + + struct injection_config *next; +}injection_config; + +typedef struct auto_memdisk +{ + int pathlen; + char isopath[256]; + + struct auto_memdisk *next; +}auto_memdisk; + +typedef struct image_list +{ + int pathlen; + char isopath[256]; + + struct image_list *next; +}image_list; + +#define VTOY_PASSWORD_NONE 0 +#define VTOY_PASSWORD_TXT 1 +#define VTOY_PASSWORD_MD5 2 +#define VTOY_PASSWORD_SALT_MD5 3 + +typedef struct vtoy_password +{ + int type; + char text[128]; + char salt[64]; + grub_uint8_t md5[16]; +}vtoy_password; + +#define vtoy_menu_pwd_file 0 +#define vtoy_menu_pwd_parent 1 + +typedef struct menu_password +{ + int type; + int pathlen; + char isopath[256]; + + vtoy_password password; + + struct menu_password *next; +}menu_password; + +extern int g_ventoy_menu_esc; +extern int g_ventoy_secondary_menu_on; +extern int g_ventoy_suppress_esc; +extern int g_ventoy_suppress_esc_default; +extern int g_ventoy_last_entry; +extern int g_ventoy_memdisk_mode; +extern int g_ventoy_iso_raw; +extern int g_ventoy_grub2_mode; +extern int g_ventoy_wimboot_mode; +extern int g_ventoy_iso_uefi_drv; +extern int g_ventoy_case_insensitive; +extern int g_ventoy_fn_mutex; +extern grub_uint8_t g_ventoy_chain_type; +extern int g_vhdboot_enable; +extern int g_default_menu_mode; +extern char g_ventoy_hotkey_tip[256]; +extern int g_ventoy_menu_refresh; + +#define VENTOY_IMG_WHITE_LIST 1 +#define VENTOY_IMG_BLACK_LIST 2 +extern int g_plugin_image_list; + +extern ventoy_gpt_info *g_ventoy_part_info; +extern int g_conf_replace_count; +extern grub_uint64_t g_conf_replace_offset[VTOY_MAX_CONF_REPLACE]; +extern grub_uint64_t g_svd_replace_offset; +extern conf_replace *g_conf_replace_node[VTOY_MAX_CONF_REPLACE]; +extern grub_uint8_t *g_conf_replace_new_buf[VTOY_MAX_CONF_REPLACE]; +extern int g_conf_replace_new_len[VTOY_MAX_CONF_REPLACE]; +extern int g_conf_replace_new_len_align[VTOY_MAX_CONF_REPLACE]; +extern int g_ventoy_disk_bios_id; +extern grub_uint64_t g_ventoy_disk_size; +extern grub_uint64_t g_ventoy_disk_part_size[2]; +extern grub_uint32_t g_ventoy_plat_data; + +#define ventoy_unix_fill_virt(new_data, new_len) \ +{ \ + data_secs = (new_len + 2047) / 2048; \ + cur->mem_sector_start = sector; \ + cur->mem_sector_end = cur->mem_sector_start + data_secs; \ + cur->mem_sector_offset = offset; \ + cur->remap_sector_start = 0; \ + cur->remap_sector_end = 0; \ + cur->org_sector_start = 0; \ + grub_memcpy(override + offset, new_data, new_len); \ + cur++; \ + sector += data_secs; \ + offset += new_len; \ + chain->virt_img_size_in_bytes += data_secs * 2048; \ +} + +#define ventoy_syscall0(name) grub_##name() +#define ventoy_syscall1(name, a) grub_##name(a) + +void ventoy_str_tolower(char *str); +void ventoy_str_toupper(char *str); +char * ventoy_get_line(char *start); +char *ventoy_str_last(char *str, char ch); +int ventoy_cmp_img(img_info *img1, img_info *img2); +void ventoy_swap_img(img_info *img1, img_info *img2); +char * ventoy_plugin_get_cur_install_template(const char *isopath, install_template **cur); +install_template * ventoy_plugin_find_install_template(const char *isopath); +persistence_config * ventoy_plugin_find_persistent(const char *isopath); +grub_uint64_t ventoy_get_vtoy_partsize(int part); +void ventoy_plugin_dump_injection(void); +void ventoy_plugin_dump_auto_install(void); +int ventoy_plugin_get_persistent_chunklist(const char *isopath, int index, ventoy_img_chunk_list *chunk_list); +const char * ventoy_plugin_get_injection(const char *isopath); +const char * ventoy_plugin_get_menu_alias(int type, const char *isopath); +const menu_tip * ventoy_plugin_get_menu_tip(int type, const char *isopath); +const char * ventoy_plugin_get_menu_class(int type, const char *name, const char *path); +int ventoy_plugin_check_memdisk(const char *isopath); +int ventoy_plugin_get_image_list_index(int type, const char *name); +int ventoy_plugin_find_conf_replace(const char *iso, conf_replace *nodes[VTOY_MAX_CONF_REPLACE]); +dud * ventoy_plugin_find_dud(const char *iso); +int ventoy_plugin_load_dud(dud *node, const char *isopart); +int ventoy_get_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start); +int ventoy_check_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start, char *err, grub_uint32_t len); +void ventoy_plugin_dump_persistence(void); +grub_err_t ventoy_cmd_set_theme(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_set_theme_path(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_select_theme_cfg(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_check_password(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_linux_get_main_initrd_index(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_collect_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_wim_patch_count(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_locate_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_sel_winpe_wim(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_unix_chain_data(grub_extcmd_context_t ctxt, int argc, char **args); +int ventoy_get_disk_guid(const char *filename, grub_uint8_t *guid, grub_uint8_t *signature); +grub_err_t ventoy_cmd_unix_reset(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_unix_check_vlnk(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_unix_replace_conf(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_unix_replace_grub_conf(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_unix_replace_ko(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_unix_ko_fillmap(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_unix_fill_image_desc(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_unix_gzip_newko(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_unix_freebsd_ver(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_parse_freenas_ver(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_unix_freebsd_ver_elf(grub_extcmd_context_t ctxt, int argc, char **args); +int ventoy_check_device_result(int ret); +int ventoy_check_device(grub_device_t dev); +void ventoy_debug_dump_guid(const char *prefix, grub_uint8_t *guid); +grub_err_t ventoy_cmd_load_vhdboot(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_patch_vhdboot(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_raw_chain_data(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_get_vtoy_type(grub_extcmd_context_t ctxt, int argc, char **args); +int ventoy_check_password(const vtoy_password *pwd, int retry); +int ventoy_plugin_add_custom_boot(const char *vcfgpath); +const char * ventoy_plugin_get_custom_boot(const char *isopath); +grub_err_t ventoy_cmd_dump_custom_boot(grub_extcmd_context_t ctxt, int argc, char **args); +int ventoy_gzip_compress(void *mem_in, int mem_in_len, void *mem_out, int mem_out_len); +int ventoy_load_part_table(const char *diskname); +int ventoy_env_init(void); +int ventoy_register_all_cmd(void); +int ventoy_unregister_all_cmd(void); +int ventoy_chain_file_size(const char *path); +int ventoy_chain_file_read(const char *path, int offset, int len, void *buf); + +#define VTOY_CMD_CHECK(a) if (33554432 != g_ventoy_disk_part_size[a]) ventoy_syscall0(exit) + +#define vtoy_theme_random_boot_second 0 +#define vtoy_theme_random_boot_day 1 +#define vtoy_theme_random_boot_month 2 + +#define ventoy_env_export(env, name) \ +{\ + grub_env_set((env), (name));\ + grub_env_export(env);\ +} + +#define ret_goto_end(a) ret = a; goto end; + +extern ventoy_grub_param *g_grub_param; + +#pragma pack(1) +#define VENTOY_UNIX_SEG_MAGIC0 0x11223344 +#define VENTOY_UNIX_SEG_MAGIC1 0x55667788 +#define VENTOY_UNIX_SEG_MAGIC2 0x99aabbcc +#define VENTOY_UNIX_SEG_MAGIC3 0xddeeff00 +#define VENTOY_UNIX_MAX_SEGNUM 40960 +struct g_ventoy_seg { + grub_uint64_t seg_start_bytes; + grub_uint64_t seg_end_bytes; +}; + +struct g_ventoy_map{ + grub_uint32_t magic1[4]; + grub_uint32_t magic2[4]; + grub_uint64_t segnum; + grub_uint64_t disksize; + grub_uint8_t diskuuid[16]; + struct g_ventoy_seg seglist[VENTOY_UNIX_MAX_SEGNUM]; + grub_uint32_t magic3[4]; +}; +#pragma pack() + +typedef struct ventoy_vlnk_part +{ + grub_uint32_t disksig; + grub_uint64_t partoffset; + char disk[64]; + char device[64]; + grub_device_t dev; + grub_fs_t fs; + int probe; + struct ventoy_vlnk_part *next; +}ventoy_vlnk_part; + + +typedef struct browser_mbuf +{ + int max; + int pos; + char *buf; +}browser_mbuf; + +typedef struct browser_node +{ + int dir; + char menuentry[1024]; + char filename[512]; + struct browser_node *prev; + struct browser_node *next; +}browser_node; + +typedef struct var_node +{ + char var[128]; + char val[256]; + + struct var_node *next; +}var_node; + +typedef struct systemd_menu_ctx +{ + char *dev; + char *buf; + const char *initrd_cmd; + int pos; + int len; +}systemd_menu_ctx; + +typedef struct global_var_cfg +{ + const char *name; + const char *defval; + char *value; +}global_var_cfg; + +typedef struct ctrl_var_cfg +{ + const char *name; + char szval[2]; +}ctrl_var_cfg; + +#define vtoy_check_goto_out(p) if (!p) goto out + +extern char *g_tree_script_buf; +extern int g_tree_script_pos; +extern int g_tree_script_pre; +extern int g_tree_view_menu_style; +extern int g_sort_case_sensitive; +extern int g_wimboot_enable; +extern int g_filt_dot_underscore_file; +extern int g_filt_trash_dir; +extern int g_vtoy_file_flt[VTOY_FILE_FLT_BUTT]; +extern const char *g_menu_class[img_type_max]; +extern char g_iso_path[256]; +int ventoy_add_vlnk_file(char *dir, const char *name); +grub_err_t ventoy_cmd_browser_dir(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_browser_disk(grub_extcmd_context_t ctxt, int argc, char **args); +int ventoy_get_fs_type(const char *fs); +int ventoy_img_name_valid(const char *filename, grub_size_t namelen); +void * ventoy_alloc_chain(grub_size_t size); +int ventoy_plugin_load_menu_lang(int init, const char *lang); +const char *ventoy_get_vmenu_title(const char *vMenu); +grub_err_t ventoy_cmd_cur_menu_lang(grub_extcmd_context_t ctxt, int argc, char **args); +extern int ventoy_menu_push_key(int code); +int ventoy_ctrl_var_init(void); +int ventoy_global_var_init(void); +grub_err_t ventoy_cmd_push_menulang(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_pop_menulang(grub_extcmd_context_t ctxt, int argc, char **args); +void ventoy_prompt_end(void); +int ventoy_set_sb_policy(void); + +#endif /* __VENTOY_DEF_H__ */ + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_json.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_json.c new file mode 100644 index 0000000..8f81779 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_json.c @@ -0,0 +1,758 @@ +/****************************************************************************** + * ventoy_json.c + * + * Copyright (c) 2020, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ventoy_def.h" + +GRUB_MOD_LICENSE ("GPLv3+"); + +static void json_debug(const char *fmt, ...) +{ + va_list args; + + if (g_ventoy_debug == 0) + { + return; + } + + va_start (args, fmt); + grub_vprintf (fmt, args); + va_end (args); + + grub_printf("\n"); +} + +static void vtoy_json_free(VTOY_JSON *pstJsonHead) +{ + VTOY_JSON *pstNext = NULL; + + while (NULL != pstJsonHead) + { + pstNext = pstJsonHead->pstNext; + if ((pstJsonHead->enDataType < JSON_TYPE_BUTT) && (NULL != pstJsonHead->pstChild)) + { + vtoy_json_free(pstJsonHead->pstChild); + } + + grub_free(pstJsonHead); + pstJsonHead = pstNext; + } + + return; +} + +static char *vtoy_json_skip(const char *pcData) +{ + while ((NULL != pcData) && ('\0' != *pcData) && (*pcData <= 32)) + { + pcData++; + } + + return (char *)pcData; +} + +VTOY_JSON *vtoy_json_find_item +( + VTOY_JSON *pstJson, + JSON_TYPE enDataType, + const char *szKey +) +{ + while (NULL != pstJson) + { + if ((enDataType == pstJson->enDataType) && + (0 == grub_strcmp(szKey, pstJson->pcName))) + { + return pstJson; + } + pstJson = pstJson->pstNext; + } + + return NULL; +} + +static int vtoy_json_parse_number +( + VTOY_JSON *pstJson, + const char *pcData, + const char **ppcEnd +) +{ + unsigned long Value; + + Value = grub_strtoul(pcData, (char **)ppcEnd, 10); + if (*ppcEnd == pcData) + { + json_debug("Failed to parse json number %s.", pcData); + return JSON_FAILED; + } + + pstJson->enDataType = JSON_TYPE_NUMBER; + pstJson->unData.lValue = Value; + + return JSON_SUCCESS; +} + +static int vtoy_json_parse_string +( + char *pcNewStart, + char *pcRawStart, + VTOY_JSON *pstJson, + const char *pcData, + const char **ppcEnd +) +{ + grub_uint32_t uiLen = 0; + const char *pcPos = NULL; + const char *pcTmp = pcData + 1; + + *ppcEnd = pcData; + + if ('\"' != *pcData) + { + return JSON_FAILED; + } + + pcPos = grub_strchr(pcTmp, '\"'); + if ((NULL == pcPos) || (pcPos < pcTmp)) + { + json_debug("Invalid string %s.", pcData); + return JSON_FAILED; + } + + if (*(pcPos - 1) == '\\') + { + for (pcPos++; *pcPos; pcPos++) + { + if (*pcPos == '"' && *(pcPos - 1) != '\\') + { + break; + } + } + + if (*pcPos == 0 || pcPos < pcTmp) + { + json_debug("Invalid quotes string %s.", pcData); + return JSON_FAILED; + } + } + + *ppcEnd = pcPos + 1; + uiLen = (grub_uint32_t)(unsigned long)(pcPos - pcTmp); + + pstJson->enDataType = JSON_TYPE_STRING; + pstJson->unData.pcStrVal = pcNewStart + (pcTmp - pcRawStart); + pstJson->unData.pcStrVal[uiLen] = '\0'; + + return JSON_SUCCESS; +} + +static int vtoy_json_parse_array +( + char *pcNewStart, + char *pcRawStart, + VTOY_JSON *pstJson, + const char *pcData, + const char **ppcEnd +) +{ + int Ret = JSON_SUCCESS; + VTOY_JSON *pstJsonChild = NULL; + VTOY_JSON *pstJsonItem = NULL; + const char *pcTmp = pcData + 1; + + *ppcEnd = pcData; + pstJson->enDataType = JSON_TYPE_ARRAY; + + if ('[' != *pcData) + { + return JSON_FAILED; + } + + pcTmp = vtoy_json_skip(pcTmp); + + if (']' == *pcTmp) + { + *ppcEnd = pcTmp + 1; + return JSON_SUCCESS; + } + + JSON_NEW_ITEM(pstJson->pstChild, JSON_FAILED); + + Ret = vtoy_json_parse_value(pcNewStart, pcRawStart, pstJson->pstChild, pcTmp, ppcEnd); + if (JSON_SUCCESS != Ret) + { + json_debug("Failed to parse array child."); + return JSON_FAILED; + } + + pstJsonChild = pstJson->pstChild; + pcTmp = vtoy_json_skip(*ppcEnd); + while ((NULL != pcTmp) && (',' == *pcTmp)) + { + JSON_NEW_ITEM(pstJsonItem, JSON_FAILED); + pstJsonChild->pstNext = pstJsonItem; + pstJsonItem->pstPrev = pstJsonChild; + pstJsonChild = pstJsonItem; + + Ret = vtoy_json_parse_value(pcNewStart, pcRawStart, pstJsonChild, vtoy_json_skip(pcTmp + 1), ppcEnd); + if (JSON_SUCCESS != Ret) + { + json_debug("Failed to parse array child."); + return JSON_FAILED; + } + pcTmp = vtoy_json_skip(*ppcEnd); + } + + if ((NULL != pcTmp) && (']' == *pcTmp)) + { + *ppcEnd = pcTmp + 1; + return JSON_SUCCESS; + } + else + { + *ppcEnd = pcTmp; + return JSON_FAILED; + } +} + +static int vtoy_json_parse_object +( + char *pcNewStart, + char *pcRawStart, + VTOY_JSON *pstJson, + const char *pcData, + const char **ppcEnd +) +{ + int Ret = JSON_SUCCESS; + VTOY_JSON *pstJsonChild = NULL; + VTOY_JSON *pstJsonItem = NULL; + const char *pcTmp = pcData + 1; + + *ppcEnd = pcData; + pstJson->enDataType = JSON_TYPE_OBJECT; + + if ('{' != *pcData) + { + return JSON_FAILED; + } + + pcTmp = vtoy_json_skip(pcTmp); + if ('}' == *pcTmp) + { + *ppcEnd = pcTmp + 1; + return JSON_SUCCESS; + } + + JSON_NEW_ITEM(pstJson->pstChild, JSON_FAILED); + + Ret = vtoy_json_parse_string(pcNewStart, pcRawStart, pstJson->pstChild, pcTmp, ppcEnd); + if (JSON_SUCCESS != Ret) + { + json_debug("Failed to parse array child."); + return JSON_FAILED; + } + + pstJsonChild = pstJson->pstChild; + pstJsonChild->pcName = pstJsonChild->unData.pcStrVal; + pstJsonChild->unData.pcStrVal = NULL; + + pcTmp = vtoy_json_skip(*ppcEnd); + if ((NULL == pcTmp) || (':' != *pcTmp)) + { + *ppcEnd = pcTmp; + return JSON_FAILED; + } + + Ret = vtoy_json_parse_value(pcNewStart, pcRawStart, pstJsonChild, vtoy_json_skip(pcTmp + 1), ppcEnd); + if (JSON_SUCCESS != Ret) + { + json_debug("Failed to parse array child."); + return JSON_FAILED; + } + + pcTmp = vtoy_json_skip(*ppcEnd); + while ((NULL != pcTmp) && (',' == *pcTmp)) + { + JSON_NEW_ITEM(pstJsonItem, JSON_FAILED); + pstJsonChild->pstNext = pstJsonItem; + pstJsonItem->pstPrev = pstJsonChild; + pstJsonChild = pstJsonItem; + + Ret = vtoy_json_parse_string(pcNewStart, pcRawStart, pstJsonChild, vtoy_json_skip(pcTmp + 1), ppcEnd); + if (JSON_SUCCESS != Ret) + { + json_debug("Failed to parse array child."); + return JSON_FAILED; + } + + pcTmp = vtoy_json_skip(*ppcEnd); + pstJsonChild->pcName = pstJsonChild->unData.pcStrVal; + pstJsonChild->unData.pcStrVal = NULL; + if ((NULL == pcTmp) || (':' != *pcTmp)) + { + *ppcEnd = pcTmp; + return JSON_FAILED; + } + + Ret = vtoy_json_parse_value(pcNewStart, pcRawStart, pstJsonChild, vtoy_json_skip(pcTmp + 1), ppcEnd); + if (JSON_SUCCESS != Ret) + { + json_debug("Failed to parse array child."); + return JSON_FAILED; + } + + pcTmp = vtoy_json_skip(*ppcEnd); + } + + if ((NULL != pcTmp) && ('}' == *pcTmp)) + { + *ppcEnd = pcTmp + 1; + return JSON_SUCCESS; + } + else + { + *ppcEnd = pcTmp; + return JSON_FAILED; + } +} + +int vtoy_json_parse_value +( + char *pcNewStart, + char *pcRawStart, + VTOY_JSON *pstJson, + const char *pcData, + const char **ppcEnd +) +{ + pcData = vtoy_json_skip(pcData); + + switch (*pcData) + { + case 'n': + { + if (0 == grub_strncmp(pcData, "null", 4)) + { + pstJson->enDataType = JSON_TYPE_NULL; + *ppcEnd = pcData + 4; + return JSON_SUCCESS; + } + break; + } + case 'f': + { + if (0 == grub_strncmp(pcData, "false", 5)) + { + pstJson->enDataType = JSON_TYPE_BOOL; + pstJson->unData.lValue = 0; + *ppcEnd = pcData + 5; + return JSON_SUCCESS; + } + break; + } + case 't': + { + if (0 == grub_strncmp(pcData, "true", 4)) + { + pstJson->enDataType = JSON_TYPE_BOOL; + pstJson->unData.lValue = 1; + *ppcEnd = pcData + 4; + return JSON_SUCCESS; + } + break; + } + case '\"': + { + return vtoy_json_parse_string(pcNewStart, pcRawStart, pstJson, pcData, ppcEnd); + } + case '[': + { + return vtoy_json_parse_array(pcNewStart, pcRawStart, pstJson, pcData, ppcEnd); + } + case '{': + { + return vtoy_json_parse_object(pcNewStart, pcRawStart, pstJson, pcData, ppcEnd); + } + case '-': + { + return vtoy_json_parse_number(pstJson, pcData, ppcEnd); + } + default : + { + if (*pcData >= '0' && *pcData <= '9') + { + return vtoy_json_parse_number(pstJson, pcData, ppcEnd); + } + } + } + + *ppcEnd = pcData; + json_debug("Invalid json data %u.", (grub_uint8_t)(*pcData)); + return JSON_FAILED; +} + +VTOY_JSON * vtoy_json_create(void) +{ + VTOY_JSON *pstJson = NULL; + + pstJson = (VTOY_JSON *)grub_zalloc(sizeof(VTOY_JSON)); + if (NULL == pstJson) + { + return NULL; + } + + return pstJson; +} + +int vtoy_json_parse(VTOY_JSON *pstJson, const char *szJsonData) +{ + grub_uint32_t uiMemSize = 0; + int Ret = JSON_SUCCESS; + char *pcNewBuf = NULL; + const char *pcEnd = NULL; + + uiMemSize = grub_strlen(szJsonData) + 1; + pcNewBuf = (char *)grub_malloc(uiMemSize); + if (NULL == pcNewBuf) + { + json_debug("Failed to alloc new buf."); + return JSON_FAILED; + } + grub_memcpy(pcNewBuf, szJsonData, uiMemSize); + pcNewBuf[uiMemSize - 1] = 0; + + Ret = vtoy_json_parse_value(pcNewBuf, (char *)szJsonData, pstJson, szJsonData, &pcEnd); + if (JSON_SUCCESS != Ret) + { + json_debug("Failed to parse json data %s start=%p, end=%p:%s.", + szJsonData, szJsonData, pcEnd, pcEnd); + return JSON_FAILED; + } + + return JSON_SUCCESS; +} + +int vtoy_json_scan_parse +( + const VTOY_JSON *pstJson, + grub_uint32_t uiParseNum, + JSON_PARSE *pstJsonParse +) +{ + grub_uint32_t i = 0; + const VTOY_JSON *pstJsonCur = NULL; + JSON_PARSE *pstCurParse = NULL; + + for (pstJsonCur = pstJson; NULL != pstJsonCur; pstJsonCur = pstJsonCur->pstNext) + { + if ((JSON_TYPE_OBJECT == pstJsonCur->enDataType) || + (JSON_TYPE_ARRAY == pstJsonCur->enDataType)) + { + continue; + } + + for (i = 0, pstCurParse = NULL; i < uiParseNum; i++) + { + if (0 == grub_strcmp(pstJsonParse[i].pcKey, pstJsonCur->pcName)) + { + pstCurParse = pstJsonParse + i; + break; + } + } + + if (NULL == pstCurParse) + { + continue; + } + + switch (pstJsonCur->enDataType) + { + case JSON_TYPE_NUMBER: + { + if (sizeof(grub_uint32_t) == pstCurParse->uiBufSize) + { + *(grub_uint32_t *)(pstCurParse->pDataBuf) = (grub_uint32_t)pstJsonCur->unData.lValue; + } + else if (sizeof(grub_uint16_t) == pstCurParse->uiBufSize) + { + *(grub_uint16_t *)(pstCurParse->pDataBuf) = (grub_uint16_t)pstJsonCur->unData.lValue; + } + else if (sizeof(grub_uint8_t) == pstCurParse->uiBufSize) + { + *(grub_uint8_t *)(pstCurParse->pDataBuf) = (grub_uint8_t)pstJsonCur->unData.lValue; + } + else if ((pstCurParse->uiBufSize > sizeof(grub_uint64_t))) + { + grub_snprintf((char *)pstCurParse->pDataBuf, pstCurParse->uiBufSize, "%llu", + (unsigned long long)(pstJsonCur->unData.lValue)); + } + else + { + json_debug("Invalid number data buf size %u.", pstCurParse->uiBufSize); + } + break; + } + case JSON_TYPE_STRING: + { + grub_strncpy((char *)pstCurParse->pDataBuf, pstJsonCur->unData.pcStrVal, pstCurParse->uiBufSize); + break; + } + case JSON_TYPE_BOOL: + { + *(grub_uint8_t *)(pstCurParse->pDataBuf) = (pstJsonCur->unData.lValue) > 0 ? 1 : 0; + break; + } + default : + { + break; + } + } + } + + return JSON_SUCCESS; +} + +int vtoy_json_scan_array +( + VTOY_JSON *pstJson, + const char *szKey, + VTOY_JSON **ppstArrayItem +) +{ + VTOY_JSON *pstJsonItem = NULL; + + pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_ARRAY, szKey); + if (NULL == pstJsonItem) + { + json_debug("Key %s is not found in json data.", szKey); + return JSON_NOT_FOUND; + } + + *ppstArrayItem = pstJsonItem; + + return JSON_SUCCESS; +} + +int vtoy_json_scan_array_ex +( + VTOY_JSON *pstJson, + const char *szKey, + VTOY_JSON **ppstArrayItem +) +{ + VTOY_JSON *pstJsonItem = NULL; + + pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_ARRAY, szKey); + if (NULL == pstJsonItem) + { + json_debug("Key %s is not found in json data.", szKey); + return JSON_NOT_FOUND; + } + + *ppstArrayItem = pstJsonItem->pstChild; + + return JSON_SUCCESS; +} + +int vtoy_json_scan_object +( + VTOY_JSON *pstJson, + const char *szKey, + VTOY_JSON **ppstObjectItem +) +{ + VTOY_JSON *pstJsonItem = NULL; + + pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_OBJECT, szKey); + if (NULL == pstJsonItem) + { + json_debug("Key %s is not found in json data.", szKey); + return JSON_NOT_FOUND; + } + + *ppstObjectItem = pstJsonItem; + + return JSON_SUCCESS; +} + +int vtoy_json_get_int +( + VTOY_JSON *pstJson, + const char *szKey, + int *piValue +) +{ + VTOY_JSON *pstJsonItem = NULL; + + pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_NUMBER, szKey); + if (NULL == pstJsonItem) + { + json_debug("Key %s is not found in json data.", szKey); + return JSON_NOT_FOUND; + } + + *piValue = (int)pstJsonItem->unData.lValue; + + return JSON_SUCCESS; +} + +int vtoy_json_get_uint +( + VTOY_JSON *pstJson, + const char *szKey, + grub_uint32_t *puiValue +) +{ + VTOY_JSON *pstJsonItem = NULL; + + pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_NUMBER, szKey); + if (NULL == pstJsonItem) + { + json_debug("Key %s is not found in json data.", szKey); + return JSON_NOT_FOUND; + } + + *puiValue = (grub_uint32_t)pstJsonItem->unData.lValue; + + return JSON_SUCCESS; +} + +int vtoy_json_get_uint64 +( + VTOY_JSON *pstJson, + const char *szKey, + grub_uint64_t *pui64Value +) +{ + VTOY_JSON *pstJsonItem = NULL; + + pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_NUMBER, szKey); + if (NULL == pstJsonItem) + { + json_debug("Key %s is not found in json data.", szKey); + return JSON_NOT_FOUND; + } + + *pui64Value = (grub_uint64_t)pstJsonItem->unData.lValue; + + return JSON_SUCCESS; +} + +int vtoy_json_get_bool +( + VTOY_JSON *pstJson, + const char *szKey, + grub_uint8_t *pbValue +) +{ + VTOY_JSON *pstJsonItem = NULL; + + pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_BOOL, szKey); + if (NULL == pstJsonItem) + { + json_debug("Key %s is not found in json data.", szKey); + return JSON_NOT_FOUND; + } + + *pbValue = pstJsonItem->unData.lValue > 0 ? 1 : 0; + + return JSON_SUCCESS; +} + +int vtoy_json_get_string +( + VTOY_JSON *pstJson, + const char *szKey, + grub_uint32_t uiBufLen, + char *pcBuf +) +{ + VTOY_JSON *pstJsonItem = NULL; + + pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_STRING, szKey); + if (NULL == pstJsonItem) + { + json_debug("Key %s is not found in json data.", szKey); + return JSON_NOT_FOUND; + } + + grub_strncpy(pcBuf, pstJsonItem->unData.pcStrVal, uiBufLen); + + return JSON_SUCCESS; +} + +const char * vtoy_json_get_string_ex(VTOY_JSON *pstJson, const char *szKey) +{ + VTOY_JSON *pstJsonItem = NULL; + + if ((NULL == pstJson) || (NULL == szKey)) + { + return NULL; + } + + pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_STRING, szKey); + if (NULL == pstJsonItem) + { + json_debug("Key %s is not found in json data.", szKey); + return NULL; + } + + return pstJsonItem->unData.pcStrVal; +} + +int vtoy_json_destroy(VTOY_JSON *pstJson) +{ + if (NULL == pstJson) + { + return JSON_SUCCESS; + } + + if (NULL != pstJson->pstChild) + { + vtoy_json_free(pstJson->pstChild); + } + + if (NULL != pstJson->pstNext) + { + vtoy_json_free(pstJson->pstNext); + } + + grub_free(pstJson); + + return JSON_SUCCESS; +} + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_linux.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_linux.c new file mode 100644 index 0000000..3777e08 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_linux.c @@ -0,0 +1,2120 @@ +/****************************************************************************** + * ventoy_linux.c + * + * Copyright (c) 2020, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ventoy_def.h" + +GRUB_MOD_LICENSE ("GPLv3+"); + +#define VTOY_APPEND_EXT_SIZE 4096 +static int g_append_ext_sector = 0; + +char * ventoy_get_line(char *start) +{ + if (start == NULL) + { + return NULL; + } + + while (*start && *start != '\n') + { + start++; + } + + if (*start == 0) + { + return NULL; + } + else + { + *start = 0; + return start + 1; + } +} + +static initrd_info * ventoy_find_initrd_by_name(initrd_info *list, const char *name) +{ + initrd_info *node = list; + + while (node) + { + if (grub_strcmp(node->name, name) == 0) + { + return node; + } + node = node->next; + } + + return NULL; +} + +grub_err_t ventoy_cmd_clear_initrd_list(grub_extcmd_context_t ctxt, int argc, char **args) +{ + initrd_info *node = g_initrd_img_list; + initrd_info *next; + + (void)ctxt; + (void)argc; + (void)args; + + while (node) + { + next = node->next; + grub_free(node); + node = next; + } + + g_initrd_img_list = NULL; + g_initrd_img_tail = NULL; + g_initrd_img_count = 0; + g_valid_initrd_count = 0; + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_dump_initrd_list(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i = 0; + initrd_info *node = g_initrd_img_list; + + (void)ctxt; + (void)argc; + (void)args; + + grub_printf("###################\n"); + grub_printf("initrd info list: valid count:%d\n", g_valid_initrd_count); + + while (node) + { + grub_printf("%s ", node->size > 0 ? "*" : " "); + grub_printf("%02u %s offset:%llu size:%llu \n", i++, node->name, (unsigned long long)node->offset, + (unsigned long long)node->size); + node = node->next; + } + + grub_printf("###################\n"); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static void ventoy_parse_directory(char *path, char *dir, int buflen) +{ + int end; + char *pos; + + pos = grub_strstr(path, ")"); + if (!pos) + { + pos = path; + } + + end = grub_snprintf(dir, buflen, "%s", pos + 1); + while (end > 0) + { + if (dir[end] == '/') + { + dir[end + 1] = 0; + break; + } + end--; + } +} + +static grub_err_t ventoy_isolinux_initrd_collect(grub_file_t file, const char *prefix) +{ + int i = 0; + int offset; + int prefixlen = 0; + char *buf = NULL; + char *pos = NULL; + char *start = NULL; + char *nextline = NULL; + initrd_info *img = NULL; + + prefixlen = grub_strlen(prefix); + + buf = grub_zalloc(file->size + 2); + if (!buf) + { + return 0; + } + + grub_file_read(file, buf, file->size); + + for (start = buf; start; start = nextline) + { + nextline = ventoy_get_line(start); + + VTOY_SKIP_SPACE(start); + + offset = 7; // strlen("initrd=") or "INITRD " or "initrd " + pos = grub_strstr(start, "initrd="); + if (pos == NULL) + { + pos = start; + + if (grub_strncmp(start, "INITRD", 6) != 0 && grub_strncmp(start, "initrd", 6) != 0) + { + if (grub_strstr(start, "xen") && + ((pos = grub_strstr(start, "--- /install.img")) != NULL || + (pos = grub_strstr(start, "--- initrd.img")) != NULL + )) + { + offset = 4; // "--- " + } + else + { + continue; + } + } + } + + pos += offset; + + while (1) + { + i = 0; + img = grub_zalloc(sizeof(initrd_info)); + if (!img) + { + break; + } + + if (*pos != '/') + { + grub_strcpy(img->name, prefix); + i = prefixlen; + } + + while (i < 255 && (0 == ventoy_is_word_end(*pos))) + { + img->name[i++] = *pos++; + } + + if (ventoy_find_initrd_by_name(g_initrd_img_list, img->name)) + { + grub_free(img); + } + else + { + if (g_initrd_img_list) + { + img->prev = g_initrd_img_tail; + g_initrd_img_tail->next = img; + } + else + { + g_initrd_img_list = img; + } + + g_initrd_img_tail = img; + g_initrd_img_count++; + } + + if (*pos == ',') + { + pos++; + } + else + { + break; + } + } + } + + grub_free(buf); + return GRUB_ERR_NONE; +} + +static int ventoy_isolinux_initrd_hook(const char *filename, const struct grub_dirhook_info *info, void *data) +{ + grub_file_t file = NULL; + ventoy_initrd_ctx *ctx = (ventoy_initrd_ctx *)data; + + (void)info; + + if (NULL == grub_strstr(filename, ".cfg") && NULL == grub_strstr(filename, ".CFG")) + { + return 0; + } + + debug("init hook dir <%s%s>\n", ctx->path_prefix, filename); + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", ctx->path_prefix, filename); + if (!file) + { + return 0; + } + + ventoy_isolinux_initrd_collect(file, ctx->dir_prefix); + grub_file_close(file); + + return 0; +} + +grub_err_t ventoy_cmd_isolinux_initrd_collect(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_fs_t fs; + grub_device_t dev = NULL; + char *device_name = NULL; + ventoy_initrd_ctx ctx; + char directory[256]; + + (void)ctxt; + (void)argc; + + device_name = grub_file_get_device_name(args[0]); + if (!device_name) + { + goto end; + } + + dev = grub_device_open(device_name); + if (!dev) + { + goto end; + } + + fs = grub_fs_probe(dev); + if (!fs) + { + goto end; + } + + debug("isolinux initrd collect %s\n", args[0]); + + ventoy_parse_directory(args[0], directory, sizeof(directory) - 1); + ctx.path_prefix = args[0]; + ctx.dir_prefix = (argc > 1) ? args[1] : directory; + + debug("path_prefix=<%s> dir_prefix=<%s>\n", ctx.path_prefix, ctx.dir_prefix); + + fs->fs_dir(dev, directory, ventoy_isolinux_initrd_hook, &ctx); + +end: + check_free(device_name, grub_free); + check_free(dev, grub_device_close); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static int ventoy_linux_initrd_collect_hook(const char *filename, const struct grub_dirhook_info *info, void *data) +{ + int len; + initrd_info *img = NULL; + + (void)data; + + if (0 == info->dir) + { + if (grub_strncmp(filename, "initrd", 6) == 0) + { + len = (int)grub_strlen(filename); + if (grub_strcmp(filename + len - 4, ".img") == 0) + { + img = grub_zalloc(sizeof(initrd_info)); + if (img) + { + grub_snprintf(img->name, sizeof(img->name), "/boot/%s", filename); + + if (ventoy_find_initrd_by_name(g_initrd_img_list, img->name)) + { + grub_free(img); + } + else + { + if (g_initrd_img_list) + { + img->prev = g_initrd_img_tail; + g_initrd_img_tail->next = img; + } + else + { + g_initrd_img_list = img; + } + + g_initrd_img_tail = img; + g_initrd_img_count++; + } + } + } + } + } + + return 0; +} + +static int ventoy_linux_collect_boot_initrds(void) +{ + grub_fs_t fs; + grub_device_t dev = NULL; + + dev = grub_device_open("loop"); + if (!dev) + { + debug("failed to open device loop\n"); + goto end; + } + + fs = grub_fs_probe(dev); + if (!fs) + { + debug("failed to probe fs %d\n", grub_errno); + goto end; + } + + fs->fs_dir(dev, "/boot", ventoy_linux_initrd_collect_hook, NULL); + +end: + return 0; +} + +static grub_err_t ventoy_grub_cfg_initrd_collect(const char *fileName) +{ + int i = 0; + int len = 0; + int dollar = 0; + int quotation = 0; + int initrd_dollar = 0; + grub_file_t file = NULL; + char *buf = NULL; + char *start = NULL; + char *nextline = NULL; + initrd_info *img = NULL; + + debug("grub initrd collect %s\n", fileName); + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", fileName); + if (!file) + { + return 0; + } + + buf = grub_zalloc(file->size + 2); + if (!buf) + { + grub_file_close(file); + return 0; + } + + grub_file_read(file, buf, file->size); + + for (start = buf; start; start = nextline) + { + nextline = ventoy_get_line(start); + + VTOY_SKIP_SPACE(start); + + if (grub_strncmp(start, "initrd", 6) != 0) + { + continue; + } + + start += 6; + while (*start && (!ventoy_isspace(*start))) + { + start++; + } + + VTOY_SKIP_SPACE(start); + + if (*start == '"') + { + quotation = 1; + start++; + } + + while (*start) + { + img = grub_zalloc(sizeof(initrd_info)); + if (!img) + { + break; + } + + dollar = 0; + for (i = 0; i < 255 && (0 == ventoy_is_word_end(*start)); i++) + { + img->name[i] = *start++; + if (img->name[i] == '$') + { + dollar = 1; + } + } + + if (quotation) + { + len = (int)grub_strlen(img->name); + if (len > 2 && img->name[len - 1] == '"') + { + img->name[len - 1] = 0; + } + debug("Remove quotation <%s>\n", img->name); + } + + /* special process for /boot/initrd$XXX.img */ + if (dollar == 1) + { + if (grub_strncmp(img->name, "/boot/initrd$", 13) == 0) + { + len = (int)grub_strlen(img->name); + if (grub_strcmp(img->name + len - 4, ".img") == 0) + { + initrd_dollar++; + } + } + } + + if (dollar == 1 || ventoy_find_initrd_by_name(g_initrd_img_list, img->name)) + { + grub_free(img); + } + else + { + if (g_initrd_img_list) + { + img->prev = g_initrd_img_tail; + g_initrd_img_tail->next = img; + } + else + { + g_initrd_img_list = img; + } + + g_initrd_img_tail = img; + g_initrd_img_count++; + } + + if (*start == ' ' || *start == '\t') + { + VTOY_SKIP_SPACE(start); + } + else + { + break; + } + } + } + + grub_free(buf); + grub_file_close(file); + + if (initrd_dollar > 0 && grub_strncmp(fileName, "(loop)/", 7) == 0) + { + debug("collect initrd variable %d\n", initrd_dollar); + ventoy_linux_collect_boot_initrds(); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static int ventoy_grub_initrd_hook(const char *filename, const struct grub_dirhook_info *info, void *data) +{ + char filePath[256]; + ventoy_initrd_ctx *ctx = (ventoy_initrd_ctx *)data; + + (void)info; + + debug("ventoy_grub_initrd_hook %s\n", filename); + + if (NULL == grub_strstr(filename, ".cfg") && + NULL == grub_strstr(filename, ".CFG") && + NULL == grub_strstr(filename, ".conf")) + { + return 0; + } + + debug("init hook dir <%s%s>\n", ctx->path_prefix, filename); + + grub_snprintf(filePath, sizeof(filePath) - 1, "%s%s", ctx->dir_prefix, filename); + ventoy_grub_cfg_initrd_collect(filePath); + + return 0; +} + +grub_err_t ventoy_cmd_grub_initrd_collect(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_fs_t fs; + grub_device_t dev = NULL; + char *device_name = NULL; + ventoy_initrd_ctx ctx; + + (void)ctxt; + (void)argc; + + if (argc != 2) + { + return 0; + } + + debug("grub initrd collect %s %s\n", args[0], args[1]); + + if (grub_strcmp(args[0], "file") == 0) + { + return ventoy_grub_cfg_initrd_collect(args[1]); + } + + device_name = grub_file_get_device_name(args[1]); + if (!device_name) + { + debug("failed to get device name %s\n", args[1]); + goto end; + } + + dev = grub_device_open(device_name); + if (!dev) + { + debug("failed to open device %s\n", device_name); + goto end; + } + + fs = grub_fs_probe(dev); + if (!fs) + { + debug("failed to probe fs %d\n", grub_errno); + goto end; + } + + ctx.dir_prefix = args[1]; + ctx.path_prefix = grub_strstr(args[1], device_name); + if (ctx.path_prefix) + { + ctx.path_prefix += grub_strlen(device_name) + 1; + } + else + { + ctx.path_prefix = args[1]; + } + + debug("ctx.path_prefix:<%s>\n", ctx.path_prefix); + + fs->fs_dir(dev, ctx.path_prefix, ventoy_grub_initrd_hook, &ctx); + +end: + check_free(device_name, grub_free); + check_free(dev, grub_device_close); + + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_specify_initrd_file(grub_extcmd_context_t ctxt, int argc, char **args) +{ + initrd_info *img = NULL; + + (void)ctxt; + (void)argc; + + debug("ventoy_cmd_specify_initrd_file %s\n", args[0]); + + img = grub_zalloc(sizeof(initrd_info)); + if (!img) + { + return 1; + } + + grub_strncpy(img->name, args[0], sizeof(img->name)); + if (ventoy_find_initrd_by_name(g_initrd_img_list, img->name)) + { + debug("%s is already exist\n", args[0]); + grub_free(img); + } + else + { + if (g_initrd_img_list) + { + img->prev = g_initrd_img_tail; + g_initrd_img_tail->next = img; + } + else + { + g_initrd_img_list = img; + } + + g_initrd_img_tail = img; + g_initrd_img_count++; + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static int ventoy_cpio_newc_get_int(char *value) +{ + char buf[16] = {0}; + + grub_memcpy(buf, value, 8); + return (int)grub_strtoul(buf, NULL, 16); +} + +static void ventoy_cpio_newc_fill_int(grub_uint32_t value, char *buf, int buflen) +{ + int i; + int len; + char intbuf[32]; + + len = grub_snprintf(intbuf, sizeof(intbuf), "%x", value); + + for (i = 0; i < buflen; i++) + { + buf[i] = '0'; + } + + if (len > buflen) + { + grub_printf("int buf len overflow %d %d\n", len, buflen); + } + else + { + grub_memcpy(buf + buflen - len, intbuf, len); + } +} + +int ventoy_cpio_newc_fill_head(void *buf, int filesize, const void *filedata, const char *name) +{ + int namelen = 0; + int headlen = 0; + static grub_uint32_t cpio_ino = 0xFFFFFFF0; + cpio_newc_header *cpio = (cpio_newc_header *)buf; + + namelen = grub_strlen(name) + 1; + headlen = sizeof(cpio_newc_header) + namelen; + headlen = ventoy_align(headlen, 4); + + grub_memset(cpio, '0', sizeof(cpio_newc_header)); + grub_memset(cpio + 1, 0, headlen - sizeof(cpio_newc_header)); + + grub_memcpy(cpio->c_magic, "070701", 6); + ventoy_cpio_newc_fill_int(cpio_ino--, cpio->c_ino, 8); + ventoy_cpio_newc_fill_int(0100777, cpio->c_mode, 8); + ventoy_cpio_newc_fill_int(1, cpio->c_nlink, 8); + ventoy_cpio_newc_fill_int(filesize, cpio->c_filesize, 8); + ventoy_cpio_newc_fill_int(namelen, cpio->c_namesize, 8); + grub_memcpy(cpio + 1, name, namelen); + + if (filedata) + { + grub_memcpy((char *)cpio + headlen, filedata, filesize); + } + + return headlen; +} + +static grub_uint32_t ventoy_linux_get_virt_chunk_count(void) +{ + int i; + grub_uint32_t count = g_valid_initrd_count; + + if (g_conf_replace_count > 0) + { + for (i = 0; i < g_conf_replace_count; i++) + { + if (g_conf_replace_offset[i] > 0) + { + count++; + } + } + } + + if (g_append_ext_sector > 0) + { + count++; + } + + return count; +} + +static grub_uint32_t ventoy_linux_get_virt_chunk_size(void) +{ + int i; + grub_uint32_t size; + + size = (sizeof(ventoy_virt_chunk) + g_ventoy_cpio_size) * g_valid_initrd_count; + + if (g_conf_replace_count > 0) + { + for (i = 0; i < g_conf_replace_count; i++) + { + if (g_conf_replace_offset[i] > 0) + { + size += sizeof(ventoy_virt_chunk) + g_conf_replace_new_len_align[i]; + } + } + } + + if (g_append_ext_sector > 0) + { + size += sizeof(ventoy_virt_chunk) + VTOY_APPEND_EXT_SIZE; + } + + return size; +} + +static void ventoy_linux_fill_virt_data( grub_uint64_t isosize, ventoy_chain_head *chain) +{ + int i = 0; + int id = 0; + int virtid = 0; + initrd_info *node; + grub_uint64_t sector; + grub_uint32_t offset; + grub_uint32_t cpio_secs; + grub_uint32_t initrd_secs; + char *override; + ventoy_virt_chunk *cur; + ventoy_grub_param_file_replace *replace = NULL; + char name[32]; + + override = (char *)chain + chain->virt_chunk_offset; + sector = (isosize + 2047) / 2048; + cpio_secs = g_ventoy_cpio_size / 2048; + + offset = ventoy_linux_get_virt_chunk_count() * sizeof(ventoy_virt_chunk); + cur = (ventoy_virt_chunk *)override; + + for (node = g_initrd_img_list; node; node = node->next) + { + if (node->size == 0) + { + continue; + } + + initrd_secs = (grub_uint32_t)((node->size + 2047) / 2048); + + cur->mem_sector_start = sector; + cur->mem_sector_end = cur->mem_sector_start + cpio_secs; + cur->mem_sector_offset = offset; + cur->remap_sector_start = cur->mem_sector_end; + cur->remap_sector_end = cur->remap_sector_start + initrd_secs; + cur->org_sector_start = (grub_uint32_t)(node->offset / 2048); + + grub_memcpy(g_ventoy_runtime_buf, &chain->os_param, sizeof(ventoy_os_param)); + + grub_memset(name, 0, 16); + grub_snprintf(name, sizeof(name), "initrd%03d", ++id); + + grub_memcpy(g_ventoy_initrd_head + 1, name, 16); + ventoy_cpio_newc_fill_int((grub_uint32_t)node->size, g_ventoy_initrd_head->c_filesize, 8); + + grub_memcpy(override + offset, g_ventoy_cpio_buf, g_ventoy_cpio_size); + + chain->virt_img_size_in_bytes += g_ventoy_cpio_size + initrd_secs * 2048; + + offset += g_ventoy_cpio_size; + sector += cpio_secs + initrd_secs; + cur++; + virtid++; + } + + /* Lenovo EasyStartup need an addional sector for boundary check */ + if (g_append_ext_sector > 0) + { + cpio_secs = VTOY_APPEND_EXT_SIZE / 2048; + + cur->mem_sector_start = sector; + cur->mem_sector_end = cur->mem_sector_start + cpio_secs; + cur->mem_sector_offset = offset; + cur->remap_sector_start = 0; + cur->remap_sector_end = 0; + cur->org_sector_start = 0; + + grub_memset(override + offset, 0, VTOY_APPEND_EXT_SIZE); + + chain->virt_img_size_in_bytes += VTOY_APPEND_EXT_SIZE; + + offset += VTOY_APPEND_EXT_SIZE; + sector += cpio_secs; + cur++; + virtid++; + } + + if (g_conf_replace_count > 0) + { + for (i = 0; i < g_conf_replace_count; i++) + { + if (g_conf_replace_offset[i] > 0) + { + cpio_secs = g_conf_replace_new_len_align[i] / 2048; + + cur->mem_sector_start = sector; + cur->mem_sector_end = cur->mem_sector_start + cpio_secs; + cur->mem_sector_offset = offset; + cur->remap_sector_start = 0; + cur->remap_sector_end = 0; + cur->org_sector_start = 0; + + grub_memcpy(override + offset, g_conf_replace_new_buf[i], g_conf_replace_new_len[i]); + + chain->virt_img_size_in_bytes += g_conf_replace_new_len_align[i]; + + replace = g_grub_param->img_replace + i; + if (replace->magic == GRUB_IMG_REPLACE_MAGIC) + { + replace->new_file_virtual_id = virtid; + } + + offset += g_conf_replace_new_len_align[i]; + sector += cpio_secs; + cur++; + virtid++; + } + } + } + + return; +} + +static grub_uint32_t ventoy_linux_get_override_chunk_count(void) +{ + int i; + grub_uint32_t count = g_valid_initrd_count; + + if (g_conf_replace_count > 0) + { + for (i = 0; i < g_conf_replace_count; i++) + { + if (g_conf_replace_offset[i] > 0) + { + count++; + } + } + } + + if (g_svd_replace_offset > 0) + { + count++; + } + + return count; +} + +static grub_uint32_t ventoy_linux_get_override_chunk_size(void) +{ + int i; + int count = g_valid_initrd_count; + + if (g_conf_replace_count > 0) + { + for (i = 0; i < g_conf_replace_count; i++) + { + if (g_conf_replace_offset[i] > 0) + { + count++; + } + } + } + + if (g_svd_replace_offset > 0) + { + count++; + } + + return sizeof(ventoy_override_chunk) * count; +} + +static void ventoy_linux_fill_override_data( grub_uint64_t isosize, void *override) +{ + int i; + initrd_info *node; + grub_uint32_t mod; + grub_uint32_t newlen; + grub_uint64_t sector; + ventoy_override_chunk *cur; + ventoy_iso9660_override *dirent; + ventoy_udf_override *udf; + + sector = (isosize + 2047) / 2048; + + cur = (ventoy_override_chunk *)override; + for (node = g_initrd_img_list; node; node = node->next) + { + if (node->size == 0) + { + continue; + } + + newlen = (grub_uint32_t)(node->size + g_ventoy_cpio_size); + mod = newlen % 4; + if (mod > 0) + { + newlen += 4 - mod; /* cpio must align with 4 */ + } + + if (node->iso_type == 0) + { + dirent = (ventoy_iso9660_override *)node->override_data; + + node->override_length = sizeof(ventoy_iso9660_override); + dirent->first_sector = (grub_uint32_t)sector; + dirent->size = newlen; + dirent->first_sector_be = grub_swap_bytes32(dirent->first_sector); + dirent->size_be = grub_swap_bytes32(dirent->size); + + sector += (dirent->size + 2047) / 2048; + } + else + { + udf = (ventoy_udf_override *)node->override_data; + + node->override_length = sizeof(ventoy_udf_override); + udf->length = newlen; + udf->position = (grub_uint32_t)sector - node->udf_start_block; + + sector += (udf->length + 2047) / 2048; + } + + cur->img_offset = node->override_offset; + cur->override_size = node->override_length; + grub_memcpy(cur->override_data, node->override_data, cur->override_size); + cur++; + } + + if (g_conf_replace_count > 0) + { + for (i = 0; i < g_conf_replace_count; i++) + { + if (g_conf_replace_offset[i] > 0) + { + cur->img_offset = g_conf_replace_offset[i]; + cur->override_size = sizeof(ventoy_iso9660_override); + + newlen = (grub_uint32_t)(g_conf_replace_new_len[i]); + + dirent = (ventoy_iso9660_override *)cur->override_data; + dirent->first_sector = (grub_uint32_t)sector; + dirent->size = newlen; + dirent->first_sector_be = grub_swap_bytes32(dirent->first_sector); + dirent->size_be = grub_swap_bytes32(dirent->size); + + sector += (dirent->size + 2047) / 2048; + cur++; + } + } + } + + if (g_svd_replace_offset > 0) + { + cur->img_offset = g_svd_replace_offset; + cur->override_size = 1; + cur->override_data[0] = 0xFF; + cur++; + } + + return; +} + +grub_err_t ventoy_cmd_initrd_count(grub_extcmd_context_t ctxt, int argc, char **args) +{ + char buf[32] = {0}; + + (void)ctxt; + (void)argc; + (void)args; + + if (argc == 1) + { + grub_snprintf(buf, sizeof(buf), "%d", g_initrd_img_count); + grub_env_set(args[0], buf); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_valid_initrd_count(grub_extcmd_context_t ctxt, int argc, char **args) +{ + char buf[32] = {0}; + + (void)ctxt; + (void)argc; + (void)args; + + if (argc == 1) + { + grub_snprintf(buf, sizeof(buf), "%d", g_valid_initrd_count); + grub_env_set(args[0], buf); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_linux_locate_initrd(int filt, int *filtcnt) +{ + int data; + int filtbysize = 1; + int sizefilt = 0; + grub_file_t file; + initrd_info *node; + + debug("ventoy_linux_locate_initrd %d\n", filt); + + g_valid_initrd_count = 0; + + if (grub_env_get("INITRD_NO_SIZE_FILT")) + { + filtbysize = 0; + } + + for (node = g_initrd_img_list; node; node = node->next) + { + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(loop)%s", node->name); + if (!file) + { + continue; + } + + debug("file <%s> size:%d\n", node->name, (int)file->size); + + /* initrd file too small */ + if (filtbysize + && (NULL == grub_strstr(node->name, "minirt.gz")) + && (NULL == grub_strstr(node->name, "initrd.xz")) + && (NULL == grub_strstr(node->name, "initrd.gz")) + ) + { + if (filt > 0 && file->size <= g_ventoy_cpio_size + 2048) + { + debug("file size too small %d\n", (int)g_ventoy_cpio_size); + grub_file_close(file); + sizefilt++; + continue; + } + } + + /* skip hdt.img */ + if (file->size <= VTOY_SIZE_1MB && grub_strcmp(node->name, "/boot/hdt.img") == 0) + { + continue; + } + + if (grub_strcmp(file->fs->name, "iso9660") == 0) + { + node->iso_type = 0; + node->override_offset = grub_iso9660_get_last_file_dirent_pos(file) + 2; + + grub_file_read(file, &data, 1); // just read for hook trigger + node->offset = grub_iso9660_get_last_read_pos(file); + } + else + { + /* TBD */ + } + + node->size = file->size; + g_valid_initrd_count++; + + grub_file_close(file); + } + + *filtcnt = sizefilt; + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + + +grub_err_t ventoy_cmd_linux_get_main_initrd_index(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int index = 0; + char buf[32]; + initrd_info *node = NULL; + + (void)ctxt; + (void)argc; + (void)args; + + if (argc != 1) + { + return 1; + } + + if (g_initrd_img_count == 1) + { + ventoy_set_env(args[0], "0"); + VENTOY_CMD_RETURN(GRUB_ERR_NONE); + } + + for (node = g_initrd_img_list; node; node = node->next) + { + if (node->size <= 0) + { + continue; + } + + if (grub_strstr(node->name, "ucode") || grub_strstr(node->name, "-firmware")) + { + index++; + continue; + } + + grub_snprintf(buf, sizeof(buf), "%d", index); + ventoy_set_env(args[0], buf); + break; + } + + debug("main initrd index:%d\n", index); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_linux_locate_initrd(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int sizefilt = 0; + + (void)ctxt; + (void)argc; + (void)args; + + ventoy_linux_locate_initrd(1, &sizefilt); + + if (g_valid_initrd_count == 0 && sizefilt > 0) + { + ventoy_linux_locate_initrd(0, &sizefilt); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static int ventoy_cpio_busybox64(cpio_newc_header *head, const char *file) +{ + char *name; + int namelen; + int offset; + int count = 0; + char filepath[128]; + + grub_snprintf(filepath, sizeof(filepath), "ventoy/busybox/%s", file); + + name = (char *)(head + 1); + while (name[0] && count < 2) + { + if (grub_strcmp(name, "ventoy/busybox/ash") == 0) + { + grub_memcpy(name, "ventoy/busybox/32h", 18); + count++; + } + else if (grub_strcmp(name, filepath) == 0) + { + grub_memcpy(name, "ventoy/busybox/ash", 18); + count++; + } + + namelen = ventoy_cpio_newc_get_int(head->c_namesize); + offset = sizeof(cpio_newc_header) + namelen; + offset = ventoy_align(offset, 4); + offset += ventoy_cpio_newc_get_int(head->c_filesize); + offset = ventoy_align(offset, 4); + + head = (cpio_newc_header *)((char *)head + offset); + name = (char *)(head + 1); + } + + return 0; +} + + +grub_err_t ventoy_cmd_cpio_busybox_64(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + debug("ventoy_cmd_busybox_64 %d\n", argc); + ventoy_cpio_busybox64((cpio_newc_header *)g_ventoy_cpio_buf, args[0]); + return 0; +} + +grub_err_t ventoy_cmd_skip_svd(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + grub_file_t file; + char buf[16]; + + (void)ctxt; + (void)argc; + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't open file %s\n", args[0]); + } + + for (i = 0; i < 10; i++) + { + buf[0] = 0; + grub_file_seek(file, (17 + i) * 2048); + grub_file_read(file, buf, 16); + + if (buf[0] == 2 && grub_strncmp(buf + 1, "CD001", 5) == 0) + { + debug("Find SVD at VD %d\n", i); + g_svd_replace_offset = (17 + i) * 2048; + break; + } + } + + if (i >= 10) + { + debug("SVD not found %d\n", (int)g_svd_replace_offset); + } + + grub_file_close(file); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_append_ext_sector(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + if (args[0][0] == '1') + { + g_append_ext_sector = 1; + } + else + { + g_append_ext_sector = 0; + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + int rc; + char *pos = NULL; + char *template_file = NULL; + char *template_buf = NULL; + char *persistent_buf = NULL; + char *injection_buf = NULL; + dud *dudnode = NULL; + char tmpname[128]; + const char *injection_file = NULL; + grub_uint8_t *buf = NULL; + grub_uint32_t mod; + grub_uint32_t headlen; + grub_uint32_t initrd_head_len; + grub_uint32_t padlen; + grub_uint32_t img_chunk_size; + grub_uint32_t template_size = 0; + grub_uint32_t persistent_size = 0; + grub_uint32_t injection_size = 0; + grub_uint32_t dud_size = 0; + grub_file_t file; + grub_file_t archfile; + grub_file_t tmpfile; + install_template *template_node = NULL; + ventoy_img_chunk_list chunk_list; + + (void)ctxt; + (void)argc; + + if (argc != 4) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s cpiofile\n", cmd_raw_name); + } + + if (g_img_chunk_list.chunk == NULL || g_img_chunk_list.cur_chunk == 0) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "image chunk is null\n"); + } + + img_chunk_size = g_img_chunk_list.cur_chunk * sizeof(ventoy_img_chunk); + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s/%s", args[0], VTOY_COMM_CPIO); + if (!file) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't open file %s/%s\n", args[0], VTOY_COMM_CPIO); + } + + archfile = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s/%s", args[0], VTOY_ARCH_CPIO); + if (!archfile) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't open file %s/%s\n", args[0], VTOY_ARCH_CPIO); + grub_file_close(file); + } + + debug("load %s %s success\n", VTOY_COMM_CPIO, VTOY_ARCH_CPIO); + + if (g_ventoy_cpio_buf) + { + grub_free(g_ventoy_cpio_buf); + g_ventoy_cpio_buf = NULL; + g_ventoy_cpio_size = 0; + } + + rc = ventoy_plugin_get_persistent_chunklist(args[1], -1, &chunk_list); + if (rc == 0 && chunk_list.cur_chunk > 0 && chunk_list.chunk) + { + persistent_size = chunk_list.cur_chunk * sizeof(ventoy_img_chunk); + persistent_buf = (char *)(chunk_list.chunk); + } + + template_file = ventoy_plugin_get_cur_install_template(args[1], &template_node); + if (template_file) + { + debug("auto install template: <%s> \n", + template_file, template_node->filebuf, template_node->filelen); + + template_size = template_node->filelen; + template_buf = grub_malloc(template_size); + if (template_buf) + { + grub_memcpy(template_buf, template_node->filebuf, template_size); + } + } + else + { + debug("auto install script skipped or not configed %s\n", args[1]); + } + + injection_file = ventoy_plugin_get_injection(args[1]); + if (injection_file) + { + debug("injection archive: <%s>\n", injection_file); + tmpfile = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", args[2], injection_file); + if (tmpfile) + { + debug("injection archive size:%d\n", (int)tmpfile->size); + injection_size = tmpfile->size; + injection_buf = grub_malloc(injection_size); + if (injection_buf) + { + grub_file_read(tmpfile, injection_buf, injection_size); + } + + grub_file_close(tmpfile); + } + else + { + debug("Failed to open injection archive %s%s\n", args[2], injection_file); + } + } + else + { + debug("injection not configed %s\n", args[1]); + } + + dudnode = ventoy_plugin_find_dud(args[1]); + if (dudnode) + { + debug("dud file: <%d>\n", dudnode->dudnum); + ventoy_plugin_load_dud(dudnode, args[2]); + for (i = 0; i < dudnode->dudnum; i++) + { + if (dudnode->files[i].size > 0) + { + dud_size += dudnode->files[i].size + sizeof(cpio_newc_header); + } + } + } + else + { + debug("dud not configed %s\n", args[1]); + } + + g_ventoy_cpio_buf = grub_malloc(file->size + archfile->size + 40960 + template_size + + persistent_size + injection_size + dud_size + img_chunk_size); + if (NULL == g_ventoy_cpio_buf) + { + grub_file_close(file); + grub_file_close(archfile); + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't alloc memory %llu\n", file->size); + } + + grub_file_read(file, g_ventoy_cpio_buf, file->size); + buf = (grub_uint8_t *)(g_ventoy_cpio_buf + file->size - 4); + while (*((grub_uint32_t *)buf) != 0x37303730) + { + buf -= 4; + } + + grub_file_read(archfile, buf, archfile->size); + buf += (archfile->size - 4); + while (*((grub_uint32_t *)buf) != 0x37303730) + { + buf -= 4; + } + + /* get initrd head len */ + initrd_head_len = ventoy_cpio_newc_fill_head(buf, 0, NULL, "initrd000.xx"); + + /* step1: insert image chunk data to cpio */ + headlen = ventoy_cpio_newc_fill_head(buf, img_chunk_size, g_img_chunk_list.chunk, "ventoy/ventoy_image_map"); + buf += headlen + ventoy_align(img_chunk_size, 4); + + if (template_buf) + { + headlen = ventoy_cpio_newc_fill_head(buf, template_size, template_buf, "ventoy/autoinstall"); + buf += headlen + ventoy_align(template_size, 4); + grub_check_free(template_buf); + } + + if (persistent_size > 0 && persistent_buf) + { + headlen = ventoy_cpio_newc_fill_head(buf, persistent_size, persistent_buf, "ventoy/ventoy_persistent_map"); + buf += headlen + ventoy_align(persistent_size, 4); + grub_check_free(persistent_buf); + } + + if (injection_size > 0 && injection_buf) + { + headlen = ventoy_cpio_newc_fill_head(buf, injection_size, injection_buf, "ventoy/ventoy_injection"); + buf += headlen + ventoy_align(injection_size, 4); + + grub_free(injection_buf); + injection_buf = NULL; + } + + if (dud_size > 0) + { + for (i = 0; i < dudnode->dudnum; i++) + { + pos = grub_strrchr(dudnode->dudpath[i].path, '.'); + grub_snprintf(tmpname, sizeof(tmpname), "ventoy/ventoy_dud%d%s", i, (pos ? pos : ".iso")); + dud_size = dudnode->files[i].size; + headlen = ventoy_cpio_newc_fill_head(buf, dud_size, dudnode->files[i].buf, tmpname); + buf += headlen + ventoy_align(dud_size, 4); + } + } + + /* step2: insert os param to cpio */ + headlen = ventoy_cpio_newc_fill_head(buf, 0, NULL, "ventoy/ventoy_os_param"); + padlen = sizeof(ventoy_os_param); + g_ventoy_cpio_size = (grub_uint32_t)(buf - g_ventoy_cpio_buf) + headlen + padlen + initrd_head_len; + mod = g_ventoy_cpio_size % 2048; + if (mod) + { + g_ventoy_cpio_size += 2048 - mod; + padlen += 2048 - mod; + } + + /* update os param data size, the data will be updated before chain boot */ + ventoy_cpio_newc_fill_int(padlen, ((cpio_newc_header *)buf)->c_filesize, 8); + g_ventoy_runtime_buf = (grub_uint8_t *)buf + headlen; + + /* step3: fill initrd cpio head, the file size will be updated before chain boot */ + g_ventoy_initrd_head = (cpio_newc_header *)(g_ventoy_runtime_buf + padlen); + ventoy_cpio_newc_fill_head(g_ventoy_initrd_head, 0, NULL, "initrd000.xx"); + + grub_file_close(file); + grub_file_close(archfile); + + if (grub_strcmp(args[3], "busybox=64") == 0) + { + debug("cpio busybox proc %s\n", args[3]); + ventoy_cpio_busybox64((cpio_newc_header *)g_ventoy_cpio_buf, "64h"); + } + else if (grub_strcmp(args[3], "busybox=a64") == 0) + { + debug("cpio busybox proc %s\n", args[3]); + ventoy_cpio_busybox64((cpio_newc_header *)g_ventoy_cpio_buf, "a64"); + } + else if (grub_strcmp(args[3], "busybox=m64") == 0) + { + debug("cpio busybox proc %s\n", args[3]); + ventoy_cpio_busybox64((cpio_newc_header *)g_ventoy_cpio_buf, "m64"); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_trailer_cpio(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int mod; + int bufsize; + int namelen; + int offset; + char *name; + grub_uint8_t *bufend; + cpio_newc_header *head; + grub_file_t file; + const grub_uint8_t trailler[124] = { + 0x30, 0x37, 0x30, 0x37, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x42, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x54, 0x52, + 0x41, 0x49, 0x4C, 0x45, 0x52, 0x21, 0x21, 0x21, 0x00, 0x00, 0x00, 0x00 + }; + + (void)ctxt; + (void)argc; + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", args[0], args[1]); + if (!file) + { + return 1; + } + + grub_memset(g_ventoy_runtime_buf, 0, sizeof(ventoy_os_param)); + ventoy_fill_os_param(file, (ventoy_os_param *)g_ventoy_runtime_buf); + + grub_file_close(file); + + grub_memcpy(g_ventoy_initrd_head, trailler, sizeof(trailler)); + bufend = (grub_uint8_t *)g_ventoy_initrd_head + sizeof(trailler); + + bufsize = (int)(bufend - g_ventoy_cpio_buf); + mod = bufsize % 512; + if (mod) + { + grub_memset(bufend, 0, 512 - mod); + bufsize += 512 - mod; + } + + if (argc > 1 && grub_strcmp(args[2], "noinit") == 0) + { + head = (cpio_newc_header *)g_ventoy_cpio_buf; + name = (char *)(head + 1); + + while (grub_strcmp(name, "TRAILER!!!")) + { + if (grub_strcmp(name, "init") == 0) + { + grub_memcpy(name, "xxxx", 4); + } + else if (grub_strcmp(name, "linuxrc") == 0) + { + grub_memcpy(name, "vtoyxrc", 7); + } + else if (grub_strcmp(name, "sbin") == 0) + { + grub_memcpy(name, "vtoy", 4); + } + else if (grub_strcmp(name, "sbin/init") == 0) + { + grub_memcpy(name, "vtoy/vtoy", 9); + } + + namelen = ventoy_cpio_newc_get_int(head->c_namesize); + offset = sizeof(cpio_newc_header) + namelen; + offset = ventoy_align(offset, 4); + offset += ventoy_cpio_newc_get_int(head->c_filesize); + offset = ventoy_align(offset, 4); + + head = (cpio_newc_header *)((char *)head + offset); + name = (char *)(head + 1); + } + } + + ventoy_memfile_env_set("ventoy_cpio", g_ventoy_cpio_buf, (ulonglong)bufsize); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_linux_chain_data(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int len = 0; + int ventoy_compatible = 0; + grub_uint32_t size = 0; + grub_uint64_t isosize = 0; + grub_uint32_t boot_catlog = 0; + grub_uint32_t img_chunk_size = 0; + grub_uint32_t override_count = 0; + grub_uint32_t override_size = 0; + grub_uint32_t virt_chunk_count = 0; + grub_uint32_t virt_chunk_size = 0; + grub_file_t file; + grub_disk_t disk; + const char *pLastChain = NULL; + const char *compatible; + ventoy_chain_head *chain; + + (void)ctxt; + (void)argc; + + compatible = grub_env_get("ventoy_compatible"); + if (compatible && compatible[0] == 'Y') + { + ventoy_compatible = 1; + } + + if ((NULL == g_img_chunk_list.chunk) || (0 == ventoy_compatible && g_ventoy_cpio_buf == NULL)) + { + grub_printf("ventoy not ready\n"); + return 1; + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + return 1; + } + + isosize = file->size; + + len = (int)grub_strlen(args[0]); + if (len >= 4 && 0 == grub_strcasecmp(args[0] + len - 4, ".img")) + { + debug("boot catlog %u for img file\n", boot_catlog); + } + else + { + boot_catlog = ventoy_get_iso_boot_catlog(file); + if (boot_catlog) + { + if (ventoy_is_efi_os() && (!ventoy_has_efi_eltorito(file, boot_catlog))) + { + grub_env_set("LoadIsoEfiDriver", "on"); + } + } + else + { + if (ventoy_is_efi_os()) + { + grub_env_set("LoadIsoEfiDriver", "on"); + } + else + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "File %s is not bootable", args[0]); + } + } + } + + img_chunk_size = g_img_chunk_list.cur_chunk * sizeof(ventoy_img_chunk); + + override_count = ventoy_linux_get_override_chunk_count(); + virt_chunk_count = ventoy_linux_get_virt_chunk_count(); + + if (ventoy_compatible) + { + size = sizeof(ventoy_chain_head) + img_chunk_size; + } + else + { + override_size = ventoy_linux_get_override_chunk_size(); + virt_chunk_size = ventoy_linux_get_virt_chunk_size(); + size = sizeof(ventoy_chain_head) + img_chunk_size + override_size + virt_chunk_size; + } + + pLastChain = grub_env_get("vtoy_chain_mem_addr"); + if (pLastChain) + { + chain = (ventoy_chain_head *)grub_strtoul(pLastChain, NULL, 16); + if (chain) + { + debug("free last chain memory %p\n", chain); + grub_free(chain); + } + } + + chain = ventoy_alloc_chain(size); + if (!chain) + { + grub_printf("Failed to alloc chain linux memory size %u\n", size); + grub_file_close(file); + return 1; + } + + ventoy_memfile_env_set("vtoy_chain_mem", chain, (ulonglong)size); + + grub_memset(chain, 0, sizeof(ventoy_chain_head)); + + /* part 1: os parameter */ + g_ventoy_chain_type = ventoy_chain_linux; + ventoy_fill_os_param(file, &(chain->os_param)); + + /* part 2: chain head */ + disk = file->device->disk; + chain->disk_drive = disk->id; + chain->disk_sector_size = (1 << disk->log_sector_size); + chain->real_img_size_in_bytes = file->size; + chain->virt_img_size_in_bytes = (file->size + 2047) / 2048 * 2048; + chain->boot_catalog = boot_catlog; + + if (!ventoy_is_efi_os()) + { + grub_file_seek(file, boot_catlog * 2048); + grub_file_read(file, chain->boot_catalog_sector, sizeof(chain->boot_catalog_sector)); + } + + /* part 3: image chunk */ + chain->img_chunk_offset = sizeof(ventoy_chain_head); + chain->img_chunk_num = g_img_chunk_list.cur_chunk; + grub_memcpy((char *)chain + chain->img_chunk_offset, g_img_chunk_list.chunk, img_chunk_size); + + if (ventoy_compatible) + { + return 0; + } + + /* part 4: override chunk */ + if (override_count > 0) + { + chain->override_chunk_offset = chain->img_chunk_offset + img_chunk_size; + chain->override_chunk_num = override_count; + ventoy_linux_fill_override_data(isosize, (char *)chain + chain->override_chunk_offset); + } + + /* part 5: virt chunk */ + if (virt_chunk_count > 0) + { + chain->virt_chunk_offset = chain->override_chunk_offset + override_size; + chain->virt_chunk_num = virt_chunk_count; + ventoy_linux_fill_virt_data(isosize, chain); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static char *ventoy_systemd_conf_tag(char *buf, const char *tag, int optional) +{ + int taglen = 0; + char *start = NULL; + char *nextline = NULL; + + taglen = grub_strlen(tag); + for (start = buf; start; start = nextline) + { + nextline = ventoy_get_line(start); + VTOY_SKIP_SPACE(start); + + if (grub_strncmp(start, tag, taglen) == 0 && (start[taglen] == ' ' || start[taglen] == '\t')) + { + start += taglen; + VTOY_SKIP_SPACE(start); + return start; + } + } + + if (optional == 0) + { + debug("tag<%s> NOT found\n", tag); + } + return NULL; +} + +static int ventoy_systemd_conf_hook(const char *filename, const struct grub_dirhook_info *info, void *data) +{ + int oldpos = 0; + char *tag = NULL; + char *bkbuf = NULL; + char *filebuf = NULL; + grub_file_t file = NULL; + systemd_menu_ctx *ctx = (systemd_menu_ctx *)data; + + debug("ventoy_systemd_conf_hook %s\n", filename); + + if (info->dir || NULL == grub_strstr(filename, ".conf")) + { + return 0; + } + + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s/loader/entries/%s", ctx->dev, filename); + if (!file) + { + return 0; + } + + filebuf = grub_zalloc(2 * file->size + 8); + if (!filebuf) + { + goto out; + } + + bkbuf = filebuf + file->size + 4; + grub_file_read(file, bkbuf, file->size); + + oldpos = ctx->pos; + + /* title --> menuentry */ + grub_memcpy(filebuf, bkbuf, file->size); + tag = ventoy_systemd_conf_tag(filebuf, "title", 0); + vtoy_check_goto_out(tag); + vtoy_len_ssprintf(ctx->buf, ctx->pos, ctx->len, "menuentry \"%s\" {\n", tag); + + /* linux xxx */ + grub_memcpy(filebuf, bkbuf, file->size); + tag = ventoy_systemd_conf_tag(filebuf, "linux", 0); + if (!tag) + { + ctx->pos = oldpos; + goto out; + } + vtoy_len_ssprintf(ctx->buf, ctx->pos, ctx->len, " echo \"Loading kernel ...\"\n linux %s ", tag); + + /* kernel options */ + grub_memcpy(filebuf, bkbuf, file->size); + tag = ventoy_systemd_conf_tag(filebuf, "options", 0); + vtoy_len_ssprintf(ctx->buf, ctx->pos, ctx->len, "%s \n", tag ? tag : ""); + + + /* initrd xxx xxx xxx */ + vtoy_len_ssprintf(ctx->buf, ctx->pos, ctx->len, " echo \"Loading initrd ...\"\n %s ", ctx->initrd_cmd); + grub_memcpy(filebuf, bkbuf, file->size); + tag = ventoy_systemd_conf_tag(filebuf, "initrd", 1); + while (tag) + { + vtoy_len_ssprintf(ctx->buf, ctx->pos, ctx->len, "%s ", tag); + tag = ventoy_systemd_conf_tag(tag + grub_strlen(tag) + 1, "initrd", 1); + } + + vtoy_len_ssprintf(ctx->buf, ctx->pos, ctx->len, "\n boot\n}\n"); + +out: + grub_check_free(filebuf); + grub_file_close(file); + return 0; +} + +grub_err_t ventoy_cmd_linux_initrd(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + int pos = 0; + char *buf = NULL; + + (void)ctxt; + + buf = (char *)grub_malloc(VTOY_SIZE_4KB); + if (!buf) + { + return 1; + } + + pos += grub_snprintf(buf + pos, VTOY_SIZE_4KB - pos, "initrd mem:%s:size:%s", + grub_env_get("ventoy_cpio_addr"), grub_env_get("ventoy_cpio_size")); + + for (i = 0; i < argc; i++) + { + pos += grub_snprintf(buf + pos, VTOY_SIZE_4KB - pos, " newc:initrd%03d:%s", i + 1, args[i]); + } + + grub_script_execute_sourcecode(buf); + grub_free(buf); + + return 0; +} + +grub_err_t ventoy_cmd_linux_systemd_menu(grub_extcmd_context_t ctxt, int argc, char **args) +{ + static char *buf = NULL; + grub_fs_t fs; + char *device_name = NULL; + grub_device_t dev = NULL; + systemd_menu_ctx ctx; + + (void)ctxt; + (void)argc; + + if (!buf) + { + buf = grub_malloc(VTOY_LINUX_SYSTEMD_MENU_MAX_BUF); + if (!buf) + { + goto end; + } + } + + device_name = grub_file_get_device_name(args[0]); + if (!device_name) + { + debug("failed to get device name %s\n", args[0]); + goto end; + } + + dev = grub_device_open(device_name); + if (!dev) + { + debug("failed to open device %s\n", device_name); + goto end; + } + + fs = grub_fs_probe(dev); + if (!fs) + { + debug("failed to probe fs %d\n", grub_errno); + goto end; + } + + ctx.dev = args[0]; + ctx.buf = buf; + ctx.initrd_cmd = args[2] ? args[2] : "initrd"; + ctx.pos = 0; + ctx.len = VTOY_LINUX_SYSTEMD_MENU_MAX_BUF; + fs->fs_dir(dev, "/loader/entries", ventoy_systemd_conf_hook, &ctx); + + ventoy_memfile_env_set(args[1], buf, (ulonglong)(ctx.pos)); + +end: + grub_check_free(device_name); + check_free(dev, grub_device_close); + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static int ventoy_limine_path_convert(char *path) +{ + char newpath[256] = {0}; + + if (grub_strncmp(path, "boot://2/", 9) == 0) + { + grub_snprintf(newpath, sizeof(newpath), "(vtimghd,2)/%s", path + 9); + } + else if (grub_strncmp(path, "boot://1/", 9) == 0) + { + grub_snprintf(newpath, sizeof(newpath), "(vtimghd,1)/%s", path + 9); + } + + if (newpath[0]) + { + grub_snprintf(path, 1024, "%s", newpath); + } + + return 0; +} + +grub_err_t ventoy_cmd_linux_limine_menu(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int pos = 0; + int sub = 0; + int len = VTOY_LINUX_SYSTEMD_MENU_MAX_BUF; + char *filebuf = NULL; + char *start = NULL; + char *nextline = NULL; + grub_file_t file = NULL; + char *title = NULL; + char *kernel = NULL; + char *initrd = NULL; + char *param = NULL; + static char *buf = NULL; + + (void)ctxt; + (void)argc; + + if (!buf) + { + buf = grub_malloc(len + 4 * 1024); + if (!buf) + { + goto end; + } + } + + title = buf + len; + kernel = title + 1024; + initrd = kernel + 1024; + param = initrd + 1024; + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, args[0]); + if (!file) + { + return 0; + } + + filebuf = grub_zalloc(file->size + 8); + if (!filebuf) + { + goto end; + } + + grub_file_read(file, filebuf, file->size); + grub_file_close(file); + + + title[0] = kernel[0] = initrd[0] = param[0] = 0; + for (start = filebuf; start; start = nextline) + { + nextline = ventoy_get_line(start); + VTOY_SKIP_SPACE(start); + + if (start[0] == ':') + { + if (start[1] == ':') + { + grub_snprintf(title, 1024, "%s", start + 2); + } + else + { + if (sub) + { + vtoy_len_ssprintf(buf, pos, len, "}\n"); + sub = 0; + } + + if (nextline && nextline[0] == ':' && nextline[1] == ':') + { + vtoy_len_ssprintf(buf, pos, len, "submenu \"[+] %s\" {\n", start + 2); + sub = 1; + title[0] = 0; + } + else + { + grub_snprintf(title, 1024, "%s", start + 1); + } + } + } + else if (grub_strncmp(start, "KERNEL_PATH=", 12) == 0) + { + grub_snprintf(kernel, 1024, "%s", start + 12); + } + else if (grub_strncmp(start, "MODULE_PATH=", 12) == 0) + { + grub_snprintf(initrd, 1024, "%s", start + 12); + } + else if (grub_strncmp(start, "KERNEL_CMDLINE=", 15) == 0) + { + grub_snprintf(param, 1024, "%s", start + 15); + } + + if (title[0] && kernel[0] && initrd[0] && param[0]) + { + ventoy_limine_path_convert(kernel); + ventoy_limine_path_convert(initrd); + + vtoy_len_ssprintf(buf, pos, len, "menuentry \"%s\" {\n", title); + vtoy_len_ssprintf(buf, pos, len, " echo \"Downloading kernel ...\"\n linux %s %s\n", kernel, param); + vtoy_len_ssprintf(buf, pos, len, " echo \"Downloading initrd ...\"\n initrd %s\n", initrd); + vtoy_len_ssprintf(buf, pos, len, "}\n"); + + title[0] = kernel[0] = initrd[0] = param[0] = 0; + } + } + + if (sub) + { + vtoy_len_ssprintf(buf, pos, len, "}\n"); + sub = 0; + } + + ventoy_memfile_env_set(args[1], buf, (ulonglong)pos); + +end: + grub_check_free(filebuf); + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_plugin.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_plugin.c new file mode 100644 index 0000000..7479d98 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_plugin.c @@ -0,0 +1,3657 @@ +/****************************************************************************** + * ventoy_plugin.c + * + * Copyright (c) 2020, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ventoy_def.h" + +GRUB_MOD_LICENSE ("GPLv3+"); + +char g_arch_mode_suffix[64]; +static char g_iso_disk_name[128]; +static vtoy_password g_boot_pwd; +static vtoy_password g_file_type_pwd[img_type_max]; +static install_template *g_install_template_head = NULL; +static dud *g_dud_head = NULL; +static menu_password *g_pwd_head = NULL; +static persistence_config *g_persistence_head = NULL; +static menu_tip *g_menu_tip_head = NULL; +static menu_alias *g_menu_alias_head = NULL; +static menu_class *g_menu_class_head = NULL; +static custom_boot *g_custom_boot_head = NULL; +static injection_config *g_injection_head = NULL; +static auto_memdisk *g_auto_memdisk_head = NULL; +static image_list *g_image_list_head = NULL; +static conf_replace *g_conf_replace_head = NULL; +static VTOY_JSON *g_menu_lang_json = NULL; + +static int g_theme_id = 0; +static int g_theme_res_fit = 0; +static int g_theme_num = 0; +static theme_list *g_theme_head = NULL; +static int g_theme_random = vtoy_theme_random_boot_second; +static char g_theme_single_file[256]; +static char g_cur_menu_language[32] = {0}; +static char g_push_menu_language[32] = {0}; + +static int ventoy_plugin_is_parent(const char *pat, int patlen, const char *isopath) +{ + if (patlen > 1) + { + if (isopath[patlen] == '/' && ventoy_strncmp(pat, isopath, patlen) == 0 && + grub_strchr(isopath + patlen + 1, '/') == NULL) + { + return 1; + } + } + else + { + if (pat[0] == '/' && grub_strchr(isopath + 1, '/') == NULL) + { + return 1; + } + } + + return 0; +} + +static int ventoy_plugin_control_check(VTOY_JSON *json, const char *isodisk) +{ + int rc = 0; + VTOY_JSON *pNode = NULL; + VTOY_JSON *pChild = NULL; + + (void)isodisk; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + grub_printf("Not array type %d\n", json->enDataType); + return 1; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + if (pNode->enDataType == JSON_TYPE_OBJECT) + { + pChild = pNode->pstChild; + if (pChild->enDataType == JSON_TYPE_STRING) + { + if (grub_strcmp(pChild->pcName, "VTOY_DEFAULT_IMAGE") == 0) + { + grub_printf("%s: %s [%s]\n", pChild->pcName, pChild->unData.pcStrVal, + ventoy_check_file_exist("%s%s", isodisk, pChild->unData.pcStrVal) ? "OK" : "NOT EXIST"); + } + else + { + grub_printf("%s: %s\n", pChild->pcName, pChild->unData.pcStrVal); + } + } + else + { + grub_printf("%s is NOT string type\n", pChild->pcName); + rc = 1; + } + } + else + { + grub_printf("%s is not an object\n", pNode->pcName); + rc = 1; + } + } + + return rc; +} + +static int ventoy_plugin_control_entry(VTOY_JSON *json, const char *isodisk) +{ + VTOY_JSON *pNode = NULL; + VTOY_JSON *pChild = NULL; + + (void)isodisk; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + debug("Not array %d\n", json->enDataType); + return 0; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + if (pNode->enDataType == JSON_TYPE_OBJECT) + { + pChild = pNode->pstChild; + if (pChild->enDataType == JSON_TYPE_STRING && pChild->pcName && pChild->unData.pcStrVal) + { + ventoy_set_env(pChild->pcName, pChild->unData.pcStrVal); + } + } + } + + return 0; +} + +static int ventoy_plugin_theme_check(VTOY_JSON *json, const char *isodisk) +{ + int exist = 0; + const char *value; + VTOY_JSON *node; + + value = vtoy_json_get_string_ex(json->pstChild, "file"); + if (value) + { + grub_printf("file: %s\n", value); + if (value[0] == '/') + { + exist = ventoy_check_file_exist("%s%s", isodisk, value); + } + else + { + exist = ventoy_check_file_exist("%s/ventoy/%s", isodisk, value); + } + + if (exist == 0) + { + grub_printf("Theme file %s does NOT exist\n", value); + return 1; + } + } + else + { + node = vtoy_json_find_item(json->pstChild, JSON_TYPE_ARRAY, "file"); + if (node) + { + for (node = node->pstChild; node; node = node->pstNext) + { + value = node->unData.pcStrVal; + grub_printf("file: %s\n", value); + if (value[0] == '/') + { + exist = ventoy_check_file_exist("%s%s", isodisk, value); + } + else + { + exist = ventoy_check_file_exist("%s/ventoy/%s", isodisk, value); + } + + if (exist == 0) + { + grub_printf("Theme file %s does NOT exist\n", value); + return 1; + } + } + + value = vtoy_json_get_string_ex(json->pstChild, "random"); + if (value) + { + grub_printf("random: %s\n", value); + } + } + } + + value = vtoy_json_get_string_ex(json->pstChild, "gfxmode"); + if (value) + { + grub_printf("gfxmode: %s\n", value); + } + + value = vtoy_json_get_string_ex(json->pstChild, "display_mode"); + if (value) + { + grub_printf("display_mode: %s\n", value); + } + + value = vtoy_json_get_string_ex(json->pstChild, "serial_param"); + if (value) + { + grub_printf("serial_param %s\n", value); + } + + value = vtoy_json_get_string_ex(json->pstChild, "ventoy_left"); + if (value) + { + grub_printf("ventoy_left: %s\n", value); + } + + value = vtoy_json_get_string_ex(json->pstChild, "ventoy_top"); + if (value) + { + grub_printf("ventoy_top: %s\n", value); + } + + value = vtoy_json_get_string_ex(json->pstChild, "ventoy_color"); + if (value) + { + grub_printf("ventoy_color: %s\n", value); + } + + node = vtoy_json_find_item(json->pstChild, JSON_TYPE_ARRAY, "fonts"); + if (node) + { + for (node = node->pstChild; node; node = node->pstNext) + { + if (node->enDataType == JSON_TYPE_STRING) + { + if (ventoy_check_file_exist("%s%s", isodisk, node->unData.pcStrVal)) + { + grub_printf("%s [OK]\n", node->unData.pcStrVal); + } + else + { + grub_printf("%s [NOT EXIST]\n", node->unData.pcStrVal); + } + } + } + } + else + { + grub_printf("fonts NOT found\n"); + } + + return 0; +} + +static int ventoy_plugin_theme_entry(VTOY_JSON *json, const char *isodisk) +{ + const char *value; + char val[64]; + char filepath[256]; + VTOY_JSON *node = NULL; + theme_list *tail = NULL; + theme_list *themenode = NULL; + + value = vtoy_json_get_string_ex(json->pstChild, "file"); + if (value) + { + if (value[0] == '/') + { + grub_snprintf(filepath, sizeof(filepath), "%s%s", isodisk, value); + } + else + { + grub_snprintf(filepath, sizeof(filepath), "%s/ventoy/%s", isodisk, value); + } + + if (ventoy_check_file_exist(filepath) == 0) + { + debug("Theme file %s does not exist\n", filepath); + return 0; + } + + debug("vtoy_theme %s\n", filepath); + ventoy_env_export("vtoy_theme", filepath); + grub_snprintf(g_theme_single_file, sizeof(g_theme_single_file), "%s", filepath); + } + else + { + node = vtoy_json_find_item(json->pstChild, JSON_TYPE_ARRAY, "file"); + if (node) + { + for (node = node->pstChild; node; node = node->pstNext) + { + value = node->unData.pcStrVal; + if (value[0] == '/') + { + grub_snprintf(filepath, sizeof(filepath), "%s%s", isodisk, value); + } + else + { + grub_snprintf(filepath, sizeof(filepath), "%s/ventoy/%s", isodisk, value); + } + + if (ventoy_check_file_exist(filepath) == 0) + { + continue; + } + + themenode = grub_zalloc(sizeof(theme_list)); + if (themenode) + { + grub_snprintf(themenode->theme.path, sizeof(themenode->theme.path), "%s", filepath); + if (g_theme_head) + { + tail->next = themenode; + } + else + { + g_theme_head = themenode; + } + tail = themenode; + g_theme_num++; + } + } + + ventoy_env_export("vtoy_theme", "random"); + value = vtoy_json_get_string_ex(json->pstChild, "random"); + if (value) + { + if (grub_strcmp(value, "boot_second") == 0) + { + g_theme_random = vtoy_theme_random_boot_second; + } + else if (grub_strcmp(value, "boot_day") == 0) + { + g_theme_random = vtoy_theme_random_boot_day; + } + else if (grub_strcmp(value, "boot_month") == 0) + { + g_theme_random = vtoy_theme_random_boot_month; + } + } + } + } + + grub_snprintf(val, sizeof(val), "%d", g_theme_num); + grub_env_set("VTOY_THEME_COUNT", val); + grub_env_export("VTOY_THEME_COUNT"); + if (g_theme_num > 0) + { + vtoy_json_get_int(json->pstChild, "default_file", &g_theme_id); + if (g_theme_id == 0) + { + vtoy_json_get_int(json->pstChild, "resolution_fit", &g_theme_res_fit); + if (g_theme_res_fit != 1) + { + g_theme_res_fit = 0; + } + + grub_snprintf(val, sizeof(val), "%d", g_theme_res_fit); + ventoy_env_export("vtoy_res_fit", val); + } + + if (g_theme_id > g_theme_num || g_theme_id < 0) + { + g_theme_id = 0; + } + } + + value = vtoy_json_get_string_ex(json->pstChild, "gfxmode"); + if (value) + { + debug("vtoy_gfxmode %s\n", value); + ventoy_env_export("vtoy_gfxmode", value); + } + + value = vtoy_json_get_string_ex(json->pstChild, "display_mode"); + if (value) + { + debug("display_mode %s\n", value); + ventoy_env_export("vtoy_display_mode", value); + } + + value = vtoy_json_get_string_ex(json->pstChild, "serial_param"); + if (value) + { + debug("serial_param %s\n", value); + ventoy_env_export("vtoy_serial_param", value); + } + + value = vtoy_json_get_string_ex(json->pstChild, "ventoy_left"); + if (value) + { + ventoy_env_export(ventoy_left_key, value); + } + + value = vtoy_json_get_string_ex(json->pstChild, "ventoy_top"); + if (value) + { + ventoy_env_export(ventoy_top_key, value); + } + + value = vtoy_json_get_string_ex(json->pstChild, "ventoy_color"); + if (value) + { + ventoy_env_export(ventoy_color_key, value); + } + + node = vtoy_json_find_item(json->pstChild, JSON_TYPE_ARRAY, "fonts"); + if (node) + { + for (node = node->pstChild; node; node = node->pstNext) + { + if (node->enDataType == JSON_TYPE_STRING && + ventoy_check_file_exist("%s%s", isodisk, node->unData.pcStrVal)) + { + grub_snprintf(filepath, sizeof(filepath), "%s%s", isodisk, node->unData.pcStrVal); + grub_font_load(filepath); + } + } + } + + return 0; +} + +static int ventoy_plugin_check_path(const char *path, const char *file) +{ + if (file[0] != '/') + { + grub_printf("%s is NOT begin with '/' \n", file); + return 1; + } + + if (grub_strchr(file, '\\')) + { + grub_printf("%s contains invalid '\\' \n", file); + return 1; + } + + if (grub_strstr(file, "//")) + { + grub_printf("%s contains invalid double slash\n", file); + return 1; + } + + if (grub_strstr(file, "../")) + { + grub_printf("%s contains invalid '../' \n", file); + return 1; + } + + if (!ventoy_check_file_exist("%s%s", path, file)) + { + grub_printf("%s%s does NOT exist\n", path, file); + return 1; + } + + return 0; +} + +static int ventoy_plugin_check_fullpath +( + VTOY_JSON *json, + const char *isodisk, + const char *key, + int *pathnum +) +{ + int rc = 0; + int ret = 0; + int cnt = 0; + VTOY_JSON *node = json; + VTOY_JSON *child = NULL; + + while (node) + { + if (0 == grub_strcmp(key, node->pcName)) + { + break; + } + node = node->pstNext; + } + + if (!node) + { + return 1; + } + + if (JSON_TYPE_STRING == node->enDataType) + { + cnt = 1; + ret = ventoy_plugin_check_path(isodisk, node->unData.pcStrVal); + grub_printf("%s: %s [%s]\n", key, node->unData.pcStrVal, ret ? "FAIL" : "OK"); + } + else if (JSON_TYPE_ARRAY == node->enDataType) + { + for (child = node->pstChild; child; child = child->pstNext) + { + if (JSON_TYPE_STRING != child->enDataType) + { + grub_printf("Non string json type\n"); + } + else + { + rc = ventoy_plugin_check_path(isodisk, child->unData.pcStrVal); + grub_printf("%s: %s [%s]\n", key, child->unData.pcStrVal, rc ? "FAIL" : "OK"); + ret += rc; + cnt++; + } + } + } + + *pathnum = cnt; + return ret; +} + +static int ventoy_plugin_parse_fullpath +( + VTOY_JSON *json, + const char *isodisk, + const char *key, + file_fullpath **fullpath, + int *pathnum +) +{ + int rc = 1; + int count = 0; + VTOY_JSON *node = json; + VTOY_JSON *child = NULL; + file_fullpath *path = NULL; + + while (node) + { + if (0 == grub_strcmp(key, node->pcName)) + { + break; + } + node = node->pstNext; + } + + if (!node) + { + return 1; + } + + if (JSON_TYPE_STRING == node->enDataType) + { + debug("%s is string type data\n", node->pcName); + + if ((node->unData.pcStrVal[0] != '/') || (!ventoy_check_file_exist("%s%s", isodisk, node->unData.pcStrVal))) + { + debug("%s%s file not found\n", isodisk, node->unData.pcStrVal); + return 1; + } + + path = (file_fullpath *)grub_zalloc(sizeof(file_fullpath)); + if (path) + { + grub_snprintf(path->path, sizeof(path->path), "%s", node->unData.pcStrVal); + *fullpath = path; + *pathnum = 1; + rc = 0; + } + } + else if (JSON_TYPE_ARRAY == node->enDataType) + { + for (child = node->pstChild; child; child = child->pstNext) + { + if ((JSON_TYPE_STRING != child->enDataType) || (child->unData.pcStrVal[0] != '/')) + { + debug("Invalid data type:%d\n", child->enDataType); + return 1; + } + count++; + } + debug("%s is array type data, count=%d\n", node->pcName, count); + + path = (file_fullpath *)grub_zalloc(sizeof(file_fullpath) * count); + if (path) + { + *fullpath = path; + + for (count = 0, child = node->pstChild; child; child = child->pstNext) + { + if (ventoy_check_file_exist("%s%s", isodisk, child->unData.pcStrVal)) + { + grub_snprintf(path->path, sizeof(path->path), "%s", child->unData.pcStrVal); + path++; + count++; + } + } + + *pathnum = count; + rc = 0; + } + } + + return rc; +} + +static int ventoy_plugin_auto_install_check(VTOY_JSON *json, const char *isodisk) +{ + int pathnum = 0; + int autosel = 0; + int timeout = 0; + char *pos = NULL; + const char *iso = NULL; + VTOY_JSON *pNode = NULL; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + grub_printf("Not array type %d\n", json->enDataType); + return 1; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + if (pNode->enDataType != JSON_TYPE_OBJECT) + { + grub_printf("NOT object type\n"); + } + + if ((iso = vtoy_json_get_string_ex(pNode->pstChild, "image")) != NULL) + { + pos = grub_strchr(iso, '*'); + if (pos || 0 == ventoy_plugin_check_path(isodisk, iso)) + { + grub_printf("image: %s [%s]\n", iso, (pos ? "*" : "OK")); + ventoy_plugin_check_fullpath(pNode->pstChild, isodisk, "template", &pathnum); + + if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "autosel", &autosel)) + { + if (autosel >= 0 && autosel <= pathnum) + { + grub_printf("autosel: %d [OK]\n", autosel); + } + else + { + grub_printf("autosel: %d [FAIL]\n", autosel); + } + } + + if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "timeout", &timeout)) + { + if (timeout >= 0) + { + grub_printf("timeout: %d [OK]\n", timeout); + } + else + { + grub_printf("timeout: %d [FAIL]\n", timeout); + } + } + } + else + { + grub_printf("image: %s [FAIL]\n", iso); + } + } + else if ((iso = vtoy_json_get_string_ex(pNode->pstChild, "parent")) != NULL) + { + if (ventoy_is_dir_exist("%s%s", isodisk, iso)) + { + grub_printf("parent: %s [OK]\n", iso); + ventoy_plugin_check_fullpath(pNode->pstChild, isodisk, "template", &pathnum); + + if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "autosel", &autosel)) + { + if (autosel >= 0 && autosel <= pathnum) + { + grub_printf("autosel: %d [OK]\n", autosel); + } + else + { + grub_printf("autosel: %d [FAIL]\n", autosel); + } + } + + if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "timeout", &timeout)) + { + if (timeout >= 0) + { + grub_printf("timeout: %d [OK]\n", timeout); + } + else + { + grub_printf("timeout: %d [FAIL]\n", timeout); + } + } + } + else + { + grub_printf("parent: %s [FAIL]\n", iso); + } + } + else + { + grub_printf("image not found\n"); + } + } + + return 0; +} + +static int ventoy_plugin_auto_install_entry(VTOY_JSON *json, const char *isodisk) +{ + int type = 0; + int pathnum = 0; + int autosel = 0; + int timeout = 0; + const char *iso = NULL; + VTOY_JSON *pNode = NULL; + install_template *node = NULL; + install_template *next = NULL; + file_fullpath *templatepath = NULL; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + debug("Not array %d\n", json->enDataType); + return 0; + } + + if (g_install_template_head) + { + for (node = g_install_template_head; node; node = next) + { + next = node->next; + grub_check_free(node->templatepath); + grub_free(node); + } + + g_install_template_head = NULL; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + type = auto_install_type_file; + iso = vtoy_json_get_string_ex(pNode->pstChild, "image"); + if (!iso) + { + type = auto_install_type_parent; + iso = vtoy_json_get_string_ex(pNode->pstChild, "parent"); + } + + if (iso && iso[0] == '/') + { + if (0 == ventoy_plugin_parse_fullpath(pNode->pstChild, isodisk, "template", &templatepath, &pathnum)) + { + node = grub_zalloc(sizeof(install_template)); + if (node) + { + node->type = type; + node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso); + node->templatepath = templatepath; + node->templatenum = pathnum; + + node->autosel = -1; + node->timeout = -1; + if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "autosel", &autosel)) + { + if (autosel >= 0 && autosel <= pathnum) + { + node->autosel = autosel; + } + } + + if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "timeout", &timeout)) + { + if (timeout >= 0) + { + node->timeout = timeout; + } + } + + if (g_install_template_head) + { + node->next = g_install_template_head; + } + + g_install_template_head = node; + } + } + } + } + + return 0; +} + +static int ventoy_plugin_dud_check(VTOY_JSON *json, const char *isodisk) +{ + int pathnum = 0; + char *pos = NULL; + const char *iso = NULL; + VTOY_JSON *pNode = NULL; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + grub_printf("Not array type %d\n", json->enDataType); + return 1; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + if (pNode->enDataType != JSON_TYPE_OBJECT) + { + grub_printf("NOT object type\n"); + } + + iso = vtoy_json_get_string_ex(pNode->pstChild, "image"); + if (iso) + { + pos = grub_strchr(iso, '*'); + if (pos || 0 == ventoy_plugin_check_path(isodisk, iso)) + { + grub_printf("image: %s [%s]\n", iso, (pos ? "*" : "OK")); + ventoy_plugin_check_fullpath(pNode->pstChild, isodisk, "dud", &pathnum); + } + else + { + grub_printf("image: %s [FAIL]\n", iso); + } + } + else + { + grub_printf("image not found\n"); + } + } + + return 0; +} + +static int ventoy_plugin_dud_entry(VTOY_JSON *json, const char *isodisk) +{ + int pathnum = 0; + const char *iso = NULL; + VTOY_JSON *pNode = NULL; + dud *node = NULL; + dud *next = NULL; + file_fullpath *dudpath = NULL; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + debug("Not array %d\n", json->enDataType); + return 0; + } + + if (g_dud_head) + { + for (node = g_dud_head; node; node = next) + { + next = node->next; + grub_check_free(node->dudpath); + grub_free(node); + } + + g_dud_head = NULL; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + iso = vtoy_json_get_string_ex(pNode->pstChild, "image"); + if (iso && iso[0] == '/') + { + if (0 == ventoy_plugin_parse_fullpath(pNode->pstChild, isodisk, "dud", &dudpath, &pathnum)) + { + node = grub_zalloc(sizeof(dud)); + if (node) + { + node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso); + node->dudpath = dudpath; + node->dudnum = pathnum; + node->files = grub_zalloc(sizeof(dudfile) * pathnum); + + if (node->files) + { + if (g_dud_head) + { + node->next = g_dud_head; + } + + g_dud_head = node; + } + else + { + grub_free(node); + } + } + } + } + } + + return 0; +} + +static int ventoy_plugin_parse_pwdstr(char *pwdstr, vtoy_password *pwd) +{ + int i; + int len; + char ch; + char *pos; + char bytes[3]; + vtoy_password tmpPwd; + + len = (int)grub_strlen(pwdstr); + if (len > 64) + { + if (NULL == pwd) grub_printf("Password too long %d\n", len); + return 1; + } + + grub_memset(&tmpPwd, 0, sizeof(tmpPwd)); + + if (grub_strncmp(pwdstr, "txt#", 4) == 0) + { + tmpPwd.type = VTOY_PASSWORD_TXT; + grub_snprintf(tmpPwd.text, sizeof(tmpPwd.text), "%s", pwdstr + 4); + } + else if (grub_strncmp(pwdstr, "md5#", 4) == 0) + { + if ((len - 4) == 32) + { + for (i = 0; i < 16; i++) + { + bytes[0] = pwdstr[4 + i * 2]; + bytes[1] = pwdstr[4 + i * 2 + 1]; + bytes[2] = 0; + + if (grub_isxdigit(bytes[0]) && grub_isxdigit(bytes[1])) + { + tmpPwd.md5[i] = (grub_uint8_t)grub_strtoul(bytes, NULL, 16); + } + else + { + if (NULL == pwd) grub_printf("Invalid md5 hex format %s %d\n", pwdstr, i); + return 1; + } + } + tmpPwd.type = VTOY_PASSWORD_MD5; + } + else if ((len - 4) > 32) + { + pos = grub_strchr(pwdstr + 4, '#'); + if (!pos) + { + if (NULL == pwd) grub_printf("Invalid md5 password format %s\n", pwdstr); + return 1; + } + + if (len - 1 - ((long)pos - (long)pwdstr) != 32) + { + if (NULL == pwd) grub_printf("Invalid md5 salt password format %s\n", pwdstr); + return 1; + } + + ch = *pos; + *pos = 0; + grub_snprintf(tmpPwd.salt, sizeof(tmpPwd.salt), "%s", pwdstr + 4); + *pos = ch; + + pos++; + for (i = 0; i < 16; i++) + { + bytes[0] = pos[i * 2]; + bytes[1] = pos[i * 2 + 1]; + bytes[2] = 0; + + if (grub_isxdigit(bytes[0]) && grub_isxdigit(bytes[1])) + { + tmpPwd.md5[i] = (grub_uint8_t)grub_strtoul(bytes, NULL, 16); + } + else + { + if (NULL == pwd) grub_printf("Invalid md5 hex format %s %d\n", pwdstr, i); + return 1; + } + } + + tmpPwd.type = VTOY_PASSWORD_SALT_MD5; + } + else + { + if (NULL == pwd) grub_printf("Invalid md5 password format %s\n", pwdstr); + return 1; + } + } + else + { + if (NULL == pwd) grub_printf("Invalid password format %s\n", pwdstr); + return 1; + } + + if (pwd) + { + grub_memcpy(pwd, &tmpPwd, sizeof(tmpPwd)); + } + + return 0; +} + +static int ventoy_plugin_get_pwd_type(const char *pwd) +{ + int i; + char pwdtype[64]; + + for (i = 0; pwd && i < (int)ARRAY_SIZE(g_menu_prefix); i++) + { + grub_snprintf(pwdtype, sizeof(pwdtype), "%spwd", g_menu_prefix[i]); + if (grub_strcmp(pwdtype, pwd) == 0) + { + return img_type_start + i; + } + } + + return -1; +} + +static int ventoy_plugin_pwd_entry(VTOY_JSON *json, const char *isodisk) +{ + int type = -1; + const char *iso = NULL; + const char *pwd = NULL; + VTOY_JSON *pNode = NULL; + VTOY_JSON *pCNode = NULL; + menu_password *node = NULL; + menu_password *tail = NULL; + menu_password *next = NULL; + + (void)isodisk; + + if (json->enDataType != JSON_TYPE_OBJECT) + { + debug("Not object %d\n", json->enDataType); + return 0; + } + + if (g_pwd_head) + { + for (node = g_pwd_head; node; node = next) + { + next = node->next; + grub_free(node); + } + + g_pwd_head = NULL; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + if (pNode->pcName && grub_strcmp("bootpwd", pNode->pcName) == 0) + { + ventoy_plugin_parse_pwdstr(pNode->unData.pcStrVal, &g_boot_pwd); + } + else if ((type = ventoy_plugin_get_pwd_type(pNode->pcName)) >= 0) + { + ventoy_plugin_parse_pwdstr(pNode->unData.pcStrVal, g_file_type_pwd + type); + } + else if (pNode->pcName && grub_strcmp("menupwd", pNode->pcName) == 0) + { + for (pCNode = pNode->pstChild; pCNode; pCNode = pCNode->pstNext) + { + if (pCNode->enDataType != JSON_TYPE_OBJECT) + { + continue; + } + + type = vtoy_menu_pwd_file; + iso = vtoy_json_get_string_ex(pCNode->pstChild, "file"); + if (!iso) + { + type = vtoy_menu_pwd_parent; + iso = vtoy_json_get_string_ex(pCNode->pstChild, "parent"); + } + + pwd = vtoy_json_get_string_ex(pCNode->pstChild, "pwd"); + if (iso && pwd && iso[0] == '/') + { + node = grub_zalloc(sizeof(menu_password)); + if (node) + { + node->type = type; + node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso); + + if (ventoy_plugin_parse_pwdstr((char *)pwd, &(node->password))) + { + grub_free(node); + continue; + } + + if (g_pwd_head) + { + tail->next = node; + } + else + { + g_pwd_head = node; + } + tail = node; + } + } + } + } + } + + return 0; +} + +static int ventoy_plugin_pwd_check(VTOY_JSON *json, const char *isodisk) +{ + int type = -1; + char *pos = NULL; + const char *iso = NULL; + const char *pwd = NULL; + VTOY_JSON *pNode = NULL; + VTOY_JSON *pCNode = NULL; + + if (json->enDataType != JSON_TYPE_OBJECT) + { + grub_printf("Not object %d\n", json->enDataType); + return 0; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + if (pNode->pcName && grub_strcmp("bootpwd", pNode->pcName) == 0) + { + if (0 == ventoy_plugin_parse_pwdstr(pNode->unData.pcStrVal, NULL)) + { + grub_printf("bootpwd:<%s>\n", pNode->unData.pcStrVal); + } + else + { + grub_printf("Invalid bootpwd.\n"); + } + } + else if ((type = ventoy_plugin_get_pwd_type(pNode->pcName)) >= 0) + { + if (0 == ventoy_plugin_parse_pwdstr(pNode->unData.pcStrVal, NULL)) + { + grub_printf("%s:<%s>\n", pNode->pcName, pNode->unData.pcStrVal); + } + else + { + grub_printf("Invalid pwd <%s>\n", pNode->unData.pcStrVal); + } + } + else if (pNode->pcName && grub_strcmp("menupwd", pNode->pcName) == 0) + { + grub_printf("\n"); + for (pCNode = pNode->pstChild; pCNode; pCNode = pCNode->pstNext) + { + if (pCNode->enDataType != JSON_TYPE_OBJECT) + { + grub_printf("Not object %d\n", pCNode->enDataType); + continue; + } + + if ((iso = vtoy_json_get_string_ex(pCNode->pstChild, "file")) != NULL) + { + pos = grub_strchr(iso, '*'); + if (pos || 0 == ventoy_plugin_check_path(isodisk, iso)) + { + pwd = vtoy_json_get_string_ex(pCNode->pstChild, "pwd"); + + if (0 == ventoy_plugin_parse_pwdstr((char *)pwd, NULL)) + { + grub_printf("file:<%s> [%s]\n", iso, (pos ? "*" : "OK")); + grub_printf("pwd:<%s>\n\n", pwd); + } + else + { + grub_printf("Invalid password for <%s>\n", iso); + } + } + else + { + grub_printf("<%s%s> not found\n", isodisk, iso); + } + } + else if ((iso = vtoy_json_get_string_ex(pCNode->pstChild, "parent")) != NULL) + { + if (ventoy_is_dir_exist("%s%s", isodisk, iso)) + { + pwd = vtoy_json_get_string_ex(pCNode->pstChild, "pwd"); + if (0 == ventoy_plugin_parse_pwdstr((char *)pwd, NULL)) + { + grub_printf("dir:<%s> [%s]\n", iso, (pos ? "*" : "OK")); + grub_printf("pwd:<%s>\n\n", pwd); + } + else + { + grub_printf("Invalid password for <%s>\n", iso); + } + } + else + { + grub_printf("<%s%s> not found\n", isodisk, iso); + } + } + else + { + grub_printf("No file item found in json.\n"); + } + } + } + } + + return 0; +} + +static int ventoy_plugin_persistence_check(VTOY_JSON *json, const char *isodisk) +{ + int autosel = 0; + int timeout = 0; + int pathnum = 0; + char *pos = NULL; + const char *iso = NULL; + VTOY_JSON *pNode = NULL; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + grub_printf("Not array type %d\n", json->enDataType); + return 1; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + if (pNode->enDataType != JSON_TYPE_OBJECT) + { + grub_printf("NOT object type\n"); + } + + iso = vtoy_json_get_string_ex(pNode->pstChild, "image"); + if (iso) + { + pos = grub_strchr(iso, '*'); + if (pos || 0 == ventoy_plugin_check_path(isodisk, iso)) + { + grub_printf("image: %s [%s]\n", iso, (pos ? "*" : "OK")); + ventoy_plugin_check_fullpath(pNode->pstChild, isodisk, "backend", &pathnum); + + if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "autosel", &autosel)) + { + if (autosel >= 0 && autosel <= pathnum) + { + grub_printf("autosel: %d [OK]\n", autosel); + } + else + { + grub_printf("autosel: %d [FAIL]\n", autosel); + } + } + + if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "timeout", &timeout)) + { + if (timeout >= 0) + { + grub_printf("timeout: %d [OK]\n", timeout); + } + else + { + grub_printf("timeout: %d [FAIL]\n", timeout); + } + } + } + else + { + grub_printf("image: %s [FAIL]\n", iso); + } + } + else + { + grub_printf("image not found\n"); + } + } + + return 0; +} + +static int ventoy_plugin_persistence_entry(VTOY_JSON *json, const char *isodisk) +{ + int autosel = 0; + int timeout = 0; + int pathnum = 0; + const char *iso = NULL; + VTOY_JSON *pNode = NULL; + persistence_config *node = NULL; + persistence_config *next = NULL; + file_fullpath *backendpath = NULL; + + (void)isodisk; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + debug("Not array %d\n", json->enDataType); + return 0; + } + + if (g_persistence_head) + { + for (node = g_persistence_head; node; node = next) + { + next = node->next; + grub_check_free(node->backendpath); + grub_free(node); + } + + g_persistence_head = NULL; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + iso = vtoy_json_get_string_ex(pNode->pstChild, "image"); + if (iso && iso[0] == '/') + { + if (0 == ventoy_plugin_parse_fullpath(pNode->pstChild, isodisk, "backend", &backendpath, &pathnum)) + { + node = grub_zalloc(sizeof(persistence_config)); + if (node) + { + node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso); + node->backendpath = backendpath; + node->backendnum = pathnum; + + node->autosel = -1; + node->timeout = -1; + if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "autosel", &autosel)) + { + if (autosel >= 0 && autosel <= pathnum) + { + node->autosel = autosel; + } + } + + if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "timeout", &timeout)) + { + if (timeout >= 0) + { + node->timeout = timeout; + } + } + + if (g_persistence_head) + { + node->next = g_persistence_head; + } + + g_persistence_head = node; + } + } + } + } + + return 0; +} + +static int ventoy_plugin_menualias_check(VTOY_JSON *json, const char *isodisk) +{ + int type; + const char *path = NULL; + const char *alias = NULL; + VTOY_JSON *pNode = NULL; + + (void)isodisk; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + grub_printf("Not array %d\n", json->enDataType); + return 1; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + type = vtoy_alias_image_file; + path = vtoy_json_get_string_ex(pNode->pstChild, "image"); + if (!path) + { + path = vtoy_json_get_string_ex(pNode->pstChild, "dir"); + type = vtoy_alias_directory; + } + + alias = vtoy_json_get_string_ex(pNode->pstChild, "alias"); + if (path && path[0] == '/' && alias) + { + if (vtoy_alias_image_file == type) + { + if (grub_strchr(path, '*')) + { + grub_printf("image: <%s> [ * ]\n", path); + } + else if (ventoy_check_file_exist("%s%s", isodisk, path)) + { + grub_printf("image: <%s> [ OK ]\n", path); + } + else + { + grub_printf("image: <%s> [ NOT EXIST ]\n", path); + } + } + else + { + if (ventoy_is_dir_exist("%s%s", isodisk, path)) + { + grub_printf("dir: <%s> [ OK ]\n", path); + } + else + { + grub_printf("dir: <%s> [ NOT EXIST ]\n", path); + } + } + + grub_printf("alias: <%s>\n\n", alias); + } + } + + return 0; +} + +static int ventoy_plugin_menualias_entry(VTOY_JSON *json, const char *isodisk) +{ + int type; + const char *path = NULL; + const char *alias = NULL; + VTOY_JSON *pNode = NULL; + menu_alias *node = NULL; + menu_alias *next = NULL; + + (void)isodisk; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + debug("Not array %d\n", json->enDataType); + return 0; + } + + if (g_menu_alias_head) + { + for (node = g_menu_alias_head; node; node = next) + { + next = node->next; + grub_free(node); + } + + g_menu_alias_head = NULL; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + type = vtoy_alias_image_file; + path = vtoy_json_get_string_ex(pNode->pstChild, "image"); + if (!path) + { + path = vtoy_json_get_string_ex(pNode->pstChild, "dir"); + type = vtoy_alias_directory; + } + + alias = vtoy_json_get_string_ex(pNode->pstChild, "alias"); + if (path && path[0] == '/' && alias) + { + node = grub_zalloc(sizeof(menu_alias)); + if (node) + { + node->type = type; + node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", path); + grub_snprintf(node->alias, sizeof(node->alias), "%s", alias); + + if (g_menu_alias_head) + { + node->next = g_menu_alias_head; + } + + g_menu_alias_head = node; + } + } + } + + return 0; +} + +static int ventoy_plugin_menutip_check(VTOY_JSON *json, const char *isodisk) +{ + int type; + const char *path = NULL; + const char *tip = NULL; + VTOY_JSON *pNode = NULL; + + (void)isodisk; + + if (json->enDataType != JSON_TYPE_OBJECT) + { + grub_printf("Not object %d\n", json->enDataType); + return 1; + } + + tip = vtoy_json_get_string_ex(json->pstChild, "left"); + if (tip) + { + grub_printf("left: <%s>\n", tip); + } + + tip = vtoy_json_get_string_ex(json->pstChild, "top"); + if (tip) + { + grub_printf("top: <%s>\n", tip); + } + + tip = vtoy_json_get_string_ex(json->pstChild, "color"); + if (tip) + { + grub_printf("color: <%s>\n", tip); + } + + pNode = vtoy_json_find_item(json->pstChild, JSON_TYPE_ARRAY, "tips"); + for (pNode = pNode->pstChild; pNode; pNode = pNode->pstNext) + { + type = vtoy_tip_image_file; + path = vtoy_json_get_string_ex(pNode->pstChild, "image"); + if (!path) + { + path = vtoy_json_get_string_ex(pNode->pstChild, "dir"); + type = vtoy_tip_directory; + } + + if (path && path[0] == '/') + { + if (vtoy_tip_image_file == type) + { + if (grub_strchr(path, '*')) + { + grub_printf("image: <%s> [ * ]\n", path); + } + else if (ventoy_check_file_exist("%s%s", isodisk, path)) + { + grub_printf("image: <%s> [ OK ]\n", path); + } + else + { + grub_printf("image: <%s> [ NOT EXIST ]\n", path); + } + } + else + { + if (ventoy_is_dir_exist("%s%s", isodisk, path)) + { + grub_printf("dir: <%s> [ OK ]\n", path); + } + else + { + grub_printf("dir: <%s> [ NOT EXIST ]\n", path); + } + } + + tip = vtoy_json_get_string_ex(pNode->pstChild, "tip"); + if (tip) + { + grub_printf("tip: <%s>\n", tip); + } + else + { + tip = vtoy_json_get_string_ex(pNode->pstChild, "tip1"); + if (tip) + grub_printf("tip1: <%s>\n", tip); + else + grub_printf("tip1: \n"); + + tip = vtoy_json_get_string_ex(pNode->pstChild, "tip2"); + if (tip) + grub_printf("tip2: <%s>\n", tip); + else + grub_printf("tip2: \n"); + } + } + else + { + grub_printf("image: <%s> [ INVALID ]\n", path); + } + } + + return 0; +} + +static int ventoy_plugin_menutip_entry(VTOY_JSON *json, const char *isodisk) +{ + int type; + const char *path = NULL; + const char *tip = NULL; + VTOY_JSON *pNode = NULL; + menu_tip *node = NULL; + menu_tip *next = NULL; + + (void)isodisk; + + if (json->enDataType != JSON_TYPE_OBJECT) + { + debug("Not object %d\n", json->enDataType); + return 0; + } + + pNode = vtoy_json_find_item(json->pstChild, JSON_TYPE_ARRAY, "tips"); + if (pNode == NULL) + { + debug("Not tips found\n"); + return 0; + } + + if (g_menu_tip_head) + { + for (node = g_menu_tip_head; node; node = next) + { + next = node->next; + grub_free(node); + } + + g_menu_tip_head = NULL; + } + + tip = vtoy_json_get_string_ex(json->pstChild, "left"); + if (tip) + { + grub_env_set("VTOY_TIP_LEFT", tip); + } + + tip = vtoy_json_get_string_ex(json->pstChild, "top"); + if (tip) + { + grub_env_set("VTOY_TIP_TOP", tip); + } + + tip = vtoy_json_get_string_ex(json->pstChild, "color"); + if (tip) + { + grub_env_set("VTOY_TIP_COLOR", tip); + } + + for (pNode = pNode->pstChild; pNode; pNode = pNode->pstNext) + { + type = vtoy_tip_image_file; + path = vtoy_json_get_string_ex(pNode->pstChild, "image"); + if (!path) + { + path = vtoy_json_get_string_ex(pNode->pstChild, "dir"); + type = vtoy_tip_directory; + } + + if (path && path[0] == '/') + { + node = grub_zalloc(sizeof(menu_tip)); + if (node) + { + node->type = type; + node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", path); + + tip = vtoy_json_get_string_ex(pNode->pstChild, "tip"); + if (tip) + { + grub_snprintf(node->tip1, 1000, "%s", tip); + } + else + { + tip = vtoy_json_get_string_ex(pNode->pstChild, "tip1"); + if (tip) + grub_snprintf(node->tip1, 1000, "%s", tip); + + tip = vtoy_json_get_string_ex(pNode->pstChild, "tip2"); + if (tip) + grub_snprintf(node->tip2, 1000, "%s", tip); + } + + if (g_menu_tip_head) + { + node->next = g_menu_tip_head; + } + + g_menu_tip_head = node; + } + } + } + + return 0; +} + +static int ventoy_plugin_injection_check(VTOY_JSON *json, const char *isodisk) +{ + int type = 0; + const char *path = NULL; + const char *archive = NULL; + VTOY_JSON *pNode = NULL; + + (void)isodisk; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + grub_printf("Not array %d\n", json->enDataType); + return 0; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + type = injection_type_file; + path = vtoy_json_get_string_ex(pNode->pstChild, "image"); + if (!path) + { + type = injection_type_parent; + path = vtoy_json_get_string_ex(pNode->pstChild, "parent"); + if (!path) + { + grub_printf("image/parent not found\n"); + continue; + } + } + + archive = vtoy_json_get_string_ex(pNode->pstChild, "archive"); + if (!archive) + { + grub_printf("archive not found\n"); + continue; + } + + if (type == injection_type_file) + { + if (grub_strchr(path, '*')) + { + grub_printf("image: <%s> [*]\n", path); + } + else + { + grub_printf("image: <%s> [%s]\n", path, ventoy_check_file_exist("%s%s", isodisk, path) ? "OK" : "NOT EXIST"); + } + } + else + { + grub_printf("parent: <%s> [%s]\n", path, + ventoy_is_dir_exist("%s%s", isodisk, path) ? "OK" : "NOT EXIST"); + } + + grub_printf("archive: <%s> [%s]\n\n", archive, ventoy_check_file_exist("%s%s", isodisk, archive) ? "OK" : "NOT EXIST"); + } + + return 0; +} + +static int ventoy_plugin_injection_entry(VTOY_JSON *json, const char *isodisk) +{ + int type = 0; + const char *path = NULL; + const char *archive = NULL; + VTOY_JSON *pNode = NULL; + injection_config *node = NULL; + injection_config *next = NULL; + + (void)isodisk; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + debug("Not array %d\n", json->enDataType); + return 0; + } + + if (g_injection_head) + { + for (node = g_injection_head; node; node = next) + { + next = node->next; + grub_free(node); + } + + g_injection_head = NULL; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + type = injection_type_file; + path = vtoy_json_get_string_ex(pNode->pstChild, "image"); + if (!path) + { + type = injection_type_parent; + path = vtoy_json_get_string_ex(pNode->pstChild, "parent"); + } + + archive = vtoy_json_get_string_ex(pNode->pstChild, "archive"); + if (path && path[0] == '/' && archive && archive[0] == '/') + { + node = grub_zalloc(sizeof(injection_config)); + if (node) + { + node->type = type; + node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", path); + grub_snprintf(node->archive, sizeof(node->archive), "%s", archive); + + if (g_injection_head) + { + node->next = g_injection_head; + } + + g_injection_head = node; + } + } + } + + return 0; +} + +static int ventoy_plugin_menuclass_entry(VTOY_JSON *json, const char *isodisk) +{ + int type; + int parent = 0; + const char *key = NULL; + const char *class = NULL; + VTOY_JSON *pNode = NULL; + menu_class *tail = NULL; + menu_class *node = NULL; + menu_class *next = NULL; + + (void)isodisk; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + debug("Not array %d\n", json->enDataType); + return 0; + } + + if (g_menu_class_head) + { + for (node = g_menu_class_head; node; node = next) + { + next = node->next; + grub_free(node); + } + + g_menu_class_head = NULL; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + parent = 0; + type = vtoy_class_image_file; + key = vtoy_json_get_string_ex(pNode->pstChild, "key"); + if (!key) + { + key = vtoy_json_get_string_ex(pNode->pstChild, "parent"); + if (key) + { + parent = 1; + } + else + { + key = vtoy_json_get_string_ex(pNode->pstChild, "dir"); + type = vtoy_class_directory; + } + } + + class = vtoy_json_get_string_ex(pNode->pstChild, "class"); + if (key && class) + { + node = grub_zalloc(sizeof(menu_class)); + if (node) + { + node->type = type; + node->parent = parent; + node->patlen = grub_snprintf(node->pattern, sizeof(node->pattern), "%s", key); + grub_snprintf(node->class, sizeof(node->class), "%s", class); + + if (g_menu_class_head) + { + tail->next = node; + } + else + { + g_menu_class_head = node; + } + tail = node; + } + } + } + + return 0; +} + +static int ventoy_plugin_menuclass_check(VTOY_JSON *json, const char *isodisk) +{ + const char *name = NULL; + const char *key = NULL; + const char *class = NULL; + VTOY_JSON *pNode = NULL; + + (void)isodisk; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + grub_printf("Not array %d\n", json->enDataType); + return 1; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + name = "key"; + key = vtoy_json_get_string_ex(pNode->pstChild, "key"); + if (!key) + { + name = "parent"; + key = vtoy_json_get_string_ex(pNode->pstChild, "parent"); + if (!key) + { + name = "dir"; + key = vtoy_json_get_string_ex(pNode->pstChild, "dir"); + } + } + + class = vtoy_json_get_string_ex(pNode->pstChild, "class"); + if (key && class) + { + grub_printf("%s: <%s>\n", name, key); + grub_printf("class: <%s>\n\n", class); + } + } + + return 0; +} + +static int ventoy_plugin_custom_boot_entry(VTOY_JSON *json, const char *isodisk) +{ + int type; + int len; + const char *key = NULL; + const char *cfg = NULL; + VTOY_JSON *pNode = NULL; + custom_boot *tail = NULL; + custom_boot *node = NULL; + custom_boot *next = NULL; + + (void)isodisk; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + debug("Not array %d\n", json->enDataType); + return 0; + } + + if (g_custom_boot_head) + { + for (node = g_custom_boot_head; node; node = next) + { + next = node->next; + grub_free(node); + } + + g_custom_boot_head = NULL; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + type = vtoy_custom_boot_image_file; + key = vtoy_json_get_string_ex(pNode->pstChild, "file"); + if (!key) + { + key = vtoy_json_get_string_ex(pNode->pstChild, "dir"); + type = vtoy_custom_boot_directory; + } + + cfg = vtoy_json_get_string_ex(pNode->pstChild, "vcfg"); + if (key && cfg) + { + node = grub_zalloc(sizeof(custom_boot)); + if (node) + { + node->type = type; + node->pathlen = grub_snprintf(node->path, sizeof(node->path), "%s", key); + len = (int)grub_snprintf(node->cfg, sizeof(node->cfg), "%s", cfg); + + if (len >= 5 && grub_strncmp(node->cfg + len - 5, ".vcfg", 5) == 0) + { + if (g_custom_boot_head) + { + tail->next = node; + } + else + { + g_custom_boot_head = node; + } + tail = node; + } + else + { + grub_free(node); + } + } + } + } + + return 0; +} + +static int ventoy_plugin_custom_boot_check(VTOY_JSON *json, const char *isodisk) +{ + int type; + int len; + const char *key = NULL; + const char *cfg = NULL; + VTOY_JSON *pNode = NULL; + + (void)isodisk; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + grub_printf("Not array %d\n", json->enDataType); + return 1; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + type = vtoy_custom_boot_image_file; + key = vtoy_json_get_string_ex(pNode->pstChild, "file"); + if (!key) + { + key = vtoy_json_get_string_ex(pNode->pstChild, "dir"); + type = vtoy_custom_boot_directory; + } + + cfg = vtoy_json_get_string_ex(pNode->pstChild, "vcfg"); + len = (int)grub_strlen(cfg); + if (key && cfg) + { + if (len < 5 || grub_strncmp(cfg + len - 5, ".vcfg", 5)) + { + grub_printf("<%s> does not have \".vcfg\" suffix\n\n", cfg); + } + else + { + grub_printf("%s: <%s>\n", (type == vtoy_custom_boot_directory) ? "dir" : "file", key); + grub_printf("vcfg: <%s>\n\n", cfg); + } + } + } + + return 0; +} + +static int ventoy_plugin_conf_replace_entry(VTOY_JSON *json, const char *isodisk) +{ + int img = 0; + const char *isof = NULL; + const char *orgf = NULL; + const char *newf = NULL; + VTOY_JSON *pNode = NULL; + conf_replace *tail = NULL; + conf_replace *node = NULL; + conf_replace *next = NULL; + + (void)isodisk; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + debug("Not array %d\n", json->enDataType); + return 0; + } + + if (g_conf_replace_head) + { + for (node = g_conf_replace_head; node; node = next) + { + next = node->next; + grub_free(node); + } + + g_conf_replace_head = NULL; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + isof = vtoy_json_get_string_ex(pNode->pstChild, "iso"); + orgf = vtoy_json_get_string_ex(pNode->pstChild, "org"); + newf = vtoy_json_get_string_ex(pNode->pstChild, "new"); + if (isof && orgf && newf && isof[0] == '/' && orgf[0] == '/' && newf[0] == '/') + { + node = grub_zalloc(sizeof(conf_replace)); + if (node) + { + if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "img", &img)) + { + node->img = img; + } + + node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", isof); + grub_snprintf(node->orgconf, sizeof(node->orgconf), "%s", orgf); + grub_snprintf(node->newconf, sizeof(node->newconf), "%s", newf); + + if (g_conf_replace_head) + { + tail->next = node; + } + else + { + g_conf_replace_head = node; + } + tail = node; + } + } + } + + return 0; +} + +static int ventoy_plugin_conf_replace_check(VTOY_JSON *json, const char *isodisk) +{ + int img = 0; + const char *isof = NULL; + const char *orgf = NULL; + const char *newf = NULL; + VTOY_JSON *pNode = NULL; + grub_file_t file = NULL; + char cmd[256]; + + (void)isodisk; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + grub_printf("Not array %d\n", json->enDataType); + return 1; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + isof = vtoy_json_get_string_ex(pNode->pstChild, "iso"); + orgf = vtoy_json_get_string_ex(pNode->pstChild, "org"); + newf = vtoy_json_get_string_ex(pNode->pstChild, "new"); + if (isof && orgf && newf && isof[0] == '/' && orgf[0] == '/' && newf[0] == '/') + { + if (ventoy_check_file_exist("%s%s", isodisk, isof)) + { + grub_printf("iso:<%s> [OK]\n", isof); + + grub_snprintf(cmd, sizeof(cmd), "loopback vtisocheck \"%s%s\"", isodisk, isof); + grub_script_execute_sourcecode(cmd); + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(vtisocheck)/%s", orgf); + if (file) + { + if (grub_strcmp(file->fs->name, "iso9660") == 0) + { + grub_printf("org:<%s> [OK]\n", orgf); + } + else + { + grub_printf("org:<%s> [Exist But NOT ISO9660]\n", orgf); + } + grub_file_close(file); + } + else + { + grub_printf("org:<%s> [NOT Exist]\n", orgf); + } + + grub_script_execute_sourcecode("loopback -d vtisocheck"); + } + else if (grub_strchr(isof, '*')) + { + grub_printf("iso:<%s> [*]\n", isof); + grub_printf("org:<%s>\n", orgf); + } + else + { + grub_printf("iso:<%s> [NOT Exist]\n", isof); + grub_printf("org:<%s>\n", orgf); + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", isodisk, newf); + if (file) + { + if (file->size > vtoy_max_replace_file_size) + { + grub_printf("new:<%s> [Too Big %lu] \n", newf, (ulong)file->size); + } + else + { + grub_printf("new1:<%s> [OK]\n", newf); + } + grub_file_close(file); + } + else + { + grub_printf("new:<%s> [NOT Exist]\n", newf); + } + + if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "img", &img)) + { + grub_printf("img:<%d>\n", img); + } + + grub_printf("\n"); + } + } + + return 0; +} + +static int ventoy_plugin_auto_memdisk_entry(VTOY_JSON *json, const char *isodisk) +{ + VTOY_JSON *pNode = NULL; + auto_memdisk *node = NULL; + auto_memdisk *next = NULL; + + (void)isodisk; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + debug("Not array %d\n", json->enDataType); + return 0; + } + + if (g_auto_memdisk_head) + { + for (node = g_auto_memdisk_head; node; node = next) + { + next = node->next; + grub_free(node); + } + + g_auto_memdisk_head = NULL; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + if (pNode->enDataType == JSON_TYPE_STRING) + { + node = grub_zalloc(sizeof(auto_memdisk)); + if (node) + { + node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", pNode->unData.pcStrVal); + + if (g_auto_memdisk_head) + { + node->next = g_auto_memdisk_head; + } + + g_auto_memdisk_head = node; + } + } + } + + return 0; +} + +static int ventoy_plugin_auto_memdisk_check(VTOY_JSON *json, const char *isodisk) +{ + VTOY_JSON *pNode = NULL; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + grub_printf("Not array %d\n", json->enDataType); + return 1; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + if (pNode->enDataType == JSON_TYPE_STRING) + { + grub_printf("<%s> ", pNode->unData.pcStrVal); + + if (grub_strchr(pNode->unData.pcStrVal, '*')) + { + grub_printf(" [*]\n"); + } + else if (ventoy_check_file_exist("%s%s", isodisk, pNode->unData.pcStrVal)) + { + grub_printf(" [OK]\n"); + } + else + { + grub_printf(" [NOT EXIST]\n"); + } + } + } + + return 0; +} + +static int ventoy_plugin_image_list_entry(VTOY_JSON *json, const char *isodisk) +{ + VTOY_JSON *pNode = NULL; + image_list *node = NULL; + image_list *next = NULL; + image_list *tail = NULL; + + (void)isodisk; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + debug("Not array %d\n", json->enDataType); + return 0; + } + + if (g_image_list_head) + { + for (node = g_image_list_head; node; node = next) + { + next = node->next; + grub_free(node); + } + + g_image_list_head = NULL; + } + + if (grub_strncmp(json->pcName, "image_blacklist", 15) == 0) + { + g_plugin_image_list = VENTOY_IMG_BLACK_LIST; + } + else + { + g_plugin_image_list = VENTOY_IMG_WHITE_LIST; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + if (pNode->enDataType == JSON_TYPE_STRING) + { + node = grub_zalloc(sizeof(image_list)); + if (node) + { + node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", pNode->unData.pcStrVal); + + if (g_image_list_head) + { + tail->next = node; + } + else + { + g_image_list_head = node; + } + tail = node; + } + } + } + + return 0; +} + +static int ventoy_plugin_image_list_check(VTOY_JSON *json, const char *isodisk) +{ + VTOY_JSON *pNode = NULL; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + grub_printf("Not array %d\n", json->enDataType); + return 1; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + if (pNode->enDataType == JSON_TYPE_STRING) + { + grub_printf("<%s> ", pNode->unData.pcStrVal); + + if (grub_strchr(pNode->unData.pcStrVal, '*')) + { + grub_printf(" [*]\n"); + } + else if (ventoy_check_file_exist("%s%s", isodisk, pNode->unData.pcStrVal)) + { + grub_printf(" [OK]\n"); + } + else + { + grub_printf(" [NOT EXIST]\n"); + } + } + } + + return 0; +} + +static plugin_entry g_plugin_entries[] = +{ + { "control", ventoy_plugin_control_entry, ventoy_plugin_control_check, 0 }, + { "theme", ventoy_plugin_theme_entry, ventoy_plugin_theme_check, 0 }, + { "auto_install", ventoy_plugin_auto_install_entry, ventoy_plugin_auto_install_check, 0 }, + { "persistence", ventoy_plugin_persistence_entry, ventoy_plugin_persistence_check, 0 }, + { "menu_alias", ventoy_plugin_menualias_entry, ventoy_plugin_menualias_check, 0 }, + { "menu_tip", ventoy_plugin_menutip_entry, ventoy_plugin_menutip_check, 0 }, + { "menu_class", ventoy_plugin_menuclass_entry, ventoy_plugin_menuclass_check, 0 }, + { "injection", ventoy_plugin_injection_entry, ventoy_plugin_injection_check, 0 }, + { "auto_memdisk", ventoy_plugin_auto_memdisk_entry, ventoy_plugin_auto_memdisk_check, 0 }, + { "image_list", ventoy_plugin_image_list_entry, ventoy_plugin_image_list_check, 0 }, + { "image_blacklist", ventoy_plugin_image_list_entry, ventoy_plugin_image_list_check, 0 }, + { "conf_replace", ventoy_plugin_conf_replace_entry, ventoy_plugin_conf_replace_check, 0 }, + { "dud", ventoy_plugin_dud_entry, ventoy_plugin_dud_check, 0 }, + { "password", ventoy_plugin_pwd_entry, ventoy_plugin_pwd_check, 0 }, + { "custom_boot", ventoy_plugin_custom_boot_entry, ventoy_plugin_custom_boot_check, 0 }, +}; + +static int ventoy_parse_plugin_config(VTOY_JSON *json, const char *isodisk) +{ + int i; + char key[128]; + VTOY_JSON *cur = NULL; + + grub_snprintf(g_iso_disk_name, sizeof(g_iso_disk_name), "%s", isodisk); + + for (cur = json; cur; cur = cur->pstNext) + { + for (i = 0; i < (int)ARRAY_SIZE(g_plugin_entries); i++) + { + grub_snprintf(key, sizeof(key), "%s_%s", g_plugin_entries[i].key, g_arch_mode_suffix); + if (g_plugin_entries[i].flag == 0 && grub_strcmp(key, cur->pcName) == 0) + { + debug("Plugin entry for %s\n", g_plugin_entries[i].key); + g_plugin_entries[i].entryfunc(cur, isodisk); + g_plugin_entries[i].flag = 1; + break; + } + } + } + + + for (cur = json; cur; cur = cur->pstNext) + { + for (i = 0; i < (int)ARRAY_SIZE(g_plugin_entries); i++) + { + if (g_plugin_entries[i].flag == 0 && grub_strcmp(g_plugin_entries[i].key, cur->pcName) == 0) + { + debug("Plugin entry for %s\n", g_plugin_entries[i].key); + g_plugin_entries[i].entryfunc(cur, isodisk); + g_plugin_entries[i].flag = 1; + break; + } + } + } + + return 0; +} + +grub_err_t ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int ret = 0; + int offset = 0; + char *buf = NULL; + grub_uint8_t *code = NULL; + grub_file_t file; + VTOY_JSON *json = NULL; + + (void)ctxt; + (void)argc; + + grub_env_set("VTOY_TIP_LEFT", "10%"); + grub_env_set("VTOY_TIP_TOP", "80%+5"); + grub_env_set("VTOY_TIP_COLOR", "blue"); + grub_env_set("VTOY_TIP_ALIGN", "left"); + + file = ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD, "%s/ventoy/ventoy.json", args[0]); + if (!file) + { + return GRUB_ERR_NONE; + } + + debug("json configuration file size %d\n", (int)file->size); + + buf = grub_malloc(file->size + 1); + if (!buf) + { + grub_file_close(file); + return 1; + } + + buf[file->size] = 0; + grub_file_read(file, buf, file->size); + grub_file_close(file); + + json = vtoy_json_create(); + if (!json) + { + return 1; + } + + code = (grub_uint8_t *)buf; + if (code[0] == 0xef && code[1] == 0xbb && code[2] == 0xbf) + { + offset = 3; /* Skip UTF-8 BOM */ + } + else if ((code[0] == 0xff && code[1] == 0xfe) || (code[0] == 0xfe && code[1] == 0xff)) + { + grub_env_set("VTOY_PLUGIN_SYNTAX_ERROR", "1"); + grub_env_export("VTOY_PLUGIN_SYNTAX_ERROR"); + + grub_env_set("VTOY_PLUGIN_ENCODE_ERROR", "1"); + grub_env_export("VTOY_PLUGIN_ENCODE_ERROR"); + + debug("Failed to parse json string %d\n", ret); + grub_free(buf); + return 1; + } + + ret = vtoy_json_parse(json, buf + offset); + if (ret) + { + grub_env_set("VTOY_PLUGIN_SYNTAX_ERROR", "1"); + grub_env_export("VTOY_PLUGIN_SYNTAX_ERROR"); + + debug("Failed to parse json string %d\n", ret); + grub_free(buf); + return 1; + } + + ventoy_parse_plugin_config(json->pstChild, args[0]); + + vtoy_json_destroy(json); + + grub_free(buf); + + if (g_boot_pwd.type) + { + grub_printf("\n\n======= %s ======\n\n", grub_env_get("VTOY_TEXT_MENU_VER")); + if (ventoy_check_password(&g_boot_pwd, 3)) + { + grub_printf("\n!!! Password check failed, will exit after 5 seconds. !!!\n"); + grub_refresh(); + grub_sleep(5); + grub_exit(); + } + } + + if (g_menu_tip_head) + { + grub_env_set("VTOY_MENU_TIP_ENABLE", "1"); + } + else + { + grub_env_unset("VTOY_MENU_TIP_ENABLE"); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +void ventoy_plugin_dump_injection(void) +{ + injection_config *node = NULL; + + for (node = g_injection_head; node; node = node->next) + { + grub_printf("\n%s:<%s>\n", (node->type == injection_type_file) ? "IMAGE" : "PARENT", node->isopath); + grub_printf("ARCHIVE:<%s>\n", node->archive); + } + + return; +} + + +void ventoy_plugin_dump_auto_install(void) +{ + int i; + install_template *node = NULL; + + for (node = g_install_template_head; node; node = node->next) + { + grub_printf("\n%s:<%s> <%d>\n", + (node->type == auto_install_type_file) ? "IMAGE" : "PARENT", + node->isopath, node->templatenum); + for (i = 0; i < node->templatenum; i++) + { + grub_printf("SCRIPT %d:<%s>\n", i, node->templatepath[i].path); + } + } + + return; +} + +void ventoy_plugin_dump_persistence(void) +{ + int rc; + int i = 0; + persistence_config *node = NULL; + ventoy_img_chunk_list chunk_list; + + for (node = g_persistence_head; node; node = node->next) + { + grub_printf("\nIMAGE:<%s> <%d>\n", node->isopath, node->backendnum); + + for (i = 0; i < node->backendnum; i++) + { + grub_printf("PERSIST %d:<%s>", i, node->backendpath[i].path); + rc = ventoy_plugin_get_persistent_chunklist(node->isopath, i, &chunk_list); + if (rc == 0) + { + grub_printf(" [ SUCCESS ]\n"); + grub_free(chunk_list.chunk); + } + else + { + grub_printf(" [ FAILED ]\n"); + } + } + } + + return; +} + +install_template * ventoy_plugin_find_install_template(const char *isopath) +{ + int len; + install_template *node = NULL; + + if (!g_install_template_head) + { + return NULL; + } + + len = (int)grub_strlen(isopath); + for (node = g_install_template_head; node; node = node->next) + { + if (node->type == auto_install_type_file) + { + if (node->pathlen == len && ventoy_strcmp(node->isopath, isopath) == 0) + { + return node; + } + } + } + + for (node = g_install_template_head; node; node = node->next) + { + if (node->type == auto_install_type_parent) + { + if (node->pathlen < len && ventoy_plugin_is_parent(node->isopath, node->pathlen, isopath)) + { + return node; + } + } + } + + return NULL; +} + +char * ventoy_plugin_get_cur_install_template(const char *isopath, install_template **cur) +{ + install_template *node = NULL; + + if (cur) + { + *cur = NULL; + } + + node = ventoy_plugin_find_install_template(isopath); + if ((!node) || (!node->templatepath)) + { + return NULL; + } + + if (node->cursel < 0 || node->cursel >= node->templatenum) + { + return NULL; + } + + if (cur) + { + *cur = node; + } + + return node->templatepath[node->cursel].path; +} + +persistence_config * ventoy_plugin_find_persistent(const char *isopath) +{ + int len; + persistence_config *node = NULL; + + if (!g_persistence_head) + { + return NULL; + } + + len = (int)grub_strlen(isopath); + for (node = g_persistence_head; node; node = node->next) + { + if ((len == node->pathlen) && (ventoy_strcmp(node->isopath, isopath) == 0)) + { + return node; + } + } + + return NULL; +} + +int ventoy_plugin_get_persistent_chunklist(const char *isopath, int index, ventoy_img_chunk_list *chunk_list) +{ + int rc = 1; + int len = 0; + char *path = NULL; + grub_uint64_t start = 0; + grub_file_t file = NULL; + persistence_config *node = NULL; + + node = ventoy_plugin_find_persistent(isopath); + if ((!node) || (!node->backendpath)) + { + return 1; + } + + if (index < 0) + { + index = node->cursel; + } + + if (index < 0 || index >= node->backendnum) + { + return 1; + } + + path = node->backendpath[index].path; + + if (node->backendpath[index].vlnk_add == 0) + { + len = grub_strlen(path); + if (len > 9 && grub_strncmp(path + len - 9, ".vlnk.dat", 9) == 0) + { + ventoy_add_vlnk_file(NULL, path); + node->backendpath[index].vlnk_add = 1; + } + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", g_iso_disk_name, path); + if (!file) + { + debug("Failed to open file %s%s\n", g_iso_disk_name, path); + goto end; + } + + grub_memset(chunk_list, 0, sizeof(ventoy_img_chunk_list)); + chunk_list->chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM); + if (NULL == chunk_list->chunk) + { + goto end; + } + + chunk_list->max_chunk = DEFAULT_CHUNK_NUM; + chunk_list->cur_chunk = 0; + + start = file->device->disk->partition->start; + ventoy_get_block_list(file, chunk_list, start); + + if (0 != ventoy_check_block_list(file, chunk_list, start, NULL, 0)) + { + grub_free(chunk_list->chunk); + chunk_list->chunk = NULL; + goto end; + } + + rc = 0; + +end: + if (file) + grub_file_close(file); + + return rc; +} + +const char * ventoy_plugin_get_injection(const char *isopath) +{ + int len; + injection_config *node = NULL; + + if (!g_injection_head) + { + return NULL; + } + + len = (int)grub_strlen(isopath); + for (node = g_injection_head; node; node = node->next) + { + if (node->type == injection_type_file) + { + if (node->pathlen == len && ventoy_strcmp(node->isopath, isopath) == 0) + { + return node->archive; + } + } + } + + for (node = g_injection_head; node; node = node->next) + { + if (node->type == injection_type_parent) + { + if (node->pathlen < len && ventoy_plugin_is_parent(node->isopath, node->pathlen, isopath)) + { + return node->archive; + } + } + } + + return NULL; +} + +const char * ventoy_plugin_get_menu_alias(int type, const char *isopath) +{ + int len; + menu_alias *node = NULL; + + if (!g_menu_alias_head) + { + return NULL; + } + + len = (int)grub_strlen(isopath); + for (node = g_menu_alias_head; node; node = node->next) + { + if (node->type == type && node->pathlen && + node->pathlen == len && ventoy_strcmp(node->isopath, isopath) == 0) + { + return node->alias; + } + } + + return NULL; +} + +const menu_tip * ventoy_plugin_get_menu_tip(int type, const char *isopath) +{ + int len; + menu_tip *node = NULL; + + if (!g_menu_tip_head) + { + return NULL; + } + + len = (int)grub_strlen(isopath); + for (node = g_menu_tip_head; node; node = node->next) + { + if (node->type == type && node->pathlen && + node->pathlen == len && ventoy_strcmp(node->isopath, isopath) == 0) + { + return node; + } + } + + return NULL; +} + +const char * ventoy_plugin_get_menu_class(int type, const char *name, const char *path) +{ + int namelen; + int pathlen; + menu_class *node = NULL; + + if (!g_menu_class_head) + { + return NULL; + } + + namelen = (int)grub_strlen(name); + pathlen = (int)grub_strlen(path); + + if (vtoy_class_image_file == type) + { + for (node = g_menu_class_head; node; node = node->next) + { + if (node->type != type) + { + continue; + } + + if (node->parent == 0) + { + if ((node->patlen < namelen) && grub_strstr(name, node->pattern)) + { + return node->class; + } + } + } + + for (node = g_menu_class_head; node; node = node->next) + { + if (node->type != type) + { + continue; + } + + if (node->parent) + { + if ((node->patlen < pathlen) && ventoy_plugin_is_parent(node->pattern, node->patlen, path)) + { + return node->class; + } + } + } + } + else + { + for (node = g_menu_class_head; node; node = node->next) + { + if (node->type == type && node->patlen == namelen && grub_strncmp(name, node->pattern, namelen) == 0) + { + return node->class; + } + } + } + + return NULL; +} + +int ventoy_plugin_add_custom_boot(const char *vcfgpath) +{ + int len; + custom_boot *node = NULL; + + node = grub_zalloc(sizeof(custom_boot)); + if (node) + { + node->type = vtoy_custom_boot_image_file; + node->pathlen = grub_snprintf(node->path, sizeof(node->path), "%s", vcfgpath); + grub_snprintf(node->cfg, sizeof(node->cfg), "%s", vcfgpath); + + /* .vcfg */ + len = node->pathlen - 5; + node->path[len] = 0; + node->pathlen = len; + + if (g_custom_boot_head) + { + node->next = g_custom_boot_head; + } + g_custom_boot_head = node; + } + + return 0; +} + +const char * ventoy_plugin_get_custom_boot(const char *isopath) +{ + int i; + int len; + custom_boot *node = NULL; + + if (!g_custom_boot_head) + { + return NULL; + } + + len = (int)grub_strlen(isopath); + + for (node = g_custom_boot_head; node; node = node->next) + { + if (node->type == vtoy_custom_boot_image_file) + { + if (node->pathlen == len && grub_strncmp(isopath, node->path, len) == 0) + { + return node->cfg; + } + } + else + { + if (node->pathlen < len && isopath[node->pathlen] == '/' && + grub_strncmp(isopath, node->path, node->pathlen) == 0) + { + for (i = node->pathlen + 1; i < len; i++) + { + if (isopath[i] == '/') + { + break; + } + } + + if (i >= len) + { + return node->cfg; + } + } + } + } + + return NULL; +} + +grub_err_t ventoy_cmd_dump_custom_boot(grub_extcmd_context_t ctxt, int argc, char **args) +{ + custom_boot *node = NULL; + + (void)argc; + (void)ctxt; + (void)args; + + for (node = g_custom_boot_head; node; node = node->next) + { + grub_printf("[%s] <%s>:<%s>\n", (node->type == vtoy_custom_boot_directory) ? "dir" : "file", + node->path, node->cfg); + } + + return 0; +} + +int ventoy_plugin_check_memdisk(const char *isopath) +{ + int len; + auto_memdisk *node = NULL; + + if (!g_auto_memdisk_head) + { + return 0; + } + + len = (int)grub_strlen(isopath); + for (node = g_auto_memdisk_head; node; node = node->next) + { + if (node->pathlen == len && ventoy_strncmp(node->isopath, isopath, len) == 0) + { + return 1; + } + } + + return 0; +} + +int ventoy_plugin_get_image_list_index(int type, const char *name) +{ + int len; + int index = 1; + image_list *node = NULL; + + if (!g_image_list_head) + { + return 0; + } + + len = (int)grub_strlen(name); + + for (node = g_image_list_head; node; node = node->next, index++) + { + if (vtoy_class_directory == type) + { + if (len < node->pathlen && ventoy_strncmp(node->isopath, name, len) == 0) + { + return index; + } + } + else + { + if (len == node->pathlen && ventoy_strncmp(node->isopath, name, len) == 0) + { + return index; + } + } + } + + return 0; +} + +int ventoy_plugin_find_conf_replace(const char *iso, conf_replace *nodes[VTOY_MAX_CONF_REPLACE]) +{ + int n = 0; + int len; + conf_replace *node; + + if (!g_conf_replace_head) + { + return 0; + } + + len = (int)grub_strlen(iso); + + for (node = g_conf_replace_head; node; node = node->next) + { + if (node->pathlen == len && ventoy_strncmp(node->isopath, iso, len) == 0) + { + nodes[n++] = node; + if (n >= VTOY_MAX_CONF_REPLACE) + { + return n; + } + } + } + + return n; +} + +dud * ventoy_plugin_find_dud(const char *iso) +{ + int len; + dud *node; + + if (!g_dud_head) + { + return NULL; + } + + len = (int)grub_strlen(iso); + for (node = g_dud_head; node; node = node->next) + { + if (node->pathlen == len && ventoy_strncmp(node->isopath, iso, len) == 0) + { + return node; + } + } + + return NULL; +} + +int ventoy_plugin_load_dud(dud *node, const char *isopart) +{ + int i; + char *buf; + grub_file_t file; + + for (i = 0; i < node->dudnum; i++) + { + if (node->files[i].size > 0) + { + debug("file %d has been loaded\n", i); + continue; + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", isopart, node->dudpath[i].path); + if (file) + { + buf = grub_malloc(file->size); + if (buf) + { + grub_file_read(file, buf, file->size); + node->files[i].size = (int)file->size; + node->files[i].buf = buf; + } + grub_file_close(file); + } + } + + return 0; +} + +static const vtoy_password * ventoy_plugin_get_password(const char *isopath) +{ + int i; + int len; + const char *pos = NULL; + menu_password *node = NULL; + + if (!isopath) + { + return NULL; + } + + if (g_pwd_head) + { + len = (int)grub_strlen(isopath); + for (node = g_pwd_head; node; node = node->next) + { + if (node->type == vtoy_menu_pwd_file) + { + if (node->pathlen == len && ventoy_strncmp(node->isopath, isopath, len) == 0) + { + return &(node->password); + } + } + } + + for (node = g_pwd_head; node; node = node->next) + { + if (node->type == vtoy_menu_pwd_parent) + { + if (node->pathlen < len && ventoy_plugin_is_parent(node->isopath, node->pathlen, isopath)) + { + return &(node->password); + } + } + } + } + + while (*isopath) + { + if (*isopath == '.') + { + pos = isopath; + } + isopath++; + } + + if (pos) + { + for (i = 0; i < (int)ARRAY_SIZE(g_menu_prefix); i++) + { + if (g_file_type_pwd[i].type && 0 == grub_strcasecmp(pos + 1, g_menu_prefix[i])) + { + return g_file_type_pwd + i; + } + } + } + + return NULL; +} + +grub_err_t ventoy_cmd_check_password(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int ret; + const vtoy_password *pwd = NULL; + + (void)ctxt; + (void)argc; + + pwd = ventoy_plugin_get_password(args[0]); + if (pwd) + { + if (0 == ventoy_check_password(pwd, 1)) + { + ret = 1; + } + else + { + ret = 0; + } + } + else + { + ret = 1; + } + + grub_errno = 0; + return ret; +} + +grub_err_t ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i = 0; + int ret = 0; + char *buf = NULL; + char key[128]; + grub_file_t file; + VTOY_JSON *node = NULL; + VTOY_JSON *json = NULL; + + (void)ctxt; + + if (argc != 3) + { + return 0; + } + + file = ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD, "%s/ventoy/ventoy.json", args[0]); + if (!file) + { + grub_printf("Plugin json file /ventoy/ventoy.json does NOT exist.\n"); + grub_printf("Attention: directory name and filename are both case-sensitive.\n"); + goto end; + } + + buf = grub_malloc(file->size + 1); + if (!buf) + { + grub_printf("Failed to malloc memory %lu.\n", (ulong)(file->size + 1)); + goto end; + } + + buf[file->size] = 0; + grub_file_read(file, buf, file->size); + + json = vtoy_json_create(); + if (!json) + { + grub_printf("Failed to create json\n"); + goto end; + } + + ret = vtoy_json_parse(json, buf); + if (ret) + { + grub_printf("Syntax error detected in ventoy.json, please check it.\n"); + goto end; + } + + grub_snprintf(key, sizeof(key), "%s_%s", args[1], g_arch_mode_suffix); + for (node = json->pstChild; node; node = node->pstNext) + { + if (grub_strcmp(node->pcName, key) == 0) + { + break; + } + } + + if (!node) + { + for (node = json->pstChild; node; node = node->pstNext) + { + if (grub_strcmp(node->pcName, args[1]) == 0) + { + break; + } + } + + if (!node) + { + grub_printf("%s is NOT found in ventoy.json\n", args[1]); + goto end; + } + } + + for (i = 0; i < (int)ARRAY_SIZE(g_plugin_entries); i++) + { + if (grub_strcmp(g_plugin_entries[i].key, args[1]) == 0) + { + if (g_plugin_entries[i].checkfunc) + { + ret = g_plugin_entries[i].checkfunc(node, args[2]); + } + break; + } + } + +end: + check_free(file, grub_file_close); + check_free(json, vtoy_json_destroy); + grub_check_free(buf); + + return 0; +} + +grub_err_t ventoy_cmd_select_theme_cfg(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int pos = 0; + int bufsize = 0; + char *name = NULL; + char *buf = NULL; + theme_list *node = NULL; + + (void)argc; + (void)args; + (void)ctxt; + + if (g_theme_single_file[0]) + { + return 0; + } + + if (g_theme_num < 2) + { + return 0; + } + + bufsize = (g_theme_num + 1) * 1024; + buf = grub_malloc(bufsize); + if (!buf) + { + return 0; + } + + for (node = g_theme_head; node; node = node->next) + { + name = grub_strstr(node->theme.path, ")/"); + if (name) + { + name++; + } + else + { + name = node->theme.path; + } + + pos += grub_snprintf(buf + pos, bufsize - pos, + "menuentry \"%s\" --class=debug_theme_item --class=debug_theme_select --class=F5tool {\n" + "vt_set_theme_path \"%s\"\n" + "}\n", + name, node->theme.path); + } + + pos += grub_snprintf(buf + pos, bufsize - pos, + "menuentry \"$VTLANG_RETURN_PREVIOUS\" --class=vtoyret VTOY_RET {\n" + "echo 'Return ...'\n" + "}\n"); + + grub_script_execute_sourcecode(buf); + grub_free(buf); + + return 0; +} + +extern char g_ventoy_theme_path[256]; + +grub_err_t ventoy_cmd_set_theme(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_uint32_t i = 0; + grub_uint32_t mod = 0; + grub_uint32_t theme_num = 0; + theme_list *node = g_theme_head; + struct grub_datetime datetime; + struct grub_video_mode_info info; + char buf[64]; + char **pThemePath = NULL; + + (void)argc; + (void)args; + (void)ctxt; + + if (g_theme_single_file[0]) + { + debug("single theme %s\n", g_theme_single_file); + grub_env_set("theme", g_theme_single_file); + goto end; + } + + debug("g_theme_num = %d\n", g_theme_num); + + if (g_theme_num == 0) + { + goto end; + } + + if (g_theme_id > 0 && g_theme_id <= g_theme_num) + { + for (i = 0; i < (grub_uint32_t)(g_theme_id - 1) && node; i++) + { + node = node->next; + } + + grub_env_set("theme", node->theme.path); + goto end; + } + + pThemePath = (char **)grub_zalloc(sizeof(char *) * g_theme_num); + if (!pThemePath) + { + goto end; + } + + if (g_theme_res_fit) + { + if (grub_video_get_info(&info) == GRUB_ERR_NONE) + { + debug("get video info success %ux%u\n", info.width, info.height); + grub_snprintf(buf, sizeof(buf), "%ux%u", info.width, info.height); + for (node = g_theme_head; node; node = node->next) + { + if (grub_strstr(node->theme.path, buf)) + { + pThemePath[theme_num++] = node->theme.path; + } + } + } + } + + if (theme_num == 0) + { + for (node = g_theme_head; node; node = node->next) + { + pThemePath[theme_num++] = node->theme.path; + } + } + + if (theme_num == 1) + { + mod = 0; + debug("Only 1 theme match, no need to random.\n"); + } + else + { + grub_memset(&datetime, 0, sizeof(datetime)); + grub_get_datetime(&datetime); + + if (g_theme_random == vtoy_theme_random_boot_second) + { + grub_divmod32((grub_uint32_t)datetime.second, theme_num, &mod); + } + else if (g_theme_random == vtoy_theme_random_boot_day) + { + grub_divmod32((grub_uint32_t)datetime.day, theme_num, &mod); + } + else if (g_theme_random == vtoy_theme_random_boot_month) + { + grub_divmod32((grub_uint32_t)datetime.month, theme_num, &mod); + } + + debug("%04d/%02d/%02d %02d:%02d:%02d theme_num:%d mod:%d\n", + datetime.year, datetime.month, datetime.day, + datetime.hour, datetime.minute, datetime.second, + theme_num, mod); + } + + if (argc > 0 && grub_strcmp(args[0], "switch") == 0) + { + grub_snprintf(g_ventoy_theme_path, sizeof(g_ventoy_theme_path), "%s", pThemePath[mod]); + } + else + { + debug("random theme %s\n", pThemePath[mod]); + grub_env_set("theme", pThemePath[mod]); + } + g_ventoy_menu_refresh = 1; + +end: + + grub_check_free(pThemePath); + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_set_theme_path(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)argc; + (void)ctxt; + + if (argc == 0) + { + g_ventoy_theme_path[0] = 0; + } + else + { + grub_snprintf(g_ventoy_theme_path, sizeof(g_ventoy_theme_path), "%s", args[0]); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +const char *ventoy_get_vmenu_title(const char *vMenu) +{ + return vtoy_json_get_string_ex(g_menu_lang_json->pstChild, vMenu); +} + +int ventoy_plugin_load_menu_lang(int init, const char *lang) +{ + int ret = 1; + grub_file_t file = NULL; + char *buf = NULL; + + if (grub_strcmp(lang, g_cur_menu_language) == 0) + { + debug("Same menu lang %s\n", lang); + return 0; + } + grub_snprintf(g_cur_menu_language, sizeof(g_cur_menu_language), "%s", lang); + + debug("Load menu lang %s\n", g_cur_menu_language); + + if (g_menu_lang_json) + { + vtoy_json_destroy(g_menu_lang_json); + g_menu_lang_json = NULL; + } + + g_menu_lang_json = vtoy_json_create(); + if (!g_menu_lang_json) + { + goto end; + } + + file = ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD, "(vt_menu_tarfs)/menu/%s.json", lang); + if (!file) + { + goto end; + } + + buf = grub_malloc(file->size + 1); + if (!buf) + { + grub_printf("Failed to malloc memory %lu.\n", (ulong)(file->size + 1)); + goto end; + } + + buf[file->size] = 0; + grub_file_read(file, buf, file->size); + + vtoy_json_parse(g_menu_lang_json, buf); + + if (g_default_menu_mode == 0) + { + grub_snprintf(g_ventoy_hotkey_tip, sizeof(g_ventoy_hotkey_tip), "%s", ventoy_get_vmenu_title("VTLANG_STR_HOTKEY_TREE")); + } + else + { + grub_snprintf(g_ventoy_hotkey_tip, sizeof(g_ventoy_hotkey_tip), "%s", ventoy_get_vmenu_title("VTLANG_STR_HOTKEY_LIST")); + } + + if (init == 0) + { + ventoy_menu_push_key(GRUB_TERM_ESC); + ventoy_menu_push_key(GRUB_TERM_ESC); + g_ventoy_menu_refresh = 1; + } + ret = 0; + +end: + + check_free(file, grub_file_close); + grub_check_free(buf); + + return ret; +} + +grub_err_t ventoy_cmd_cur_menu_lang(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + + if (argc > 0) + { + grub_env_set(args[0], g_cur_menu_language); + } + else + { + grub_printf("%s\n", g_cur_menu_language); + grub_printf("%s\n", g_ventoy_hotkey_tip); + grub_refresh(); + } + + VENTOY_CMD_RETURN(0); +} + +grub_err_t ventoy_cmd_push_menulang(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)argc; + (void)ctxt; + + if (g_push_menu_language[0] == 0) + { + grub_memcpy(g_push_menu_language, g_cur_menu_language, sizeof(g_push_menu_language)); + ventoy_plugin_load_menu_lang(0, args[0]); + } + + VENTOY_CMD_RETURN(0); +} + +grub_err_t ventoy_cmd_pop_menulang(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)argc; + (void)ctxt; + (void)args; + + if (g_push_menu_language[0]) + { + ventoy_plugin_load_menu_lang(0, g_push_menu_language); + g_push_menu_language[0] = 0; + } + + VENTOY_CMD_RETURN(0); +} + + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_unix.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_unix.c new file mode 100644 index 0000000..9d16ed1 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_unix.c @@ -0,0 +1,1264 @@ +/****************************************************************************** + * ventoy_unix.c + * + * Copyright (c) 2020, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ventoy_def.h" + +GRUB_MOD_LICENSE ("GPLv3+"); + +char g_ko_mod_path[256]; +int g_conf_new_len = 0; +char *g_conf_new_data = NULL; + +int g_mod_new_len = 0; +char *g_mod_new_data = NULL; + +int g_mod_search_magic = 0; +int g_unix_vlnk_boot = 0; + +int g_ko_fillmap_len = 0; +char *g_ko_fillmap_data = NULL; + +grub_uint64_t g_mod_override_offset = 0; +grub_uint64_t g_conf_override_offset = 0; + +static int ventoy_get_file_override(const char *filename, grub_uint64_t *offset) +{ + grub_file_t file; + + *offset = 0; + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(loop)%s", filename); + if (!file) + { + return 1; + } + + *offset = grub_iso9660_get_last_file_dirent_pos(file) + 2; + + grub_file_close(file); + + return 0; +} + +static grub_uint32_t ventoy_unix_get_override_chunk_count(void) +{ + grub_uint32_t count = 0; + + if (g_conf_new_len > 0) + { + count++; + } + + if (g_mod_new_len > 0) + { + count++; + } + + if (g_ko_fillmap_len > 0) + { + count += (g_ko_fillmap_len / 512); + if ((g_ko_fillmap_len % 512) > 0) + { + count++; + } + } + + return count; +} + +static grub_uint32_t ventoy_unix_get_virt_chunk_count(void) +{ + grub_uint32_t count = 0; + + if (g_conf_new_len > 0) + { + count++; + } + + if (g_mod_new_len > 0) + { + count++; + } + + return count; +} +static grub_uint32_t ventoy_unix_get_virt_chunk_size(void) +{ + grub_uint32_t size; + + size = sizeof(ventoy_virt_chunk) * ventoy_unix_get_virt_chunk_count(); + + if (g_conf_new_len > 0) + { + size += ventoy_align_2k(g_conf_new_len); + } + + if (g_mod_new_len > 0) + { + size += ventoy_align_2k(g_mod_new_len); + } + + return size; +} + +static void ventoy_unix_fill_map_data(ventoy_chain_head *chain, struct g_ventoy_map *map) +{ + grub_uint32_t i; + ventoy_img_chunk *chunk = NULL; + + debug("Fill unix map data: <%llu> <%u> %p\n", + (unsigned long long)chain->os_param.vtoy_disk_size, g_img_chunk_list.cur_chunk, map); + + map->magic1[0] = map->magic2[0] = VENTOY_UNIX_SEG_MAGIC0; + map->magic1[1] = map->magic2[1] = VENTOY_UNIX_SEG_MAGIC1; + map->magic1[2] = map->magic2[2] = VENTOY_UNIX_SEG_MAGIC2; + map->magic1[3] = map->magic2[3] = VENTOY_UNIX_SEG_MAGIC3; + + map->disksize = chain->os_param.vtoy_disk_size; + grub_memcpy(map->diskuuid, chain->os_param.vtoy_disk_guid, 16); + + map->segnum = g_img_chunk_list.cur_chunk; + if (g_img_chunk_list.cur_chunk > VENTOY_UNIX_MAX_SEGNUM) + { + debug("####[FAIL] Too many segments for the ISO file %u\n", g_img_chunk_list.cur_chunk); + map->segnum = VENTOY_UNIX_MAX_SEGNUM; + } + + for (i = 0; i < (grub_uint32_t)(map->segnum); i++) + { + chunk = g_img_chunk_list.chunk + i; + map->seglist[i].seg_start_bytes = chunk->disk_start_sector * 512ULL; + map->seglist[i].seg_end_bytes = (chunk->disk_end_sector + 1) * 512ULL; + } +} + +static void ventoy_unix_fill_override_data( grub_uint64_t isosize, ventoy_chain_head *chain) +{ + int i; + int left; + char *data = NULL; + grub_uint64_t offset; + grub_uint64_t sector; + ventoy_override_chunk *cur; + ventoy_iso9660_override *dirent; + + sector = (isosize + 2047) / 2048; + + cur = (ventoy_override_chunk *)((char *)chain + chain->override_chunk_offset); + + if (g_conf_new_len > 0) + { + /* loader.conf */ + cur->img_offset = g_conf_override_offset; + cur->override_size = sizeof(ventoy_iso9660_override); + dirent = (ventoy_iso9660_override *)cur->override_data; + dirent->first_sector = (grub_uint32_t)sector; + dirent->size = (grub_uint32_t)g_conf_new_len; + dirent->first_sector_be = grub_swap_bytes32(dirent->first_sector); + dirent->size_be = grub_swap_bytes32(dirent->size); + sector += (dirent->size + 2047) / 2048; + cur++; + } + + if (g_mod_new_len > 0) + { + /* mod.ko */ + cur->img_offset = g_mod_override_offset; + cur->override_size = sizeof(ventoy_iso9660_override); + dirent = (ventoy_iso9660_override *)cur->override_data; + dirent->first_sector = (grub_uint32_t)sector; + dirent->size = (grub_uint32_t)g_mod_new_len; + dirent->first_sector_be = grub_swap_bytes32(dirent->first_sector); + dirent->size_be = grub_swap_bytes32(dirent->size); + sector += (dirent->size + 2047) / 2048; + cur++; + } + + if (g_ko_fillmap_len > 0) + { + data = g_ko_fillmap_data; + offset = g_mod_override_offset; + + ventoy_unix_fill_map_data(chain, (struct g_ventoy_map *)data); + + for (i = 0; i < g_ko_fillmap_len / 512; i++) + { + cur->img_offset = offset; + cur->override_size = 512; + grub_memcpy(cur->override_data, data, 512); + + offset += 512; + data += 512; + cur++; + } + + left = (g_ko_fillmap_len % 512); + if (left > 0) + { + cur->img_offset = offset; + cur->override_size = left; + grub_memcpy(cur->override_data, data, left); + + offset += left; + cur++; + } + } + + return; +} + +static void ventoy_unix_fill_virt_data( grub_uint64_t isosize, ventoy_chain_head *chain) +{ + grub_uint64_t sector; + grub_uint32_t offset; + grub_uint32_t data_secs; + char *override; + ventoy_virt_chunk *cur; + + override = (char *)chain + chain->virt_chunk_offset; + cur = (ventoy_virt_chunk *)override; + + sector = (isosize + 2047) / 2048; + offset = 2 * sizeof(ventoy_virt_chunk); + + if (g_conf_new_len > 0) + { + ventoy_unix_fill_virt(g_conf_new_data, g_conf_new_len); + } + + if (g_mod_new_len > 0) + { + if (g_mod_search_magic > 0) + { + ventoy_unix_fill_map_data(chain, (struct g_ventoy_map *)(g_mod_new_data + g_mod_search_magic)); + } + + ventoy_unix_fill_virt(g_mod_new_data, g_mod_new_len); + } + + return; +} + +static int ventoy_freebsd_append_conf(char *buf, const char *isopath, const char *alias) +{ + int pos = 0; + grub_uint32_t i; + grub_disk_t disk; + grub_file_t isofile; + char uuid[64] = {0}; + const char *val = NULL; + ventoy_img_chunk *chunk; + grub_uint8_t disk_sig[4]; + grub_uint8_t disk_guid[16]; + + debug("ventoy_freebsd_append_conf %s\n", isopath); + + isofile = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", isopath); + if (!isofile) + { + return 1; + } + + vtoy_ssprintf(buf, pos, "ventoy_load=\"%s\"\n", "YES"); + vtoy_ssprintf(buf, pos, "ventoy_name=\"%s\"\n", g_ko_mod_path); + + if (alias) + { + vtoy_ssprintf(buf, pos, "hint.ventoy.0.alias=\"%s\"\n", alias); + } + + if (g_unix_vlnk_boot) + { + vtoy_ssprintf(buf, pos, "hint.ventoy.0.vlnk=%d\n", 1); + } + + val = ventoy_get_env("VTOY_UNIX_REMOUNT"); + if (val && val[0] == '1' && val[1] == 0) + { + vtoy_ssprintf(buf, pos, "hint.ventoy.0.remount=%d\n", 1); + } + + if (g_mod_search_magic) + { + debug("hint.ventoy NO need\n"); + goto out; + } + + debug("Fill hint.ventoy info\n"); + + disk = isofile->device->disk; + + ventoy_get_disk_guid(isofile->name, disk_guid, disk_sig); + + for (i = 0; i < 16; i++) + { + grub_snprintf(uuid + i * 2, sizeof(uuid), "%02x", disk_guid[i]); + } + + vtoy_ssprintf(buf, pos, "hint.ventoy.0.disksize=%llu\n", (ulonglong)(disk->total_sectors * (1 << disk->log_sector_size))); + vtoy_ssprintf(buf, pos, "hint.ventoy.0.diskuuid=\"%s\"\n", uuid); + vtoy_ssprintf(buf, pos, "hint.ventoy.0.disksignature=%02x%02x%02x%02x\n", disk_sig[0], disk_sig[1], disk_sig[2], disk_sig[3]); + vtoy_ssprintf(buf, pos, "hint.ventoy.0.segnum=%u\n", g_img_chunk_list.cur_chunk); + + for (i = 0; i < g_img_chunk_list.cur_chunk; i++) + { + chunk = g_img_chunk_list.chunk + i; + vtoy_ssprintf(buf, pos, "hint.ventoy.%u.seg=\"0x%llx@0x%llx\"\n", + i, (ulonglong)(chunk->disk_start_sector * 512), + (ulonglong)((chunk->disk_end_sector + 1) * 512)); + } + +out: + grub_file_close(isofile); + return pos; +} + +static int ventoy_dragonfly_append_conf(char *buf, const char *isopath) +{ + int pos = 0; + + debug("ventoy_dragonfly_append_conf %s\n", isopath); + + vtoy_ssprintf(buf, pos, "tmpfs_load=\"%s\"\n", "YES"); + vtoy_ssprintf(buf, pos, "dm_target_linear_load=\"%s\"\n", "YES"); + vtoy_ssprintf(buf, pos, "initrd.img_load=\"%s\"\n", "YES"); + vtoy_ssprintf(buf, pos, "initrd.img_type=\"%s\"\n", "md_image"); + vtoy_ssprintf(buf, pos, "vfs.root.mountfrom=\"%s\"\n", "ufs:md0s0"); + + return pos; +} + +grub_err_t ventoy_cmd_unix_reset(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + g_unix_vlnk_boot = 0; + g_mod_search_magic = 0; + g_conf_new_len = 0; + g_mod_new_len = 0; + g_mod_override_offset = 0; + g_conf_override_offset = 0; + g_ko_fillmap_len = 0; + + check_free(g_mod_new_data, grub_free); + check_free(g_conf_new_data, grub_free); + check_free(g_ko_fillmap_data, grub_free); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_unix_check_vlnk(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_file_t file; + + (void)ctxt; + + if (argc != 1) + { + return 1; + } + + file = grub_file_open(args[0], VENTOY_FILE_TYPE); + if (file) + { + g_unix_vlnk_boot = file->vlnk; + grub_file_close(file); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_parse_freenas_ver(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_file_t file; + const char *ver = NULL; + char *buf = NULL; + VTOY_JSON *json = NULL; + + (void)ctxt; + (void)argc; + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + debug("Failed to open file %s\n", args[0]); + return 1; + } + + buf = grub_malloc(file->size + 2); + if (!buf) + { + grub_file_close(file); + return 0; + } + grub_file_read(file, buf, file->size); + buf[file->size] = 0; + + json = vtoy_json_create(); + if (!json) + { + goto end; + } + + if (vtoy_json_parse(json, buf)) + { + goto end; + } + + ver = vtoy_json_get_string_ex(json->pstChild, "Version"); + if (ver) + { + debug("NAS version:<%s>\n", ver); + if (grub_strncmp(ver, "TrueNAS-", 8) == 0) + { + ver += 8; + } + ventoy_set_env(args[1], ver); + } + else + { + debug("NAS version:<%s>\n", "NOT FOUND"); + grub_env_unset(args[1]); + } + +end: + grub_check_free(buf); + check_free(json, vtoy_json_destroy); + grub_file_close(file); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_unix_freebsd_ver(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_file_t file; + char *buf; + char *start = NULL; + char *nextline = NULL; + + (void)ctxt; + (void)argc; + (void)args; + + file = ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD, "%s", args[0]); + if (!file) + { + debug("Failed to open file %s\n", args[0]); + return 1; + } + + buf = grub_zalloc(file->size + 2); + if (!buf) + { + grub_file_close(file); + return 0; + } + grub_file_read(file, buf, file->size); + + for (start = buf; start; start = nextline) + { + if (grub_strncmp(start, "USERLAND_VERSION", 16) == 0) + { + nextline = start; + while (*nextline && *nextline != '\r' && *nextline != '\n') + { + nextline++; + } + + *nextline = 0; + break; + } + nextline = ventoy_get_line(start); + } + + if (start) + { + debug("freebsd version:<%s>\n", start); + ventoy_set_env(args[1], start); + } + else + { + debug("freebsd version:<%s>\n", "NOT FOUND"); + grub_env_unset(args[1]); + } + + grub_free(buf); + grub_file_close(file); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static int ventoy_freebsd_ver_elf(int bit64, grub_elf_t elf, const char *section, const char *env, char *data) +{ + int j = 0; + int k = 0; + int ret = 1; + char *str = NULL; + void *hdr = NULL; + grub_off_t offset = 0; + grub_uint32_t len = 0; + char ver[64] = {0}; + + if (bit64) + { + Elf64_Ehdr *e = &(elf->ehdr.ehdr64); + Elf64_Shdr *h; + Elf64_Shdr *s; + Elf64_Shdr *t; + Elf64_Half i; + + h = hdr = grub_zalloc(e->e_shnum * e->e_shentsize); + if (!h) + { + goto out; + } + + debug("read section header %u %u %u\n", e->e_shnum, e->e_shentsize, e->e_shstrndx); + grub_file_seek(elf->file, e->e_shoff); + grub_file_read(elf->file, h, e->e_shnum * e->e_shentsize); + + s = (Elf64_Shdr *)((char *)h + e->e_shstrndx * e->e_shentsize); + str = grub_malloc(s->sh_size + 1); + if (!str) + { + goto out; + } + str[s->sh_size] = 0; + + debug("read string table %u %u\n", (grub_uint32_t)s->sh_offset, (grub_uint32_t)s->sh_size); + grub_file_seek(elf->file, s->sh_offset); + grub_file_read(elf->file, str, s->sh_size); + + for (t = h, i = 0; i < e->e_shnum; i++) + { + if (grub_strcmp(str + t->sh_name, section) == 0) + { + offset = t->sh_offset; + len = t->sh_size; + debug("find %s section at %u %u\n", section, (grub_uint32_t)offset, len); + break; + } + t = (Elf64_Shdr *)((char *)t + e->e_shentsize); + } + } + else + { + Elf32_Ehdr *e = &(elf->ehdr.ehdr32); + Elf32_Shdr *h; + Elf32_Shdr *s; + Elf32_Shdr *t; + Elf32_Half i; + + h = hdr = grub_zalloc(e->e_shnum * e->e_shentsize); + if (!h) + { + goto out; + } + + debug("read section header %u %u %u\n", e->e_shnum, e->e_shentsize, e->e_shstrndx); + grub_file_seek(elf->file, e->e_shoff); + grub_file_read(elf->file, h, e->e_shnum * e->e_shentsize); + + s = (Elf32_Shdr *)((char *)h + e->e_shstrndx * e->e_shentsize); + str = grub_malloc(s->sh_size + 1); + if (!str) + { + goto out; + } + str[s->sh_size] = 0; + + debug("read string table %u %u\n", (grub_uint32_t)s->sh_offset, (grub_uint32_t)s->sh_size); + grub_file_seek(elf->file, s->sh_offset); + grub_file_read(elf->file, str, s->sh_size); + + for (t = h, i = 0; i < e->e_shnum; i++) + { + if (grub_strcmp(str + t->sh_name, section) == 0) + { + offset = t->sh_offset; + len = t->sh_size; + debug("find %s section at %u %u\n", section, (grub_uint32_t)offset, len); + break; + } + t = (Elf32_Shdr *)((char *)t + e->e_shentsize); + } + } + + if (offset == 0 || len == 0) + { + debug("%s section not found\n", section); + goto out; + } + + grub_file_seek(elf->file, offset + len - 8192); + grub_file_read(elf->file, data, 8192); + + for (j = 0; j < 8192 - 12; j++) + { + if (grub_strncmp(data + j, "@(#)FreeBSD ", 12) == 0) + { + for (k = j + 12; k < 8192; k++) + { + if (0 == grub_isdigit(data[k]) && data[k] != '.') + { + data[k] = 0; + break; + } + } + + grub_snprintf(ver, sizeof(ver), "%s", data + j + 12); + break; + } + } + + + if (ver[0]) + { + k = (int)grub_strtoul(ver, NULL, 10); + debug("%s freebsd version:<%s> <%d.x>\n", section, ver, k); + grub_snprintf(ver, sizeof(ver), "%d.x", k); + ventoy_set_env(env, ver); + ret = 0; + } + else + { + debug("%s freebsd version:<%s>\n", section, "NOT FOUND"); + ret = 1; + } + +out: + grub_check_free(str); + grub_check_free(hdr); + return ret; +} + +grub_err_t ventoy_cmd_unix_freebsd_ver_elf(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int ret = 0; + int bit64 = 0; + char *data = NULL; + grub_elf_t elf = NULL; + + (void)ctxt; + + if (argc != 3) + { + debug("Invalid argc %d\n", argc); + return 1; + } + + data = grub_zalloc(8192); + if (!data) + { + goto out; + } + + elf = grub_elf_open(args[0], GRUB_FILE_TYPE_LINUX_INITRD); + if (!elf) + { + debug("Failed to open file %s\n", args[0]); + goto out; + } + + bit64 = (args[1][0] == '6') ? 1 : 0; + + ret = ventoy_freebsd_ver_elf(bit64, elf, ".data", args[2], data); + if (ret != 0) + { + ret = ventoy_freebsd_ver_elf(bit64, elf, ".rodata", args[2], data); + } + +out: + grub_check_free(data); + check_free(elf, grub_elf_close); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_unix_replace_grub_conf(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int len = 0; + grub_uint32_t i; + char *data; + char *pos; + const char *val = NULL; + grub_uint64_t offset; + grub_file_t file; + char extcfg[512]; + const char *confile = NULL; + const char * loader_conf[] = + { + "/boot/grub/grub.cfg", + }; + + (void)ctxt; + + if (argc != 1 && argc != 2) + { + debug("Replace conf invalid argc %d\n", argc); + return 1; + } + + for (i = 0; i < sizeof(loader_conf) / sizeof(loader_conf[0]); i++) + { + if (ventoy_get_file_override(loader_conf[i], &offset) == 0) + { + confile = loader_conf[i]; + g_conf_override_offset = offset; + break; + } + } + + if (confile == NULL) + { + debug("Can't find grub.cfg file from %u locations\n", i); + return 1; + } + + file = ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD, "(loop)/%s", confile); + if (!file) + { + debug("Failed to open %s \n", confile); + return 1; + } + + debug("old grub2 conf file size:%d\n", (int)file->size); + + data = grub_malloc(VTOY_MAX_SCRIPT_BUF); + if (!data) + { + grub_file_close(file); + return 1; + } + + grub_file_read(file, data, file->size); + grub_file_close(file); + + g_conf_new_data = data; + g_conf_new_len = (int)file->size; + + pos = grub_strstr(data, "kfreebsd /boot/kernel/kernel"); + if (pos) + { + pos += grub_strlen("kfreebsd /boot/kernel/kernel"); + if (grub_strncmp(pos, ".gz", 3) == 0) + { + pos += 3; + } + + if (argc == 2) + { + vtoy_ssprintf(extcfg, len, ";kfreebsd_module_elf %s; set kFreeBSD.hint.ventoy.0.alias=\"%s\"", args[0], args[1]); + } + else + { + vtoy_ssprintf(extcfg, len, ";kfreebsd_module_elf %s", args[0]); + } + + if (g_unix_vlnk_boot) + { + vtoy_ssprintf(extcfg, len, ";set kFreeBSD.hint.ventoy.0.vlnk=%d", 1); + } + + val = ventoy_get_env("VTOY_UNIX_REMOUNT"); + if (val && val[0] == '1' && val[1] == 0) + { + vtoy_ssprintf(extcfg, len, ";set kFreeBSD.hint.ventoy.0.remount=%d", 1); + } + + grub_memmove(pos + len, pos, (int)(file->size - (pos - data))); + grub_memcpy(pos, extcfg, len); + g_conf_new_len += len; + } + else + { + debug("no kfreebsd found\n"); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_unix_replace_conf(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_uint32_t i; + char *data; + grub_uint64_t offset; + grub_file_t file; + const char *confile = NULL; + const char * loader_conf[] = + { + "/boot/loader.conf", + "/boot/defaults/loader.conf", + }; + + (void)ctxt; + + if (argc != 2 && argc != 3) + { + debug("Replace conf invalid argc %d\n", argc); + return 1; + } + + for (i = 0; i < sizeof(loader_conf) / sizeof(loader_conf[0]); i++) + { + if (ventoy_get_file_override(loader_conf[i], &offset) == 0) + { + confile = loader_conf[i]; + g_conf_override_offset = offset; + break; + } + } + + if (confile == NULL) + { + debug("Can't find loader.conf file from %u locations\n", i); + return 1; + } + + file = ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD, "(loop)/%s", confile); + if (!file) + { + debug("Failed to open %s \n", confile); + return 1; + } + + debug("old conf file <%s> size:%d\n", confile, (int)file->size); + + data = grub_malloc(VTOY_MAX_SCRIPT_BUF); + if (!data) + { + grub_file_close(file); + return 1; + } + + grub_file_read(file, data, file->size); + grub_file_close(file); + + g_conf_new_data = data; + g_conf_new_len = (int)file->size; + + if (grub_strcmp(args[0], "FreeBSD") == 0) + { + g_conf_new_len += ventoy_freebsd_append_conf(data + file->size, args[1], (argc > 2) ? args[2] : NULL); + } + else if (grub_strcmp(args[0], "DragonFly") == 0) + { + g_conf_new_len += ventoy_dragonfly_append_conf(data + file->size, args[1]); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static int ventoy_unix_search_magic(char *data, int len) +{ + int i; + grub_uint32_t *magic = NULL; + + for (i = 0; i < len; i += 4096) + { + magic = (grub_uint32_t *)(data + i); + if (magic[0] == VENTOY_UNIX_SEG_MAGIC0 && magic[1] == VENTOY_UNIX_SEG_MAGIC1 && + magic[2] == VENTOY_UNIX_SEG_MAGIC2 && magic[3] == VENTOY_UNIX_SEG_MAGIC3) + { + debug("unix find search magic at 0x%x loop:%d\n", i, (i >> 12)); + g_mod_search_magic = i; + return 0; + } + } + + debug("unix can not find search magic\n"); + return 1; +} + +grub_err_t ventoy_cmd_unix_replace_ko(grub_extcmd_context_t ctxt, int argc, char **args) +{ + char *data; + grub_uint64_t offset; + grub_file_t file; + + (void)ctxt; + + if (argc != 2) + { + debug("Replace ko invalid argc %d\n", argc); + return 1; + } + + debug("replace ko %s\n", args[0]); + + if (ventoy_get_file_override(args[0], &offset) == 0) + { + grub_snprintf(g_ko_mod_path, sizeof(g_ko_mod_path), "%s", args[0]); + g_mod_override_offset = offset; + } + else + { + debug("Can't find replace ko file from %s\n", args[0]); + return 1; + } + + file = ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD, "%s", args[1]); + if (!file) + { + debug("Failed to open %s \n", args[1]); + return 1; + } + + debug("new ko file size:%d\n", (int)file->size); + + data = grub_malloc(file->size); + if (!data) + { + debug("Failed to alloc memory for new ko %d\n", (int)file->size); + grub_file_close(file); + return 1; + } + + grub_file_read(file, data, file->size); + grub_file_close(file); + + g_mod_new_data = data; + g_mod_new_len = (int)file->size; + + ventoy_unix_search_magic(g_mod_new_data, g_mod_new_len); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_unix_ko_fillmap(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + grub_file_t file; + grub_uint32_t magic[4]; + grub_uint32_t len; + + (void)ctxt; + + if (argc != 1) + { + debug("Fillmap ko invalid argc %d\n", argc); + return 1; + } + + debug("Fillmap ko %s\n", args[0]); + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(loop)%s", args[0]); + if (file) + { + grub_file_read(file, magic, 4); /* read for trigger */ + g_mod_override_offset = grub_iso9660_get_last_read_pos(file); + } + else + { + debug("Can't find replace ko file from %s\n", args[0]); + return 1; + } + + for (i = 0; i < (int)(file->size); i += 65536) + { + magic[0] = 0; + grub_file_seek(file, i); + grub_file_read(file, magic, sizeof(magic)); + + if (magic[0] == VENTOY_UNIX_SEG_MAGIC0 && magic[1] == VENTOY_UNIX_SEG_MAGIC1 && + magic[2] == VENTOY_UNIX_SEG_MAGIC2 && magic[3] == VENTOY_UNIX_SEG_MAGIC3) + { + debug("unix find search magic at 0x%x loop:%d\n", i, (i >> 16)); + g_mod_override_offset += i; + break; + } + } + + len = (grub_uint32_t)OFFSET_OF(struct g_ventoy_map, seglist) + + (sizeof(struct g_ventoy_seg) * g_img_chunk_list.cur_chunk); + + g_ko_fillmap_len = (int)len; + g_ko_fillmap_data = grub_malloc(len); + if (!g_ko_fillmap_data) + { + g_ko_fillmap_len = 0; + debug("Failed to malloc fillmap data\n"); + } + + debug("Fillmap ko segnum:%u, override len:%u data:%p\n", g_img_chunk_list.cur_chunk, len, g_ko_fillmap_data); + + grub_file_close(file); + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_unix_fill_image_desc(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + grub_uint8_t *byte; + grub_uint32_t memsize; + ventoy_image_desc *desc; + grub_uint8_t flag[32] = { + 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF + }; + + (void)ctxt; + (void)argc; + (void)args; + + debug("ventoy_cmd_unix_fill_image_desc %p\n", g_mod_new_data); + + if (!g_mod_new_data) + { + goto end; + } + + byte = (grub_uint8_t *)g_mod_new_data; + for (i = 0; i < g_mod_new_len - 32; i += 16) + { + if (byte[i] == 0xFF && byte[i + 1] == 0xEE) + { + if (grub_memcmp(flag, byte + i, 32) == 0) + { + debug("Find position flag at %d(0x%x)\n", i, i); + break; + } + } + } + + if (i >= g_mod_new_len - 32) + { + debug("Failed to find position flag %d\n", i); + goto end; + } + + desc = (ventoy_image_desc *)(byte + i); + desc->disk_size = g_ventoy_disk_size; + desc->part1_size = g_ventoy_disk_part_size[0]; + grub_memcpy(desc->disk_uuid, g_ventoy_part_info->MBR.BootCode + 0x180, 16); + grub_memcpy(desc->disk_signature, g_ventoy_part_info->MBR.BootCode + 0x1B8, 4); + + desc->img_chunk_count = g_img_chunk_list.cur_chunk; + memsize = g_img_chunk_list.cur_chunk * sizeof(ventoy_img_chunk); + + debug("image chunk count:%u memsize:%u\n", desc->img_chunk_count, memsize); + + if (memsize >= VTOY_SIZE_1MB * 8) + { + grub_printf("image chunk count:%u memsize:%u too big\n", desc->img_chunk_count, memsize); + goto end; + } + + grub_memcpy(desc + 1, g_img_chunk_list.chunk, memsize); + +end: + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_unix_gzip_newko(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int newlen; + grub_uint8_t *buf; + + (void)ctxt; + (void)argc; + (void)args; + + debug("ventoy_cmd_unix_gzip_newko %p\n", g_mod_new_data); + + if (!g_mod_new_data) + { + goto end; + } + + buf = grub_malloc(g_mod_new_len); + if (!buf) + { + goto end; + } + + newlen = ventoy_gzip_compress(g_mod_new_data, g_mod_new_len, buf, g_mod_new_len); + + grub_free(g_mod_new_data); + + debug("gzip org len:%d newlen:%d\n", g_mod_new_len, newlen); + + g_mod_new_data = (char *)buf; + g_mod_new_len = newlen; + +end: + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_unix_chain_data(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int ventoy_compatible = 0; + grub_uint32_t size = 0; + grub_uint64_t isosize = 0; + grub_uint32_t boot_catlog = 0; + grub_uint32_t img_chunk_size = 0; + grub_uint32_t override_count = 0; + grub_uint32_t override_size = 0; + grub_uint32_t virt_chunk_size = 0; + grub_file_t file; + grub_disk_t disk; + const char *pLastChain = NULL; + const char *compatible; + ventoy_chain_head *chain; + + (void)ctxt; + (void)argc; + + compatible = grub_env_get("ventoy_compatible"); + if (compatible && compatible[0] == 'Y') + { + ventoy_compatible = 1; + } + + if (NULL == g_img_chunk_list.chunk) + { + grub_printf("ventoy not ready\n"); + return 1; + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + return 1; + } + + isosize = file->size; + + boot_catlog = ventoy_get_iso_boot_catlog(file); + if (boot_catlog) + { + if (ventoy_is_efi_os() && (!ventoy_has_efi_eltorito(file, boot_catlog))) + { + grub_env_set("LoadIsoEfiDriver", "on"); + } + } + else + { + if (ventoy_is_efi_os()) + { + grub_env_set("LoadIsoEfiDriver", "on"); + } + else + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "File %s is not bootable", args[0]); + } + } + + img_chunk_size = g_img_chunk_list.cur_chunk * sizeof(ventoy_img_chunk); + + if (ventoy_compatible) + { + size = sizeof(ventoy_chain_head) + img_chunk_size; + } + else + { + override_count = ventoy_unix_get_override_chunk_count(); + override_size = override_count * sizeof(ventoy_override_chunk); + + virt_chunk_size = ventoy_unix_get_virt_chunk_size(); + size = sizeof(ventoy_chain_head) + img_chunk_size + override_size + virt_chunk_size; + } + + pLastChain = grub_env_get("vtoy_chain_mem_addr"); + if (pLastChain) + { + chain = (ventoy_chain_head *)grub_strtoul(pLastChain, NULL, 16); + if (chain) + { + debug("free last chain memory %p\n", chain); + grub_free(chain); + } + } + + chain = ventoy_alloc_chain(size); + if (!chain) + { + grub_printf("Failed to alloc chain unix memory size %u\n", size); + grub_file_close(file); + return 1; + } + + ventoy_memfile_env_set("vtoy_chain_mem", chain, (ulonglong)size); + + grub_memset(chain, 0, sizeof(ventoy_chain_head)); + + /* part 1: os parameter */ + g_ventoy_chain_type = ventoy_chain_linux; + ventoy_fill_os_param(file, &(chain->os_param)); + + /* part 2: chain head */ + disk = file->device->disk; + chain->disk_drive = disk->id; + chain->disk_sector_size = (1 << disk->log_sector_size); + chain->real_img_size_in_bytes = file->size; + chain->virt_img_size_in_bytes = (file->size + 2047) / 2048 * 2048; + chain->boot_catalog = boot_catlog; + + if (!ventoy_is_efi_os()) + { + grub_file_seek(file, boot_catlog * 2048); + grub_file_read(file, chain->boot_catalog_sector, sizeof(chain->boot_catalog_sector)); + } + + /* part 3: image chunk */ + chain->img_chunk_offset = sizeof(ventoy_chain_head); + chain->img_chunk_num = g_img_chunk_list.cur_chunk; + grub_memcpy((char *)chain + chain->img_chunk_offset, g_img_chunk_list.chunk, img_chunk_size); + + if (ventoy_compatible) + { + return 0; + } + + /* part 4: override chunk */ + chain->override_chunk_offset = chain->img_chunk_offset + img_chunk_size; + chain->override_chunk_num = override_count; + ventoy_unix_fill_override_data(isosize, chain); + + /* part 5: virt chunk */ + chain->virt_chunk_offset = chain->override_chunk_offset + override_size; + chain->virt_chunk_num = ventoy_unix_get_virt_chunk_count(); + ventoy_unix_fill_virt_data(isosize, chain); + + grub_file_close(file); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_vhd.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_vhd.c new file mode 100644 index 0000000..c5839c2 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_vhd.c @@ -0,0 +1,754 @@ +/****************************************************************************** + * ventoy_vhd.c + * + * Copyright (c) 2020, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef GRUB_MACHINE_EFI +#include +#endif +#include +#include "ventoy_def.h" + +GRUB_MOD_LICENSE ("GPLv3+"); + +static int g_vhdboot_isolen = 0; +static char *g_vhdboot_totbuf = NULL; +static char *g_vhdboot_isobuf = NULL; +static grub_uint64_t g_img_trim_head_secnum = 0; + +static int ventoy_vhd_find_bcd(int *bcdoffset, int *bcdlen, const char *path) +{ + grub_uint32_t offset; + grub_file_t file; + char cmdbuf[128]; + + grub_snprintf(cmdbuf, sizeof(cmdbuf), "loopback vhdiso mem:0x%lx:size:%d", (ulong)g_vhdboot_isobuf, g_vhdboot_isolen); + + grub_script_execute_sourcecode(cmdbuf); + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(vhdiso)%s", path); + if (!file) + { + return 1; + } + + grub_file_read(file, &offset, 4); + offset = (grub_uint32_t)grub_iso9660_get_last_read_pos(file); + + *bcdoffset = (int)offset; + *bcdlen = (int)file->size; + + debug("vhdiso bcd file offset:%d len:%d\n", *bcdoffset, *bcdlen); + + grub_file_close(file); + + grub_script_execute_sourcecode("loopback -d vhdiso"); + + return 0; +} + +static int ventoy_vhd_patch_path(char *vhdpath, ventoy_patch_vhd *patch1, ventoy_patch_vhd *patch2, + int bcdoffset, int bcdlen) +{ + int i; + int cnt = 0; + char *pos; + grub_size_t pathlen; + const char *plat; + char *newpath = NULL; + grub_uint16_t *unicode_path; + const grub_uint8_t winloadexe[] = + { + 0x77, 0x00, 0x69, 0x00, 0x6E, 0x00, 0x6C, 0x00, 0x6F, 0x00, 0x61, 0x00, 0x64, 0x00, 0x2E, 0x00, + 0x65, 0x00, 0x78, 0x00, 0x65, 0x00 + }; + + while ((*vhdpath) != '/') + { + vhdpath++; + } + + pathlen = sizeof(grub_uint16_t) * (grub_strlen(vhdpath) + 1); + debug("unicode path for <%s> len:%d\n", vhdpath, (int)pathlen); + + unicode_path = grub_zalloc(pathlen); + if (!unicode_path) + { + return 0; + } + + plat = grub_env_get("grub_platform"); + + if (plat && (plat[0] == 'e')) /* UEFI */ + { + pos = g_vhdboot_isobuf + bcdoffset; + + /* winload.exe ==> winload.efi */ + for (i = 0; i + (int)sizeof(winloadexe) < bcdlen; i++) + { + if (*((grub_uint32_t *)(pos + i)) == 0x00690077 && + grub_memcmp(pos + i, winloadexe, sizeof(winloadexe)) == 0) + { + pos[i + sizeof(winloadexe) - 4] = 0x66; + pos[i + sizeof(winloadexe) - 2] = 0x69; + cnt++; + } + } + + debug("winload patch %d times\n", cnt); + } + + newpath = grub_strdup(vhdpath); + for (pos = newpath; *pos; pos++) + { + if (*pos == '/') + { + *pos = '\\'; + } + } + + grub_utf8_to_utf16(unicode_path, pathlen, (grub_uint8_t *)newpath, -1, NULL); + grub_memcpy(patch1->vhd_file_path, unicode_path, pathlen); + grub_memcpy(patch2->vhd_file_path, unicode_path, pathlen); + + grub_free(newpath); + return 0; +} + +static int ventoy_vhd_read_parttbl(const char *filename, ventoy_gpt_info *gpt, int *index, grub_uint64_t *poffset) +{ + int i; + int find = 0; + int ret = 1; + grub_uint64_t start; + grub_file_t file = NULL; + grub_disk_t disk = NULL; + grub_uint8_t zeroguid[16] = {0}; + + file = grub_file_open(filename, VENTOY_FILE_TYPE); + if (!file) + { + goto end; + } + + disk = grub_disk_open(file->device->disk->name); + if (!disk) + { + goto end; + } + + grub_disk_read(disk, 0, 0, sizeof(ventoy_gpt_info), gpt); + + start = file->device->disk->partition->start; + + if (grub_memcmp(gpt->Head.Signature, "EFI PART", 8) == 0) + { + debug("GPT part start: %llu\n", (ulonglong)start); + for (i = 0; i < 128; i++) + { + if (grub_memcmp(gpt->PartTbl[i].PartGuid, zeroguid, 16)) + { + if (start == gpt->PartTbl[i].StartLBA) + { + *index = i; + find = 1; + break; + } + } + } + } + else + { + debug("MBR part start: %llu\n", (ulonglong)start); + for (i = 0; i < 4; i++) + { + if ((grub_uint32_t)start == gpt->MBR.PartTbl[i].StartSectorId) + { + *index = i; + find = 1; + break; + } + } + } + + if (find == 0) // MBR Logical partition + { + if (file->device->disk->partition->number > 0) + { + *index = file->device->disk->partition->number; + debug("Fall back part number: %d\n", *index); + } + } + + *poffset = start; + ret = 0; + +end: + check_free(file, grub_file_close); + check_free(disk, grub_disk_close); + + return ret; +} + +static int ventoy_vhd_patch_disk(const char *vhdpath, ventoy_patch_vhd *patch1, ventoy_patch_vhd *patch2) +{ + int partIndex = 0; + grub_uint64_t offset = 0; + char efipart[16] = {0}; + ventoy_gpt_info *gpt = NULL; + + if (vhdpath[0] == '/') + { + gpt = g_ventoy_part_info; + partIndex = 0; + debug("This is Ventoy ISO partIndex %d %s\n", partIndex, vhdpath); + } + else + { + gpt = grub_zalloc(sizeof(ventoy_gpt_info)); + ventoy_vhd_read_parttbl(vhdpath, gpt, &partIndex, &offset); + debug("This is HDD partIndex %d %s\n", partIndex, vhdpath); + } + + grub_memcpy(efipart, gpt->Head.Signature, sizeof(gpt->Head.Signature)); + + grub_memset(patch1, 0, OFFSET_OF(ventoy_patch_vhd, vhd_file_path)); + grub_memset(patch2, 0, OFFSET_OF(ventoy_patch_vhd, vhd_file_path)); + + if (grub_strncmp(efipart, "EFI PART", 8) == 0) + { + ventoy_debug_dump_guid("GPT disk GUID: ", gpt->Head.DiskGuid); + ventoy_debug_dump_guid("GPT partIndex GUID: ", gpt->PartTbl[partIndex].PartGuid); + + grub_memcpy(patch1->disk_signature_or_guid, gpt->Head.DiskGuid, 16); + grub_memcpy(patch1->part_offset_or_guid, gpt->PartTbl[partIndex].PartGuid, 16); + grub_memcpy(patch2->disk_signature_or_guid, gpt->Head.DiskGuid, 16); + grub_memcpy(patch2->part_offset_or_guid, gpt->PartTbl[partIndex].PartGuid, 16); + + patch1->part_type = patch2->part_type = 0; + } + else + { + if (offset == 0) + { + offset = gpt->MBR.PartTbl[partIndex].StartSectorId; + } + offset *= 512; + debug("MBR disk signature: %02x%02x%02x%02x Part(%d) offset:%llu\n", + gpt->MBR.BootCode[0x1b8 + 0], gpt->MBR.BootCode[0x1b8 + 1], + gpt->MBR.BootCode[0x1b8 + 2], gpt->MBR.BootCode[0x1b8 + 3], + partIndex + 1, offset); + + grub_memcpy(patch1->part_offset_or_guid, &offset, 8); + grub_memcpy(patch2->part_offset_or_guid, &offset, 8); + + grub_memcpy(patch1->disk_signature_or_guid, gpt->MBR.BootCode + 0x1b8, 4); + grub_memcpy(patch2->disk_signature_or_guid, gpt->MBR.BootCode + 0x1b8, 4); + + patch1->part_type = patch2->part_type = 1; + } + + if (gpt != g_ventoy_part_info) + { + grub_free(gpt); + } + + return 0; +} + +static int ventoy_find_vhdpatch_offset(int bcdoffset, int bcdlen, int *offset) +{ + int i; + int cnt = 0; + grub_uint8_t *buf = (grub_uint8_t *)(g_vhdboot_isobuf + bcdoffset); + grub_uint8_t magic[16] = { + 0x5C, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00 + }; + + for (i = 0; i < bcdlen - 16 && cnt < 2; i++) + { + if (*(grub_uint32_t *)(buf + i) == 0x0058005C) + { + if (grub_memcmp(magic, buf + i, 16) == 0) + { + *offset++ = i - (int)OFFSET_OF(ventoy_patch_vhd, vhd_file_path); + cnt++; + } + } + } + + return 0; +} + +grub_err_t ventoy_cmd_patch_vhdboot(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int rc; + int bcdoffset, bcdlen; + int patchoffset[2]; + ventoy_patch_vhd *patch1; + ventoy_patch_vhd *patch2; + + (void)ctxt; + (void)argc; + + grub_env_unset("vtoy_vhd_buf_addr"); + + debug("patch vhd <%s>\n", args[0]); + + if ((!g_vhdboot_enable) || (!g_vhdboot_totbuf)) + { + debug("vhd boot not ready %d %p\n", g_vhdboot_enable, g_vhdboot_totbuf); + return 0; + } + + rc = ventoy_vhd_find_bcd(&bcdoffset, &bcdlen, "/boot/bcd"); + if (rc) + { + debug("failed to get bcd location %d\n", rc); + } + else + { + ventoy_find_vhdpatch_offset(bcdoffset, bcdlen, patchoffset); + patch1 = (ventoy_patch_vhd *)(g_vhdboot_isobuf + bcdoffset + patchoffset[0]); + patch2 = (ventoy_patch_vhd *)(g_vhdboot_isobuf + bcdoffset + patchoffset[1]); + + debug("Find /boot/bcd (%d %d) now patch it (offset: 0x%x 0x%x) ...\n", + bcdoffset, bcdlen, patchoffset[0], patchoffset[1]); + ventoy_vhd_patch_disk(args[0], patch1, patch2); + ventoy_vhd_patch_path(args[0], patch1, patch2, bcdoffset, bcdlen); + } + + rc = ventoy_vhd_find_bcd(&bcdoffset, &bcdlen, "/boot/BCD"); + if (rc) + { + debug("No file /boot/BCD \n"); + } + else + { + ventoy_find_vhdpatch_offset(bcdoffset, bcdlen, patchoffset); + patch1 = (ventoy_patch_vhd *)(g_vhdboot_isobuf + bcdoffset + patchoffset[0]); + patch2 = (ventoy_patch_vhd *)(g_vhdboot_isobuf + bcdoffset + patchoffset[1]); + + debug("Find /boot/BCD (%d %d) now patch it (offset: 0x%x 0x%x) ...\n", + bcdoffset, bcdlen, patchoffset[0], patchoffset[1]); + ventoy_vhd_patch_disk(args[0], patch1, patch2); + ventoy_vhd_patch_path(args[0], patch1, patch2, bcdoffset, bcdlen); + } + + /* set buffer and size */ +#ifdef GRUB_MACHINE_EFI + ventoy_memfile_env_set("vtoy_vhd_buf", g_vhdboot_totbuf, (ulonglong)(g_vhdboot_isolen + sizeof(ventoy_chain_head))); +#else + ventoy_memfile_env_set("vtoy_vhd_buf", g_vhdboot_isobuf, (ulonglong)g_vhdboot_isolen); +#endif + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_load_vhdboot(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int buflen; + grub_file_t file; + + (void)ctxt; + (void)argc; + + g_vhdboot_enable = 0; + grub_check_free(g_vhdboot_totbuf); + + file = grub_file_open(args[0], VENTOY_FILE_TYPE); + if (!file) + { + return 0; + } + + debug("load vhd boot: <%s> <%lu>\n", args[0], (ulong)file->size); + + if (file->size < VTOY_SIZE_1KB * 32) + { + grub_file_close(file); + return 0; + } + + g_vhdboot_isolen = (int)file->size; + + buflen = (int)(file->size + sizeof(ventoy_chain_head)); + +#ifdef GRUB_MACHINE_EFI + g_vhdboot_totbuf = (char *)grub_efi_allocate_iso_buf(buflen); +#else + g_vhdboot_totbuf = (char *)grub_malloc(buflen); +#endif + + if (!g_vhdboot_totbuf) + { + grub_file_close(file); + return 0; + } + + g_vhdboot_isobuf = g_vhdboot_totbuf + sizeof(ventoy_chain_head); + + grub_file_read(file, g_vhdboot_isobuf, file->size); + grub_file_close(file); + + g_vhdboot_enable = 1; + + return 0; +} + +static int ventoy_raw_trim_head(grub_uint64_t offset) +{ + grub_uint32_t i; + grub_uint32_t memsize; + grub_uint32_t imgstart = 0; + grub_uint32_t imgsecs = 0; + grub_uint64_t sectors = 0; + grub_uint64_t cursecs = 0; + grub_uint64_t delta = 0; + + if ((!g_img_chunk_list.chunk) || (!offset)) + { + debug("image chunk not ready %p %lu\n", g_img_chunk_list.chunk, (ulong)offset); + return 0; + } + + debug("image trim head %lu\n", (ulong)offset); + + for (i = 0; i < g_img_chunk_list.cur_chunk; i++) + { + cursecs = g_img_chunk_list.chunk[i].disk_end_sector + 1 - g_img_chunk_list.chunk[i].disk_start_sector; + sectors += cursecs; + if (sectors >= offset) + { + delta = cursecs - (sectors - offset); + break; + } + } + + if (sectors < offset || i >= g_img_chunk_list.cur_chunk) + { + debug("Invalid size %lu %lu\n", (ulong)sectors, (ulong)offset); + return 0; + } + + if (sectors == offset) + { + memsize = (g_img_chunk_list.cur_chunk - (i + 1)) * sizeof(ventoy_img_chunk); + grub_memmove(g_img_chunk_list.chunk, g_img_chunk_list.chunk + i + 1, memsize); + g_img_chunk_list.cur_chunk -= (i + 1); + } + else + { + g_img_chunk_list.chunk[i].disk_start_sector += delta; + g_img_chunk_list.chunk[i].img_start_sector += (grub_uint32_t)(delta / 4); + + if (i > 0) + { + memsize = (g_img_chunk_list.cur_chunk - i) * sizeof(ventoy_img_chunk); + grub_memmove(g_img_chunk_list.chunk, g_img_chunk_list.chunk + i, memsize); + g_img_chunk_list.cur_chunk -= i; + } + } + + for (i = 0; i < g_img_chunk_list.cur_chunk; i++) + { + imgsecs = g_img_chunk_list.chunk[i].img_end_sector + 1 - g_img_chunk_list.chunk[i].img_start_sector; + g_img_chunk_list.chunk[i].img_start_sector = imgstart; + g_img_chunk_list.chunk[i].img_end_sector = imgstart + (imgsecs - 1); + imgstart += imgsecs; + } + + return 0; +} + +grub_err_t ventoy_cmd_get_vtoy_type(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + int altboot = 0; + int offset = -1; + grub_file_t file; + grub_uint8_t data = 0; + vhd_footer_t vhdfoot; + VDIPREHEADER vdihdr; + char type[16] = {0}; + ventoy_gpt_info *gpt = NULL; + + (void)ctxt; + + g_img_trim_head_secnum = 0; + + if (argc != 4) + { + return 0; + } + + file = grub_file_open(args[0], VENTOY_FILE_TYPE); + if (!file) + { + debug("Failed to open file %s\n", args[0]); + return 0; + } + + grub_snprintf(type, sizeof(type), "unknown"); + + grub_file_seek(file, file->size - 512); + grub_file_read(file, &vhdfoot, sizeof(vhdfoot)); + + if (grub_strncmp(vhdfoot.cookie, "conectix", 8) == 0) + { + offset = 0; + grub_snprintf(type, sizeof(type), "vhd%u", grub_swap_bytes32(vhdfoot.disktype)); + } + else + { + grub_file_seek(file, 0); + grub_file_read(file, &vdihdr, sizeof(vdihdr)); + if (vdihdr.u32Signature == VDI_IMAGE_SIGNATURE) + { + grub_snprintf(type, sizeof(type), "vdi"); + if (grub_strncmp(vdihdr.szFileInfo, VDI_IMAGE_FILE_INFO, grub_strlen(VDI_IMAGE_FILE_INFO)) == 0) + { + offset = 2 * 1048576; + g_img_trim_head_secnum = offset / 512; + debug("VDI V1\n"); + } + else if (grub_strncmp(vdihdr.szFileInfo, VDI_IMAGE_FILE_INFO2, grub_strlen(VDI_IMAGE_FILE_INFO2)) == 0) + { + offset = 2 * 1048576; + g_img_trim_head_secnum = offset / 512; + debug("VDI V2\n"); + } + else + { + debug("invalid file info <%s>\n", vdihdr.szFileInfo); + } + } + else + { + offset = 0; + grub_snprintf(type, sizeof(type), "raw"); + } + } + + grub_env_set(args[1], type); + debug("<%s> vtoy type: <%s> offset:%d\n", args[0], type, offset); + + if (offset >= 0) + { + gpt = grub_zalloc(sizeof(ventoy_gpt_info)); + if (!gpt) + { + grub_env_set(args[1], "unknown"); + goto end; + } + + grub_file_seek(file, offset); + grub_file_read(file, gpt, sizeof(ventoy_gpt_info)); + + if (gpt->MBR.Byte55 != 0x55 || gpt->MBR.ByteAA != 0xAA) + { + grub_env_set(args[1], "unknown"); + debug("invalid mbr signature: 0x%x 0x%x offset=%d\n", gpt->MBR.Byte55, gpt->MBR.ByteAA, offset); + goto end; + } + + if (grub_memcmp(gpt->Head.Signature, "EFI PART", 8) == 0) + { + grub_env_set(args[2], "gpt"); + debug("part type: %s\n", "GPT"); + + if (gpt->MBR.PartTbl[0].FsFlag == 0xEE) + { + for (i = 0; i < 128; i++) + { + if (grub_memcmp(gpt->PartTbl[i].PartType, "Hah!IdontNeedEFI", 16) == 0) + { + debug("part %d is grub_bios part\n", i); + altboot = 1; + grub_env_set(args[3], "1"); + break; + } + else if (gpt->PartTbl[i].LastLBA == 0) + { + break; + } + } + } + + if (!altboot) + { + if (gpt->MBR.BootCode[92] == 0x22) + { + grub_file_seek(file, offset + 17908); + grub_file_read(file, &data, 1); + if (data == 0x23) + { + altboot = 1; + grub_env_set(args[3], "1"); + } + else + { + debug("offset data=0x%x\n", data); + } + } + else + { + debug("BootCode: 0x%x\n", gpt->MBR.BootCode[92]); + } + } + } + else + { + grub_env_set(args[2], "mbr"); + debug("part type: %s\n", "MBR"); + + for (i = 0; i < 4; i++) + { + if (gpt->MBR.PartTbl[i].FsFlag == 0xEF) + { + debug("part %d is esp part in MBR mode\n", i); + altboot = 1; + grub_env_set(args[3], "1"); + break; + } + } + } + } + else + { + debug("part type: %s\n", "xxx"); + } + +end: + grub_check_free(gpt); + grub_file_close(file); + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_raw_chain_data(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_uint32_t size = 0; + grub_uint32_t img_chunk_size = 0; + grub_file_t file; + grub_disk_t disk; + const char *pLastChain = NULL; + ventoy_chain_head *chain; + + (void)ctxt; + (void)argc; + + if (NULL == g_img_chunk_list.chunk) + { + grub_printf("ventoy not ready\n"); + return 1; + } + + if (g_img_trim_head_secnum > 0) + { + ventoy_raw_trim_head(g_img_trim_head_secnum); + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + return 1; + } + + if (grub_strncmp(args[0], g_iso_path, grub_strlen(g_iso_path))) + { + file->vlnk = 1; + } + + img_chunk_size = g_img_chunk_list.cur_chunk * sizeof(ventoy_img_chunk); + + size = sizeof(ventoy_chain_head) + img_chunk_size; + + pLastChain = grub_env_get("vtoy_chain_mem_addr"); + if (pLastChain) + { + chain = (ventoy_chain_head *)grub_strtoul(pLastChain, NULL, 16); + if (chain) + { + debug("free last chain memory %p\n", chain); + grub_free(chain); + } + } + + chain = ventoy_alloc_chain(size); + if (!chain) + { + grub_printf("Failed to alloc chain raw memory size %u\n", size); + grub_file_close(file); + return 1; + } + + ventoy_memfile_env_set("vtoy_chain_mem", chain, (ulonglong)size); + + grub_env_export("vtoy_chain_mem_addr"); + grub_env_export("vtoy_chain_mem_size"); + + grub_memset(chain, 0, sizeof(ventoy_chain_head)); + + /* part 1: os parameter */ + g_ventoy_chain_type = ventoy_chain_linux; + ventoy_fill_os_param(file, &(chain->os_param)); + + /* part 2: chain head */ + disk = file->device->disk; + chain->disk_drive = disk->id; + chain->disk_sector_size = (1 << disk->log_sector_size); + + chain->real_img_size_in_bytes = file->size; + if (g_img_trim_head_secnum > 0) + { + chain->real_img_size_in_bytes -= g_img_trim_head_secnum * 512; + } + + chain->virt_img_size_in_bytes = chain->real_img_size_in_bytes; + chain->boot_catalog = 0; + + /* part 3: image chunk */ + chain->img_chunk_offset = sizeof(ventoy_chain_head); + chain->img_chunk_num = g_img_chunk_list.cur_chunk; + grub_memcpy((char *)chain + chain->img_chunk_offset, g_img_chunk_list.chunk, img_chunk_size); + + grub_file_seek(file, g_img_trim_head_secnum * 512); + grub_file_read(file, chain->boot_catalog_sector, 512); + + grub_file_close(file); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_windows.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_windows.c new file mode 100644 index 0000000..6a47ad9 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_windows.c @@ -0,0 +1,2781 @@ +/****************************************************************************** + * ventoy_windows.c + * + * Copyright (c) 2020, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ventoy_def.h" + +GRUB_MOD_LICENSE ("GPLv3+"); + +static int g_iso_fs_type = 0; +static int g_wim_total_patch_count = 0; +static int g_wim_valid_patch_count = 0; +static wim_patch *g_wim_patch_head = NULL; + +static grub_uint64_t g_suppress_wincd_override_offset = 0; +static grub_uint32_t g_suppress_wincd_override_data = 0; + +grub_uint8_t g_temp_buf[512]; + +grub_ssize_t lzx_decompress ( const void *data, grub_size_t len, void *buf ); +grub_ssize_t xca_decompress ( const void *data, grub_size_t len, void *buf ); + +static wim_patch *ventoy_find_wim_patch(const char *path) +{ + int len = (int)grub_strlen(path); + wim_patch *node = g_wim_patch_head; + + while (node) + { + if (len == node->pathlen && 0 == grub_strcmp(path, node->path)) + { + return node; + } + node = node->next; + } + + return NULL; +} + +static int ventoy_collect_wim_patch(const char *bcdfile) +{ + int i, j, k; + int rc = 1; + grub_uint64_t magic; + grub_file_t file = NULL; + char *buf = NULL; + wim_patch *node = NULL; + char c; + grub_uint8_t byte; + char valid; + char path[256]; + + g_ventoy_case_insensitive = 1; + file = grub_file_open(bcdfile, VENTOY_FILE_TYPE); + g_ventoy_case_insensitive = 0; + if (!file) + { + debug("Failed to open file %s\n", bcdfile); + grub_errno = 0; + goto end; + } + + buf = grub_malloc(file->size + 8); + if (!buf) + { + goto end; + } + + grub_file_read(file, buf, file->size); + + for (i = 0; i < (int)file->size - 8; i++) + { + if (buf[i + 8] != 0) + { + continue; + } + + magic = *(grub_uint64_t *)(buf + i); + + /* .wim .WIM .Wim */ + if ((magic == 0x006D00690077002EULL) || + (magic == 0x004D00490057002EULL) || + (magic == 0x006D00690057002EULL)) + { + for (j = i; j > 0; j-= 2) + { + if (*(grub_uint16_t *)(buf + j) == 0) + { + break; + } + } + + if (j > 0) + { + byte = (grub_uint8_t)(*(grub_uint16_t *)(buf + j + 2)); + if (byte != '/' && byte != '\\') + { + continue; + } + + valid = 1; + for (k = 0, j += 2; k < (int)sizeof(path) - 1 && j < i + 8; j += 2) + { + byte = (grub_uint8_t)(*(grub_uint16_t *)(buf + j)); + c = (char)byte; + if (byte > '~' || byte < ' ') /* not printable */ + { + valid = 0; + break; + } + else if (c == '\\') + { + c = '/'; + } + + path[k++] = c; + } + path[k++] = 0; + + debug("@@@@ Find wim flag:<%s>\n", path); + + if (0 == valid) + { + debug("Invalid wim file %d\n", k); + } + else if (NULL == ventoy_find_wim_patch(path)) + { + node = grub_zalloc(sizeof(wim_patch)); + if (node) + { + node->pathlen = grub_snprintf(node->path, sizeof(node->path), "%s", path); + + debug("add patch <%s>\n", path); + + if (g_wim_patch_head) + { + node->next = g_wim_patch_head; + } + g_wim_patch_head = node; + + g_wim_total_patch_count++; + } + } + else + { + debug("wim <%s> already exist\n", path); + } + } + } + } + +end: + check_free(file, grub_file_close); + grub_check_free(buf); + return rc; +} + +grub_err_t ventoy_cmd_wim_patch_count(grub_extcmd_context_t ctxt, int argc, char **args) +{ + char buf[32]; + + (void)ctxt; + (void)argc; + (void)args; + + if (argc == 1) + { + grub_snprintf(buf, sizeof(buf), "%d", g_wim_total_patch_count); + ventoy_set_env(args[0], buf); + } + + return 0; +} + +grub_err_t ventoy_cmd_collect_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args) +{ + wim_patch *node = NULL; + + (void)ctxt; + (void)argc; + (void)args; + + if (argc != 2) + { + return 1; + } + + debug("ventoy_cmd_collect_wim_patch %s %s\n", args[0], args[1]); + + if (grub_strcmp(args[0], "bcd") == 0) + { + ventoy_collect_wim_patch(args[1]); + return 0; + } + + if (NULL == ventoy_find_wim_patch(args[1])) + { + node = grub_zalloc(sizeof(wim_patch)); + if (node) + { + node->pathlen = grub_snprintf(node->path, sizeof(node->path), "%s", args[1]); + + debug("add patch <%s>\n", args[1]); + + if (g_wim_patch_head) + { + node->next = g_wim_patch_head; + } + g_wim_patch_head = node; + + g_wim_total_patch_count++; + } + } + + return 0; +} + + +grub_err_t ventoy_cmd_dump_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i = 0; + wim_patch *node = NULL; + + (void)ctxt; + (void)argc; + (void)args; + + for (node = g_wim_patch_head; node; node = node->next) + { + grub_printf("%d %s [%s]\n", i++, node->path, node->valid ? "SUCCESS" : "FAIL"); + } + + return 0; +} + + +static int wim_name_cmp(const char *search, grub_uint16_t *name, grub_uint16_t namelen) +{ + char c1 = vtoy_to_upper(*search); + char c2 = vtoy_to_upper(*name); + + while (namelen > 0 && (c1 == c2)) + { + search++; + name++; + namelen--; + + c1 = vtoy_to_upper(*search); + c2 = vtoy_to_upper(*name); + } + + if (namelen == 0 && *search == 0) + { + return 0; + } + + return 1; +} + +static int ventoy_is_pe64(grub_uint8_t *buffer) +{ + grub_uint32_t pe_off; + + if (buffer[0] != 'M' || buffer[1] != 'Z') + { + return 0; + } + + pe_off = *(grub_uint32_t *)(buffer + 60); + + if (buffer[pe_off] != 'P' || buffer[pe_off + 1] != 'E') + { + return 0; + } + + if (*(grub_uint16_t *)(buffer + pe_off + 24) == 0x020b) + { + return 1; + } + + return 0; +} + +grub_err_t ventoy_cmd_is_pe64(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int ret = 1; + grub_file_t file; + grub_uint8_t buf[512]; + + (void)ctxt; + (void)argc; + + file = grub_file_open(args[0], VENTOY_FILE_TYPE); + if (!file) + { + return 1; + } + + grub_memset(buf, 0, 512); + grub_file_read(file, buf, 512); + if (ventoy_is_pe64(buf)) + { + debug("%s is PE64\n", args[0]); + ret = 0; + } + else + { + debug("%s is PE32\n", args[0]); + } + grub_file_close(file); + + return ret; +} + +grub_err_t ventoy_cmd_sel_wimboot(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int size; + char *buf = NULL; + char configfile[128]; + + (void)ctxt; + (void)argc; + (void)args; + + debug("select wimboot argc:%d\n", argc); + + buf = (char *)grub_malloc(8192); + if (!buf) + { + return 0; + } + + size = (int)grub_snprintf(buf, 8192, + "menuentry \"Windows Setup (32-bit)\" {\n" + " set vtoy_wimboot_sel=32\n" + "}\n" + "menuentry \"Windows Setup (64-bit)\" {\n" + " set vtoy_wimboot_sel=64\n" + "}\n" + ); + buf[size] = 0; + + g_ventoy_menu_esc = 1; + g_ventoy_suppress_esc = 1; + g_ventoy_suppress_esc_default = 1; + + grub_snprintf(configfile, sizeof(configfile), "configfile mem:0x%llx:size:%d", (ulonglong)(ulong)buf, size); + grub_script_execute_sourcecode(configfile); + + g_ventoy_menu_esc = 0; + g_ventoy_suppress_esc = 0; + + grub_free(buf); + + if (g_ventoy_last_entry == 0) + { + debug("last entry=%d %s=32\n", g_ventoy_last_entry, args[0]); + grub_env_set(args[0], "32"); + } + else + { + debug("last entry=%d %s=64\n", g_ventoy_last_entry, args[0]); + grub_env_set(args[0], "64"); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_wimdows_reset(grub_extcmd_context_t ctxt, int argc, char **args) +{ + wim_patch *next = NULL; + wim_patch *node = g_wim_patch_head; + + (void)ctxt; + (void)argc; + (void)args; + + while (node) + { + next = node->next; + grub_free(node); + node = next; + } + + g_wim_patch_head = NULL; + g_wim_total_patch_count = 0; + g_wim_valid_patch_count = 0; + + return 0; +} + +static int ventoy_load_jump_exe(const char *path, grub_uint8_t **data, grub_uint32_t *size, wim_hash *hash) +{ + grub_uint32_t i; + grub_uint32_t align; + grub_file_t file; + + debug("windows load jump %s\n", path); + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", path); + if (!file) + { + debug("Can't open file %s\n", path); + return 1; + } + + align = ventoy_align((int)file->size, 2048); + + debug("file %s size:%d align:%u\n", path, (int)file->size, align); + + *size = (grub_uint32_t)file->size; + *data = (grub_uint8_t *)grub_malloc(align); + if ((*data) == NULL) + { + debug("Failed to alloc memory size %u\n", align); + goto end; + } + + grub_file_read(file, (*data), file->size); + + if (hash) + { + grub_crypto_hash(GRUB_MD_SHA1, hash->sha1, (*data), file->size); + + if (g_ventoy_debug) + { + debug("%s", "jump bin 64 hash: "); + for (i = 0; i < sizeof(hash->sha1); i++) + { + ventoy_debug("%02x ", hash->sha1[i]); + } + ventoy_debug("\n"); + } + } + +end: + + grub_file_close(file); + return 0; +} + +static int ventoy_get_override_info(grub_file_t file, wim_tail *wim_data) +{ + grub_uint32_t start_block; + grub_uint64_t file_offset; + grub_uint64_t override_offset; + grub_uint32_t override_len; + grub_uint64_t fe_entry_size_offset; + + if (grub_strcmp(file->fs->name, "iso9660") == 0) + { + g_iso_fs_type = wim_data->iso_type = 0; + override_len = sizeof(ventoy_iso9660_override); + override_offset = grub_iso9660_get_last_file_dirent_pos(file) + 2; + + grub_file_read(file, &start_block, 1); // just read for hook trigger + file_offset = grub_iso9660_get_last_read_pos(file); + + debug("iso9660 wim size:%llu override_offset:%llu file_offset:%llu\n", + (ulonglong)file->size, (ulonglong)override_offset, (ulonglong)file_offset); + } + else + { + g_iso_fs_type = wim_data->iso_type = 1; + override_len = sizeof(ventoy_udf_override); + override_offset = grub_udf_get_last_file_attr_offset(file, &start_block, &fe_entry_size_offset); + + file_offset = grub_udf_get_file_offset(file); + + debug("UDF wim size:%llu override_offset:%llu file_offset:%llu start_block=%u\n", + (ulonglong)file->size, (ulonglong)override_offset, (ulonglong)file_offset, start_block); + } + + wim_data->file_offset = file_offset; + wim_data->udf_start_block = start_block; + wim_data->fe_entry_size_offset = fe_entry_size_offset; + wim_data->override_offset = override_offset; + wim_data->override_len = override_len; + + return 0; +} + +static int ventoy_read_resource(grub_file_t fp, wim_header *wimhdr, wim_resource_header *head, void **buffer) +{ + int decompress_len = 0; + int total_decompress = 0; + grub_uint32_t i = 0; + grub_uint32_t chunk_num = 0; + grub_uint32_t chunk_size = 0; + grub_uint32_t last_chunk_size = 0; + grub_uint32_t last_decompress_size = 0; + grub_uint32_t cur_offset = 0; + grub_uint8_t *cur_dst = NULL; + grub_uint8_t *buffer_compress = NULL; + grub_uint8_t *buffer_decompress = NULL; + grub_uint32_t *chunk_offset = NULL; + + buffer_decompress = (grub_uint8_t *)grub_malloc(head->raw_size + head->size_in_wim); + if (NULL == buffer_decompress) + { + return 0; + } + + grub_file_seek(fp, head->offset); + + if (head->size_in_wim == head->raw_size) + { + grub_file_read(fp, buffer_decompress, head->size_in_wim); + *buffer = buffer_decompress; + return 0; + } + + buffer_compress = buffer_decompress + head->raw_size; + grub_file_read(fp, buffer_compress, head->size_in_wim); + + chunk_num = (head->raw_size + WIM_CHUNK_LEN - 1) / WIM_CHUNK_LEN; + cur_offset = (chunk_num - 1) * 4; + chunk_offset = (grub_uint32_t *)buffer_compress; + + //debug("%llu %llu chunk_num=%lu", (ulonglong)head->size_in_wim, (ulonglong)head->raw_size, chunk_num); + + cur_dst = buffer_decompress; + + for (i = 0; i < chunk_num - 1; i++) + { + chunk_size = (i == 0) ? chunk_offset[i] : chunk_offset[i] - chunk_offset[i - 1]; + + if (WIM_CHUNK_LEN == chunk_size) + { + grub_memcpy(cur_dst, buffer_compress + cur_offset, chunk_size); + decompress_len = (int)chunk_size; + } + else + { + if (wimhdr->flags & FLAG_HEADER_COMPRESS_XPRESS) + { + decompress_len = (int)xca_decompress(buffer_compress + cur_offset, chunk_size, cur_dst); + } + else + { + decompress_len = (int)lzx_decompress(buffer_compress + cur_offset, chunk_size, cur_dst); + } + } + + //debug("chunk_size:%u decompresslen:%d\n", chunk_size, decompress_len); + + total_decompress += decompress_len; + cur_dst += decompress_len; + cur_offset += chunk_size; + } + + /* last chunk */ + last_chunk_size = (grub_uint32_t)(head->size_in_wim - cur_offset); + last_decompress_size = head->raw_size - total_decompress; + + if (last_chunk_size < WIM_CHUNK_LEN && last_chunk_size == last_decompress_size) + { + debug("Last chunk %u uncompressed\n", last_chunk_size); + grub_memcpy(cur_dst, buffer_compress + cur_offset, last_chunk_size); + decompress_len = (int)last_chunk_size; + } + else + { + if (wimhdr->flags & FLAG_HEADER_COMPRESS_XPRESS) + { + decompress_len = (int)xca_decompress(buffer_compress + cur_offset, head->size_in_wim - cur_offset, cur_dst); + } + else + { + decompress_len = (int)lzx_decompress(buffer_compress + cur_offset, head->size_in_wim - cur_offset, cur_dst); + } + } + + cur_dst += decompress_len; + total_decompress += decompress_len; + + //debug("last chunk_size:%u decompresslen:%d tot:%d\n", last_chunk_size, decompress_len, total_decompress); + + if (cur_dst != buffer_decompress + head->raw_size) + { + debug("head->size_in_wim:%llu head->raw_size:%llu cur_dst:%p buffer_decompress:%p total_decompress:%d\n", + (ulonglong)head->size_in_wim, (ulonglong)head->raw_size, cur_dst, buffer_decompress, total_decompress); + grub_free(buffer_decompress); + return 1; + } + + *buffer = buffer_decompress; + return 0; +} + + +static wim_directory_entry * search_wim_dirent(wim_directory_entry *dir, const char *search_name) +{ + do + { + if (dir->len && dir->name_len) + { + if (wim_name_cmp(search_name, (grub_uint16_t *)(dir + 1), dir->name_len / 2) == 0) + { + return dir; + } + } + dir = (wim_directory_entry *)((grub_uint8_t *)dir + dir->len); + } while(dir->len); + + return NULL; +} + +static wim_directory_entry * search_full_wim_dirent +( + void *meta_data, + wim_directory_entry *dir, + const char **path +) +{ + wim_directory_entry *subdir = NULL; + wim_directory_entry *search = dir; + + while (*path) + { + subdir = (wim_directory_entry *)((char *)meta_data + search->subdir); + search = search_wim_dirent(subdir, *path); + path++; + } + + return search; +} + + + +static wim_lookup_entry * ventoy_find_look_entry(wim_header *header, wim_lookup_entry *lookup, wim_hash *hash) +{ + grub_uint32_t i = 0; + + for (i = 0; i < (grub_uint32_t)header->lookup.raw_size / sizeof(wim_lookup_entry); i++) + { + if (grub_memcmp(&lookup[i].hash, hash, sizeof(wim_hash)) == 0) + { + return lookup + i; + } + } + + return NULL; +} + +static int parse_registry_setup_cmdline +( + grub_file_t file, + wim_header *head, + wim_lookup_entry *lookup, + void *meta_data, + wim_directory_entry *dir, + char *buf, + grub_uint32_t buflen +) +{ + char c; + int ret = 0; + grub_uint32_t i = 0; + grub_uint32_t reglen = 0; + wim_hash zerohash; + reg_vk *regvk = NULL; + wim_lookup_entry *look = NULL; + wim_directory_entry *wim_dirent = NULL; + char *decompress_data = NULL; + const char *reg_path[] = { "Windows", "System32", "config", "SYSTEM", NULL }; + + wim_dirent = search_full_wim_dirent(meta_data, dir, reg_path); + debug("search reg SYSTEM %p\n", wim_dirent); + if (!wim_dirent) + { + return 1; + } + + grub_memset(&zerohash, 0, sizeof(zerohash)); + if (grub_memcmp(&zerohash, wim_dirent->hash.sha1, sizeof(wim_hash)) == 0) + { + return 2; + } + + look = ventoy_find_look_entry(head, lookup, &wim_dirent->hash); + if (!look) + { + return 3; + } + + reglen = (grub_uint32_t)look->resource.raw_size; + debug("find system lookup entry_id:%ld raw_size:%u\n", + ((long)look - (long)lookup) / sizeof(wim_lookup_entry), reglen); + + if (0 != ventoy_read_resource(file, head, &(look->resource), (void **)&(decompress_data))) + { + return 4; + } + + if (grub_strncmp(decompress_data + 0x1000, "hbin", 4)) + { + ret_goto_end(5); + } + + for (i = 0x1000; i + sizeof(reg_vk) < reglen; i += 8) + { + regvk = (reg_vk *)(decompress_data + i); + if (regvk->sig == 0x6B76 && regvk->namesize == 7 && + regvk->datatype == 1 && regvk->flag == 1) + { + if (grub_strncasecmp((char *)(regvk + 1), "cmdline", 7) == 0) + { + debug("find registry cmdline i:%u offset:(0x%x)%u size:(0x%x)%u\n", + i, regvk->dataoffset, regvk->dataoffset, regvk->datasize, regvk->datasize); + break; + } + } + } + + if (i + sizeof(reg_vk) >= reglen || regvk == NULL) + { + ret_goto_end(6); + } + + if (regvk->datasize == 0 || (regvk->datasize & 0x80000000) > 0 || + regvk->dataoffset == 0 || regvk->dataoffset == 0xFFFFFFFF) + { + ret_goto_end(7); + } + + if (regvk->datasize / 2 >= buflen) + { + ret_goto_end(8); + } + + debug("start offset is 0x%x(%u)\n", 0x1000 + regvk->dataoffset + 4, 0x1000 + regvk->dataoffset + 4); + + for (i = 0; i < regvk->datasize; i+=2) + { + c = (char)(*(grub_uint16_t *)(decompress_data + 0x1000 + regvk->dataoffset + 4 + i)); + *buf++ = c; + } + + ret = 0; + +end: + grub_check_free(decompress_data); + return ret; +} + +static int parse_custom_setup_path(char *cmdline, const char **path, char *exefile) +{ + int i = 0; + int len = 0; + char *pos1 = NULL; + char *pos2 = NULL; + + if ((cmdline[0] == 'x' || cmdline[0] == 'X') && cmdline[1] == ':') + { + pos1 = pos2 = cmdline + 3; + + while (i < VTOY_MAX_DIR_DEPTH && *pos2) + { + while (*pos2 && *pos2 != '\\' && *pos2 != '/') + { + pos2++; + } + + path[i++] = pos1; + + if (*pos2 == 0) + { + break; + } + + *pos2 = 0; + pos1 = pos2 + 1; + pos2 = pos1; + } + + if (i == 0 || i >= VTOY_MAX_DIR_DEPTH) + { + return 1; + } + } + else + { + path[i++] = "Windows"; + path[i++] = "System32"; + path[i++] = cmdline; + } + + pos1 = (char *)path[i - 1]; + while (*pos1 != ' ' && *pos1 != '\t' && *pos1) + { + pos1++; + } + *pos1 = 0; + + len = (int)grub_strlen(path[i - 1]); + if (len < 4 || grub_strcasecmp(path[i - 1] + len - 4, ".exe") != 0) + { + grub_snprintf(exefile, 256, "%s.exe", path[i - 1]); + path[i - 1] = exefile; + } + + + debug("custom setup: %d <%s>\n", i, path[i - 1]); + return 0; +} + +static wim_directory_entry * search_replace_wim_dirent +( + grub_file_t file, + wim_header *head, + wim_lookup_entry *lookup, + void *meta_data, + wim_directory_entry *dir +) +{ + int ret; + char exefile[256] = {0}; + char cmdline[256] = {0}; + wim_directory_entry *wim_dirent = NULL; + wim_directory_entry *pecmd_dirent = NULL; + const char *peset_path[] = { "Windows", "System32", "peset.exe", NULL }; + const char *pecmd_path[] = { "Windows", "System32", "pecmd.exe", NULL }; + const char *winpeshl_path[] = { "Windows", "System32", "winpeshl.exe", NULL }; + const char *custom_path[VTOY_MAX_DIR_DEPTH + 1] = { NULL }; + + pecmd_dirent = search_full_wim_dirent(meta_data, dir, pecmd_path); + debug("search pecmd.exe %p\n", pecmd_dirent); + + if (pecmd_dirent) + { + ret = parse_registry_setup_cmdline(file, head, lookup, meta_data, dir, cmdline, sizeof(cmdline) - 1); + if (0 == ret) + { + debug("registry setup cmdline:<%s>\n", cmdline); + + if (grub_strncasecmp(cmdline, "PECMD", 5) == 0) + { + wim_dirent = pecmd_dirent; + } + else if (grub_strncasecmp(cmdline, "PESET", 5) == 0) + { + wim_dirent = search_full_wim_dirent(meta_data, dir, peset_path); + debug("search peset.exe %p\n", wim_dirent); + } + else if (grub_strncasecmp(cmdline, "WINPESHL", 8) == 0) + { + wim_dirent = search_full_wim_dirent(meta_data, dir, winpeshl_path); + debug("search winpeshl.exe %p\n", wim_dirent); + } + else if (0 == parse_custom_setup_path(cmdline, custom_path, exefile)) + { + wim_dirent = search_full_wim_dirent(meta_data, dir, custom_path); + debug("search custom path %p\n", wim_dirent); + } + + if (wim_dirent) + { + return wim_dirent; + } + } + else + { + debug("registry setup cmdline failed : %d\n", ret); + } + } + + wim_dirent = pecmd_dirent; + if (wim_dirent) + { + return wim_dirent; + } + + wim_dirent = search_full_wim_dirent(meta_data, dir, winpeshl_path); + debug("search winpeshl.exe %p\n", wim_dirent); + if (wim_dirent) + { + return wim_dirent; + } + + return NULL; +} + + +static wim_lookup_entry * ventoy_find_meta_entry(wim_header *header, wim_lookup_entry *lookup) +{ + grub_uint32_t i = 0; + grub_uint32_t index = 0;; + + if ((header == NULL) || (lookup == NULL)) + { + return NULL; + } + + for (i = 0; i < (grub_uint32_t)header->lookup.raw_size / sizeof(wim_lookup_entry); i++) + { + if (lookup[i].resource.flags & RESHDR_FLAG_METADATA) + { + index++; + if (index == header->boot_index) + { + return lookup + i; + } + } + } + + return NULL; +} + +static grub_uint64_t ventoy_get_stream_len(wim_directory_entry *dir) +{ + grub_uint16_t i; + grub_uint64_t offset = 0; + wim_stream_entry *stream = (wim_stream_entry *)((char *)dir + dir->len); + + for (i = 0; i < dir->streams; i++) + { + offset += stream->len; + stream = (wim_stream_entry *)((char *)stream + stream->len); + } + + return offset; +} + +static int ventoy_update_stream_hash(wim_patch *patch, wim_directory_entry *dir) +{ + grub_uint16_t i; + grub_uint64_t offset = 0; + wim_stream_entry *stream = (wim_stream_entry *)((char *)dir + dir->len); + + for (i = 0; i < dir->streams; i++) + { + if (grub_memcmp(stream->hash.sha1, patch->old_hash.sha1, sizeof(wim_hash)) == 0) + { + debug("find target stream %u, name_len:%u upadte hash\n", i, stream->name_len); + grub_memcpy(stream->hash.sha1, &(patch->wim_data.bin_hash), sizeof(wim_hash)); + } + + offset += stream->len; + stream = (wim_stream_entry *)((char *)stream + stream->len); + } + + return offset; +} + +static int ventoy_update_all_hash(wim_patch *patch, void *meta_data, wim_directory_entry *dir) +{ + if ((meta_data == NULL) || (dir == NULL)) + { + return 0; + } + + if (dir->len < sizeof(wim_directory_entry)) + { + return 0; + } + + do + { + if (dir->subdir == 0 && grub_memcmp(dir->hash.sha1, patch->old_hash.sha1, sizeof(wim_hash)) == 0) + { + debug("find target file, name_len:%u upadte hash\n", dir->name_len); + grub_memcpy(dir->hash.sha1, &(patch->wim_data.bin_hash), sizeof(wim_hash)); + } + + if (dir->subdir) + { + ventoy_update_all_hash(patch, meta_data, (wim_directory_entry *)((char *)meta_data + dir->subdir)); + } + + if (dir->streams) + { + ventoy_update_stream_hash(patch, dir); + dir = (wim_directory_entry *)((char *)dir + dir->len + ventoy_get_stream_len(dir)); + } + else + { + dir = (wim_directory_entry *)((char *)dir + dir->len); + } + } while (dir->len >= sizeof(wim_directory_entry)); + + return 0; +} + +static int ventoy_cat_exe_file_data(wim_tail *wim_data, grub_uint32_t exe_len, grub_uint8_t *exe_data, int windatalen) +{ + int pe64 = 0; + char file[256]; + grub_uint32_t jump_len = 0; + grub_uint32_t jump_align = 0; + grub_uint8_t *jump_data = NULL; + + pe64 = ventoy_is_pe64(exe_data); + + grub_snprintf(file, sizeof(file), "%s/vtoyjump%d.exe", grub_env_get("vtoy_path"), pe64 ? 64 : 32); + ventoy_load_jump_exe(file, &jump_data, &jump_len, NULL); + jump_align = ventoy_align(jump_len, 16); + + wim_data->jump_exe_len = jump_len; + wim_data->bin_raw_len = jump_align + sizeof(ventoy_os_param) + windatalen + exe_len; + wim_data->bin_align_len = ventoy_align(wim_data->bin_raw_len, 2048); + + wim_data->jump_bin_data = grub_malloc(wim_data->bin_align_len); + if (wim_data->jump_bin_data) + { + grub_memcpy(wim_data->jump_bin_data, jump_data, jump_len); + grub_memcpy(wim_data->jump_bin_data + jump_align + sizeof(ventoy_os_param) + windatalen, exe_data, exe_len); + } + + debug("jump_exe_len:%u bin_raw_len:%u bin_align_len:%u\n", + wim_data->jump_exe_len, wim_data->bin_raw_len, wim_data->bin_align_len); + + return 0; +} + +static int ventoy_get_windows_rtdata_len(const char *iso, int *flag) +{ + int size = 0; + int template_file_len = 0; + char *pos = NULL; + char *script = NULL; + install_template *template_node = NULL; + + *flag = 0; + size = (int)sizeof(ventoy_windows_data); + + pos = grub_strstr(iso, "/"); + if (!pos) + { + return size; + } + + script = ventoy_plugin_get_cur_install_template(pos, &template_node); + if (script) + { + (*flag) |= WINDATA_FLAG_TEMPLATE; + template_file_len = template_node->filelen; + } + + return size + template_file_len; +} + +static int ventoy_fill_windows_rtdata(void *buf, char *isopath, int dataflag) +{ + int template_len = 0; + char *pos = NULL; + char *end = NULL; + char *script = NULL; + const char *env = NULL; + install_template *template_node = NULL; + ventoy_windows_data *data = (ventoy_windows_data *)buf; + + grub_memset(data, 0, sizeof(ventoy_windows_data)); + + env = grub_env_get("VTOY_WIN11_BYPASS_CHECK"); + if (env && env[0] == '1' && env[1] == 0) + { + data->windows11_bypass_check = 1; + } + + env = grub_env_get("VTOY_WIN11_BYPASS_NRO"); + if (env && env[0] == '1' && env[1] == 0) + { + data->windows11_bypass_nro = 1; + } + + pos = grub_strstr(isopath, "/"); + if (!pos) + { + return 1; + } + + if (dataflag & WINDATA_FLAG_TEMPLATE) + { + script = ventoy_plugin_get_cur_install_template(pos, &template_node); + if (script) + { + data->auto_install_len = template_len = template_node->filelen; + debug("auto install script OK <%s> \n", script, template_len); + end = ventoy_str_last(script, '/'); + grub_snprintf(data->auto_install_script, sizeof(data->auto_install_script) - 1, "%s", end ? end + 1 : script); + grub_memcpy(data + 1, template_node->filebuf, template_len); + } + } + else + { + debug("auto install script skipped or not configed %s\n", pos); + } + + script = (char *)ventoy_plugin_get_injection(pos); + if (script) + { + if (ventoy_check_file_exist("%s%s", ventoy_get_env("vtoy_iso_part"), script)) + { + debug("injection archive <%s> OK\n", script); + grub_snprintf(data->injection_archive, sizeof(data->injection_archive) - 1, "%s", script); + } + else + { + debug("injection archive <%s> NOT exist\n", script); + } + } + else + { + debug("injection archive not configed %s\n", pos); + } + + return 0; +} + +static int ventoy_update_before_chain(ventoy_os_param *param, char *isopath) +{ + grub_uint32_t jump_align = 0; + wim_lookup_entry *meta_look = NULL; + wim_security_header *security = NULL; + wim_directory_entry *rootdir = NULL; + wim_header *head = NULL; + wim_lookup_entry *lookup = NULL; + wim_patch *node = NULL; + wim_tail *wim_data = NULL; + + for (node = g_wim_patch_head; node; node = node->next) + { + if (0 == node->valid) + { + continue; + } + + wim_data = &node->wim_data; + head = &wim_data->wim_header; + lookup = (wim_lookup_entry *)wim_data->new_lookup_data; + + jump_align = ventoy_align(wim_data->jump_exe_len, 16); + if (wim_data->jump_bin_data) + { + grub_memcpy(wim_data->jump_bin_data + jump_align, param, sizeof(ventoy_os_param)); + ventoy_fill_windows_rtdata(wim_data->jump_bin_data + jump_align + sizeof(ventoy_os_param), isopath, wim_data->windata_flag); + } + + grub_crypto_hash(GRUB_MD_SHA1, wim_data->bin_hash.sha1, wim_data->jump_bin_data, wim_data->bin_raw_len); + + security = (wim_security_header *)wim_data->new_meta_data; + if (security->len > 0) + { + rootdir = (wim_directory_entry *)(wim_data->new_meta_data + ((security->len + 7) & 0xFFFFFFF8U)); + } + else + { + rootdir = (wim_directory_entry *)(wim_data->new_meta_data + 8); + } + + /* update all winpeshl.exe dirent entry's hash */ + ventoy_update_all_hash(node, wim_data->new_meta_data, rootdir); + + /* update winpeshl.exe lookup entry data (hash/offset/length) */ + if (node->replace_look) + { + debug("update replace lookup entry_id:%ld\n", ((long)node->replace_look - (long)lookup) / sizeof(wim_lookup_entry)); + node->replace_look->resource.raw_size = wim_data->bin_raw_len; + node->replace_look->resource.size_in_wim = wim_data->bin_raw_len; + node->replace_look->resource.flags = 0; + node->replace_look->resource.offset = wim_data->wim_align_size; + + grub_memcpy(node->replace_look->hash.sha1, wim_data->bin_hash.sha1, sizeof(wim_hash)); + } + + /* update metadata's hash */ + meta_look = ventoy_find_meta_entry(head, lookup); + if (meta_look) + { + debug("find meta lookup entry_id:%ld\n", ((long)meta_look - (long)lookup) / sizeof(wim_lookup_entry)); + grub_memcpy(&meta_look->resource, &head->metadata, sizeof(wim_resource_header)); + grub_crypto_hash(GRUB_MD_SHA1, meta_look->hash.sha1, wim_data->new_meta_data, wim_data->new_meta_len); + } + } + + return 0; +} + +static int ventoy_wimdows_locate_wim(const char *disk, wim_patch *patch, int windatalen) +{ + int rc; + grub_uint16_t i; + grub_file_t file; + grub_uint32_t exe_len; + grub_uint8_t *exe_data = NULL; + grub_uint8_t *decompress_data = NULL; + wim_lookup_entry *lookup = NULL; + wim_security_header *security = NULL; + wim_directory_entry *rootdir = NULL; + wim_directory_entry *search = NULL; + wim_stream_entry *stream = NULL; + wim_header *head = &(patch->wim_data.wim_header); + wim_tail *wim_data = &patch->wim_data; + + debug("windows locate wim start %s\n", patch->path); + + g_ventoy_case_insensitive = 1; + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", disk, patch->path); + g_ventoy_case_insensitive = 0; + + if (!file) + { + debug("File %s%s NOT exist\n", disk, patch->path); + return 1; + } + + ventoy_get_override_info(file, &patch->wim_data); + + grub_file_seek(file, 0); + grub_file_read(file, head, sizeof(wim_header)); + + if (grub_memcmp(head->signature, WIM_HEAD_SIGNATURE, sizeof(head->signature))) + { + debug("Not a valid wim file %s\n", (char *)head->signature); + grub_file_close(file); + return 1; + } + + if (head->flags & FLAG_HEADER_COMPRESS_LZMS) + { + debug("LZMS compress is not supported 0x%x\n", head->flags); + grub_file_close(file); + return 1; + } + + rc = ventoy_read_resource(file, head, &head->metadata, (void **)&decompress_data); + if (rc) + { + grub_printf("failed to read meta data %d\n", rc); + grub_file_close(file); + return 1; + } + + security = (wim_security_header *)decompress_data; + if (security->len > 0) + { + rootdir = (wim_directory_entry *)(decompress_data + ((security->len + 7) & 0xFFFFFFF8U)); + } + else + { + rootdir = (wim_directory_entry *)(decompress_data + 8); + } + + + debug("read lookup offset:%llu size:%llu\n", (ulonglong)head->lookup.offset, (ulonglong)head->lookup.raw_size); + lookup = grub_malloc(head->lookup.raw_size); + grub_file_seek(file, head->lookup.offset); + grub_file_read(file, lookup, head->lookup.raw_size); + + + + /* search winpeshl.exe dirent entry */ + search = search_replace_wim_dirent(file, head, lookup, decompress_data, rootdir); + if (!search) + { + debug("Failed to find replace file %p\n", search); + grub_file_close(file); + return 1; + } + + debug("find replace file at %p\n", search); + + grub_memset(&patch->old_hash, 0, sizeof(wim_hash)); + if (grub_memcmp(&patch->old_hash, search->hash.sha1, sizeof(wim_hash)) == 0) + { + debug("search hash all 0, now do deep search\n"); + stream = (wim_stream_entry *)((char *)search + search->len); + for (i = 0; i < search->streams; i++) + { + if (stream->name_len == 0) + { + grub_memcpy(&patch->old_hash, stream->hash.sha1, sizeof(wim_hash)); + debug("new search hash: %02x %02x %02x %02x %02x %02x %02x %02x\n", + ventoy_varg_8(patch->old_hash.sha1)); + break; + } + stream = (wim_stream_entry *)((char *)stream + stream->len); + } + } + else + { + grub_memcpy(&patch->old_hash, search->hash.sha1, sizeof(wim_hash)); + } + + + /* find and extact winpeshl.exe */ + patch->replace_look = ventoy_find_look_entry(head, lookup, &patch->old_hash); + if (patch->replace_look) + { + exe_len = (grub_uint32_t)patch->replace_look->resource.raw_size; + debug("find replace lookup entry_id:%ld raw_size:%u\n", + ((long)patch->replace_look - (long)lookup) / sizeof(wim_lookup_entry), exe_len); + + if (0 == ventoy_read_resource(file, head, &(patch->replace_look->resource), (void **)&(exe_data))) + { + ventoy_cat_exe_file_data(wim_data, exe_len, exe_data, windatalen); + grub_free(exe_data); + } + else + { + debug("failed to read replace file meta data %u\n", exe_len); + } + } + else + { + debug("failed to find lookup entry for replace file %02x %02x %02x %02x\n", + ventoy_varg_4(patch->old_hash.sha1)); + } + + wim_data->wim_raw_size = (grub_uint32_t)file->size; + wim_data->wim_align_size = ventoy_align(wim_data->wim_raw_size, 2048); + + grub_check_free(wim_data->new_meta_data); + wim_data->new_meta_data = decompress_data; + wim_data->new_meta_len = head->metadata.raw_size; + wim_data->new_meta_align_len = ventoy_align(wim_data->new_meta_len, 2048); + + grub_check_free(wim_data->new_lookup_data); + wim_data->new_lookup_data = (grub_uint8_t *)lookup; + wim_data->new_lookup_len = (grub_uint32_t)head->lookup.raw_size; + wim_data->new_lookup_align_len = ventoy_align(wim_data->new_lookup_len, 2048); + + head->metadata.flags = RESHDR_FLAG_METADATA; + head->metadata.offset = wim_data->wim_align_size + wim_data->bin_align_len; + head->metadata.size_in_wim = wim_data->new_meta_len; + head->metadata.raw_size = wim_data->new_meta_len; + + head->lookup.flags = 0; + head->lookup.offset = head->metadata.offset + wim_data->new_meta_align_len; + head->lookup.size_in_wim = wim_data->new_lookup_len; + head->lookup.raw_size = wim_data->new_lookup_len; + + grub_file_close(file); + + debug("%s", "windows locate wim finish\n"); + return 0; +} + +grub_err_t ventoy_cmd_sel_winpe_wim(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i = 0; + int pos = 0; + int len = 0; + int find = 0; + char *cmd = NULL; + wim_patch *node = NULL; + wim_patch *tmp = NULL; + grub_file_t file = NULL; + wim_header *head = NULL; + char cfgfile[128]; + + (void)ctxt; + (void)argc; + + len = 8 * VTOY_SIZE_1KB; + cmd = (char *)grub_malloc(len + sizeof(wim_header)); + if (!cmd) + { + return 1; + } + + head = (wim_header *)(cmd + len); + grub_env_unset("vtoy_pe_wim_path"); + + for (node = g_wim_patch_head; node; node = node->next) + { + find = 0; + for (tmp = g_wim_patch_head; tmp != node; tmp = tmp->next) + { + if (tmp->valid && grub_strcasecmp(tmp->path, node->path) == 0) + { + find = 1; + break; + } + } + + if (find) + { + continue; + } + + g_ventoy_case_insensitive = 1; + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", args[0], node->path); + g_ventoy_case_insensitive = 0; + if (!file) + { + debug("File %s%s NOT exist\n", args[0], node->path); + continue; + } + + grub_file_read(file, head, sizeof(wim_header)); + if (grub_memcmp(head->signature, WIM_HEAD_SIGNATURE, sizeof(head->signature))) + { + debug("Not a valid wim file %s\n", (char *)head->signature); + grub_file_close(file); + continue; + } + + if (head->flags & FLAG_HEADER_COMPRESS_LZMS) + { + debug("LZMS compress is not supported 0x%x\n", head->flags); + grub_file_close(file); + continue; + } + + grub_file_close(file); + node->valid = 1; + + vtoy_len_ssprintf(cmd, pos, len, "menuentry \"%s\" --class=\"sel_wim\" {\n echo \"\"\n}\n", node->path); + } + + if (pos > 0) + { + g_ventoy_menu_esc = 1; + g_ventoy_suppress_esc = 1; + g_ventoy_suppress_esc_default = 0; + g_ventoy_secondary_menu_on = 1; + + grub_snprintf(cfgfile, sizeof(cfgfile), "configfile mem:0x%llx:size:%d", (ulonglong)(ulong)cmd, pos); + grub_script_execute_sourcecode(cfgfile); + + g_ventoy_menu_esc = 0; + g_ventoy_suppress_esc = 0; + g_ventoy_suppress_esc_default = 1; + g_ventoy_secondary_menu_on = 0; + + for (node = g_wim_patch_head; node; node = node->next) + { + if (node->valid) + { + if (i == g_ventoy_last_entry) + { + grub_env_set("vtoy_pe_wim_path", node->path); + break; + } + i++; + } + } + } + + grub_free(cmd); + return 0; +} + +grub_err_t ventoy_cmd_locate_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int datalen = 0; + int dataflag = 0; + wim_patch *node = g_wim_patch_head; + + (void)ctxt; + (void)argc; + (void)args; + + datalen = ventoy_get_windows_rtdata_len(args[1], &dataflag); + + while (node) + { + node->wim_data.windata_flag = dataflag; + if (0 == ventoy_wimdows_locate_wim(args[0], node, datalen)) + { + node->valid = 1; + g_wim_valid_patch_count++; + } + + node = node->next; + } + + return 0; +} + +static grub_uint32_t ventoy_get_override_chunk_num(void) +{ + grub_uint32_t chunk_num = 0; + + if (g_iso_fs_type == 0) + { + /* ISO9660: */ + /* per wim */ + /* 1: file_size and file_offset */ + /* 2: new wim file header */ + chunk_num = g_wim_valid_patch_count * 2; + } + else + { + /* UDF: */ + /* global: */ + /* 1: block count in Partition Descriptor */ + + /* per wim */ + /* 1: file_size in file_entry or extend_file_entry */ + /* 2: data_size and position in extend data short ad */ + /* 3: new wim file header */ + chunk_num = g_wim_valid_patch_count * 3 + 1; + } + + if (g_suppress_wincd_override_offset > 0) + { + chunk_num++; + } + + return chunk_num; +} + +static void ventoy_fill_suppress_wincd_override_data(void *override) +{ + ventoy_override_chunk *cur = (ventoy_override_chunk *)override; + + cur->override_size = 4; + cur->img_offset = g_suppress_wincd_override_offset; + grub_memcpy(cur->override_data, &g_suppress_wincd_override_data, cur->override_size); +} + +static void ventoy_windows_fill_override_data_iso9660( grub_uint64_t isosize, void *override) +{ + grub_uint64_t sector; + grub_uint32_t new_wim_size; + ventoy_override_chunk *cur; + wim_patch *node = NULL; + wim_tail *wim_data = NULL; + ventoy_iso9660_override *dirent = NULL; + + sector = (isosize + 2047) / 2048; + + cur = (ventoy_override_chunk *)override; + + if (g_suppress_wincd_override_offset > 0) + { + ventoy_fill_suppress_wincd_override_data(cur); + cur++; + } + + debug("ventoy_windows_fill_override_data_iso9660 %lu\n", (ulong)isosize); + + for (node = g_wim_patch_head; node; node = node->next) + { + wim_data = &node->wim_data; + if (0 == node->valid) + { + continue; + } + + new_wim_size = wim_data->wim_align_size + wim_data->bin_align_len + + wim_data->new_meta_align_len + wim_data->new_lookup_align_len; + + dirent = (ventoy_iso9660_override *)wim_data->override_data; + + dirent->first_sector = (grub_uint32_t)sector; + dirent->size = new_wim_size; + dirent->first_sector_be = grub_swap_bytes32(dirent->first_sector); + dirent->size_be = grub_swap_bytes32(dirent->size); + + sector += (new_wim_size / 2048); + + /* override 1: position and length in dirent */ + cur->img_offset = wim_data->override_offset; + cur->override_size = wim_data->override_len; + grub_memcpy(cur->override_data, wim_data->override_data, cur->override_size); + cur++; + + /* override 2: new wim file header */ + cur->img_offset = wim_data->file_offset; + cur->override_size = sizeof(wim_header); + grub_memcpy(cur->override_data, &(wim_data->wim_header), cur->override_size); + cur++; + } + + return; +} + +static int ventoy_windows_fill_udf_short_ad(grub_file_t isofile, grub_uint32_t curpos, + wim_tail *wim_data, grub_uint32_t new_wim_size) +{ + int i; + grub_uint32_t total = 0; + grub_uint32_t left_size = 0; + ventoy_udf_override *udf = NULL; + ventoy_udf_override tmp[4]; + + grub_memset(tmp, 0, sizeof(tmp)); + grub_file_seek(isofile, wim_data->override_offset); + grub_file_read(isofile, tmp, sizeof(tmp)); + + left_size = new_wim_size; + udf = (ventoy_udf_override *)wim_data->override_data; + + for (i = 0; i < 4; i++) + { + total += tmp[i].length; + if (total >= wim_data->wim_raw_size) + { + udf->length = left_size; + udf->position = curpos; + return 0; + } + else + { + udf->length = tmp[i].length; + udf->position = curpos; + } + + left_size -= tmp[i].length; + curpos += udf->length / 2048; + udf++; + wim_data->override_len += sizeof(ventoy_udf_override); + } + + debug("######## Too many udf ad ######\n"); + return 1; +} + +static void ventoy_windows_fill_override_data_udf(grub_file_t isofile, void *override) +{ + grub_uint32_t data32; + grub_uint64_t data64; + grub_uint64_t sector; + grub_uint32_t new_wim_size; + grub_uint64_t total_wim_size = 0; + grub_uint32_t udf_start_block = 0; + ventoy_override_chunk *cur; + wim_patch *node = NULL; + wim_tail *wim_data = NULL; + + sector = (isofile->size + 2047) / 2048; + + cur = (ventoy_override_chunk *)override; + + if (g_suppress_wincd_override_offset > 0) + { + ventoy_fill_suppress_wincd_override_data(cur); + cur++; + } + + debug("ventoy_windows_fill_override_data_udf %lu\n", (ulong)isofile->size); + + for (node = g_wim_patch_head; node; node = node->next) + { + wim_data = &node->wim_data; + if (node->valid) + { + if (udf_start_block == 0) + { + udf_start_block = wim_data->udf_start_block; + } + new_wim_size = wim_data->wim_align_size + wim_data->bin_align_len + + wim_data->new_meta_align_len + wim_data->new_lookup_align_len; + total_wim_size += new_wim_size; + } + } + + //override 1: sector number in pd data + cur->img_offset = grub_udf_get_last_pd_size_offset(); + cur->override_size = 4; + data32 = sector - udf_start_block + (total_wim_size / 2048); + grub_memcpy(cur->override_data, &(data32), 4); + + for (node = g_wim_patch_head; node; node = node->next) + { + wim_data = &node->wim_data; + if (0 == node->valid) + { + continue; + } + + new_wim_size = wim_data->wim_align_size + wim_data->bin_align_len + + wim_data->new_meta_align_len + wim_data->new_lookup_align_len; + + //override 2: filesize in file_entry + cur++; + cur->img_offset = wim_data->fe_entry_size_offset; + cur->override_size = 8; + data64 = new_wim_size; + grub_memcpy(cur->override_data, &(data64), 8); + + /* override 3: position and length in extend data */ + ventoy_windows_fill_udf_short_ad(isofile, (grub_uint32_t)sector - udf_start_block, wim_data, new_wim_size); + + sector += (new_wim_size / 2048); + + cur++; + cur->img_offset = wim_data->override_offset; + cur->override_size = wim_data->override_len; + grub_memcpy(cur->override_data, wim_data->override_data, cur->override_size); + + /* override 4: new wim file header */ + cur++; + cur->img_offset = wim_data->file_offset; + cur->override_size = sizeof(wim_header); + grub_memcpy(cur->override_data, &(wim_data->wim_header), cur->override_size); + } + + return; +} + +static grub_uint32_t ventoy_windows_get_virt_data_size(void) +{ + grub_uint32_t size = 0; + wim_tail *wim_data = NULL; + wim_patch *node = g_wim_patch_head; + + while (node) + { + if (node->valid) + { + wim_data = &node->wim_data; + size += sizeof(ventoy_virt_chunk) + wim_data->bin_align_len + + wim_data->new_meta_align_len + wim_data->new_lookup_align_len; + } + node = node->next; + } + + return size; +} + +static void ventoy_windows_fill_virt_data( grub_uint64_t isosize, ventoy_chain_head *chain) +{ + grub_uint64_t sector; + grub_uint32_t offset; + grub_uint32_t wim_secs; + grub_uint32_t mem_secs; + char *override = NULL; + ventoy_virt_chunk *cur = NULL; + wim_tail *wim_data = NULL; + wim_patch *node = NULL; + + sector = (isosize + 2047) / 2048; + offset = sizeof(ventoy_virt_chunk) * g_wim_valid_patch_count; + + override = (char *)chain + chain->virt_chunk_offset; + cur = (ventoy_virt_chunk *)override; + + for (node = g_wim_patch_head; node; node = node->next) + { + if (0 == node->valid) + { + continue; + } + + wim_data = &node->wim_data; + + wim_secs = wim_data->wim_align_size / 2048; + mem_secs = (wim_data->bin_align_len + wim_data->new_meta_align_len + wim_data->new_lookup_align_len) / 2048; + + cur->remap_sector_start = sector; + cur->remap_sector_end = cur->remap_sector_start + wim_secs; + cur->org_sector_start = (grub_uint32_t)(wim_data->file_offset / 2048); + + cur->mem_sector_start = cur->remap_sector_end; + cur->mem_sector_end = cur->mem_sector_start + mem_secs; + cur->mem_sector_offset = offset; + + sector += wim_secs + mem_secs; + cur++; + + grub_memcpy(override + offset, wim_data->jump_bin_data, wim_data->bin_raw_len); + offset += wim_data->bin_align_len; + + grub_memcpy(override + offset, wim_data->new_meta_data, wim_data->new_meta_len); + offset += wim_data->new_meta_align_len; + + grub_memcpy(override + offset, wim_data->new_lookup_data, wim_data->new_lookup_len); + offset += wim_data->new_lookup_align_len; + + chain->virt_img_size_in_bytes += wim_data->wim_align_size + + wim_data->bin_align_len + + wim_data->new_meta_align_len + + wim_data->new_lookup_align_len; + } + + return; +} + +static int ventoy_windows_drive_map(ventoy_chain_head *chain, int vlnk) +{ + int hd1 = 0; + grub_disk_t disk; + + debug("drive map begin <%p> <%d> ...\n", chain, vlnk); + + disk = grub_disk_open("hd1"); + if (disk) + { + grub_disk_close(disk); + hd1 = 1; + debug("BIOS hd1 exist\n"); + } + else + { + debug("failed to open disk %s\n", "hd1"); + } + + if (vlnk) + { + if (g_ventoy_disk_bios_id == 0x80 && hd1) + { + debug("drive map needed vlnk %p\n", disk); + chain->drive_map = 0x81; + } + } + else if (chain->disk_drive == 0x80) + { + if (hd1) + { + debug("drive map needed normal %p\n", disk); + chain->drive_map = 0x81; + } + } + else + { + debug("no need to map 0x%x\n", chain->disk_drive); + } + + return 0; +} + +static int ventoy_suppress_windows_cd_prompt(void) +{ + int rc = 1; + const char *cdprompt = NULL; + grub_uint64_t readpos = 0; + grub_file_t file = NULL; + grub_uint8_t data[32]; + + cdprompt = ventoy_get_env("VTOY_WINDOWS_CD_PROMPT"); + if (cdprompt && cdprompt[0] == '1' && cdprompt[1] == 0) + { + debug("VTOY_WINDOWS_CD_PROMPT:<%s>\n", cdprompt); + return 0; + } + + g_ventoy_case_insensitive = 1; + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s/boot/bootfix.bin", "(loop)"); + g_ventoy_case_insensitive = 0; + + if (!file) + { + debug("Failed to open %s\n", "bootfix.bin"); + goto end; + } + + grub_file_read(file, data, 32); + + if (file->fs && file->fs->name && grub_strcmp(file->fs->name, "udf") == 0) + { + readpos = grub_udf_get_file_offset(file); + } + else + { + readpos = grub_iso9660_get_last_read_pos(file); + } + + debug("bootfix.bin readpos:%lu (sector:%lu) data: %02x %02x %02x %02x\n", + (ulong)readpos, (ulong)readpos / 2048, data[24], data[25], data[26], data[27]); + + if (*(grub_uint32_t *)(data + 24) == 0x13cd0080) + { + g_suppress_wincd_override_offset = readpos + 24; + g_suppress_wincd_override_data = 0x13cd00fd; + + rc = 0; + } + + debug("g_suppress_wincd_override_offset:%lu\n", (ulong)g_suppress_wincd_override_offset); + +end: + check_free(file, grub_file_close); + + return rc; +} + +static int ventoy_extract_init_exe(char *wimfile, grub_uint8_t **pexe_data, grub_uint32_t *pexe_len, char *exe_name) +{ + int rc; + int ret = 1; + grub_uint16_t i; + grub_file_t file = NULL; + grub_uint32_t exe_len = 0; + wim_header *head = NULL; + grub_uint16_t *uname = NULL; + grub_uint8_t *exe_data = NULL; + grub_uint8_t *decompress_data = NULL; + wim_lookup_entry *lookup = NULL; + wim_security_header *security = NULL; + wim_directory_entry *rootdir = NULL; + wim_directory_entry *search = NULL; + wim_stream_entry *stream = NULL; + wim_lookup_entry *replace_look = NULL; + wim_header wimhdr; + wim_hash hashdata; + + head = &wimhdr; + + file = grub_file_open(wimfile, VENTOY_FILE_TYPE); + if (!file) + { + goto out; + } + + grub_file_read(file, head, sizeof(wim_header)); + rc = ventoy_read_resource(file, head, &head->metadata, (void **)&decompress_data); + if (rc) + { + grub_printf("failed to read meta data %d\n", rc); + goto out; + } + + security = (wim_security_header *)decompress_data; + if (security->len > 0) + { + rootdir = (wim_directory_entry *)(decompress_data + ((security->len + 7) & 0xFFFFFFF8U)); + } + else + { + rootdir = (wim_directory_entry *)(decompress_data + 8); + } + + debug("read lookup offset:%llu size:%llu\n", (ulonglong)head->lookup.offset, (ulonglong)head->lookup.raw_size); + lookup = grub_malloc(head->lookup.raw_size); + grub_file_seek(file, head->lookup.offset); + grub_file_read(file, lookup, head->lookup.raw_size); + + /* search winpeshl.exe dirent entry */ + search = search_replace_wim_dirent(file, head, lookup, decompress_data, rootdir); + if (!search) + { + debug("Failed to find replace file %p\n", search); + goto out; + } + + uname = (grub_uint16_t *)(search + 1); + for (i = 0; i < search->name_len / 2 && i < 200; i++) + { + exe_name[i] = (char)uname[i]; + } + exe_name[i] = 0; + debug("find replace file at %p <%s>\n", search, exe_name); + + grub_memset(&hashdata, 0, sizeof(wim_hash)); + if (grub_memcmp(&hashdata, search->hash.sha1, sizeof(wim_hash)) == 0) + { + debug("search hash all 0, now do deep search\n"); + stream = (wim_stream_entry *)((char *)search + search->len); + for (i = 0; i < search->streams; i++) + { + if (stream->name_len == 0) + { + grub_memcpy(&hashdata, stream->hash.sha1, sizeof(wim_hash)); + debug("new search hash: %02x %02x %02x %02x %02x %02x %02x %02x\n", + ventoy_varg_8(hashdata.sha1)); + break; + } + stream = (wim_stream_entry *)((char *)stream + stream->len); + } + } + else + { + grub_memcpy(&hashdata, search->hash.sha1, sizeof(wim_hash)); + } + + /* find and extact winpeshl.exe */ + replace_look = ventoy_find_look_entry(head, lookup, &hashdata); + if (replace_look) + { + exe_len = (grub_uint32_t)replace_look->resource.raw_size; + debug("find replace lookup entry_id:%ld raw_size:%u\n", + ((long)replace_look - (long)lookup) / sizeof(wim_lookup_entry), exe_len); + + if (0 != ventoy_read_resource(file, head, &(replace_look->resource), (void **)&(exe_data))) + { + exe_len = 0; + exe_data = NULL; + debug("failed to read replace file meta data %u\n", exe_len); + } + } + else + { + debug("failed to find lookup entry for replace file %02x %02x %02x %02x\n", + ventoy_varg_4(hashdata.sha1)); + } + + if (exe_data) + { + ret = 0; + *pexe_data = exe_data; + *pexe_len = exe_len; + } + +out: + + grub_check_free(lookup); + grub_check_free(decompress_data); + check_free(file, grub_file_close); + + return ret; +} + +grub_err_t ventoy_cmd_windows_wimboot_data(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int rc = 0; + int wim64 = 0; + int datalen = 0; + int dataflag = 0; + grub_uint32_t exe_len = 0; + grub_uint32_t jump_align = 0; + const char *addr = NULL; + ventoy_chain_head *chain = NULL; + grub_uint8_t *param = NULL; + grub_uint8_t *exe_data = NULL; + ventoy_windows_data *rtdata = NULL; + char exename[128] = {0}; + wim_tail wim_data; + + (void)ctxt; + (void)argc; + + addr = grub_env_get("vtoy_chain_mem_addr"); + if (!addr) + { + debug("Failed to find vtoy_chain_mem_addr\n"); + return 1; + } + + chain = (ventoy_chain_head *)(void *)grub_strtoul(addr, NULL, 16); + + if (grub_memcmp(&g_ventoy_guid, &chain->os_param.guid, 16) != 0) + { + debug("os_param.guid not match\n"); + return 1; + } + + datalen = ventoy_get_windows_rtdata_len(chain->os_param.vtoy_img_path, &dataflag); + + rc = ventoy_extract_init_exe(args[0], &exe_data, &exe_len, exename); + if (rc) + { + return 1; + } + wim64 = ventoy_is_pe64(exe_data); + + grub_memset(&wim_data, 0, sizeof(wim_data)); + ventoy_cat_exe_file_data(&wim_data, exe_len, exe_data, datalen); + grub_check_free(exe_data); + + jump_align = ventoy_align(wim_data.jump_exe_len, 16); + param = wim_data.jump_bin_data; + + grub_memcpy(param + jump_align, &chain->os_param, sizeof(ventoy_os_param)); + + rtdata = (ventoy_windows_data *)(param + jump_align + sizeof(ventoy_os_param)); + ventoy_fill_windows_rtdata(rtdata, chain->os_param.vtoy_img_path, dataflag); + + ventoy_memfile_env_set("vtoy_wimboot_mem", param, (ulonglong)(wim_data.bin_align_len)); + + grub_env_set(args[1], exename); + grub_env_set(args[2], wim64 ? "64" : "32"); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int unknown_image = 0; + int ventoy_compatible = 0; + grub_uint32_t size = 0; + grub_uint64_t isosize = 0; + grub_uint32_t boot_catlog = 0; + grub_uint32_t img_chunk_size = 0; + grub_uint32_t override_size = 0; + grub_uint32_t virt_chunk_size = 0; + grub_file_t file; + grub_disk_t disk; + const char *pLastChain = NULL; + const char *compatible; + ventoy_chain_head *chain; + + (void)ctxt; + (void)argc; + + debug("chain data begin <%s> ...\n", args[0]); + + compatible = grub_env_get("ventoy_compatible"); + if (compatible && compatible[0] == 'Y') + { + ventoy_compatible = 1; + } + + if (NULL == g_img_chunk_list.chunk) + { + grub_printf("ventoy not ready\n"); + return 1; + } + + if (0 == ventoy_compatible && g_wim_valid_patch_count == 0) + { + unknown_image = 1; + if (!g_ventoy_wimboot_mode) + { + debug("Warning: %s was not recognized by Ventoy\n", args[0]); + } + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + return 1; + } + + isosize = file->size; + + boot_catlog = ventoy_get_iso_boot_catlog(file); + if (boot_catlog) + { + if (ventoy_is_efi_os() && (!ventoy_has_efi_eltorito(file, boot_catlog))) + { + grub_env_set("LoadIsoEfiDriver", "on"); + } + } + else + { + if (ventoy_is_efi_os()) + { + grub_env_set("LoadIsoEfiDriver", "on"); + } + else + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "File %s is not bootable", args[0]); + } + } + + g_suppress_wincd_override_offset = 0; + if (!ventoy_is_efi_os()) /* legacy mode */ + { + ventoy_suppress_windows_cd_prompt(); + } + + img_chunk_size = g_img_chunk_list.cur_chunk * sizeof(ventoy_img_chunk); + + if (ventoy_compatible || unknown_image) + { + override_size = g_suppress_wincd_override_offset > 0 ? sizeof(ventoy_override_chunk) : 0; + size = sizeof(ventoy_chain_head) + img_chunk_size + override_size; + } + else + { + override_size = ventoy_get_override_chunk_num() * sizeof(ventoy_override_chunk); + virt_chunk_size = ventoy_windows_get_virt_data_size(); + size = sizeof(ventoy_chain_head) + img_chunk_size + override_size + virt_chunk_size; + } + + pLastChain = grub_env_get("vtoy_chain_mem_addr"); + if (pLastChain) + { + chain = (ventoy_chain_head *)grub_strtoul(pLastChain, NULL, 16); + if (chain) + { + debug("free last chain memory %p\n", chain); + grub_free(chain); + } + } + + chain = ventoy_alloc_chain(size); + if (!chain) + { + grub_printf("Failed to alloc chain win1 memory size %u\n", size); + grub_file_close(file); + return 1; + } + + ventoy_memfile_env_set("vtoy_chain_mem", chain, (ulonglong)size); + + grub_memset(chain, 0, sizeof(ventoy_chain_head)); + + /* part 1: os parameter */ + g_ventoy_chain_type = ventoy_chain_windows; + ventoy_fill_os_param(file, &(chain->os_param)); + + if (0 == unknown_image) + { + ventoy_update_before_chain(&(chain->os_param), args[0]); + } + + /* part 2: chain head */ + disk = file->device->disk; + chain->disk_drive = disk->id; + chain->disk_sector_size = (1 << disk->log_sector_size); + chain->real_img_size_in_bytes = file->size; + chain->virt_img_size_in_bytes = (file->size + 2047) / 2048 * 2048; + chain->boot_catalog = boot_catlog; + + if (!ventoy_is_efi_os()) + { + grub_file_seek(file, boot_catlog * 2048); + grub_file_read(file, chain->boot_catalog_sector, sizeof(chain->boot_catalog_sector)); + } + + /* part 3: image chunk */ + chain->img_chunk_offset = sizeof(ventoy_chain_head); + chain->img_chunk_num = g_img_chunk_list.cur_chunk; + grub_memcpy((char *)chain + chain->img_chunk_offset, g_img_chunk_list.chunk, img_chunk_size); + + if (ventoy_compatible || unknown_image) + { + if (g_suppress_wincd_override_offset > 0) + { + chain->override_chunk_offset = chain->img_chunk_offset + img_chunk_size; + chain->override_chunk_num = 1; + ventoy_fill_suppress_wincd_override_data((char *)chain + chain->override_chunk_offset); + } + + return 0; + } + + if (0 == g_wim_valid_patch_count) + { + return 0; + } + + /* part 4: override chunk */ + chain->override_chunk_offset = chain->img_chunk_offset + img_chunk_size; + chain->override_chunk_num = ventoy_get_override_chunk_num(); + + if (g_iso_fs_type == 0) + { + ventoy_windows_fill_override_data_iso9660(isosize, (char *)chain + chain->override_chunk_offset); + } + else + { + ventoy_windows_fill_override_data_udf(file, (char *)chain + chain->override_chunk_offset); + } + + /* part 5: virt chunk */ + chain->virt_chunk_offset = chain->override_chunk_offset + override_size; + chain->virt_chunk_num = g_wim_valid_patch_count; + ventoy_windows_fill_virt_data(isosize, chain); + + if (ventoy_is_efi_os() == 0) + { + ventoy_windows_drive_map(chain, file->vlnk); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_uint32_t ventoy_get_wim_iso_offset(const char *filepath) +{ + grub_uint32_t imgoffset; + grub_file_t file; + char cmdbuf[128]; + + grub_snprintf(cmdbuf, sizeof(cmdbuf), "loopback wimiso \"%s\"", filepath); + grub_script_execute_sourcecode(cmdbuf); + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", "(wimiso)/boot/boot.wim"); + if (!file) + { + grub_printf("Failed to open boot.wim file in the image file\n"); + return 0; + } + + imgoffset = (grub_uint32_t)grub_iso9660_get_last_file_dirent_pos(file) + 2; + + debug("wimiso wim direct offset: %u\n", imgoffset); + + grub_file_close(file); + + grub_script_execute_sourcecode("loopback -d wimiso"); + + return imgoffset; +} + +static int ventoy_get_wim_chunklist(grub_file_t wimfile, ventoy_img_chunk_list *wimchunk) +{ + grub_memset(wimchunk, 0, sizeof(ventoy_img_chunk_list)); + wimchunk->chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM); + if (NULL == wimchunk->chunk) + { + return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Can't allocate image chunk memoty\n"); + } + + wimchunk->max_chunk = DEFAULT_CHUNK_NUM; + wimchunk->cur_chunk = 0; + + ventoy_get_block_list(wimfile, wimchunk, wimfile->device->disk->partition->start); + + return 0; +} + +grub_err_t ventoy_cmd_is_standard_winiso(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + int ret = 1; + char prefix[32] = {0}; + const char *chkfile[] = + { + "boot/bcd", "boot/boot.sdi", NULL + }; + + (void)ctxt; + (void)argc; + + if (ventoy_check_file_exist("%s/sources/boot.wim", args[0])) + { + prefix[0] = 0; + } + else if (ventoy_check_file_exist("%s/x86/sources/boot.wim", args[0])) + { + grub_snprintf(prefix, sizeof(prefix), "/x86"); + } + else if (ventoy_check_file_exist("%s/x64/sources/boot.wim", args[0])) + { + grub_snprintf(prefix, sizeof(prefix), "/x64"); + } + else + { + debug("No boot.wim found.\n"); + goto out; + } + + for (i = 0; chkfile[i]; i++) + { + if (!ventoy_check_file_exist("%s%s/%s", args[0], prefix, chkfile[i])) + { + debug("%s not found.\n", chkfile[i]); + goto out; + } + } + + if ((!ventoy_check_file_exist("%s%s/sources/install.wim", args[0], prefix)) && + (!ventoy_check_file_exist("%s%s/sources/install.esd", args[0], prefix))) + { + debug("No install.wim(esd) found.\n"); + goto out; + } + + if (!ventoy_check_file_exist("%s/setup.exe", args[0])) + { + debug("No setup.exe found.\n"); + goto out; + } + + ret = 0; + debug("This is standard Windows ISO.\n"); + +out: + + return ret; +} + +grub_err_t ventoy_cmd_wim_check_bootable(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_uint32_t boot_index; + grub_file_t file = NULL; + wim_header *wimhdr = NULL; + + (void)ctxt; + (void)argc; + + wimhdr = grub_zalloc(sizeof(wim_header)); + if (!wimhdr) + { + return 1; + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + grub_free(wimhdr); + return 1; + } + + grub_file_read(file, wimhdr, sizeof(wim_header)); + grub_file_close(file); + boot_index = wimhdr->boot_index; + grub_free(wimhdr); + + if (boot_index == 0) + { + return 1; + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_vlnk_wim_chain_data(grub_file_t wimfile) +{ + grub_uint32_t i = 0; + grub_uint32_t imgoffset = 0; + grub_uint32_t size = 0; + grub_uint32_t isosector = 0; + grub_uint64_t wimsize = 0; + grub_uint32_t boot_catlog = 0; + grub_uint32_t img_chunk1_size = 0; + grub_uint32_t img_chunk2_size = 0; + grub_uint32_t override_size = 0; + grub_file_t file; + grub_disk_t disk; + const char *pLastChain = NULL; + ventoy_chain_head *chain; + ventoy_iso9660_override *dirent; + ventoy_img_chunk *chunknode; + ventoy_override_chunk *override; + ventoy_img_chunk_list wimchunk; + + debug("vlnk wim chain data begin <%s> ...\n", wimfile->name); + + if (NULL == g_wimiso_chunk_list.chunk || NULL == g_wimiso_path) + { + grub_printf("ventoy not ready\n"); + return 1; + } + + imgoffset = ventoy_get_wim_iso_offset(g_wimiso_path); + if (imgoffset == 0) + { + grub_printf("image offset not found\n"); + return 1; + } + + if (0 != ventoy_get_wim_chunklist(wimfile, &wimchunk)) + { + grub_printf("Failed to get wim chunklist\n"); + return 1; + } + wimsize = wimfile->size; + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", g_wimiso_path); + if (!file) + { + return 1; + } + + boot_catlog = ventoy_get_iso_boot_catlog(file); + + img_chunk1_size = g_wimiso_chunk_list.cur_chunk * sizeof(ventoy_img_chunk); + img_chunk2_size = wimchunk.cur_chunk * sizeof(ventoy_img_chunk); + override_size = sizeof(ventoy_override_chunk) + g_wimiso_size; + + size = sizeof(ventoy_chain_head) + img_chunk1_size + img_chunk2_size + override_size; + + pLastChain = grub_env_get("vtoy_chain_mem_addr"); + if (pLastChain) + { + chain = (ventoy_chain_head *)grub_strtoul(pLastChain, NULL, 16); + if (chain) + { + debug("free last chain memory %p\n", chain); + grub_free(chain); + } + } + + chain = ventoy_alloc_chain(size); + if (!chain) + { + grub_printf("Failed to alloc chain win2 memory size %u\n", size); + grub_file_close(file); + return 1; + } + + ventoy_memfile_env_set("vtoy_chain_mem", chain, (ulonglong)size); + + grub_memset(chain, 0, sizeof(ventoy_chain_head)); + + /* part 1: os parameter */ + g_ventoy_chain_type = ventoy_chain_wim; + ventoy_fill_os_param(wimfile, &(chain->os_param)); + + /* part 2: chain head */ + disk = wimfile->device->disk; + chain->disk_drive = disk->id; + chain->disk_sector_size = (1 << disk->log_sector_size); + chain->real_img_size_in_bytes = ventoy_align_2k(file->size) + ventoy_align_2k(wimsize); + chain->virt_img_size_in_bytes = chain->real_img_size_in_bytes; + chain->boot_catalog = boot_catlog; + + if (!ventoy_is_efi_os()) + { + grub_file_seek(file, boot_catlog * 2048); + grub_file_read(file, chain->boot_catalog_sector, sizeof(chain->boot_catalog_sector)); + } + + /* part 3: image chunk */ + chain->img_chunk_offset = sizeof(ventoy_chain_head); + chain->img_chunk_num = g_wimiso_chunk_list.cur_chunk + wimchunk.cur_chunk; + grub_memcpy((char *)chain + chain->img_chunk_offset, g_wimiso_chunk_list.chunk, img_chunk1_size); + + chunknode = (ventoy_img_chunk *)((char *)chain + chain->img_chunk_offset); + for (i = 0; i < g_wimiso_chunk_list.cur_chunk; i++) + { + chunknode->disk_end_sector = chunknode->disk_end_sector - chunknode->disk_start_sector; + chunknode->disk_start_sector = 0; + chunknode++; + } + + /* fs cluster size >= 2048, so don't need to proc align */ + + /* align by 2048 */ + chunknode = wimchunk.chunk + wimchunk.cur_chunk - 1; + i = (chunknode->disk_end_sector + 1 - chunknode->disk_start_sector) % 4; + if (i) + { + chunknode->disk_end_sector += 4 - i; + } + + isosector = (grub_uint32_t)((file->size + 2047) / 2048); + for (i = 0; i < wimchunk.cur_chunk; i++) + { + chunknode = wimchunk.chunk + i; + chunknode->img_start_sector = isosector; + chunknode->img_end_sector = chunknode->img_start_sector + + ((chunknode->disk_end_sector + 1 - chunknode->disk_start_sector) / 4) - 1; + isosector = chunknode->img_end_sector + 1; + } + + grub_memcpy((char *)chain + chain->img_chunk_offset + img_chunk1_size, wimchunk.chunk, img_chunk2_size); + + /* part 4: override chunk */ + chain->override_chunk_offset = chain->img_chunk_offset + img_chunk1_size + img_chunk2_size; + chain->override_chunk_num = 1; + + override = (ventoy_override_chunk *)((char *)chain + chain->override_chunk_offset); + override->img_offset = 0; + override->override_size = g_wimiso_size; + + grub_file_seek(file, 0); + grub_file_read(file, override->override_data, file->size); + + dirent = (ventoy_iso9660_override *)(override->override_data + imgoffset); + dirent->first_sector = (grub_uint32_t)((file->size + 2047) / 2048); + dirent->size = (grub_uint32_t)(wimsize); + dirent->first_sector_be = grub_swap_bytes32(dirent->first_sector); + dirent->size_be = grub_swap_bytes32(dirent->size); + + debug("imgoffset=%u first_sector=0x%x size=0x%x\n", imgoffset, dirent->first_sector, dirent->size); + + if (ventoy_is_efi_os() == 0) + { + ventoy_windows_drive_map(chain, 0); + } + + grub_file_close(file); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_normal_wim_chain_data(grub_file_t wimfile) +{ + grub_uint32_t i = 0; + grub_uint32_t imgoffset = 0; + grub_uint32_t size = 0; + grub_uint32_t isosector = 0; + grub_uint64_t wimsize = 0; + grub_uint32_t boot_catlog = 0; + grub_uint32_t img_chunk1_size = 0; + grub_uint32_t img_chunk2_size = 0; + grub_uint32_t override_size = 0; + grub_file_t file; + grub_disk_t disk; + const char *pLastChain = NULL; + ventoy_chain_head *chain; + ventoy_iso9660_override *dirent; + ventoy_img_chunk *chunknode; + ventoy_override_chunk *override; + ventoy_img_chunk_list wimchunk; + + debug("normal wim chain data begin <%s> ...\n", wimfile->name); + + if (NULL == g_wimiso_chunk_list.chunk || NULL == g_wimiso_path) + { + grub_printf("ventoy not ready\n"); + return 1; + } + + imgoffset = ventoy_get_wim_iso_offset(g_wimiso_path); + if (imgoffset == 0) + { + grub_printf("image offset not found\n"); + return 1; + } + + if (0 != ventoy_get_wim_chunklist(wimfile, &wimchunk)) + { + grub_printf("Failed to get wim chunklist\n"); + return 1; + } + wimsize = wimfile->size; + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", g_wimiso_path); + if (!file) + { + return 1; + } + + boot_catlog = ventoy_get_iso_boot_catlog(file); + + img_chunk1_size = g_wimiso_chunk_list.cur_chunk * sizeof(ventoy_img_chunk); + img_chunk2_size = wimchunk.cur_chunk * sizeof(ventoy_img_chunk); + override_size = sizeof(ventoy_override_chunk); + + size = sizeof(ventoy_chain_head) + img_chunk1_size + img_chunk2_size + override_size; + + pLastChain = grub_env_get("vtoy_chain_mem_addr"); + if (pLastChain) + { + chain = (ventoy_chain_head *)grub_strtoul(pLastChain, NULL, 16); + if (chain) + { + debug("free last chain memory %p\n", chain); + grub_free(chain); + } + } + + chain = ventoy_alloc_chain(size); + if (!chain) + { + grub_printf("Failed to alloc chain win3 memory size %u\n", size); + grub_file_close(file); + return 1; + } + + ventoy_memfile_env_set("vtoy_chain_mem", chain, (ulonglong)size); + + grub_memset(chain, 0, sizeof(ventoy_chain_head)); + + /* part 1: os parameter */ + g_ventoy_chain_type = ventoy_chain_wim; + ventoy_fill_os_param(file, &(chain->os_param)); + + /* part 2: chain head */ + disk = file->device->disk; + chain->disk_drive = disk->id; + chain->disk_sector_size = (1 << disk->log_sector_size); + chain->real_img_size_in_bytes = ventoy_align_2k(file->size) + ventoy_align_2k(wimsize); + chain->virt_img_size_in_bytes = chain->real_img_size_in_bytes; + chain->boot_catalog = boot_catlog; + + if (!ventoy_is_efi_os()) + { + grub_file_seek(file, boot_catlog * 2048); + grub_file_read(file, chain->boot_catalog_sector, sizeof(chain->boot_catalog_sector)); + } + + /* part 3: image chunk */ + chain->img_chunk_offset = sizeof(ventoy_chain_head); + chain->img_chunk_num = g_wimiso_chunk_list.cur_chunk + wimchunk.cur_chunk; + grub_memcpy((char *)chain + chain->img_chunk_offset, g_wimiso_chunk_list.chunk, img_chunk1_size); + + /* fs cluster size >= 2048, so don't need to proc align */ + + /* align by 2048 */ + chunknode = wimchunk.chunk + wimchunk.cur_chunk - 1; + i = (chunknode->disk_end_sector + 1 - chunknode->disk_start_sector) % 4; + if (i) + { + chunknode->disk_end_sector += 4 - i; + } + + isosector = (grub_uint32_t)((file->size + 2047) / 2048); + for (i = 0; i < wimchunk.cur_chunk; i++) + { + chunknode = wimchunk.chunk + i; + chunknode->img_start_sector = isosector; + chunknode->img_end_sector = chunknode->img_start_sector + + ((chunknode->disk_end_sector + 1 - chunknode->disk_start_sector) / 4) - 1; + isosector = chunknode->img_end_sector + 1; + } + + grub_memcpy((char *)chain + chain->img_chunk_offset + img_chunk1_size, wimchunk.chunk, img_chunk2_size); + + /* part 4: override chunk */ + chain->override_chunk_offset = chain->img_chunk_offset + img_chunk1_size + img_chunk2_size; + chain->override_chunk_num = 1; + + override = (ventoy_override_chunk *)((char *)chain + chain->override_chunk_offset); + override->img_offset = imgoffset; + override->override_size = sizeof(ventoy_iso9660_override); + + dirent = (ventoy_iso9660_override *)(override->override_data); + dirent->first_sector = (grub_uint32_t)((file->size + 2047) / 2048); + dirent->size = (grub_uint32_t)(wimsize); + dirent->first_sector_be = grub_swap_bytes32(dirent->first_sector); + dirent->size_be = grub_swap_bytes32(dirent->size); + + debug("imgoffset=%u first_sector=0x%x size=0x%x\n", imgoffset, dirent->first_sector, dirent->size); + + if (ventoy_is_efi_os() == 0) + { + ventoy_windows_drive_map(chain, 0); + } + + grub_file_close(file); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_err_t ret; + grub_file_t wimfile; + + (void)ctxt; + (void)argc; + + wimfile = grub_file_open(args[0], VENTOY_FILE_TYPE); + if (!wimfile) + { + return 1; + } + + if (wimfile->vlnk) + { + ret = ventoy_vlnk_wim_chain_data(wimfile); + } + else + { + ret = ventoy_normal_wim_chain_data(wimfile); + } + + grub_file_close(wimfile); + return ret; +} + +int ventoy_chain_file_size(const char *path) +{ + int size; + grub_file_t file; + + file = grub_file_open(path, VENTOY_FILE_TYPE); + size = (int)(file->size); + + grub_file_close(file); + + return size; +} + +int ventoy_chain_file_read(const char *path, int offset, int len, void *buf) +{ + int size; + grub_file_t file; + + file = grub_file_open(path, VENTOY_FILE_TYPE); + grub_file_seek(file, offset); + size = grub_file_read(file, buf, len); + grub_file_close(file); + + return size; +} + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/wimboot.h b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/wimboot.h new file mode 100644 index 0000000..5a77eae --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/wimboot.h @@ -0,0 +1,65 @@ +/****************************************************************************** + * wimboot.h + * + * Copyright (c) 2020, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ +#ifndef __WIMBOOT_H__ +#define __WIMBOOT_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ventoy_def.h" + + +#define size_t grub_size_t +#define ssize_t grub_ssize_t +#define memset grub_memset +#define memcpy grub_memcpy + +#define uint8_t grub_uint8_t +#define uint16_t grub_uint16_t +#define uint32_t grub_uint32_t +#define uint64_t grub_uint64_t +#define int32_t grub_int32_t + + + +#define assert(exp) + +//#define DBG grub_printf +#define DBG(fmt, ...) + +const char * huffman_bin ( unsigned long value, unsigned int bits ); + +#endif + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/xpress.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/xpress.c new file mode 100644 index 0000000..bfb3125 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/xpress.c @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2012 Michael Brown . + * + * 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. + */ + +/** + * @file + * + * Xpress Compression Algorithm (MS-XCA) decompression + * + */ + +#include "wimboot.h" +#include "huffman.h" +#include "xpress.h" + +#pragma GCC diagnostic ignored "-Wcast-align" + +/** + * Decompress XCA-compressed data + * + * @v data Compressed data + * @v len Length of compressed data + * @v buf Decompression buffer, or NULL + * @ret out_len Length of decompressed data, or negative error + */ +ssize_t xca_decompress ( const void *data, size_t len, void *buf ) { + const void *src = data; + const void *end = ( uint8_t * ) src + len; + uint8_t *out = buf; + size_t out_len = 0; + size_t out_len_threshold = 0; + const struct xca_huf_len *lengths; + struct xca xca; + uint32_t accum = 0; + int extra_bits = 0; + unsigned int huf; + struct huffman_symbols *sym; + unsigned int raw; + unsigned int match_len; + unsigned int match_offset_bits; + unsigned int match_offset; + const uint8_t *copy; + int rc; + + /* Process data stream */ + while ( src < end ) { + + /* (Re)initialise decompressor if applicable */ + if ( out_len >= out_len_threshold ) { + + /* Construct symbol lengths */ + lengths = src; + src = ( uint8_t * ) src + sizeof ( *lengths ); + if ( src > end ) { + DBG ( "XCA too short to hold Huffman lengths table.\n"); + return -1; + } + for ( raw = 0 ; raw < XCA_CODES ; raw++ ) + xca.lengths[raw] = xca_huf_len ( lengths, raw ); + + /* Construct Huffman alphabet */ + if ( ( rc = huffman_alphabet ( &xca.alphabet, + xca.lengths, + XCA_CODES ) ) != 0 ) + return rc; + + /* Initialise state */ + accum = XCA_GET16 ( src ); + accum <<= 16; + accum |= XCA_GET16 ( src ); + extra_bits = 16; + + /* Determine next threshold */ + out_len_threshold = ( out_len + XCA_BLOCK_SIZE ); + } + + /* Determine symbol */ + huf = ( accum >> ( 32 - HUFFMAN_BITS ) ); + sym = huffman_sym ( &xca.alphabet, huf ); + raw = huffman_raw ( sym, huf ); + accum <<= huffman_len ( sym ); + extra_bits -= huffman_len ( sym ); + if ( extra_bits < 0 ) { + accum |= ( XCA_GET16 ( src ) << ( -extra_bits ) ); + extra_bits += 16; + } + + /* Process symbol */ + if ( raw < XCA_END_MARKER ) { + + /* Literal symbol - add to output stream */ + if ( buf ) + *(out++) = raw; + out_len++; + + } else if ( ( raw == XCA_END_MARKER ) && + ( (uint8_t *) src >= ( ( uint8_t * ) end - 1 ) ) ) { + + /* End marker symbol */ + return out_len; + + } else { + + /* LZ77 match symbol */ + raw -= XCA_END_MARKER; + match_offset_bits = ( raw >> 4 ); + match_len = ( raw & 0x0f ); + if ( match_len == 0x0f ) { + match_len = XCA_GET8 ( src ); + if ( match_len == 0xff ) { + match_len = XCA_GET16 ( src ); + } else { + match_len += 0x0f; + } + } + match_len += 3; + if ( match_offset_bits ) { + match_offset = + ( ( accum >> ( 32 - match_offset_bits )) + + ( 1 << match_offset_bits ) ); + } else { + match_offset = 1; + } + accum <<= match_offset_bits; + extra_bits -= match_offset_bits; + if ( extra_bits < 0 ) { + accum |= ( XCA_GET16 ( src ) << (-extra_bits) ); + extra_bits += 16; + } + + /* Copy data */ + out_len += match_len; + if ( buf ) { + copy = ( out - match_offset ); + while ( match_len-- ) + *(out++) = *(copy++); + } + } + } + + return out_len; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/xpress.h b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/xpress.h new file mode 100644 index 0000000..6a430f7 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/xpress.h @@ -0,0 +1,87 @@ +#ifndef _XCA_H +#define _XCA_H + +/* + * Copyright (C) 2012 Michael Brown . + * + * 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. + */ + +/** + * @file + * + * Xpress Compression Algorithm (MS-XCA) decompression + * + */ + +#include "huffman.h" + +/** Number of XCA codes */ +#define XCA_CODES 512 + +/** XCA decompressor */ +struct xca { + /** Huffman alphabet */ + struct huffman_alphabet alphabet; + /** Raw symbols + * + * Must immediately follow the Huffman alphabet. + */ + huffman_raw_symbol_t raw[XCA_CODES]; + /** Code lengths */ + uint8_t lengths[XCA_CODES]; +}; + +/** XCA symbol Huffman lengths table */ +struct xca_huf_len { + /** Lengths of each symbol */ + uint8_t nibbles[ XCA_CODES / 2 ]; +} __attribute__ (( packed )); + +/** + * Extract Huffman-coded length of a raw symbol + * + * @v lengths Huffman lengths table + * @v symbol Raw symbol + * @ret len Huffman-coded length + */ +static inline unsigned int xca_huf_len ( const struct xca_huf_len *lengths, + unsigned int symbol ) { + return ( ( ( lengths->nibbles[ symbol / 2 ] ) >> + ( 4 * ( symbol % 2 ) ) ) & 0x0f ); +} + +/** Get word from source data stream */ +#define XCA_GET16( src ) ( { \ + const uint16_t *src16 = src; \ + src = ( uint8_t * ) src + sizeof ( *src16 ); \ + *src16; } ) + +/** Get byte from source data stream */ +#define XCA_GET8( src ) ( { \ + const uint8_t *src8 = src; \ + src = ( uint8_t * ) src + sizeof ( *src8 ); \ + *src8; } ) + +/** XCA source data stream end marker */ +#define XCA_END_MARKER 256 + +/** XCA block size */ +#define XCA_BLOCK_SIZE ( 64 * 1024 ) + +extern ssize_t xca_decompress ( const void *data, size_t len, void *buf ); + +#endif /* _XCA_H */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/cache.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/cache.h new file mode 100644 index 0000000..7a4070d --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/cache.h @@ -0,0 +1,56 @@ +/* cache.h - Flush the processor's cache. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2007 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_CACHE_H +#define GRUB_CACHE_H 1 + +#include +#include + +#if defined (__i386__) || defined (__x86_64__) +static inline void +grub_arch_sync_caches (void *address __attribute__ ((unused)), + grub_size_t len __attribute__ ((unused))) +{ +} +#else +void EXPORT_FUNC(grub_arch_sync_caches) (void *address, grub_size_t len); +#endif + +#ifndef GRUB_MACHINE_EMU +#if defined (__aarch64__) || defined (__ia64__) || defined (__powerpc__) || \ + defined (__sparc__) + +#elif defined (__i386__) || defined (__x86_64__) +static inline void +grub_arch_sync_dma_caches (volatile void *address __attribute__ ((unused)), + grub_size_t len __attribute__ ((unused))) +{ +} +#elif defined(__mips__) && (_MIPS_SIM != _ABI64) +void EXPORT_FUNC(grub_arch_sync_dma_caches) (volatile void *address, grub_size_t len); +#endif +#endif + +#ifdef __arm__ +void +grub_arm_cache_enable (void); +#endif + +#endif /* ! GRUB_CACHE_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/charset.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/charset.h new file mode 100644 index 0000000..4c59753 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/charset.h @@ -0,0 +1,329 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_CHARSET_HEADER +#define GRUB_CHARSET_HEADER 1 + +#include + +#define GRUB_UINT8_1_LEADINGBIT 0x80 +#define GRUB_UINT8_2_LEADINGBITS 0xc0 +#define GRUB_UINT8_3_LEADINGBITS 0xe0 +#define GRUB_UINT8_4_LEADINGBITS 0xf0 +#define GRUB_UINT8_5_LEADINGBITS 0xf8 +#define GRUB_UINT8_6_LEADINGBITS 0xfc +#define GRUB_UINT8_7_LEADINGBITS 0xfe + +#define GRUB_UINT8_1_TRAILINGBIT 0x01 +#define GRUB_UINT8_2_TRAILINGBITS 0x03 +#define GRUB_UINT8_3_TRAILINGBITS 0x07 +#define GRUB_UINT8_4_TRAILINGBITS 0x0f +#define GRUB_UINT8_5_TRAILINGBITS 0x1f +#define GRUB_UINT8_6_TRAILINGBITS 0x3f + +#define GRUB_MAX_UTF8_PER_UTF16 4 +/* You need at least one UTF-8 byte to have one UTF-16 word. + You need at least three UTF-8 bytes to have 2 UTF-16 words (surrogate pairs). + */ +#define GRUB_MAX_UTF16_PER_UTF8 1 +#define GRUB_MAX_UTF8_PER_CODEPOINT 4 + +#define GRUB_UCS2_LIMIT 0x10000 +#define GRUB_UTF16_UPPER_SURROGATE(code) \ + (0xD800 | ((((code) - GRUB_UCS2_LIMIT) >> 10) & 0x3ff)) +#define GRUB_UTF16_LOWER_SURROGATE(code) \ + (0xDC00 | (((code) - GRUB_UCS2_LIMIT) & 0x3ff)) + +/* Process one character from UTF8 sequence. + At beginning set *code = 0, *count = 0. Returns 0 on failure and + 1 on success. *count holds the number of trailing bytes. */ +static inline int +grub_utf8_process (grub_uint8_t c, grub_uint32_t *code, int *count) +{ + if (*count) + { + if ((c & GRUB_UINT8_2_LEADINGBITS) != GRUB_UINT8_1_LEADINGBIT) + { + *count = 0; + /* invalid */ + return 0; + } + else + { + *code <<= 6; + *code |= (c & GRUB_UINT8_6_TRAILINGBITS); + (*count)--; + /* Overlong. */ + if ((*count == 1 && *code <= 0x1f) + || (*count == 2 && *code <= 0xf)) + { + *code = 0; + *count = 0; + return 0; + } + return 1; + } + } + + if ((c & GRUB_UINT8_1_LEADINGBIT) == 0) + { + *code = c; + return 1; + } + if ((c & GRUB_UINT8_3_LEADINGBITS) == GRUB_UINT8_2_LEADINGBITS) + { + *count = 1; + *code = c & GRUB_UINT8_5_TRAILINGBITS; + /* Overlong */ + if (*code <= 1) + { + *count = 0; + *code = 0; + return 0; + } + return 1; + } + if ((c & GRUB_UINT8_4_LEADINGBITS) == GRUB_UINT8_3_LEADINGBITS) + { + *count = 2; + *code = c & GRUB_UINT8_4_TRAILINGBITS; + return 1; + } + if ((c & GRUB_UINT8_5_LEADINGBITS) == GRUB_UINT8_4_LEADINGBITS) + { + *count = 3; + *code = c & GRUB_UINT8_3_TRAILINGBITS; + return 1; + } + return 0; +} + + +/* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE + bytes (if SRCSIZE is -1, it is ignored) in length to a UTF-16 string. + Return the number of characters converted. DEST must be able to hold + at least DESTSIZE characters. If an invalid sequence is found, return -1. + If SRCEND is not NULL, then *SRCEND is set to the next byte after the + last byte used in SRC. */ +static inline grub_size_t +grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize, + const grub_uint8_t *src, grub_size_t srcsize, + const grub_uint8_t **srcend) +{ + grub_uint16_t *p = dest; + int count = 0; + grub_uint32_t code = 0; + + if (srcend) + *srcend = src; + + while (srcsize && destsize) + { + int was_count = count; + if (srcsize != (grub_size_t)-1) + srcsize--; + if (!grub_utf8_process (*src++, &code, &count)) + { + code = '?'; + count = 0; + /* Character c may be valid, don't eat it. */ + if (was_count) + src--; + } + if (count != 0) + continue; + if (code == 0) + break; + if (destsize < 2 && code >= GRUB_UCS2_LIMIT) + break; + if (code >= GRUB_UCS2_LIMIT) + { + *p++ = GRUB_UTF16_UPPER_SURROGATE (code); + *p++ = GRUB_UTF16_LOWER_SURROGATE (code); + destsize -= 2; + } + else + { + *p++ = code; + destsize--; + } + } + + if (srcend) + *srcend = src; + return p - dest; +} + +/* Determine the last position where the UTF-8 string [beg, end) can + be safely cut. */ +static inline grub_size_t +grub_getend (const char *beg, const char *end) +{ + const char *ptr; + for (ptr = end - 1; ptr >= beg; ptr--) + if ((*ptr & GRUB_UINT8_2_LEADINGBITS) != GRUB_UINT8_1_LEADINGBIT) + break; + if (ptr < beg) + return 0; + if ((*ptr & GRUB_UINT8_1_LEADINGBIT) == 0) + return ptr + 1 - beg; + if ((*ptr & GRUB_UINT8_3_LEADINGBITS) == GRUB_UINT8_2_LEADINGBITS + && ptr + 2 <= end) + return ptr + 2 - beg; + if ((*ptr & GRUB_UINT8_4_LEADINGBITS) == GRUB_UINT8_3_LEADINGBITS + && ptr + 3 <= end) + return ptr + 3 - beg; + if ((*ptr & GRUB_UINT8_5_LEADINGBITS) == GRUB_UINT8_4_LEADINGBITS + && ptr + 4 <= end) + return ptr + 4 - beg; + /* Invalid character or incomplete. Cut before it. */ + return ptr - beg; +} + +/* Convert UTF-16 to UTF-8. */ +static inline grub_uint8_t * +grub_utf16_to_utf8 (grub_uint8_t *dest, const grub_uint16_t *src, + grub_size_t size) +{ + grub_uint32_t code_high = 0; + + while (size--) + { + grub_uint32_t code = *src++; + + if (code_high) + { + if (code >= 0xDC00 && code <= 0xDFFF) + { + /* Surrogate pair. */ + code = ((code_high - 0xD800) << 10) + (code - 0xDC00) + 0x10000; + + *dest++ = (code >> 18) | 0xF0; + *dest++ = ((code >> 12) & 0x3F) | 0x80; + *dest++ = ((code >> 6) & 0x3F) | 0x80; + *dest++ = (code & 0x3F) | 0x80; + } + else + { + /* Error... */ + *dest++ = '?'; + /* *src may be valid. Don't eat it. */ + src--; + } + + code_high = 0; + } + else + { + if (code <= 0x007F) + *dest++ = code; + else if (code <= 0x07FF) + { + *dest++ = (code >> 6) | 0xC0; + *dest++ = (code & 0x3F) | 0x80; + } + else if (code >= 0xD800 && code <= 0xDBFF) + { + code_high = code; + continue; + } + else if (code >= 0xDC00 && code <= 0xDFFF) + { + /* Error... */ + *dest++ = '?'; + } + else if (code < 0x10000) + { + *dest++ = (code >> 12) | 0xE0; + *dest++ = ((code >> 6) & 0x3F) | 0x80; + *dest++ = (code & 0x3F) | 0x80; + } + else + { + *dest++ = (code >> 18) | 0xF0; + *dest++ = ((code >> 12) & 0x3F) | 0x80; + *dest++ = ((code >> 6) & 0x3F) | 0x80; + *dest++ = (code & 0x3F) | 0x80; + } + } + } + + return dest; +} + +#define GRUB_MAX_UTF8_PER_LATIN1 2 + +/* Convert Latin1 to UTF-8. */ +static inline grub_uint8_t * +grub_latin1_to_utf8 (grub_uint8_t *dest, const grub_uint8_t *src, + grub_size_t size) +{ + while (size--) + { + if (!(*src & 0x80)) + *dest++ = *src; + else + { + *dest++ = (*src >> 6) | 0xC0; + *dest++ = (*src & 0x3F) | 0x80; + } + src++; + } + + return dest; +} + +/* Convert UCS-4 to UTF-8. */ +char *grub_ucs4_to_utf8_alloc (const grub_uint32_t *src, grub_size_t size); + +int +grub_is_valid_utf8 (const grub_uint8_t *src, grub_size_t srcsize); + +grub_ssize_t grub_utf8_to_ucs4_alloc (const char *msg, + grub_uint32_t **unicode_msg, + grub_uint32_t **last_position); + +/* Returns the number of bytes the string src would occupy is converted + to UTF-8, excluding \0. */ +grub_size_t +grub_get_num_of_utf8_bytes (const grub_uint32_t *src, grub_size_t size); + +/* Converts UCS-4 to UTF-8. Returns the number of bytes effectively written + excluding the trailing \0. */ +grub_size_t +grub_ucs4_to_utf8 (const grub_uint32_t *src, grub_size_t size, + grub_uint8_t *dest, grub_size_t destsize); +grub_size_t grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize, + const grub_uint8_t *src, grub_size_t srcsize, + const grub_uint8_t **srcend); +/* Returns -2 if not enough space, -1 on invalid character. */ +grub_ssize_t +grub_encode_utf8_character (grub_uint8_t *dest, grub_uint8_t *destend, + grub_uint32_t code); + +const grub_uint32_t * +grub_unicode_get_comb_start (const grub_uint32_t *str, + const grub_uint32_t *cur); + +int +grub_utf8_get_num_code (const char *src, grub_size_t srcsize); + +const char * +grub_utf8_offset_code (const char *src, grub_size_t srcsize, int num); + +#endif diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/compiler.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/compiler.h new file mode 100644 index 0000000..9859ff4 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/compiler.h @@ -0,0 +1,53 @@ +/* compiler.h - macros for various compiler features */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2005,2006,2007,2008,2009,2010,2014 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_COMPILER_HEADER +#define GRUB_COMPILER_HEADER 1 + +/* GCC version checking borrowed from glibc. */ +#if defined(__GNUC__) && defined(__GNUC_MINOR__) +# define GNUC_PREREQ(maj,min) \ + ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) +#else +# define GNUC_PREREQ(maj,min) 0 +#endif + +/* Does this compiler support compile-time error attributes? */ +#if GNUC_PREREQ(4,3) +# define ATTRIBUTE_ERROR(msg) \ + __attribute__ ((__error__ (msg))) +#else +# define ATTRIBUTE_ERROR(msg) __attribute__ ((noreturn)) +#endif + +#if GNUC_PREREQ(4,4) +# define GNU_PRINTF gnu_printf +#else +# define GNU_PRINTF printf +#endif + +#if GNUC_PREREQ(3,4) +# define WARN_UNUSED_RESULT __attribute__ ((warn_unused_result)) +#else +# define WARN_UNUSED_RESULT +#endif + +#define UNUSED __attribute__((__unused__)) + +#endif /* ! GRUB_COMPILER_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/disk.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/disk.h new file mode 100644 index 0000000..5d81ba4 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/disk.h @@ -0,0 +1,267 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_DISK_HEADER +#define GRUB_DISK_HEADER 1 + +#include + +#include +#include +#include +#include +/* For NULL. */ +#include + +/* These are used to set a device id. When you add a new disk device, + you must define a new id for it here. */ +enum grub_disk_dev_id + { + GRUB_DISK_DEVICE_BIOSDISK_ID, + GRUB_DISK_DEVICE_OFDISK_ID, + GRUB_DISK_DEVICE_LOOPBACK_ID, + GRUB_DISK_DEVICE_EFIDISK_ID, + GRUB_DISK_DEVICE_DISKFILTER_ID, + GRUB_DISK_DEVICE_HOST_ID, + GRUB_DISK_DEVICE_ATA_ID, + GRUB_DISK_DEVICE_MEMDISK_ID, + GRUB_DISK_DEVICE_NAND_ID, + GRUB_DISK_DEVICE_SCSI_ID, + GRUB_DISK_DEVICE_CRYPTODISK_ID, + GRUB_DISK_DEVICE_ARCDISK_ID, + GRUB_DISK_DEVICE_HOSTDISK_ID, + GRUB_DISK_DEVICE_PROCFS_ID, + GRUB_DISK_DEVICE_CBFSDISK_ID, + GRUB_DISK_DEVICE_UBOOTDISK_ID, + GRUB_DISK_DEVICE_XEN, + GRUB_DISK_DEVICE_OBDISK_ID, + }; + +struct grub_disk; +#ifdef GRUB_UTIL +struct grub_disk_memberlist; +#endif + +typedef enum + { + GRUB_DISK_PULL_NONE, + GRUB_DISK_PULL_REMOVABLE, + GRUB_DISK_PULL_RESCAN, + GRUB_DISK_PULL_MAX + } grub_disk_pull_t; + +typedef int (*grub_disk_dev_iterate_hook_t) (const char *name, void *data); + +/* Disk device. */ +struct grub_disk_dev +{ + /* The device name. */ + const char *name; + + /* The device id used by the cache manager. */ + enum grub_disk_dev_id id; + + /* Call HOOK with each device name, until HOOK returns non-zero. */ + int (*disk_iterate) (grub_disk_dev_iterate_hook_t hook, void *hook_data, + grub_disk_pull_t pull); + + /* Open the device named NAME, and set up DISK. */ + grub_err_t (*disk_open) (const char *name, struct grub_disk *disk); + + /* Close the disk DISK. */ + void (*disk_close) (struct grub_disk *disk); + + /* Read SIZE sectors from the sector SECTOR of the disk DISK into BUF. */ + grub_err_t (*disk_read) (struct grub_disk *disk, grub_disk_addr_t sector, + grub_size_t size, char *buf); + + /* Write SIZE sectors from BUF into the sector SECTOR of the disk DISK. */ + grub_err_t (*disk_write) (struct grub_disk *disk, grub_disk_addr_t sector, + grub_size_t size, const char *buf); + +#ifdef GRUB_UTIL + struct grub_disk_memberlist *(*disk_memberlist) (struct grub_disk *disk); + const char * (*disk_raidname) (struct grub_disk *disk); +#endif + + /* The next disk device. */ + struct grub_disk_dev *next; +}; +typedef struct grub_disk_dev *grub_disk_dev_t; + +extern grub_disk_dev_t EXPORT_VAR (grub_disk_dev_list); + +struct grub_partition; + +typedef void (*grub_disk_read_hook_t) (grub_disk_addr_t sector, + unsigned offset, unsigned length, + void *data); + +/* Disk. */ +struct grub_disk +{ + /* The disk name. */ + const char *name; + + /* The underlying disk device. */ + grub_disk_dev_t dev; + + /* The total number of sectors. */ + grub_uint64_t total_sectors; + + /* Logarithm of sector size. */ + unsigned int log_sector_size; + + /* Maximum number of sectors read divided by GRUB_DISK_CACHE_SIZE. */ + unsigned int max_agglomerate; + + /* The id used by the disk cache manager. */ + unsigned long id; + + /* The partition information. This is machine-specific. */ + struct grub_partition *partition; + + /* Called when a sector was read. OFFSET is between 0 and + the sector size minus 1, and LENGTH is between 0 and the sector size. */ + grub_disk_read_hook_t read_hook; + + /* Caller-specific data passed to the read hook. */ + void *read_hook_data; + + /* Device-specific data. */ + void *data; +}; +typedef struct grub_disk *grub_disk_t; + +#ifdef GRUB_UTIL +struct grub_disk_memberlist +{ + grub_disk_t disk; + struct grub_disk_memberlist *next; +}; +typedef struct grub_disk_memberlist *grub_disk_memberlist_t; +#endif + +/* The sector size. */ +#define GRUB_DISK_SECTOR_SIZE 0x200 +#define GRUB_DISK_SECTOR_BITS 9 + +/* The maximum number of disk caches. */ +#define GRUB_DISK_CACHE_NUM 1021 + +/* The size of a disk cache in 512B units. Must be at least as big as the + largest supported sector size, currently 16K. */ +#define GRUB_DISK_CACHE_BITS 6 +#define GRUB_DISK_CACHE_SIZE (1 << GRUB_DISK_CACHE_BITS) + +#define GRUB_DISK_MAX_MAX_AGGLOMERATE ((1 << (30 - GRUB_DISK_CACHE_BITS - GRUB_DISK_SECTOR_BITS)) - 1) + +/* Return value of grub_disk_get_size() in case disk size is unknown. */ +#define GRUB_DISK_SIZE_UNKNOWN 0xffffffffffffffffULL + +/* This is called from the memory manager. */ +void grub_disk_cache_invalidate_all (void); + +void EXPORT_FUNC(grub_disk_dev_register) (grub_disk_dev_t dev); +void EXPORT_FUNC(grub_disk_dev_unregister) (grub_disk_dev_t dev); +static inline int +grub_disk_dev_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data) +{ + grub_disk_dev_t p; + grub_disk_pull_t pull; + + for (pull = 0; pull < GRUB_DISK_PULL_MAX; pull++) + for (p = grub_disk_dev_list; p; p = p->next) + if (p->disk_iterate && (p->disk_iterate) (hook, hook_data, pull)) + return 1; + + return 0; +} + +grub_disk_t EXPORT_FUNC(grub_disk_open) (const char *name); +void EXPORT_FUNC(grub_disk_close) (grub_disk_t disk); +grub_err_t EXPORT_FUNC(grub_disk_blocklist_read)(void *chunklist, grub_uint64_t sector, + grub_uint64_t size, grub_uint32_t log_sector_size); +grub_err_t EXPORT_FUNC(grub_disk_blocklist_read2)(grub_disk_t disk, grub_uint64_t sector, + grub_uint64_t size, char *buf); + +grub_err_t EXPORT_FUNC(grub_disk_read) (grub_disk_t disk, + grub_disk_addr_t sector, + grub_off_t offset, + grub_size_t size, + void *buf); +grub_err_t grub_disk_write (grub_disk_t disk, + grub_disk_addr_t sector, + grub_off_t offset, + grub_size_t size, + const void *buf); +extern grub_err_t (*EXPORT_VAR(grub_disk_write_weak)) (grub_disk_t disk, + grub_disk_addr_t sector, + grub_off_t offset, + grub_size_t size, + const void *buf); + + +grub_uint64_t EXPORT_FUNC(grub_disk_get_size) (grub_disk_t disk); + +#if DISK_CACHE_STATS +void +EXPORT_FUNC(grub_disk_cache_get_performance) (unsigned long *hits, unsigned long *misses); +#endif + +extern void (* EXPORT_VAR(grub_disk_firmware_fini)) (void); +extern int EXPORT_VAR(grub_disk_firmware_is_tainted); + +static inline void +grub_stop_disk_firmware (void) +{ + /* To prevent two drivers operating on the same disks. */ + grub_disk_firmware_is_tainted = 1; + if (grub_disk_firmware_fini) + { + grub_disk_firmware_fini (); + grub_disk_firmware_fini = NULL; + } +} + +/* Disk cache. */ +struct grub_disk_cache +{ + enum grub_disk_dev_id dev_id; + unsigned long disk_id; + grub_disk_addr_t sector; + char *data; + int lock; +}; + +extern struct grub_disk_cache EXPORT_VAR(grub_disk_cache_table)[GRUB_DISK_CACHE_NUM]; + +#if defined (GRUB_UTIL) +void grub_lvm_init (void); +void grub_ldm_init (void); +void grub_mdraid09_init (void); +void grub_mdraid1x_init (void); +void grub_diskfilter_init (void); +void grub_lvm_fini (void); +void grub_ldm_fini (void); +void grub_mdraid09_fini (void); +void grub_mdraid1x_fini (void); +void grub_diskfilter_fini (void); +#endif + +#endif /* ! GRUB_DISK_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/dl.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/dl.h new file mode 100644 index 0000000..f70498d --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/dl.h @@ -0,0 +1,309 @@ +/* dl.h - types and prototypes for loadable module support */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2004,2005,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_DL_H +#define GRUB_DL_H 1 + +#include +#ifndef ASM_FILE +#include +#include +#include +#include +#include +#endif + +/* + * Macros GRUB_MOD_INIT and GRUB_MOD_FINI are also used by build rules + * to collect module names, so we define them only when they are not + * defined already. + */ +#ifndef ASM_FILE + +#ifndef GRUB_MOD_INIT + +#if !defined (GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) && !defined (GRUB_KERNEL) + +#define GRUB_MOD_INIT(name) \ +static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \ +static void \ +grub_mod_init (grub_dl_t mod __attribute__ ((unused))) + +#define GRUB_MOD_FINI(name) \ +static void grub_mod_fini (void) __attribute__ ((used)); \ +static void \ +grub_mod_fini (void) + +#elif defined (GRUB_KERNEL) + +#define GRUB_MOD_INIT(name) \ +static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \ +void \ +grub_##name##_init (void) { grub_mod_init (0); } \ +static void \ +grub_mod_init (grub_dl_t mod __attribute__ ((unused))) + +#define GRUB_MOD_FINI(name) \ +static void grub_mod_fini (void) __attribute__ ((used)); \ +void \ +grub_##name##_fini (void) { grub_mod_fini (); } \ +static void \ +grub_mod_fini (void) + +#else + +#define GRUB_MOD_INIT(name) \ +static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \ +void grub_##name##_init (void); \ +void \ +grub_##name##_init (void) { grub_mod_init (0); } \ +static void \ +grub_mod_init (grub_dl_t mod __attribute__ ((unused))) + +#define GRUB_MOD_FINI(name) \ +static void grub_mod_fini (void) __attribute__ ((used)); \ +void grub_##name##_fini (void); \ +void \ +grub_##name##_fini (void) { grub_mod_fini (); } \ +static void \ +grub_mod_fini (void) + +#endif + +#endif + +#endif + +#ifndef ASM_FILE +#ifdef __APPLE__ +#define GRUB_MOD_SECTION(x) "_" #x ", _" #x "" +#else +#define GRUB_MOD_SECTION(x) "." #x +#endif +#else +#ifdef __APPLE__ +#define GRUB_MOD_SECTION(x) _ ## x , _ ##x +#else +#define GRUB_MOD_SECTION(x) . ## x +#endif +#endif + +/* Me, Vladimir Serbinenko, hereby I add this module check as per new + GNU module policy. Note that this license check is informative only. + Modules have to be licensed under GPLv3 or GPLv3+ (optionally + multi-licensed under other licences as well) independently of the + presence of this check and solely by linking (module loading in GRUB + constitutes linking) and GRUB core being licensed under GPLv3+. + Be sure to understand your license obligations. +*/ +#ifndef ASM_FILE +#if GNUC_PREREQ (3,2) +#define ATTRIBUTE_USED __used__ +#else +#define ATTRIBUTE_USED __unused__ +#endif +#define GRUB_MOD_LICENSE(license) \ + static char grub_module_license[] __attribute__ ((section (GRUB_MOD_SECTION (module_license)), ATTRIBUTE_USED)) = "LICENSE=" license; +#define GRUB_MOD_DEP(name) \ +static const char grub_module_depend_##name[] \ + __attribute__((section(GRUB_MOD_SECTION(moddeps)), ATTRIBUTE_USED)) = #name +#define GRUB_MOD_NAME(name) \ +static const char grub_module_name_##name[] \ + __attribute__((section(GRUB_MOD_SECTION(modname)), __used__)) = #name +#else +#ifdef __APPLE__ +.macro GRUB_MOD_LICENSE + .section GRUB_MOD_SECTION(module_license) + .ascii "LICENSE=" + .ascii $0 + .byte 0 +.endm +#else +.macro GRUB_MOD_LICENSE license + .section GRUB_MOD_SECTION(module_license), "a" + .ascii "LICENSE=" + .ascii "\license" + .byte 0 +.endm +#endif +#endif + +/* Under GPL license obligations you have to distribute your module + under GPLv3(+). However, you can also distribute the same code under + another license as long as GPLv3(+) version is provided. +*/ +#define GRUB_MOD_DUAL_LICENSE(x) + +#ifndef ASM_FILE + +struct grub_dl_segment +{ + struct grub_dl_segment *next; + void *addr; + grub_size_t size; + unsigned section; +}; +typedef struct grub_dl_segment *grub_dl_segment_t; + +struct grub_dl; + +struct grub_dl_dep +{ + struct grub_dl_dep *next; + struct grub_dl *mod; +}; +typedef struct grub_dl_dep *grub_dl_dep_t; + +#ifndef GRUB_UTIL +struct grub_dl +{ + char *name; + int ref_count; + int persistent; + grub_dl_dep_t dep; + grub_dl_segment_t segment; + Elf_Sym *symtab; + grub_size_t symsize; + void (*init) (struct grub_dl *mod); + void (*fini) (void); +#if !defined (__i386__) && !defined (__x86_64__) + void *got; + void *gotptr; + void *tramp; + void *trampptr; +#endif +#if defined(__mips__) && (_MIPS_SIM != _ABI64) + grub_uint32_t *reginfo; +#endif + void *base; + grub_size_t sz; + struct grub_dl *next; +}; +#endif +typedef struct grub_dl *grub_dl_t; + +grub_dl_t grub_dl_load_file (const char *filename); +grub_dl_t EXPORT_FUNC(grub_dl_load) (const char *name); +grub_dl_t grub_dl_load_core (void *addr, grub_size_t size); +grub_dl_t EXPORT_FUNC(grub_dl_load_core_noinit) (void *addr, grub_size_t size); +int EXPORT_FUNC(grub_dl_unload) (grub_dl_t mod); +void grub_dl_unload_unneeded (void); +int EXPORT_FUNC(grub_dl_ref) (grub_dl_t mod); +int EXPORT_FUNC(grub_dl_unref) (grub_dl_t mod); +extern grub_dl_t EXPORT_VAR(grub_dl_head); + +#ifndef GRUB_UTIL + +#define FOR_DL_MODULES(var) FOR_LIST_ELEMENTS ((var), (grub_dl_head)) + +#ifdef GRUB_MACHINE_EMU +void * +grub_osdep_dl_memalign (grub_size_t align, grub_size_t size); +void +grub_dl_osdep_dl_free (void *ptr); +#endif + +static inline void +grub_dl_init (grub_dl_t mod) +{ + if (mod->init) + (mod->init) (mod); + + mod->next = grub_dl_head; + grub_dl_head = mod; +} + +static inline grub_dl_t +grub_dl_get (const char *name) +{ + grub_dl_t l; + + FOR_DL_MODULES(l) + if (grub_strcmp (name, l->name) == 0) + return l; + + return 0; +} + +static inline void +grub_dl_set_persistent (grub_dl_t mod) +{ + mod->persistent = 1; +} + +static inline int +grub_dl_is_persistent (grub_dl_t mod) +{ + return mod->persistent; +} + +#endif + +grub_err_t grub_dl_register_symbol (const char *name, void *addr, + int isfunc, grub_dl_t mod); + +grub_err_t grub_arch_dl_check_header (void *ehdr); +#ifndef GRUB_UTIL +grub_err_t +grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, + Elf_Shdr *s, grub_dl_segment_t seg); +#endif + +#if defined (__mips__) && (_MIPS_SIM != _ABI64) +#define GRUB_LINKER_HAVE_INIT 1 +void grub_arch_dl_init_linker (void); +#endif + +#define GRUB_IA64_DL_TRAMP_ALIGN 16 +#define GRUB_IA64_DL_GOT_ALIGN 16 + +grub_err_t +grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, + grub_size_t *got); +grub_err_t +grub_arm64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, + grub_size_t *got); + +#if defined (__ia64__) +#define GRUB_ARCH_DL_TRAMP_ALIGN GRUB_IA64_DL_TRAMP_ALIGN +#define GRUB_ARCH_DL_GOT_ALIGN GRUB_IA64_DL_GOT_ALIGN +#define grub_arch_dl_get_tramp_got_size grub_ia64_dl_get_tramp_got_size +#elif defined (__aarch64__) +#define grub_arch_dl_get_tramp_got_size grub_arm64_dl_get_tramp_got_size +#else +grub_err_t +grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, + grub_size_t *got); +#endif + +#if defined (__powerpc__) || (defined (__mips__) && (_MIPS_SIM != _ABI64)) || defined (__arm__) || \ + (defined(__riscv) && (__riscv_xlen == 32)) +#define GRUB_ARCH_DL_TRAMP_ALIGN 4 +#define GRUB_ARCH_DL_GOT_ALIGN 4 +#endif + +#if defined (__aarch64__) || defined (__sparc__) || (defined (__mips__) && (_MIPS_SIM == _ABI64)) || \ + (defined(__riscv) && (__riscv_xlen == 64)) +#define GRUB_ARCH_DL_TRAMP_ALIGN 8 +#define GRUB_ARCH_DL_GOT_ALIGN 8 +#endif + +#endif + +#endif /* ! GRUB_DL_H */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/efi/api.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/efi/api.h new file mode 100644 index 0000000..16cfef9 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/efi/api.h @@ -0,0 +1,1766 @@ +/* efi.h - declare EFI types and functions */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_EFI_API_HEADER +#define GRUB_EFI_API_HEADER 1 + +#include +#include + +/* For consistency and safety, we name the EFI-defined types differently. + All names are transformed into lower case, _t appended, and + grub_efi_ prepended. */ + +/* Constants. */ +#define GRUB_EFI_EVT_TIMER 0x80000000 +#define GRUB_EFI_EVT_RUNTIME 0x40000000 +#define GRUB_EFI_EVT_RUNTIME_CONTEXT 0x20000000 +#define GRUB_EFI_EVT_NOTIFY_WAIT 0x00000100 +#define GRUB_EFI_EVT_NOTIFY_SIGNAL 0x00000200 +#define GRUB_EFI_EVT_SIGNAL_EXIT_BOOT_SERVICES 0x00000201 +#define GRUB_EFI_EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE 0x60000202 + +#define GRUB_EFI_TPL_APPLICATION 4 +#define GRUB_EFI_TPL_CALLBACK 8 +#define GRUB_EFI_TPL_NOTIFY 16 +#define GRUB_EFI_TPL_HIGH_LEVEL 31 + +#define GRUB_EFI_MEMORY_UC 0x0000000000000001LL +#define GRUB_EFI_MEMORY_WC 0x0000000000000002LL +#define GRUB_EFI_MEMORY_WT 0x0000000000000004LL +#define GRUB_EFI_MEMORY_WB 0x0000000000000008LL +#define GRUB_EFI_MEMORY_UCE 0x0000000000000010LL +#define GRUB_EFI_MEMORY_WP 0x0000000000001000LL +#define GRUB_EFI_MEMORY_RP 0x0000000000002000LL +#define GRUB_EFI_MEMORY_XP 0x0000000000004000LL +#define GRUB_EFI_MEMORY_NV 0x0000000000008000LL +#define GRUB_EFI_MEMORY_MORE_RELIABLE 0x0000000000010000LL +#define GRUB_EFI_MEMORY_RO 0x0000000000020000LL +#define GRUB_EFI_MEMORY_RUNTIME 0x8000000000000000LL + +#define GRUB_EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 0x00000001 +#define GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL 0x00000002 +#define GRUB_EFI_OPEN_PROTOCOL_TEST_PROTOCOL 0x00000004 +#define GRUB_EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 0x00000008 +#define GRUB_EFI_OPEN_PROTOCOL_BY_DRIVER 0x00000010 +#define GRUB_EFI_OPEN_PROTOCOL_BY_EXCLUSIVE 0x00000020 + +#define GRUB_EFI_OS_INDICATIONS_BOOT_TO_FW_UI 0x0000000000000001ULL + +#define GRUB_EFI_VARIABLE_NON_VOLATILE 0x0000000000000001 +#define GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002 +#define GRUB_EFI_VARIABLE_RUNTIME_ACCESS 0x0000000000000004 + +#define GRUB_EFI_TIME_ADJUST_DAYLIGHT 0x01 +#define GRUB_EFI_TIME_IN_DAYLIGHT 0x02 + +#define GRUB_EFI_UNSPECIFIED_TIMEZONE 0x07FF + +#define GRUB_EFI_OPTIONAL_PTR 0x00000001 + +#define GRUB_EFI_LOADED_IMAGE_GUID \ + { 0x5b1b31a1, 0x9562, 0x11d2, \ + { 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ + } + +#define GRUB_EFI_DISK_IO_GUID \ + { 0xce345171, 0xba0b, 0x11d2, \ + { 0x8e, 0x4f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ + } + +#define GRUB_EFI_BLOCK_IO_GUID \ + { 0x964e5b21, 0x6459, 0x11d2, \ + { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ + } + +#define GRUB_EFI_SERIAL_IO_GUID \ + { 0xbb25cf6f, 0xf1d4, 0x11d2, \ + { 0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0xfd } \ + } + +#define GRUB_EFI_SIMPLE_NETWORK_GUID \ + { 0xa19832b9, 0xac25, 0x11d3, \ + { 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +#define GRUB_EFI_PXE_GUID \ + { 0x03c4e603, 0xac28, 0x11d3, \ + { 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +#define GRUB_EFI_DEVICE_PATH_GUID \ + { 0x09576e91, 0x6d3f, 0x11d2, \ + { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ + } + +#define GRUB_EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID \ + { 0x387477c1, 0x69c7, 0x11d2, \ + { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ + } + +#define GRUB_EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID \ + { 0xdd9e7534, 0x7762, 0x4698, \ + { 0x8c, 0x14, 0xf5, 0x85, 0x17, 0xa6, 0x25, 0xaa } \ + } + +#define GRUB_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID \ + { 0x387477c2, 0x69c7, 0x11d2, \ + { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ + } + +#define GRUB_EFI_SIMPLE_POINTER_PROTOCOL_GUID \ + { 0x31878c87, 0xb75, 0x11d5, \ + { 0x9a, 0x4f, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +#define GRUB_EFI_ABSOLUTE_POINTER_PROTOCOL_GUID \ + { 0x8D59D32B, 0xC655, 0x4AE9, \ + { 0x9B, 0x15, 0xF2, 0x59, 0x04, 0x99, 0x2A, 0x43 } \ + } + +#define GRUB_EFI_DRIVER_BINDING_PROTOCOL_GUID \ + { 0x18A031AB, 0xB443, 0x4D1A, \ + { 0xA5, 0xC0, 0x0C, 0x09, 0x26, 0x1E, 0x9F, 0x71 } \ + } + +#define GRUB_EFI_LOADED_IMAGE_PROTOCOL_GUID \ + { 0x5B1B31A1, 0x9562, 0x11d2, \ + { 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } \ + } + +#define GRUB_EFI_LOAD_FILE_PROTOCOL_GUID \ + { 0x56EC3091, 0x954C, 0x11d2, \ + { 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } \ + } + +#define GRUB_EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \ + { 0x0964e5b22, 0x6459, 0x11d2, \ + { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ + } + +#define GRUB_EFI_TAPE_IO_PROTOCOL_GUID \ + { 0x1e93e633, 0xd65a, 0x459e, \ + { 0xab, 0x84, 0x93, 0xd9, 0xec, 0x26, 0x6d, 0x18 } \ + } + +#define GRUB_EFI_UNICODE_COLLATION_PROTOCOL_GUID \ + { 0x1d85cd7f, 0xf43d, 0x11d2, \ + { 0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +#define GRUB_EFI_SCSI_IO_PROTOCOL_GUID \ + { 0x932f47e6, 0x2362, 0x4002, \ + { 0x80, 0x3e, 0x3c, 0xd5, 0x4b, 0x13, 0x8f, 0x85 } \ + } + +#define GRUB_EFI_USB2_HC_PROTOCOL_GUID \ + { 0x3e745226, 0x9818, 0x45b6, \ + { 0xa2, 0xac, 0xd7, 0xcd, 0x0e, 0x8b, 0xa2, 0xbc } \ + } + +#define GRUB_EFI_DEBUG_SUPPORT_PROTOCOL_GUID \ + { 0x2755590C, 0x6F3C, 0x42FA, \ + { 0x9E, 0xA4, 0xA3, 0xBA, 0x54, 0x3C, 0xDA, 0x25 } \ + } + +#define GRUB_EFI_DEBUGPORT_PROTOCOL_GUID \ + { 0xEBA4E8D2, 0x3858, 0x41EC, \ + { 0xA2, 0x81, 0x26, 0x47, 0xBA, 0x96, 0x60, 0xD0 } \ + } + +#define GRUB_EFI_DECOMPRESS_PROTOCOL_GUID \ + { 0xd8117cfe, 0x94a6, 0x11d4, \ + { 0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +#define GRUB_EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID \ + { 0x8b843e20, 0x8132, 0x4852, \ + { 0x90, 0xcc, 0x55, 0x1a, 0x4e, 0x4a, 0x7f, 0x1c } \ + } + +#define GRUB_EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID \ + { 0x379be4e, 0xd706, 0x437d, \ + { 0xb0, 0x37, 0xed, 0xb8, 0x2f, 0xb7, 0x72, 0xa4 } \ + } + +#define GRUB_EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID \ + { 0x5c99a21, 0xc70f, 0x4ad2, \ + { 0x8a, 0x5f, 0x35, 0xdf, 0x33, 0x43, 0xf5, 0x1e } \ + } + +#define GRUB_EFI_ACPI_TABLE_PROTOCOL_GUID \ + { 0xffe06bdd, 0x6107, 0x46a6, \ + { 0x7b, 0xb2, 0x5a, 0x9c, 0x7e, 0xc5, 0x27, 0x5c} \ + } + +#define GRUB_EFI_HII_CONFIG_ROUTING_PROTOCOL_GUID \ + { 0x587e72d7, 0xcc50, 0x4f79, \ + { 0x82, 0x09, 0xca, 0x29, 0x1f, 0xc1, 0xa1, 0x0f } \ + } + +#define GRUB_EFI_HII_DATABASE_PROTOCOL_GUID \ + { 0xef9fc172, 0xa1b2, 0x4693, \ + { 0xb3, 0x27, 0x6d, 0x32, 0xfc, 0x41, 0x60, 0x42 } \ + } + +#define GRUB_EFI_HII_STRING_PROTOCOL_GUID \ + { 0xfd96974, 0x23aa, 0x4cdc, \ + { 0xb9, 0xcb, 0x98, 0xd1, 0x77, 0x50, 0x32, 0x2a } \ + } + +#define GRUB_EFI_HII_IMAGE_PROTOCOL_GUID \ + { 0x31a6406a, 0x6bdf, 0x4e46, \ + { 0xb2, 0xa2, 0xeb, 0xaa, 0x89, 0xc4, 0x9, 0x20 } \ + } + +#define GRUB_EFI_HII_FONT_PROTOCOL_GUID \ + { 0xe9ca4775, 0x8657, 0x47fc, \ + { 0x97, 0xe7, 0x7e, 0xd6, 0x5a, 0x8, 0x43, 0x24 } \ + } + +#define GRUB_EFI_HII_CONFIGURATION_ACCESS_PROTOCOL_GUID \ + { 0x330d4706, 0xf2a0, 0x4e4f, \ + { 0xa3, 0x69, 0xb6, 0x6f, 0xa8, 0xd5, 0x43, 0x85 } \ + } + +#define GRUB_EFI_COMPONENT_NAME2_PROTOCOL_GUID \ + { 0x6a7a5cff, 0xe8d9, 0x4f70, \ + { 0xba, 0xda, 0x75, 0xab, 0x30, 0x25, 0xce, 0x14} \ + } + +#define GRUB_EFI_USB_IO_PROTOCOL_GUID \ + { 0x2B2F68D6, 0x0CD2, 0x44cf, \ + { 0x8E, 0x8B, 0xBB, 0xA2, 0x0B, 0x1B, 0x5B, 0x75 } \ + } + +#define GRUB_EFI_TIANO_CUSTOM_DECOMPRESS_GUID \ + { 0xa31280ad, 0x481e, 0x41b6, \ + { 0x95, 0xe8, 0x12, 0x7f, 0x4c, 0x98, 0x47, 0x79 } \ + } + +#define GRUB_EFI_CRC32_GUIDED_SECTION_EXTRACTION_GUID \ + { 0xfc1bcdb0, 0x7d31, 0x49aa, \ + { 0x93, 0x6a, 0xa4, 0x60, 0x0d, 0x9d, 0xd0, 0x83 } \ + } + +#define GRUB_EFI_LZMA_CUSTOM_DECOMPRESS_GUID \ + { 0xee4e5898, 0x3914, 0x4259, \ + { 0x9d, 0x6e, 0xdc, 0x7b, 0xd7, 0x94, 0x03, 0xcf } \ + } + +#define GRUB_EFI_TSC_FREQUENCY_GUID \ + { 0xdba6a7e3, 0xbb57, 0x4be7, \ + { 0x8a, 0xf8, 0xd5, 0x78, 0xdb, 0x7e, 0x56, 0x87 } \ + } + +#define GRUB_EFI_SYSTEM_RESOURCE_TABLE_GUID \ + { 0xb122a263, 0x3661, 0x4f68, \ + { 0x99, 0x29, 0x78, 0xf8, 0xb0, 0xd6, 0x21, 0x80 } \ + } + +#define GRUB_EFI_DXE_SERVICES_TABLE_GUID \ + { 0x05ad34ba, 0x6f02, 0x4214, \ + { 0x95, 0x2e, 0x4d, 0xa0, 0x39, 0x8e, 0x2b, 0xb9 } \ + } + +#define GRUB_EFI_HOB_LIST_GUID \ + { 0x7739f24c, 0x93d7, 0x11d4, \ + { 0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +#define GRUB_EFI_MEMORY_TYPE_INFORMATION_GUID \ + { 0x4c19049f, 0x4137, 0x4dd3, \ + { 0x9c, 0x10, 0x8b, 0x97, 0xa8, 0x3f, 0xfd, 0xfa } \ + } + +#define GRUB_EFI_DEBUG_IMAGE_INFO_TABLE_GUID \ + { 0x49152e77, 0x1ada, 0x4764, \ + { 0xb7, 0xa2, 0x7a, 0xfe, 0xfe, 0xd9, 0x5e, 0x8b } \ + } + +#define GRUB_EFI_MPS_TABLE_GUID \ + { 0xeb9d2d2f, 0x2d88, 0x11d3, \ + { 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +#define GRUB_EFI_ACPI_TABLE_GUID \ + { 0xeb9d2d30, 0x2d88, 0x11d3, \ + { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +#define GRUB_EFI_ACPI_20_TABLE_GUID \ + { 0x8868e871, 0xe4f1, 0x11d3, \ + { 0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \ + } + +#define GRUB_EFI_SMBIOS_TABLE_GUID \ + { 0xeb9d2d31, 0x2d88, 0x11d3, \ + { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +#define GRUB_EFI_SMBIOS3_TABLE_GUID \ + { 0xf2fd1544, 0x9794, 0x4a2c, \ + { 0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94 } \ + } + +#define GRUB_EFI_SAL_TABLE_GUID \ + { 0xeb9d2d32, 0x2d88, 0x11d3, \ + { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +#define GRUB_EFI_HCDP_TABLE_GUID \ + { 0xf951938d, 0x620b, 0x42ef, \ + { 0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98 } \ + } + +#define GRUB_EFI_DEVICE_TREE_GUID \ + { 0xb1b621d5, 0xf19c, 0x41a5, \ + { 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0 } \ + } + +#define GRUB_EFI_VENDOR_APPLE_GUID \ + { 0x2B0585EB, 0xD8B8, 0x49A9, \ + { 0x8B, 0x8C, 0xE2, 0x1B, 0x01, 0xAE, 0xF2, 0xB7 } \ + } + +struct grub_efi_sal_system_table +{ + grub_uint32_t signature; + grub_uint32_t total_table_len; + grub_uint16_t sal_rev; + grub_uint16_t entry_count; + grub_uint8_t checksum; + grub_uint8_t reserved1[7]; + grub_uint16_t sal_a_version; + grub_uint16_t sal_b_version; + grub_uint8_t oem_id[32]; + grub_uint8_t product_id[32]; + grub_uint8_t reserved2[8]; + grub_uint8_t entries[0]; +}; + +enum + { + GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_ENTRYPOINT_DESCRIPTOR = 0, + GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_MEMORY_DESCRIPTOR = 1, + GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_PLATFORM_FEATURES = 2, + GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_TRANSLATION_REGISTER_DESCRIPTOR = 3, + GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_PURGE_TRANSLATION_COHERENCE = 4, + GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_AP_WAKEUP = 5 + }; + +struct grub_efi_sal_system_table_entrypoint_descriptor +{ + grub_uint8_t type; + grub_uint8_t pad[7]; + grub_uint64_t pal_proc_addr; + grub_uint64_t sal_proc_addr; + grub_uint64_t global_data_ptr; + grub_uint64_t reserved[2]; +}; + +struct grub_efi_sal_system_table_memory_descriptor +{ + grub_uint8_t type; + grub_uint8_t sal_used; + grub_uint8_t attr; + grub_uint8_t ar; + grub_uint8_t attr_mask; + grub_uint8_t mem_type; + grub_uint8_t usage; + grub_uint8_t unknown; + grub_uint64_t addr; + grub_uint64_t len; + grub_uint64_t unknown2; +}; + +struct grub_efi_sal_system_table_platform_features +{ + grub_uint8_t type; + grub_uint8_t flags; + grub_uint8_t reserved[14]; +}; + +struct grub_efi_sal_system_table_translation_register_descriptor +{ + grub_uint8_t type; + grub_uint8_t register_type; + grub_uint8_t register_number; + grub_uint8_t reserved[5]; + grub_uint64_t addr; + grub_uint64_t page_size; + grub_uint64_t reserver; +}; + +struct grub_efi_sal_system_table_purge_translation_coherence +{ + grub_uint8_t type; + grub_uint8_t reserved[3]; + grub_uint32_t ndomains; + grub_uint64_t coherence; +}; + +struct grub_efi_sal_system_table_ap_wakeup +{ + grub_uint8_t type; + grub_uint8_t mechanism; + grub_uint8_t reserved[6]; + grub_uint64_t vector; +}; + +enum + { + GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_BUSLOCK = 1, + GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_IRQREDIRECT = 2, + GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_IPIREDIRECT = 4, + GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_ITCDRIFT = 8, + }; + +typedef enum grub_efi_parity_type + { + GRUB_EFI_SERIAL_DEFAULT_PARITY, + GRUB_EFI_SERIAL_NO_PARITY, + GRUB_EFI_SERIAL_EVEN_PARITY, + GRUB_EFI_SERIAL_ODD_PARITY + } +grub_efi_parity_type_t; + +typedef enum grub_efi_stop_bits + { + GRUB_EFI_SERIAL_DEFAULT_STOP_BITS, + GRUB_EFI_SERIAL_1_STOP_BIT, + GRUB_EFI_SERIAL_1_5_STOP_BITS, + GRUB_EFI_SERIAL_2_STOP_BITS + } + grub_efi_stop_bits_t; + +/* Enumerations. */ +enum grub_efi_timer_delay + { + GRUB_EFI_TIMER_CANCEL, + GRUB_EFI_TIMER_PERIODIC, + GRUB_EFI_TIMER_RELATIVE + }; +typedef enum grub_efi_timer_delay grub_efi_timer_delay_t; + +enum grub_efi_allocate_type + { + GRUB_EFI_ALLOCATE_ANY_PAGES, + GRUB_EFI_ALLOCATE_MAX_ADDRESS, + GRUB_EFI_ALLOCATE_ADDRESS, + GRUB_EFI_MAX_ALLOCATION_TYPE + }; +typedef enum grub_efi_allocate_type grub_efi_allocate_type_t; + +enum grub_efi_memory_type + { + GRUB_EFI_RESERVED_MEMORY_TYPE, + GRUB_EFI_LOADER_CODE, + GRUB_EFI_LOADER_DATA, + GRUB_EFI_BOOT_SERVICES_CODE, + GRUB_EFI_BOOT_SERVICES_DATA, + GRUB_EFI_RUNTIME_SERVICES_CODE, + GRUB_EFI_RUNTIME_SERVICES_DATA, + GRUB_EFI_CONVENTIONAL_MEMORY, + GRUB_EFI_UNUSABLE_MEMORY, + GRUB_EFI_ACPI_RECLAIM_MEMORY, + GRUB_EFI_ACPI_MEMORY_NVS, + GRUB_EFI_MEMORY_MAPPED_IO, + GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE, + GRUB_EFI_PAL_CODE, + GRUB_EFI_PERSISTENT_MEMORY, + GRUB_EFI_MAX_MEMORY_TYPE + }; +typedef enum grub_efi_memory_type grub_efi_memory_type_t; + +enum grub_efi_interface_type + { + GRUB_EFI_NATIVE_INTERFACE + }; +typedef enum grub_efi_interface_type grub_efi_interface_type_t; + +enum grub_efi_locate_search_type + { + GRUB_EFI_ALL_HANDLES, + GRUB_EFI_BY_REGISTER_NOTIFY, + GRUB_EFI_BY_PROTOCOL + }; +typedef enum grub_efi_locate_search_type grub_efi_locate_search_type_t; + +enum grub_efi_reset_type + { + GRUB_EFI_RESET_COLD, + GRUB_EFI_RESET_WARM, + GRUB_EFI_RESET_SHUTDOWN + }; +typedef enum grub_efi_reset_type grub_efi_reset_type_t; + +/* Types. */ +typedef char grub_efi_boolean_t; +#if GRUB_CPU_SIZEOF_VOID_P == 8 +typedef grub_int64_t grub_efi_intn_t; +typedef grub_uint64_t grub_efi_uintn_t; +#else +typedef grub_int32_t grub_efi_intn_t; +typedef grub_uint32_t grub_efi_uintn_t; +#endif +typedef grub_int8_t grub_efi_int8_t; +typedef grub_uint8_t grub_efi_uint8_t; +typedef grub_int16_t grub_efi_int16_t; +typedef grub_uint16_t grub_efi_uint16_t; +typedef grub_int32_t grub_efi_int32_t; +typedef grub_uint32_t grub_efi_uint32_t; +typedef grub_int64_t grub_efi_int64_t; +typedef grub_uint64_t grub_efi_uint64_t; +typedef grub_uint8_t grub_efi_char8_t; +typedef grub_uint16_t grub_efi_char16_t; + +typedef grub_efi_intn_t grub_efi_status_t; + +#define GRUB_EFI_ERROR_CODE(value) \ + ((((grub_efi_status_t) 1) << (sizeof (grub_efi_status_t) * 8 - 1)) | (value)) + +#define GRUB_EFI_WARNING_CODE(value) (value) + +#define GRUB_EFI_SUCCESS 0 + +#define GRUB_EFI_LOAD_ERROR GRUB_EFI_ERROR_CODE (1) +#define GRUB_EFI_INVALID_PARAMETER GRUB_EFI_ERROR_CODE (2) +#define GRUB_EFI_UNSUPPORTED GRUB_EFI_ERROR_CODE (3) +#define GRUB_EFI_BAD_BUFFER_SIZE GRUB_EFI_ERROR_CODE (4) +#define GRUB_EFI_BUFFER_TOO_SMALL GRUB_EFI_ERROR_CODE (5) +#define GRUB_EFI_NOT_READY GRUB_EFI_ERROR_CODE (6) +#define GRUB_EFI_DEVICE_ERROR GRUB_EFI_ERROR_CODE (7) +#define GRUB_EFI_WRITE_PROTECTED GRUB_EFI_ERROR_CODE (8) +#define GRUB_EFI_OUT_OF_RESOURCES GRUB_EFI_ERROR_CODE (9) +#define GRUB_EFI_VOLUME_CORRUPTED GRUB_EFI_ERROR_CODE (10) +#define GRUB_EFI_VOLUME_FULL GRUB_EFI_ERROR_CODE (11) +#define GRUB_EFI_NO_MEDIA GRUB_EFI_ERROR_CODE (12) +#define GRUB_EFI_MEDIA_CHANGED GRUB_EFI_ERROR_CODE (13) +#define GRUB_EFI_NOT_FOUND GRUB_EFI_ERROR_CODE (14) +#define GRUB_EFI_ACCESS_DENIED GRUB_EFI_ERROR_CODE (15) +#define GRUB_EFI_NO_RESPONSE GRUB_EFI_ERROR_CODE (16) +#define GRUB_EFI_NO_MAPPING GRUB_EFI_ERROR_CODE (17) +#define GRUB_EFI_TIMEOUT GRUB_EFI_ERROR_CODE (18) +#define GRUB_EFI_NOT_STARTED GRUB_EFI_ERROR_CODE (19) +#define GRUB_EFI_ALREADY_STARTED GRUB_EFI_ERROR_CODE (20) +#define GRUB_EFI_ABORTED GRUB_EFI_ERROR_CODE (21) +#define GRUB_EFI_ICMP_ERROR GRUB_EFI_ERROR_CODE (22) +#define GRUB_EFI_TFTP_ERROR GRUB_EFI_ERROR_CODE (23) +#define GRUB_EFI_PROTOCOL_ERROR GRUB_EFI_ERROR_CODE (24) +#define GRUB_EFI_INCOMPATIBLE_VERSION GRUB_EFI_ERROR_CODE (25) +#define GRUB_EFI_SECURITY_VIOLATION GRUB_EFI_ERROR_CODE (26) +#define GRUB_EFI_CRC_ERROR GRUB_EFI_ERROR_CODE (27) + +#define GRUB_EFI_WARN_UNKNOWN_GLYPH GRUB_EFI_WARNING_CODE (1) +#define GRUB_EFI_WARN_DELETE_FAILURE GRUB_EFI_WARNING_CODE (2) +#define GRUB_EFI_WARN_WRITE_FAILURE GRUB_EFI_WARNING_CODE (3) +#define GRUB_EFI_WARN_BUFFER_TOO_SMALL GRUB_EFI_WARNING_CODE (4) + +typedef void *grub_efi_handle_t; +typedef void *grub_efi_event_t; +typedef grub_efi_uint64_t grub_efi_lba_t; +typedef grub_efi_uintn_t grub_efi_tpl_t; +typedef grub_uint8_t grub_efi_mac_address_t[32]; +typedef grub_uint8_t grub_efi_ipv4_address_t[4]; +typedef grub_uint16_t grub_efi_ipv6_address_t[8]; +typedef grub_uint8_t grub_efi_ip_address_t[8] __attribute__ ((aligned(4))); +typedef grub_efi_uint64_t grub_efi_physical_address_t; +typedef grub_efi_uint64_t grub_efi_virtual_address_t; + +struct grub_efi_guid +{ + grub_uint32_t data1; + grub_uint16_t data2; + grub_uint16_t data3; + grub_uint8_t data4[8]; +} __attribute__ ((aligned(8))); +typedef struct grub_efi_guid grub_efi_guid_t; + +struct grub_efi_packed_guid +{ + grub_uint32_t data1; + grub_uint16_t data2; + grub_uint16_t data3; + grub_uint8_t data4[8]; +} GRUB_PACKED; +typedef struct grub_efi_packed_guid grub_efi_packed_guid_t; + +/* XXX although the spec does not specify the padding, this actually + must have the padding! */ +struct grub_efi_memory_descriptor +{ + grub_efi_uint32_t type; + grub_efi_uint32_t padding; + grub_efi_physical_address_t physical_start; + grub_efi_virtual_address_t virtual_start; + grub_efi_uint64_t num_pages; + grub_efi_uint64_t attribute; +} GRUB_PACKED; +typedef struct grub_efi_memory_descriptor grub_efi_memory_descriptor_t; + +/* Device Path definitions. */ +struct grub_efi_device_path +{ + grub_efi_uint8_t type; + grub_efi_uint8_t subtype; + grub_efi_uint16_t length; +} GRUB_PACKED; +typedef struct grub_efi_device_path grub_efi_device_path_t; +/* XXX EFI does not define EFI_DEVICE_PATH_PROTOCOL but uses it. + It seems to be identical to EFI_DEVICE_PATH. */ +typedef struct grub_efi_device_path grub_efi_device_path_protocol_t; + +#define GRUB_EFI_DEVICE_PATH_TYPE(dp) ((dp)->type & 0x7f) +#define GRUB_EFI_DEVICE_PATH_SUBTYPE(dp) ((dp)->subtype) +#define GRUB_EFI_DEVICE_PATH_LENGTH(dp) ((dp)->length) + +/* The End of Device Path nodes. */ +#define GRUB_EFI_END_DEVICE_PATH_TYPE (0xff & 0x7f) + +#define GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE 0xff +#define GRUB_EFI_END_THIS_DEVICE_PATH_SUBTYPE 0x01 + +#define GRUB_EFI_END_ENTIRE_DEVICE_PATH(dp) \ + (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_END_DEVICE_PATH_TYPE \ + && (GRUB_EFI_DEVICE_PATH_SUBTYPE (dp) \ + == GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE)) + +#define GRUB_EFI_NEXT_DEVICE_PATH(dp) \ + ((grub_efi_device_path_t *) ((char *) (dp) \ + + GRUB_EFI_DEVICE_PATH_LENGTH (dp))) + +/* Hardware Device Path. */ +#define GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE 1 + +#define GRUB_EFI_PCI_DEVICE_PATH_SUBTYPE 1 + +struct grub_efi_pci_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint8_t function; + grub_efi_uint8_t device; +} GRUB_PACKED; +typedef struct grub_efi_pci_device_path grub_efi_pci_device_path_t; + +#define GRUB_EFI_PCCARD_DEVICE_PATH_SUBTYPE 2 + +struct grub_efi_pccard_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint8_t function; +} GRUB_PACKED; +typedef struct grub_efi_pccard_device_path grub_efi_pccard_device_path_t; + +#define GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE 3 + +struct grub_efi_memory_mapped_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint32_t memory_type; + grub_efi_physical_address_t start_address; + grub_efi_physical_address_t end_address; +} GRUB_PACKED; +typedef struct grub_efi_memory_mapped_device_path grub_efi_memory_mapped_device_path_t; + +#define GRUB_EFI_VENDOR_DEVICE_PATH_SUBTYPE 4 + +struct grub_efi_vendor_device_path +{ + grub_efi_device_path_t header; + grub_efi_packed_guid_t vendor_guid; + grub_efi_uint8_t vendor_defined_data[0]; +} GRUB_PACKED; +typedef struct grub_efi_vendor_device_path grub_efi_vendor_device_path_t; + +#define GRUB_EFI_CONTROLLER_DEVICE_PATH_SUBTYPE 5 + +struct grub_efi_controller_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint32_t controller_number; +} GRUB_PACKED; +typedef struct grub_efi_controller_device_path grub_efi_controller_device_path_t; + +/* ACPI Device Path. */ +#define GRUB_EFI_ACPI_DEVICE_PATH_TYPE 2 + +#define GRUB_EFI_ACPI_DEVICE_PATH_SUBTYPE 1 + +struct grub_efi_acpi_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint32_t hid; + grub_efi_uint32_t uid; +} GRUB_PACKED; +typedef struct grub_efi_acpi_device_path grub_efi_acpi_device_path_t; + +#define GRUB_EFI_EXPANDED_ACPI_DEVICE_PATH_SUBTYPE 2 + +struct grub_efi_expanded_acpi_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint32_t hid; + grub_efi_uint32_t uid; + grub_efi_uint32_t cid; + char hidstr[0]; +} GRUB_PACKED; +typedef struct grub_efi_expanded_acpi_device_path grub_efi_expanded_acpi_device_path_t; + +#define GRUB_EFI_EXPANDED_ACPI_HIDSTR(dp) \ + (((grub_efi_expanded_acpi_device_path_t *) dp)->hidstr) +#define GRUB_EFI_EXPANDED_ACPI_UIDSTR(dp) \ + (GRUB_EFI_EXPANDED_ACPI_HIDSTR(dp) \ + + grub_strlen (GRUB_EFI_EXPANDED_ACPI_HIDSTR(dp)) + 1) +#define GRUB_EFI_EXPANDED_ACPI_CIDSTR(dp) \ + (GRUB_EFI_EXPANDED_ACPI_UIDSTR(dp) \ + + grub_strlen (GRUB_EFI_EXPANDED_ACPI_UIDSTR(dp)) + 1) + +/* Messaging Device Path. */ +#define GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE 3 + +#define GRUB_EFI_ATAPI_DEVICE_PATH_SUBTYPE 1 + +struct grub_efi_atapi_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint8_t primary_secondary; + grub_efi_uint8_t slave_master; + grub_efi_uint16_t lun; +} GRUB_PACKED; +typedef struct grub_efi_atapi_device_path grub_efi_atapi_device_path_t; + +#define GRUB_EFI_SCSI_DEVICE_PATH_SUBTYPE 2 + +struct grub_efi_scsi_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint16_t pun; + grub_efi_uint16_t lun; +} GRUB_PACKED; +typedef struct grub_efi_scsi_device_path grub_efi_scsi_device_path_t; + +#define GRUB_EFI_FIBRE_CHANNEL_DEVICE_PATH_SUBTYPE 3 + +struct grub_efi_fibre_channel_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint32_t reserved; + grub_efi_uint64_t wwn; + grub_efi_uint64_t lun; +} GRUB_PACKED; +typedef struct grub_efi_fibre_channel_device_path grub_efi_fibre_channel_device_path_t; + +#define GRUB_EFI_1394_DEVICE_PATH_SUBTYPE 4 + +struct grub_efi_1394_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint32_t reserved; + grub_efi_uint64_t guid; +} GRUB_PACKED; +typedef struct grub_efi_1394_device_path grub_efi_1394_device_path_t; + +#define GRUB_EFI_USB_DEVICE_PATH_SUBTYPE 5 + +struct grub_efi_usb_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint8_t parent_port_number; + grub_efi_uint8_t usb_interface; +} GRUB_PACKED; +typedef struct grub_efi_usb_device_path grub_efi_usb_device_path_t; + +#define GRUB_EFI_USB_CLASS_DEVICE_PATH_SUBTYPE 15 + +struct grub_efi_usb_class_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint16_t vendor_id; + grub_efi_uint16_t product_id; + grub_efi_uint8_t device_class; + grub_efi_uint8_t device_subclass; + grub_efi_uint8_t device_protocol; +} GRUB_PACKED; +typedef struct grub_efi_usb_class_device_path grub_efi_usb_class_device_path_t; + +#define GRUB_EFI_I2O_DEVICE_PATH_SUBTYPE 6 + +struct grub_efi_i2o_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint32_t tid; +} GRUB_PACKED; +typedef struct grub_efi_i2o_device_path grub_efi_i2o_device_path_t; + +#define GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE 11 + +struct grub_efi_mac_address_device_path +{ + grub_efi_device_path_t header; + grub_efi_mac_address_t mac_address; + grub_efi_uint8_t if_type; +} GRUB_PACKED; +typedef struct grub_efi_mac_address_device_path grub_efi_mac_address_device_path_t; + +#define GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE 12 + +struct grub_efi_ipv4_device_path +{ + grub_efi_device_path_t header; + grub_efi_ipv4_address_t local_ip_address; + grub_efi_ipv4_address_t remote_ip_address; + grub_efi_uint16_t local_port; + grub_efi_uint16_t remote_port; + grub_efi_uint16_t protocol; + grub_efi_uint8_t static_ip_address; +} GRUB_PACKED; +typedef struct grub_efi_ipv4_device_path grub_efi_ipv4_device_path_t; + +#define GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE 13 + +struct grub_efi_ipv6_device_path +{ + grub_efi_device_path_t header; + grub_efi_ipv6_address_t local_ip_address; + grub_efi_ipv6_address_t remote_ip_address; + grub_efi_uint16_t local_port; + grub_efi_uint16_t remote_port; + grub_efi_uint16_t protocol; + grub_efi_uint8_t static_ip_address; +} GRUB_PACKED; +typedef struct grub_efi_ipv6_device_path grub_efi_ipv6_device_path_t; + +#define GRUB_EFI_INFINIBAND_DEVICE_PATH_SUBTYPE 9 + +struct grub_efi_infiniband_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint32_t resource_flags; + grub_efi_uint8_t port_gid[16]; + grub_efi_uint64_t remote_id; + grub_efi_uint64_t target_port_id; + grub_efi_uint64_t device_id; +} GRUB_PACKED; +typedef struct grub_efi_infiniband_device_path grub_efi_infiniband_device_path_t; + +#define GRUB_EFI_UART_DEVICE_PATH_SUBTYPE 14 + +struct grub_efi_uart_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint32_t reserved; + grub_efi_uint64_t baud_rate; + grub_efi_uint8_t data_bits; + grub_efi_uint8_t parity; + grub_efi_uint8_t stop_bits; +} GRUB_PACKED; +typedef struct grub_efi_uart_device_path grub_efi_uart_device_path_t; + +#define GRUB_EFI_SATA_DEVICE_PATH_SUBTYPE 18 + +struct grub_efi_sata_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint16_t hba_port; + grub_efi_uint16_t multiplier_port; + grub_efi_uint16_t lun; +} GRUB_PACKED; +typedef struct grub_efi_sata_device_path grub_efi_sata_device_path_t; + +#define GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE 10 + +/* Media Device Path. */ +#define GRUB_EFI_MEDIA_DEVICE_PATH_TYPE 4 + +#define GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE 1 + +struct grub_efi_hard_drive_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint32_t partition_number; + grub_efi_lba_t partition_start; + grub_efi_lba_t partition_size; + grub_efi_uint8_t partition_signature[16]; + grub_efi_uint8_t partmap_type; + grub_efi_uint8_t signature_type; +} GRUB_PACKED; +typedef struct grub_efi_hard_drive_device_path grub_efi_hard_drive_device_path_t; + +#define GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE 2 + +struct grub_efi_cdrom_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint32_t boot_entry; + grub_efi_lba_t partition_start; + grub_efi_lba_t partition_size; +} GRUB_PACKED; +typedef struct grub_efi_cdrom_device_path grub_efi_cdrom_device_path_t; + +#define GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE 3 + +struct grub_efi_vendor_media_device_path +{ + grub_efi_device_path_t header; + grub_efi_packed_guid_t vendor_guid; + grub_efi_uint8_t vendor_defined_data[0]; +} GRUB_PACKED; +typedef struct grub_efi_vendor_media_device_path grub_efi_vendor_media_device_path_t; + +#define GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE 4 + +struct grub_efi_file_path_device_path +{ + grub_efi_device_path_t header; + grub_efi_char16_t path_name[0]; +} GRUB_PACKED; +typedef struct grub_efi_file_path_device_path grub_efi_file_path_device_path_t; + +#define GRUB_EFI_PROTOCOL_DEVICE_PATH_SUBTYPE 5 + +struct grub_efi_protocol_device_path +{ + grub_efi_device_path_t header; + grub_efi_packed_guid_t guid; +} GRUB_PACKED; +typedef struct grub_efi_protocol_device_path grub_efi_protocol_device_path_t; + +#define GRUB_EFI_PIWG_DEVICE_PATH_SUBTYPE 6 + +struct grub_efi_piwg_device_path +{ + grub_efi_device_path_t header; + grub_efi_packed_guid_t guid; +} GRUB_PACKED; +typedef struct grub_efi_piwg_device_path grub_efi_piwg_device_path_t; + + +/* BIOS Boot Specification Device Path. */ +#define GRUB_EFI_BIOS_DEVICE_PATH_TYPE 5 + +#define GRUB_EFI_BIOS_DEVICE_PATH_SUBTYPE 1 + +struct grub_efi_bios_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint16_t device_type; + grub_efi_uint16_t status_flags; + char description[0]; +} GRUB_PACKED; +typedef struct grub_efi_bios_device_path grub_efi_bios_device_path_t; + +struct grub_efi_open_protocol_information_entry +{ + grub_efi_handle_t agent_handle; + grub_efi_handle_t controller_handle; + grub_efi_uint32_t attributes; + grub_efi_uint32_t open_count; +}; +typedef struct grub_efi_open_protocol_information_entry grub_efi_open_protocol_information_entry_t; + +struct grub_efi_time +{ + grub_efi_uint16_t year; + grub_efi_uint8_t month; + grub_efi_uint8_t day; + grub_efi_uint8_t hour; + grub_efi_uint8_t minute; + grub_efi_uint8_t second; + grub_efi_uint8_t pad1; + grub_efi_uint32_t nanosecond; + grub_efi_int16_t time_zone; + grub_efi_uint8_t daylight; + grub_efi_uint8_t pad2; +} GRUB_PACKED; +typedef struct grub_efi_time grub_efi_time_t; + +struct grub_efi_time_capabilities +{ + grub_efi_uint32_t resolution; + grub_efi_uint32_t accuracy; + grub_efi_boolean_t sets_to_zero; +}; +typedef struct grub_efi_time_capabilities grub_efi_time_capabilities_t; + +struct grub_efi_input_key +{ + grub_efi_uint16_t scan_code; + grub_efi_char16_t unicode_char; +}; +typedef struct grub_efi_input_key grub_efi_input_key_t; + +typedef grub_efi_uint8_t grub_efi_key_toggle_state_t; +struct grub_efi_key_state +{ + grub_efi_uint32_t key_shift_state; + grub_efi_key_toggle_state_t key_toggle_state; +}; +typedef struct grub_efi_key_state grub_efi_key_state_t; + +#define GRUB_EFI_SHIFT_STATE_VALID 0x80000000 +#define GRUB_EFI_RIGHT_SHIFT_PRESSED 0x00000001 +#define GRUB_EFI_LEFT_SHIFT_PRESSED 0x00000002 +#define GRUB_EFI_RIGHT_CONTROL_PRESSED 0x00000004 +#define GRUB_EFI_LEFT_CONTROL_PRESSED 0x00000008 +#define GRUB_EFI_RIGHT_ALT_PRESSED 0x00000010 +#define GRUB_EFI_LEFT_ALT_PRESSED 0x00000020 +#define GRUB_EFI_RIGHT_LOGO_PRESSED 0x00000040 +#define GRUB_EFI_LEFT_LOGO_PRESSED 0x00000080 +#define GRUB_EFI_MENU_KEY_PRESSED 0x00000100 +#define GRUB_EFI_SYS_REQ_PRESSED 0x00000200 + +#define GRUB_EFI_TOGGLE_STATE_VALID 0x80 +#define GRUB_EFI_KEY_STATE_EXPOSED 0x40 +#define GRUB_EFI_SCROLL_LOCK_ACTIVE 0x01 +#define GRUB_EFI_NUM_LOCK_ACTIVE 0x02 +#define GRUB_EFI_CAPS_LOCK_ACTIVE 0x04 + +struct grub_efi_simple_text_output_mode +{ + grub_efi_int32_t max_mode; + grub_efi_int32_t mode; + grub_efi_int32_t attribute; + grub_efi_int32_t cursor_column; + grub_efi_int32_t cursor_row; + grub_efi_boolean_t cursor_visible; +}; +typedef struct grub_efi_simple_text_output_mode grub_efi_simple_text_output_mode_t; + +/* Tables. */ +struct grub_efi_table_header +{ + grub_efi_uint64_t signature; + grub_efi_uint32_t revision; + grub_efi_uint32_t header_size; + grub_efi_uint32_t crc32; + grub_efi_uint32_t reserved; +}; +typedef struct grub_efi_table_header grub_efi_table_header_t; + +struct grub_efi_boot_services +{ + grub_efi_table_header_t hdr; + + grub_efi_tpl_t + (*raise_tpl) (grub_efi_tpl_t new_tpl); + + void + (*restore_tpl) (grub_efi_tpl_t old_tpl); + + grub_efi_status_t + (*allocate_pages) (grub_efi_allocate_type_t type, + grub_efi_memory_type_t memory_type, + grub_efi_uintn_t pages, + grub_efi_physical_address_t *memory); + + grub_efi_status_t + (*free_pages) (grub_efi_physical_address_t memory, + grub_efi_uintn_t pages); + + grub_efi_status_t + (*get_memory_map) (grub_efi_uintn_t *memory_map_size, + grub_efi_memory_descriptor_t *memory_map, + grub_efi_uintn_t *map_key, + grub_efi_uintn_t *descriptor_size, + grub_efi_uint32_t *descriptor_version); + + grub_efi_status_t + (*allocate_pool) (grub_efi_memory_type_t pool_type, + grub_efi_uintn_t size, + void **buffer); + + grub_efi_status_t + (*free_pool) (void *buffer); + + grub_efi_status_t + (*create_event) (grub_efi_uint32_t type, + grub_efi_tpl_t notify_tpl, + void (*notify_function) (grub_efi_event_t event, + void *context), + void *notify_context, + grub_efi_event_t *event); + + grub_efi_status_t + (*set_timer) (grub_efi_event_t event, + grub_efi_timer_delay_t type, + grub_efi_uint64_t trigger_time); + + grub_efi_status_t + (*wait_for_event) (grub_efi_uintn_t num_events, + grub_efi_event_t *event, + grub_efi_uintn_t *index); + + grub_efi_status_t + (*signal_event) (grub_efi_event_t event); + + grub_efi_status_t + (*close_event) (grub_efi_event_t event); + + grub_efi_status_t + (*check_event) (grub_efi_event_t event); + + grub_efi_status_t + (*install_protocol_interface) (grub_efi_handle_t *handle, + grub_efi_guid_t *protocol, + grub_efi_interface_type_t protocol_interface_type, + void *protocol_interface); + + grub_efi_status_t + (*reinstall_protocol_interface) (grub_efi_handle_t handle, + grub_efi_guid_t *protocol, + void *old_interface, + void *new_interface); + + grub_efi_status_t + (*uninstall_protocol_interface) (grub_efi_handle_t handle, + grub_efi_guid_t *protocol, + void *protocol_interface); + + grub_efi_status_t + (*handle_protocol) (grub_efi_handle_t handle, + grub_efi_guid_t *protocol, + void **protocol_interface); + + void *reserved; + + grub_efi_status_t + (*register_protocol_notify) (grub_efi_guid_t *protocol, + grub_efi_event_t event, + void **registration); + + grub_efi_status_t + (*locate_handle) (grub_efi_locate_search_type_t search_type, + grub_efi_guid_t *protocol, + void *search_key, + grub_efi_uintn_t *buffer_size, + grub_efi_handle_t *buffer); + + grub_efi_status_t + (*locate_device_path) (grub_efi_guid_t *protocol, + grub_efi_device_path_t **device_path, + grub_efi_handle_t *device); + + grub_efi_status_t + (*install_configuration_table) (grub_efi_guid_t *guid, void *table); + + grub_efi_status_t + (*load_image) (grub_efi_boolean_t boot_policy, + grub_efi_handle_t parent_image_handle, + grub_efi_device_path_t *file_path, + void *source_buffer, + grub_efi_uintn_t source_size, + grub_efi_handle_t *image_handle); + + grub_efi_status_t + (*start_image) (grub_efi_handle_t image_handle, + grub_efi_uintn_t *exit_data_size, + grub_efi_char16_t **exit_data); + + grub_efi_status_t + (*exit) (grub_efi_handle_t image_handle, + grub_efi_status_t exit_status, + grub_efi_uintn_t exit_data_size, + grub_efi_char16_t *exit_data) __attribute__((noreturn)); + + grub_efi_status_t + (*unload_image) (grub_efi_handle_t image_handle); + + grub_efi_status_t + (*exit_boot_services) (grub_efi_handle_t image_handle, + grub_efi_uintn_t map_key); + + grub_efi_status_t + (*get_next_monotonic_count) (grub_efi_uint64_t *count); + + grub_efi_status_t + (*stall) (grub_efi_uintn_t microseconds); + + grub_efi_status_t + (*set_watchdog_timer) (grub_efi_uintn_t timeout, + grub_efi_uint64_t watchdog_code, + grub_efi_uintn_t data_size, + grub_efi_char16_t *watchdog_data); + + grub_efi_status_t + (*connect_controller) (grub_efi_handle_t controller_handle, + grub_efi_handle_t *driver_image_handle, + grub_efi_device_path_protocol_t *remaining_device_path, + grub_efi_boolean_t recursive); + + grub_efi_status_t + (*disconnect_controller) (grub_efi_handle_t controller_handle, + grub_efi_handle_t driver_image_handle, + grub_efi_handle_t child_handle); + + grub_efi_status_t + (*open_protocol) (grub_efi_handle_t handle, + grub_efi_guid_t *protocol, + void **protocol_interface, + grub_efi_handle_t agent_handle, + grub_efi_handle_t controller_handle, + grub_efi_uint32_t attributes); + + grub_efi_status_t + (*close_protocol) (grub_efi_handle_t handle, + grub_efi_guid_t *protocol, + grub_efi_handle_t agent_handle, + grub_efi_handle_t controller_handle); + + grub_efi_status_t + (*open_protocol_information) (grub_efi_handle_t handle, + grub_efi_guid_t *protocol, + grub_efi_open_protocol_information_entry_t **entry_buffer, + grub_efi_uintn_t *entry_count); + + grub_efi_status_t + (*protocols_per_handle) (grub_efi_handle_t handle, + grub_efi_packed_guid_t ***protocol_buffer, + grub_efi_uintn_t *protocol_buffer_count); + + grub_efi_status_t + (*locate_handle_buffer) (grub_efi_locate_search_type_t search_type, + grub_efi_guid_t *protocol, + void *search_key, + grub_efi_uintn_t *no_handles, + grub_efi_handle_t **buffer); + + grub_efi_status_t + (*locate_protocol) (grub_efi_guid_t *protocol, + void *registration, + void **protocol_interface); + + grub_efi_status_t + (*install_multiple_protocol_interfaces) (grub_efi_handle_t *handle, ...); + + grub_efi_status_t + (*uninstall_multiple_protocol_interfaces) (grub_efi_handle_t handle, ...); + + grub_efi_status_t + (*calculate_crc32) (void *data, + grub_efi_uintn_t data_size, + grub_efi_uint32_t *crc32); + + void + (*copy_mem) (void *destination, void *source, grub_efi_uintn_t length); + + void + (*set_mem) (void *buffer, grub_efi_uintn_t size, grub_efi_uint8_t value); +}; +typedef struct grub_efi_boot_services grub_efi_boot_services_t; + +struct grub_efi_runtime_services +{ + grub_efi_table_header_t hdr; + + grub_efi_status_t + (*get_time) (grub_efi_time_t *time, + grub_efi_time_capabilities_t *capabilities); + + grub_efi_status_t + (*set_time) (grub_efi_time_t *time); + + grub_efi_status_t + (*get_wakeup_time) (grub_efi_boolean_t *enabled, + grub_efi_boolean_t *pending, + grub_efi_time_t *time); + + grub_efi_status_t + (*set_wakeup_time) (grub_efi_boolean_t enabled, + grub_efi_time_t *time); + + grub_efi_status_t + (*set_virtual_address_map) (grub_efi_uintn_t memory_map_size, + grub_efi_uintn_t descriptor_size, + grub_efi_uint32_t descriptor_version, + grub_efi_memory_descriptor_t *virtual_map); + + grub_efi_status_t + (*convert_pointer) (grub_efi_uintn_t debug_disposition, void **address); + +#define GRUB_EFI_GLOBAL_VARIABLE_GUID \ + { 0x8BE4DF61, 0x93CA, 0x11d2, { 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B,0x8C }} + + + grub_efi_status_t + (*get_variable) (grub_efi_char16_t *variable_name, + const grub_efi_guid_t *vendor_guid, + grub_efi_uint32_t *attributes, + grub_efi_uintn_t *data_size, + void *data); + + grub_efi_status_t + (*get_next_variable_name) (grub_efi_uintn_t *variable_name_size, + grub_efi_char16_t *variable_name, + grub_efi_guid_t *vendor_guid); + + grub_efi_status_t + (*set_variable) (grub_efi_char16_t *variable_name, + const grub_efi_guid_t *vendor_guid, + grub_efi_uint32_t attributes, + grub_efi_uintn_t data_size, + void *data); + + grub_efi_status_t + (*get_next_high_monotonic_count) (grub_efi_uint32_t *high_count); + + void + (*reset_system) (grub_efi_reset_type_t reset_type, + grub_efi_status_t reset_status, + grub_efi_uintn_t data_size, + grub_efi_char16_t *reset_data); +}; +typedef struct grub_efi_runtime_services grub_efi_runtime_services_t; + +struct grub_efi_configuration_table +{ + grub_efi_packed_guid_t vendor_guid; + void *vendor_table; +} GRUB_PACKED; +typedef struct grub_efi_configuration_table grub_efi_configuration_table_t; + +#define GRUB_EFIEMU_SYSTEM_TABLE_SIGNATURE 0x5453595320494249LL +#define GRUB_EFIEMU_RUNTIME_SERVICES_SIGNATURE 0x56524553544e5552LL + +struct grub_efi_serial_io_interface +{ + grub_efi_uint32_t revision; + void (*reset) (void); + grub_efi_status_t (*set_attributes) (struct grub_efi_serial_io_interface *this, + grub_efi_uint64_t speed, + grub_efi_uint32_t fifo_depth, + grub_efi_uint32_t timeout, + grub_efi_parity_type_t parity, + grub_uint8_t word_len, + grub_efi_stop_bits_t stop_bits); + grub_efi_status_t (*set_control_bits) (struct grub_efi_serial_io_interface *this, + grub_efi_uint32_t flags); + void (*get_control_bits) (void); + grub_efi_status_t (*write) (struct grub_efi_serial_io_interface *this, + grub_efi_uintn_t *buf_size, + void *buffer); + grub_efi_status_t (*read) (struct grub_efi_serial_io_interface *this, + grub_efi_uintn_t *buf_size, + void *buffer); +}; + +struct grub_efi_simple_input_interface +{ + grub_efi_status_t + (*reset) (struct grub_efi_simple_input_interface *this, + grub_efi_boolean_t extended_verification); + + grub_efi_status_t + (*read_key_stroke) (struct grub_efi_simple_input_interface *this, + grub_efi_input_key_t *key); + + grub_efi_event_t wait_for_key; +}; +typedef struct grub_efi_simple_input_interface grub_efi_simple_input_interface_t; + +struct grub_efi_key_data { + grub_efi_input_key_t key; + grub_efi_key_state_t key_state; +}; +typedef struct grub_efi_key_data grub_efi_key_data_t; + +typedef grub_efi_status_t (*grub_efi_key_notify_function_t) ( + grub_efi_key_data_t *key_data + ); + +struct grub_efi_simple_text_input_ex_interface +{ + grub_efi_status_t + (*reset) (struct grub_efi_simple_text_input_ex_interface *this, + grub_efi_boolean_t extended_verification); + + grub_efi_status_t + (*read_key_stroke) (struct grub_efi_simple_text_input_ex_interface *this, + grub_efi_key_data_t *key_data); + + grub_efi_event_t wait_for_key; + + grub_efi_status_t + (*set_state) (struct grub_efi_simple_text_input_ex_interface *this, + grub_efi_key_toggle_state_t *key_toggle_state); + + grub_efi_status_t + (*register_key_notify) (struct grub_efi_simple_text_input_ex_interface *this, + grub_efi_key_data_t *key_data, + grub_efi_key_notify_function_t key_notification_function); + + grub_efi_status_t + (*unregister_key_notify) (struct grub_efi_simple_text_input_ex_interface *this, + void *notification_handle); +}; +typedef struct grub_efi_simple_text_input_ex_interface grub_efi_simple_text_input_ex_interface_t; + +struct grub_efi_simple_text_output_interface +{ + grub_efi_status_t + (*reset) (struct grub_efi_simple_text_output_interface *this, + grub_efi_boolean_t extended_verification); + + grub_efi_status_t + (*output_string) (struct grub_efi_simple_text_output_interface *this, + grub_efi_char16_t *string); + + grub_efi_status_t + (*test_string) (struct grub_efi_simple_text_output_interface *this, + grub_efi_char16_t *string); + + grub_efi_status_t + (*query_mode) (struct grub_efi_simple_text_output_interface *this, + grub_efi_uintn_t mode_number, + grub_efi_uintn_t *columns, + grub_efi_uintn_t *rows); + + grub_efi_status_t + (*set_mode) (struct grub_efi_simple_text_output_interface *this, + grub_efi_uintn_t mode_number); + + grub_efi_status_t + (*set_attributes) (struct grub_efi_simple_text_output_interface *this, + grub_efi_uintn_t attribute); + + grub_efi_status_t + (*clear_screen) (struct grub_efi_simple_text_output_interface *this); + + grub_efi_status_t + (*set_cursor_position) (struct grub_efi_simple_text_output_interface *this, + grub_efi_uintn_t column, + grub_efi_uintn_t row); + + grub_efi_status_t + (*enable_cursor) (struct grub_efi_simple_text_output_interface *this, + grub_efi_boolean_t visible); + + grub_efi_simple_text_output_mode_t *mode; +}; +typedef struct grub_efi_simple_text_output_interface grub_efi_simple_text_output_interface_t; + +typedef grub_uint8_t grub_efi_pxe_packet_t[1472]; + +typedef struct grub_efi_pxe_mode +{ + grub_uint8_t unused[52]; + grub_efi_pxe_packet_t dhcp_discover; + grub_efi_pxe_packet_t dhcp_ack; + grub_efi_pxe_packet_t proxy_offer; + grub_efi_pxe_packet_t pxe_discover; + grub_efi_pxe_packet_t pxe_reply; +} grub_efi_pxe_mode_t; + +typedef struct grub_efi_pxe +{ + grub_uint64_t rev; + void (*start) (void); + void (*stop) (void); + void (*dhcp) (void); + void (*discover) (void); + void (*mftp) (void); + void (*udpwrite) (void); + void (*udpread) (void); + void (*setipfilter) (void); + void (*arp) (void); + void (*setparams) (void); + void (*setstationip) (void); + void (*setpackets) (void); + struct grub_efi_pxe_mode *mode; +} grub_efi_pxe_t; + +#define GRUB_EFI_BLACK 0x00 +#define GRUB_EFI_BLUE 0x01 +#define GRUB_EFI_GREEN 0x02 +#define GRUB_EFI_CYAN 0x03 +#define GRUB_EFI_RED 0x04 +#define GRUB_EFI_MAGENTA 0x05 +#define GRUB_EFI_BROWN 0x06 +#define GRUB_EFI_LIGHTGRAY 0x07 +#define GRUB_EFI_BRIGHT 0x08 +#define GRUB_EFI_DARKGRAY 0x08 +#define GRUB_EFI_LIGHTBLUE 0x09 +#define GRUB_EFI_LIGHTGREEN 0x0A +#define GRUB_EFI_LIGHTCYAN 0x0B +#define GRUB_EFI_LIGHTRED 0x0C +#define GRUB_EFI_LIGHTMAGENTA 0x0D +#define GRUB_EFI_YELLOW 0x0E +#define GRUB_EFI_WHITE 0x0F + +#define GRUB_EFI_BACKGROUND_BLACK 0x00 +#define GRUB_EFI_BACKGROUND_BLUE 0x10 +#define GRUB_EFI_BACKGROUND_GREEN 0x20 +#define GRUB_EFI_BACKGROUND_CYAN 0x30 +#define GRUB_EFI_BACKGROUND_RED 0x40 +#define GRUB_EFI_BACKGROUND_MAGENTA 0x50 +#define GRUB_EFI_BACKGROUND_BROWN 0x60 +#define GRUB_EFI_BACKGROUND_LIGHTGRAY 0x70 + +#define GRUB_EFI_TEXT_ATTR(fg, bg) ((fg) | ((bg))) + +struct grub_efi_system_table +{ + grub_efi_table_header_t hdr; + grub_efi_char16_t *firmware_vendor; + grub_efi_uint32_t firmware_revision; + grub_efi_handle_t console_in_handler; + grub_efi_simple_input_interface_t *con_in; + grub_efi_handle_t console_out_handler; + grub_efi_simple_text_output_interface_t *con_out; + grub_efi_handle_t standard_error_handle; + grub_efi_simple_text_output_interface_t *std_err; + grub_efi_runtime_services_t *runtime_services; + grub_efi_boot_services_t *boot_services; + grub_efi_uintn_t num_table_entries; + grub_efi_configuration_table_t *configuration_table; +}; +typedef struct grub_efi_system_table grub_efi_system_table_t; + +struct grub_efi_loaded_image +{ + grub_efi_uint32_t revision; + grub_efi_handle_t parent_handle; + grub_efi_system_table_t *system_table; + + grub_efi_handle_t device_handle; + grub_efi_device_path_t *file_path; + void *reserved; + + grub_efi_uint32_t load_options_size; + void *load_options; + + void *image_base; + grub_efi_uint64_t image_size; + grub_efi_memory_type_t image_code_type; + grub_efi_memory_type_t image_data_type; + + grub_efi_status_t (*unload) (grub_efi_handle_t image_handle); +}; +typedef struct grub_efi_loaded_image grub_efi_loaded_image_t; + +struct grub_efi_disk_io +{ + grub_efi_uint64_t revision; + grub_efi_status_t (*read) (struct grub_efi_disk_io *this, + grub_efi_uint32_t media_id, + grub_efi_uint64_t offset, + grub_efi_uintn_t buffer_size, + void *buffer); + grub_efi_status_t (*write) (struct grub_efi_disk_io *this, + grub_efi_uint32_t media_id, + grub_efi_uint64_t offset, + grub_efi_uintn_t buffer_size, + void *buffer); +}; +typedef struct grub_efi_disk_io grub_efi_disk_io_t; + +struct grub_efi_block_io_media +{ + grub_efi_uint32_t media_id; + grub_efi_boolean_t removable_media; + grub_efi_boolean_t media_present; + grub_efi_boolean_t logical_partition; + grub_efi_boolean_t read_only; + grub_efi_boolean_t write_caching; + grub_efi_uint8_t pad[3]; + grub_efi_uint32_t block_size; + grub_efi_uint32_t io_align; + grub_efi_uint8_t pad2[4]; + grub_efi_lba_t last_block; +}; +typedef struct grub_efi_block_io_media grub_efi_block_io_media_t; + +typedef grub_uint8_t grub_efi_mac_t[32]; + +struct grub_efi_simple_network_mode +{ + grub_uint32_t state; + grub_uint32_t hwaddr_size; + grub_uint32_t media_header_size; + grub_uint32_t max_packet_size; + grub_uint32_t nvram_size; + grub_uint32_t nvram_access_size; + grub_uint32_t receive_filter_mask; + grub_uint32_t receive_filter_setting; + grub_uint32_t max_mcast_filter_count; + grub_uint32_t mcast_filter_count; + grub_efi_mac_t mcast_filter[16]; + grub_efi_mac_t current_address; + grub_efi_mac_t broadcast_address; + grub_efi_mac_t permanent_address; + grub_uint8_t if_type; + grub_uint8_t mac_changeable; + grub_uint8_t multitx_supported; + grub_uint8_t media_present_supported; + grub_uint8_t media_present; +}; + +enum + { + GRUB_EFI_NETWORK_STOPPED, + GRUB_EFI_NETWORK_STARTED, + GRUB_EFI_NETWORK_INITIALIZED, + }; + +enum + { + GRUB_EFI_SIMPLE_NETWORK_RECEIVE_UNICAST = 0x01, + GRUB_EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST = 0x02, + GRUB_EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST = 0x04, + GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS = 0x08, + GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST = 0x10, + }; + +struct grub_efi_simple_network +{ + grub_uint64_t revision; + grub_efi_status_t (*start) (struct grub_efi_simple_network *this); + grub_efi_status_t (*stop) (struct grub_efi_simple_network *this); + grub_efi_status_t (*initialize) (struct grub_efi_simple_network *this, + grub_efi_uintn_t extra_rx, + grub_efi_uintn_t extra_tx); + void (*reset) (void); + grub_efi_status_t (*shutdown) (struct grub_efi_simple_network *this); + grub_efi_status_t (*receive_filters) (struct grub_efi_simple_network *this, + grub_uint32_t enable, + grub_uint32_t disable, + grub_efi_boolean_t reset_mcast_filter, + grub_efi_uintn_t mcast_filter_count, + grub_efi_mac_address_t *mcast_filter); + void (*station_address) (void); + void (*statistics) (void); + void (*mcastiptomac) (void); + void (*nvdata) (void); + grub_efi_status_t (*get_status) (struct grub_efi_simple_network *this, + grub_uint32_t *int_status, + void **txbuf); + grub_efi_status_t (*transmit) (struct grub_efi_simple_network *this, + grub_efi_uintn_t header_size, + grub_efi_uintn_t buffer_size, + void *buffer, + grub_efi_mac_t *src_addr, + grub_efi_mac_t *dest_addr, + grub_efi_uint16_t *protocol); + grub_efi_status_t (*receive) (struct grub_efi_simple_network *this, + grub_efi_uintn_t *header_size, + grub_efi_uintn_t *buffer_size, + void *buffer, + grub_efi_mac_t *src_addr, + grub_efi_mac_t *dest_addr, + grub_uint16_t *protocol); + void (*waitforpacket) (void); + struct grub_efi_simple_network_mode *mode; +}; +typedef struct grub_efi_simple_network grub_efi_simple_network_t; + + +struct grub_efi_block_io +{ + grub_efi_uint64_t revision; + grub_efi_block_io_media_t *media; + grub_efi_status_t (*reset) (struct grub_efi_block_io *this, + grub_efi_boolean_t extended_verification); + grub_efi_status_t (*read_blocks) (struct grub_efi_block_io *this, + grub_efi_uint32_t media_id, + grub_efi_lba_t lba, + grub_efi_uintn_t buffer_size, + void *buffer); + grub_efi_status_t (*write_blocks) (struct grub_efi_block_io *this, + grub_efi_uint32_t media_id, + grub_efi_lba_t lba, + grub_efi_uintn_t buffer_size, + void *buffer); + grub_efi_status_t (*flush_blocks) (struct grub_efi_block_io *this); +}; +typedef struct grub_efi_block_io grub_efi_block_io_t; + +#if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \ + || defined (__aarch64__) || defined(__mips__) || defined (__MINGW64__) || defined (__CYGWIN__) \ + || defined(__riscv) + +#define efi_call_0(func) func() +#define efi_call_1(func, a) func(a) +#define efi_call_2(func, a, b) func(a, b) +#define efi_call_3(func, a, b, c) func(a, b, c) +#define efi_call_4(func, a, b, c, d) func(a, b, c, d) +#define efi_call_5(func, a, b, c, d, e) func(a, b, c, d, e) +#define efi_call_6(func, a, b, c, d, e, f) func(a, b, c, d, e, f) +#define efi_call_7(func, a, b, c, d, e, f, g) func(a, b, c, d, e, f, g) +#define efi_call_10(func, a, b, c, d, e, f, g, h, i, j) func(a, b, c, d, e, f, g, h, i, j) + +#else + +#define efi_call_0(func) \ + efi_wrap_0(func) +#define efi_call_1(func, a) \ + efi_wrap_1(func, (grub_uint64_t) (a)) +#define efi_call_2(func, a, b) \ + efi_wrap_2(func, (grub_uint64_t) (a), (grub_uint64_t) (b)) +#define efi_call_3(func, a, b, c) \ + efi_wrap_3(func, (grub_uint64_t) (a), (grub_uint64_t) (b), \ + (grub_uint64_t) (c)) +#define efi_call_4(func, a, b, c, d) \ + efi_wrap_4(func, (grub_uint64_t) (a), (grub_uint64_t) (b), \ + (grub_uint64_t) (c), (grub_uint64_t) (d)) +#define efi_call_5(func, a, b, c, d, e) \ + efi_wrap_5(func, (grub_uint64_t) (a), (grub_uint64_t) (b), \ + (grub_uint64_t) (c), (grub_uint64_t) (d), (grub_uint64_t) (e)) +#define efi_call_6(func, a, b, c, d, e, f) \ + efi_wrap_6(func, (grub_uint64_t) (a), (grub_uint64_t) (b), \ + (grub_uint64_t) (c), (grub_uint64_t) (d), (grub_uint64_t) (e), \ + (grub_uint64_t) (f)) +#define efi_call_7(func, a, b, c, d, e, f, g) \ + efi_wrap_7(func, (grub_uint64_t) (a), (grub_uint64_t) (b), \ + (grub_uint64_t) (c), (grub_uint64_t) (d), (grub_uint64_t) (e), \ + (grub_uint64_t) (f), (grub_uint64_t) (g)) +#define efi_call_10(func, a, b, c, d, e, f, g, h, i, j) \ + efi_wrap_10(func, (grub_uint64_t) (a), (grub_uint64_t) (b), \ + (grub_uint64_t) (c), (grub_uint64_t) (d), (grub_uint64_t) (e), \ + (grub_uint64_t) (f), (grub_uint64_t) (g), (grub_uint64_t) (h), \ + (grub_uint64_t) (i), (grub_uint64_t) (j)) + +grub_uint64_t EXPORT_FUNC(efi_wrap_0) (void *func); +grub_uint64_t EXPORT_FUNC(efi_wrap_1) (void *func, grub_uint64_t arg1); +grub_uint64_t EXPORT_FUNC(efi_wrap_2) (void *func, grub_uint64_t arg1, + grub_uint64_t arg2); +grub_uint64_t EXPORT_FUNC(efi_wrap_3) (void *func, grub_uint64_t arg1, + grub_uint64_t arg2, grub_uint64_t arg3); +grub_uint64_t EXPORT_FUNC(efi_wrap_4) (void *func, grub_uint64_t arg1, + grub_uint64_t arg2, grub_uint64_t arg3, + grub_uint64_t arg4); +grub_uint64_t EXPORT_FUNC(efi_wrap_5) (void *func, grub_uint64_t arg1, + grub_uint64_t arg2, grub_uint64_t arg3, + grub_uint64_t arg4, grub_uint64_t arg5); +grub_uint64_t EXPORT_FUNC(efi_wrap_6) (void *func, grub_uint64_t arg1, + grub_uint64_t arg2, grub_uint64_t arg3, + grub_uint64_t arg4, grub_uint64_t arg5, + grub_uint64_t arg6); +grub_uint64_t EXPORT_FUNC(efi_wrap_7) (void *func, grub_uint64_t arg1, + grub_uint64_t arg2, grub_uint64_t arg3, + grub_uint64_t arg4, grub_uint64_t arg5, + grub_uint64_t arg6, grub_uint64_t arg7); +grub_uint64_t EXPORT_FUNC(efi_wrap_10) (void *func, grub_uint64_t arg1, + grub_uint64_t arg2, grub_uint64_t arg3, + grub_uint64_t arg4, grub_uint64_t arg5, + grub_uint64_t arg6, grub_uint64_t arg7, + grub_uint64_t arg8, grub_uint64_t arg9, + grub_uint64_t arg10); +#endif + +#endif /* ! GRUB_EFI_API_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/efi/efi.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/efi/efi.h new file mode 100644 index 0000000..aec589c --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/efi/efi.h @@ -0,0 +1,125 @@ +/* efi.h - declare variables and functions for EFI support */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_EFI_EFI_HEADER +#define GRUB_EFI_EFI_HEADER 1 + +#include +#include +#include + +/* Functions. */ +void *EXPORT_FUNC(grub_efi_locate_protocol) (grub_efi_guid_t *protocol, + void *registration); +grub_efi_handle_t * +EXPORT_FUNC(grub_efi_locate_handle) (grub_efi_locate_search_type_t search_type, + grub_efi_guid_t *protocol, + void *search_key, + grub_efi_uintn_t *num_handles); +void *EXPORT_FUNC(grub_efi_open_protocol) (grub_efi_handle_t handle, + grub_efi_guid_t *protocol, + grub_efi_uint32_t attributes); +int EXPORT_FUNC(grub_efi_set_text_mode) (int on); +void EXPORT_FUNC(grub_efi_stall) (grub_efi_uintn_t microseconds); +void * +EXPORT_FUNC(grub_efi_allocate_pages_real) (grub_efi_physical_address_t address, + grub_efi_uintn_t pages, + grub_efi_allocate_type_t alloctype, + grub_efi_memory_type_t memtype); +void * +EXPORT_FUNC(grub_efi_allocate_fixed) (grub_efi_physical_address_t address, + grub_efi_uintn_t pages); +void * +EXPORT_FUNC(grub_efi_allocate_any_pages) (grub_efi_uintn_t pages); +void EXPORT_FUNC(grub_efi_free_pages) (grub_efi_physical_address_t address, + grub_efi_uintn_t pages); +grub_efi_uintn_t EXPORT_FUNC(grub_efi_find_mmap_size) (void); +int +EXPORT_FUNC(grub_efi_get_memory_map) (grub_efi_uintn_t *memory_map_size, + grub_efi_memory_descriptor_t *memory_map, + grub_efi_uintn_t *map_key, + grub_efi_uintn_t *descriptor_size, + grub_efi_uint32_t *descriptor_version); +void grub_efi_memory_fini (void); +grub_efi_loaded_image_t *EXPORT_FUNC(grub_efi_get_loaded_image) (grub_efi_handle_t image_handle); +void EXPORT_FUNC(grub_efi_print_device_path) (grub_efi_device_path_t *dp); +char *EXPORT_FUNC(grub_efi_get_filename) (grub_efi_device_path_t *dp); +grub_efi_device_path_t * +EXPORT_FUNC(grub_efi_get_device_path) (grub_efi_handle_t handle); +grub_efi_device_path_t * +EXPORT_FUNC(grub_efi_find_last_device_path) (const grub_efi_device_path_t *dp); +grub_efi_device_path_t * +EXPORT_FUNC(grub_efi_duplicate_device_path) (const grub_efi_device_path_t *dp); +grub_err_t EXPORT_FUNC (grub_efi_finish_boot_services) (grub_efi_uintn_t *outbuf_size, void *outbuf, + grub_efi_uintn_t *map_key, + grub_efi_uintn_t *efi_desc_size, + grub_efi_uint32_t *efi_desc_version); +grub_err_t EXPORT_FUNC (grub_efi_set_virtual_address_map) (grub_efi_uintn_t memory_map_size, + grub_efi_uintn_t descriptor_size, + grub_efi_uint32_t descriptor_version, + grub_efi_memory_descriptor_t *virtual_map); +void *EXPORT_FUNC (grub_efi_get_variable) (const char *variable, + const grub_efi_guid_t *guid, + grub_size_t *datasize_out); +grub_err_t +EXPORT_FUNC (grub_efi_set_variable) (const char *var, + const grub_efi_guid_t *guid, + void *data, + grub_size_t datasize); +int +EXPORT_FUNC (grub_efi_compare_device_paths) (const grub_efi_device_path_t *dp1, + const grub_efi_device_path_t *dp2); + +void * EXPORT_FUNC (grub_efi_allocate_iso_buf) (grub_uint64_t size); +void * EXPORT_FUNC (grub_efi_allocate_chain_buf) (grub_uint64_t size); +void EXPORT_FUNC (grub_efi_get_reserved_page_num) (grub_uint64_t *total, grub_uint64_t *org_required, grub_uint64_t *new_required); + +extern void (*EXPORT_VAR(grub_efi_net_config)) (grub_efi_handle_t hnd, + char **device, + char **path); + +#if defined(__arm__) || defined(__aarch64__) || defined(__riscv) +void *EXPORT_FUNC(grub_efi_get_firmware_fdt)(void); +grub_err_t EXPORT_FUNC(grub_efi_get_ram_base)(grub_addr_t *); +#include +grub_err_t grub_arch_efi_linux_check_image(struct linux_arch_kernel_header *lh); +grub_err_t grub_arch_efi_linux_boot_image(grub_addr_t addr, grub_size_t size, + char *args); +#endif + +grub_addr_t grub_efi_modules_addr (void); + +void grub_efi_mm_init (void); +void grub_efi_mm_fini (void); +void grub_efi_init (void); +void grub_efi_fini (void); +void grub_efi_set_prefix (void); + +/* Variables. */ +extern grub_efi_system_table_t *EXPORT_VAR(grub_efi_system_table); +extern grub_efi_handle_t EXPORT_VAR(grub_efi_image_handle); + +extern int EXPORT_VAR(grub_efi_is_finished); + +struct grub_net_card; + +grub_efi_handle_t +grub_efinet_get_device_handle (struct grub_net_card *card); + +#endif /* ! GRUB_EFI_EFI_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/efi/pe32.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/efi/pe32.h new file mode 100644 index 0000000..5b4a035 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/efi/pe32.h @@ -0,0 +1,339 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_EFI_PE32_HEADER +#define GRUB_EFI_PE32_HEADER 1 + +#include +#include + +/* The MSDOS compatibility stub. This was copied from the output of + objcopy, and it is not necessary to care about what this means. */ +#define GRUB_PE32_MSDOS_STUB \ + { \ + 0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, \ + 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, \ + 0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd, \ + 0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, 0x54, 0x68, \ + 0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72, \ + 0x61, 0x6d, 0x20, 0x63, 0x61, 0x6e, 0x6e, 0x6f, \ + 0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6e, \ + 0x20, 0x69, 0x6e, 0x20, 0x44, 0x4f, 0x53, 0x20, \ + 0x6d, 0x6f, 0x64, 0x65, 0x2e, 0x0d, 0x0d, 0x0a, \ + 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 \ + } + +#define GRUB_PE32_MSDOS_STUB_SIZE 0x80 + +#define GRUB_PE32_MAGIC 0x5a4d + +/* According to the spec, the minimal alignment is 512 bytes... + But some examples (such as EFI drivers in the Intel + Sample Implementation) use 32 bytes (0x20) instead, and it seems + to be working. + + However, there is firmware showing up in the field now with + page alignment constraints to guarantee that page protection + bits take effect. Because currently existing GRUB code can not + properly distinguish between in-memory and in-file layout, let's + bump all alignment to GRUB_EFI_PAGE_SIZE. */ +#define GRUB_PE32_SECTION_ALIGNMENT GRUB_EFI_PAGE_SIZE +#define GRUB_PE32_FILE_ALIGNMENT GRUB_PE32_SECTION_ALIGNMENT + +struct grub_pe32_coff_header +{ + grub_uint16_t machine; + grub_uint16_t num_sections; + grub_uint32_t time; + grub_uint32_t symtab_offset; + grub_uint32_t num_symbols; + grub_uint16_t optional_header_size; + grub_uint16_t characteristics; +}; + +#define GRUB_PE32_MACHINE_I386 0x14c +#define GRUB_PE32_MACHINE_MIPS 0x166 +#define GRUB_PE32_MACHINE_IA64 0x200 +#define GRUB_PE32_MACHINE_X86_64 0x8664 +#define GRUB_PE32_MACHINE_ARMTHUMB_MIXED 0x01c2 +#define GRUB_PE32_MACHINE_ARM64 0xAA64 +#define GRUB_PE32_MACHINE_RISCV32 0x5032 +#define GRUB_PE32_MACHINE_RISCV64 0x5064 + +#define GRUB_PE32_RELOCS_STRIPPED 0x0001 +#define GRUB_PE32_EXECUTABLE_IMAGE 0x0002 +#define GRUB_PE32_LINE_NUMS_STRIPPED 0x0004 +#define GRUB_PE32_LOCAL_SYMS_STRIPPED 0x0008 +#define GRUB_PE32_AGGRESSIVE_WS_TRIM 0x0010 +#define GRUB_PE32_LARGE_ADDRESS_AWARE 0x0020 +#define GRUB_PE32_16BIT_MACHINE 0x0040 +#define GRUB_PE32_BYTES_REVERSED_LO 0x0080 +#define GRUB_PE32_32BIT_MACHINE 0x0100 +#define GRUB_PE32_DEBUG_STRIPPED 0x0200 +#define GRUB_PE32_REMOVABLE_RUN_FROM_SWAP 0x0400 +#define GRUB_PE32_SYSTEM 0x1000 +#define GRUB_PE32_DLL 0x2000 +#define GRUB_PE32_UP_SYSTEM_ONLY 0x4000 +#define GRUB_PE32_BYTES_REVERSED_HI 0x8000 + +struct grub_pe32_data_directory +{ + grub_uint32_t rva; + grub_uint32_t size; +}; + +struct grub_pe32_optional_header +{ + grub_uint16_t magic; + grub_uint8_t major_linker_version; + grub_uint8_t minor_linker_version; + grub_uint32_t code_size; + grub_uint32_t data_size; + grub_uint32_t bss_size; + grub_uint32_t entry_addr; + grub_uint32_t code_base; + + grub_uint32_t data_base; + grub_uint32_t image_base; + + grub_uint32_t section_alignment; + grub_uint32_t file_alignment; + grub_uint16_t major_os_version; + grub_uint16_t minor_os_version; + grub_uint16_t major_image_version; + grub_uint16_t minor_image_version; + grub_uint16_t major_subsystem_version; + grub_uint16_t minor_subsystem_version; + grub_uint32_t reserved; + grub_uint32_t image_size; + grub_uint32_t header_size; + grub_uint32_t checksum; + grub_uint16_t subsystem; + grub_uint16_t dll_characteristics; + + grub_uint32_t stack_reserve_size; + grub_uint32_t stack_commit_size; + grub_uint32_t heap_reserve_size; + grub_uint32_t heap_commit_size; + + grub_uint32_t loader_flags; + grub_uint32_t num_data_directories; + + /* Data directories. */ + struct grub_pe32_data_directory export_table; + struct grub_pe32_data_directory import_table; + struct grub_pe32_data_directory resource_table; + struct grub_pe32_data_directory exception_table; + struct grub_pe32_data_directory certificate_table; + struct grub_pe32_data_directory base_relocation_table; + struct grub_pe32_data_directory debug; + struct grub_pe32_data_directory architecture; + struct grub_pe32_data_directory global_ptr; + struct grub_pe32_data_directory tls_table; + struct grub_pe32_data_directory load_config_table; + struct grub_pe32_data_directory bound_import; + struct grub_pe32_data_directory iat; + struct grub_pe32_data_directory delay_import_descriptor; + struct grub_pe32_data_directory com_runtime_header; + struct grub_pe32_data_directory reserved_entry; +}; + +struct grub_pe64_optional_header +{ + grub_uint16_t magic; + grub_uint8_t major_linker_version; + grub_uint8_t minor_linker_version; + grub_uint32_t code_size; + grub_uint32_t data_size; + grub_uint32_t bss_size; + grub_uint32_t entry_addr; + grub_uint32_t code_base; + + grub_uint64_t image_base; + + grub_uint32_t section_alignment; + grub_uint32_t file_alignment; + grub_uint16_t major_os_version; + grub_uint16_t minor_os_version; + grub_uint16_t major_image_version; + grub_uint16_t minor_image_version; + grub_uint16_t major_subsystem_version; + grub_uint16_t minor_subsystem_version; + grub_uint32_t reserved; + grub_uint32_t image_size; + grub_uint32_t header_size; + grub_uint32_t checksum; + grub_uint16_t subsystem; + grub_uint16_t dll_characteristics; + + grub_uint64_t stack_reserve_size; + grub_uint64_t stack_commit_size; + grub_uint64_t heap_reserve_size; + grub_uint64_t heap_commit_size; + + grub_uint32_t loader_flags; + grub_uint32_t num_data_directories; + + /* Data directories. */ + struct grub_pe32_data_directory export_table; + struct grub_pe32_data_directory import_table; + struct grub_pe32_data_directory resource_table; + struct grub_pe32_data_directory exception_table; + struct grub_pe32_data_directory certificate_table; + struct grub_pe32_data_directory base_relocation_table; + struct grub_pe32_data_directory debug; + struct grub_pe32_data_directory architecture; + struct grub_pe32_data_directory global_ptr; + struct grub_pe32_data_directory tls_table; + struct grub_pe32_data_directory load_config_table; + struct grub_pe32_data_directory bound_import; + struct grub_pe32_data_directory iat; + struct grub_pe32_data_directory delay_import_descriptor; + struct grub_pe32_data_directory com_runtime_header; + struct grub_pe32_data_directory reserved_entry; +}; + +#define GRUB_PE32_PE32_MAGIC 0x10b +#define GRUB_PE32_PE64_MAGIC 0x20b + +#define GRUB_PE32_SUBSYSTEM_EFI_APPLICATION 10 + +#define GRUB_PE32_NUM_DATA_DIRECTORIES 16 + +struct grub_pe32_section_table +{ + char name[8]; + grub_uint32_t virtual_size; + grub_uint32_t virtual_address; + grub_uint32_t raw_data_size; + grub_uint32_t raw_data_offset; + grub_uint32_t relocations_offset; + grub_uint32_t line_numbers_offset; + grub_uint16_t num_relocations; + grub_uint16_t num_line_numbers; + grub_uint32_t characteristics; +}; + +#define GRUB_PE32_SCN_CNT_CODE 0x00000020 +#define GRUB_PE32_SCN_CNT_INITIALIZED_DATA 0x00000040 +#define GRUB_PE32_SCN_MEM_DISCARDABLE 0x02000000 +#define GRUB_PE32_SCN_MEM_EXECUTE 0x20000000 +#define GRUB_PE32_SCN_MEM_READ 0x40000000 +#define GRUB_PE32_SCN_MEM_WRITE 0x80000000 + +#define GRUB_PE32_SCN_ALIGN_1BYTES 0x00100000 +#define GRUB_PE32_SCN_ALIGN_2BYTES 0x00200000 +#define GRUB_PE32_SCN_ALIGN_4BYTES 0x00300000 +#define GRUB_PE32_SCN_ALIGN_8BYTES 0x00400000 +#define GRUB_PE32_SCN_ALIGN_16BYTES 0x00500000 +#define GRUB_PE32_SCN_ALIGN_32BYTES 0x00600000 +#define GRUB_PE32_SCN_ALIGN_64BYTES 0x00700000 + +#define GRUB_PE32_SCN_ALIGN_SHIFT 20 +#define GRUB_PE32_SCN_ALIGN_MASK 7 + +#define GRUB_PE32_SIGNATURE_SIZE 4 + +struct grub_pe32_header +{ + /* This should be filled in with GRUB_PE32_MSDOS_STUB. */ + grub_uint8_t msdos_stub[GRUB_PE32_MSDOS_STUB_SIZE]; + + /* This is always PE\0\0. */ + char signature[GRUB_PE32_SIGNATURE_SIZE]; + + /* The COFF file header. */ + struct grub_pe32_coff_header coff_header; + +#if GRUB_TARGET_SIZEOF_VOID_P == 8 + /* The Optional header. */ + struct grub_pe64_optional_header optional_header; +#else + /* The Optional header. */ + struct grub_pe32_optional_header optional_header; +#endif +}; + +struct grub_pe32_fixup_block +{ + grub_uint32_t page_rva; + grub_uint32_t block_size; + grub_uint16_t entries[0]; +}; + +#define GRUB_PE32_FIXUP_ENTRY(type, offset) (((type) << 12) | (offset)) + +#define GRUB_PE32_REL_BASED_ABSOLUTE 0 +#define GRUB_PE32_REL_BASED_HIGH 1 +#define GRUB_PE32_REL_BASED_LOW 2 +#define GRUB_PE32_REL_BASED_HIGHLOW 3 +#define GRUB_PE32_REL_BASED_HIGHADJ 4 +#define GRUB_PE32_REL_BASED_MIPS_JMPADDR 5 +#define GRUB_PE32_REL_BASED_MIPS_LOW 6 +#define GRUB_PE32_REL_BASED_MIPS_HIGH 4 +#define GRUB_PE32_REL_BASED_MIPS_HIGHER 7 +#define GRUB_PE32_REL_BASED_MIPS_HIGHEST 8 +#define GRUB_PE32_REL_BASED_ARM_MOV32A 5 +#define GRUB_PE32_REL_BASED_RISCV_HI20 5 +#define GRUB_PE32_REL_BASED_SECTION 6 +#define GRUB_PE32_REL_BASED_REL 7 +#define GRUB_PE32_REL_BASED_ARM_MOV32T 7 +#define GRUB_PE32_REL_BASED_RISCV_LOW12I 7 +#define GRUB_PE32_REL_BASED_RISCV_LOW12S 8 +#define GRUB_PE32_REL_BASED_IA64_IMM64 9 +#define GRUB_PE32_REL_BASED_DIR64 10 +#define GRUB_PE32_REL_BASED_HIGH3ADJ 11 + +struct grub_pe32_symbol +{ + union + { + char short_name[8]; + grub_uint32_t long_name[2]; + }; + + grub_uint32_t value; + grub_uint16_t section; + grub_uint16_t type; + grub_uint8_t storage_class; + grub_uint8_t num_aux; +} GRUB_PACKED; + +#define GRUB_PE32_SYM_CLASS_EXTERNAL 2 +#define GRUB_PE32_SYM_CLASS_STATIC 3 +#define GRUB_PE32_SYM_CLASS_FILE 0x67 + +#define GRUB_PE32_DT_FUNCTION 0x20 + +struct grub_pe32_reloc +{ + grub_uint32_t offset; + grub_uint32_t symtab_index; + grub_uint16_t type; +} GRUB_PACKED; + +#define GRUB_PE32_REL_I386_DIR32 0x6 +#define GRUB_PE32_REL_I386_REL32 0x14 + +#endif /* ! GRUB_EFI_PE32_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/env.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/env.h new file mode 100644 index 0000000..6a5e69d --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/env.h @@ -0,0 +1,78 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2005,2006,2007,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_ENV_HEADER +#define GRUB_ENV_HEADER 1 + +#include +#include +#include +#include + +#define VTOY_SB_POLICY_BYPASS 0 +#define VTOY_SB_POLICY_CHECK 1 +extern grub_uint8_t EXPORT_VAR(g_sys_sb); +extern grub_uint8_t EXPORT_VAR(g_sb_policy); + +struct grub_env_var; + +typedef const char *(*grub_env_read_hook_t) (struct grub_env_var *var, + const char *val); +typedef char *(*grub_env_write_hook_t) (struct grub_env_var *var, + const char *val); + +struct grub_env_var +{ + char *name; + char *value; + grub_env_read_hook_t read_hook; + grub_env_write_hook_t write_hook; + struct grub_env_var *next; + struct grub_env_var **prevp; + struct grub_env_var *sorted_next; + int global; +}; + +grub_err_t EXPORT_FUNC(grub_env_set) (const char *name, const char *val); +const char *EXPORT_FUNC(grub_env_get) (const char *name); +void EXPORT_FUNC(grub_env_unset) (const char *name); +struct grub_env_var *EXPORT_FUNC(grub_env_update_get_sorted) (void); + +#define FOR_SORTED_ENV(var) for (var = grub_env_update_get_sorted (); var; var = var->sorted_next) + +grub_err_t EXPORT_FUNC(grub_register_variable_hook) (const char *name, + grub_env_read_hook_t read_hook, + grub_env_write_hook_t write_hook); +grub_err_t EXPORT_FUNC(grub_register_vtoy_menu_lang_hook) (grub_env_read_hook_t read_hook); + +grub_err_t grub_env_context_open (void); +grub_err_t grub_env_context_close (void); +grub_err_t EXPORT_FUNC(grub_env_export) (const char *name); + +void grub_env_unset_menu (void); +grub_menu_t grub_env_get_menu (void); +void grub_env_set_menu (grub_menu_t nmenu); + +grub_err_t +grub_env_extractor_open (int source); + +grub_err_t +grub_env_extractor_close (int source); + + +#endif /* ! GRUB_ENV_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/file.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/file.h new file mode 100644 index 0000000..21af4e0 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/file.h @@ -0,0 +1,251 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2007 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_FILE_HEADER +#define GRUB_FILE_HEADER 1 + +#include +#include +#include +#include +#include + +enum grub_file_type + { + GRUB_FILE_TYPE_NONE = 0, + /* GRUB module to be loaded. */ + GRUB_FILE_TYPE_GRUB_MODULE, + /* Loopback file to be represented as disk. */ + GRUB_FILE_TYPE_LOOPBACK, + /* Linux kernel to be loaded. */ + GRUB_FILE_TYPE_LINUX_KERNEL, + /* Linux initrd. */ + GRUB_FILE_TYPE_LINUX_INITRD, + + /* Multiboot kernel. */ + GRUB_FILE_TYPE_MULTIBOOT_KERNEL, + /* Multiboot module. */ + GRUB_FILE_TYPE_MULTIBOOT_MODULE, + + /* Xen hypervisor - used on ARM only. */ + GRUB_FILE_TYPE_XEN_HYPERVISOR, + /* Xen module - used on ARM only. */ + GRUB_FILE_TYPE_XEN_MODULE, + + GRUB_FILE_TYPE_BSD_KERNEL, + GRUB_FILE_TYPE_FREEBSD_ENV, + GRUB_FILE_TYPE_FREEBSD_MODULE, + GRUB_FILE_TYPE_FREEBSD_MODULE_ELF, + GRUB_FILE_TYPE_NETBSD_MODULE, + GRUB_FILE_TYPE_OPENBSD_RAMDISK, + + GRUB_FILE_TYPE_XNU_INFO_PLIST, + GRUB_FILE_TYPE_XNU_MKEXT, + GRUB_FILE_TYPE_XNU_KEXT, + GRUB_FILE_TYPE_XNU_KERNEL, + GRUB_FILE_TYPE_XNU_RAMDISK, + GRUB_FILE_TYPE_XNU_HIBERNATE_IMAGE, + GRUB_FILE_XNU_DEVPROP, + + GRUB_FILE_TYPE_PLAN9_KERNEL, + + GRUB_FILE_TYPE_NTLDR, + GRUB_FILE_TYPE_TRUECRYPT, + GRUB_FILE_TYPE_FREEDOS, + GRUB_FILE_TYPE_PXECHAINLOADER, + GRUB_FILE_TYPE_PCCHAINLOADER, + + GRUB_FILE_TYPE_COREBOOT_CHAINLOADER, + + GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE, + + /* File holding signature. */ + GRUB_FILE_TYPE_SIGNATURE, + /* File holding public key to verify signature once. */ + GRUB_FILE_TYPE_PUBLIC_KEY, + /* File holding public key to add to trused keys. */ + GRUB_FILE_TYPE_PUBLIC_KEY_TRUST, + /* File of which we intend to print a blocklist to the user. */ + GRUB_FILE_TYPE_PRINT_BLOCKLIST, + /* File we intend to use for test loading or testing speed. */ + GRUB_FILE_TYPE_TESTLOAD, + /* File we open only to get its size. E.g. in ls output. */ + GRUB_FILE_TYPE_GET_SIZE, + /* Font file. */ + GRUB_FILE_TYPE_FONT, + /* File holding encryption key for encrypted ZFS. */ + GRUB_FILE_TYPE_ZFS_ENCRYPTION_KEY, + /* File we open n grub-fstest. */ + GRUB_FILE_TYPE_FSTEST, + /* File we open n grub-mount. */ + GRUB_FILE_TYPE_MOUNT, + /* File which we attempt to identify the type of. */ + GRUB_FILE_TYPE_FILE_ID, + /* File holding ACPI table. */ + GRUB_FILE_TYPE_ACPI_TABLE, + /* File holding Device Tree. */ + GRUB_FILE_TYPE_DEVICE_TREE_IMAGE, + /* File we intend show to user. */ + GRUB_FILE_TYPE_CAT, + GRUB_FILE_TYPE_HEXCAT, + /* One of pair of files we intend to compare. */ + GRUB_FILE_TYPE_CMP, + /* List of hashes for hashsum. */ + GRUB_FILE_TYPE_HASHLIST, + /* File hashed by hashsum. */ + GRUB_FILE_TYPE_TO_HASH, + /* Keyboard layout. */ + GRUB_FILE_TYPE_KEYBOARD_LAYOUT, + /* Picture file. */ + GRUB_FILE_TYPE_PIXMAP, + /* *.lst shipped by GRUB. */ + GRUB_FILE_TYPE_GRUB_MODULE_LIST, + /* config file. */ + GRUB_FILE_TYPE_CONFIG, + GRUB_FILE_TYPE_THEME, + GRUB_FILE_TYPE_GETTEXT_CATALOG, + GRUB_FILE_TYPE_FS_SEARCH, + GRUB_FILE_TYPE_AUDIO, + GRUB_FILE_TYPE_VBE_DUMP, + + GRUB_FILE_TYPE_LOADENV, + GRUB_FILE_TYPE_SAVEENV, + + GRUB_FILE_TYPE_VERIFY_SIGNATURE, + + GRUB_FILE_TYPE_MASK = 0xffff, + + /* --skip-sig is specified. */ + GRUB_FILE_TYPE_SKIP_SIGNATURE = 0x10000, + GRUB_FILE_TYPE_NO_DECOMPRESS = 0x20000, + GRUB_FILE_TYPE_NO_VLNK = 0x40000, + }; + +/* File description. */ +struct grub_file +{ + /* File name. */ + char *name; + + int vlnk; + + /* The underlying device. */ + grub_device_t device; + + /* The underlying filesystem. */ + grub_fs_t fs; + + /* The current offset. */ + grub_off_t offset; + grub_off_t progress_offset; + + /* Progress info. */ + grub_uint64_t last_progress_time; + grub_off_t last_progress_offset; + grub_uint64_t estimated_speed; + + /* The file size. */ + grub_off_t size; + + /* If file is not easily seekable. Should be set by underlying layer. */ + int not_easily_seekable; + + /* Filesystem-specific data. */ + void *data; + + /* This is called when a sector is read. Used only for a disk device. */ + grub_disk_read_hook_t read_hook; + + /* Caller-specific data passed to the read hook. */ + void *read_hook_data; +}; +typedef struct grub_file *grub_file_t; + +extern grub_disk_read_hook_t EXPORT_VAR(grub_file_progress_hook); + +/* Filters with lower ID are executed first. */ +typedef enum grub_file_filter_id + { + GRUB_FILE_FILTER_VERIFY, + GRUB_FILE_FILTER_GZIO, + GRUB_FILE_FILTER_XZIO, + GRUB_FILE_FILTER_LZOPIO, + GRUB_FILE_FILTER_MAX, + GRUB_FILE_FILTER_COMPRESSION_FIRST = GRUB_FILE_FILTER_GZIO, + GRUB_FILE_FILTER_COMPRESSION_LAST = GRUB_FILE_FILTER_LZOPIO, + } grub_file_filter_id_t; + +typedef grub_file_t (*grub_file_filter_t) (grub_file_t in, enum grub_file_type type); + +extern grub_file_filter_t EXPORT_VAR(grub_file_filters)[GRUB_FILE_FILTER_MAX]; + +static inline void +grub_file_filter_register (grub_file_filter_id_t id, grub_file_filter_t filter) +{ + grub_file_filters[id] = filter; +} + +static inline void +grub_file_filter_unregister (grub_file_filter_id_t id) +{ + grub_file_filters[id] = 0; +} + +/* Get a device name from NAME. */ +char *EXPORT_FUNC(grub_file_get_device_name) (const char *name); + +int EXPORT_FUNC(ventoy_check_file_exist) (const char * fmt, ...); +grub_file_t EXPORT_FUNC(grub_file_open) (const char *name, enum grub_file_type type); +grub_ssize_t EXPORT_FUNC(grub_file_read) (grub_file_t file, void *buf, + grub_size_t len); +grub_off_t EXPORT_FUNC(grub_file_seek) (grub_file_t file, grub_off_t offset); +grub_err_t EXPORT_FUNC(grub_file_close) (grub_file_t file); + +int EXPORT_FUNC(grub_file_is_vlnk_suffix)(const char *name, int len); +int EXPORT_FUNC(grub_file_add_vlnk)(const char *src, const char *dst); +int EXPORT_FUNC(grub_file_vtoy_vlnk)(const char *src, const char *dst); +const char * EXPORT_FUNC(grub_file_get_vlnk)(const char *name, int *vlnk); + +/* Return value of grub_file_size() in case file size is unknown. */ +#define GRUB_FILE_SIZE_UNKNOWN 0xffffffffffffffffULL + +static inline grub_off_t +grub_file_size (const grub_file_t file) +{ + return file->size; +} + +static inline grub_off_t +grub_file_tell (const grub_file_t file) +{ + return file->offset; +} + +static inline int +grub_file_seekable (const grub_file_t file) +{ + return !file->not_easily_seekable; +} + +grub_file_t +grub_file_offset_open (grub_file_t parent, enum grub_file_type type, + grub_off_t start, grub_off_t size); +void +grub_file_offset_close (grub_file_t file); + +#endif /* ! GRUB_FILE_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/fs.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/fs.h new file mode 100644 index 0000000..50b3a18 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/fs.h @@ -0,0 +1,133 @@ +/* fs.h - filesystem manager */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_FS_HEADER +#define GRUB_FS_HEADER 1 + +#include +#include +#include + +#include +/* For embedding types. */ +#ifdef GRUB_UTIL +#include +#endif + +/* Forward declaration is required, because of mutual reference. */ +struct grub_file; + +struct grub_dirhook_info +{ + unsigned dir:1; + unsigned mtimeset:1; + unsigned case_insensitive:1; + unsigned inodeset:1; + grub_int32_t mtime; + grub_uint64_t inode; + grub_uint64_t size; +}; + +typedef int (*grub_fs_dir_hook_t) (const char *filename, + const struct grub_dirhook_info *info, + void *data); + +/* Filesystem descriptor. */ +struct grub_fs +{ + /* The next filesystem. */ + struct grub_fs *next; + struct grub_fs **prev; + + /* My name. */ + const char *name; + + /* Call HOOK with each file under DIR. */ + grub_err_t (*fs_dir) (grub_device_t device, const char *path, + grub_fs_dir_hook_t hook, void *hook_data); + + /* Open a file named NAME and initialize FILE. */ + grub_err_t (*fs_open) (struct grub_file *file, const char *name); + + /* Read LEN bytes data from FILE into BUF. */ + grub_ssize_t (*fs_read) (struct grub_file *file, char *buf, grub_size_t len); + + /* Close the file FILE. */ + grub_err_t (*fs_close) (struct grub_file *file); + + /* Return the label of the device DEVICE in LABEL. The label is + returned in a grub_malloc'ed buffer and should be freed by the + caller. */ + grub_err_t (*fs_label) (grub_device_t device, char **label); + + /* Return the uuid of the device DEVICE in UUID. The uuid is + returned in a grub_malloc'ed buffer and should be freed by the + caller. */ + grub_err_t (*fs_uuid) (grub_device_t device, char **uuid); + + /* Get writing time of filesystem. */ + grub_err_t (*fs_mtime) (grub_device_t device, grub_int32_t *timebuf); + +#ifdef GRUB_UTIL + /* Determine sectors available for embedding. */ + grub_err_t (*fs_embed) (grub_device_t device, unsigned int *nsectors, + unsigned int max_nsectors, + grub_embed_type_t embed_type, + grub_disk_addr_t **sectors); + + /* Whether this filesystem reserves first sector for DOS-style boot. */ + int reserved_first_sector; + + /* Whether blocklist installs have a chance to work. */ + int blocklist_install; +#endif +}; +typedef struct grub_fs *grub_fs_t; + +/* This is special, because block lists are not files in usual sense. */ +extern struct grub_fs grub_fs_blocklist; + +/* This hook is used to automatically load filesystem modules. + If this hook loads a module, return non-zero. Otherwise return zero. + The newly loaded filesystem is assumed to be inserted into the head of + the linked list GRUB_FS_LIST through the function grub_fs_register. */ +typedef int (*grub_fs_autoload_hook_t) (void); +extern grub_fs_autoload_hook_t EXPORT_VAR(grub_fs_autoload_hook); +extern grub_fs_t EXPORT_VAR (grub_fs_list); + +#ifndef GRUB_LST_GENERATOR +static inline void +grub_fs_register (grub_fs_t fs) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_fs_list), GRUB_AS_LIST (fs)); +} +#endif + +static inline void +grub_fs_unregister (grub_fs_t fs) +{ + grub_list_remove (GRUB_AS_LIST (fs)); +} + +#define FOR_FILESYSTEMS(var) FOR_LIST_ELEMENTS((var), (grub_fs_list)) + +grub_fs_t EXPORT_FUNC(grub_fs_probe) (grub_device_t device); +grub_fs_t EXPORT_FUNC(grub_fs_list_probe) (grub_device_t device, const char **list); + +#endif /* ! GRUB_FS_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/gfxmenu_view.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/gfxmenu_view.h new file mode 100644 index 0000000..56c0d17 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/gfxmenu_view.h @@ -0,0 +1,128 @@ +/* gfxmenu_view.h - gfxmenu view interface. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_GFXMENU_VIEW_HEADER +#define GRUB_GFXMENU_VIEW_HEADER 1 + +#include +#include +#include +#include +#include + +struct grub_gfxmenu_view; /* Forward declaration of opaque type. */ +typedef struct grub_gfxmenu_view *grub_gfxmenu_view_t; + + +grub_gfxmenu_view_t grub_gfxmenu_view_new (const char *theme_path, + int width, int height); + +void grub_gfxmenu_view_destroy (grub_gfxmenu_view_t view); + +/* Set properties on the view based on settings from the specified + theme file. */ +grub_err_t grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view, + const char *theme_path); + +grub_err_t grub_gui_recreate_box (grub_gfxmenu_box_t *boxptr, + const char *pattern, const char *theme_dir); + +void grub_gfxmenu_view_draw (grub_gfxmenu_view_t view); + +void +grub_gfxmenu_redraw_menu (grub_gfxmenu_view_t view); + +void +grub_gfxmenu_redraw_timeout (grub_gfxmenu_view_t view); + +void +grub_gfxmenu_view_redraw (grub_gfxmenu_view_t view, + const grub_video_rect_t *region); + +void +grub_gfxmenu_clear_timeout (void *data); +void +grub_gfxmenu_print_timeout (int timeout, void *data); +void +grub_gfxmenu_set_chosen_entry (int entry, void *data); +void +grub_gfxmenu_scroll_chosen_entry (void *data, int diren); + +grub_err_t grub_font_draw_string (const char *str, + grub_font_t font, + grub_video_color_t color, + int left_x, int baseline_y); +int grub_font_get_string_width (grub_font_t font, + const char *str); + + +/* Implementation details -- this should not be used outside of the + view itself. */ + +#include +#include +#include +#include +#include +#include + +/* Definition of the private representation of the view. */ +struct grub_gfxmenu_view +{ + grub_video_rect_t screen; + + int need_to_check_sanity; + grub_video_rect_t terminal_rect; + int terminal_border; + + grub_font_t title_font; + grub_font_t message_font; + char *terminal_font_name; + grub_video_rgba_color_t title_color; + grub_video_rgba_color_t message_color; + grub_video_rgba_color_t message_bg_color; + struct grub_video_bitmap *raw_desktop_image; + struct grub_video_bitmap *scaled_desktop_image; + grub_video_bitmap_selection_method_t desktop_image_scale_method; + grub_video_bitmap_h_align_t desktop_image_h_align; + grub_video_bitmap_v_align_t desktop_image_v_align; + grub_video_rgba_color_t desktop_color; + grub_gfxmenu_box_t terminal_box; + char *title_text; + char *progress_message_text; + char *theme_path; + + grub_gui_container_t canvas; + + int double_repaint; + + int selected; + + grub_video_rect_t progress_message_frame; + + grub_menu_t menu; + + int nested; + + int first_timeout; + + int *menu_title_offset; +}; + +#endif /* ! GRUB_GFXMENU_VIEW_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/kernel.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/kernel.h new file mode 100644 index 0000000..55c1c12 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/kernel.h @@ -0,0 +1,133 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_KERNEL_HEADER +#define GRUB_KERNEL_HEADER 1 + +#include +#include + +enum +{ + OBJ_TYPE_ELF, + OBJ_TYPE_MEMDISK, + OBJ_TYPE_CONFIG, + OBJ_TYPE_PREFIX, + OBJ_TYPE_PUBKEY, + OBJ_TYPE_DTB +}; + +/* The module header. */ +struct grub_module_header +{ + /* The type of object. */ + grub_uint32_t type; + /* The size of object (including this header). */ + grub_uint32_t size; +}; + +/* "gmim" (GRUB Module Info Magic). */ +#define GRUB_MODULE_MAGIC 0x676d696d + +struct grub_module_info32 +{ + /* Magic number so we know we have modules present. */ + grub_uint32_t magic; + /* The offset of the modules. */ + grub_uint32_t offset; + /* The size of all modules plus this header. */ + grub_uint32_t size; +}; + +struct grub_module_info64 +{ + /* Magic number so we know we have modules present. */ + grub_uint32_t magic; + grub_uint32_t padding; + /* The offset of the modules. */ + grub_uint64_t offset; + /* The size of all modules plus this header. */ + grub_uint64_t size; +}; + +#ifndef GRUB_UTIL +/* Space isn't reusable on some platforms. */ +/* On Qemu the preload space is readonly. */ +/* On emu there is no preload space. */ +/* On ieee1275 our code assumes that heap is p=v which isn't guaranteed for module space. */ +#if defined (GRUB_MACHINE_QEMU) || defined (GRUB_MACHINE_EMU) \ + || defined (GRUB_MACHINE_EFI) \ + || (defined (GRUB_MACHINE_IEEE1275) && !defined (__sparc__)) +#define GRUB_KERNEL_PRELOAD_SPACE_REUSABLE 0 +#endif + +#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) \ + || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) \ + || defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_ARC) \ + || (defined (__sparc__) && defined (GRUB_MACHINE_IEEE1275)) \ + || defined (GRUB_MACHINE_UBOOT) || defined (GRUB_MACHINE_XEN) \ + || defined(GRUB_MACHINE_XEN_PVH) +/* FIXME: stack is between 2 heap regions. Move it. */ +#define GRUB_KERNEL_PRELOAD_SPACE_REUSABLE 1 +#endif + +#ifndef GRUB_KERNEL_PRELOAD_SPACE_REUSABLE +#error "Please check if preload space is reusable on this platform!" +#endif + +#if GRUB_TARGET_SIZEOF_VOID_P == 8 +#define grub_module_info grub_module_info64 +#else +#define grub_module_info grub_module_info32 +#endif + +extern grub_addr_t EXPORT_VAR (grub_modbase); + +void EXPORT_FUNC(ventoy_env_hook_root)(int hook); + +#define FOR_MODULES(var) for (\ + var = (grub_modbase && ((((struct grub_module_info *) grub_modbase)->magic) == GRUB_MODULE_MAGIC)) ? (struct grub_module_header *) \ + (grub_modbase + (((struct grub_module_info *) grub_modbase)->offset)) : 0;\ + var && (grub_addr_t) var \ + < (grub_modbase + (((struct grub_module_info *) grub_modbase)->size)); \ + var = (struct grub_module_header *) \ + (((grub_uint32_t *) var) + ((((struct grub_module_header *) var)->size + sizeof (grub_addr_t) - 1) / sizeof (grub_addr_t)) * (sizeof (grub_addr_t) / sizeof (grub_uint32_t)))) + +grub_addr_t grub_modules_get_end (void); + +#endif + +/* The start point of the C code. */ +void grub_main (void) __attribute__ ((noreturn)); + +/* The machine-specific initialization. This must initialize memory. */ +void grub_machine_init (void); + +/* The machine-specific finalization. */ +void EXPORT_FUNC(grub_machine_fini) (int flags); + +/* The machine-specific prefix initialization. */ +void +grub_machine_get_bootlocation (char **device, char **path); + +/* Register all the exported symbols. This is automatically generated. */ +void grub_register_exported_symbols (void); + +extern void (*EXPORT_VAR(grub_net_poll_cards_idle)) (void); + +#endif /* ! GRUB_KERNEL_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/menu.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/menu.h new file mode 100644 index 0000000..0acdc2a --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/menu.h @@ -0,0 +1,119 @@ +/* menu.h - Menu model function prototypes and data structures. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_MENU_HEADER +#define GRUB_MENU_HEADER 1 + +struct bls_entry +{ + struct bls_entry *next; + struct bls_entry *prev; + struct keyval **keyvals; + int nkeyvals; + char *filename; + int visible; +}; + +struct grub_menu_entry_class +{ + char *name; + struct grub_menu_entry_class *next; +}; + +/* The menu entry. */ +struct grub_menu_entry +{ + /* The title name. */ + const char *title; + + /* The identifier. */ + const char *id; + + /* If set means not everybody is allowed to boot this entry. */ + int restricted; + + /* Allowed users. */ + const char *users; + + /* The classes associated with the menu entry: + used to choose an icon or other style attributes. + This is a dummy head node for the linked list, so for an entry E, + E.classes->next is the first class if it is not NULL. */ + struct grub_menu_entry_class *classes; + + /* The sourcecode of the menu entry, used by the editor. */ + const char *sourcecode; + + /* Parameters to be passed to menu definition. */ + int argc; + char **args; + + int hotkey; + + int submenu; + + /* The next element. */ + struct grub_menu_entry *next; + + /* BLS used to populate the entry */ + struct bls_entry *bls; +}; +typedef struct grub_menu_entry *grub_menu_entry_t; + +/* The menu. */ +struct grub_menu +{ + /* The size of a menu. */ + int size; + + /* The list of menu entries. */ + grub_menu_entry_t entry_list; +}; +typedef struct grub_menu *grub_menu_t; + +/* Callback structure menu viewers can use to provide user feedback when + default entries are executed, possibly including fallback entries. */ +typedef struct grub_menu_execute_callback +{ + /* Called immediately before ENTRY is booted. */ + void (*notify_booting) (grub_menu_entry_t entry, void *userdata); + + /* Called when executing one entry has failed, and another entry, ENTRY, will + be executed as a fallback. The implementation of this function should + delay for a period of at least 2 seconds before returning in order to + allow the user time to read the information before it can be lost by + executing ENTRY. */ + void (*notify_fallback) (grub_menu_entry_t entry, void *userdata); + + /* Called when an entry has failed to execute and there is no remaining + fallback entry to attempt. */ + void (*notify_failure) (void *userdata); +} +*grub_menu_execute_callback_t; + +grub_menu_entry_t grub_menu_get_entry (grub_menu_t menu, int no); +int grub_menu_get_timeout (void); +void grub_menu_set_timeout (int timeout); +void grub_menu_entry_run (grub_menu_entry_t entry); +int grub_menu_get_default_entry_index (grub_menu_t menu); + +void grub_menu_init (void); +void grub_menu_fini (void); + +#endif /* GRUB_MENU_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/menu_viewer.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/menu_viewer.h new file mode 100644 index 0000000..f068af9 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/menu_viewer.h @@ -0,0 +1,49 @@ +/* menu_viewer.h - Interface to menu viewer implementations. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_MENU_VIEWER_HEADER +#define GRUB_MENU_VIEWER_HEADER 1 + +#include +#include +#include +#include +#include + +struct grub_menu_viewer +{ + struct grub_menu_viewer *next; + void *data; + void (*set_chosen_entry) (int entry, void *data); + void (*scroll_chosen_entry) (void *data, int diren); + void (*print_timeout) (int timeout, void *data); + void (*clear_timeout) (void *data); + void (*fini) (void *fini); +}; + +void grub_menu_register_viewer (struct grub_menu_viewer *viewer); + +grub_err_t +grub_menu_try_text (struct grub_term_output *term, + int entry, grub_menu_t menu, int nested); + +extern grub_err_t (*grub_gfxmenu_try_hook) (int entry, grub_menu_t menu, + int nested); + +#endif /* GRUB_MENU_VIEWER_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/asm.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/asm.h new file mode 100644 index 0000000..062bdf5 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/asm.h @@ -0,0 +1,10 @@ +#ifndef GRUB_MIPS64_ASM_HEADER +#define GRUB_MIPS64_ASM_HEADER 1 + +#define GRUB_ASM_T4 $a4 +#define GRUB_ASM_T5 $a5 +#define GRUB_ASM_SZREG 8 +#define GRUB_ASM_REG_S sd +#define GRUB_ASM_REG_L ld + +#endif diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/efi/boot.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/efi/boot.h new file mode 100644 index 0000000..e69de29 diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/efi/loader.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/efi/loader.h new file mode 100644 index 0000000..71a0159 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/efi/loader.h @@ -0,0 +1,25 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2006,2007,2017 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_LOADER_MACHINE_HEADER +#define GRUB_LOADER_MACHINE_HEADER 1 + +#include +#include + +#endif /* ! GRUB_LOADER_MACHINE_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/efi/loongson.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/efi/loongson.h new file mode 100644 index 0000000..180c3a5 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/efi/loongson.h @@ -0,0 +1,303 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2017 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_EFI_LOONGSON_HEADER +#define GRUB_EFI_LOONGSON_HEADER 1 + +#include + +#include + +#define GRUB_EFI_LOONGSON_SMBIOS_TABLE_GUID \ + { 0x4660f721, 0x2ec5, 0x416a, \ + { 0x89, 0x9a, 0x43, 0x18, 0x02, 0x50, 0xa0, 0xc9 } \ + } + +#define GRUB_EFI_LOONGSON_MMAP_MAX 128 +typedef enum + { + GRUB_EFI_LOONGSON_SYSTEM_RAM_LOW = 1, + GRUB_EFI_LOONGSON_SYSTEM_RAM_HIGH, + GRUB_EFI_LOONGSON_MEMORY_RESERVED, + GRUB_EFI_LOONGSON_PCI_IO, + GRUB_EFI_LOONGSON_PCI_MEM, + GRUB_EFI_LOONGSON_CFG_REG, + GRUB_EFI_LOONGSON_VIDEO_ROM, + GRUB_EFI_LOONGSON_ADAPTER_ROM, + GRUB_EFI_LOONGSON_ACPI_TABLE, + GRUB_EFI_LOONGSON_SMBIOS_TABLE, + GRUB_EFI_LOONGSON_UMA_VIDEO_RAM, + GRUB_EFI_LOONGSON_VUMA_VIDEO_RAM, + GRUB_EFI_LOONGSON_SYSTEM_RAM_LOW_DMA, + GRUB_EFI_LOONGSON_SYSTEM_RAM_HIGH_DMA, + GRUB_EFI_LOONGSON_ACPI_NVS, + GRUB_EFI_LOONGSON_MAX_MEMORY_TYPE + } +grub_efi_loongson_memory_type; + +typedef struct +{ + grub_uint16_t vers; /* version */ + grub_uint32_t nr_map; /* number of memory_maps */ + grub_uint32_t mem_freq; /* memory frequence */ + struct mem_map { + grub_uint32_t node_id; /* node_id which memory attached to */ + grub_uint32_t mem_type; /* system memory, pci memory, pci io, etc. */ + grub_uint64_t mem_start; /* memory map start address */ + grub_uint32_t mem_size; /* each memory_map size, not the total size */ + } map[GRUB_EFI_LOONGSON_MMAP_MAX]; +} GRUB_PACKED +grub_efi_loongson_memory_map; + +/* + * Capability and feature descriptor structure for MIPS CPU + */ +typedef struct +{ + grub_uint16_t vers; /* version */ + grub_uint32_t processor_id; /* PRID, e.g. 6305, 6306 */ + grub_uint32_t cputype; /* Loongson_3A/3B, etc. */ + grub_uint32_t total_node; /* num of total numa nodes */ + grub_uint16_t cpu_startup_core_id; /* Boot core id */ + grub_uint16_t reserved_cores_mask; + grub_uint32_t cpu_clock_freq; /* cpu_clock */ + grub_uint32_t nr_cpus; +} GRUB_PACKED +grub_efi_loongson_cpu_info; + +#define GRUB_EFI_LOONGSON_MAX_UARTS 64 + +typedef struct +{ + grub_uint32_t iotype; /* see include/linux/serial_core.h */ + grub_uint32_t uartclk; + grub_uint32_t int_offset; + grub_uint64_t uart_base; +} GRUB_PACKED +grub_efi_loongson_uart_device; + +#define GRUB_EFI_LOONGSON_MAX_SENSORS 64 + +typedef struct +{ + char name[32]; /* a formal name */ + char label[64]; /* a flexible description */ + grub_uint32_t type; /* SENSOR_* */ + grub_uint32_t id; /* instance id of a sensor-class */ + grub_uint32_t fan_policy; + grub_uint32_t fan_percent; /* only for constant speed policy */ + grub_uint64_t base_addr; /* base address of device registers */ +} GRUB_PACKED +grub_efi_loongson_sensor_device; + +typedef struct +{ + grub_uint16_t vers; /* version */ + grub_uint32_t ccnuma_smp; /* 0: no numa; 1: has numa */ + grub_uint32_t sing_double_channel; /* 1:single; 2:double */ + grub_uint32_t nr_uarts; + grub_efi_loongson_uart_device uarts[GRUB_EFI_LOONGSON_MAX_UARTS]; + grub_uint32_t nr_sensors; + grub_efi_loongson_sensor_device sensors[GRUB_EFI_LOONGSON_MAX_SENSORS]; + char has_ec; + char ec_name[32]; + grub_uint64_t ec_base_addr; + char has_tcm; + char tcm_name[32]; + grub_uint64_t tcm_base_addr; + grub_uint64_t workarounds; /* see workarounds.h */ +} GRUB_PACKED +grub_efi_loongson_system_info; + +typedef struct +{ + grub_uint16_t vers; + grub_uint16_t size; + grub_uint16_t rtr_bus; + grub_uint16_t rtr_devfn; + grub_uint32_t vendor; + grub_uint32_t device; + grub_uint32_t PIC_type; /* conform use HT or PCI to route to CPU-PIC */ + grub_uint64_t ht_int_bit; /* 3A: 1<<24; 3B: 1<<16 */ + grub_uint64_t ht_enable; /* irqs used in this PIC */ + grub_uint32_t node_id; /* node id: 0x0-0; 0x1-1; 0x10-2; 0x11-3 */ + grub_uint64_t pci_mem_start_addr; + grub_uint64_t pci_mem_end_addr; + grub_uint64_t pci_io_start_addr; + grub_uint64_t pci_io_end_addr; + grub_uint64_t pci_config_addr; + grub_uint32_t dma_mask_bits; +} GRUB_PACKED +grub_efi_loongson_irq_src_routing_table; + +typedef struct +{ + grub_uint16_t vers; /* version */ + grub_uint16_t size; + grub_uint8_t flag; + char description[64]; +} GRUB_PACKED +grub_efi_loongson_interface_info; + +#define GRUB_EFI_LOONGSON_MAX_RESOURCE_NUMBER 128 + +typedef struct +{ + grub_uint64_t start; /* resource start address */ + grub_uint64_t end; /* resource end address */ + char name[64]; + grub_uint32_t flags; +} +grub_efi_loongson_resource; + +/* arch specific additions */ +typedef struct +{ +} +grub_efi_loongson_archdev_data; + +typedef struct +{ + char name[64]; /* hold the device name */ + grub_uint32_t num_resources; /* number of device_resource */ + /* for each device's resource */ + grub_efi_loongson_resource resource[GRUB_EFI_LOONGSON_MAX_RESOURCE_NUMBER]; + /* arch specific additions */ + grub_efi_loongson_archdev_data archdata; +} +grub_efi_loongson_board_devices; + +typedef struct +{ + grub_uint16_t vers; /* version */ + char special_name[64]; /* special_atribute_name */ + grub_uint32_t loongson_special_type; /* type of special device */ + /* for each device's resource */ + grub_efi_loongson_resource resource[GRUB_EFI_LOONGSON_MAX_RESOURCE_NUMBER]; +} +grub_efi_loongson_special_attribute; + +typedef struct +{ + grub_uint64_t memory_offset; /* efi_loongson_memory_map struct offset */ + grub_uint64_t cpu_offset; /* efi_loongson_cpuinfo struct offset */ + grub_uint64_t system_offset; /* efi_loongson_system_info struct offset */ + grub_uint64_t irq_offset; /* efi_loongson_irq_src_routing_table struct offset */ + grub_uint64_t interface_offset; /* interface_info struct offset */ + grub_uint64_t special_offset; /* efi_loongson_special_attribute struct offset */ + grub_uint64_t boarddev_table_offset; /* efi_loongson_board_devices offset */ +} +grub_efi_loongson_params; + +typedef struct +{ + grub_uint16_t vers; /* version */ + grub_uint64_t vga_bios; /* vga_bios address */ + grub_efi_loongson_params lp; +} +grub_efi_loongson_smbios_table; + +typedef struct +{ + grub_uint64_t reset_cold; + grub_uint64_t reset_warm; + grub_uint64_t reset_type; + grub_uint64_t shutdown; + grub_uint64_t do_suspend; /* NULL if not support */ +} +grub_efi_loongson_reset_system; + +typedef struct +{ + grub_uint64_t mps; /* MPS table */ + grub_uint64_t acpi; /* ACPI table (IA64 ext 0.71) */ + grub_uint64_t acpi20; /* ACPI table (ACPI 2.0) */ + grub_efi_loongson_smbios_table smbios; /* SM BIOS table */ + grub_uint64_t sal_systab; /* SAL system table */ + grub_uint64_t boot_info; /* boot info table */ +} +grub_efi_loongson; + +typedef struct +{ + grub_efi_loongson efi; + grub_efi_loongson_reset_system reset_system; +} +grub_efi_loongson_boot_params; + +extern grub_uint64_t grub_efi_loongson_reset_system_addr; + +extern void grub_efi_loongson_reset_cold (void); +extern void grub_efi_loongson_reset_warm (void); +extern void grub_efi_loongson_reset_shutdown (void); +extern void grub_efi_loongson_reset_suspend (void); + +void grub_efi_loongson_init (void); +void grub_efi_loongson_fini (void); +void grub_efi_loongson_alloc_boot_params (void); +void grub_efi_loongson_free_boot_params (void); +void * grub_efi_loongson_get_smbios_table (void); + +int EXPORT_FUNC(grub_efi_is_loongson) (void); + +grub_uint8_t +EXPORT_FUNC(grub_efi_loongson_calculatesum8) (const grub_uint8_t *Buffer, grub_efi_uintn_t Length); + +grub_uint8_t +EXPORT_FUNC(grub_efi_loongson_grub_calculatechecksum8) (const grub_uint8_t *Buffer, grub_efi_uintn_t Length); + + +void * +EXPORT_FUNC(grub_efi_loongson_get_boot_params) (void); + +typedef struct _extention_list_hdr{ + grub_uint64_t signature; + grub_uint32_t length; + grub_uint8_t revision; + grub_uint8_t checksum; + struct _extention_list_hdr *next; +}GRUB_PACKED +ext_list; + +typedef struct bootparamsinterface { + grub_uint64_t signature; //{'B', 'P', 'I', '_', '0', '_', '1'} + grub_efi_system_table_t *systemtable; + ext_list *extlist; +}GRUB_PACKED +bootparamsinterface; + +typedef struct { + ext_list header; // {'M', 'E', 'M'} + grub_uint8_t mapcount; + struct GRUB_PACKED memmap { + grub_uint32_t memtype; + grub_uint64_t memstart; + grub_uint64_t memsize; + } map[GRUB_EFI_LOONGSON_MMAP_MAX]; +}GRUB_PACKED +mem_map; + +typedef struct { + ext_list header; // {VBIOS} + grub_uint64_t vbiosaddr; +}GRUB_PACKED +vbios; + +grub_uint32_t +EXPORT_FUNC (grub_efi_loongson_memmap_sort) (struct memmap array[], grub_uint32_t length, mem_map * bpmem, grub_uint32_t index, grub_uint32_t memtype); +#endif /* ! GRUB_EFI_LOONGSON_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/efi/memory.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/efi/memory.h new file mode 100644 index 0000000..2692d83 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/efi/memory.h @@ -0,0 +1,7 @@ +#ifndef GRUB_MEMORY_CPU_HEADER +#include + +//#define GRUB_EFI_MAX_USABLE_ADDRESS 0x980000000fffffffUL +#define GRUB_EFI_MAX_USABLE_ADDRESS 0x98000000ffffffffUL + +#endif /* ! GRUB_MEMORY_CPU_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/efi/time.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/efi/time.h new file mode 100644 index 0000000..e69de29 diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/io.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/io.h new file mode 100644 index 0000000..5f34103 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/io.h @@ -0,0 +1,62 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009,2017 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_IO_H +#define GRUB_IO_H 1 + +#include + +typedef grub_addr_t grub_port_t; + +static __inline unsigned char +grub_inb (grub_port_t port) +{ + return *(volatile grub_uint8_t *) port; +} + +static __inline unsigned short int +grub_inw (grub_port_t port) +{ + return *(volatile grub_uint16_t *) port; +} + +static __inline unsigned int +grub_inl (grub_port_t port) +{ + return *(volatile grub_uint32_t *) port; +} + +static __inline void +grub_outb (unsigned char value, grub_port_t port) +{ + *(volatile grub_uint8_t *) port = value; +} + +static __inline void +grub_outw (unsigned short int value, grub_port_t port) +{ + *(volatile grub_uint16_t *) port = value; +} + +static __inline void +grub_outl (unsigned int value, grub_port_t port) +{ + *(volatile grub_uint32_t *) port = value; +} + +#endif /* _SYS_IO_H */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/kernel.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/kernel.h new file mode 100644 index 0000000..909d539 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/kernel.h @@ -0,0 +1,24 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007,2008,2009,2017 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_KERNEL_CPU_HEADER +#define GRUB_KERNEL_CPU_HEADER 1 + +#include + +#endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/memory.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/memory.h new file mode 100644 index 0000000..d322dbd --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/memory.h @@ -0,0 +1,57 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2017 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_MEMORY_CPU_HEADER +#define GRUB_MEMORY_CPU_HEADER 1 + +#ifndef ASM_FILE +#include +#include +#include +#endif + +#ifndef ASM_FILE + +typedef grub_addr_t grub_phys_addr_t; + +static inline grub_phys_addr_t +grub_vtop (void *a) +{ + if (-1 == ((grub_int64_t) a >> 32)) + return ((grub_phys_addr_t) a) & 0x1fffffffUL; + return ((grub_phys_addr_t) a) & 0xffffffffffffUL; +} + +static inline void * +grub_map_memory (grub_phys_addr_t a, grub_size_t size) +{ + if ((a + size) < 0x20000000UL) + return (void *) (a | 0xffffffff80000000UL); +// return (void *) (a | 0x9800000000000000UL); + return (void *) ((a&0x8fffffff) | 0xffffffff00000000UL); +} + +static inline void +grub_unmap_memory (void *a __attribute__ ((unused)), + grub_size_t size __attribute__ ((unused))) +{ +} + +#endif + +#endif diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/mips.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/mips.h new file mode 100644 index 0000000..a13c709 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/mips.h @@ -0,0 +1,30 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010,2017 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_REGISTERS_CPU_HEADER +#define GRUB_REGISTERS_CPU_HEADER 1 + +#ifdef ASM_FILE +#define GRUB_CPU_REGISTER_WRAP(x) x +#else +#define GRUB_CPU_REGISTER_WRAP(x) #x +#endif + +#define GRUB_CPU_MIPS_COP0_TIMER_COUNT GRUB_CPU_REGISTER_WRAP($9) + +#endif diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/relocator.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/relocator.h new file mode 100644 index 0000000..8815314 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/relocator.h @@ -0,0 +1,38 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2017 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_RELOCATOR_CPU_HEADER +#define GRUB_RELOCATOR_CPU_HEADER 1 + +#include +#include +#include + +struct grub_relocator64_state +{ + /* gpr[0] is ignored since it's hardwired to 0. */ + grub_uint64_t gpr[32]; + /* Register holding target $pc. */ + int jumpreg; +}; + +grub_err_t +grub_relocator64_boot (struct grub_relocator *rel, + struct grub_relocator64_state state); + +#endif /* ! GRUB_RELOCATOR_CPU_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/setjmp.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/setjmp.h new file mode 100644 index 0000000..d9a0776 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/setjmp.h @@ -0,0 +1,27 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2004,2006,2007,2009,2017 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_SETJMP_CPU_HEADER +#define GRUB_SETJMP_CPU_HEADER 1 + +typedef grub_uint64_t grub_jmp_buf[12]; + +int grub_setjmp (grub_jmp_buf env) RETURNS_TWICE; +void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn)); + +#endif /* ! GRUB_SETJMP_CPU_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/time.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/time.h new file mode 100644 index 0000000..c9a7334 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/time.h @@ -0,0 +1,39 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2007,2017 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef KERNEL_CPU_TIME_HEADER +#define KERNEL_CPU_TIME_HEADER 1 + +#ifndef GRUB_UTIL + +#define GRUB_TICKS_PER_SECOND (grub_arch_cpuclock / 2) + +void grub_timer_init (grub_uint32_t cpuclock); + +/* Return the real time in ticks. */ +grub_uint64_t grub_get_rtc (void); + +extern grub_uint32_t grub_arch_cpuclock; +#endif + +static inline void +grub_cpu_idle(void) +{ +} + +#endif diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/types.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/types.h new file mode 100644 index 0000000..fc896c8 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/types.h @@ -0,0 +1,38 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2006,2007,2009,2017 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_TYPES_CPU_HEADER +#define GRUB_TYPES_CPU_HEADER 1 + +/* The size of void *. */ +#define GRUB_TARGET_SIZEOF_VOID_P 8 + +/* The size of long. */ +#define GRUB_TARGET_SIZEOF_LONG 8 + +#ifdef GRUB_CPU_MIPS64EL +/* mips64EL is little-endian. */ +#undef GRUB_TARGET_WORDS_BIGENDIAN +#elif defined (GRUB_CPU_MIPS64) +/* mips64 is big-endian. */ +#define GRUB_TARGET_WORDS_BIGENDIAN +#elif !defined (GRUB_SYMBOL_GENERATOR) +#error Neither GRUB_CPU_MIPS64 nor GRUB_CPU_MIPS64EL is defined +#endif + +#endif /* ! GRUB_TYPES_CPU_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/misc.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/misc.h new file mode 100644 index 0000000..ec48e71 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/misc.h @@ -0,0 +1,466 @@ +/* misc.h - prototypes for misc functions */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_MISC_HEADER +#define GRUB_MISC_HEADER 1 + +#include +#include +#include +#include +#include +#include + +#define ALIGN_UP(addr, align) \ + ((addr + (typeof (addr)) align - 1) & ~((typeof (addr)) align - 1)) +#define ALIGN_UP_OVERHEAD(addr, align) ((-(addr)) & ((typeof (addr)) (align) - 1)) +#define ALIGN_DOWN(addr, align) \ + ((addr) & ~((typeof (addr)) align - 1)) +#define ARRAY_SIZE(array) (sizeof (array) / sizeof (array[0])) +#define COMPILE_TIME_ASSERT(cond) switch (0) { case 1: case !(cond): ; } + +#define grub_dprintf(condition, ...) grub_real_dprintf(GRUB_FILE, __LINE__, condition, __VA_ARGS__) + +void *EXPORT_FUNC(grub_memmove) (void *dest, const void *src, grub_size_t n); +char *EXPORT_FUNC(grub_strcpy) (char *dest, const char *src); + +static inline char * +grub_strncpy (char *dest, const char *src, int c) +{ + char *p = dest; + + while ((*p++ = *src++) != '\0' && --c) + ; + + return dest; +} + +static inline char * +grub_stpcpy (char *dest, const char *src) +{ + char *d = dest; + const char *s = src; + + do + *d++ = *s; + while (*s++ != '\0'); + + return d - 1; +} + +/* XXX: If grub_memmove is too slow, we must implement grub_memcpy. */ +static inline void * +grub_memcpy (void *dest, const void *src, grub_size_t n) +{ + return grub_memmove (dest, src, n); +} + +#if defined(__x86_64__) && !defined (GRUB_UTIL) +#if defined (__MINGW32__) || defined (__CYGWIN__) || defined (__MINGW64__) +#define GRUB_ASM_ATTR __attribute__ ((sysv_abi)) +#else +#define GRUB_ASM_ATTR +#endif +#endif + +int EXPORT_FUNC(grub_memcmp) (const void *s1, const void *s2, grub_size_t n); +int EXPORT_FUNC(grub_strcmp) (const char *s1, const char *s2); +int EXPORT_FUNC(grub_strncmp) (const char *s1, const char *s2, grub_size_t n); + +char *EXPORT_FUNC(grub_strchr) (const char *s, int c); +char *EXPORT_FUNC(grub_strrchr) (const char *s, int c); +int EXPORT_FUNC(grub_strword) (const char *s, const char *w); + +/* Copied from gnulib. + Written by Bruno Haible , 2005. */ +static inline char * +grub_strstr (const char *haystack, const char *needle) +{ + /* Be careful not to look at the entire extent of haystack or needle + until needed. This is useful because of these two cases: + - haystack may be very long, and a match of needle found early, + - needle may be very long, and not even a short initial segment of + needle may be found in haystack. */ + if (*needle != '\0') + { + /* Speed up the following searches of needle by caching its first + character. */ + char b = *needle++; + + for (;; haystack++) + { + if (*haystack == '\0') + /* No match. */ + return 0; + if (*haystack == b) + /* The first character matches. */ + { + const char *rhaystack = haystack + 1; + const char *rneedle = needle; + + for (;; rhaystack++, rneedle++) + { + if (*rneedle == '\0') + /* Found a match. */ + return (char *) haystack; + if (*rhaystack == '\0') + /* No match. */ + return 0; + if (*rhaystack != *rneedle) + /* Nothing in this round. */ + break; + } + } + } + } + else + return (char *) haystack; +} + +int EXPORT_FUNC(grub_isspace) (int c); + +static inline int +grub_isprint (int c) +{ + return (c >= ' ' && c <= '~'); +} + +static inline int +grub_iscntrl (int c) +{ + return (c >= 0x00 && c <= 0x1F) || c == 0x7F; +} + +static inline int +grub_isalpha (int c) +{ + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); +} + +static inline int +grub_islower (int c) +{ + return (c >= 'a' && c <= 'z'); +} + +static inline int +grub_isupper (int c) +{ + return (c >= 'A' && c <= 'Z'); +} + +static inline int +grub_isgraph (int c) +{ + return (c >= '!' && c <= '~'); +} + +static inline int +grub_isdigit (int c) +{ + return (c >= '0' && c <= '9'); +} + +static inline int +grub_isxdigit (int c) +{ + return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); +} + +static inline int +grub_isalnum (int c) +{ + return grub_isalpha (c) || grub_isdigit (c); +} + +static inline int +grub_tolower (int c) +{ + if (c >= 'A' && c <= 'Z') + return c - 'A' + 'a'; + + return c; +} + +static inline int +grub_toupper (int c) +{ + if (c >= 'a' && c <= 'z') + return c - 'a' + 'A'; + + return c; +} + +static inline int +grub_strcasecmp (const char *s1, const char *s2) +{ + while (*s1 && *s2) + { + if (grub_tolower ((grub_uint8_t) *s1) + != grub_tolower ((grub_uint8_t) *s2)) + break; + + s1++; + s2++; + } + + return (int) grub_tolower ((grub_uint8_t) *s1) + - (int) grub_tolower ((grub_uint8_t) *s2); +} + +static inline int +grub_strncasecmp (const char *s1, const char *s2, grub_size_t n) +{ + if (n == 0) + return 0; + + while (*s1 && *s2 && --n) + { + if (grub_tolower (*s1) != grub_tolower (*s2)) + break; + + s1++; + s2++; + } + + return (int) grub_tolower ((grub_uint8_t) *s1) + - (int) grub_tolower ((grub_uint8_t) *s2); +} + +unsigned long EXPORT_FUNC(grub_strtoul) (const char *str, char **end, int base); +unsigned long long EXPORT_FUNC(grub_strtoull) (const char *str, char **end, int base); + +static inline long +grub_strtol (const char *str, char **end, int base) +{ + int negative = 0; + unsigned long long magnitude; + + while (*str && grub_isspace (*str)) + str++; + + if (*str == '-') + { + negative = 1; + str++; + } + + magnitude = grub_strtoull (str, end, base); + if (negative) + { + if (magnitude > (unsigned long) GRUB_LONG_MAX + 1) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); + return GRUB_LONG_MIN; + } + return -((long) magnitude); + } + else + { + if (magnitude > GRUB_LONG_MAX) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); + return GRUB_LONG_MAX; + } + return (long) magnitude; + } +} + +char *EXPORT_FUNC(grub_strdup) (const char *s) WARN_UNUSED_RESULT; +char *EXPORT_FUNC(grub_strndup) (const char *s, grub_size_t n) WARN_UNUSED_RESULT; +void *EXPORT_FUNC(grub_memset) (void *s, int c, grub_size_t n); +grub_size_t EXPORT_FUNC(grub_strlen) (const char *s) WARN_UNUSED_RESULT; +int EXPORT_FUNC(grub_printf) (const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 1, 2))); +int EXPORT_FUNC(grub_printf_) (const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 1, 2))); + +/* Replace all `ch' characters of `input' with `with' and copy the + result into `output'; return EOS address of `output'. */ +static inline char * +grub_strchrsub (char *output, const char *input, char ch, const char *with) +{ + while (*input) + { + if (*input == ch) + { + grub_strcpy (output, with); + output += grub_strlen (with); + input++; + continue; + } + *output++ = *input++; + } + *output = '\0'; + return output; +} + +extern void (*EXPORT_VAR (grub_xputs)) (const char *str); + +static inline int +grub_puts (const char *s) +{ + const char nl[2] = "\n"; + grub_xputs (s); + grub_xputs (nl); + + return 1; /* Cannot fail. */ +} + +int EXPORT_FUNC(grub_puts_) (const char *s); +void EXPORT_FUNC(grub_real_dprintf) (const char *file, + const int line, + const char *condition, + const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 4, 5))); +int EXPORT_FUNC(grub_vprintf) (const char *fmt, va_list args); +int EXPORT_FUNC(grub_snprintf) (char *str, grub_size_t n, const char *fmt, ...) + __attribute__ ((format (GNU_PRINTF, 3, 4))); +int EXPORT_FUNC(grub_vsnprintf) (char *str, grub_size_t n, const char *fmt, + va_list args); +char *EXPORT_FUNC(grub_xasprintf) (const char *fmt, ...) + __attribute__ ((format (GNU_PRINTF, 1, 2))) WARN_UNUSED_RESULT; +char *EXPORT_FUNC(grub_xvasprintf) (const char *fmt, va_list args) WARN_UNUSED_RESULT; +void EXPORT_FUNC(grub_exit) (void) __attribute__ ((noreturn)); +grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n, + grub_uint64_t d, + grub_uint64_t *r); + +/* Must match softdiv group in gentpl.py. */ +#if !defined(GRUB_MACHINE_EMU) && (defined(__arm__) || defined(__ia64__) || \ + (defined(__riscv) && (__riscv_xlen == 32))) +#define GRUB_DIVISION_IN_SOFTWARE 1 +#else +#define GRUB_DIVISION_IN_SOFTWARE 0 +#endif + +/* Some division functions need to be in kernel if compiler generates calls + to them. Otherwise we still need them for consistent tests but they go + into a separate module. */ +#if GRUB_DIVISION_IN_SOFTWARE +#define EXPORT_FUNC_IF_SOFTDIV EXPORT_FUNC +#else +#define EXPORT_FUNC_IF_SOFTDIV(x) x +#endif + +grub_int64_t +EXPORT_FUNC_IF_SOFTDIV(grub_divmod64s) (grub_int64_t n, + grub_int64_t d, + grub_int64_t *r); + +grub_uint32_t +EXPORT_FUNC_IF_SOFTDIV (grub_divmod32) (grub_uint32_t n, + grub_uint32_t d, + grub_uint32_t *r); + +grub_int32_t +EXPORT_FUNC_IF_SOFTDIV (grub_divmod32s) (grub_int32_t n, + grub_int32_t d, + grub_int32_t *r); + +/* Inline functions. */ + +static inline char * +grub_memchr (const void *p, int c, grub_size_t len) +{ + const char *s = (const char *) p; + const char *e = s + len; + + for (; s < e; s++) + if (*s == c) + return (char *) s; + + return 0; +} + + +static inline unsigned int +grub_abs (int x) +{ + if (x < 0) + return (unsigned int) (-x); + else + return (unsigned int) x; +} + +/* Reboot the machine. */ +#if defined (GRUB_MACHINE_EMU) || defined (GRUB_MACHINE_QEMU_MIPS) || \ + defined (GRUB_MACHINE_EFI) +void EXPORT_FUNC(grub_reboot) (void) __attribute__ ((noreturn)); +#else +void grub_reboot (void) __attribute__ ((noreturn)); +#endif + +#if defined (__clang__) && !defined (GRUB_UTIL) +void __attribute__ ((noreturn)) EXPORT_FUNC (abort) (void); +#endif + +#ifdef GRUB_MACHINE_PCBIOS +/* Halt the system, using APM if possible. If NO_APM is true, don't + * use APM even if it is available. */ +void grub_halt (int no_apm) __attribute__ ((noreturn)); +#elif (defined (__mips__) && (_MIPS_SIM != _ABI64)) && !defined (GRUB_MACHINE_EMU) +void EXPORT_FUNC (grub_halt) (void) __attribute__ ((noreturn)); +#else +void grub_halt (void) __attribute__ ((noreturn)); +#endif + +#ifdef GRUB_MACHINE_EMU +/* Flag to check if module loading is available. */ +extern const int EXPORT_VAR(grub_no_modules); +#else +#define grub_no_modules 0 +#endif + +static inline void +grub_error_save (struct grub_error_saved *save) +{ + grub_memcpy (save->errmsg, grub_errmsg, sizeof (save->errmsg)); + save->grub_errno = grub_errno; + grub_errno = GRUB_ERR_NONE; +} + +static inline void +grub_error_load (const struct grub_error_saved *save) +{ + grub_memcpy (grub_errmsg, save->errmsg, sizeof (grub_errmsg)); + grub_errno = save->grub_errno; +} + +#if BOOT_TIME_STATS +struct grub_boot_time +{ + struct grub_boot_time *next; + grub_uint64_t tp; + const char *file; + int line; + char *msg; +}; + +extern struct grub_boot_time *EXPORT_VAR(grub_boot_time_head); + +void EXPORT_FUNC(grub_real_boot_time) (const char *file, + const int line, + const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 3, 4))); +#define grub_boot_time(...) grub_real_boot_time(GRUB_FILE, __LINE__, __VA_ARGS__) +#else +#define grub_boot_time(...) +#endif + +#define grub_max(a, b) (((a) > (b)) ? (a) : (b)) +#define grub_min(a, b) (((a) < (b)) ? (a) : (b)) + +#endif /* ! GRUB_MISC_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/normal.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/normal.h new file mode 100644 index 0000000..8839ad8 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/normal.h @@ -0,0 +1,177 @@ +/* normal.h - prototypes for the normal mode */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_NORMAL_HEADER +#define GRUB_NORMAL_HEADER 1 + +#include +#include +#include +#include +#include +#include +#include + +/* The standard left and right margin for some messages. */ +#define STANDARD_MARGIN 6 + +/* The type of a completion item. */ +enum grub_completion_type + { + GRUB_COMPLETION_TYPE_COMMAND, + GRUB_COMPLETION_TYPE_DEVICE, + GRUB_COMPLETION_TYPE_PARTITION, + GRUB_COMPLETION_TYPE_FILE, + GRUB_COMPLETION_TYPE_ARGUMENT + }; +typedef enum grub_completion_type grub_completion_type_t; + +extern struct grub_menu_viewer grub_normal_text_menu_viewer; +extern int grub_normal_exit_level; + +/* Defined in `main.c'. */ +void grub_enter_normal_mode (const char *config); +void grub_normal_execute (const char *config, int nested, int batch); +struct grub_term_screen_geometry +{ + /* The number of entries shown at a time. */ + int num_entries; + int first_entry_y; + int first_entry_x; + int entry_width; + int timeout_y; + int timeout_lines; + int border; + int right_margin; +}; + +void grub_menu_init_page (int nested, int edit, + struct grub_term_screen_geometry *geo, + struct grub_term_output *term); +void grub_normal_init_page (struct grub_term_output *term, int y); +char *grub_file_getline (grub_file_t file); +void grub_cmdline_run (int nested, int force_auth); + +/* Defined in `cmdline.c'. */ +char *grub_cmdline_get (const char *prompt); +grub_err_t grub_set_history (int newsize); + +/* Defined in `completion.c'. */ +char *grub_normal_do_completion (char *buf, int *restore, + void (*hook) (const char *item, grub_completion_type_t type, int count)); + +/* Defined in `misc.c'. */ +grub_err_t grub_normal_print_device_info (const char *name); + +/* Defined in `color.c'. */ +char *grub_env_write_color_normal (struct grub_env_var *var, const char *val); +char *grub_env_write_color_highlight (struct grub_env_var *var, const char *val); +int grub_parse_color_name_pair (grub_uint8_t *ret, const char *name); + +/* Defined in `menu_text.c'. */ +void grub_wait_after_message (void); +void +grub_print_ucs4 (const grub_uint32_t * str, + const grub_uint32_t * last_position, + int margin_left, int margin_right, + struct grub_term_output *term); + +void +grub_print_ucs4_menu (const grub_uint32_t * str, + const grub_uint32_t * last_position, + int margin_left, int margin_right, + struct grub_term_output *term, + int skip_lines, int max_lines, grub_uint32_t contchar, + struct grub_term_pos *pos); +int +grub_ucs4_count_lines (const grub_uint32_t * str, + const grub_uint32_t * last_position, + int margin_left, int margin_right, + struct grub_term_output *term); +grub_size_t grub_getstringwidth (grub_uint32_t * str, + const grub_uint32_t * last_position, + struct grub_term_output *term); +void grub_print_message_indented (const char *msg, int margin_left, + int margin_right, + struct grub_term_output *term); +void +grub_menu_text_register_instances (int entry, grub_menu_t menu, int nested); +grub_err_t +grub_show_menu (grub_menu_t menu, int nested, int autobooted); + +/* Defined in `handler.c'. */ +void read_handler_list (void); +void free_handler_list (void); + +/* Defined in `dyncmd.c'. */ +void read_command_list (const char *prefix); + +/* Defined in `autofs.c'. */ +void read_fs_list (const char *prefix); + +void grub_context_init (void); +void grub_context_fini (void); + +void read_crypto_list (const char *prefix); + +void read_terminal_list (const char *prefix); + +void grub_set_more (int onoff); + +void grub_normal_reset_more (void); + +void grub_xputs_normal (const char *str); + +extern int grub_extractor_level; + +grub_err_t +grub_normal_add_menu_entry (int argc, const char **args, char **classes, + const char *id, + const char *users, const char *hotkey, + const char *prefix, const char *sourcecode, + int submenu, int *index, struct bls_entry *bls); + +grub_err_t +grub_normal_set_password (const char *user, const char *password); + +void grub_normal_free_menu (grub_menu_t menu); + +void grub_normal_auth_init (void); +void grub_normal_auth_fini (void); + +void +grub_xnputs (const char *str, grub_size_t msg_len); + +grub_command_t +grub_dyncmd_get_cmd (grub_command_t cmd); + +void +grub_gettext_reread_prefix (const char *val); + +enum grub_human_size_type + { + GRUB_HUMAN_SIZE_NORMAL, + GRUB_HUMAN_SIZE_SHORT, + GRUB_HUMAN_SIZE_SPEED, + }; + +const char * +grub_get_human_size (grub_uint64_t size, enum grub_human_size_type type); + +#endif /* ! GRUB_NORMAL_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/partition.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/partition.h new file mode 100644 index 0000000..639f1e6 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/partition.h @@ -0,0 +1,141 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2004,2006,2007 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_PART_HEADER +#define GRUB_PART_HEADER 1 + +#include +#include + +struct grub_disk; + +typedef struct grub_partition *grub_partition_t; + +#ifdef GRUB_UTIL +typedef enum +{ + GRUB_EMBED_PCBIOS +} grub_embed_type_t; +#endif + +typedef int (*grub_partition_iterate_hook_t) (struct grub_disk *disk, + const grub_partition_t partition, + void *data); + +/* Partition map type. */ +struct grub_partition_map +{ + /* The next partition map type. */ + struct grub_partition_map *next; + struct grub_partition_map **prev; + + /* The name of the partition map type. */ + const char *name; + + /* Call HOOK with each partition, until HOOK returns non-zero. */ + grub_err_t (*iterate) (struct grub_disk *disk, + grub_partition_iterate_hook_t hook, void *hook_data); +#ifdef GRUB_UTIL + /* Determine sectors available for embedding. */ + grub_err_t (*embed) (struct grub_disk *disk, unsigned int *nsectors, + unsigned int max_nsectors, + grub_embed_type_t embed_type, + grub_disk_addr_t **sectors); +#endif +}; +typedef struct grub_partition_map *grub_partition_map_t; + +/* Partition description. */ +struct grub_partition +{ + /* The partition number. */ + int number; + + /* The start sector (relative to parent). */ + grub_disk_addr_t start; + + /* The length in sector units. */ + grub_uint64_t len; + + /* The offset of the partition table. */ + grub_disk_addr_t offset; + + /* The index of this partition in the partition table. */ + int index; + + /* Parent partition (physically contains this partition). */ + struct grub_partition *parent; + + /* The type partition map. */ + grub_partition_map_t partmap; + + /* The type of partition whne it's on MSDOS. + Used for embedding detection. */ + grub_uint8_t msdostype; + + /* The attrib field for GPT. Needed for priority detection. */ + grub_uint64_t gpt_attrib; +}; + +grub_partition_t EXPORT_FUNC(grub_partition_probe) (struct grub_disk *disk, + const char *str); +int EXPORT_FUNC(grub_partition_iterate) (struct grub_disk *disk, + grub_partition_iterate_hook_t hook, + void *hook_data); +char *EXPORT_FUNC(grub_partition_get_name) (const grub_partition_t partition); + + +extern grub_partition_map_t EXPORT_VAR(grub_partition_map_list); + +#ifndef GRUB_LST_GENERATOR +static inline void +grub_partition_map_register (grub_partition_map_t partmap) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_partition_map_list), + GRUB_AS_LIST (partmap)); +} +#endif + +static inline void +grub_partition_map_unregister (grub_partition_map_t partmap) +{ + grub_list_remove (GRUB_AS_LIST (partmap)); +} + +#define FOR_PARTITION_MAPS(var) FOR_LIST_ELEMENTS((var), (grub_partition_map_list)) + + +static inline grub_disk_addr_t +grub_partition_get_start (const grub_partition_t p) +{ + grub_partition_t part; + grub_uint64_t part_start = 0; + + for (part = p; part; part = part->parent) + part_start += part->start; + + return part_start; +} + +static inline grub_uint64_t +grub_partition_get_len (const grub_partition_t p) +{ + return p->len; +} + +#endif /* ! GRUB_PART_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/serial.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/serial.h new file mode 100644 index 0000000..f8cc461 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/serial.h @@ -0,0 +1,205 @@ +/* serial.h - serial device interface */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_SERIAL_HEADER +#define GRUB_SERIAL_HEADER 1 + +#include +#if (defined(__mips__) && _MIPS_SIM != _ABI64) || defined (__i386__) || defined (__x86_64__) +#include +#endif +#include +#include +#include +#ifdef GRUB_MACHINE_IEEE1275 +#include +#endif +#ifdef GRUB_MACHINE_ARC +#include +#endif + +struct grub_serial_port; +struct grub_serial_config; + +struct grub_serial_driver +{ + grub_err_t (*configure) (struct grub_serial_port *port, + struct grub_serial_config *config); + int (*fetch) (struct grub_serial_port *port); + void (*put) (struct grub_serial_port *port, const int c); + void (*fini) (struct grub_serial_port *port); +}; + +/* The type of parity. */ +typedef enum + { + GRUB_SERIAL_PARITY_NONE, + GRUB_SERIAL_PARITY_ODD, + GRUB_SERIAL_PARITY_EVEN, + } grub_serial_parity_t; + +typedef enum + { + GRUB_SERIAL_STOP_BITS_1, + GRUB_SERIAL_STOP_BITS_1_5, + GRUB_SERIAL_STOP_BITS_2, + } grub_serial_stop_bits_t; + +struct grub_serial_config +{ + unsigned speed; + int word_len; + grub_serial_parity_t parity; + grub_serial_stop_bits_t stop_bits; + grub_uint64_t base_clock; + int rtscts; +}; + +struct grub_serial_port +{ + struct grub_serial_port *next; + struct grub_serial_port **prev; + char *name; + struct grub_serial_driver *driver; + struct grub_serial_config config; + int configured; + int broken; + + /* This should be void *data but since serial is useful as an early console + when malloc isn't available it's a union. + */ + union + { +#if (defined(__mips__) && _MIPS_SIM != _ABI64) || defined (__i386__) || defined (__x86_64__) + grub_port_t port; +#endif + struct + { + grub_usb_device_t usbdev; + int configno; + int interfno; + char buf[64]; + int bufstart, bufend; + struct grub_usb_desc_endp *in_endp; + struct grub_usb_desc_endp *out_endp; + }; + struct grub_escc_descriptor *escc_desc; +#ifdef GRUB_MACHINE_IEEE1275 + struct + { + grub_ieee1275_ihandle_t handle; + struct ofserial_hash_ent *elem; + }; +#endif +#ifdef GRUB_MACHINE_EFI + struct grub_efi_serial_io_interface *interface; +#endif +#ifdef GRUB_MACHINE_ARC + struct + { + grub_arc_fileno_t handle; + int handle_valid; + }; +#endif + }; + grub_term_output_t term_out; + grub_term_input_t term_in; +}; + +grub_err_t EXPORT_FUNC(grub_serial_register) (struct grub_serial_port *port); + +void EXPORT_FUNC(grub_serial_unregister) (struct grub_serial_port *port); + + /* Convenience functions to perform primitive operations on a port. */ +static inline grub_err_t +grub_serial_port_configure (struct grub_serial_port *port, + struct grub_serial_config *config) +{ + return port->driver->configure (port, config); +} + +static inline int +grub_serial_port_fetch (struct grub_serial_port *port) +{ + return port->driver->fetch (port); +} + +static inline void +grub_serial_port_put (struct grub_serial_port *port, const int c) +{ + port->driver->put (port, c); +} + +static inline void +grub_serial_port_fini (struct grub_serial_port *port) +{ + port->driver->fini (port); +} + + /* Set default settings. */ +static inline grub_err_t +grub_serial_config_defaults (struct grub_serial_port *port) +{ + struct grub_serial_config config = + { +#ifdef GRUB_MACHINE_MIPS_LOONGSON + .speed = 115200, + /* On Loongson machines serial port has only 3 wires. */ + .rtscts = 0, +#else + .speed = 9600, + .rtscts = 1, +#endif + .word_len = 8, + .parity = GRUB_SERIAL_PARITY_NONE, + .stop_bits = GRUB_SERIAL_STOP_BITS_1, + .base_clock = 0 + }; + + return port->driver->configure (port, &config); +} + +#if (defined(__mips__) && _MIPS_SIM != _ABI64) || defined (__i386__) || defined (__x86_64__) +void grub_ns8250_init (void); +char *grub_serial_ns8250_add_port (grub_port_t port); +#endif +#ifdef GRUB_MACHINE_IEEE1275 +void grub_ofserial_init (void); +#endif +#ifdef GRUB_MACHINE_EFI +void +grub_efiserial_init (void); +#endif +#ifdef GRUB_MACHINE_ARC +void +grub_arcserial_init (void); +const char * +grub_arcserial_add_port (const char *path); +#endif + +struct grub_serial_port *grub_serial_find (const char *name); +extern struct grub_serial_driver grub_ns8250_driver; +void EXPORT_FUNC(grub_serial_unregister_driver) (struct grub_serial_driver *driver); + +#ifndef GRUB_MACHINE_EMU +extern void grub_serial_init (void); +extern void grub_serial_fini (void); +#endif + +#endif diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/smbios.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/smbios.h new file mode 100644 index 0000000..15ec260 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/smbios.h @@ -0,0 +1,69 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2019 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_SMBIOS_HEADER +#define GRUB_SMBIOS_HEADER 1 + +#include +#include + +#define GRUB_SMBIOS_TYPE_END_OF_TABLE ((grub_uint8_t)127) + +struct grub_smbios_ieps +{ + grub_uint8_t anchor[5]; /* "_DMI_" */ + grub_uint8_t checksum; + grub_uint16_t table_length; + grub_uint32_t table_address; + grub_uint16_t structures; + grub_uint8_t revision; +} GRUB_PACKED; + +struct grub_smbios_eps +{ + grub_uint8_t anchor[4]; /* "_SM_" */ + grub_uint8_t checksum; + grub_uint8_t length; /* 0x1f */ + grub_uint8_t version_major; + grub_uint8_t version_minor; + grub_uint16_t maximum_structure_size; + grub_uint8_t revision; + grub_uint8_t formatted[5]; + struct grub_smbios_ieps intermediate; +} GRUB_PACKED; + +struct grub_smbios_eps3 +{ + grub_uint8_t anchor[5]; /* "_SM3_" */ + grub_uint8_t checksum; + grub_uint8_t length; /* 0x18 */ + grub_uint8_t version_major; + grub_uint8_t version_minor; + grub_uint8_t docrev; + grub_uint8_t revision; + grub_uint8_t reserved; + grub_uint32_t maximum_table_length; + grub_uint64_t table_address; +} GRUB_PACKED; + +extern struct grub_smbios_eps *grub_machine_smbios_get_eps (void); +extern struct grub_smbios_eps3 *grub_machine_smbios_get_eps3 (void); + +extern struct grub_smbios_eps *EXPORT_FUNC (grub_smbios_get_eps) (void); + +#endif /* ! GRUB_SMBIOS_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/term.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/term.h new file mode 100644 index 0000000..a2bd7a9 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/term.h @@ -0,0 +1,466 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2005,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_TERM_HEADER +#define GRUB_TERM_HEADER 1 + +#define GRUB_TERM_NO_KEY 0 + +/* Internal codes used by GRUB to represent terminal input. */ +/* Only for keys otherwise not having shifted modification. */ +#define GRUB_TERM_SHIFT 0x01000000 +#define GRUB_TERM_CTRL 0x02000000 +#define GRUB_TERM_ALT 0x04000000 + +/* Keys without associated character. */ +#define GRUB_TERM_EXTENDED 0x00800000 +#define GRUB_TERM_KEY_MASK 0x00ffffff + +#define GRUB_TERM_KEY_LEFT (GRUB_TERM_EXTENDED | 0x4b) +#define GRUB_TERM_KEY_RIGHT (GRUB_TERM_EXTENDED | 0x4d) +#define GRUB_TERM_KEY_UP (GRUB_TERM_EXTENDED | 0x48) +#define GRUB_TERM_KEY_DOWN (GRUB_TERM_EXTENDED | 0x50) +#define GRUB_TERM_KEY_HOME (GRUB_TERM_EXTENDED | 0x47) +#define GRUB_TERM_KEY_END (GRUB_TERM_EXTENDED | 0x4f) +#define GRUB_TERM_KEY_DC (GRUB_TERM_EXTENDED | 0x53) +#define GRUB_TERM_KEY_PPAGE (GRUB_TERM_EXTENDED | 0x49) +#define GRUB_TERM_KEY_NPAGE (GRUB_TERM_EXTENDED | 0x51) +#define GRUB_TERM_KEY_F1 (GRUB_TERM_EXTENDED | 0x3b) +#define GRUB_TERM_KEY_F2 (GRUB_TERM_EXTENDED | 0x3c) +#define GRUB_TERM_KEY_F3 (GRUB_TERM_EXTENDED | 0x3d) +#define GRUB_TERM_KEY_F4 (GRUB_TERM_EXTENDED | 0x3e) +#define GRUB_TERM_KEY_F5 (GRUB_TERM_EXTENDED | 0x3f) +#define GRUB_TERM_KEY_F6 (GRUB_TERM_EXTENDED | 0x40) +#define GRUB_TERM_KEY_F7 (GRUB_TERM_EXTENDED | 0x41) +#define GRUB_TERM_KEY_F8 (GRUB_TERM_EXTENDED | 0x42) +#define GRUB_TERM_KEY_F9 (GRUB_TERM_EXTENDED | 0x43) +#define GRUB_TERM_KEY_F10 (GRUB_TERM_EXTENDED | 0x44) +#define GRUB_TERM_KEY_F11 (GRUB_TERM_EXTENDED | 0x57) +#define GRUB_TERM_KEY_F12 (GRUB_TERM_EXTENDED | 0x58) +#define GRUB_TERM_KEY_INSERT (GRUB_TERM_EXTENDED | 0x52) +#define GRUB_TERM_KEY_CENTER (GRUB_TERM_EXTENDED | 0x4c) + +/* Hex value is used for ESC, since '\e' is nonstandard */ +#define GRUB_TERM_ESC 0x1b +#define GRUB_TERM_TAB '\t' +#define GRUB_TERM_BACKSPACE '\b' + +#define GRUB_PROGRESS_NO_UPDATE -1 +#define GRUB_PROGRESS_FAST 0 +#define GRUB_PROGRESS_SLOW 2 + +#ifndef ASM_FILE + +#include +#include +#include +#include +#include + +/* These are used to represent the various color states we use. */ +typedef enum + { + /* The color used to display all text that does not use the + user defined colors below. */ + GRUB_TERM_COLOR_STANDARD, + /* The user defined colors for normal text. */ + GRUB_TERM_COLOR_NORMAL, + /* The user defined colors for highlighted text. */ + GRUB_TERM_COLOR_HIGHLIGHT + } +grub_term_color_state; + +/* Flags for representing the capabilities of a terminal. */ +/* Some notes about the flags: + - These flags are used by higher-level functions but not terminals + themselves. + - If a terminal is dumb, you may assume that only putchar, getkey and + checkkey are called. + - Some fancy features (setcolorstate, setcolor and setcursor) can be set + to NULL. */ + +/* Set when input characters shouldn't be echoed back. */ +#define GRUB_TERM_NO_ECHO (1 << 0) +/* Set when the editing feature should be disabled. */ +#define GRUB_TERM_NO_EDIT (1 << 1) +/* Set when the terminal cannot do fancy things. */ +#define GRUB_TERM_DUMB (1 << 2) +/* Which encoding does terminal expect stream to be. */ +#define GRUB_TERM_CODE_TYPE_SHIFT 3 +#define GRUB_TERM_CODE_TYPE_MASK (7 << GRUB_TERM_CODE_TYPE_SHIFT) +/* Only ASCII characters accepted. */ +#define GRUB_TERM_CODE_TYPE_ASCII (0 << GRUB_TERM_CODE_TYPE_SHIFT) +/* Expects CP-437 characters (ASCII + pseudographics). */ +#define GRUB_TERM_CODE_TYPE_CP437 (1 << GRUB_TERM_CODE_TYPE_SHIFT) +/* UTF-8 stream in logical order. Usually used for terminals + which just forward the stream to another computer. */ +#define GRUB_TERM_CODE_TYPE_UTF8_LOGICAL (2 << GRUB_TERM_CODE_TYPE_SHIFT) +/* UTF-8 in visual order. Like UTF-8 logical but for buggy endpoints. */ +#define GRUB_TERM_CODE_TYPE_UTF8_VISUAL (3 << GRUB_TERM_CODE_TYPE_SHIFT) +/* Glyph description in visual order. */ +#define GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS (4 << GRUB_TERM_CODE_TYPE_SHIFT) + + +/* Bitmasks for modifier keys returned by grub_getkeystatus. */ +#define GRUB_TERM_STATUS_RSHIFT (1 << 0) +#define GRUB_TERM_STATUS_LSHIFT (1 << 1) +#define GRUB_TERM_STATUS_RCTRL (1 << 2) +#define GRUB_TERM_STATUS_RALT (1 << 3) +#define GRUB_TERM_STATUS_SCROLL (1 << 4) +#define GRUB_TERM_STATUS_NUM (1 << 5) +#define GRUB_TERM_STATUS_CAPS (1 << 6) +#define GRUB_TERM_STATUS_LCTRL (1 << 8) +#define GRUB_TERM_STATUS_LALT (1 << 9) + +/* Menu-related geometrical constants. */ + +/* The number of columns/lines between messages/borders/etc. */ +#define GRUB_TERM_MARGIN 1 + +/* The number of columns of scroll information. */ +#define GRUB_TERM_SCROLL_WIDTH 1 + +struct grub_term_input +{ + /* The next terminal. */ + struct grub_term_input *next; + struct grub_term_input **prev; + + /* The terminal name. */ + const char *name; + + /* Initialize the terminal. */ + grub_err_t (*init) (struct grub_term_input *term); + + /* Clean up the terminal. */ + grub_err_t (*fini) (struct grub_term_input *term); + + /* Get a character if any input character is available. Otherwise return -1 */ + int (*getkey) (struct grub_term_input *term); + + /* Get keyboard modifier status. */ + int (*getkeystatus) (struct grub_term_input *term); + + void *data; +}; +typedef struct grub_term_input *grub_term_input_t; + +/* Made in a way to fit into uint32_t and so be passed in a register. */ +struct grub_term_coordinate +{ + grub_uint16_t x; + grub_uint16_t y; +}; + +struct grub_term_output +{ + /* The next terminal. */ + struct grub_term_output *next; + struct grub_term_output **prev; + + /* The terminal name. */ + const char *name; + + /* Initialize the terminal. */ + grub_err_t (*init) (struct grub_term_output *term); + + /* Clean up the terminal. */ + grub_err_t (*fini) (struct grub_term_output *term); + + /* Put a character. C is encoded in Unicode. */ + void (*putchar) (struct grub_term_output *term, + const struct grub_unicode_glyph *c); + + /* Get the number of columns occupied by a given character C. C is + encoded in Unicode. */ + grub_size_t (*getcharwidth) (struct grub_term_output *term, + const struct grub_unicode_glyph *c); + + /* Get the screen size. */ + struct grub_term_coordinate (*getwh) (struct grub_term_output *term); + + /* Get the cursor position. The return value is ((X << 8) | Y). */ + struct grub_term_coordinate (*getxy) (struct grub_term_output *term); + + /* Go to the position (X, Y). */ + void (*gotoxy) (struct grub_term_output *term, + struct grub_term_coordinate pos); + + /* Clear the screen. */ + void (*cls) (struct grub_term_output *term); + + /* Set the current color to be used */ + void (*setcolorstate) (struct grub_term_output *term, + grub_term_color_state state); + + /* Turn on/off the cursor. */ + void (*setcursor) (struct grub_term_output *term, int on); + + /* Update the screen. */ + void (*refresh) (struct grub_term_output *term); + + /* gfxterm only: put in fullscreen mode. */ + grub_err_t (*fullscreen) (void); + + /* The feature flags defined above. */ + grub_uint32_t flags; + + /* Progress data. */ + grub_uint32_t progress_update_divisor; + grub_uint32_t progress_update_counter; + + void *data; +}; +typedef struct grub_term_output *grub_term_output_t; + +#define GRUB_TERM_DEFAULT_NORMAL_COLOR 0x07 +#define GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR 0x70 +#define GRUB_TERM_DEFAULT_STANDARD_COLOR 0x07 + +/* Current color state. */ +extern grub_uint8_t EXPORT_VAR(grub_term_normal_color); +extern grub_uint8_t EXPORT_VAR(grub_term_highlight_color); + +extern struct grub_term_output *EXPORT_VAR(grub_term_outputs_disabled); +extern struct grub_term_input *EXPORT_VAR(grub_term_inputs_disabled); +extern struct grub_term_output *EXPORT_VAR(grub_term_outputs); +extern struct grub_term_input *EXPORT_VAR(grub_term_inputs); + +static inline void +grub_term_register_input (const char *name __attribute__ ((unused)), + grub_term_input_t term) +{ + if (grub_term_inputs) + grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled), + GRUB_AS_LIST (term)); + else + { + /* If this is the first terminal, enable automatically. */ + if (! term->init || term->init (term) == GRUB_ERR_NONE) + grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs), GRUB_AS_LIST (term)); + } +} + +static inline void +grub_term_register_input_inactive (const char *name __attribute__ ((unused)), + grub_term_input_t term) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled), + GRUB_AS_LIST (term)); +} + +static inline void +grub_term_register_input_active (const char *name __attribute__ ((unused)), + grub_term_input_t term) +{ + if (! term->init || term->init (term) == GRUB_ERR_NONE) + grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs), GRUB_AS_LIST (term)); +} + +static inline void +grub_term_register_output (const char *name __attribute__ ((unused)), + grub_term_output_t term) +{ + if (grub_term_outputs) + grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs_disabled), + GRUB_AS_LIST (term)); + else + { + /* If this is the first terminal, enable automatically. */ + if (! term->init || term->init (term) == GRUB_ERR_NONE) + grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs), + GRUB_AS_LIST (term)); + } +} + +static inline void +grub_term_register_output_inactive (const char *name __attribute__ ((unused)), + grub_term_output_t term) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs_disabled), + GRUB_AS_LIST (term)); +} + +static inline void +grub_term_register_output_active (const char *name __attribute__ ((unused)), + grub_term_output_t term) +{ + if (! term->init || term->init (term) == GRUB_ERR_NONE) + grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs), + GRUB_AS_LIST (term)); +} + +static inline void +grub_term_unregister_input (grub_term_input_t term) +{ + grub_list_remove (GRUB_AS_LIST (term)); + grub_list_remove (GRUB_AS_LIST (term)); +} + +static inline void +grub_term_unregister_output (grub_term_output_t term) +{ + grub_list_remove (GRUB_AS_LIST (term)); + grub_list_remove (GRUB_AS_LIST (term)); +} + +#define FOR_ACTIVE_TERM_INPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_inputs)) +#define FOR_DISABLED_TERM_INPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_inputs_disabled)) +#define FOR_ACTIVE_TERM_OUTPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_outputs)) +#define FOR_DISABLED_TERM_OUTPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_outputs_disabled)) + +void grub_putcode (grub_uint32_t code, struct grub_term_output *term); +int EXPORT_FUNC(grub_getkey) (void); +int EXPORT_FUNC(grub_getkey_noblock) (void); +extern int (*EXPORT_VAR (grub_key_remap))(int key); +void grub_cls (void); +void EXPORT_FUNC(grub_refresh) (void); +void grub_puts_terminal (const char *str, struct grub_term_output *term); +struct grub_term_coordinate *grub_term_save_pos (void); +void grub_term_restore_pos (struct grub_term_coordinate *pos); + +static inline unsigned grub_term_width (struct grub_term_output *term) +{ + return term->getwh(term).x ? : 80; +} + +static inline unsigned grub_term_height (struct grub_term_output *term) +{ + return term->getwh(term).y ? : 24; +} + +static inline struct grub_term_coordinate +grub_term_getxy (struct grub_term_output *term) +{ + return term->getxy (term); +} + +static inline void +grub_term_refresh (struct grub_term_output *term) +{ + if (term->refresh) + term->refresh (term); +} + +static inline void +grub_term_gotoxy (struct grub_term_output *term, struct grub_term_coordinate pos) +{ + term->gotoxy (term, pos); +} + +static inline void +grub_term_setcolorstate (struct grub_term_output *term, + grub_term_color_state state) +{ + if (term->setcolorstate) + term->setcolorstate (term, state); +} + +static inline void +grub_setcolorstate (grub_term_color_state state) +{ + struct grub_term_output *term; + + FOR_ACTIVE_TERM_OUTPUTS(term) + grub_term_setcolorstate (term, state); +} + +/* Turn on/off the cursor. */ +static inline void +grub_term_setcursor (struct grub_term_output *term, int on) +{ + if (term->setcursor) + term->setcursor (term, on); +} + +static inline void +grub_term_cls (struct grub_term_output *term) +{ + if (term->cls) + (term->cls) (term); + else + { + grub_putcode ('\n', term); + grub_term_refresh (term); + } +} + +#if HAVE_FONT_SOURCE + +grub_size_t +grub_unicode_estimate_width (const struct grub_unicode_glyph *c); + +#else + +static inline grub_size_t +grub_unicode_estimate_width (const struct grub_unicode_glyph *c __attribute__ ((unused))) +{ + if (grub_unicode_get_comb_type (c->base)) + return 0; + return 1; +} + +#endif + +#define GRUB_TERM_TAB_WIDTH 8 + +static inline grub_size_t +grub_term_getcharwidth (struct grub_term_output *term, + const struct grub_unicode_glyph *c) +{ + if (c->base == '\t') + return GRUB_TERM_TAB_WIDTH; + + if (term->getcharwidth) + return term->getcharwidth (term, c); + else if (((term->flags & GRUB_TERM_CODE_TYPE_MASK) + == GRUB_TERM_CODE_TYPE_UTF8_LOGICAL) + || ((term->flags & GRUB_TERM_CODE_TYPE_MASK) + == GRUB_TERM_CODE_TYPE_UTF8_VISUAL) + || ((term->flags & GRUB_TERM_CODE_TYPE_MASK) + == GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS)) + return grub_unicode_estimate_width (c); + else + return 1; +} + +struct grub_term_autoload +{ + struct grub_term_autoload *next; + char *name; + char *modname; +}; + +extern struct grub_term_autoload *grub_term_input_autoload; +extern struct grub_term_autoload *grub_term_output_autoload; + +static inline void +grub_print_spaces (struct grub_term_output *term, int number_spaces) +{ + while (--number_spaces >= 0) + grub_putcode (' ', term); +} + +extern void (*EXPORT_VAR (grub_term_poll_usb)) (int wait_for_completion); + +#define GRUB_TERM_REPEAT_PRE_INTERVAL 400 +#define GRUB_TERM_REPEAT_INTERVAL 50 + +#endif /* ! ASM_FILE */ + +#endif /* ! GRUB_TERM_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/util/install.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/util/install.h new file mode 100644 index 0000000..58aa50e --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/util/install.h @@ -0,0 +1,269 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_UTIL_INSTALL_HEADER +#define GRUB_UTIL_INSTALL_HEADER 1 + +#include +#include + +#include +#include +#include + +#define GRUB_INSTALL_OPTIONS \ + { "modules", GRUB_INSTALL_OPTIONS_MODULES, N_("MODULES"), \ + 0, N_("pre-load specified modules MODULES"), 1 }, \ + { "dtb", GRUB_INSTALL_OPTIONS_DTB, N_("FILE"), \ + 0, N_("embed a specific DTB"), 1 }, \ + { "install-modules", GRUB_INSTALL_OPTIONS_INSTALL_MODULES, \ + N_("MODULES"), 0, \ + N_("install only MODULES and their dependencies [default=all]"), 1 }, \ + { "themes", GRUB_INSTALL_OPTIONS_INSTALL_THEMES, N_("THEMES"), \ + 0, N_("install THEMES [default=%s]"), 1 }, \ + { "fonts", GRUB_INSTALL_OPTIONS_INSTALL_FONTS, N_("FONTS"), \ + 0, N_("install FONTS [default=%s]"), 1 }, \ + { "locales", GRUB_INSTALL_OPTIONS_INSTALL_LOCALES, N_("LOCALES"),\ + 0, N_("install only LOCALES [default=all]"), 1 }, \ + { "compress", GRUB_INSTALL_OPTIONS_INSTALL_COMPRESS, \ + "no|xz|gz|lzo", 0, \ + N_("compress GRUB files [optional]"), 1 }, \ + {"core-compress", GRUB_INSTALL_OPTIONS_INSTALL_CORE_COMPRESS, \ + "xz|none|auto", \ + 0, N_("choose the compression to use for core image"), 2}, \ + /* TRANSLATORS: platform here isn't identifier. It can be translated. */ \ + { "directory", 'd', N_("DIR"), 0, \ + N_("use images and modules under DIR [default=%s/]"), 1 }, \ + { "override-directory", GRUB_INSTALL_OPTIONS_DIRECTORY2, \ + N_("DIR"), OPTION_HIDDEN, \ + N_("use images and modules under DIR [default=%s/]"), 1 }, \ + { "locale-directory", GRUB_INSTALL_OPTIONS_LOCALE_DIRECTORY, \ + N_("DIR"), 0, \ + N_("use translations under DIR [default=%s]"), 1 }, \ + { "themes-directory", GRUB_INSTALL_OPTIONS_THEMES_DIRECTORY, \ + N_("DIR"), OPTION_HIDDEN, \ + N_("use themes under DIR [default=%s]"), 1 }, \ + { "grub-mkimage", GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE, \ + "FILE", OPTION_HIDDEN, 0, 1 }, \ + /* TRANSLATORS: "embed" is a verb (command description). "*/ \ + { "pubkey", 'k', N_("FILE"), 0, \ + N_("embed FILE as public key for signature checking"), 0}, \ + { "verbose", 'v', 0, 0, \ + N_("print verbose messages."), 1 } + +int +grub_install_parse (int key, char *arg); + +void +grub_install_push_module (const char *val); + +void +grub_install_pop_module (void); + +char * +grub_install_help_filter (int key, const char *text, + void *input __attribute__ ((unused))); + +enum grub_install_plat + { + GRUB_INSTALL_PLATFORM_I386_PC, + GRUB_INSTALL_PLATFORM_I386_EFI, + GRUB_INSTALL_PLATFORM_I386_QEMU, + GRUB_INSTALL_PLATFORM_I386_COREBOOT, + GRUB_INSTALL_PLATFORM_I386_MULTIBOOT, + GRUB_INSTALL_PLATFORM_I386_IEEE1275, + GRUB_INSTALL_PLATFORM_X86_64_EFI, + GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, + GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275, + GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275, + GRUB_INSTALL_PLATFORM_MIPSEL_ARC, + GRUB_INSTALL_PLATFORM_MIPS_ARC, + GRUB_INSTALL_PLATFORM_IA64_EFI, + GRUB_INSTALL_PLATFORM_ARM_UBOOT, + GRUB_INSTALL_PLATFORM_ARM_EFI, + GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS, + GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS, + GRUB_INSTALL_PLATFORM_I386_XEN, + GRUB_INSTALL_PLATFORM_X86_64_XEN, + GRUB_INSTALL_PLATFORM_I386_XEN_PVH, + GRUB_INSTALL_PLATFORM_ARM64_EFI, + GRUB_INSTALL_PLATFORM_MIPS64EL_EFI, + GRUB_INSTALL_PLATFORM_ARM_COREBOOT, + GRUB_INSTALL_PLATFORM_RISCV32_EFI, + GRUB_INSTALL_PLATFORM_RISCV64_EFI, + GRUB_INSTALL_PLATFORM_MAX + }; + +enum grub_install_options { + GRUB_INSTALL_OPTIONS_DIRECTORY = 'd', + GRUB_INSTALL_OPTIONS_VERBOSITY = 'v', + GRUB_INSTALL_OPTIONS_MODULES = 0x201, + GRUB_INSTALL_OPTIONS_INSTALL_MODULES, + GRUB_INSTALL_OPTIONS_INSTALL_THEMES, + GRUB_INSTALL_OPTIONS_INSTALL_FONTS, + GRUB_INSTALL_OPTIONS_INSTALL_LOCALES, + GRUB_INSTALL_OPTIONS_INSTALL_COMPRESS, + GRUB_INSTALL_OPTIONS_DIRECTORY2, + GRUB_INSTALL_OPTIONS_LOCALE_DIRECTORY, + GRUB_INSTALL_OPTIONS_THEMES_DIRECTORY, + GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE, + GRUB_INSTALL_OPTIONS_INSTALL_CORE_COMPRESS, + GRUB_INSTALL_OPTIONS_DTB +}; + +extern char *grub_install_source_directory; + +enum grub_install_plat +grub_install_get_target (const char *src); +void +grub_install_mkdir_p (const char *dst); + +void +grub_install_copy_files (const char *src, + const char *dst, + enum grub_install_plat platid); +char * +grub_install_get_platform_name (enum grub_install_plat platid); + +const char * +grub_install_get_platform_cpu (enum grub_install_plat platid); + +const char * +grub_install_get_platform_platform (enum grub_install_plat platid); + +char * +grub_install_get_platforms_string (void); + +typedef enum { + GRUB_COMPRESSION_AUTO, + GRUB_COMPRESSION_NONE, + GRUB_COMPRESSION_XZ, + GRUB_COMPRESSION_LZMA +} grub_compression_t; + +void +grub_install_make_image_wrap (const char *dir, const char *prefix, + const char *outname, char *memdisk_path, + char *config_path, + const char *format, int note); +void +grub_install_make_image_wrap_file (const char *dir, const char *prefix, + FILE *fp, const char *outname, + char *memdisk_path, + char *config_path, + const char *mkimage_target, int note); + +int +grub_install_copy_file (const char *src, + const char *dst, + int is_critical); + +struct grub_install_image_target_desc; + +void +grub_install_generate_image (const char *dir, const char *prefix, + FILE *out, + const char *outname, char *mods[], + char *memdisk_path, char **pubkey_paths, + size_t npubkeys, + char *config_path, + const struct grub_install_image_target_desc *image_target, + int note, + grub_compression_t comp, const char *dtb_file); + +const struct grub_install_image_target_desc * +grub_install_get_image_target (const char *arg); + +void +grub_util_bios_setup (const char *dir, + const char *boot_file, const char *core_file, + const char *dest, int force, + int fs_probe, int allow_floppy, + int add_rs_codes); +void +grub_util_sparc_setup (const char *dir, + const char *boot_file, const char *core_file, + const char *dest, int force, + int fs_probe, int allow_floppy, + int add_rs_codes); + +char * +grub_install_get_image_targets_string (void); + +const char * +grub_util_get_target_dirname (const struct grub_install_image_target_desc *t); + +void +grub_install_create_envblk_file (const char *name); + +const char * +grub_install_get_default_arm_platform (void); + +const char * +grub_install_get_default_x86_platform (void); + +int +grub_install_register_efi (grub_device_t efidir_grub_dev, + const char *efifile_path, + const char *efi_distributor); + +void +grub_install_register_ieee1275 (int is_prep, const char *install_device, + int partno, const char *relpath); + +void +grub_install_sgi_setup (const char *install_device, + const char *imgfile, const char *destname); + +int +grub_install_compress_gzip (const char *src, const char *dest); +int +grub_install_compress_lzop (const char *src, const char *dest); +int +grub_install_compress_xz (const char *src, const char *dest); + +void +grub_install_get_blocklist (grub_device_t root_dev, + const char *core_path, const char *core_img, + size_t core_size, + void (*callback) (grub_disk_addr_t sector, + unsigned offset, + unsigned length, + void *data), + void *hook_data); + +void +grub_util_create_envblk_file (const char *name); + +void +grub_util_glue_efi (const char *file32, const char *file64, const char *out); + +void +grub_util_render_label (const char *label_font, + const char *label_bgcolor, + const char *label_color, + const char *label_string, + const char *label); + +const char * +grub_util_get_target_name (const struct grub_install_image_target_desc *t); + +extern char *grub_install_copy_buffer; +#define GRUB_INSTALL_COPY_BUFFER_SIZE 1048576 + +#endif diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/ventoy.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/ventoy.h new file mode 100644 index 0000000..d15e26e --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/ventoy.h @@ -0,0 +1,331 @@ +/****************************************************************************** + * ventoy.h + * + * Copyright (c) 2020, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#ifndef __VENTOY_H__ +#define __VENTOY_H__ + +#define COMPILE_ASSERT(a, expr) extern char __compile_assert##a[(expr) ? 1 : -1] + +#define VENTOY_COMPATIBLE_STR "VENTOY COMPATIBLE" +#define VENTOY_COMPATIBLE_STR_LEN 17 + +#define VENTOY_GUID { 0x77772020, 0x2e77, 0x6576, { 0x6e, 0x74, 0x6f, 0x79, 0x2e, 0x6e, 0x65, 0x74 }} + +typedef enum ventoy_fs_type +{ + ventoy_fs_exfat = 0, /* 0: exfat */ + ventoy_fs_ntfs, /* 1: NTFS */ + ventoy_fs_ext, /* 2: ext2/ext3/ext4 */ + ventoy_fs_xfs, /* 3: XFS */ + ventoy_fs_udf, /* 4: UDF */ + ventoy_fs_fat, /* 5: FAT */ + ventoy_fs_btrfs, /* 6: BTRFS */ + + ventoy_fs_max +}ventoy_fs_type; + +typedef enum ventoy_chain_type +{ + ventoy_chain_linux = 0, /* 0: linux */ + ventoy_chain_windows, /* 1: windows */ + ventoy_chain_wim, /* 2: wim */ + + ventoy_chain_max +}ventoy_chain_type; + +#pragma pack(1) + +typedef struct ventoy_guid +{ + grub_uint32_t data1; + grub_uint16_t data2; + grub_uint16_t data3; + grub_uint8_t data4[8]; +}ventoy_guid; + + +typedef struct ventoy_image_disk_region +{ + grub_uint32_t image_sector_count; /* image sectors contained in this region (in 2048) */ + grub_uint32_t image_start_sector; /* image sector start (in 2048) */ + grub_uint64_t disk_start_sector; /* disk sector start (in 512) */ +}ventoy_image_disk_region; + +typedef struct ventoy_image_location +{ + ventoy_guid guid; + + /* image sector size, 2048/512 */ + grub_uint32_t image_sector_size; + + /* disk sector size, normally the value is 512 */ + grub_uint32_t disk_sector_size; + + grub_uint32_t region_count; + + /* + * disk region data (region_count) + * If the image file has more than one fragments in disk, + * there will be more than one region data here. + * + */ + ventoy_image_disk_region regions[1]; + + /* ventoy_image_disk_region regions[2~region_count-1] */ +}ventoy_image_location; + + +typedef struct ventoy_os_param +{ + ventoy_guid guid; // VENTOY_GUID + grub_uint8_t chksum; // checksum + + grub_uint8_t vtoy_disk_guid[16]; + grub_uint64_t vtoy_disk_size; // disk size in bytes + grub_uint16_t vtoy_disk_part_id; // begin with 1 + grub_uint16_t vtoy_disk_part_type; // 0:exfat 1:ntfs other: reserved + char vtoy_img_path[384]; // It seems to be enough, utf-8 format + grub_uint64_t vtoy_img_size; // image file size in bytes + + /* + * Ventoy will write a copy of ventoy_image_location data into runtime memory + * this is the physically address and length of that memory. + * Address 0 means no such data exist. + * Address will be aligned by 4KB. + * + */ + grub_uint64_t vtoy_img_location_addr; + grub_uint32_t vtoy_img_location_len; + + /* + * These 32 bytes are reserved by ventoy. + * + * vtoy_reserved[0]: vtoy_break_level + * vtoy_reserved[1]: vtoy_debug_level + * vtoy_reserved[2]: vtoy_chain_type 0:Linux 1:Windows 2:wimfile + * vtoy_reserved[3]: vtoy_iso_format 0:iso9660 1:udf + * vtoy_reserved[4]: vtoy_windows_cd_prompt + * vtoy_reserved[5]: vtoy_linux_remount + * vtoy_reserved[6]: vtoy_vlnk + * vtoy_reserved[7~10]: vtoy_disk_sig[4] used for vlnk + * vtoy_reserved[11]: vtoy_win_uefi_max_res + * + */ + grub_uint8_t vtoy_reserved[32]; // Internal use by ventoy + + grub_uint8_t vtoy_disk_signature[4]; + + grub_uint8_t reserved[27]; +}ventoy_os_param; + + +typedef struct ventoy_windows_data +{ + char auto_install_script[384]; + char injection_archive[384]; + grub_uint8_t windows11_bypass_check; + + grub_uint32_t auto_install_len; + + grub_uint8_t windows11_bypass_nro; + + grub_uint8_t reserved[255 - 5]; + + /* auto_intall file buf */ + /* ...... + auto_install_len */ +}ventoy_windows_data; + + +typedef struct ventoy_secure_data +{ + grub_uint8_t magic1[16]; /* VENTOY_GUID */ + grub_uint8_t diskuuid[16]; + grub_uint8_t Checksum[16]; + grub_uint8_t adminSHA256[32]; + grub_uint8_t reserved[4000]; + grub_uint8_t magic2[16]; /* VENTOY_GUID */ +}ventoy_secure_data; + + +typedef struct ventoy_vlnk +{ + ventoy_guid guid; // VENTOY_GUID + grub_uint32_t crc32; // crc32 + grub_uint32_t disk_signature; + grub_uint64_t part_offset; // in bytes + char filepath[384]; + grub_uint8_t reserved[96]; +}ventoy_vlnk; + +#pragma pack() + +// compile assert check : sizeof(ventoy_os_param) must be 512 +COMPILE_ASSERT(1,sizeof(ventoy_os_param) == 512); +COMPILE_ASSERT(2,sizeof(ventoy_secure_data) == 4096); +COMPILE_ASSERT(3,sizeof(ventoy_vlnk) == 512); + + + + + + + +#pragma pack(4) + +typedef struct ventoy_chain_head +{ + ventoy_os_param os_param; + + grub_uint32_t disk_drive; + grub_uint32_t drive_map; + grub_uint32_t disk_sector_size; + + grub_uint64_t real_img_size_in_bytes; + grub_uint64_t virt_img_size_in_bytes; + grub_uint32_t boot_catalog; + grub_uint8_t boot_catalog_sector[2048]; + + grub_uint32_t img_chunk_offset; + grub_uint32_t img_chunk_num; + + grub_uint32_t override_chunk_offset; + grub_uint32_t override_chunk_num; + + grub_uint32_t virt_chunk_offset; + grub_uint32_t virt_chunk_num; +}ventoy_chain_head; + +typedef struct ventoy_image_desc +{ + grub_uint64_t disk_size; + grub_uint64_t part1_size; + grub_uint8_t disk_uuid[16]; + grub_uint8_t disk_signature[4]; + grub_uint32_t img_chunk_count; + /* ventoy_img_chunk list */ +}ventoy_image_desc; + + + +typedef struct ventoy_img_chunk +{ + grub_uint32_t img_start_sector; // sector size: 2KB + grub_uint32_t img_end_sector; // included + + grub_uint64_t disk_start_sector; // in disk_sector_size + grub_uint64_t disk_end_sector; // included +}ventoy_img_chunk; + + +typedef struct ventoy_override_chunk +{ + grub_uint64_t img_offset; + grub_uint32_t override_size; + grub_uint8_t override_data[512]; +}ventoy_override_chunk; + +typedef struct ventoy_virt_chunk +{ + grub_uint32_t mem_sector_start; + grub_uint32_t mem_sector_end; + grub_uint32_t mem_sector_offset; + grub_uint32_t remap_sector_start; + grub_uint32_t remap_sector_end; + grub_uint32_t org_sector_start; +}ventoy_virt_chunk; + +#define DEFAULT_CHUNK_NUM 1024 +typedef struct ventoy_img_chunk_list +{ + char *buf; + grub_uint32_t last_off; + grub_uint32_t err_code; + + grub_uint32_t max_chunk; + grub_uint32_t cur_chunk; + ventoy_img_chunk *chunk; +}ventoy_img_chunk_list; + +#pragma pack() + +#define ventoy_filt_register grub_file_filter_register + +#pragma pack(1) + +#define VTOY_MAX_CONF_REPLACE 2 +#define GRUB_FILE_REPLACE_MAGIC 0x1258BEEF +#define GRUB_IMG_REPLACE_MAGIC 0x1259BEEF + +typedef const char * (*grub_env_get_pf)(const char *name); +typedef int (*grub_env_set_pf)(const char *name, const char *val); +typedef int (*grub_env_printf_pf)(const char *fmt, ...); + +typedef struct ventoy_grub_param_file_replace +{ + grub_uint32_t magic; + char old_file_name[4][256]; + grub_uint32_t old_name_cnt; + grub_uint32_t new_file_virtual_id; +}ventoy_grub_param_file_replace; + +typedef struct ventoy_grub_param +{ + grub_env_get_pf grub_env_get; + grub_env_set_pf grub_env_set; + ventoy_grub_param_file_replace file_replace; + ventoy_grub_param_file_replace img_replace[VTOY_MAX_CONF_REPLACE]; + grub_env_printf_pf grub_env_printf; +}ventoy_grub_param; + +#pragma pack() + +#define VTOY_CHUNK_BUF_SIZE (4 * 1024 * 1024) + +typedef enum vtoy_chunk_err +{ + VTOY_CHUNK_ERR_NONE = 0, + VTOY_CHUNK_ERR_MULTI_DEV, + VTOY_CHUNK_ERR_RAID, + VTOY_CHUNK_ERR_COMPRESS, + VTOY_CHUNK_ERR_NOT_FLAT, + VTOY_CHUNK_ERR_OVER_FLOW, + VTOY_CHUNK_ERR_MAX +}vtoy_chunk_err; + +int grub_ext_get_file_chunk(grub_uint64_t part_start, grub_file_t file, ventoy_img_chunk_list *chunk_list); +int grub_btrfs_get_file_chunk(grub_uint64_t part_start, grub_file_t file, ventoy_img_chunk_list *chunk_list); +int grub_fat_get_file_chunk(grub_uint64_t part_start, grub_file_t file, ventoy_img_chunk_list *chunk_list); +void grub_iso9660_set_nojoliet(int nojoliet); +int grub_iso9660_is_joliet(void); +grub_uint64_t grub_iso9660_get_last_read_pos(grub_file_t file); +grub_uint64_t grub_iso9660_get_last_file_dirent_pos(grub_file_t file); +grub_uint64_t grub_udf_get_file_offset(grub_file_t file); +grub_uint64_t grub_udf_get_last_pd_size_offset(void); +grub_uint64_t grub_udf_get_last_file_attr_offset +( + grub_file_t file, + grub_uint32_t *startBlock, + grub_uint64_t *fe_entry_size_offset +); +int ventoy_is_efi_os(void); +void ventoy_memfile_env_set(const char *prefix, const void *buf, unsigned long long len); + +#endif /* __VENTOY_H__ */ + diff --git a/GRUB2/MOD_SRC/grub-2.04/install.sh b/GRUB2/MOD_SRC/grub-2.04/install.sh new file mode 100644 index 0000000..45c7cb7 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/install.sh @@ -0,0 +1,137 @@ +#!/bin/bash + +VT_DIR=$PWD/../../.. + +rm -rf $VT_DIR/GRUB2/INSTALL +rm -rf $VT_DIR/GRUB2/PXE +mkdir -p $VT_DIR/GRUB2/INSTALL +mkdir -p $VT_DIR/GRUB2/PXE + +make install + +PATH=$VT_DIR/GRUB2/INSTALL/bin/:$VT_DIR/GRUB2/INSTALL/sbin/:$PATH + +net_modules_legacy="net tftp http" +all_modules_legacy="file date drivemap blocklist newc vga_text ntldr search at_keyboard usb_keyboard gcry_md5 hashsum gzio xzio lzopio lspci pci ext2 xfs ventoy chain read halt iso9660 linux16 test true sleep reboot echo videotest videoinfo videotest_checksum video_colors video_cirrus video_bochs vga vbe font video gettext extcmd terminal linux minicmd help configfile tr trig boot biosdisk disk ls tar squash4 password_pbkdf2 all_video png jpeg part_gpt part_msdos fat exfat ntfs loopback gzio normal video_fb udf gfxmenu gfxterm gfxterm_background gfxterm_menu smbios" + +net_modules_uefi="efinet net tftp http" +all_modules_uefi="file setkey blocklist ventoy test true regexp newc search at_keyboard usb_keyboard gcry_md5 hashsum gzio xzio lzopio ext2 xfs read halt sleep serial terminfo png password_pbkdf2 gcry_sha512 pbkdf2 part_gpt part_msdos ls tar squash4 loopback part_apple minicmd diskfilter linux relocator jpeg iso9660 udf hfsplus halt acpi mmap gfxmenu video_colors trig bitmap_scale gfxterm bitmap font fat exfat ntfs fshelp efifwsetup reboot echo configfile normal terminal gettext chain priority_queue bufio datetime cat extcmd crypto gzio boot all_video efi_gop efi_uga video_bochs video_cirrus video video_fb gfxterm_background gfxterm_menu mouse fwload smbios zfs" + +all_modules_arm64_uefi="file setkey blocklist ventoy test true regexp newc search gcry_md5 hashsum gzio xzio lzopio ext2 xfs read halt sleep serial terminfo png password_pbkdf2 gcry_sha512 pbkdf2 part_gpt part_msdos ls tar squash4 loopback part_apple minicmd diskfilter linux jpeg iso9660 udf hfsplus halt acpi mmap gfxmenu video_colors trig bitmap_scale gfxterm bitmap font fat exfat ntfs fshelp efifwsetup reboot echo configfile normal terminal gettext chain priority_queue bufio datetime cat extcmd crypto gzio boot all_video efi_gop video video_fb gfxterm_background gfxterm_menu zfs" + +all_modules_mips64el_uefi="file setkey blocklist ventoy test true regexp newc search gcry_md5 hashsum gzio xzio lzopio ext2 xfs read halt sleep serial terminfo png password_pbkdf2 gcry_sha512 pbkdf2 part_gpt part_msdos ls tar squash4 loopback part_apple minicmd diskfilter linux jpeg iso9660 udf hfsplus halt acpi mmap gfxmenu video_colors trig bitmap_scale gfxterm bitmap font fat exfat ntfs fshelp efifwsetup reboot echo configfile normal terminal gettext chain priority_queue bufio datetime cat extcmd crypto gzio boot all_video efi_gop video video_fb gfxterm_background gfxterm_menu zfs" + + +if [ "$1" = "uefi" ]; then + all_modules="$net_modules_uefi $all_modules_uefi " + + grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/x86_64-efi" --prefix '(,2)/grub' --output "$VT_DIR/INSTALL/EFI/BOOT/grubx64_real.efi" --format 'x86_64-efi' --compression 'auto' $all_modules_uefi + + #grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/x86_64-efi" -c "$VT_DIR/LiveCD/GRUB/embed.cfg" --prefix '/EFI/boot' --output "$VT_DIR/LiveCD/GRUB/bootx64.efi" --format 'x86_64-efi' --compression 'auto' $all_modules_uefi 'fat' 'part_msdos' +elif [ "$1" = "i386efi" ]; then + all_modules="$net_modules_uefi $all_modules_uefi " + + grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/i386-efi" --prefix '(,2)/grub' --output "$VT_DIR/INSTALL/EFI/BOOT/grubia32_real.efi" --format 'i386-efi' --compression 'auto' $all_modules_uefi +elif [ "$1" = "arm64" ]; then + all_modules="$net_modules_uefi $all_modules_arm64_uefi " + + grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/arm64-efi" --prefix '(,2)/grub' --output "$VT_DIR/INSTALL/EFI/BOOT/BOOTAA64.EFI" --format 'arm64-efi' --compression 'auto' $all_modules_arm64_uefi +elif [ "$1" = "mips64el" ]; then + all_modules="$net_modules_uefi $all_modules_mips64el_uefi " + + grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/mips64el-efi" --prefix '(,2)/grub' --output "$VT_DIR/INSTALL/EFI/BOOT/BOOTMIPS.EFI" --format 'mips64el-efi' --compression 'auto' $all_modules_mips64el_uefi +else + all_modules="$net_modules_legacy $all_modules_legacy " + grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/i386-pc" --prefix '(,2)/grub' --output "$VT_DIR/INSTALL/grub/i386-pc/core.img" --format 'i386-pc' --compression 'auto' $all_modules_legacy 'fat' 'part_msdos' 'biosdisk' + + #grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/i386-pc" -c "$VT_DIR/LiveCD/GRUB/embed.cfg" --prefix '/EFI/boot' --output "$VT_DIR/LiveCD/GRUB/cdrom.img" --format 'i386-pc-eltorito' --compression 'auto' $all_modules_legacy 'biosdisk' 'iso9660' 'fat' 'part_msdos' + #rm -f $VT_DIR/LiveCD/GRUB/boot_hybrid.img + #cp -a $VT_DIR/GRUB2/INSTALL/lib/grub/i386-pc/boot_hybrid.img $VT_DIR/LiveCD/GRUB/boot_hybrid.img +fi + +grub-mknetdir --modules="$all_modules" --net-directory=$VT_DIR/GRUB2/PXE --subdir=grub2 --locales=en@quot || exit 1 + +if [ "$1" = "uefi" ]; then + rm -f $VT_DIR/GRUB2/NBP/core.efi + cp -a $VT_DIR/GRUB2/PXE/grub2/x86_64-efi/core.efi $VT_DIR/GRUB2/NBP/core.efi || exit 1 + + rm -rf $VT_DIR/INSTALL/grub/x86_64-efi + mkdir -p $VT_DIR/INSTALL/grub/x86_64-efi + + cp -a $VT_DIR/GRUB2/PXE/grub2/x86_64-efi/normal.mod $VT_DIR/INSTALL/grub/x86_64-efi/normal.mod || exit 1 + + #copy other modules + ls -1 $VT_DIR/GRUB2/INSTALL/lib/grub/x86_64-efi/ | egrep '\.(lst|mod)$' | while read line; do + if ! echo $all_modules | grep -q " ${line%.mod} "; then + echo "Copy $line ..." + cp -a $VT_DIR/GRUB2/INSTALL/lib/grub/x86_64-efi/$line $VT_DIR/INSTALL/grub/x86_64-efi/ + fi + done +elif [ "$1" = "i386efi" ]; then + rm -f $VT_DIR/GRUB2/NBP/core.efi + cp -a $VT_DIR/GRUB2/PXE/grub2/i386-efi/core.efi $VT_DIR/GRUB2/NBP/core.efi || exit 1 + + rm -rf $VT_DIR/INSTALL/grub/i386-efi + mkdir -p $VT_DIR/INSTALL/grub/i386-efi + + cp -a $VT_DIR/GRUB2/PXE/grub2/i386-efi/normal.mod $VT_DIR/INSTALL/grub/i386-efi/normal.mod || exit 1 + + #copy other modules + ls -1 $VT_DIR/GRUB2/INSTALL/lib/grub/i386-efi/ | egrep '\.(lst|mod)$' | while read line; do + if ! echo $all_modules | grep -q " ${line%.mod} "; then + echo "Copy $line ..." + cp -a $VT_DIR/GRUB2/INSTALL/lib/grub/i386-efi/$line $VT_DIR/INSTALL/grub/i386-efi/ + fi + done +elif [ "$1" = "arm64" ]; then + rm -f $VT_DIR/GRUB2/NBP/core.efi + cp -a $VT_DIR/GRUB2/PXE/grub2/arm64-efi/core.efi $VT_DIR/GRUB2/NBP/core.efi || exit 1 + + rm -rf $VT_DIR/INSTALL/grub/arm64-efi + mkdir -p $VT_DIR/INSTALL/grub/arm64-efi + + cp -a $VT_DIR/GRUB2/PXE/grub2/arm64-efi/normal.mod $VT_DIR/INSTALL/grub/arm64-efi/normal.mod || exit 1 + + #copy other modules + ls -1 $VT_DIR/GRUB2/INSTALL/lib/grub/arm64-efi/ | egrep '\.(lst|mod)$' | while read line; do + if ! echo $all_modules | grep -q " ${line%.mod} "; then + echo "Copy $line ..." + cp -a $VT_DIR/GRUB2/INSTALL/lib/grub/arm64-efi/$line $VT_DIR/INSTALL/grub/arm64-efi/ + xz $VT_DIR/INSTALL/grub/arm64-efi/$line + mv $VT_DIR/INSTALL/grub/arm64-efi/${line}.xz $VT_DIR/INSTALL/grub/arm64-efi/${line} + fi + done +elif [ "$1" = "mips64el" ]; then + rm -f $VT_DIR/GRUB2/NBP/core.efi + cp -a $VT_DIR/GRUB2/PXE/grub2/mips64el-efi/core.efi $VT_DIR/GRUB2/NBP/core.efi || exit 1 + + rm -rf $VT_DIR/INSTALL/grub/mips64el-efi + mkdir -p $VT_DIR/INSTALL/grub/mips64el-efi + + cp -a $VT_DIR/GRUB2/PXE/grub2/mips64el-efi/normal.mod $VT_DIR/INSTALL/grub/mips64el-efi/normal.mod || exit 1 + + #copy other modules + ls -1 $VT_DIR/GRUB2/INSTALL/lib/grub/mips64el-efi/ | egrep '\.(lst|mod)$' | while read line; do + if ! echo $all_modules | grep -q " ${line%.mod} "; then + echo "Copy $line ..." + cp -a $VT_DIR/GRUB2/INSTALL/lib/grub/mips64el-efi/$line $VT_DIR/INSTALL/grub/mips64el-efi/ + xz $VT_DIR/INSTALL/grub/mips64el-efi/$line + mv $VT_DIR/INSTALL/grub/mips64el-efi/${line}.xz $VT_DIR/INSTALL/grub/mips64el-efi/${line} + fi + done +else + rm -f $VT_DIR/GRUB2/NBP/core.0 + cp -a $VT_DIR/GRUB2/PXE/grub2/i386-pc/core.0 $VT_DIR/GRUB2/NBP/core.0 || exit 1 + + rm -f $VT_DIR/INSTALL/grub/i386-pc/boot.img + cp -a $VT_DIR/GRUB2/INSTALL/lib/grub/i386-pc/boot.img $VT_DIR/INSTALL/grub/i386-pc/boot.img || exit 1 + + #copy other modules + ls -1 $VT_DIR/GRUB2/INSTALL/lib/grub/i386-pc/ | egrep '\.(lst|mod)$' | while read line; do + if ! echo $all_modules | grep -q " ${line%.mod} "; then + echo "Copy $line ..." + rm -f $VT_DIR/INSTALL/grub/i386-pc/$line + cp -a $VT_DIR/GRUB2/INSTALL/lib/grub/i386-pc/$line $VT_DIR/INSTALL/grub/i386-pc/ + fi + done +fi diff --git a/GRUB2/MOD_SRC/grub-2.04/util/grub-install-common.c b/GRUB2/MOD_SRC/grub-2.04/util/grub-install-common.c new file mode 100644 index 0000000..b18d55f --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/util/grub-install-common.c @@ -0,0 +1,1000 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#pragma GCC diagnostic ignored "-Wformat-nonliteral" + +char * +grub_install_help_filter (int key, const char *text, + void *input __attribute__ ((unused))) +{ + switch (key) + { + case GRUB_INSTALL_OPTIONS_INSTALL_THEMES: + return xasprintf(text, "starfield"); + case GRUB_INSTALL_OPTIONS_INSTALL_FONTS: + return xasprintf(text, "unicode"); + case GRUB_INSTALL_OPTIONS_DIRECTORY: + case GRUB_INSTALL_OPTIONS_DIRECTORY2: + return xasprintf(text, grub_util_get_pkglibdir ()); + case GRUB_INSTALL_OPTIONS_LOCALE_DIRECTORY: + return xasprintf(text, grub_util_get_localedir ()); + case GRUB_INSTALL_OPTIONS_THEMES_DIRECTORY: + return grub_util_path_concat (2, grub_util_get_pkgdatadir (), "themes"); + default: + return (char *) text; + } +} + +#pragma GCC diagnostic error "-Wformat-nonliteral" + +static int (*compress_func) (const char *src, const char *dest) = NULL; +char *grub_install_copy_buffer; +static char *dtb; + +int +grub_install_copy_file (const char *src, + const char *dst, + int is_needed) +{ + grub_util_fd_t in, out; + ssize_t r; + + grub_util_info ("copying `%s' -> `%s'", src, dst); + + in = grub_util_fd_open (src, GRUB_UTIL_FD_O_RDONLY); + if (!GRUB_UTIL_FD_IS_VALID (in)) + { + if (is_needed) + grub_util_error (_("cannot open `%s': %s"), src, grub_util_fd_strerror ()); + else + grub_util_info (_("cannot open `%s': %s"), src, grub_util_fd_strerror ()); + return 0; + } + out = grub_util_fd_open (dst, GRUB_UTIL_FD_O_WRONLY + | GRUB_UTIL_FD_O_CREATTRUNC); + if (!GRUB_UTIL_FD_IS_VALID (out)) + { + grub_util_error (_("cannot open `%s': %s"), dst, + grub_util_fd_strerror ()); + grub_util_fd_close (in); + return 0; + } + + if (!grub_install_copy_buffer) + grub_install_copy_buffer = xmalloc (GRUB_INSTALL_COPY_BUFFER_SIZE); + + while (1) + { + r = grub_util_fd_read (in, grub_install_copy_buffer, GRUB_INSTALL_COPY_BUFFER_SIZE); + if (r <= 0) + break; + r = grub_util_fd_write (out, grub_install_copy_buffer, r); + if (r <= 0) + break; + } + if (grub_util_fd_sync (out) < 0) + r = -1; + if (grub_util_fd_close (in) < 0) + r = -1; + if (grub_util_fd_close (out) < 0) + r = -1; + + if (r < 0) + grub_util_error (_("cannot copy `%s' to `%s': %s"), + src, dst, grub_util_fd_strerror ()); + + return 1; +} + +static int +grub_install_compress_file (const char *in_name, + const char *out_name, + int is_needed) +{ + int ret; + + if (!compress_func) + ret = grub_install_copy_file (in_name, out_name, is_needed); + else + { + grub_util_info ("compressing `%s' -> `%s'", in_name, out_name); + ret = !compress_func (in_name, out_name); + if (!ret && is_needed) + grub_util_warn (_("can't compress `%s' to `%s'"), in_name, out_name); + } + + if (!ret && is_needed) + grub_util_error (_("cannot copy `%s' to `%s': %s"), + in_name, out_name, grub_util_fd_strerror ()); + + return ret; +} + +static int +is_path_separator (char c) +{ +#if defined (__MINGW32__) || defined (__CYGWIN__) + if (c == '\\') + return 1; +#endif + if (c == '/') + return 1; + return 0; +} + +void +grub_install_mkdir_p (const char *dst) +{ + char *t = xstrdup (dst); + char *p; + for (p = t; *p; p++) + { + if (is_path_separator (*p)) + { + char s = *p; + *p = '\0'; + grub_util_mkdir (t); + *p = s; + } + } + grub_util_mkdir (t); + free (t); +} + +static void +clean_grub_dir (const char *di) +{ + grub_util_fd_dir_t d; + grub_util_fd_dirent_t de; + + d = grub_util_fd_opendir (di); + if (!d) + grub_util_error (_("cannot open directory `%s': %s"), + di, grub_util_fd_strerror ()); + + while ((de = grub_util_fd_readdir (d))) + { + const char *ext = strrchr (de->d_name, '.'); + if ((ext && (strcmp (ext, ".mod") == 0 + || strcmp (ext, ".lst") == 0 + || strcmp (ext, ".img") == 0 + || strcmp (ext, ".mo") == 0) + && strcmp (de->d_name, "menu.lst") != 0) + || strcmp (de->d_name, "efiemu32.o") == 0 + || strcmp (de->d_name, "efiemu64.o") == 0) + { + char *x = grub_util_path_concat (2, di, de->d_name); + if (grub_util_unlink (x) < 0) + grub_util_error (_("cannot delete `%s': %s"), x, + grub_util_fd_strerror ()); + free (x); + } + } + grub_util_fd_closedir (d); +} + +struct install_list +{ + int is_default; + char **entries; + size_t n_entries; + size_t n_alloc; +}; + +struct install_list install_modules = { 1, 0, 0, 0 }; +struct install_list modules = { 1, 0, 0, 0 }; +struct install_list install_locales = { 1, 0, 0, 0 }; +struct install_list install_fonts = { 1, 0, 0, 0 }; +struct install_list install_themes = { 1, 0, 0, 0 }; +char *grub_install_source_directory = NULL; +char *grub_install_locale_directory = NULL; +char *grub_install_themes_directory = NULL; + +void +grub_install_push_module (const char *val) +{ + modules.is_default = 0; + if (modules.n_entries + 1 >= modules.n_alloc) + { + modules.n_alloc <<= 1; + if (modules.n_alloc < 16) + modules.n_alloc = 16; + modules.entries = xrealloc (modules.entries, + modules.n_alloc * sizeof (*modules.entries)); + } + modules.entries[modules.n_entries++] = xstrdup (val); + modules.entries[modules.n_entries] = NULL; +} + +void +grub_install_pop_module (void) +{ + modules.n_entries--; + free (modules.entries[modules.n_entries]); + modules.entries[modules.n_entries] = NULL; +} + + +static void +handle_install_list (struct install_list *il, const char *val, + int default_all) +{ + const char *ptr; + char **ce; + il->is_default = 0; + free (il->entries); + il->entries = NULL; + il->n_entries = 0; + if (strcmp (val, "all") == 0 && default_all) + { + il->is_default = 1; + return; + } + ptr = val; + while (1) + { + while (*ptr && grub_isspace (*ptr)) + ptr++; + if (!*ptr) + break; + while (*ptr && !grub_isspace (*ptr)) + ptr++; + il->n_entries++; + } + il->n_alloc = il->n_entries + 1; + il->entries = xmalloc (il->n_alloc * sizeof (il->entries[0])); + ptr = val; + for (ce = il->entries; ; ce++) + { + const char *bptr; + while (*ptr && grub_isspace (*ptr)) + ptr++; + if (!*ptr) + break; + bptr = ptr; + while (*ptr && !grub_isspace (*ptr)) + ptr++; + *ce = xmalloc (ptr - bptr + 1); + memcpy (*ce, bptr, ptr - bptr); + (*ce)[ptr - bptr] = '\0'; + } + *ce = NULL; +} + +static char **pubkeys; +static size_t npubkeys; +static grub_compression_t compression; + +int +grub_install_parse (int key, char *arg) +{ + switch (key) + { + case 'C': + if (grub_strcmp (arg, "xz") == 0) + { +#ifdef HAVE_LIBLZMA + compression = GRUB_COMPRESSION_XZ; +#else + grub_util_error ("%s", + _("grub-mkimage is compiled without XZ support")); +#endif + } + else if (grub_strcmp (arg, "none") == 0) + compression = GRUB_COMPRESSION_NONE; + else if (grub_strcmp (arg, "auto") == 0) + compression = GRUB_COMPRESSION_AUTO; + else + grub_util_error (_("Unknown compression format %s"), arg); + return 1; + case 'k': + pubkeys = xrealloc (pubkeys, + sizeof (pubkeys[0]) + * (npubkeys + 1)); + pubkeys[npubkeys++] = xstrdup (arg); + return 1; + + case GRUB_INSTALL_OPTIONS_VERBOSITY: + verbosity++; + return 1; + + case GRUB_INSTALL_OPTIONS_DIRECTORY: + case GRUB_INSTALL_OPTIONS_DIRECTORY2: + free (grub_install_source_directory); + grub_install_source_directory = xstrdup (arg); + return 1; + case GRUB_INSTALL_OPTIONS_LOCALE_DIRECTORY: + free (grub_install_locale_directory); + grub_install_locale_directory = xstrdup (arg); + return 1; + case GRUB_INSTALL_OPTIONS_THEMES_DIRECTORY: + free (grub_install_themes_directory); + grub_install_themes_directory = xstrdup (arg); + return 1; + case GRUB_INSTALL_OPTIONS_INSTALL_MODULES: + handle_install_list (&install_modules, arg, 0); + return 1; + case GRUB_INSTALL_OPTIONS_MODULES: + handle_install_list (&modules, arg, 0); + return 1; + case GRUB_INSTALL_OPTIONS_INSTALL_LOCALES: + handle_install_list (&install_locales, arg, 0); + return 1; + case GRUB_INSTALL_OPTIONS_INSTALL_THEMES: + handle_install_list (&install_themes, arg, 0); + return 1; + case GRUB_INSTALL_OPTIONS_INSTALL_FONTS: + handle_install_list (&install_fonts, arg, 0); + return 1; + case GRUB_INSTALL_OPTIONS_DTB: + if (dtb) + free (dtb); + dtb = xstrdup (arg); + return 1; + case GRUB_INSTALL_OPTIONS_INSTALL_COMPRESS: + if (strcmp (arg, "no") == 0 + || strcmp (arg, "none") == 0) + { + compress_func = NULL; + return 1; + } + if (strcmp (arg, "gz") == 0) + { + compress_func = grub_install_compress_gzip; + return 1; + } + if (strcmp (arg, "xz") == 0) + { + compress_func = grub_install_compress_xz; + return 1; + } + if (strcmp (arg, "lzo") == 0) + { + compress_func = grub_install_compress_lzop; + return 1; + } + grub_util_error (_("Unrecognized compression `%s'"), arg); + case GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE: + return 1; + default: + return 0; + } +} + +static int +decompressors (void) +{ + if (compress_func == grub_install_compress_gzip) + { + grub_install_push_module ("gzio"); + return 1; + } + if (compress_func == grub_install_compress_xz) + { + grub_install_push_module ("xzio"); + grub_install_push_module ("gcry_crc"); + return 2; + } + if (compress_func == grub_install_compress_lzop) + { + grub_install_push_module ("lzopio"); + grub_install_push_module ("adler32"); + grub_install_push_module ("gcry_crc"); + return 3; + } + return 0; +} + +void +grub_install_make_image_wrap_file (const char *dir, const char *prefix, + FILE *fp, const char *outname, + char *memdisk_path, + char *config_path, + const char *mkimage_target, int note) +{ + const struct grub_install_image_target_desc *tgt; + const char *const compnames[] = + { + [GRUB_COMPRESSION_AUTO] = "auto", + [GRUB_COMPRESSION_NONE] = "none", + [GRUB_COMPRESSION_XZ] = "xz", + [GRUB_COMPRESSION_LZMA] = "lzma", + }; + grub_size_t slen = 1; + char *s, *p; + char **pk, **md; + int dc = decompressors (); + + if (memdisk_path) + slen += 20 + grub_strlen (memdisk_path); + if (config_path) + slen += 20 + grub_strlen (config_path); + + for (pk = pubkeys; pk < pubkeys + npubkeys; pk++) + slen += 20 + grub_strlen (*pk); + + for (md = modules.entries; *md; md++) + { + slen += 10 + grub_strlen (*md); + } + + p = s = xmalloc (slen); + if (memdisk_path) + { + p = grub_stpcpy (p, "--memdisk '"); + p = grub_stpcpy (p, memdisk_path); + *p++ = '\''; + *p++ = ' '; + } + if (config_path) + { + p = grub_stpcpy (p, "--config '"); + p = grub_stpcpy (p, config_path); + *p++ = '\''; + *p++ = ' '; + } + for (pk = pubkeys; pk < pubkeys + npubkeys; pk++) + { + p = grub_stpcpy (p, "--pubkey '"); + p = grub_stpcpy (p, *pk); + *p++ = '\''; + *p++ = ' '; + } + + for (md = modules.entries; *md; md++) + { + *p++ = '\''; + p = grub_stpcpy (p, *md); + *p++ = '\''; + *p++ = ' '; + } + + *p = '\0'; + + grub_util_info ("grub-mkimage --directory '%s' --prefix '%s'" + " --output '%s' " + " --dtb '%s' " + "--format '%s' --compression '%s' %s %s\n", + dir, prefix, + outname, dtb ? : "", mkimage_target, + compnames[compression], note ? "--note" : "", s); + free (s); + + tgt = grub_install_get_image_target (mkimage_target); + if (!tgt) + grub_util_error (_("unknown target format %s"), mkimage_target); + + grub_install_generate_image (dir, prefix, fp, outname, + modules.entries, memdisk_path, + pubkeys, npubkeys, config_path, tgt, + note, compression, dtb); + while (dc--) + grub_install_pop_module (); +} + +void +grub_install_make_image_wrap (const char *dir, const char *prefix, + const char *outname, char *memdisk_path, + char *config_path, + const char *mkimage_target, int note) +{ + FILE *fp; + + fp = grub_util_fopen (outname, "wb"); + if (! fp) + grub_util_error (_("cannot open `%s': %s"), outname, + strerror (errno)); + grub_install_make_image_wrap_file (dir, prefix, fp, outname, + memdisk_path, config_path, + mkimage_target, note); + if (grub_util_file_sync (fp) < 0) + grub_util_error (_("cannot sync `%s': %s"), outname, strerror (errno)); + fclose (fp); +} + +static void +copy_by_ext (const char *srcd, + const char *dstd, + const char *extf, + int req) +{ + grub_util_fd_dir_t d; + grub_util_fd_dirent_t de; + + d = grub_util_fd_opendir (srcd); + if (!d && !req) + return; + if (!d) + grub_util_error (_("cannot open directory `%s': %s"), + srcd, grub_util_fd_strerror ()); + + while ((de = grub_util_fd_readdir (d))) + { + const char *ext = strrchr (de->d_name, '.'); + if (ext && strcmp (ext, extf) == 0) + { + char *srcf = grub_util_path_concat (2, srcd, de->d_name); + char *dstf = grub_util_path_concat (2, dstd, de->d_name); + grub_install_compress_file (srcf, dstf, 1); + free (srcf); + free (dstf); + } + } + grub_util_fd_closedir (d); +} + +static void +copy_all (const char *srcd, + const char *dstd) +{ + grub_util_fd_dir_t d; + grub_util_fd_dirent_t de; + + d = grub_util_fd_opendir (srcd); + if (!d) + grub_util_error (_("cannot open directory `%s': %s"), + srcd, grub_util_fd_strerror ()); + + while ((de = grub_util_fd_readdir (d))) + { + char *srcf; + char *dstf; + if (strcmp (de->d_name, ".") == 0 + || strcmp (de->d_name, "..") == 0) + continue; + srcf = grub_util_path_concat (2, srcd, de->d_name); + if (grub_util_is_special_file (srcf) + || grub_util_is_directory (srcf)) + continue; + dstf = grub_util_path_concat (2, dstd, de->d_name); + grub_install_compress_file (srcf, dstf, 1); + free (srcf); + free (dstf); + } + grub_util_fd_closedir (d); +} + +#if !(defined (GRUB_UTIL) && defined(ENABLE_NLS) && ENABLE_NLS) +static const char * +get_localedir (void) +{ + if (grub_install_locale_directory) + return grub_install_locale_directory; + else + return grub_util_get_localedir (); +} + +static void +copy_locales (const char *dstd) +{ + grub_util_fd_dir_t d; + grub_util_fd_dirent_t de; + const char *locale_dir = get_localedir (); + + d = grub_util_fd_opendir (locale_dir); + if (!d) + { + grub_util_warn (_("cannot open directory `%s': %s"), + locale_dir, grub_util_fd_strerror ()); + return; + } + + while ((de = grub_util_fd_readdir (d))) + { + char *srcf; + char *dstf; + char *ext; + if (strcmp (de->d_name, ".") == 0) + continue; + if (strcmp (de->d_name, "..") == 0) + continue; + ext = grub_strrchr (de->d_name, '.'); + if (ext && (grub_strcmp (ext, ".mo") == 0 + || grub_strcmp (ext, ".gmo") == 0)) + { + srcf = grub_util_path_concat (2, locale_dir, de->d_name); + dstf = grub_util_path_concat (2, dstd, de->d_name); + ext = grub_strrchr (dstf, '.'); + grub_strcpy (ext, ".mo"); + } + else + { + srcf = grub_util_path_concat_ext (4, locale_dir, de->d_name, + "LC_MESSAGES", PACKAGE, ".mo"); + dstf = grub_util_path_concat_ext (2, dstd, de->d_name, ".mo"); + } + grub_install_compress_file (srcf, dstf, 0); + free (srcf); + free (dstf); + } + grub_util_fd_closedir (d); +} +#endif + +static void +grub_install_copy_nls(const char *src __attribute__ ((unused)), + const char *dst __attribute__ ((unused))) +{ +#if !(defined (GRUB_UTIL) && defined(ENABLE_NLS) && ENABLE_NLS) + char *dst_locale; + + dst_locale = grub_util_path_concat (2, dst, "locale"); + grub_install_mkdir_p (dst_locale); + clean_grub_dir (dst_locale); + + if (install_locales.is_default) + { + char *srcd = grub_util_path_concat (2, src, "po"); + copy_by_ext (srcd, dst_locale, ".mo", 0); + copy_locales (dst_locale); + free (srcd); + } + else + { + size_t i; + const char *locale_dir = get_localedir (); + + for (i = 0; i < install_locales.n_entries; i++) + { + char *srcf = grub_util_path_concat_ext (3, src, "po", + install_locales.entries[i], + ".mo"); + char *dstf = grub_util_path_concat_ext (2, dst_locale, + install_locales.entries[i], + ".mo"); + if (grub_install_compress_file (srcf, dstf, 0)) + { + free (srcf); + free (dstf); + continue; + } + free (srcf); + srcf = grub_util_path_concat_ext (4, locale_dir, + install_locales.entries[i], + "LC_MESSAGES", PACKAGE, ".mo"); + if (grub_install_compress_file (srcf, dstf, 0) == 0) + grub_util_error (_("cannot find locale `%s'"), + install_locales.entries[i]); + free (srcf); + free (dstf); + } + } + free (dst_locale); +#endif +} + +static struct +{ + const char *cpu; + const char *platform; +} platforms[GRUB_INSTALL_PLATFORM_MAX] = + { + [GRUB_INSTALL_PLATFORM_I386_PC] = { "i386", "pc" }, + [GRUB_INSTALL_PLATFORM_I386_EFI] = { "i386", "efi" }, + [GRUB_INSTALL_PLATFORM_I386_QEMU] = { "i386", "qemu" }, + [GRUB_INSTALL_PLATFORM_I386_COREBOOT] = { "i386", "coreboot" }, + [GRUB_INSTALL_PLATFORM_I386_MULTIBOOT] = { "i386", "multiboot" }, + [GRUB_INSTALL_PLATFORM_I386_IEEE1275] = { "i386", "ieee1275" }, + [GRUB_INSTALL_PLATFORM_X86_64_EFI] = { "x86_64", "efi" }, + [GRUB_INSTALL_PLATFORM_I386_XEN] = { "i386", "xen" }, + [GRUB_INSTALL_PLATFORM_X86_64_XEN] = { "x86_64", "xen" }, + [GRUB_INSTALL_PLATFORM_I386_XEN_PVH] = { "i386", "xen_pvh" }, + [GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON] = { "mipsel", "loongson" }, + [GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS] = { "mipsel", "qemu_mips" }, + [GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS] = { "mips", "qemu_mips" }, + [GRUB_INSTALL_PLATFORM_MIPSEL_ARC] = { "mipsel", "arc" }, + [GRUB_INSTALL_PLATFORM_MIPS_ARC] = { "mips", "arc" }, + [GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275] = { "sparc64", "ieee1275" }, + [GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275] = { "powerpc", "ieee1275" }, + [GRUB_INSTALL_PLATFORM_IA64_EFI] = { "ia64", "efi" }, + [GRUB_INSTALL_PLATFORM_ARM_EFI] = { "arm", "efi" }, + [GRUB_INSTALL_PLATFORM_ARM64_EFI] = { "arm64", "efi" }, + [GRUB_INSTALL_PLATFORM_MIPS64EL_EFI] = { "mips64el","efi" }, + [GRUB_INSTALL_PLATFORM_ARM_UBOOT] = { "arm", "uboot" }, + [GRUB_INSTALL_PLATFORM_ARM_COREBOOT] = { "arm", "coreboot" }, + [GRUB_INSTALL_PLATFORM_RISCV32_EFI] = { "riscv32", "efi" }, + [GRUB_INSTALL_PLATFORM_RISCV64_EFI] = { "riscv64", "efi" }, + }; + +char * +grub_install_get_platforms_string (void) +{ + char **arr = xmalloc (sizeof (char *) * ARRAY_SIZE (platforms)); + int platform_strins_len = 0; + char *platforms_string; + char *ptr; + unsigned i; + for (i = 0; i < ARRAY_SIZE (platforms); i++) + { + arr[i] = xasprintf ("%s-%s", platforms[i].cpu, + platforms[i].platform); + platform_strins_len += strlen (arr[i]) + 2; + } + ptr = platforms_string = xmalloc (platform_strins_len); + qsort (arr, ARRAY_SIZE (platforms), sizeof (char *), grub_qsort_strcmp); + for (i = 0; i < ARRAY_SIZE (platforms); i++) + { + strcpy (ptr, arr[i]); + ptr += strlen (arr[i]); + *ptr++ = ','; + *ptr++ = ' '; + free (arr[i]); + } + ptr[-2] = 0; + free (arr); + + return platforms_string; +} + +char * +grub_install_get_platform_name (enum grub_install_plat platid) +{ + return xasprintf ("%s-%s", platforms[platid].cpu, + platforms[platid].platform); +} + +const char * +grub_install_get_platform_cpu (enum grub_install_plat platid) +{ + return platforms[platid].cpu; +} + +const char * +grub_install_get_platform_platform (enum grub_install_plat platid) +{ + return platforms[platid].platform; +} + + +void +grub_install_copy_files (const char *src, + const char *dst, + enum grub_install_plat platid) +{ + char *dst_platform, *dst_fonts; + const char *pkgdatadir = grub_util_get_pkgdatadir (); + char *themes_dir; + + { + char *platform; + platform = xasprintf ("%s-%s", platforms[platid].cpu, + platforms[platid].platform); + dst_platform = grub_util_path_concat (2, dst, platform); + free (platform); + } + dst_fonts = grub_util_path_concat (2, dst, "fonts"); + grub_install_mkdir_p (dst_platform); + clean_grub_dir (dst); + clean_grub_dir (dst_platform); + + grub_install_copy_nls(src, dst); + + if (install_modules.is_default) + copy_by_ext (src, dst_platform, ".mod", 1); + else + { + struct grub_util_path_list *path_list, *p; + + path_list = grub_util_resolve_dependencies (src, "moddep.lst", + install_modules.entries); + for (p = path_list; p; p = p->next) + { + const char *srcf = p->name; + const char *dir; + char *dstf; + + dir = grub_strrchr (srcf, '/'); + if (dir) + dir++; + else + dir = srcf; + dstf = grub_util_path_concat (2, dst_platform, dir); + grub_install_compress_file (srcf, dstf, 1); + free (dstf); + } + + grub_util_free_path_list (path_list); + } + + const char *pkglib_DATA[] = {"efiemu32.o", "efiemu64.o", + "moddep.lst", "command.lst", + "fs.lst", "partmap.lst", + "parttool.lst", + "video.lst", "crypto.lst", + "terminal.lst", "modinfo.sh" }; + size_t i; + + for (i = 0; i < ARRAY_SIZE (pkglib_DATA); i++) + { + char *srcf = grub_util_path_concat (2, src, pkglib_DATA[i]); + char *dstf = grub_util_path_concat (2, dst_platform, pkglib_DATA[i]); + if (i == 0 || i == 1) + grub_install_compress_file (srcf, dstf, 0); + else + grub_install_compress_file (srcf, dstf, 1); + free (srcf); + free (dstf); + } + + if (install_themes.is_default) + { + install_themes.is_default = 0; + install_themes.n_entries = 1; + install_themes.entries = xmalloc (2 * sizeof (install_themes.entries[0])); + install_themes.entries[0] = xstrdup ("starfield"); + install_themes.entries[1] = NULL; + } + + if (grub_install_themes_directory) + themes_dir = xstrdup (grub_install_themes_directory); + else + themes_dir = grub_util_path_concat (2, grub_util_get_pkgdatadir (), + "themes"); + + for (i = 0; i < install_themes.n_entries; i++) + { + char *srcf = grub_util_path_concat (3, themes_dir, + install_themes.entries[i], + "theme.txt"); + if (grub_util_is_regular (srcf)) + { + char *srcd = grub_util_path_concat (2, themes_dir, + install_themes.entries[i]); + char *dstd = grub_util_path_concat (3, dst, "themes", + install_themes.entries[i]); + grub_install_mkdir_p (dstd); + copy_all (srcd, dstd); + free (srcd); + free (dstd); + } + free (srcf); + } + + free (themes_dir); + + if (install_fonts.is_default) + { + install_fonts.is_default = 0; + install_fonts.n_entries = 1; + install_fonts.entries = xmalloc (2 * sizeof (install_fonts.entries[0])); + install_fonts.entries[0] = xstrdup ("unicode"); + install_fonts.entries[1] = NULL; + } + + grub_install_mkdir_p (dst_fonts); + + for (i = 0; i < install_fonts.n_entries; i++) + { + char *srcf = grub_util_path_concat_ext (2, pkgdatadir, + install_fonts.entries[i], + ".pf2"); + char *dstf = grub_util_path_concat_ext (2, dst_fonts, + install_fonts.entries[i], + ".pf2"); + + grub_install_compress_file (srcf, dstf, 0); + free (srcf); + free (dstf); + } + + free (dst_platform); + free (dst_fonts); +} + +enum grub_install_plat +grub_install_get_target (const char *src) +{ + char *fn; + grub_util_fd_t f; + char buf[8192]; + ssize_t r; + char *c, *pl, *p; + size_t i; + fn = grub_util_path_concat (2, src, "modinfo.sh"); + f = grub_util_fd_open (fn, GRUB_UTIL_FD_O_RDONLY); + if (!GRUB_UTIL_FD_IS_VALID (f)) + grub_util_error (_("%s doesn't exist. Please specify --target or --directory"), + fn); + r = grub_util_fd_read (f, buf, sizeof (buf) - 1); + if (r < 0) + grub_util_error (_("cannot read `%s': %s"), fn, strerror (errno)); + grub_util_fd_close (f); + buf[r] = '\0'; + c = strstr (buf, "grub_modinfo_target_cpu="); + if (!c || (c != buf && !grub_isspace (*(c-1)))) + grub_util_error (_("invalid modinfo file `%s'"), fn); + pl = strstr (buf, "grub_modinfo_platform="); + if (!pl || (pl != buf && !grub_isspace (*(pl-1)))) + grub_util_error (_("invalid modinfo file `%s'"), fn); + c += sizeof ("grub_modinfo_target_cpu=") - 1; + pl += sizeof ("grub_modinfo_platform=") - 1; + for (p = c; *p && !grub_isspace (*p); p++); + *p = '\0'; + for (p = pl; *p && !grub_isspace (*p); p++); + *p = '\0'; + + for (i = 0; i < ARRAY_SIZE (platforms); i++) + if (strcmp (platforms[i].cpu, c) == 0 + && strcmp (platforms[i].platform, pl) == 0) + { + free (fn); + return i; + } + grub_util_error (_("Unknown platform `%s-%s'"), c, pl); +} + + +void +grub_util_unlink_recursive (const char *name) +{ + grub_util_fd_dir_t d; + grub_util_fd_dirent_t de; + + d = grub_util_fd_opendir (name); + + while ((de = grub_util_fd_readdir (d))) + { + char *fp; + if (strcmp (de->d_name, ".") == 0) + continue; + if (strcmp (de->d_name, "..") == 0) + continue; + fp = grub_util_path_concat (2, name, de->d_name); + if (grub_util_is_special_file (fp)) + { + free (fp); + continue; + } + if (grub_util_is_regular (fp)) + grub_util_unlink (fp); + else if (grub_util_is_directory (fp)) + grub_util_unlink_recursive (fp); + free (fp); + } + grub_util_rmdir (name); + grub_util_fd_closedir (d); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/util/grub-install.c b/GRUB2/MOD_SRC/grub-2.04/util/grub-install.c new file mode 100644 index 0000000..76c7bbe --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/util/grub-install.c @@ -0,0 +1,1982 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#pragma GCC diagnostic ignored "-Wmissing-prototypes" +#pragma GCC diagnostic ignored "-Wmissing-declarations" +#include +#pragma GCC diagnostic error "-Wmissing-prototypes" +#pragma GCC diagnostic error "-Wmissing-declarations" + +#include "progname.h" + +static char *target; +static int removable = 0; +static int recheck = 0; +static int update_nvram = 1; +static char *install_device = NULL; +static char *debug_image = NULL; +static char *rootdir = NULL; +static char *bootdir = NULL; +static int allow_floppy = 0; +static int force_file_id = 0; +static char *disk_module = NULL; +static char *efidir = NULL; +static char *macppcdir = NULL; +static int force = 0; +static int have_abstractions = 0; +static int have_cryptodisk = 0; +static char * bootloader_id; +static int have_load_cfg = 0; +static FILE * load_cfg_f = NULL; +static char *load_cfg; +static int install_bootsector = 1; +static char *label_font; +static char *label_color; +static char *label_bgcolor; +static char *product_version; +static int add_rs_codes = 1; + +enum + { + OPTION_BOOT_DIRECTORY = 0x301, + OPTION_ROOT_DIRECTORY, + OPTION_TARGET, + OPTION_SETUP, + OPTION_MKRELPATH, + OPTION_MKDEVICEMAP, + OPTION_PROBE, + OPTION_EDITENV, + OPTION_ALLOW_FLOPPY, + OPTION_RECHECK, + OPTION_FORCE, + OPTION_FORCE_FILE_ID, + OPTION_NO_NVRAM, + OPTION_REMOVABLE, + OPTION_BOOTLOADER_ID, + OPTION_EFI_DIRECTORY, + OPTION_FONT, + OPTION_DEBUG, + OPTION_DEBUG_IMAGE, + OPTION_NO_FLOPPY, + OPTION_DISK_MODULE, + OPTION_NO_BOOTSECTOR, + OPTION_NO_RS_CODES, + OPTION_MACPPC_DIRECTORY, + OPTION_LABEL_FONT, + OPTION_LABEL_COLOR, + OPTION_LABEL_BGCOLOR, + OPTION_PRODUCT_VERSION + }; + +static int fs_probe = 1; + +static error_t +argp_parser (int key, char *arg, struct argp_state *state) +{ + if (grub_install_parse (key, arg)) + return 0; + switch (key) + { + case OPTION_FORCE_FILE_ID: + force_file_id = 1; + return 0; + case 's': + fs_probe = 0; + return 0; + + case OPTION_SETUP: + if (!grub_strstr (arg, "setup")) + install_bootsector = 0; + return 0; + + case OPTION_PRODUCT_VERSION: + free (product_version); + product_version = xstrdup (arg); + return 0; + case OPTION_LABEL_FONT: + free (label_font); + label_font = xstrdup (arg); + return 0; + + case OPTION_LABEL_COLOR: + free (label_color); + label_color = xstrdup (arg); + return 0; + + case OPTION_LABEL_BGCOLOR: + free (label_bgcolor); + label_bgcolor = xstrdup (arg); + return 0; + + /* Accept and ignore for compatibility. */ + case OPTION_FONT: + case OPTION_MKRELPATH: + case OPTION_PROBE: + case OPTION_EDITENV: + case OPTION_MKDEVICEMAP: + case OPTION_NO_FLOPPY: + return 0; + case OPTION_ROOT_DIRECTORY: + /* Accept for compatibility. */ + free (rootdir); + rootdir = xstrdup (arg); + return 0; + + case OPTION_BOOT_DIRECTORY: + free (bootdir); + bootdir = xstrdup (arg); + return 0; + + case OPTION_MACPPC_DIRECTORY: + free (macppcdir); + macppcdir = xstrdup (arg); + return 0; + + case OPTION_EFI_DIRECTORY: + free (efidir); + efidir = xstrdup (arg); + return 0; + + case OPTION_DISK_MODULE: + free (disk_module); + disk_module = xstrdup (arg); + return 0; + + case OPTION_TARGET: + free (target); + target = xstrdup (arg); + return 0; + + case OPTION_DEBUG_IMAGE: + free (debug_image); + debug_image = xstrdup (arg); + return 0; + + case OPTION_NO_NVRAM: + update_nvram = 0; + return 0; + + case OPTION_FORCE: + force = 1; + return 0; + + case OPTION_RECHECK: + recheck = 1; + return 0; + + case OPTION_REMOVABLE: + removable = 1; + return 0; + + case OPTION_ALLOW_FLOPPY: + allow_floppy = 1; + return 0; + + case OPTION_NO_BOOTSECTOR: + install_bootsector = 0; + return 0; + + case OPTION_NO_RS_CODES: + add_rs_codes = 0; + return 0; + + case OPTION_DEBUG: + verbosity++; + return 0; + + case OPTION_BOOTLOADER_ID: + free (bootloader_id); + bootloader_id = xstrdup (arg); + return 0; + + case ARGP_KEY_ARG: + if (install_device) + grub_util_error ("%s", _("More than one install device?")); + install_device = xstrdup (arg); + return 0; + + default: + return ARGP_ERR_UNKNOWN; + } +} + + +static struct argp_option options[] = { + GRUB_INSTALL_OPTIONS, + {"boot-directory", OPTION_BOOT_DIRECTORY, N_("DIR"), + 0, N_("install GRUB images under the directory DIR/%s instead of the %s directory"), 2}, + {"root-directory", OPTION_ROOT_DIRECTORY, N_("DIR"), + OPTION_HIDDEN, 0, 2}, + {"font", OPTION_FONT, N_("FILE"), + OPTION_HIDDEN, 0, 2}, + {"target", OPTION_TARGET, N_("TARGET"), + /* TRANSLATORS: "TARGET" as in "target platform". */ + 0, N_("install GRUB for TARGET platform [default=%s]; available targets: %s"), 2}, + {"grub-setup", OPTION_SETUP, "FILE", OPTION_HIDDEN, 0, 2}, + {"grub-mkrelpath", OPTION_MKRELPATH, "FILE", OPTION_HIDDEN, 0, 2}, + {"grub-mkdevicemap", OPTION_MKDEVICEMAP, "FILE", OPTION_HIDDEN, 0, 2}, + {"grub-probe", OPTION_PROBE, "FILE", OPTION_HIDDEN, 0, 2}, + {"grub-editenv", OPTION_EDITENV, "FILE", OPTION_HIDDEN, 0, 2}, + {"allow-floppy", OPTION_ALLOW_FLOPPY, 0, 0, + /* TRANSLATORS: "may break" doesn't just mean that option wouldn't have any + effect but that it will make the resulting install unbootable from HDD. */ + N_("make the drive also bootable as floppy (default for fdX devices)." + " May break on some BIOSes."), 2}, + {"recheck", OPTION_RECHECK, 0, 0, + N_("delete device map if it already exists"), 2}, + {"force", OPTION_FORCE, 0, 0, + N_("install even if problems are detected"), 2}, + {"force-file-id", OPTION_FORCE_FILE_ID, 0, 0, + N_("use identifier file even if UUID is available"), 2}, + {"disk-module", OPTION_DISK_MODULE, N_("MODULE"), 0, + N_("disk module to use (biosdisk or native). " + "This option is only available on BIOS target."), 2}, + {"no-nvram", OPTION_NO_NVRAM, 0, 0, + N_("don't update the `boot-device'/`Boot*' NVRAM variables. " + "This option is only available on EFI and IEEE1275 targets."), 2}, + {"skip-fs-probe",'s',0, 0, + N_("do not probe for filesystems in DEVICE"), 0}, + {"no-bootsector", OPTION_NO_BOOTSECTOR, 0, 0, + N_("do not install bootsector"), 0}, + {"no-rs-codes", OPTION_NO_RS_CODES, 0, 0, + N_("Do not apply any reed-solomon codes when embedding core.img. " + "This option is only available on x86 BIOS targets."), 0}, + + {"debug", OPTION_DEBUG, 0, OPTION_HIDDEN, 0, 2}, + {"no-floppy", OPTION_NO_FLOPPY, 0, OPTION_HIDDEN, 0, 2}, + {"debug-image", OPTION_DEBUG_IMAGE, N_("STRING"), OPTION_HIDDEN, 0, 2}, + {"removable", OPTION_REMOVABLE, 0, 0, + N_("the installation device is removable. " + "This option is only available on EFI."), 2}, + {"bootloader-id", OPTION_BOOTLOADER_ID, N_("ID"), 0, + N_("the ID of bootloader. This option is only available on EFI and Macs."), 2}, + {"efi-directory", OPTION_EFI_DIRECTORY, N_("DIR"), 0, + N_("use DIR as the EFI System Partition root."), 2}, + {"macppc-directory", OPTION_MACPPC_DIRECTORY, N_("DIR"), 0, + N_("use DIR for PPC MAC install."), 2}, + {"label-font", OPTION_LABEL_FONT, N_("FILE"), 0, N_("use FILE as font for label"), 2}, + {"label-color", OPTION_LABEL_COLOR, N_("COLOR"), 0, N_("use COLOR for label"), 2}, + {"label-bgcolor", OPTION_LABEL_BGCOLOR, N_("COLOR"), 0, N_("use COLOR for label background"), 2}, + {"product-version", OPTION_PRODUCT_VERSION, N_("STRING"), 0, N_("use STRING as product version"), 2}, + {0, 0, 0, 0, 0, 0} +}; + +static const char * +get_default_platform (void) +{ +#ifdef __powerpc__ + return "powerpc-ieee1275"; +#elif defined (__sparc__) || defined (__sparc64__) + return "sparc64-ieee1275"; +#elif defined (__MIPSEL__) +#if _MIPS_SIM == _ABI64 + return "mips64el-efi"; +#else + return "mipsel-loongson"; +#endif +#elif defined (__MIPSEB__) + return "mips-arc"; +#elif defined (__ia64__) + return "ia64-efi"; +#elif defined (__arm__) + return grub_install_get_default_arm_platform (); +#elif defined (__aarch64__) + return "arm64-efi"; +#elif defined (__amd64__) || defined (__x86_64__) || defined (__i386__) + return grub_install_get_default_x86_platform (); +#else + return NULL; +#endif +} + +#pragma GCC diagnostic ignored "-Wformat-nonliteral" + +static char * +help_filter (int key, const char *text, void *input __attribute__ ((unused))) +{ + switch (key) + { + case OPTION_BOOT_DIRECTORY: + return xasprintf (text, GRUB_DIR_NAME, GRUB_BOOT_DIR_NAME "/" GRUB_DIR_NAME); + case OPTION_TARGET: + { + char *plats = grub_install_get_platforms_string (); + char *ret; + ret = xasprintf (text, get_default_platform (), plats); + free (plats); + return ret; + } + case ARGP_KEY_HELP_POST_DOC: + return xasprintf (text, program_name, GRUB_BOOT_DIR_NAME "/" GRUB_DIR_NAME); + default: + return grub_install_help_filter (key, text, input); + } +} + +#pragma GCC diagnostic error "-Wformat-nonliteral" + +/* TRANSLATORS: INSTALL_DEVICE isn't an identifier and is the DEVICE you + install to. */ +struct argp argp = { + options, argp_parser, N_("[OPTION] [INSTALL_DEVICE]"), + N_("Install GRUB on your drive.")"\v" + N_("INSTALL_DEVICE must be system device filename.\n" + "%s copies GRUB images into %s. On some platforms, it" + " may also install GRUB into the boot sector."), + NULL, help_filter, NULL +}; + +static int +probe_raid_level (grub_disk_t disk) +{ + /* disk might be NULL in the case of a LVM physical volume with no LVM + signature. Ignore such cases here. */ + if (!disk) + return -1; + + if (disk->dev->id != GRUB_DISK_DEVICE_DISKFILTER_ID) + return -1; + + if (disk->name[0] != 'm' || disk->name[1] != 'd') + return -1; + + if (!((struct grub_diskfilter_lv *) disk->data)->segments) + return -1; + return ((struct grub_diskfilter_lv *) disk->data)->segments->type; +} + +static void +push_partmap_module (const char *map, void *data __attribute__ ((unused))) +{ + char buf[50]; + + if (strcmp (map, "openbsd") == 0 || strcmp (map, "netbsd") == 0) + { + grub_install_push_module ("part_bsd"); + return; + } + + snprintf (buf, sizeof (buf), "part_%s", map); + grub_install_push_module (buf); +} + +static void +push_cryptodisk_module (const char *mod, void *data __attribute__ ((unused))) +{ + grub_install_push_module (mod); +} + +static void +probe_mods (grub_disk_t disk) +{ + grub_partition_t part; + grub_disk_memberlist_t list = NULL, tmp; + int raid_level; + + if (disk->partition == NULL) + grub_util_info ("no partition map found for %s", disk->name); + + for (part = disk->partition; part; part = part->parent) + push_partmap_module (part->partmap->name, NULL); + + if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID) + { + grub_diskfilter_get_partmap (disk, push_partmap_module, NULL); + have_abstractions = 1; + } + + if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID + && (grub_memcmp (disk->name, "lvm/", sizeof ("lvm/") - 1) == 0 || + grub_memcmp (disk->name, "lvmid/", sizeof ("lvmid/") - 1) == 0)) + grub_install_push_module ("lvm"); + + if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID + && grub_memcmp (disk->name, "ldm/", sizeof ("ldm/") - 1) == 0) + grub_install_push_module ("ldm"); + + if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID) + { + grub_util_cryptodisk_get_abstraction (disk, + push_cryptodisk_module, NULL); + have_abstractions = 1; + have_cryptodisk = 1; + } + + raid_level = probe_raid_level (disk); + if (raid_level >= 0) + { + grub_install_push_module ("diskfilter"); + if (disk->dev->disk_raidname) + grub_install_push_module (disk->dev->disk_raidname (disk)); + } + if (raid_level == 5) + grub_install_push_module ("raid5rec"); + if (raid_level == 6) + grub_install_push_module ("raid6rec"); + + /* In case of LVM/RAID, check the member devices as well. */ + if (disk->dev->disk_memberlist) + list = disk->dev->disk_memberlist (disk); + while (list) + { + probe_mods (list->disk); + tmp = list->next; + free (list); + list = tmp; + } +} + +static int +have_bootdev (enum grub_install_plat pl) +{ + switch (pl) + { + case GRUB_INSTALL_PLATFORM_I386_PC: + case GRUB_INSTALL_PLATFORM_I386_EFI: + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI: + case GRUB_INSTALL_PLATFORM_RISCV32_EFI: + case GRUB_INSTALL_PLATFORM_RISCV64_EFI: + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: + case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: + case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: + case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: + case GRUB_INSTALL_PLATFORM_MIPS_ARC: + return 1; + + case GRUB_INSTALL_PLATFORM_I386_QEMU: + case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_ARM_COREBOOT: + case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: + case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: + + case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: + case GRUB_INSTALL_PLATFORM_ARM_UBOOT: + + case GRUB_INSTALL_PLATFORM_I386_XEN: + case GRUB_INSTALL_PLATFORM_X86_64_XEN: + case GRUB_INSTALL_PLATFORM_I386_XEN_PVH: + return 0; + + /* pacify warning. */ + case GRUB_INSTALL_PLATFORM_MAX: + return 0; + } + return 0; +} + +static void +probe_cryptodisk_uuid (grub_disk_t disk) +{ + grub_disk_memberlist_t list = NULL, tmp; + + /* In case of LVM/RAID, check the member devices as well. */ + if (disk->dev->disk_memberlist) + { + list = disk->dev->disk_memberlist (disk); + } + while (list) + { + probe_cryptodisk_uuid (list->disk); + tmp = list->next; + free (list); + list = tmp; + } + if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID) + { + const char *uuid = grub_util_cryptodisk_get_uuid (disk); + if (!load_cfg_f) + load_cfg_f = grub_util_fopen (load_cfg, "wb"); + have_load_cfg = 1; + + fprintf (load_cfg_f, "cryptomount -u %s\n", + uuid); + } +} + +static int +is_same_disk (const char *a, const char *b) +{ + while (1) + { + if ((*a == ',' || *a == '\0') && (*b == ',' || *b == '\0')) + return 1; + if (*a != *b) + return 0; + if (*a == '\\') + { + if (a[1] != b[1]) + return 0; + a += 2; + b += 2; + continue; + } + a++; + b++; + } +} + +static char * +get_rndstr (void) +{ + grub_uint8_t rnd[15]; + const size_t sz = sizeof (rnd) * GRUB_CHAR_BIT / 5; + char * ret = xmalloc (sz + 1); + size_t i; + if (grub_get_random (rnd, sizeof (rnd))) + grub_util_error ("%s", _("couldn't retrieve random data")); + for (i = 0; i < sz; i++) + { + grub_size_t b = i * 5; + grub_uint8_t r; + grub_size_t f1 = GRUB_CHAR_BIT - b % GRUB_CHAR_BIT; + grub_size_t f2; + if (f1 > 5) + f1 = 5; + f2 = 5 - f1; + r = (rnd[b / GRUB_CHAR_BIT] >> (b % GRUB_CHAR_BIT)) & ((1 << f1) - 1); + if (f2) + r |= (rnd[b / GRUB_CHAR_BIT + 1] & ((1 << f2) - 1)) << f1; + if (r < 10) + ret[i] = '0' + r; + else + ret[i] = 'a' + (r - 10); + } + ret[sz] = '\0'; + return ret; +} + +static char * +escape (const char *in) +{ + char *ptr; + char *ret; + int overhead = 0; + + for (ptr = (char*)in; *ptr; ptr++) + if (*ptr == '\'') + overhead += 3; + ret = grub_malloc (ptr - in + overhead + 1); + if (!ret) + return NULL; + + grub_strchrsub (ret, in, '\'', "'\\''"); + return ret; +} + +static struct grub_util_config config; + +static void +device_map_check_duplicates (const char *dev_map) +{ + FILE *fp; + char buf[1024]; /* XXX */ + size_t alloced = 8; + size_t filled = 0; + char **d; + size_t i; + + if (dev_map[0] == '\0') + return; + + fp = grub_util_fopen (dev_map, "r"); + if (! fp) + return; + + d = xmalloc (alloced * sizeof (d[0])); + + while (fgets (buf, sizeof (buf), fp)) + { + char *p = buf; + char *e; + + /* Skip leading spaces. */ + while (*p && grub_isspace (*p)) + p++; + + /* If the first character is `#' or NUL, skip this line. */ + if (*p == '\0' || *p == '#') + continue; + + if (*p != '(') + continue; + + p++; + + e = p; + p = strchr (p, ')'); + if (! p) + continue; + + if (filled >= alloced) + { + alloced *= 2; + d = xrealloc (d, alloced * sizeof (d[0])); + } + + *p = '\0'; + + d[filled++] = xstrdup (e); + } + + fclose (fp); + + qsort (d, filled, sizeof (d[0]), grub_qsort_strcmp); + + for (i = 0; i + 1 < filled; i++) + if (strcmp (d[i], d[i+1]) == 0) + { + grub_util_error (_("the drive %s is defined multiple times in the device map %s"), + d[i], dev_map); + } + + for (i = 0; i < filled; i++) + free (d[i]); + + free (d); +} + +static grub_err_t +write_to_disk (grub_device_t dev, const char *fn) +{ + char *core_img; + size_t core_size; + grub_err_t err; + + core_size = grub_util_get_image_size (fn); + + core_img = grub_util_read_image (fn); + + grub_util_info ("writing `%s' to `%s'", fn, dev->disk->name); + err = grub_disk_write (dev->disk, 0, 0, + core_size, core_img); + free (core_img); + return err; +} + +static int +is_prep_partition (grub_device_t dev) +{ + if (!dev->disk) + return 0; + if (!dev->disk->partition) + return 0; + if (strcmp(dev->disk->partition->partmap->name, "msdos") == 0) + return (dev->disk->partition->msdostype == 0x41); + + if (strcmp (dev->disk->partition->partmap->name, "gpt") == 0) + { + struct grub_gpt_partentry gptdata; + grub_partition_t p = dev->disk->partition; + int ret = 0; + dev->disk->partition = dev->disk->partition->parent; + + if (grub_disk_read (dev->disk, p->offset, p->index, + sizeof (gptdata), &gptdata) == 0) + { + const grub_gpt_part_guid_t template = { + grub_cpu_to_le32_compile_time (0x9e1a2d38), + grub_cpu_to_le16_compile_time (0xc612), + grub_cpu_to_le16_compile_time (0x4316), + { 0xaa, 0x26, 0x8b, 0x49, 0x52, 0x1e, 0x5a, 0x8b } + }; + + ret = grub_memcmp (&template, &gptdata.type, + sizeof (template)) == 0; + } + dev->disk->partition = p; + return ret; + } + + return 0; +} + +static int +is_prep_empty (grub_device_t dev) +{ + grub_disk_addr_t dsize, addr; + grub_uint32_t buffer[32768]; + + dsize = grub_disk_get_size (dev->disk); + for (addr = 0; addr < dsize; + addr += sizeof (buffer) / GRUB_DISK_SECTOR_SIZE) + { + grub_size_t sz = sizeof (buffer); + grub_uint32_t *ptr; + + if (sizeof (buffer) / GRUB_DISK_SECTOR_SIZE > dsize - addr) + sz = (dsize - addr) * GRUB_DISK_SECTOR_SIZE; + grub_disk_read (dev->disk, addr, 0, sz, buffer); + + if (addr == 0 && grub_memcmp (buffer, ELFMAG, SELFMAG) == 0) + return 1; + + for (ptr = buffer; ptr < buffer + sz / sizeof (*buffer); ptr++) + if (*ptr) + return 0; + } + + return 1; +} + +static void +bless (grub_device_t dev, const char *path, int x86) +{ + struct stat st; + grub_err_t err; + + grub_util_info ("blessing %s", path); + + if (stat (path, &st) < 0) + grub_util_error (N_("cannot stat `%s': %s"), + path, strerror (errno)); + + err = grub_mac_bless_inode (dev, st.st_ino, S_ISDIR (st.st_mode), x86); + if (err) + grub_util_error ("%s", grub_errmsg); + grub_util_info ("blessed"); +} + +static void +fill_core_services (const char *core_services) +{ + char *label; + FILE *f; + char *label_text; + char *label_string = xasprintf ("%s %s", bootloader_id, product_version); + char *sysv_plist; + + label = grub_util_path_concat (2, core_services, ".disk_label"); + grub_util_info ("rendering label %s", label_string); + grub_util_render_label (label_font, label_bgcolor ? : "white", + label_color ? : "black", label_string, label); + grub_util_info ("label rendered"); + free (label); + label_text = grub_util_path_concat (2, core_services, ".disk_label.contentDetails"); + f = grub_util_fopen (label_text, "wb"); + fprintf (f, "%s\n", label_string); + fclose (f); + free (label_string); + free (label_text); + + sysv_plist = grub_util_path_concat (2, core_services, "SystemVersion.plist"); + f = grub_util_fopen (sysv_plist, "wb"); + fprintf (f, + "\n" + "\n" + " ProductBuildVersion\n" + " \n" + " ProductName\n" + " %s\n" + " ProductVersion\n" + " %s\n" + "\n" + "\n", bootloader_id, product_version); + fclose (f); + free (sysv_plist); +} + +int +main (int argc, char *argv[]) +{ + int is_efi = 0; + const char *efi_distributor = NULL; + const char *efi_file = NULL; + char **grub_devices; + grub_fs_t grub_fs; + grub_device_t grub_dev = NULL; + enum grub_install_plat platform; + char *grubdir, *device_map; + char **curdev, **curdrive; + char **grub_drives; + char *relative_grubdir; + char **efidir_device_names = NULL; + grub_device_t efidir_grub_dev = NULL; + char *efidir_grub_devname; + int efidir_is_mac = 0; + int is_prep = 0; + const char *pkgdatadir; + + grub_util_host_init (&argc, &argv); + product_version = xstrdup (PACKAGE_VERSION); + pkgdatadir = grub_util_get_pkgdatadir (); + label_font = grub_util_path_concat (2, pkgdatadir, "unicode.pf2"); + + argp_parse (&argp, argc, argv, 0, 0, 0); + + if (verbosity > 1) + grub_env_set ("debug", "all"); + + grub_util_load_config (&config); + + if (!bootloader_id && config.grub_distributor) + { + char *ptr; + bootloader_id = xstrdup (config.grub_distributor); + for (ptr = bootloader_id; *ptr && *ptr != ' '; ptr++) + if (*ptr >= 'A' && *ptr <= 'Z') + *ptr = *ptr - 'A' + 'a'; + *ptr = '\0'; + } + if (!bootloader_id || bootloader_id[0] == '\0') + { + free (bootloader_id); + bootloader_id = xstrdup ("grub"); + } + + if (!grub_install_source_directory) + { + if (!target) + { + const char * t; + t = get_default_platform (); + if (!t) + grub_util_error ("%s", + _("Unable to determine your platform." + " Use --target.") + ); + target = xstrdup (t); + } + grub_install_source_directory + = grub_util_path_concat (2, grub_util_get_pkglibdir (), target); + } + + platform = grub_install_get_target (grub_install_source_directory); + + { + char *platname = grub_install_get_platform_name (platform); + fprintf (stderr, _("Installing for %s platform.\n"), platname); + free (platname); + } + + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_PC: + if (!disk_module) + disk_module = xstrdup ("biosdisk"); + break; + case GRUB_INSTALL_PLATFORM_I386_EFI: + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI: + case GRUB_INSTALL_PLATFORM_RISCV32_EFI: + case GRUB_INSTALL_PLATFORM_RISCV64_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: + case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: + case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: + case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: + case GRUB_INSTALL_PLATFORM_MIPS_ARC: + case GRUB_INSTALL_PLATFORM_ARM_UBOOT: + case GRUB_INSTALL_PLATFORM_I386_XEN: + case GRUB_INSTALL_PLATFORM_X86_64_XEN: + case GRUB_INSTALL_PLATFORM_I386_XEN_PVH: + break; + + case GRUB_INSTALL_PLATFORM_I386_QEMU: + case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_ARM_COREBOOT: + case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: + case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: + case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: + disk_module = xstrdup ("native"); + break; + + /* pacify warning. */ + case GRUB_INSTALL_PLATFORM_MAX: + break; + } + + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_PC: + case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: + if (!install_device) + grub_util_error ("%s", _("install device isn't specified")); + break; + case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: + if (install_device) + is_prep = 1; + break; + case GRUB_INSTALL_PLATFORM_MIPS_ARC: + case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: + break; + case GRUB_INSTALL_PLATFORM_I386_EFI: + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI: + case GRUB_INSTALL_PLATFORM_RISCV32_EFI: + case GRUB_INSTALL_PLATFORM_RISCV64_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: + case GRUB_INSTALL_PLATFORM_ARM_UBOOT: + case GRUB_INSTALL_PLATFORM_I386_QEMU: + case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_ARM_COREBOOT: + case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: + case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: + case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_I386_XEN: + case GRUB_INSTALL_PLATFORM_X86_64_XEN: + case GRUB_INSTALL_PLATFORM_I386_XEN_PVH: + free (install_device); + install_device = NULL; + break; + + /* pacify warning. */ + case GRUB_INSTALL_PLATFORM_MAX: + break; + } + + if (!bootdir) + bootdir = grub_util_path_concat (3, "/", rootdir, GRUB_BOOT_DIR_NAME); + + { + char * t = grub_util_path_concat (2, bootdir, GRUB_DIR_NAME); + grub_install_mkdir_p (t); + grubdir = grub_canonicalize_file_name (t); + if (!grubdir) + grub_util_error (_("failed to get canonical path of `%s'"), t); + free (t); + } + device_map = grub_util_path_concat (2, grubdir, "device.map"); + + if (recheck) + grub_util_unlink (device_map); + + device_map_check_duplicates (device_map); + grub_util_biosdisk_init (device_map); + + /* Initialize all modules. */ + grub_init_all (); + grub_gcry_init_all (); + grub_hostfs_init (); + grub_host_init (); + + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_EFI: + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI: + case GRUB_INSTALL_PLATFORM_RISCV32_EFI: + case GRUB_INSTALL_PLATFORM_RISCV64_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + is_efi = 1; + break; + default: + is_efi = 0; + break; + + /* pacify warning. */ + case GRUB_INSTALL_PLATFORM_MAX: + break; + } + + /* Find the EFI System Partition. */ + + if (is_efi) + { + grub_fs_t fs; + free (install_device); + install_device = NULL; + if (!efidir) + { + char *d = grub_util_path_concat (2, bootdir, "efi"); + char *dr = NULL; + if (!grub_util_is_directory (d)) + { + free (d); + d = grub_util_path_concat (2, bootdir, "EFI"); + } + /* + The EFI System Partition may have been given directly using + --root-directory. + */ + if (!grub_util_is_directory (d) + && rootdir && grub_strcmp (rootdir, "/") != 0) + { + free (d); + d = xstrdup (rootdir); + } + if (grub_util_is_directory (d)) + dr = grub_make_system_path_relative_to_its_root (d); + /* Is it a mount point? */ + if (dr && dr[0] == '\0') + efidir = d; + else + free (d); + free (dr); + } + if (!efidir) + grub_util_error ("%s", _("cannot find EFI directory")); + efidir_device_names = grub_guess_root_devices (efidir); + if (!efidir_device_names || !efidir_device_names[0]) + grub_util_error (_("cannot find a device for %s (is /dev mounted?)"), + efidir); + install_device = efidir_device_names[0]; + + for (curdev = efidir_device_names; *curdev; curdev++) + grub_util_pull_device (*curdev); + + efidir_grub_devname = grub_util_get_grub_dev (efidir_device_names[0]); + if (!efidir_grub_devname) + grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"), + efidir_device_names[0]); + + efidir_grub_dev = grub_device_open (efidir_grub_devname); + if (! efidir_grub_dev) + grub_util_error ("%s", grub_errmsg); + + fs = grub_fs_probe (efidir_grub_dev); + if (! fs) + grub_util_error ("%s", grub_errmsg); + + efidir_is_mac = 0; + + if (grub_strcmp (fs->name, "hfs") == 0 + || grub_strcmp (fs->name, "hfsplus") == 0) + efidir_is_mac = 1; + + if (!efidir_is_mac && grub_strcmp (fs->name, "fat") != 0) + grub_util_error (_("%s doesn't look like an EFI partition"), efidir); + + /* The EFI specification requires that an EFI System Partition must + contain an "EFI" subdirectory, and that OS loaders are stored in + subdirectories below EFI. Vendors are expected to pick names that do + not collide with other vendors. To minimise collisions, we use the + name of our distributor if possible. + */ + char *t; + efi_distributor = bootloader_id; + if (removable) + { + /* The specification makes stricter requirements of removable + devices, in order that only one image can be automatically loaded + from them. The image must always reside under /EFI/BOOT, and it + must have a specific file name depending on the architecture. + */ + efi_distributor = "BOOT"; + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_EFI: + efi_file = "BOOTIA32.EFI"; + break; + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + efi_file = "BOOTX64.EFI"; + break; + case GRUB_INSTALL_PLATFORM_IA64_EFI: + efi_file = "BOOTIA64.EFI"; + break; + case GRUB_INSTALL_PLATFORM_ARM_EFI: + efi_file = "BOOTARM.EFI"; + break; + case GRUB_INSTALL_PLATFORM_ARM64_EFI: + efi_file = "BOOTAA64.EFI"; + break; + case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI: + efi_file = "BOOTMIPS64EL.EFI"; + break; + case GRUB_INSTALL_PLATFORM_RISCV32_EFI: + efi_file = "BOOTRISCV32.EFI"; + break; + case GRUB_INSTALL_PLATFORM_RISCV64_EFI: + efi_file = "BOOTRISCV64.EFI"; + break; + default: + grub_util_error ("%s", _("You've found a bug")); + break; + } + } + else + { + /* It is convenient for each architecture to have a different + efi_file, so that different versions can be installed in parallel. + */ + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_EFI: + efi_file = "grubia32.efi"; + break; + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + efi_file = "grubx64.efi"; + break; + case GRUB_INSTALL_PLATFORM_IA64_EFI: + efi_file = "grubia64.efi"; + break; + case GRUB_INSTALL_PLATFORM_ARM_EFI: + efi_file = "grubarm.efi"; + break; + case GRUB_INSTALL_PLATFORM_ARM64_EFI: + efi_file = "grubaa64.efi"; + break; + case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI: + efi_file = "grubmips64el.efi"; + break; + case GRUB_INSTALL_PLATFORM_RISCV32_EFI: + efi_file = "grubriscv32.efi"; + break; + case GRUB_INSTALL_PLATFORM_RISCV64_EFI: + efi_file = "grubriscv64.efi"; + break; + default: + efi_file = "grub.efi"; + break; + } + } + t = grub_util_path_concat (3, efidir, "EFI", efi_distributor); + free (efidir); + efidir = t; + grub_install_mkdir_p (efidir); + } + + if (platform == GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275) + { + int is_guess = 0; + if (!macppcdir) + { + char *d; + + is_guess = 1; + d = grub_util_path_concat (2, bootdir, "macppc"); + if (!grub_util_is_directory (d)) + { + free (d); + d = grub_util_path_concat (2, bootdir, "efi"); + } + /* Find the Mac HFS(+) System Partition. */ + if (!grub_util_is_directory (d)) + { + free (d); + d = grub_util_path_concat (2, bootdir, "EFI"); + } + if (!grub_util_is_directory (d)) + { + free (d); + d = 0; + } + if (d) + macppcdir = d; + } + if (macppcdir) + { + char **macppcdir_device_names = NULL; + grub_device_t macppcdir_grub_dev = NULL; + char *macppcdir_grub_devname; + grub_fs_t fs; + + macppcdir_device_names = grub_guess_root_devices (macppcdir); + if (!macppcdir_device_names || !macppcdir_device_names[0]) + grub_util_error (_("cannot find a device for %s (is /dev mounted?)"), + macppcdir); + + for (curdev = macppcdir_device_names; *curdev; curdev++) + grub_util_pull_device (*curdev); + + macppcdir_grub_devname = grub_util_get_grub_dev (macppcdir_device_names[0]); + if (!macppcdir_grub_devname) + grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"), + macppcdir_device_names[0]); + + macppcdir_grub_dev = grub_device_open (macppcdir_grub_devname); + if (! macppcdir_grub_dev) + grub_util_error ("%s", grub_errmsg); + + fs = grub_fs_probe (macppcdir_grub_dev); + if (! fs) + grub_util_error ("%s", grub_errmsg); + + if (grub_strcmp (fs->name, "hfs") != 0 + && grub_strcmp (fs->name, "hfsplus") != 0 + && !is_guess) + grub_util_error (_("filesystem on %s is neither HFS nor HFS+"), + macppcdir); + if (grub_strcmp (fs->name, "hfs") == 0 + || grub_strcmp (fs->name, "hfsplus") == 0) + { + install_device = macppcdir_device_names[0]; + is_prep = 0; + } + } + } + + grub_install_copy_files (grub_install_source_directory, + grubdir, platform); + + char *envfile = grub_util_path_concat (2, grubdir, "grubenv"); + if (!grub_util_is_regular (envfile)) + grub_util_create_envblk_file (envfile); + + size_t ndev = 0; + + /* Write device to a variable so we don't have to traverse /dev every time. */ + grub_devices = grub_guess_root_devices (grubdir); + if (!grub_devices || !grub_devices[0]) + grub_util_error (_("cannot find a device for %s (is /dev mounted?)"), + grubdir); + + for (curdev = grub_devices; *curdev; curdev++) + { + grub_util_pull_device (*curdev); + ndev++; + } + + grub_drives = xmalloc (sizeof (grub_drives[0]) * (ndev + 1)); + + for (curdev = grub_devices, curdrive = grub_drives; *curdev; curdev++, + curdrive++) + { + *curdrive = grub_util_get_grub_dev (*curdev); + if (! *curdrive) + grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"), + *curdev); + } + *curdrive = 0; + + grub_dev = grub_device_open (grub_drives[0]); + if (! grub_dev) + grub_util_error ("%s", grub_errmsg); + + grub_fs = grub_fs_probe (grub_dev); + if (! grub_fs) + grub_util_error ("%s", grub_errmsg); + + grub_install_push_module (grub_fs->name); + + if (grub_dev->disk) + probe_mods (grub_dev->disk); + + for (curdrive = grub_drives + 1; *curdrive; curdrive++) + { + grub_device_t dev = grub_device_open (*curdrive); + if (!dev) + continue; + if (dev->disk) + probe_mods (dev->disk); + grub_device_close (dev); + } + + if (!config.is_cryptodisk_enabled && have_cryptodisk) + grub_util_error (_("attempt to install to encrypted disk without cryptodisk enabled. " + "Set `%s' in file `%s'"), "GRUB_ENABLE_CRYPTODISK=y", + grub_util_get_config_filename ()); + + if (disk_module && grub_strcmp (disk_module, "ata") == 0) + grub_install_push_module ("pata"); + else if (disk_module && grub_strcmp (disk_module, "native") == 0) + { + grub_install_push_module ("pata"); + grub_install_push_module ("ahci"); + grub_install_push_module ("ohci"); + grub_install_push_module ("uhci"); + grub_install_push_module ("ehci"); + grub_install_push_module ("usbms"); + } + else if (disk_module && disk_module[0]) + grub_install_push_module (disk_module); + + relative_grubdir = grub_make_system_path_relative_to_its_root (grubdir); + if (relative_grubdir[0] == '\0') + { + free (relative_grubdir); + relative_grubdir = xstrdup ("/"); + } + + char *platname = grub_install_get_platform_name (platform); + char *platdir; + { + char *t = grub_util_path_concat (2, grubdir, + platname); + platdir = grub_canonicalize_file_name (t); + if (!platdir) + grub_util_error (_("failed to get canonical path of `%s'"), + t); + free (t); + } + load_cfg = grub_util_path_concat (2, platdir, + "load.cfg"); + + grub_util_unlink (load_cfg); + + if (debug_image && debug_image[0]) + { + load_cfg_f = grub_util_fopen (load_cfg, "wb"); + have_load_cfg = 1; + fprintf (load_cfg_f, "set debug='%s'\n", + debug_image); + } + char *prefix_drive = NULL; + char *install_drive = NULL; + + if (install_device) + { + if (install_device[0] == '(' + && install_device[grub_strlen (install_device) - 1] == ')') + { + size_t len = grub_strlen (install_device) - 2; + install_drive = xmalloc (len + 1); + memcpy (install_drive, install_device + 1, len); + install_drive[len] = '\0'; + } + else + { + grub_util_pull_device (install_device); + install_drive = grub_util_get_grub_dev (install_device); + if (!install_drive) + grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"), + install_device); + } + } + + if (!have_abstractions) + { + if ((disk_module && grub_strcmp (disk_module, "biosdisk") != 0) + || grub_drives[1] + || (!install_drive + && platform != GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275) + || (install_drive && !is_same_disk (grub_drives[0], install_drive)) + || !have_bootdev (platform)) + { + char *uuid = NULL; + /* generic method (used on coreboot and ata mod). */ + if (!force_file_id + && grub_fs->fs_uuid && grub_fs->fs_uuid (grub_dev, &uuid)) + { + grub_print_error (); + grub_errno = 0; + uuid = NULL; + } + + if (!load_cfg_f) + load_cfg_f = grub_util_fopen (load_cfg, "wb"); + have_load_cfg = 1; + if (uuid) + { + fprintf (load_cfg_f, "search.fs_uuid %s root ", + uuid); + grub_install_push_module ("search_fs_uuid"); + } + else + { + char *rndstr = get_rndstr (); + char *fl = grub_util_path_concat (3, grubdir, + "uuid", rndstr); + char *fldir = grub_util_path_concat (2, grubdir, + "uuid"); + char *relfl; + FILE *flf; + grub_install_mkdir_p (fldir); + flf = grub_util_fopen (fl, "w"); + if (!flf) + grub_util_error (_("Can't create file: %s"), strerror (errno)); + fclose (flf); + relfl = grub_make_system_path_relative_to_its_root (fl); + fprintf (load_cfg_f, "search.file %s root ", + relfl); + grub_install_push_module ("search_fs_file"); + } + for (curdev = grub_devices, curdrive = grub_drives; *curdev; curdev++, + curdrive++) + { + const char *map; + char *g = NULL; + grub_device_t dev; + if (curdrive == grub_drives) + dev = grub_dev; + else + dev = grub_device_open (*curdrive); + if (!dev) + continue; + + if (dev->disk->dev->id != GRUB_DISK_DEVICE_HOSTDISK_ID) + { + grub_util_fprint_full_disk_name (load_cfg_f, + dev->disk->name, + dev); + fprintf (load_cfg_f, " "); + if (dev != grub_dev) + grub_device_close (dev); + continue; + } + + map = grub_util_biosdisk_get_compatibility_hint (dev->disk); + + if (map) + { + grub_util_fprint_full_disk_name (load_cfg_f, map, dev); + fprintf (load_cfg_f, " "); + } + + + if (disk_module && disk_module[0] + && grub_strcmp (disk_module, "biosdisk") != 0) + g = grub_util_guess_baremetal_drive (*curdev); + else + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_PC: + g = grub_util_guess_bios_drive (*curdev); + break; + case GRUB_INSTALL_PLATFORM_I386_EFI: + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI: + case GRUB_INSTALL_PLATFORM_RISCV32_EFI: + case GRUB_INSTALL_PLATFORM_RISCV64_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + g = grub_util_guess_efi_drive (*curdev); + break; + case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: + case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: + { + const char * ofpath = grub_util_devname_to_ofpath (*curdev); + g = xasprintf ("ieee1275/%s", ofpath); + break; + } + case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: + case GRUB_INSTALL_PLATFORM_I386_QEMU: + case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_ARM_COREBOOT: + case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: + case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: + g = grub_util_guess_baremetal_drive (*curdev); + break; + case GRUB_INSTALL_PLATFORM_MIPS_ARC: + case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: + case GRUB_INSTALL_PLATFORM_ARM_UBOOT: + case GRUB_INSTALL_PLATFORM_I386_XEN: + case GRUB_INSTALL_PLATFORM_X86_64_XEN: + case GRUB_INSTALL_PLATFORM_I386_XEN_PVH: + grub_util_warn ("%s", _("no hints available for your platform. Expect reduced performance")); + break; + /* pacify warning. */ + case GRUB_INSTALL_PLATFORM_MAX: + break; + } + if (g) + { + grub_util_fprint_full_disk_name (load_cfg_f, g, dev); + fprintf (load_cfg_f, " "); + free (g); + } + if (dev != grub_dev) + grub_device_close (dev); + } + fprintf (load_cfg_f, "\n"); + char *escaped_relpath = escape (relative_grubdir); + fprintf (load_cfg_f, "set prefix=($root)'%s'\n", + escaped_relpath); + } + else + { + /* We need to hardcode the partition number in the core image's prefix. */ + char *p; + for (p = grub_drives[0]; *p; ) + { + if (*p == '\\' && p[1]) + { + p += 2; + continue; + } + if (*p == ',' || *p == '\0') + break; + p++; + } + prefix_drive = xasprintf ("(%s)", p); + } + } + else + { + if (config.is_cryptodisk_enabled) + { + if (grub_dev->disk) + probe_cryptodisk_uuid (grub_dev->disk); + + for (curdrive = grub_drives + 1; *curdrive; curdrive++) + { + grub_device_t dev = grub_device_open (*curdrive); + if (!dev) + continue; + if (dev->disk) + probe_cryptodisk_uuid (dev->disk); + grub_device_close (dev); + } + } + prefix_drive = xasprintf ("(%s)", grub_drives[0]); + } + + char mkimage_target[200]; + const char *core_name = NULL; + + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_EFI: + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI: + case GRUB_INSTALL_PLATFORM_RISCV32_EFI: + case GRUB_INSTALL_PLATFORM_RISCV64_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + core_name = "core.efi"; + snprintf (mkimage_target, sizeof (mkimage_target), + "%s-%s", + grub_install_get_platform_cpu (platform), + grub_install_get_platform_platform (platform)); + break; + case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: + case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: + core_name = "core.elf"; + snprintf (mkimage_target, sizeof (mkimage_target), + "%s-%s-elf", + grub_install_get_platform_cpu (platform), + grub_install_get_platform_platform (platform)); + break; + + case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_ARM_COREBOOT: + case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: + case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: + case GRUB_INSTALL_PLATFORM_I386_XEN: + case GRUB_INSTALL_PLATFORM_X86_64_XEN: + case GRUB_INSTALL_PLATFORM_I386_XEN_PVH: + core_name = "core.elf"; + snprintf (mkimage_target, sizeof (mkimage_target), + "%s-%s", + grub_install_get_platform_cpu (platform), + grub_install_get_platform_platform (platform)); + break; + + + case GRUB_INSTALL_PLATFORM_I386_PC: + case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: + case GRUB_INSTALL_PLATFORM_MIPS_ARC: + case GRUB_INSTALL_PLATFORM_ARM_UBOOT: + case GRUB_INSTALL_PLATFORM_I386_QEMU: + snprintf (mkimage_target, sizeof (mkimage_target), + "%s-%s", + grub_install_get_platform_cpu (platform), + grub_install_get_platform_platform (platform)); + core_name = "core.img"; + break; + case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: + strcpy (mkimage_target, "sparc64-ieee1275-raw"); + core_name = "core.img"; + break; + /* pacify warning. */ + case GRUB_INSTALL_PLATFORM_MAX: + break; + } + + if (!core_name) + grub_util_error ("%s", _("You've found a bug")); + + if (load_cfg_f) + fclose (load_cfg_f); + + char *imgfile = grub_util_path_concat (2, platdir, + core_name); + char *prefix = xasprintf ("%s%s", prefix_drive ? : "", + relative_grubdir); + grub_install_make_image_wrap (/* source dir */ grub_install_source_directory, + /*prefix */ prefix, + /* output */ imgfile, + /* memdisk */ NULL, + have_load_cfg ? load_cfg : NULL, + /* image target */ mkimage_target, 0); + /* Backward-compatibility kludges. */ + switch (platform) + { + case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: + { + char *dst = grub_util_path_concat (2, bootdir, "grub.elf"); + grub_install_copy_file (imgfile, dst, 1); + free (dst); + } + break; + + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: + case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: + { + char *dst = grub_util_path_concat (2, grubdir, "grub"); + grub_install_copy_file (imgfile, dst, 1); + free (dst); + } + break; + + case GRUB_INSTALL_PLATFORM_I386_EFI: + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + { + char *dst = grub_util_path_concat (2, platdir, "grub.efi"); + grub_install_make_image_wrap (/* source dir */ grub_install_source_directory, + /* prefix */ "", + /* output */ dst, + /* memdisk */ NULL, + have_load_cfg ? load_cfg : NULL, + /* image target */ mkimage_target, 0); + } + break; + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI: + case GRUB_INSTALL_PLATFORM_RISCV32_EFI: + case GRUB_INSTALL_PLATFORM_RISCV64_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_ARM_COREBOOT: + case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: + case GRUB_INSTALL_PLATFORM_I386_PC: + case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: + case GRUB_INSTALL_PLATFORM_MIPS_ARC: + case GRUB_INSTALL_PLATFORM_ARM_UBOOT: + case GRUB_INSTALL_PLATFORM_I386_QEMU: + case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: + case GRUB_INSTALL_PLATFORM_I386_XEN: + case GRUB_INSTALL_PLATFORM_X86_64_XEN: + case GRUB_INSTALL_PLATFORM_I386_XEN_PVH: + break; + /* pacify warning. */ + case GRUB_INSTALL_PLATFORM_MAX: + break; + } + + /* Perform the platform-dependent install */ + + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_PC: + { + char *boot_img_src = grub_util_path_concat (2, + grub_install_source_directory, + "boot.img"); + char *boot_img = grub_util_path_concat (2, platdir, + "boot.img"); + grub_install_copy_file (boot_img_src, boot_img, 1); + + grub_util_info ("%sgrub-bios-setup %s %s %s %s %s --directory='%s' --device-map='%s' '%s'", + /* TRANSLATORS: This is a prefix in the log to indicate that usually + a command would be executed but due to an option was skipped. */ + install_bootsector ? "" : _("NOT RUNNING: "), + allow_floppy ? "--allow-floppy " : "", + verbosity ? "--verbose " : "", + force ? "--force " : "", + !fs_probe ? "--skip-fs-probe" : "", + !add_rs_codes ? "--no-rs-codes" : "", + platdir, + device_map, + install_device); + + /* Now perform the installation. */ + if (install_bootsector) + grub_util_bios_setup (platdir, "boot.img", "core.img", + install_drive, force, + fs_probe, allow_floppy, add_rs_codes); + break; + } + case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: + { + char *boot_img_src = grub_util_path_concat (2, + grub_install_source_directory, + "boot.img"); + char *boot_img = grub_util_path_concat (2, platdir, + "boot.img"); + grub_install_copy_file (boot_img_src, boot_img, 1); + + grub_util_info ("%sgrub-sparc64-setup %s %s %s %s --directory='%s' --device-map='%s' '%s'", + install_bootsector ? "" : "NOT RUNNING: ", + allow_floppy ? "--allow-floppy " : "", + verbosity ? "--verbose " : "", + force ? "--force " : "", + !fs_probe ? "--skip-fs-probe" : "", + platdir, + device_map, + install_drive); + + /* Now perform the installation. */ + if (install_bootsector) + grub_util_sparc_setup (platdir, "boot.img", "core.img", + install_drive, force, + fs_probe, allow_floppy, + 0 /* unused */ ); + break; + } + + case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: + if (macppcdir) + { + char *core_services = grub_util_path_concat (4, macppcdir, + "System", "Library", + "CoreServices"); + char *mach_kernel = grub_util_path_concat (2, macppcdir, + "mach_kernel"); + char *grub_elf, *bootx; + FILE *f; + grub_device_t ins_dev; + char *grub_chrp = grub_util_path_concat (2, + grub_install_source_directory, + "grub.chrp"); + + grub_install_mkdir_p (core_services); + + bootx = grub_util_path_concat (2, core_services, "BootX"); + grub_install_copy_file (grub_chrp, bootx, 1); + + grub_elf = grub_util_path_concat (2, core_services, "grub.elf"); + grub_install_copy_file (imgfile, grub_elf, 1); + + f = grub_util_fopen (mach_kernel, "a+"); + if (!f) + grub_util_error (_("Can't create file: %s"), strerror (errno)); + fclose (f); + + fill_core_services (core_services); + + ins_dev = grub_device_open (install_drive); + + bless (ins_dev, core_services, 0); + + if (update_nvram) + { + const char *dev; + int partno; + + partno = ins_dev->disk->partition + ? ins_dev->disk->partition->number + 1 : 0; + dev = grub_util_get_os_disk (install_device); + grub_install_register_ieee1275 (0, dev, partno, + "\\\\BootX"); + } + grub_device_close (ins_dev); + free (grub_elf); + free (bootx); + free (mach_kernel); + free (grub_chrp); + break; + } + /* If a install device is defined, copy the core.elf to PReP partition. */ + if (is_prep && install_device && install_device[0]) + { + grub_device_t ins_dev; + ins_dev = grub_device_open (install_drive); + if (!ins_dev || !is_prep_partition (ins_dev)) + { + grub_util_error ("%s", _("the chosen partition is not a PReP partition")); + } + if (is_prep_empty (ins_dev)) + { + if (write_to_disk (ins_dev, imgfile)) + grub_util_error ("%s", _("failed to copy Grub to the PReP partition")); + } + else + { + char *s = xasprintf ("dd if=/dev/zero of=%s", install_device); + grub_util_error (_("the PReP partition is not empty. If you are sure you want to use it, run dd to clear it: `%s'"), + s); + } + grub_device_close (ins_dev); + if (update_nvram) + grub_install_register_ieee1275 (1, grub_util_get_os_disk (install_device), + 0, NULL); + break; + } + /* fallthrough. */ + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: + if (update_nvram) + { + const char *dev; + char *relpath; + int partno; + relpath = grub_make_system_path_relative_to_its_root (imgfile); + partno = grub_dev->disk->partition + ? grub_dev->disk->partition->number + 1 : 0; + dev = grub_util_get_os_disk (grub_devices[0]); + grub_install_register_ieee1275 (0, dev, + partno, relpath); + } + break; + case GRUB_INSTALL_PLATFORM_MIPS_ARC: + grub_install_sgi_setup (install_device, imgfile, "grub"); + break; + + case GRUB_INSTALL_PLATFORM_I386_EFI: + if (!efidir_is_mac) + { + char *dst = grub_util_path_concat (2, efidir, "grub.efi"); + /* For old macs. Suggested by Peter Jones. */ + grub_install_copy_file (imgfile, dst, 1); + free (dst); + } + /* Fallthrough. */ + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + if (efidir_is_mac) + { + char *boot_efi; + char *core_services = grub_util_path_concat (4, efidir, + "System", "Library", + "CoreServices"); + char *mach_kernel = grub_util_path_concat (2, efidir, + "mach_kernel"); + FILE *f; + grub_device_t ins_dev; + + grub_install_mkdir_p (core_services); + + boot_efi = grub_util_path_concat (2, core_services, "boot.efi"); + grub_install_copy_file (imgfile, boot_efi, 1); + + f = grub_util_fopen (mach_kernel, "r+"); + if (!f) + grub_util_error (_("Can't create file: %s"), strerror (errno)); + fclose (f); + + fill_core_services(core_services); + + ins_dev = grub_device_open (install_drive); + + bless (ins_dev, boot_efi, 1); + if (!removable && update_nvram) + { + /* Try to make this image bootable using the EFI Boot Manager, if available. */ + int ret; + ret = grub_install_register_efi (efidir_grub_dev, + "\\System\\Library\\CoreServices", + efi_distributor); + if (ret) + grub_util_error (_("efibootmgr failed to register the boot entry: %s"), + strerror (ret)); + } + + grub_device_close (ins_dev); + free (boot_efi); + free (mach_kernel); + break; + } + /* FALLTHROUGH */ + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI: + case GRUB_INSTALL_PLATFORM_RISCV32_EFI: + case GRUB_INSTALL_PLATFORM_RISCV64_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + { + char *dst = grub_util_path_concat (2, efidir, efi_file); + grub_install_copy_file (imgfile, dst, 1); + free (dst); + } + if (!removable && update_nvram) + { + char * efifile_path; + char * part; + int ret; + + /* Try to make this image bootable using the EFI Boot Manager, if available. */ + if (!efi_distributor || efi_distributor[0] == '\0') + grub_util_error ("%s", _("EFI bootloader id isn't specified.")); + efifile_path = xasprintf ("\\EFI\\%s\\%s", + efi_distributor, + efi_file); + part = (efidir_grub_dev->disk->partition + ? grub_partition_get_name (efidir_grub_dev->disk->partition) + : 0); + grub_util_info ("Registering with EFI: distributor = `%s'," + " path = `%s', ESP at %s%s%s", + efi_distributor, efifile_path, + efidir_grub_dev->disk->name, + (part ? ",": ""), (part ? : "")); + grub_free (part); + ret = grub_install_register_efi (efidir_grub_dev, + efifile_path, efi_distributor); + if (ret) + grub_util_error (_("efibootmgr failed to register the boot entry: %s"), + strerror (ret)); + } + break; + + case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: + case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_ARM_COREBOOT: + case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: + case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: + case GRUB_INSTALL_PLATFORM_ARM_UBOOT: + case GRUB_INSTALL_PLATFORM_I386_QEMU: + case GRUB_INSTALL_PLATFORM_I386_XEN: + case GRUB_INSTALL_PLATFORM_X86_64_XEN: + case GRUB_INSTALL_PLATFORM_I386_XEN_PVH: + grub_util_warn ("%s", + _("WARNING: no platform-specific install was performed")); + break; + /* pacify warning. */ + case GRUB_INSTALL_PLATFORM_MAX: + break; + } + + fprintf (stderr, "%s\n", _("Installation finished. No error reported.")); + + /* Free resources. */ + grub_gcry_fini_all (); + grub_fini_all (); + + return 0; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/util/grub-mkconfig_lib.in b/GRUB2/MOD_SRC/grub-2.04/util/grub-mkconfig_lib.in new file mode 100644 index 0000000..0c820d5 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/util/grub-mkconfig_lib.in @@ -0,0 +1,373 @@ +# Helper library for grub-mkconfig +# Copyright (C) 2007,2008,2009,2010 Free Software Foundation, Inc. +# +# GRUB is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB 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 GRUB. If not, see . + +prefix="@prefix@" +exec_prefix="@exec_prefix@" +datarootdir="@datarootdir@" +datadir="@datadir@" +bindir="@bindir@" +sbindir="@sbindir@" +if [ "x$pkgdatadir" = x ]; then + pkgdatadir="${datadir}/@PACKAGE@" +fi + +if test "x$grub_probe" = x; then + grub_probe="${sbindir}/@grub_probe@" +fi +if test "x$grub_file" = x; then + grub_file="${bindir}/@grub_file@" +fi +if test "x$grub_mkrelpath" = x; then + grub_mkrelpath="${bindir}/@grub_mkrelpath@" +fi + +if which gettext >/dev/null 2>/dev/null; then + : +else + gettext () { + printf "%s" "$@" + } +fi + +grub_warn () +{ + echo "$(gettext "Warning:")" "$@" >&2 +} + +make_system_path_relative_to_its_root () +{ + "${grub_mkrelpath}" "$1" +} + +is_path_readable_by_grub () +{ + path="$1" + + # abort if path doesn't exist + if test -e "$path" ; then : ;else + return 1 + fi + + # abort if file is in a filesystem we can't read + if "${grub_probe}" -t fs "$path" > /dev/null 2>&1 ; then : ; else + return 1 + fi + + # ... or if we can't figure out the abstraction module, for example if + # memberlist fails on an LVM volume group. + if abstractions="`"${grub_probe}" -t abstraction "$path"`" 2> /dev/null ; then + : + else + return 1 + fi + + if [ x$GRUB_ENABLE_CRYPTODISK = xy ]; then + return 0 + fi + + for abstraction in $abstractions; do + if [ "x$abstraction" = xcryptodisk ]; then + return 1 + fi + done + + return 0 +} + +convert_system_path_to_grub_path () +{ + path="$1" + + grub_warn "convert_system_path_to_grub_path() is deprecated. Use prepare_grub_to_access_device() instead." + + # abort if GRUB can't access the path + if is_path_readable_by_grub "${path}" ; then : ; else + return 1 + fi + + if drive="`"${grub_probe}" -t drive "$path"`" ; then : ; else + return 1 + fi + + if relative_path="`make_system_path_relative_to_its_root "$path"`" ; then : ; else + return 1 + fi + + echo "${drive}${relative_path}" +} + +save_default_entry () +{ + if [ "x${GRUB_SAVEDEFAULT}" = "xtrue" ] ; then + cat << EOF +savedefault +EOF + fi +} + +prepare_grub_to_access_device () +{ + old_ifs="$IFS" + IFS=' +' +:<<\EOF + partmap="`"${grub_probe}" --device $@ --target=partmap`" + for module in ${partmap} ; do + case "${module}" in + netbsd | openbsd) + echo "insmod part_bsd";; + *) + echo "insmod part_${module}";; + esac + done +EOF + + # Abstraction modules aren't auto-loaded. + abstraction="`"${grub_probe}" --device $@ --target=abstraction`" + for module in ${abstraction} ; do + echo "insmod ${module}" + done + +# fs="`"${grub_probe}" --device $@ --target=fs`" +# for module in ${fs} ; do +# echo "insmod ${module}" +# done + + if [ x$GRUB_ENABLE_CRYPTODISK = xy ]; then + for uuid in `"${grub_probe}" --device $@ --target=cryptodisk_uuid`; do + echo "cryptomount -u $uuid" + done + fi + + # If there's a filesystem UUID that GRUB is capable of identifying, use it; + # otherwise set root as per value in device.map. + fs_hint="`"${grub_probe}" --device $@ --target=compatibility_hint`" + if [ "x$fs_hint" != x ]; then + echo "set root='$fs_hint'" + fi + if fs_uuid="`"${grub_probe}" --device $@ --target=fs_uuid 2> /dev/null`" ; then + hints="`"${grub_probe}" --device $@ --target=hints_string 2> /dev/null`" || hints= + echo "if [ x\$feature_platform_search_hint = xy ]; then" + echo " search --no-floppy --fs-uuid --set=root ${hints} ${fs_uuid}" + echo "else" + echo " search --no-floppy --fs-uuid --set=root ${fs_uuid}" + echo "fi" + fi + IFS="$old_ifs" +} + +grub_get_device_id () +{ + old_ifs="$IFS" + IFS=' +' + device="$1" + if fs_uuid="`"${grub_probe}" --device ${device} --target=fs_uuid 2> /dev/null`" ; then + echo "$fs_uuid"; + else + echo $device |sed 's, ,_,g' + fi + IFS="$old_ifs" +} + +grub_file_is_not_garbage () +{ + if test -f "$1" ; then + case "$1" in + *.dpkg-*) return 1 ;; # debian dpkg + *.rpmsave|*.rpmnew) return 1 ;; + README*|*/README*) return 1 ;; # documentation + *.sig) return 1 ;; # signatures + esac + else + return 1 + fi + return 0 +} + +version_sort () +{ + case $version_sort_sort_has_v in + yes) + LC_ALL=C sort -V;; + no) + LC_ALL=C sort -n;; + *) + if sort -V /dev/null 2>&1; then + version_sort_sort_has_v=yes + LC_ALL=C sort -V + else + version_sort_sort_has_v=no + LC_ALL=C sort -n + fi;; + esac +} + +version_test_numeric () +{ + version_test_numeric_a="$1" + version_test_numeric_cmp="$2" + version_test_numeric_b="$3" + if [ "$version_test_numeric_a" = "$version_test_numeric_b" ] ; then + case "$version_test_numeric_cmp" in + ge|eq|le) return 0 ;; + gt|lt) return 1 ;; + esac + fi + if [ "$version_test_numeric_cmp" = "lt" ] ; then + version_test_numeric_c="$version_test_numeric_a" + version_test_numeric_a="$version_test_numeric_b" + version_test_numeric_b="$version_test_numeric_c" + fi + if (echo "$version_test_numeric_a" ; echo "$version_test_numeric_b") | version_sort | head -n 1 | grep -qx "$version_test_numeric_b" ; then + return 0 + else + return 1 + fi +} + +version_test_gt () +{ + version_test_gt_a="`echo "$1" | sed -e "s/[^-]*-//"`" + version_test_gt_b="`echo "$2" | sed -e "s/[^-]*-//"`" + version_test_gt_cmp=gt + if [ "x$version_test_gt_b" = "x" ] ; then + return 0 + fi + case "$version_test_gt_a:$version_test_gt_b" in + *.old:*.old) ;; + *.old:*) version_test_gt_a="`echo "$version_test_gt_a" | sed -e 's/\.old$//'`" ; version_test_gt_cmp=gt ;; + *:*.old) version_test_gt_b="`echo "$version_test_gt_b" | sed -e 's/\.old$//'`" ; version_test_gt_cmp=ge ;; + esac + version_test_numeric "$version_test_gt_a" "$version_test_gt_cmp" "$version_test_gt_b" + return "$?" +} + +version_find_latest () +{ + version_find_latest_a="" + for i in "$@" ; do + if version_test_gt "$i" "$version_find_latest_a" ; then + version_find_latest_a="$i" + fi + done + echo "$version_find_latest_a" +} + +# One layer of quotation is eaten by "" and the second by sed; so this turns +# ' into \'. +grub_quote () { + sed "s/'/'\\\\''/g" +} + +gettext_quoted () { + gettext "$@" | grub_quote +} + +# Run the first argument through gettext, and then pass that and all +# remaining arguments to printf. This is a useful abbreviation and tends to +# be easier to type. +gettext_printf () { + gettext_printf_format="$1" + shift + printf "$(gettext "$gettext_printf_format")" "$@" +} + +uses_abstraction () { + device="$1" + old_ifs="$IFS" + IFS=' +' + + abstraction="`"${grub_probe}" --device ${device} --target=abstraction`" + for module in ${abstraction}; do + if test "x${module}" = "x$2"; then + IFS="$old_ifs" + return 0 + fi + done + IFS="$old_ifs" + return 1 +} + +print_option_help () { + if test x$print_option_help_wc = x; then + if wc -L /dev/null 2>&1; then + print_option_help_wc=-L + elif wc -m /dev/null 2>&1; then + print_option_help_wc=-m + else + print_option_help_wc=-b + fi + fi + if test x$grub_have_fmt = x; then + if fmt -w 40 /dev/null 2>&1; then + grub_have_fmt=y; + else + grub_have_fmt=n; + fi + fi + print_option_help_lead=" $1" + print_option_help_lspace="$(echo "$print_option_help_lead" | wc $print_option_help_wc)" + print_option_help_fill="$((26 - print_option_help_lspace))" + printf "%s" "$print_option_help_lead" + if test $print_option_help_fill -le 0; then + print_option_help_nl=y + echo + else + print_option_help_i=0; + while test $print_option_help_i -lt $print_option_help_fill; do + printf " " + print_option_help_i=$((print_option_help_i+1)) + done + print_option_help_nl=n + fi + if test x$grub_have_fmt = xy; then + print_option_help_split="$(echo "$2" | fmt -w 50)" + else + print_option_help_split="$2" + fi + if test x$print_option_help_nl = xy; then + echo "$print_option_help_split" | awk \ + '{ print " " $0; }' + else + echo "$print_option_help_split" | awk 'BEGIN { n = 0 } + { if (n == 1) print " " $0; else print $0; n = 1 ; }' + fi +} + +grub_fmt () { + if test x$grub_have_fmt = x; then + if fmt -w 40 < /dev/null > /dev/null; then + grub_have_fmt=y; + else + grub_have_fmt=n; + fi + fi + + if test x$grub_have_fmt = xy; then + fmt + else + cat + fi +} + +grub_tab=" " + +grub_add_tab () { + sed -e "s/^/$grub_tab/" +} + diff --git a/GRUB2/MOD_SRC/grub-2.04/util/grub-mkimagexx.c b/GRUB2/MOD_SRC/grub-2.04/util/grub-mkimagexx.c new file mode 100644 index 0000000..de8fd25 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/util/grub-mkimagexx.c @@ -0,0 +1,2689 @@ +/* grub-mkimage.c - make a bootable image */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#pragma GCC diagnostic ignored "-Wcast-align" + +#define GRUB_MKIMAGEXX +#if !defined(MKIMAGE_ELF32) && !defined(MKIMAGE_ELF64) +#if __SIZEOF_POINTER__ == 8 +#include "grub-mkimage64.c" +#else +#include "grub-mkimage32.c" +#endif +#endif + +/* These structures are defined according to the CHRP binding to IEEE1275, + "Client Program Format" section. */ + +struct grub_ieee1275_note_desc +{ + grub_uint32_t real_mode; + grub_uint32_t real_base; + grub_uint32_t real_size; + grub_uint32_t virt_base; + grub_uint32_t virt_size; + grub_uint32_t load_base; +}; + +#define GRUB_IEEE1275_NOTE_NAME "PowerPC" +#define GRUB_IEEE1275_NOTE_TYPE 0x1275 + +struct grub_ieee1275_note +{ + Elf32_Nhdr header; + char name[ALIGN_UP(sizeof (GRUB_IEEE1275_NOTE_NAME), 4)]; + struct grub_ieee1275_note_desc descriptor; +}; + +#define GRUB_XEN_NOTE_NAME "Xen" + +struct fixup_block_list +{ + struct fixup_block_list *next; + int state; + struct grub_pe32_fixup_block b; +}; + +#define ALIGN_ADDR(x) (ALIGN_UP((x), image_target->voidp_sizeof)) + +struct section_metadata +{ + Elf_Half num_sections; + Elf_Shdr *sections; + Elf_Addr *addrs; + Elf_Addr *vaddrs; + Elf_Half section_entsize; + Elf_Shdr *symtab; + const char *strtab; +}; + +static int +is_relocatable (const struct grub_install_image_target_desc *image_target) +{ + return image_target->id == IMAGE_EFI || image_target->id == IMAGE_UBOOT + || (image_target->id == IMAGE_COREBOOT && image_target->elf_target == EM_ARM); +} + +#ifdef MKIMAGE_ELF32 + +/* + * R_ARM_THM_CALL/THM_JUMP24 + * + * Relocate Thumb (T32) instruction set relative branches: + * B.W, BL and BLX + */ +static grub_err_t +grub_arm_reloc_thm_call (grub_uint16_t *target, Elf32_Addr sym_addr) +{ + grub_int32_t offset; + + offset = grub_arm_thm_call_get_offset (target); + + grub_dprintf ("dl", " sym_addr = 0x%08x", sym_addr); + + offset += sym_addr; + + grub_dprintf("dl", " BL*: target=%p, sym_addr=0x%08x, offset=%d\n", + target, sym_addr, offset); + + /* Keep traditional (pre-Thumb2) limits on blx. In any case if the kernel + is bigger than 2M (currently under 150K) then we probably have a problem + somewhere else. */ + if (offset < -0x200000 || offset >= 0x200000) + return grub_error (GRUB_ERR_BAD_MODULE, + "THM_CALL Relocation out of range."); + + grub_dprintf ("dl", " relative destination = %p", + (char *) target + offset); + + return grub_arm_thm_call_set_offset (target, offset); +} + +/* + * R_ARM_THM_JUMP19 + * + * Relocate conditional Thumb (T32) B.W + */ +static grub_err_t +grub_arm_reloc_thm_jump19 (grub_uint16_t *target, Elf32_Addr sym_addr) +{ + grub_int32_t offset; + + if (!(sym_addr & 1)) + return grub_error (GRUB_ERR_BAD_MODULE, + "Relocation targeting wrong execution state"); + + offset = grub_arm_thm_jump19_get_offset (target); + + /* Adjust and re-truncate offset */ + offset += sym_addr; + + if (!grub_arm_thm_jump19_check_offset (offset)) + return grub_error (GRUB_ERR_BAD_MODULE, + "THM_JUMP19 Relocation out of range."); + + grub_arm_thm_jump19_set_offset (target, offset); + + return GRUB_ERR_NONE; +} + +/* + * R_ARM_JUMP24 + * + * Relocate ARM (A32) B + */ +static grub_err_t +grub_arm_reloc_jump24 (grub_uint32_t *target, Elf32_Addr sym_addr) +{ + grub_int32_t offset; + + if (sym_addr & 1) + return grub_error (GRUB_ERR_BAD_MODULE, + "Relocation targeting wrong execution state"); + + offset = grub_arm_jump24_get_offset (target); + offset += sym_addr; + + if (!grub_arm_jump24_check_offset (offset)) + return grub_error (GRUB_ERR_BAD_MODULE, + "JUMP24 Relocation out of range."); + + + grub_arm_jump24_set_offset (target, offset); + + return GRUB_ERR_NONE; +} + +#endif + +void +SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc *image_target, + int note, char **core_img, size_t *core_size, + Elf_Addr target_addr, + struct grub_mkimage_layout *layout) +{ + char *elf_img; + size_t program_size; + Elf_Ehdr *ehdr; + Elf_Phdr *phdr; + Elf_Shdr *shdr; + int header_size, footer_size = 0; + int phnum = 1; + int shnum = 4; + int string_size = sizeof (".text") + sizeof ("mods") + 1; + + if (image_target->id != IMAGE_LOONGSON_ELF) + phnum += 2; + + if (note) + { + phnum++; + footer_size += sizeof (struct grub_ieee1275_note); + } + if (image_target->id == IMAGE_XEN || image_target->id == IMAGE_XEN_PVH) + { + phnum++; + shnum++; + string_size += sizeof (".xen"); + footer_size += (image_target->id == IMAGE_XEN) ? XEN_NOTE_SIZE : XEN_PVH_NOTE_SIZE; + } + header_size = ALIGN_UP (sizeof (*ehdr) + phnum * sizeof (*phdr) + + shnum * sizeof (*shdr) + string_size, layout->align); + + program_size = ALIGN_ADDR (*core_size); + + elf_img = xmalloc (program_size + header_size + footer_size); + memset (elf_img, 0, program_size + header_size + footer_size); + memcpy (elf_img + header_size, *core_img, *core_size); + ehdr = (void *) elf_img; + phdr = (void *) (elf_img + sizeof (*ehdr)); + shdr = (void *) (elf_img + sizeof (*ehdr) + phnum * sizeof (*phdr)); + memcpy (ehdr->e_ident, ELFMAG, SELFMAG); + ehdr->e_ident[EI_CLASS] = ELFCLASSXX; + if (!image_target->bigendian) + ehdr->e_ident[EI_DATA] = ELFDATA2LSB; + else + ehdr->e_ident[EI_DATA] = ELFDATA2MSB; + ehdr->e_ident[EI_VERSION] = EV_CURRENT; + ehdr->e_ident[EI_OSABI] = ELFOSABI_NONE; + ehdr->e_type = grub_host_to_target16 (ET_EXEC); + ehdr->e_machine = grub_host_to_target16 (image_target->elf_target); + ehdr->e_version = grub_host_to_target32 (EV_CURRENT); + + ehdr->e_phoff = grub_host_to_target32 ((char *) phdr - (char *) ehdr); + ehdr->e_phentsize = grub_host_to_target16 (sizeof (*phdr)); + ehdr->e_phnum = grub_host_to_target16 (phnum); + + ehdr->e_shoff = grub_host_to_target32 ((grub_uint8_t *) shdr + - (grub_uint8_t *) ehdr); + if (image_target->id == IMAGE_LOONGSON_ELF) + ehdr->e_shentsize = grub_host_to_target16 (0); + else + ehdr->e_shentsize = grub_host_to_target16 (sizeof (Elf_Shdr)); + ehdr->e_shnum = grub_host_to_target16 (shnum); + ehdr->e_shstrndx = grub_host_to_target16 (1); + + ehdr->e_ehsize = grub_host_to_target16 (sizeof (*ehdr)); + + phdr->p_type = grub_host_to_target32 (PT_LOAD); + phdr->p_offset = grub_host_to_target32 (header_size); + phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); + + ehdr->e_entry = grub_host_to_target32 (target_addr); + phdr->p_vaddr = grub_host_to_target32 (target_addr); + phdr->p_paddr = grub_host_to_target32 (target_addr); + phdr->p_align = grub_host_to_target32 (layout->align > image_target->link_align ? + layout->align : image_target->link_align); + if (image_target->id == IMAGE_LOONGSON_ELF) + ehdr->e_flags = grub_host_to_target32 (0x1000 | EF_MIPS_NOREORDER + | EF_MIPS_PIC | EF_MIPS_CPIC); + else + ehdr->e_flags = 0; + if (image_target->id == IMAGE_LOONGSON_ELF) + { + phdr->p_filesz = grub_host_to_target32 (*core_size); + phdr->p_memsz = grub_host_to_target32 (*core_size); + } + else + { + grub_uint32_t target_addr_mods; + phdr->p_filesz = grub_host_to_target32 (layout->kernel_size); + if (image_target->id == IMAGE_COREBOOT && image_target->elf_target == EM_ARM) + phdr->p_memsz = grub_host_to_target32 (layout->kernel_size); + else + phdr->p_memsz = grub_host_to_target32 (layout->kernel_size + layout->bss_size); + + phdr++; + phdr->p_type = grub_host_to_target32 (PT_GNU_STACK); + phdr->p_offset = grub_host_to_target32 (header_size + layout->kernel_size); + phdr->p_paddr = phdr->p_vaddr = phdr->p_filesz = phdr->p_memsz = 0; + phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); + phdr->p_align = grub_host_to_target32 (image_target->link_align); + + phdr++; + phdr->p_type = grub_host_to_target32 (PT_LOAD); + phdr->p_offset = grub_host_to_target32 (header_size + layout->kernel_size); + phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); + phdr->p_filesz = phdr->p_memsz + = grub_host_to_target32 (*core_size - layout->kernel_size); + + if (image_target->id == IMAGE_COREBOOT && image_target->elf_target == EM_386) + target_addr_mods = GRUB_KERNEL_I386_COREBOOT_MODULES_ADDR; + else if (image_target->id == IMAGE_COREBOOT && image_target->elf_target == EM_ARM) + target_addr_mods = ALIGN_UP (target_addr + layout->end + + image_target->mod_gap, + image_target->mod_align); + else + target_addr_mods = ALIGN_UP (target_addr + layout->kernel_size + layout->bss_size + + image_target->mod_gap, + image_target->mod_align); + phdr->p_vaddr = grub_host_to_target_addr (target_addr_mods); + phdr->p_paddr = grub_host_to_target_addr (target_addr_mods); + phdr->p_align = grub_host_to_target32 (image_target->link_align); + } + + if (image_target->id == IMAGE_XEN) + { + char *note_start = (elf_img + program_size + header_size); + Elf_Nhdr *note_ptr; + char *ptr = (char *) note_start; + + grub_util_info ("adding XEN NOTE segment"); + + /* Guest OS. */ + note_ptr = (Elf_Nhdr *) ptr; + note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME)); + note_ptr->n_descsz = grub_host_to_target32 (sizeof (PACKAGE_NAME)); + note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_GUEST_OS); + ptr += sizeof (Elf_Nhdr); + memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME)); + ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4); + memcpy (ptr, PACKAGE_NAME, sizeof (PACKAGE_NAME)); + ptr += ALIGN_UP (sizeof (PACKAGE_NAME), 4); + + /* Loader. */ + note_ptr = (Elf_Nhdr *) ptr; + note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME)); + note_ptr->n_descsz = grub_host_to_target32 (sizeof ("generic")); + note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_LOADER); + ptr += sizeof (Elf_Nhdr); + memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME)); + ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4); + memcpy (ptr, "generic", sizeof ("generic")); + ptr += ALIGN_UP (sizeof ("generic"), 4); + + /* Version. */ + note_ptr = (Elf_Nhdr *) ptr; + note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME)); + note_ptr->n_descsz = grub_host_to_target32 (sizeof ("xen-3.0")); + note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_XEN_VERSION); + ptr += sizeof (Elf_Nhdr); + memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME)); + ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4); + memcpy (ptr, "xen-3.0", sizeof ("xen-3.0")); + ptr += ALIGN_UP (sizeof ("xen-3.0"), 4); + + /* Entry. */ + note_ptr = (Elf_Nhdr *) ptr; + note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME)); + note_ptr->n_descsz = grub_host_to_target32 (image_target->voidp_sizeof); + note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_ENTRY); + ptr += sizeof (Elf_Nhdr); + memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME)); + ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4); + memset (ptr, 0, image_target->voidp_sizeof); + ptr += image_target->voidp_sizeof; + + /* Virt base. */ + note_ptr = (Elf_Nhdr *) ptr; + note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME)); + note_ptr->n_descsz = grub_host_to_target32 (image_target->voidp_sizeof); + note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_VIRT_BASE); + ptr += sizeof (Elf_Nhdr); + memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME)); + ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4); + memset (ptr, 0, image_target->voidp_sizeof); + ptr += image_target->voidp_sizeof; + + /* PAE. */ + if (image_target->elf_target == EM_386) + { + note_ptr = (Elf_Nhdr *) ptr; + note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME)); + note_ptr->n_descsz = grub_host_to_target32 (sizeof ("yes,bimodal")); + note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_PAE_MODE); + ptr += sizeof (Elf_Nhdr); + memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME)); + ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4); + memcpy (ptr, "yes", sizeof ("yes")); + ptr += ALIGN_UP (sizeof ("yes"), 4); + } + + assert (XEN_NOTE_SIZE == (ptr - note_start)); + + phdr++; + phdr->p_type = grub_host_to_target32 (PT_NOTE); + phdr->p_flags = grub_host_to_target32 (PF_R); + phdr->p_align = grub_host_to_target32 (image_target->voidp_sizeof); + phdr->p_vaddr = 0; + phdr->p_paddr = 0; + phdr->p_filesz = grub_host_to_target32 (XEN_NOTE_SIZE); + phdr->p_memsz = 0; + phdr->p_offset = grub_host_to_target32 (header_size + program_size); + } + + if (image_target->id == IMAGE_XEN_PVH) + { + char *note_start = (elf_img + program_size + header_size); + Elf_Nhdr *note_ptr; + char *ptr = (char *) note_start; + + grub_util_info ("adding XEN NOTE segment"); + + /* Phys32 Entry. */ + note_ptr = (Elf_Nhdr *) ptr; + note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME)); + note_ptr->n_descsz = grub_host_to_target32 (image_target->voidp_sizeof); + note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_PHYS32_ENTRY); + ptr += sizeof (Elf_Nhdr); + memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME)); + ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4); + memset (ptr, 0, image_target->voidp_sizeof); + *(grub_uint32_t *) ptr = GRUB_KERNEL_I386_XEN_PVH_LINK_ADDR; + ptr += image_target->voidp_sizeof; + + assert (XEN_PVH_NOTE_SIZE == (ptr - note_start)); + + phdr++; + phdr->p_type = grub_host_to_target32 (PT_NOTE); + phdr->p_flags = grub_host_to_target32 (PF_R); + phdr->p_align = grub_host_to_target32 (image_target->voidp_sizeof); + phdr->p_vaddr = 0; + phdr->p_paddr = 0; + phdr->p_filesz = grub_host_to_target32 (XEN_PVH_NOTE_SIZE); + phdr->p_memsz = 0; + phdr->p_offset = grub_host_to_target32 (header_size + program_size); + } + + if (note) + { + int note_size = sizeof (struct grub_ieee1275_note); + struct grub_ieee1275_note *note_ptr = (struct grub_ieee1275_note *) + (elf_img + program_size + header_size); + + grub_util_info ("adding CHRP NOTE segment"); + + note_ptr->header.n_namesz = grub_host_to_target32 (sizeof (GRUB_IEEE1275_NOTE_NAME)); + note_ptr->header.n_descsz = grub_host_to_target32 (note_size); + note_ptr->header.n_type = grub_host_to_target32 (GRUB_IEEE1275_NOTE_TYPE); + strcpy (note_ptr->name, GRUB_IEEE1275_NOTE_NAME); + note_ptr->descriptor.real_mode = grub_host_to_target32 (0xffffffff); + note_ptr->descriptor.real_base = grub_host_to_target32 (0x00c00000); + note_ptr->descriptor.real_size = grub_host_to_target32 (0xffffffff); + note_ptr->descriptor.virt_base = grub_host_to_target32 (0xffffffff); + note_ptr->descriptor.virt_size = grub_host_to_target32 (0xffffffff); + note_ptr->descriptor.load_base = grub_host_to_target32 (0x00004000); + + phdr++; + phdr->p_type = grub_host_to_target32 (PT_NOTE); + phdr->p_flags = grub_host_to_target32 (PF_R); + phdr->p_align = grub_host_to_target32 (image_target->voidp_sizeof); + phdr->p_vaddr = 0; + phdr->p_paddr = 0; + phdr->p_filesz = grub_host_to_target32 (note_size); + phdr->p_memsz = 0; + phdr->p_offset = grub_host_to_target32 (header_size + program_size); + } + + { + char *str_start = (elf_img + sizeof (*ehdr) + phnum * sizeof (*phdr) + + shnum * sizeof (*shdr)); + char *ptr = str_start + 1; + + shdr++; + + shdr->sh_name = grub_host_to_target32 (0); + shdr->sh_type = grub_host_to_target32 (SHT_STRTAB); + shdr->sh_addr = grub_host_to_target_addr (0); + shdr->sh_offset = grub_host_to_target_addr (str_start - elf_img); + shdr->sh_size = grub_host_to_target32 (string_size); + shdr->sh_link = grub_host_to_target32 (0); + shdr->sh_info = grub_host_to_target32 (0); + shdr->sh_addralign = grub_host_to_target32 (layout->align); + shdr->sh_entsize = grub_host_to_target32 (0); + shdr++; + + memcpy (ptr, ".text", sizeof (".text")); + + shdr->sh_name = grub_host_to_target32 (ptr - str_start); + ptr += sizeof (".text"); + shdr->sh_type = grub_host_to_target32 (SHT_PROGBITS); + shdr->sh_addr = grub_host_to_target_addr (target_addr); + shdr->sh_offset = grub_host_to_target_addr (header_size); + shdr->sh_size = grub_host_to_target32 (layout->kernel_size); + shdr->sh_link = grub_host_to_target32 (0); + shdr->sh_info = grub_host_to_target32 (0); + shdr->sh_addralign = grub_host_to_target32 (layout->align); + shdr->sh_entsize = grub_host_to_target32 (0); + shdr++; + + memcpy (ptr, "mods", sizeof ("mods")); + shdr->sh_name = grub_host_to_target32 (ptr - str_start); + ptr += sizeof ("mods"); + shdr->sh_type = grub_host_to_target32 (SHT_PROGBITS); + shdr->sh_addr = grub_host_to_target_addr (target_addr + layout->kernel_size); + shdr->sh_offset = grub_host_to_target_addr (header_size + layout->kernel_size); + shdr->sh_size = grub_host_to_target32 (*core_size - layout->kernel_size); + shdr->sh_link = grub_host_to_target32 (0); + shdr->sh_info = grub_host_to_target32 (0); + shdr->sh_addralign = grub_host_to_target32 (image_target->voidp_sizeof); + shdr->sh_entsize = grub_host_to_target32 (0); + shdr++; + + if (image_target->id == IMAGE_XEN || image_target->id == IMAGE_XEN_PVH) + { + memcpy (ptr, ".xen", sizeof (".xen")); + shdr->sh_name = grub_host_to_target32 (ptr - str_start); + ptr += sizeof (".xen"); + shdr->sh_type = grub_host_to_target32 (SHT_PROGBITS); + shdr->sh_addr = grub_host_to_target_addr (target_addr + layout->kernel_size); + shdr->sh_offset = grub_host_to_target_addr (program_size + header_size); + if (image_target->id == IMAGE_XEN) + shdr->sh_size = grub_host_to_target32 (XEN_NOTE_SIZE); + else + shdr->sh_size = grub_host_to_target32 (XEN_PVH_NOTE_SIZE); + shdr->sh_link = grub_host_to_target32 (0); + shdr->sh_info = grub_host_to_target32 (0); + shdr->sh_addralign = grub_host_to_target32 (image_target->voidp_sizeof); + shdr->sh_entsize = grub_host_to_target32 (0); + shdr++; + } + } + + free (*core_img); + *core_img = elf_img; + *core_size = program_size + header_size + footer_size; +} + +/* Relocate symbols; note that this function overwrites the symbol table. + Return the address of a start symbol. */ +static Elf_Addr +SUFFIX (relocate_symbols) (Elf_Ehdr *e, struct section_metadata *smd, + void *jumpers, Elf_Addr jumpers_addr, + Elf_Addr bss_start, Elf_Addr end, + const struct grub_install_image_target_desc *image_target) +{ + Elf_Word symtab_size, sym_size, num_syms; + Elf_Off symtab_offset; + Elf_Addr start_address = (Elf_Addr) -1; + Elf_Sym *sym; + Elf_Word i; + Elf_Shdr *symtab_section; + const char *symtab; + grub_uint64_t *jptr = jumpers; + + symtab_section = (Elf_Shdr *) ((char *) smd->sections + + grub_target_to_host32 (smd->symtab->sh_link) + * smd->section_entsize); + symtab = (char *) e + grub_target_to_host (symtab_section->sh_offset); + + symtab_size = grub_target_to_host (smd->symtab->sh_size); + sym_size = grub_target_to_host (smd->symtab->sh_entsize); + symtab_offset = grub_target_to_host (smd->symtab->sh_offset); + num_syms = symtab_size / sym_size; + + for (i = 0, sym = (Elf_Sym *) ((char *) e + symtab_offset); + i < num_syms; + i++, sym = (Elf_Sym *) ((char *) sym + sym_size)) + { + Elf_Section cur_index; + const char *name; + + name = symtab + grub_target_to_host32 (sym->st_name); + + cur_index = grub_target_to_host16 (sym->st_shndx); + if (cur_index == STN_ABS) + { + continue; + } + else if (cur_index == STN_UNDEF) + { + if (sym->st_name && grub_strcmp (name, "__bss_start") == 0) + sym->st_value = bss_start; + else if (sym->st_name && grub_strcmp (name, "_end") == 0) + sym->st_value = end; + else if (sym->st_name) + grub_util_error ("undefined symbol %s", name); + else + continue; + } + else if (cur_index >= smd->num_sections) + grub_util_error ("section %d does not exist", cur_index); + else + { + sym->st_value = (grub_target_to_host (sym->st_value) + + smd->vaddrs[cur_index]); + } + + if (image_target->elf_target == EM_IA_64 && ELF_ST_TYPE (sym->st_info) + == STT_FUNC) + { + *jptr = grub_host_to_target64 (sym->st_value); + sym->st_value = (char *) jptr - (char *) jumpers + jumpers_addr; + jptr++; + *jptr = 0; + jptr++; + } + grub_util_info ("locating %s at 0x%" GRUB_HOST_PRIxLONG_LONG + " (0x%" GRUB_HOST_PRIxLONG_LONG ")", name, + (unsigned long long) sym->st_value, + (unsigned long long) smd->vaddrs[cur_index]); + + if (start_address == (Elf_Addr)-1) + if (strcmp (name, "_start") == 0 || strcmp (name, "start") == 0) + start_address = sym->st_value; + } + + return start_address; +} + +/* Return the address of a symbol at the index I in the section S. */ +static Elf_Addr +SUFFIX (get_symbol_address) (Elf_Ehdr *e, Elf_Shdr *s, Elf_Word i, + const struct grub_install_image_target_desc *image_target) +{ + Elf_Sym *sym; + + sym = (Elf_Sym *) ((char *) e + + grub_target_to_host (s->sh_offset) + + i * grub_target_to_host (s->sh_entsize)); + return sym->st_value; +} + +/* Return the address of a modified value. */ +static Elf_Addr * +SUFFIX (get_target_address) (Elf_Ehdr *e, Elf_Shdr *s, Elf_Addr offset, + const struct grub_install_image_target_desc *image_target) +{ + return (Elf_Addr *) ((char *) e + grub_target_to_host (s->sh_offset) + offset); +} + +#ifdef MKIMAGE_ELF64 +static Elf_Addr +SUFFIX (count_funcs) (Elf_Ehdr *e, Elf_Shdr *symtab_section, + const struct grub_install_image_target_desc *image_target) +{ + Elf_Word symtab_size, sym_size, num_syms; + Elf_Off symtab_offset; + Elf_Sym *sym; + Elf_Word i; + int ret = 0; + + symtab_size = grub_target_to_host (symtab_section->sh_size); + sym_size = grub_target_to_host (symtab_section->sh_entsize); + symtab_offset = grub_target_to_host (symtab_section->sh_offset); + num_syms = symtab_size / sym_size; + + for (i = 0, sym = (Elf_Sym *) ((char *) e + symtab_offset); + i < num_syms; + i++, sym = (Elf_Sym *) ((char *) sym + sym_size)) + if (ELF_ST_TYPE (sym->st_info) == STT_FUNC) + ret++; + + return ret; +} +#endif + +#ifdef MKIMAGE_ELF32 +/* Deal with relocation information. This function relocates addresses + within the virtual address space starting from 0. So only relative + addresses can be fully resolved. Absolute addresses must be relocated + again by a PE32 relocator when loaded. */ +static grub_size_t +arm_get_trampoline_size (Elf_Ehdr *e, + Elf_Shdr *sections, + Elf_Half section_entsize, + Elf_Half num_sections, + const struct grub_install_image_target_desc *image_target) +{ + Elf_Half i; + Elf_Shdr *s; + grub_size_t ret = 0; + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if ((s->sh_type == grub_host_to_target32 (SHT_REL)) || + (s->sh_type == grub_host_to_target32 (SHT_RELA))) + { + Elf_Rela *r; + Elf_Word rtab_size, r_size, num_rs; + Elf_Off rtab_offset; + Elf_Shdr *symtab_section; + Elf_Word j; + + symtab_section = (Elf_Shdr *) ((char *) sections + + (grub_target_to_host32 (s->sh_link) + * section_entsize)); + + rtab_size = grub_target_to_host (s->sh_size); + r_size = grub_target_to_host (s->sh_entsize); + rtab_offset = grub_target_to_host (s->sh_offset); + num_rs = rtab_size / r_size; + + for (j = 0, r = (Elf_Rela *) ((char *) e + rtab_offset); + j < num_rs; + j++, r = (Elf_Rela *) ((char *) r + r_size)) + { + Elf_Addr info; + Elf_Addr sym_addr; + + info = grub_target_to_host (r->r_info); + sym_addr = SUFFIX (get_symbol_address) (e, symtab_section, + ELF_R_SYM (info), image_target); + + sym_addr += (s->sh_type == grub_target_to_host32 (SHT_RELA)) ? + grub_target_to_host (r->r_addend) : 0; + + switch (ELF_R_TYPE (info)) + { + case R_ARM_ABS32: + case R_ARM_V4BX: + break; + case R_ARM_THM_CALL: + case R_ARM_THM_JUMP24: + case R_ARM_THM_JUMP19: + if (!(sym_addr & 1)) + ret += 8; + break; + + case R_ARM_CALL: + case R_ARM_JUMP24: + if (sym_addr & 1) + ret += 16; + break; + + default: + grub_util_error (_("relocation 0x%x is not implemented yet"), + (unsigned int) ELF_R_TYPE (info)); + break; + } + } + } + return ret; +} +#endif + +static int +SUFFIX (is_kept_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target); +static int +SUFFIX (is_kept_reloc_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target, + struct section_metadata *smd); + +/* Deal with relocation information. This function relocates addresses + within the virtual address space starting from 0. So only relative + addresses can be fully resolved. Absolute addresses must be relocated + again by a PE32 relocator when loaded. */ +static void +SUFFIX (relocate_addrs) (Elf_Ehdr *e, struct section_metadata *smd, + char *pe_target, Elf_Addr tramp_off, Elf_Addr got_off, + const struct grub_install_image_target_desc *image_target) +{ + Elf_Half i; + Elf_Shdr *s; +#ifdef MKIMAGE_ELF64 + struct grub_ia64_trampoline *tr = (void *) (pe_target + tramp_off); + grub_uint64_t *gpptr = (void *) (pe_target + got_off); + unsigned unmatched_adr_got_page = 0; +#define MASK19 ((1 << 19) - 1) +#else + grub_uint32_t *tr = (void *) (pe_target + tramp_off); +#endif + + for (i = 0, s = smd->sections; + i < smd->num_sections; + i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize)) + if ((s->sh_type == grub_host_to_target32 (SHT_REL)) || + (s->sh_type == grub_host_to_target32 (SHT_RELA))) + { + Elf_Rela *r; + Elf_Word rtab_size, r_size, num_rs; + Elf_Off rtab_offset; + Elf_Word target_section_index; + Elf_Addr target_section_addr; + Elf_Shdr *target_section; + Elf_Word j; + + if (!SUFFIX (is_kept_section) (s, image_target) && + !SUFFIX (is_kept_reloc_section) (s, image_target, smd)) + { + grub_util_info ("not translating relocations for omitted section %s", + smd->strtab + grub_le_to_cpu32 (s->sh_name)); + continue; + } + + target_section_index = grub_target_to_host32 (s->sh_info); + target_section_addr = smd->addrs[target_section_index]; + target_section = (Elf_Shdr *) ((char *) smd->sections + + (target_section_index + * smd->section_entsize)); + + grub_util_info ("dealing with the relocation section %s for %s", + smd->strtab + grub_target_to_host32 (s->sh_name), + smd->strtab + grub_target_to_host32 (target_section->sh_name)); + + rtab_size = grub_target_to_host (s->sh_size); + r_size = grub_target_to_host (s->sh_entsize); + rtab_offset = grub_target_to_host (s->sh_offset); + num_rs = rtab_size / r_size; + + for (j = 0, r = (Elf_Rela *) ((char *) e + rtab_offset); + j < num_rs; + j++, r = (Elf_Rela *) ((char *) r + r_size)) + { + Elf_Addr info; + Elf_Addr offset; + Elf_Addr sym_addr; + Elf_Addr *target; + Elf_Addr addend; + + offset = grub_target_to_host (r->r_offset); + target = SUFFIX (get_target_address) (e, target_section, + offset, image_target); + if (image_target->elf_target == EM_MIPS && image_target->voidp_sizeof == 8) + info = ((grub_uint64_t) r->r_info << 32) | + (grub_uint32_t) grub_be_to_cpu64 (r->r_info); + else + info = grub_target_to_host (r->r_info); + sym_addr = SUFFIX (get_symbol_address) (e, smd->symtab, + ELF_R_SYM (info), image_target); + + addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ? + grub_target_to_host (r->r_addend) : 0; + + switch (image_target->elf_target) + { + case EM_386: + switch (ELF_R_TYPE (info)) + { + case R_386_NONE: + break; + + case R_386_32: + /* This is absolute. */ + *target = grub_host_to_target32 (grub_target_to_host32 (*target) + + addend + sym_addr); + grub_util_info ("relocating an R_386_32 entry to 0x%" + GRUB_HOST_PRIxLONG_LONG " at the offset 0x%" + GRUB_HOST_PRIxLONG_LONG, + (unsigned long long) *target, + (unsigned long long) offset); + break; + + case R_386_PC32: + /* This is relative. */ + *target = grub_host_to_target32 (grub_target_to_host32 (*target) + + addend + sym_addr + - target_section_addr - offset + - image_target->vaddr_offset); + grub_util_info ("relocating an R_386_PC32 entry to 0x%" + GRUB_HOST_PRIxLONG_LONG " at the offset 0x%" + GRUB_HOST_PRIxLONG_LONG, + (unsigned long long) *target, + (unsigned long long) offset); + break; + default: + grub_util_error (_("relocation 0x%x is not implemented yet"), + (unsigned int) ELF_R_TYPE (info)); + break; + } + break; +#ifdef MKIMAGE_ELF64 + case EM_X86_64: + switch (ELF_R_TYPE (info)) + { + + case R_X86_64_NONE: + break; + + case R_X86_64_64: + *target = grub_host_to_target64 (grub_target_to_host64 (*target) + + addend + sym_addr); + grub_util_info ("relocating an R_X86_64_64 entry to 0x%" + GRUB_HOST_PRIxLONG_LONG " at the offset 0x%" + GRUB_HOST_PRIxLONG_LONG, + (unsigned long long) *target, + (unsigned long long) offset); + break; + + case R_X86_64_PC32: + case R_X86_64_PLT32: + { + grub_uint32_t *t32 = (grub_uint32_t *) target; + *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) + + addend + sym_addr + - target_section_addr - offset + - image_target->vaddr_offset); + grub_util_info ("relocating an R_X86_64_PC32 entry to 0x%x at the offset 0x%" + GRUB_HOST_PRIxLONG_LONG, + *t32, (unsigned long long) offset); + break; + } + + case R_X86_64_PC64: + { + *target = grub_host_to_target64 (grub_target_to_host64 (*target) + + addend + sym_addr + - target_section_addr - offset + - image_target->vaddr_offset); + grub_util_info ("relocating an R_X86_64_PC64 entry to 0x%" + GRUB_HOST_PRIxLONG_LONG " at the offset 0x%" + GRUB_HOST_PRIxLONG_LONG, + (unsigned long long) *target, + (unsigned long long) offset); + break; + } + + case R_X86_64_32: + case R_X86_64_32S: + { + grub_uint32_t *t32 = (grub_uint32_t *) target; + *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) + + addend + sym_addr); + grub_util_info ("relocating an R_X86_64_32(S) entry to 0x%x at the offset 0x%" + GRUB_HOST_PRIxLONG_LONG, + *t32, (unsigned long long) offset); + break; + } + + default: + grub_util_error (_("relocation 0x%x is not implemented yet"), + (unsigned int) ELF_R_TYPE (info)); + break; + } + break; + case EM_IA_64: + switch (ELF_R_TYPE (info)) + { + case R_IA64_PCREL21B: + { + grub_uint64_t noff; + grub_ia64_make_trampoline (tr, addend + sym_addr); + noff = ((char *) tr - (char *) pe_target + - target_section_addr - (offset & ~3)) >> 4; + tr++; + if (noff & ~MASK19) + grub_util_error ("trampoline offset too big (%" + GRUB_HOST_PRIxLONG_LONG ")", + (unsigned long long) noff); + grub_ia64_add_value_to_slot_20b ((grub_addr_t) target, noff); + } + break; + + case R_IA64_LTOFF22X: + case R_IA64_LTOFF22: + { + Elf_Sym *sym; + + sym = (Elf_Sym *) ((char *) e + + grub_target_to_host (smd->symtab->sh_offset) + + ELF_R_SYM (info) * grub_target_to_host (smd->symtab->sh_entsize)); + if (ELF_ST_TYPE (sym->st_info) == STT_FUNC) + sym_addr = grub_target_to_host64 (*(grub_uint64_t *) (pe_target + + sym->st_value + - image_target->vaddr_offset)); + } + /* FALLTHROUGH */ + case R_IA64_LTOFF_FPTR22: + *gpptr = grub_host_to_target64 (addend + sym_addr); + grub_ia64_add_value_to_slot_21 ((grub_addr_t) target, + (char *) gpptr - (char *) pe_target + + image_target->vaddr_offset); + gpptr++; + break; + + case R_IA64_GPREL22: + grub_ia64_add_value_to_slot_21 ((grub_addr_t) target, + addend + sym_addr); + break; + case R_IA64_GPREL64I: + grub_ia64_set_immu64 ((grub_addr_t) target, + addend + sym_addr); + break; + case R_IA64_PCREL64LSB: + *target = grub_host_to_target64 (grub_target_to_host64 (*target) + + addend + sym_addr + - target_section_addr - offset + - image_target->vaddr_offset); + break; + + case R_IA64_SEGREL64LSB: + *target = grub_host_to_target64 (grub_target_to_host64 (*target) + + addend + sym_addr - target_section_addr); + break; + case R_IA64_DIR64LSB: + case R_IA64_FPTR64LSB: + *target = grub_host_to_target64 (grub_target_to_host64 (*target) + + addend + sym_addr); + grub_util_info ("relocating a direct entry to 0x%" + GRUB_HOST_PRIxLONG_LONG " at the offset 0x%" + GRUB_HOST_PRIxLONG_LONG, + (unsigned long long) + grub_target_to_host64 (*target), + (unsigned long long) offset); + break; + + /* We treat LTOFF22X as LTOFF22, so we can ignore LDXMOV. */ + case R_IA64_LDXMOV: + break; + + default: + grub_util_error (_("relocation 0x%x is not implemented yet"), + (unsigned int) ELF_R_TYPE (info)); + break; + } + break; + case EM_AARCH64: + { + sym_addr += addend; + switch (ELF_R_TYPE (info)) + { + case R_AARCH64_ABS64: + { + *target = grub_host_to_target64 (grub_target_to_host64 (*target) + sym_addr); + } + break; + case R_AARCH64_PREL32: + { + grub_uint32_t *t32 = (grub_uint32_t *) target; + *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) + + sym_addr + - target_section_addr - offset + - image_target->vaddr_offset); + grub_util_info ("relocating an R_AARCH64_PREL32 entry to 0x%x at the offset 0x%" + GRUB_HOST_PRIxLONG_LONG, + *t32, (unsigned long long) offset); + break; + } + case R_AARCH64_ADD_ABS_LO12_NC: + grub_arm64_set_abs_lo12 ((grub_uint32_t *) target, + sym_addr); + break; + case R_AARCH64_LDST64_ABS_LO12_NC: + grub_arm64_set_abs_lo12_ldst64 ((grub_uint32_t *) target, + sym_addr); + break; + case R_AARCH64_JUMP26: + case R_AARCH64_CALL26: + { + sym_addr -= offset; + sym_addr -= target_section_addr + image_target->vaddr_offset; + if (!grub_arm_64_check_xxxx26_offset (sym_addr)) + grub_util_error ("%s", "CALL26 Relocation out of range"); + + grub_arm64_set_xxxx26_offset((grub_uint32_t *)target, + sym_addr); + } + break; + case R_AARCH64_ADR_GOT_PAGE: + { + Elf64_Rela *rel2; + grub_int64_t gpoffset = (((char *) gpptr - (char *) pe_target + image_target->vaddr_offset) & ~0xfffULL) + - ((offset + target_section_addr + image_target->vaddr_offset) & ~0xfffULL); + unsigned k; + *gpptr = grub_host_to_target64 (sym_addr); + unmatched_adr_got_page++; + if (!grub_arm64_check_hi21_signed (gpoffset)) + grub_util_error ("HI21 out of range"); + grub_arm64_set_hi21((grub_uint32_t *)target, + gpoffset); + for (k = 0, rel2 = (Elf_Rela *) ((char *) r + r_size); + k < num_rs; + k++, rel2 = (Elf_Rela *) ((char *) rel2 + r_size)) + if (ELF_R_SYM (rel2->r_info) + == ELF_R_SYM (r->r_info) + && r->r_addend == rel2->r_addend + && ELF_R_TYPE (rel2->r_info) == R_AARCH64_LD64_GOT_LO12_NC) + { + grub_arm64_set_abs_lo12_ldst64 ((grub_uint32_t *) SUFFIX (get_target_address) (e, target_section, + grub_target_to_host (rel2->r_offset), image_target), + ((char *) gpptr - (char *) pe_target + image_target->vaddr_offset)); + break; + } + if (k >= num_rs) + grub_util_error ("ADR_GOT_PAGE without matching LD64_GOT_LO12_NC"); + gpptr++; + } + break; + case R_AARCH64_LD64_GOT_LO12_NC: + if (unmatched_adr_got_page == 0) + grub_util_error ("LD64_GOT_LO12_NC without matching ADR_GOT_PAGE"); + unmatched_adr_got_page--; + break; + case R_AARCH64_ADR_PREL_PG_HI21: + { + sym_addr &= ~0xfffULL; + sym_addr -= (offset + target_section_addr + image_target->vaddr_offset) & ~0xfffULL; + if (!grub_arm64_check_hi21_signed (sym_addr)) + grub_util_error ("%s", "CALL26 Relocation out of range"); + + grub_arm64_set_hi21((grub_uint32_t *)target, + sym_addr); + } + break; + default: + grub_util_error (_("relocation 0x%x is not implemented yet"), + (unsigned int) ELF_R_TYPE (info)); + break; + } + break; + } + case EM_MIPS: + { + sym_addr += addend; + switch (ELF_R_TYPE (info)) + { + case R_MIPS_NONE: + break; + case R_MIPS_64: + { + *target = grub_host_to_target64 (grub_target_to_host64 (*target) + sym_addr); + } + break; + case R_MIPS_32: + { + grub_uint32_t *t32 = (grub_uint32_t *) target; + *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) + sym_addr); + } + break; + case R_MIPS_26: + { + grub_uint32_t *t32 = (grub_uint32_t *) target; + grub_addr_t addr = grub_host_to_target64 (sym_addr); + *t32 = ((*t32) & 0xfc000000U) | ((addr >> 2) & 0x3ffffffUL); + } + break; + case R_MIPS_LO16: + { + grub_int16_t *t16 = (grub_int16_t *) target; + grub_addr_t addr = grub_host_to_target64 (sym_addr); + *t16 = (grub_int16_t) addr; + } + break; + case R_MIPS_HI16: + { + grub_int16_t *t16 = (grub_int16_t *) target; + grub_addr_t addr = grub_host_to_target64 (sym_addr); + *t16 = (grub_int16_t) ((addr + 0x8000UL) >> 16); + } + break; + case R_MIPS_HIGHER: + { + grub_int16_t *t16 = (grub_int16_t *) target; + grub_addr_t addr = grub_host_to_target64 (sym_addr); + *t16 = (grub_int16_t) ((addr + 0x80008000UL) >> 32); + } + break; + case R_MIPS_HIGHEST: + { + grub_uint16_t *t16 = (grub_uint16_t *) target; + grub_addr_t addr = grub_host_to_target64 (sym_addr); + *t16 = (grub_uint16_t) ((addr + 0x800080008000UL) >> 48); + } + break; + default: + grub_util_error (_("relocation 0x%x is not implemented yet"), + (unsigned int) ELF_R_TYPE (info)); + break; + } + break; + } +#endif +#if defined(MKIMAGE_ELF32) + case EM_ARM: + { + sym_addr += addend; + sym_addr -= image_target->vaddr_offset; + switch (ELF_R_TYPE (info)) + { + case R_ARM_ABS32: + { + grub_util_info (" ABS32:\toffset=%d\t(0x%08x)", + (int) sym_addr, (int) sym_addr); + /* Data will be naturally aligned */ + if (image_target->id == IMAGE_EFI) + sym_addr += GRUB_PE32_SECTION_ALIGNMENT; + *target = grub_host_to_target32 (grub_target_to_host32 (*target) + sym_addr); + } + break; + /* Happens when compiled with -march=armv4. + Since currently we need at least armv5, keep bx as-is. + */ + case R_ARM_V4BX: + break; + case R_ARM_THM_CALL: + case R_ARM_THM_JUMP24: + case R_ARM_THM_JUMP19: + { + grub_err_t err; + Elf_Sym *sym; + grub_util_info (" THM_JUMP24:\ttarget=0x%08lx\toffset=(0x%08x)", + (unsigned long) ((char *) target + - (char *) e), + sym_addr); + sym = (Elf_Sym *) ((char *) e + + grub_target_to_host (smd->symtab->sh_offset) + + ELF_R_SYM (info) * grub_target_to_host (smd->symtab->sh_entsize)); + if (ELF_ST_TYPE (sym->st_info) != STT_FUNC) + sym_addr |= 1; + if (!(sym_addr & 1)) + { + grub_uint32_t tr_addr; + grub_int32_t new_offset; + tr_addr = (char *) tr - (char *) pe_target + - target_section_addr; + new_offset = sym_addr - tr_addr - 12; + + if (!grub_arm_jump24_check_offset (new_offset)) + return grub_util_error ("jump24 relocation out of range"); + + tr[0] = grub_host_to_target32 (0x46c04778); /* bx pc; nop */ + tr[1] = grub_host_to_target32 (((new_offset >> 2) & 0xffffff) | 0xea000000); /* b new_offset */ + tr += 2; + sym_addr = tr_addr | 1; + } + sym_addr -= offset; + /* Thumb instructions can be 16-bit aligned */ + if (ELF_R_TYPE (info) == R_ARM_THM_JUMP19) + err = grub_arm_reloc_thm_jump19 ((grub_uint16_t *) target, sym_addr); + else + err = grub_arm_reloc_thm_call ((grub_uint16_t *) target, + sym_addr); + if (err) + grub_util_error ("%s", grub_errmsg); + } + break; + + case R_ARM_CALL: + case R_ARM_JUMP24: + { + grub_err_t err; + grub_util_info (" JUMP24:\ttarget=0x%08lx\toffset=(0x%08x)", (unsigned long) ((char *) target - (char *) e), sym_addr); + if (sym_addr & 1) + { + grub_uint32_t tr_addr; + grub_int32_t new_offset; + tr_addr = (char *) tr - (char *) pe_target + - target_section_addr; + new_offset = sym_addr - tr_addr - 12; + + /* There is no immediate version of bx, only register one... */ + tr[0] = grub_host_to_target32 (0xe59fc004); /* ldr ip, [pc, #4] */ + tr[1] = grub_host_to_target32 (0xe08cc00f); /* add ip, ip, pc */ + tr[2] = grub_host_to_target32 (0xe12fff1c); /* bx ip */ + tr[3] = grub_host_to_target32 (new_offset | 1); + tr += 4; + sym_addr = tr_addr; + } + sym_addr -= offset; + err = grub_arm_reloc_jump24 (target, + sym_addr); + if (err) + grub_util_error ("%s", grub_errmsg); + } + break; + + default: + grub_util_error (_("relocation 0x%x is not implemented yet"), + (unsigned int) ELF_R_TYPE (info)); + break; + } + break; + } +#endif /* MKIMAGE_ELF32 */ + case EM_RISCV: + { + grub_uint64_t *t64 = (grub_uint64_t *) target; + grub_uint32_t *t32 = (grub_uint32_t *) target; + grub_uint16_t *t16 = (grub_uint16_t *) target; + grub_uint8_t *t8 = (grub_uint8_t *) target; + grub_int64_t off = (long)sym_addr - target_section_addr - offset + - image_target->vaddr_offset; + + /* + * Instructions and instruction encoding are documented in the RISC-V + * specification. This file is based on version 2.2: + * + * https://github.com/riscv/riscv-isa-manual/blob/master/release/riscv-spec-v2.2.pdf + */ + + sym_addr += addend; + + switch (ELF_R_TYPE (info)) + { + case R_RISCV_ADD8: + *t8 = *t8 + sym_addr; + break; + case R_RISCV_ADD16: + *t16 = grub_host_to_target16 (grub_target_to_host16 (*t16) + sym_addr); + break; + case R_RISCV_32: + case R_RISCV_ADD32: + *t32 = grub_host_to_target32 (grub_target_to_host32 (*t32) + sym_addr); + break; + case R_RISCV_64: + case R_RISCV_ADD64: + *t64 = grub_host_to_target64 (grub_target_to_host64 (*t64) + sym_addr); + break; + + case R_RISCV_SUB8: + *t8 = sym_addr - *t8; + break; + case R_RISCV_SUB16: + *t16 = grub_host_to_target16 (grub_target_to_host16 (*t16) - sym_addr); + break; + case R_RISCV_SUB32: + *t32 = grub_host_to_target32 (grub_target_to_host32 (*t32) - sym_addr); + break; + case R_RISCV_SUB64: + *t64 = grub_host_to_target64 (grub_target_to_host64 (*t64) - sym_addr); + break; + case R_RISCV_BRANCH: + { + grub_uint32_t imm12 = (off & 0x1000) << (31 - 12); + grub_uint32_t imm11 = (off & 0x800) >> (11 - 7); + grub_uint32_t imm10_5 = (off & 0x7e0) << (30 - 10); + grub_uint32_t imm4_1 = (off & 0x1e) << (11 - 4); + *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0x1fff07f) + | imm12 | imm11 | imm10_5 | imm4_1); + } + break; + case R_RISCV_JAL: + { + grub_uint32_t imm20 = (off & 0x100000) << (31 - 20); + grub_uint32_t imm19_12 = (off & 0xff000); + grub_uint32_t imm11 = (off & 0x800) << (20 - 11); + grub_uint32_t imm10_1 = (off & 0x7fe) << (30 - 10); + *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0xfff) + | imm20 | imm19_12 | imm11 | imm10_1); + } + break; + case R_RISCV_CALL: + { + grub_uint32_t hi20, lo12; + + if (off != (grub_int32_t)off) + grub_util_error ("target %lx not reachable from pc=%lx", (long)sym_addr, (long)((char *)target - (char *)e)); + + hi20 = (off + 0x800) & 0xfffff000; + lo12 = (off - hi20) & 0xfff; + t32[0] = grub_host_to_target32 ((grub_target_to_host32 (t32[0]) & 0xfff) | hi20); + t32[1] = grub_host_to_target32 ((grub_target_to_host32 (t32[1]) & 0xfffff) | (lo12 << 20)); + } + break; + case R_RISCV_RVC_BRANCH: + { + grub_uint16_t imm8 = (off & 0x100) << (12 - 8); + grub_uint16_t imm7_6 = (off & 0xc0) >> (6 - 5); + grub_uint16_t imm5 = (off & 0x20) >> (5 - 2); + grub_uint16_t imm4_3 = (off & 0x18) << (12 - 5); + grub_uint16_t imm2_1 = (off & 0x6) << (12 - 10); + *t16 = grub_host_to_target16 ((grub_target_to_host16 (*t16) & 0xe383) + | imm8 | imm7_6 | imm5 | imm4_3 | imm2_1); + } + break; + case R_RISCV_RVC_JUMP: + { + grub_uint16_t imm11 = (off & 0x800) << (12 - 11); + grub_uint16_t imm10 = (off & 0x400) >> (10 - 8); + grub_uint16_t imm9_8 = (off & 0x300) << (12 - 11); + grub_uint16_t imm7 = (off & 0x80) >> (7 - 6); + grub_uint16_t imm6 = (off & 0x40) << (12 - 11); + grub_uint16_t imm5 = (off & 0x20) >> (5 - 2); + grub_uint16_t imm4 = (off & 0x10) << (12 - 5); + grub_uint16_t imm3_1 = (off & 0xe) << (12 - 10); + *t16 = grub_host_to_target16 ((grub_target_to_host16 (*t16) & 0xe003) + | imm11 | imm10 | imm9_8 | imm7 | imm6 + | imm5 | imm4 | imm3_1); + } + break; + case R_RISCV_PCREL_HI20: + { + grub_int32_t hi20; + + if (off != (grub_int32_t)off) + grub_util_error ("target %lx not reachable from pc=%lx", (long)sym_addr, (long)((char *)target - (char *)e)); + + hi20 = (off + 0x800) & 0xfffff000; + *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0xfff) | hi20); + } + break; + case R_RISCV_PCREL_LO12_I: + case R_RISCV_PCREL_LO12_S: + { + Elf_Rela *rel2; + Elf_Word k; + /* Search backwards for matching HI20 reloc. */ + for (k = j, rel2 = (Elf_Rela *) ((char *) r - r_size); + k > 0; + k--, rel2 = (Elf_Rela *) ((char *) rel2 - r_size)) + { + Elf_Addr rel2_info; + Elf_Addr rel2_offset; + Elf_Addr rel2_sym_addr; + Elf_Addr rel2_addend; + Elf_Addr rel2_loc; + grub_int64_t rel2_off; + + rel2_offset = grub_target_to_host (rel2->r_offset); + rel2_info = grub_target_to_host (rel2->r_info); + rel2_loc = target_section_addr + rel2_offset + image_target->vaddr_offset; + + if (ELF_R_TYPE (rel2_info) == R_RISCV_PCREL_HI20 + && rel2_loc == sym_addr) + { + rel2_sym_addr = SUFFIX (get_symbol_address) + (e, smd->symtab, ELF_R_SYM (rel2_info), + image_target); + rel2_addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ? + grub_target_to_host (rel2->r_addend) : 0; + rel2_off = rel2_sym_addr + rel2_addend - rel2_loc; + off = rel2_off - ((rel2_off + 0x800) & 0xfffff000); + + if (ELF_R_TYPE (info) == R_RISCV_PCREL_LO12_I) + *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0xfffff) | (off & 0xfff) << 20); + else + { + grub_uint32_t imm11_5 = (off & 0xfe0) << (31 - 11); + grub_uint32_t imm4_0 = (off & 0x1f) << (11 - 4); + *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0x1fff07f) | imm11_5 | imm4_0); + } + break; + } + } + if (k == 0) + grub_util_error ("cannot find matching HI20 relocation"); + } + break; + case R_RISCV_HI20: + *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0xfff) | (((grub_int32_t) sym_addr + 0x800) & 0xfffff000)); + break; + case R_RISCV_LO12_I: + { + grub_int32_t lo12 = (grub_int32_t) sym_addr - (((grub_int32_t) sym_addr + 0x800) & 0xfffff000); + *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0xfffff) | ((lo12 & 0xfff) << 20)); + } + break; + case R_RISCV_LO12_S: + { + grub_int32_t lo12 = (grub_int32_t) sym_addr - (((grub_int32_t) sym_addr + 0x800) & 0xfffff000); + grub_uint32_t imm11_5 = (lo12 & 0xfe0) << (31 - 11); + grub_uint32_t imm4_0 = (lo12 & 0x1f) << (11 - 4); + *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0x1fff07f) | imm11_5 | imm4_0); + } + break; + case R_RISCV_RELAX: + break; + default: + grub_util_error (_("relocation 0x%x is not implemented yet"), + (unsigned int) ELF_R_TYPE (info)); + break; + } + break; + } + default: + grub_util_error ("unknown architecture type %d", + image_target->elf_target); + } + } + } +} + +/* Add a PE32's fixup entry for a relocation. Return the resulting address + after having written to the file OUT. */ +static Elf_Addr +add_fixup_entry (struct fixup_block_list **cblock, grub_uint16_t type, + Elf_Addr addr, int flush, Elf_Addr current_address, + const struct grub_install_image_target_desc *image_target) +{ + struct grub_pe32_fixup_block *b; + + b = &((*cblock)->b); + + /* First, check if it is necessary to write out the current block. */ + if ((*cblock)->state) + { + if (flush || (type && (addr < b->page_rva || b->page_rva + 0x1000 <= addr))) + { + grub_uint32_t size; + + if (flush) + { + /* Add as much padding as necessary to align the address + with a section boundary. */ + Elf_Addr next_address; + unsigned padding_size; + size_t cur_index; + + next_address = current_address + b->block_size; + padding_size = ((ALIGN_UP (next_address, image_target->section_align) + - next_address) + >> 1); + cur_index = ((b->block_size - sizeof (*b)) >> 1); + grub_util_info ("adding %d padding fixup entries", padding_size); + while (padding_size--) + { + b->entries[cur_index++] = 0; + b->block_size += 2; + } + } + else while (b->block_size & (8 - 1)) + { + /* If not aligned with a 32-bit boundary, add + a padding entry. */ + size_t cur_index; + + grub_util_info ("adding a padding fixup entry"); + cur_index = ((b->block_size - sizeof (*b)) >> 1); + b->entries[cur_index] = 0; + b->block_size += 2; + } + + /* Flush it. */ + grub_util_info ("writing %d bytes of a fixup block starting at 0x%x", + b->block_size, b->page_rva); + size = b->block_size; + current_address += size; + b->page_rva = grub_host_to_target32 (b->page_rva); + b->block_size = grub_host_to_target32 (b->block_size); + (*cblock)->next = xmalloc (sizeof (**cblock) + 2 * 0x1000); + memset ((*cblock)->next, 0, sizeof (**cblock) + 2 * 0x1000); + *cblock = (*cblock)->next; + } + } + + b = &((*cblock)->b); + + if (! flush) + { + grub_uint16_t entry; + size_t cur_index; + + /* If not allocated yet, allocate a block with enough entries. */ + if (! (*cblock)->state) + { + (*cblock)->state = 1; + + /* The spec does not mention the requirement of a Page RVA. + Here, align the address with a 4K boundary for safety. */ + if (type) + b->page_rva = (addr & ~(0x1000 - 1)); + b->block_size = sizeof (*b); + } + + /* Sanity check. */ + if (b->block_size >= sizeof (*b) + 2 * 0x1000) + grub_util_error ("too many fixup entries"); + + /* Add a new entry. */ + cur_index = ((b->block_size - sizeof (*b)) >> 1); + entry = GRUB_PE32_FIXUP_ENTRY (type, type ? (addr - b->page_rva) : addr); + b->entries[cur_index] = grub_host_to_target16 (entry); + b->block_size += 2; + } + + return current_address; +} + +struct raw_reloc +{ + struct raw_reloc *next; + grub_uint32_t offset; + enum raw_reloc_type { + RAW_RELOC_NONE = -1, + RAW_RELOC_32 = 0, + RAW_RELOC_MAX = 1, + } type; +}; + +struct translate_context +{ + /* PE */ + struct fixup_block_list *lst, *lst0; + Elf_Addr current_address; + + /* Raw */ + struct raw_reloc *raw_relocs; +}; + +static void +translate_reloc_start (struct translate_context *ctx, + const struct grub_install_image_target_desc *image_target) +{ + grub_memset (ctx, 0, sizeof (*ctx)); + if (image_target->id == IMAGE_EFI) + { + ctx->lst = ctx->lst0 = xmalloc (sizeof (*ctx->lst) + 2 * 0x1000); + memset (ctx->lst, 0, sizeof (*ctx->lst) + 2 * 0x1000); + ctx->current_address = 0; + } +} + +static void +translate_relocation_pe (struct translate_context *ctx, + Elf_Addr addr, + Elf_Addr info, + Elf_Addr sym_addr, + Elf_Addr addend, + const struct grub_install_image_target_desc *image_target) +{ + /* Necessary to relocate only absolute addresses. */ + switch (image_target->elf_target) + { + case EM_386: + if (ELF_R_TYPE (info) == R_386_32) + { + grub_util_info ("adding a relocation entry for 0x%" + GRUB_HOST_PRIxLONG_LONG, + (unsigned long long) addr); + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_HIGHLOW, + addr, 0, ctx->current_address, + image_target); + } + break; + case EM_X86_64: + if ((ELF_R_TYPE (info) == R_X86_64_32) || + (ELF_R_TYPE (info) == R_X86_64_32S)) + { + grub_util_error ("can\'t add fixup entry for R_X86_64_32(S)"); + } + else if (ELF_R_TYPE (info) == R_X86_64_64) + { + grub_util_info ("adding a relocation entry for 0x%" + GRUB_HOST_PRIxLONG_LONG, + (unsigned long long) addr); + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_DIR64, + addr, + 0, ctx->current_address, + image_target); + } + break; + case EM_IA_64: + switch (ELF_R_TYPE (info)) + { + case R_IA64_PCREL64LSB: + case R_IA64_LDXMOV: + case R_IA64_PCREL21B: + case R_IA64_LTOFF_FPTR22: + case R_IA64_LTOFF22X: + case R_IA64_LTOFF22: + case R_IA64_GPREL22: + case R_IA64_GPREL64I: + case R_IA64_SEGREL64LSB: + break; + + case R_IA64_FPTR64LSB: + case R_IA64_DIR64LSB: +#if 1 + { + grub_util_info ("adding a relocation entry for 0x%" + GRUB_HOST_PRIxLONG_LONG, + (unsigned long long) addr); + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_DIR64, + addr, + 0, ctx->current_address, + image_target); + } +#endif + break; + default: + grub_util_error (_("relocation 0x%x is not implemented yet"), + (unsigned int) ELF_R_TYPE (info)); + break; + } + break; + case EM_AARCH64: + switch (ELF_R_TYPE (info)) + { + case R_AARCH64_ABS64: + { + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_DIR64, + addr, 0, ctx->current_address, + image_target); + } + break; + /* Relative relocations do not require fixup entries. */ + case R_AARCH64_CALL26: + case R_AARCH64_JUMP26: + case R_AARCH64_PREL32: + break; + /* Page-relative relocations do not require fixup entries. */ + case R_AARCH64_ADR_PREL_PG_HI21: + /* We page-align the whole kernel, so no need + for fixup entries. + */ + case R_AARCH64_ADD_ABS_LO12_NC: + case R_AARCH64_LDST64_ABS_LO12_NC: + break; + + /* GOT is relocated separately. */ + case R_AARCH64_ADR_GOT_PAGE: + case R_AARCH64_LD64_GOT_LO12_NC: + break; + + default: + grub_util_error (_("relocation 0x%x is not implemented yet"), + (unsigned int) ELF_R_TYPE (info)); + break; + } + break; +#if defined(MKIMAGE_ELF64) + case EM_MIPS: + switch (ELF_R_TYPE (info)) + { + case R_MIPS_64: + { + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_DIR64, + addr, 0, ctx->current_address, + image_target); + } + break; + case R_MIPS_32: +#if 0 + { + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_HIGHLOW, + addr, 0, ctx->current_address, + image_target); + } +#endif + break; + case R_MIPS_26: + { + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_MIPS_JMPADDR, + addr, 0, ctx->current_address, + image_target); + } + break; + case R_MIPS_LO16: + { + Elf_Addr target = sym_addr + addend; + + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_MIPS_LOW, + addr, 0, ctx->current_address, + image_target); + /* Hi */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_int16_t) ((target & 0x8000UL) >> 16), + 0, ctx->current_address, + image_target); + /* Higher */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_int16_t) ((target & 0x80008000UL) >> 32), + 0, ctx->current_address, + image_target); + /* Highest */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_uint16_t) ((target & 0x800080008000UL) >> 48), + 0, ctx->current_address, + image_target); + } + break; + case R_MIPS_HI16: + { + Elf_Addr target = sym_addr + addend; + + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_MIPS_HIGH, + addr, 0, ctx->current_address, + image_target); + /* Lo */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_int16_t) target, + 0, ctx->current_address, + image_target); + /* Higher */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_int16_t) ((target & 0x80008000UL) >> 32), + 0, ctx->current_address, + image_target); + /* Highest */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_uint16_t) ((target & 0x800080008000UL) >> 48), + 0, ctx->current_address, + image_target); + } + break; + case R_MIPS_HIGHER: + { + Elf_Addr target = sym_addr + addend; + + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_MIPS_HIGHER, + addr, 0, ctx->current_address, + image_target); + /* Lo */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_int16_t) target, + 0, ctx->current_address, + image_target); + /* Hi */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_int16_t) ((target & 0x8000UL) >> 16), + 0, ctx->current_address, + image_target); + /* Highest */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_uint16_t) ((target & 0x800080008000UL) >> 48), + 0, ctx->current_address, + image_target); + } + break; + case R_MIPS_HIGHEST: + { + Elf_Addr target = sym_addr + addend; + + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_MIPS_HIGHEST, + addr, 0, ctx->current_address, + image_target); + /* Lo */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_int16_t) target, + 0, ctx->current_address, + image_target); + /* Hi */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_int16_t) ((target & 0x8000UL) >> 16), + 0, ctx->current_address, + image_target); + /* Higher */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_int16_t) ((target & 0x80008000UL) >> 32), + 0, ctx->current_address, + image_target); + } + break; + default: + grub_util_error (_("relocation 0x%x is not implemented yet"), + (unsigned int) ELF_R_TYPE (info)); + break; + } + break; +#endif +#if defined(MKIMAGE_ELF32) + case EM_ARM: + switch (ELF_R_TYPE (info)) + { + case R_ARM_V4BX: + /* Relative relocations do not require fixup entries. */ + case R_ARM_JUMP24: + case R_ARM_THM_CALL: + case R_ARM_THM_JUMP19: + case R_ARM_THM_JUMP24: + case R_ARM_CALL: + { + grub_util_info (" %s: not adding fixup: 0x%08x : 0x%08x", __FUNCTION__, (unsigned int) addr, (unsigned int) ctx->current_address); + } + break; + /* Create fixup entry for PE/COFF loader */ + case R_ARM_ABS32: + { + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_HIGHLOW, + addr, 0, ctx->current_address, + image_target); + } + break; + default: + grub_util_error (_("relocation 0x%x is not implemented yet"), + (unsigned int) ELF_R_TYPE (info)); + break; + } + break; +#endif /* defined(MKIMAGE_ELF32) */ + case EM_RISCV: + switch (ELF_R_TYPE (info)) + { + case R_RISCV_32: + { + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_HIGHLOW, + addr, 0, ctx->current_address, + image_target); + } + break; + case R_RISCV_64: + { + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_DIR64, + addr, 0, ctx->current_address, + image_target); + } + break; + /* Relative relocations do not require fixup entries. */ + case R_RISCV_BRANCH: + case R_RISCV_JAL: + case R_RISCV_CALL: + case R_RISCV_PCREL_HI20: + case R_RISCV_PCREL_LO12_I: + case R_RISCV_PCREL_LO12_S: + case R_RISCV_RVC_BRANCH: + case R_RISCV_RVC_JUMP: + case R_RISCV_ADD32: + case R_RISCV_SUB32: + grub_util_info (" %s: not adding fixup: 0x%08x : 0x%08x", __FUNCTION__, (unsigned int) addr, (unsigned int) ctx->current_address); + break; + case R_RISCV_HI20: + { + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_RISCV_HI20, + addr, 0, ctx->current_address, + image_target); + } + break; + case R_RISCV_LO12_I: + { + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_RISCV_LOW12I, + addr, 0, ctx->current_address, + image_target); + } + break; + case R_RISCV_LO12_S: + { + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_RISCV_LOW12S, + addr, 0, ctx->current_address, + image_target); + } + break; + case R_RISCV_RELAX: + break; + default: + grub_util_error (_("relocation 0x%x is not implemented yet"), + (unsigned int) ELF_R_TYPE (info)); + break; + } + break; + default: + grub_util_error ("unknown machine type 0x%x", image_target->elf_target); + } +} + +static enum raw_reloc_type +classify_raw_reloc (Elf_Addr info, + const struct grub_install_image_target_desc *image_target) +{ + /* Necessary to relocate only absolute addresses. */ + switch (image_target->elf_target) + { + case EM_ARM: + switch (ELF_R_TYPE (info)) + { + case R_ARM_V4BX: + case R_ARM_JUMP24: + case R_ARM_THM_CALL: + case R_ARM_THM_JUMP19: + case R_ARM_THM_JUMP24: + case R_ARM_CALL: + return RAW_RELOC_NONE; + case R_ARM_ABS32: + return RAW_RELOC_32; + default: + grub_util_error (_("relocation 0x%x is not implemented yet"), + (unsigned int) ELF_R_TYPE (info)); + break; + } + break; + default: + grub_util_error ("unknown machine type 0x%x", image_target->elf_target); + } +} + +static void +translate_relocation_raw (struct translate_context *ctx, + Elf_Addr addr, + Elf_Addr info, + const struct grub_install_image_target_desc *image_target) +{ + enum raw_reloc_type class = classify_raw_reloc (info, image_target); + struct raw_reloc *rel; + if (class == RAW_RELOC_NONE) + return; + rel = xmalloc (sizeof (*rel)); + rel->next = ctx->raw_relocs; + rel->type = class; + rel->offset = addr; + ctx->raw_relocs = rel; +} + +static void +translate_relocation (struct translate_context *ctx, + Elf_Addr addr, + Elf_Addr info, + Elf_Addr sym_addr, + Elf_Addr addend, + const struct grub_install_image_target_desc *image_target) +{ + if (image_target->id == IMAGE_EFI) + translate_relocation_pe (ctx, addr, info, sym_addr, addend, image_target); + else + translate_relocation_raw (ctx, addr, info, image_target); +} + +static void +finish_reloc_translation_pe (struct translate_context *ctx, struct grub_mkimage_layout *layout, + const struct grub_install_image_target_desc *image_target) +{ + ctx->current_address = add_fixup_entry (&ctx->lst, 0, 0, 1, ctx->current_address, image_target); + + { + grub_uint8_t *ptr; + layout->reloc_section = ptr = xmalloc (ctx->current_address); + for (ctx->lst = ctx->lst0; ctx->lst; ctx->lst = ctx->lst->next) + if (ctx->lst->state) + { + memcpy (ptr, &ctx->lst->b, grub_target_to_host32 (ctx->lst->b.block_size)); + ptr += grub_target_to_host32 (ctx->lst->b.block_size); + } + assert ((ctx->current_address + (grub_uint8_t *) layout->reloc_section) == ptr); + } + + for (ctx->lst = ctx->lst0; ctx->lst; ) + { + struct fixup_block_list *next; + next = ctx->lst->next; + free (ctx->lst); + ctx->lst = next; + } + + layout->reloc_size = ctx->current_address; + if (image_target->elf_target == EM_ARM && layout->reloc_size > GRUB_KERNEL_ARM_STACK_SIZE) + grub_util_error ("Reloc section (%d) is bigger than stack size (%d). " + "This breaks assembly assumptions. Please increase stack size", + (int) layout->reloc_size, + (int) GRUB_KERNEL_ARM_STACK_SIZE); +} + +/* + Layout: + + + + + ... + + + each relocation starts with 32-bit offset. Rest depends on relocation. + mkimage stops when it sees first unknown type or end marker. + This allows images to be created with mismatched mkimage and + kernel as long as no relocations are present in kernel that mkimage + isn't aware of (in which case mkimage aborts). + This also allows simple assembly to do the relocs. +*/ + +#define RAW_SEPARATOR 0xfffffffe +#define RAW_END_MARKER 0xffffffff + +static void +finish_reloc_translation_raw (struct translate_context *ctx, struct grub_mkimage_layout *layout, + const struct grub_install_image_target_desc *image_target) +{ + size_t count = 0, sz; + enum raw_reloc_type highest = RAW_RELOC_NONE; + enum raw_reloc_type curtype; + struct raw_reloc *cur; + grub_uint32_t *p; + if (!ctx->raw_relocs) + { + layout->reloc_section = p = xmalloc (sizeof (grub_uint32_t)); + p[0] = RAW_END_MARKER; + layout->reloc_size = sizeof (grub_uint32_t); + return; + } + for (cur = ctx->raw_relocs; cur; cur = cur->next) + { + count++; + if (cur->type > highest) + highest = cur->type; + } + /* highest separators, count relocations and one end marker. */ + sz = (highest + count + 1) * sizeof (grub_uint32_t); + layout->reloc_section = p = xmalloc (sz); + for (curtype = 0; curtype <= highest; curtype++) + { + /* Support for special cases would go here. */ + for (cur = ctx->raw_relocs; cur; cur = cur->next) + if (cur->type == curtype) + { + *p++ = cur->offset; + } + *p++ = RAW_SEPARATOR; + } + *--p = RAW_END_MARKER; + layout->reloc_size = sz; +} + +static void +finish_reloc_translation (struct translate_context *ctx, struct grub_mkimage_layout *layout, + const struct grub_install_image_target_desc *image_target) +{ + if (image_target->id == IMAGE_EFI) + finish_reloc_translation_pe (ctx, layout, image_target); + else + finish_reloc_translation_raw (ctx, layout, image_target); +} + + +static void +create_u64_fixups (struct translate_context *ctx, + Elf_Addr jumpers, grub_size_t njumpers, + const struct grub_install_image_target_desc *image_target) +{ + unsigned i; + assert (image_target->id == IMAGE_EFI); + for (i = 0; i < njumpers; i++) + ctx->current_address = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_DIR64, + jumpers + 8 * i, + 0, ctx->current_address, + image_target); +} + +/* Make a .reloc section. */ +static void +make_reloc_section (Elf_Ehdr *e, struct grub_mkimage_layout *layout, + struct section_metadata *smd, + const struct grub_install_image_target_desc *image_target) +{ + unsigned i; + Elf_Shdr *s; + struct translate_context ctx; + + translate_reloc_start (&ctx, image_target); + + for (i = 0, s = smd->sections; i < smd->num_sections; + i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize)) + if ((grub_target_to_host32 (s->sh_type) == SHT_REL) || + (grub_target_to_host32 (s->sh_type) == SHT_RELA)) + { + Elf_Rela *r; + Elf_Word rtab_size, r_size, num_rs; + Elf_Off rtab_offset; + Elf_Shdr *symtab_section; + Elf_Addr section_address; + Elf_Word j; + + if (!SUFFIX (is_kept_reloc_section) (s, image_target, smd)) + { + grub_util_info ("not translating the skipped relocation section %s", + smd->strtab + grub_le_to_cpu32 (s->sh_name)); + continue; + } + + symtab_section = (Elf_Shdr *) ((char *) smd->sections + + (grub_target_to_host32 (s->sh_link) + * smd->section_entsize)); + + grub_util_info ("translating the relocation section %s", + smd->strtab + grub_le_to_cpu32 (s->sh_name)); + + rtab_size = grub_target_to_host (s->sh_size); + r_size = grub_target_to_host (s->sh_entsize); + rtab_offset = grub_target_to_host (s->sh_offset); + num_rs = rtab_size / r_size; + + section_address = smd->vaddrs[grub_le_to_cpu32 (s->sh_info)]; + + for (j = 0, r = (Elf_Rela *) ((char *) e + rtab_offset); + j < num_rs; + j++, r = (Elf_Rela *) ((char *) r + r_size)) + { + Elf_Addr info; + Elf_Addr offset; + Elf_Addr addr; + Elf_Addr sym_addr; + Elf_Addr addend; + + offset = grub_target_to_host (r->r_offset); + if (image_target->elf_target == EM_MIPS && image_target->voidp_sizeof == 8) + info = ((grub_uint64_t) r->r_info << 32) | + (grub_uint32_t) grub_be_to_cpu64 (r->r_info); + else + info = grub_target_to_host (r->r_info); + + sym_addr = SUFFIX (get_symbol_address) (e, symtab_section, + ELF_R_SYM (info), image_target); + addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ? + grub_target_to_host (r->r_addend) : 0; + addr = section_address + offset; + + translate_relocation (&ctx, addr, info, sym_addr, addend, image_target); + } + } + + if (image_target->elf_target == EM_IA_64) + create_u64_fixups (&ctx, + layout->ia64jmp_off + + image_target->vaddr_offset, + 2 * layout->ia64jmpnum, + image_target); + if (image_target->elf_target == EM_IA_64 || image_target->elf_target == EM_AARCH64) + create_u64_fixups (&ctx, + layout->got_off + + image_target->vaddr_offset, + (layout->got_size / 8), + image_target); + + finish_reloc_translation (&ctx, layout, image_target); +} + +/* Determine if this section is a text section. Return false if this + section is not allocated. */ +static int +SUFFIX (is_text_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target) +{ + if (!is_relocatable (image_target) + && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) + return 0; + return ((grub_target_to_host (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) + == (SHF_EXECINSTR | SHF_ALLOC)); +} + +/* Determine if this section is a data section. */ +static int +SUFFIX (is_data_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target) +{ + if (!is_relocatable (image_target) + && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) + return 0; + return ((grub_target_to_host (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) + == SHF_ALLOC) && !(grub_target_to_host32 (s->sh_type) == SHT_NOBITS); +} + +static int +SUFFIX (is_bss_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target) +{ + if (!is_relocatable (image_target)) + return 0; + return ((grub_target_to_host (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) + == SHF_ALLOC) && (grub_target_to_host32 (s->sh_type) == SHT_NOBITS); +} + +/* Determine if a section is going to be in the final output */ +static int +SUFFIX (is_kept_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target) +{ + /* We keep .text and .data */ + if (SUFFIX (is_text_section) (s, image_target) + || SUFFIX (is_data_section) (s, image_target)) + return 1; + + /* + * And we keep .bss if we're producing PE binaries or the target doesn't + * have a relocating loader. Platforms other than EFI and U-boot shouldn't + * have .bss in their binaries as we build with -Wl,-Ttext. + */ + if (SUFFIX (is_bss_section) (s, image_target) + && (image_target->id == IMAGE_EFI || !is_relocatable (image_target))) + return 1; + + /* Otherwise this is not a section we're keeping in the final output. */ + return 0; +} + +static int +SUFFIX (is_kept_reloc_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target, + struct section_metadata *smd) +{ + int i; + int r = 0; + const char *name = smd->strtab + grub_host_to_target32 (s->sh_name); + + if (!strncmp (name, ".rela.", 6)) + name += 5; + else if (!strncmp (name, ".rel.", 5)) + name += 4; + else + return 1; + + for (i = 0, s = smd->sections; i < smd->num_sections; + i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize)) + { + const char *sname = smd->strtab + grub_host_to_target32 (s->sh_name); + if (strcmp (sname, name)) + continue; + + return SUFFIX (is_kept_section) (s, image_target); + } + + return r; +} + +/* Return if the ELF header is valid. */ +static int +SUFFIX (check_elf_header) (Elf_Ehdr *e, size_t size, const struct grub_install_image_target_desc *image_target) +{ + if (size < sizeof (*e) + || e->e_ident[EI_MAG0] != ELFMAG0 + || e->e_ident[EI_MAG1] != ELFMAG1 + || e->e_ident[EI_MAG2] != ELFMAG2 + || e->e_ident[EI_MAG3] != ELFMAG3 + || e->e_ident[EI_VERSION] != EV_CURRENT + || e->e_ident[EI_CLASS] != ELFCLASSXX + || e->e_version != grub_host_to_target32 (EV_CURRENT)) + return 0; + + return 1; +} + +static Elf_Addr +SUFFIX (put_section) (Elf_Shdr *s, int i, + Elf_Addr current_address, + struct section_metadata *smd, + const struct grub_install_image_target_desc *image_target) +{ + Elf_Word align = grub_host_to_target_addr (s->sh_addralign); + const char *name = smd->strtab + grub_host_to_target32 (s->sh_name); + + if (align) + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + align) + - image_target->vaddr_offset; + + grub_util_info ("locating the section %s at 0x%" + GRUB_HOST_PRIxLONG_LONG, + name, (unsigned long long) current_address); + if (!is_relocatable (image_target)) + current_address = grub_host_to_target_addr (s->sh_addr) + - image_target->link_addr; + smd->addrs[i] = current_address; + current_address += grub_host_to_target_addr (s->sh_size); + return current_address; +} + +/* + * Locate section addresses by merging code sections and data sections + * into .text and .data, respectively. + */ +static void +SUFFIX (locate_sections) (Elf_Ehdr *e, const char *kernel_path, + struct section_metadata *smd, + struct grub_mkimage_layout *layout, + const struct grub_install_image_target_desc *image_target) +{ + int i; + Elf_Shdr *s; + + layout->align = 1; + /* Page-aligning simplifies relocation handling. */ + if (image_target->elf_target == EM_AARCH64) + layout->align = 4096; + + layout->kernel_size = 0; + + for (i = 0, s = smd->sections; + i < smd->num_sections; + i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize)) + if ((grub_target_to_host (s->sh_flags) & SHF_ALLOC) + && grub_host_to_target32 (s->sh_addralign) > layout->align) + layout->align = grub_host_to_target32 (s->sh_addralign); + + /* .text */ + for (i = 0, s = smd->sections; + i < smd->num_sections; + i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize)) + if (SUFFIX (is_text_section) (s, image_target)) + { + layout->kernel_size = SUFFIX (put_section) (s, i, layout->kernel_size, + smd, image_target); + if (!is_relocatable (image_target) && + grub_host_to_target_addr (s->sh_addr) != image_target->link_addr) + { + char *msg + = grub_xasprintf (_("`%s' is miscompiled: its start address is 0x%llx" + " instead of 0x%llx: ld.gold bug?"), + kernel_path, + (unsigned long long) grub_host_to_target_addr (s->sh_addr), + (unsigned long long) image_target->link_addr); + grub_util_error ("%s", msg); + } + } + +#ifdef MKIMAGE_ELF32 + if (image_target->elf_target == EM_ARM) + { + grub_size_t tramp; + + layout->kernel_size = ALIGN_UP (layout->kernel_size, 16); + + tramp = arm_get_trampoline_size (e, smd->sections, smd->section_entsize, + smd->num_sections, image_target); + + layout->tramp_off = layout->kernel_size; + layout->kernel_size += ALIGN_UP (tramp, 16); + } +#endif + + layout->kernel_size = ALIGN_UP (layout->kernel_size + image_target->vaddr_offset, + image_target->section_align) + - image_target->vaddr_offset; + layout->exec_size = layout->kernel_size; + + /* .data */ + for (i = 0, s = smd->sections; + i < smd->num_sections; + i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize)) + if (SUFFIX (is_data_section) (s, image_target)) + layout->kernel_size = SUFFIX (put_section) (s, i, layout->kernel_size, smd, + image_target); + + layout->bss_start = layout->kernel_size; + layout->end = layout->kernel_size; + + /* .bss */ + for (i = 0, s = smd->sections; + i < smd->num_sections; + i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize)) + { + if (SUFFIX (is_bss_section) (s, image_target)) + layout->end = SUFFIX (put_section) (s, i, layout->end, smd, image_target); + + /* + * This must to be in the last time this function passes through the loop. + */ + smd->vaddrs[i] = smd->addrs[i] + image_target->vaddr_offset; + } + + layout->end = ALIGN_UP (layout->end + image_target->vaddr_offset, + image_target->section_align) - image_target->vaddr_offset; + /* Explicitly initialize BSS + when producing PE32 to avoid a bug in EFI implementations. + Platforms other than EFI and U-boot shouldn't have .bss in + their binaries as we build with -Wl,-Ttext. + */ + if (image_target->id == IMAGE_EFI || !is_relocatable (image_target)) + layout->kernel_size = layout->end; +} + +char * +SUFFIX (grub_mkimage_load_image) (const char *kernel_path, + size_t total_module_size, + struct grub_mkimage_layout *layout, + const struct grub_install_image_target_desc *image_target) +{ + char *kernel_img, *out_img; + struct section_metadata smd = { 0, 0, 0, 0, 0, 0, 0 }; + Elf_Ehdr *e; + int i; + Elf_Shdr *s; + Elf_Off section_offset; + grub_size_t kernel_size; + + grub_memset (layout, 0, sizeof (*layout)); + + layout->start_address = 0; + + kernel_size = grub_util_get_image_size (kernel_path); + kernel_img = xmalloc (kernel_size); + grub_util_load_image (kernel_path, kernel_img); + + e = (Elf_Ehdr *) kernel_img; + if (! SUFFIX (check_elf_header) (e, kernel_size, image_target)) + grub_util_error ("invalid ELF header"); + + section_offset = grub_target_to_host (e->e_shoff); + smd.section_entsize = grub_target_to_host16 (e->e_shentsize); + smd.num_sections = grub_target_to_host16 (e->e_shnum); + + if (kernel_size < section_offset + + (grub_uint32_t) smd.section_entsize * smd.num_sections) + grub_util_error (_("premature end of file %s"), kernel_path); + + smd.sections = (Elf_Shdr *) (kernel_img + section_offset); + + /* Relocate sections then symbols in the virtual address space. */ + s = (Elf_Shdr *) ((char *) smd.sections + + grub_host_to_target16 (e->e_shstrndx) * smd.section_entsize); + smd.strtab = (char *) e + grub_host_to_target_addr (s->sh_offset); + + smd.addrs = xmalloc (sizeof (*smd.addrs) * smd.num_sections); + memset (smd.addrs, 0, sizeof (*smd.addrs) * smd.num_sections); + smd.vaddrs = xmalloc (sizeof (*smd.vaddrs) * smd.num_sections); + memset (smd.vaddrs, 0, sizeof (*smd.vaddrs) * smd.num_sections); + + SUFFIX (locate_sections) (e, kernel_path, &smd, layout, image_target); + + if (!is_relocatable (image_target)) + { + Elf_Addr current_address = layout->kernel_size; + + for (i = 0, s = smd.sections; + i < smd.num_sections; + i++, s = (Elf_Shdr *) ((char *) s + smd.section_entsize)) + if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) + { + Elf_Word sec_align = grub_host_to_target_addr (s->sh_addralign); + const char *name = smd.strtab + grub_host_to_target32 (s->sh_name); + + if (sec_align) + current_address = ALIGN_UP (current_address + + image_target->vaddr_offset, + sec_align) + - image_target->vaddr_offset; + + grub_util_info ("locating the section %s at 0x%" + GRUB_HOST_PRIxLONG_LONG, + name, (unsigned long long) current_address); + if (!is_relocatable (image_target)) + current_address = grub_host_to_target_addr (s->sh_addr) + - image_target->link_addr; + + smd.vaddrs[i] = current_address + + image_target->vaddr_offset; + current_address += grub_host_to_target_addr (s->sh_size); + } + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + image_target->section_align) + - image_target->vaddr_offset; + layout->bss_size = current_address - layout->kernel_size; + } + else + layout->bss_size = 0; + + if (image_target->id == IMAGE_SPARC64_AOUT + || image_target->id == IMAGE_SPARC64_RAW + || image_target->id == IMAGE_UBOOT + || image_target->id == IMAGE_COREBOOT + || image_target->id == IMAGE_SPARC64_CDCORE) + layout->kernel_size = ALIGN_UP (layout->kernel_size, image_target->mod_align); + + if (is_relocatable (image_target)) + { + smd.symtab = NULL; + for (i = 0, s = smd.sections; + i < smd.num_sections; + i++, s = (Elf_Shdr *) ((char *) s + smd.section_entsize)) + if (s->sh_type == grub_host_to_target32 (SHT_SYMTAB)) + { + smd.symtab = s; + break; + } + if (! smd.symtab) + grub_util_error ("%s", _("no symbol table")); +#ifdef MKIMAGE_ELF64 + if (image_target->elf_target == EM_IA_64) + { + grub_size_t tramp; + + layout->kernel_size = ALIGN_UP (layout->kernel_size, 16); + + grub_ia64_dl_get_tramp_got_size (e, &tramp, &layout->got_size); + + layout->tramp_off = layout->kernel_size; + layout->kernel_size += ALIGN_UP (tramp, 16); + + layout->ia64jmp_off = layout->kernel_size; + layout->ia64jmpnum = SUFFIX (count_funcs) (e, smd.symtab, + image_target); + layout->kernel_size += 16 * layout->ia64jmpnum; + + layout->got_off = layout->kernel_size; + layout->kernel_size += ALIGN_UP (layout->got_size, 16); + } + if (image_target->elf_target == EM_AARCH64) + { + grub_size_t tramp; + + layout->kernel_size = ALIGN_UP (layout->kernel_size, 16); + + grub_arm64_dl_get_tramp_got_size (e, &tramp, &layout->got_size); + + layout->got_off = layout->kernel_size; + layout->kernel_size += ALIGN_UP (layout->got_size, 16); + } +#endif + } + else + { + layout->reloc_size = 0; + layout->reloc_section = NULL; + } + + out_img = xmalloc (layout->kernel_size + total_module_size); + memset (out_img, 0, layout->kernel_size + total_module_size); + + if (is_relocatable (image_target)) + { + layout->start_address = SUFFIX (relocate_symbols) (e, &smd, + (char *) out_img + layout->ia64jmp_off, + layout->ia64jmp_off + image_target->vaddr_offset, + layout->bss_start, layout->end, image_target); + + if (layout->start_address == (Elf_Addr) -1) + grub_util_error ("start symbol is not defined"); + + /* Resolve addrs in the virtual address space. */ + SUFFIX (relocate_addrs) (e, &smd, out_img, layout->tramp_off, + layout->got_off, image_target); + + make_reloc_section (e, layout, &smd, image_target); + if (image_target->id != IMAGE_EFI) + { + out_img = xrealloc (out_img, layout->kernel_size + total_module_size + + ALIGN_UP (layout->reloc_size, image_target->mod_align)); + memcpy (out_img + layout->kernel_size, layout->reloc_section, layout->reloc_size); + memset (out_img + layout->kernel_size + layout->reloc_size, 0, + total_module_size + ALIGN_UP (layout->reloc_size, image_target->mod_align) - layout->reloc_size); + layout->kernel_size += ALIGN_UP (layout->reloc_size, image_target->mod_align); + } + } + + for (i = 0, s = smd.sections; + i < smd.num_sections; + i++, s = (Elf_Shdr *) ((char *) s + smd.section_entsize)) + if (SUFFIX (is_kept_section) (s, image_target)) + { + if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) + memset (out_img + smd.addrs[i], 0, + grub_host_to_target_addr (s->sh_size)); + else + memcpy (out_img + smd.addrs[i], + kernel_img + grub_host_to_target_addr (s->sh_offset), + grub_host_to_target_addr (s->sh_size)); + } + free (kernel_img); + + free (smd.vaddrs); + smd.vaddrs = NULL; + free (smd.addrs); + smd.addrs = NULL; + + return out_img; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/util/grub-mknetdir.c b/GRUB2/MOD_SRC/grub-2.04/util/grub-mknetdir.c new file mode 100644 index 0000000..4db1e53 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/util/grub-mknetdir.c @@ -0,0 +1,225 @@ +/* + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2013 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . +*/ + +#include + +#include +#include +#include + +#include +#include + +#pragma GCC diagnostic ignored "-Wmissing-prototypes" +#pragma GCC diagnostic ignored "-Wmissing-declarations" +#include +#pragma GCC diagnostic error "-Wmissing-prototypes" +#pragma GCC diagnostic error "-Wmissing-declarations" + +static char *rootdir = NULL, *subdir = NULL; +static char *debug_image = NULL; + +enum + { + OPTION_NET_DIRECTORY = 0x301, + OPTION_SUBDIR, + OPTION_DEBUG, + OPTION_DEBUG_IMAGE + }; + +static struct argp_option options[] = { + GRUB_INSTALL_OPTIONS, + {"net-directory", OPTION_NET_DIRECTORY, N_("DIR"), + 0, N_("root directory of TFTP server"), 2}, + {"subdir", OPTION_SUBDIR, N_("DIR"), + 0, N_("relative subdirectory on network server"), 2}, + {"debug", OPTION_DEBUG, 0, OPTION_HIDDEN, 0, 2}, + {"debug-image", OPTION_DEBUG_IMAGE, N_("STRING"), OPTION_HIDDEN, 0, 2}, + {0, 0, 0, 0, 0, 0} +}; + +static error_t +argp_parser (int key, char *arg, struct argp_state *state) +{ + if (grub_install_parse (key, arg)) + return 0; + switch (key) + { + case OPTION_NET_DIRECTORY: + free (rootdir); + rootdir = xstrdup (arg); + return 0; + case OPTION_SUBDIR: + free (subdir); + subdir = xstrdup (arg); + return 0; + /* This is an undocumented feature... */ + case OPTION_DEBUG: + verbosity++; + return 0; + case OPTION_DEBUG_IMAGE: + free (debug_image); + debug_image = xstrdup (arg); + return 0; + + case ARGP_KEY_ARG: + default: + return ARGP_ERR_UNKNOWN; + } +} + + +struct argp argp = { + options, argp_parser, NULL, + "\v"N_("Prepares GRUB network boot images at net_directory/subdir " + "assuming net_directory being TFTP root."), + NULL, grub_install_help_filter, NULL +}; + +static char *base; + +static const struct +{ + const char *mkimage_target; + const char *netmodule; + const char *ext; +} targets[GRUB_INSTALL_PLATFORM_MAX] = + { + [GRUB_INSTALL_PLATFORM_I386_PC] = { "i386-pc-pxe", "pxe", ".0" }, + [GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275] = { "sparc64-ieee1275-aout", "ofnet", ".img" }, + [GRUB_INSTALL_PLATFORM_I386_IEEE1275] = { "i386-ieee1275", "ofnet", ".elf" }, + [GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275] = { "powerpc-ieee1275", "ofnet", ".elf" }, + [GRUB_INSTALL_PLATFORM_I386_EFI] = { "i386-efi", "efinet", ".efi" }, + [GRUB_INSTALL_PLATFORM_X86_64_EFI] = { "x86_64-efi", "efinet", ".efi" }, + [GRUB_INSTALL_PLATFORM_IA64_EFI] = { "ia64-efi", "efinet", ".efi" }, + [GRUB_INSTALL_PLATFORM_ARM_EFI] = { "arm-efi", "efinet", ".efi" }, + [GRUB_INSTALL_PLATFORM_ARM64_EFI] = { "arm64-efi", "efinet", ".efi" }, + [GRUB_INSTALL_PLATFORM_MIPS64EL_EFI] = { "mips64el-efi", "efinet", ".efi" }, + [GRUB_INSTALL_PLATFORM_RISCV32_EFI] = { "riscv32-efi", "efinet", ".efi" }, + [GRUB_INSTALL_PLATFORM_RISCV64_EFI] = { "riscv64-efi", "efinet", ".efi" }, + }; + +static void +process_input_dir (const char *input_dir, enum grub_install_plat platform) +{ + char *platsub = grub_install_get_platform_name (platform); + char *grubdir = grub_util_path_concat (3, rootdir, subdir, platsub); + char *load_cfg = grub_util_path_concat (2, grubdir, "load.cfg"); + char *prefix; + char *output; + char *grub_cfg; + FILE *cfg; + + grub_install_copy_files (input_dir, base, platform); + grub_util_unlink (load_cfg); + + if (debug_image) + { + FILE *f = grub_util_fopen (load_cfg, "wb"); + if (!f) + grub_util_error (_("cannot open `%s': %s"), load_cfg, + strerror (errno)); + fprintf (f, "set debug='%s'\n", debug_image); + fclose (f); + } + else + { + free (load_cfg); + load_cfg = 0; + } + + prefix = xasprintf ("/%s", subdir); + if (!targets[platform].mkimage_target) + grub_util_error (_("unsupported platform %s"), platsub); + + grub_cfg = grub_util_path_concat (2, grubdir, "grub.cfg"); + cfg = grub_util_fopen (grub_cfg, "wb"); + if (!cfg) + grub_util_error (_("cannot open `%s': %s"), grub_cfg, + strerror (errno)); + fprintf (cfg, "source %s/grub.cfg", subdir); + fclose (cfg); + + grub_install_push_module (targets[platform].netmodule); + + output = grub_util_path_concat_ext (2, grubdir, "core", targets[platform].ext); + grub_install_make_image_wrap (input_dir, prefix, output, + 0, load_cfg, + targets[platform].mkimage_target, 0); + grub_install_pop_module (); + + /* TRANSLATORS: First %s is replaced by platform name. Second one by filename. */ + printf (_("Netboot directory for %s created. Configure your DHCP server to point to %s\n"), + platsub, output); + + free (platsub); + free (output); + free (prefix); + free (grub_cfg); + free (grubdir); +} + + +int +main (int argc, char *argv[]) +{ + const char *pkglibdir; + + grub_util_host_init (&argc, &argv); + grub_util_disable_fd_syncs (); + rootdir = xstrdup ("/srv/tftp"); + pkglibdir = grub_util_get_pkglibdir (); + + subdir = grub_util_path_concat (2, GRUB_BOOT_DIR_NAME, GRUB_DIR_NAME); + + argp_parse (&argp, argc, argv, 0, 0, 0); + + base = grub_util_path_concat (2, rootdir, subdir); + /* Create the GRUB directory if it is not present. */ + + grub_install_mkdir_p (base); + + grub_install_push_module ("tftp"); + + if (!grub_install_source_directory) + { + enum grub_install_plat plat; + + for (plat = 0; plat < GRUB_INSTALL_PLATFORM_MAX; plat++) + if (targets[plat].mkimage_target) + { + char *platdir = grub_util_path_concat (2, pkglibdir, + grub_install_get_platform_name (plat)); + + grub_util_info ("Looking for `%s'", platdir); + + if (!grub_util_is_directory (platdir)) + { + free (platdir); + continue; + } + process_input_dir (platdir, plat); + } + } + else + { + enum grub_install_plat plat; + plat = grub_install_get_target (grub_install_source_directory); + process_input_dir (grub_install_source_directory, plat); + } + return 0; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/util/grub-mkrescue.c b/GRUB2/MOD_SRC/grub-2.04/util/grub-mkrescue.c new file mode 100644 index 0000000..190ebe4 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/util/grub-mkrescue.c @@ -0,0 +1,1003 @@ +/* + * Make GRUB rescue image + * + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include + +#include +#include +#include +#include +#include +#pragma GCC diagnostic ignored "-Wmissing-prototypes" +#pragma GCC diagnostic ignored "-Wmissing-declarations" +#include +#pragma GCC diagnostic error "-Wmissing-prototypes" +#pragma GCC diagnostic error "-Wmissing-declarations" + +#include +#include + +#include +#include + +static char *source_dirs[GRUB_INSTALL_PLATFORM_MAX]; +static char *rom_directory; +static char *label_font; +static char *label_color; +static char *label_bgcolor; +static char *product_name; +static char *product_version; +static char *output_image; +static char *xorriso; +static char *boot_grub; +static int xorriso_argc; +static int xorriso_arg_alloc; +static char **xorriso_argv; +static char *iso_uuid; +static char *iso9660_dir; + +static void +xorriso_push (const char *val) +{ + if (xorriso_arg_alloc <= xorriso_argc + 1) + { + xorriso_arg_alloc = 2 * (4 + xorriso_argc); + xorriso_argv = xrealloc (xorriso_argv, + sizeof (xorriso_argv[0]) + * xorriso_arg_alloc); + } + xorriso_argv[xorriso_argc++] = xstrdup (val); +} + +static void +xorriso_link (const char *from, const char *to) +{ + char *tof = grub_util_path_concat (2, iso9660_dir, to); + char *val = xasprintf ("%s=%s", from, tof); + xorriso_push (val); + free (val); + free (tof); +} + +enum + { + OPTION_OUTPUT = 'o', + OPTION_ROM_DIRECTORY = 0x301, + OPTION_XORRISO, + OPTION_GLUE_EFI, + OPTION_RENDER_LABEL, + OPTION_LABEL_FONT, + OPTION_LABEL_COLOR, + OPTION_LABEL_BGCOLOR, + OPTION_PRODUCT_NAME, + OPTION_PRODUCT_VERSION, + OPTION_SPARC_BOOT, + OPTION_ARCS_BOOT + }; + +static struct argp_option options[] = { + GRUB_INSTALL_OPTIONS, + {"output", 'o', N_("FILE"), + 0, N_("save output in FILE [required]"), 2}, + {"rom-directory", OPTION_ROM_DIRECTORY, N_("DIR"), + 0, N_("save ROM images in DIR [optional]"), 2}, + {"xorriso", OPTION_XORRISO, N_("FILE"), + /* TRANSLATORS: xorriso is a program for creating ISOs and burning CDs. */ + 0, N_("use FILE as xorriso [optional]"), 2}, + {"grub-glue-efi", OPTION_GLUE_EFI, N_("FILE"), OPTION_HIDDEN, 0, 2}, + {"grub-render-label", OPTION_RENDER_LABEL, N_("FILE"), OPTION_HIDDEN, 0, 2}, + {"label-font", OPTION_LABEL_FONT, N_("FILE"), 0, N_("use FILE as font for label"), 2}, + {"label-color", OPTION_LABEL_COLOR, N_("COLOR"), 0, N_("use COLOR for label"), 2}, + {"label-bgcolor", OPTION_LABEL_BGCOLOR, N_("COLOR"), 0, N_("use COLOR for label background"), 2}, + {"product-name", OPTION_PRODUCT_NAME, N_("STRING"), 0, N_("use STRING as product name"), 2}, + {"product-version", OPTION_PRODUCT_VERSION, N_("STRING"), 0, N_("use STRING as product version"), 2}, + {"sparc-boot", OPTION_SPARC_BOOT, 0, 0, N_("enable sparc boot. Disables HFS+, APM, ARCS and boot as disk image for i386-pc"), 2}, + {"arcs-boot", OPTION_ARCS_BOOT, 0, 0, N_("enable ARCS (big-endian mips machines, mostly SGI) boot. Disables HFS+, APM, sparc64 and boot as disk image for i386-pc"), 2}, + {0, 0, 0, 0, 0, 0} +}; + +#pragma GCC diagnostic ignored "-Wformat-nonliteral" + +static char * +help_filter (int key, const char *text, void *input __attribute__ ((unused))) +{ + switch (key) + { + case ARGP_KEY_HELP_PRE_DOC: + /* TRANSLATORS: it generates one single image which is bootable through any method. */ + return strdup (_("Make GRUB CD-ROM, disk, pendrive and floppy bootable image.")); + case ARGP_KEY_HELP_POST_DOC: + { + char *p1, *out; + + p1 = xasprintf (_("Generates a bootable CD/USB/floppy image. Arguments other than options to this program" + " are passed to xorriso, and indicate source files, source directories, or any of the " + "mkisofs options listed by the output of `%s'."), "xorriso -as mkisofs -help"); + out = xasprintf ("%s\n\n%s\n\n%s", p1, + _("Option -- switches to native xorriso command mode."), + _("Mail xorriso support requests to .")); + free (p1); + return out; + } + default: + return grub_install_help_filter (key, text, input); + } +} + +#pragma GCC diagnostic error "-Wformat-nonliteral" + +enum { + SYS_AREA_AUTO, + SYS_AREA_COMMON, + SYS_AREA_SPARC, + SYS_AREA_ARCS +} system_area = SYS_AREA_AUTO; + +static error_t +argp_parser (int key, char *arg, struct argp_state *state) +{ + if (grub_install_parse (key, arg)) + return 0; + switch (key) + { + case OPTION_OUTPUT: + free (output_image); + output_image = xstrdup (arg); + return 0; + case OPTION_ROM_DIRECTORY: + free (rom_directory); + rom_directory = xstrdup (arg); + return 0; + + /* + FIXME: + # Intentionally undocumented + --grub-mkimage-extra) + mkimage_extra_arg="$mkimage_extra_arg `argument $option "$@"`"; shift ;; + --grub-mkimage-extra=*) + mkimage_extra_arg="$mkimage_extra_arg `echo "$option" | sed 's/--grub-mkimage-extra=//'`" ;; + */ + case OPTION_SPARC_BOOT: + system_area = SYS_AREA_SPARC; + return 0; + case OPTION_ARCS_BOOT: + system_area = SYS_AREA_ARCS; + return 0; + case OPTION_PRODUCT_NAME: + free (product_name); + product_name = xstrdup (arg); + return 0; + case OPTION_PRODUCT_VERSION: + free (product_version); + product_version = xstrdup (arg); + return 0; + /* Accept and ignore for compatibility. */ + case OPTION_GLUE_EFI: + case OPTION_RENDER_LABEL: + return 0; + case OPTION_LABEL_FONT: + free (label_font); + label_font = xstrdup (arg); + return 0; + + case OPTION_LABEL_COLOR: + free (label_color); + label_color = xstrdup (arg); + return 0; + + case OPTION_LABEL_BGCOLOR: + free (label_bgcolor); + label_bgcolor = xstrdup (arg); + return 0; + + case OPTION_XORRISO: + free (xorriso); + xorriso = xstrdup (arg); + return 0; + + default: + return ARGP_ERR_UNKNOWN; + } +} + +struct argp argp = { + options, argp_parser, N_("[OPTION] SOURCE..."), + NULL, NULL, help_filter, NULL +}; + +static void +write_part (FILE *f, const char *srcdir) +{ + FILE *in; + char *inname = grub_util_path_concat (2, srcdir, "partmap.lst"); + char buf[260]; + in = grub_util_fopen (inname, "rb"); + if (!in) + return; + while (fgets (buf, 256, in)) + { + char *ptr; + for (ptr = buf + strlen (buf) - 1; + ptr >= buf && (*ptr == '\n' || *ptr == '\r'); + ptr--); + ptr[1] = '\0'; + fprintf (f, "insmod %s\n", buf); + } + fclose (in); +} + +static void +make_image_abs (enum grub_install_plat plat, + const char *mkimage_target, + const char *output) +{ + char *load_cfg; + FILE *load_cfg_f; + + if (!source_dirs[plat]) + return; + + grub_util_info (N_("enabling %s support ..."), + mkimage_target); + + load_cfg = grub_util_make_temporary_file (); + + load_cfg_f = grub_util_fopen (load_cfg, "wb"); + fprintf (load_cfg_f, "search --fs-uuid --set=root %s\n", iso_uuid); + fprintf (load_cfg_f, "set prefix=(${root})/boot/grub\n"); + + write_part (load_cfg_f, source_dirs[plat]); + fclose (load_cfg_f); + + grub_install_push_module ("search"); + grub_install_push_module ("iso9660"); + grub_install_make_image_wrap (source_dirs[plat], "/boot/grub", output, + 0, load_cfg, + mkimage_target, 0); + grub_install_pop_module (); + grub_install_pop_module (); + grub_util_unlink (load_cfg); +} + +static void +make_image (enum grub_install_plat plat, + const char *mkimage_target, + const char *output_sub) +{ + char *out = grub_util_path_concat (2, boot_grub, output_sub); + make_image_abs (plat, mkimage_target, out); + free (out); +} + +static void +make_image_fwdisk_abs (enum grub_install_plat plat, + const char *mkimage_target, + const char *output) +{ + char *load_cfg; + FILE *load_cfg_f; + + if (!source_dirs[plat]) + return; + + grub_util_info (N_("enabling %s support ..."), + mkimage_target); + + load_cfg = grub_util_make_temporary_file (); + + load_cfg_f = grub_util_fopen (load_cfg, "wb"); + write_part (load_cfg_f, source_dirs[plat]); + fclose (load_cfg_f); + + grub_install_push_module ("iso9660"); + grub_install_make_image_wrap (source_dirs[plat], "()/boot/grub", output, + 0, load_cfg, mkimage_target, 0); + grub_install_pop_module (); + grub_util_unlink (load_cfg); +} + +static int +check_xorriso (const char *val) +{ + const char *argv[5]; + int fd; + pid_t pid; + FILE *mdadm; + char *buf = NULL; + size_t len = 0; + int ret = 0; + int wstatus = 0; + + argv[0] = xorriso; + argv[1] = "-as"; + argv[2] = "mkisofs"; + argv[3] = "-help"; + argv[4] = NULL; + + pid = grub_util_exec_pipe_stderr (argv, &fd); + + if (!pid) + return 0; + + /* Parent. Read mdadm's output. */ + mdadm = fdopen (fd, "r"); + if (! mdadm) + return 0; + + while (getline (&buf, &len, mdadm) > 0) + { + if (grub_strstr (buf, val)) + ret = 1; + } + + close (fd); + waitpid (pid, &wstatus, 0); + free (buf); + if (!WIFEXITED (wstatus) || WEXITSTATUS(wstatus) != 0) + return 0; + return ret; +} + +static void +make_image_fwdisk (enum grub_install_plat plat, + const char *mkimage_target, + const char *output_sub) +{ + char *out = grub_util_path_concat (2, boot_grub, output_sub); + make_image_fwdisk_abs (plat, mkimage_target, out); + free (out); +} + +static int +option_is_end (const struct argp_option *opt) +{ + return !opt->key && !opt->name && !opt->doc && !opt->group; +} + + +static int +args_to_eat (const char *arg) +{ + int j; + + if (arg[0] != '-') + return 0; + + if (arg[1] == '-') + { + for (j = 0; !option_is_end(&options[j]); j++) + { + size_t len = strlen (options[j].name); + if (strncmp (arg + 2, options[j].name, len) == 0) + { + if (arg[2 + len] == '=') + return 1; + if (arg[2 + len] == '\0' && options[j].arg) + return 2; + if (arg[2 + len] == '\0') + return 1; + } + } + if (strcmp (arg, "--help") == 0) + return 1; + if (strcmp (arg, "--usage") == 0) + return 1; + if (strcmp (arg, "--version") == 0) + return 1; + return 0; + } + if (arg[2] && arg[3]) + return 0; + for (j = 0; !option_is_end(&options[j]); j++) + { + if (options[j].key > 0 && options[j].key < 128 && arg[1] == options[j].key) + { + if (options[j].arg) + return 2; + return 1; + } + if (arg[1] == '?') + return 1; + } + return 0; +} + +int +main (int argc, char *argv[]) +{ + char *romdir; + char *sysarea_img = NULL; + const char *pkgdatadir; + int argp_argc; + char **argp_argv; + int xorriso_tail_argc; + char **xorriso_tail_argv; + int rv; + + grub_util_host_init (&argc, &argv); + grub_util_disable_fd_syncs (); + + pkgdatadir = grub_util_get_pkgdatadir (); + + product_name = xstrdup (PACKAGE_NAME); + product_version = xstrdup (PACKAGE_VERSION); + xorriso = xstrdup ("xorriso"); + label_font = grub_util_path_concat (2, pkgdatadir, "unicode.pf2"); + + argp_argv = xmalloc (sizeof (argp_argv[0]) * argc); + xorriso_tail_argv = xmalloc (sizeof (argp_argv[0]) * argc); + + xorriso_tail_argc = 0; + /* Program name */ + argp_argv[0] = argv[0]; + argp_argc = 1; + + /* argp doesn't allow us to catch unknwon arguments, + so catch them before passing to argp + */ + { + int i; + for (i = 1; i < argc; i++) + { + if (strcmp (argv[i], "-output") == 0) { + argp_argv[argp_argc++] = (char *) "--output"; + i++; + argp_argv[argp_argc++] = argv[i]; + continue; + } + switch (args_to_eat (argv[i])) + { + case 2: + argp_argv[argp_argc++] = argv[i++]; + /* Fallthrough */ + case 1: + argp_argv[argp_argc++] = argv[i]; + break; + case 0: + xorriso_tail_argv[xorriso_tail_argc++] = argv[i]; + break; + } + } + } + + argp_parse (&argp, argp_argc, argp_argv, 0, 0, 0); + + if (!output_image) + grub_util_error ("%s", _("output file must be specified")); + + if (!check_xorriso ("graft-points")) { + grub_util_error ("%s", _("xorriso not found")); + } + + grub_init_all (); + grub_hostfs_init (); + grub_host_init (); + + xorriso_push (xorriso); + xorriso_push ("-as"); + xorriso_push ("mkisofs"); + xorriso_push ("-graft-points"); + + iso9660_dir = grub_util_make_temporary_dir (); + grub_util_info ("temporary iso9660 dir is `%s'", iso9660_dir); + boot_grub = grub_util_path_concat (3, iso9660_dir, "boot", "grub"); + grub_install_mkdir_p (boot_grub); + romdir = grub_util_path_concat (2, boot_grub, "roms"); + grub_util_mkdir (romdir); + + if (!grub_install_source_directory) + { + const char *pkglibdir = grub_util_get_pkglibdir (); + enum grub_install_plat plat; + + for (plat = 0; plat < GRUB_INSTALL_PLATFORM_MAX; plat++) + { + char *platdir = grub_util_path_concat (2, pkglibdir, + grub_install_get_platform_name (plat)); + + if (!grub_util_is_directory (platdir)) + { + free (platdir); + continue; + } + source_dirs[plat] = platdir; + grub_install_copy_files (platdir, + boot_grub, plat); + } + } + else + { + enum grub_install_plat plat; + plat = grub_install_get_target (grub_install_source_directory); + grub_install_copy_files (grub_install_source_directory, + boot_grub, plat); + source_dirs[plat] = xstrdup (grub_install_source_directory); + } + if (system_area == SYS_AREA_AUTO || grub_install_source_directory) + { + if (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC] + || source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275] + || source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_IA64_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_ARM_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_ARM64_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_MIPS64EL_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_RISCV32_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_RISCV64_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI]) + system_area = SYS_AREA_COMMON; + else if (source_dirs[GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275]) + system_area = SYS_AREA_SPARC; + else if (source_dirs[GRUB_INSTALL_PLATFORM_MIPS_ARC]) + system_area = SYS_AREA_ARCS; + } + + /* obtain date-based UUID. */ + { + time_t tim; + struct tm *tmm; + tim = time (NULL); + tmm = gmtime (&tim); + iso_uuid = xmalloc (55); + grub_snprintf (iso_uuid, 50, + "%04d-%02d-%02d-%02d-%02d-%02d-00", + tmm->tm_year + 1900, + tmm->tm_mon + 1, + tmm->tm_mday, + tmm->tm_hour, + tmm->tm_min, + tmm->tm_sec); + } + { + char *uuid_out = xmalloc (strlen (iso_uuid) + 1 + 40); + char *optr; + const char *iptr; + optr = grub_stpcpy (uuid_out, "--modification-date="); + for (iptr = iso_uuid; *iptr; iptr++) + if (*iptr != '-') + *optr++ = *iptr; + *optr = '\0'; + xorriso_push (uuid_out); + free (uuid_out); + } + + /* build BIOS core.img. */ + if (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC]) + { + char *load_cfg; + FILE *load_cfg_f; + char *output = grub_util_path_concat (3, boot_grub, "i386-pc", "eltorito.img"); + load_cfg = grub_util_make_temporary_file (); + + grub_util_info (N_("enabling %s support ..."), "BIOS"); + load_cfg_f = grub_util_fopen (load_cfg, "wb"); + write_part (load_cfg_f, source_dirs[GRUB_INSTALL_PLATFORM_I386_PC]); + fclose (load_cfg_f); + + grub_install_push_module ("biosdisk"); + grub_install_push_module ("iso9660"); + grub_install_make_image_wrap (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC], + "/boot/grub", output, + 0, load_cfg, + "i386-pc-eltorito", 0); + + xorriso_push ("-b"); + xorriso_push ("boot/grub/i386-pc/eltorito.img"); + xorriso_push ("-no-emul-boot"); + xorriso_push ("-boot-load-size"); + xorriso_push ("4"); + xorriso_push ("-boot-info-table"); + if (system_area == SYS_AREA_COMMON) + { + if (check_xorriso ("grub2-boot-info")) + { + char *boot_hybrid = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_I386_PC], + "boot_hybrid.img"); + xorriso_push ("--grub2-boot-info"); + xorriso_push ("--grub2-mbr"); + xorriso_push (boot_hybrid); + } + else + { + FILE *sa, *bi; + size_t sz; + char buf[512]; + char *bin = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_I386_PC], + "boot.img"); + grub_util_warn ("%s", _("Your xorriso doesn't support `--grub2-boot-info'. Some features are disabled. Please use xorriso 1.2.9 or later.")); + sysarea_img = grub_util_make_temporary_file (); + sa = grub_util_fopen (sysarea_img, "wb"); + if (!sa) + grub_util_error (_("cannot open `%s': %s"), sysarea_img, + strerror (errno)); + bi = grub_util_fopen (bin, "rb"); + if (!bi) + grub_util_error (_("cannot open `%s': %s"), bin, + strerror (errno)); + if (fread (buf, 1, 512, bi) != 512) + grub_util_error (_("cannot read `%s': %s"), bin, + strerror (errno)); + fclose (bi); + fwrite (buf, 1, 512, sa); + + grub_install_make_image_wrap_file (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC], + "/boot/grub", sa, sysarea_img, + 0, load_cfg, + "i386-pc", 0); + sz = ftello (sa); + fflush (sa); + grub_util_fd_sync (fileno (sa)); + fclose (sa); + + if (sz > 32768) + { + grub_util_warn ("%s", _("Your xorriso doesn't support `--grub2-boot-info'. Your core image is too big. Boot as disk is disabled. Please use xorriso 1.2.9 or later.")); + } + else + { + xorriso_push ("-G"); + xorriso_push (sysarea_img); + } + } + } + grub_install_pop_module (); + grub_install_pop_module (); + grub_util_unlink (load_cfg); + } + + /** build multiboot core.img */ + grub_install_push_module ("pata"); + grub_install_push_module ("ahci"); + grub_install_push_module ("at_keyboard"); + make_image (GRUB_INSTALL_PLATFORM_I386_MULTIBOOT, "i386-multiboot", "i386-multiboot/core.elf"); + grub_install_pop_module (); + grub_install_pop_module (); + grub_install_pop_module (); + + make_image_fwdisk (GRUB_INSTALL_PLATFORM_I386_IEEE1275, "i386-ieee1275", "ofwx86.elf"); + + char *core_services = NULL; + + if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275]) + { + char *mach_ker, *sv, *label, *label_text; + FILE *f; + core_services = grub_util_path_concat (4, iso9660_dir, "System", "Library", "CoreServices"); + grub_install_mkdir_p (core_services); + + mach_ker = grub_util_path_concat (2, iso9660_dir, "mach_kernel"); + f = grub_util_fopen (mach_ker, "wb"); + fclose (f); + free (mach_ker); + + sv = grub_util_path_concat (2, core_services, "SystemVersion.plist"); + f = grub_util_fopen (sv, "wb"); + fprintf (f, "\n" + "\n" + " ProductBuildVersion\n" + " \n" + " ProductName\n" + " %s\n" + " ProductVersion\n" + " %s\n" + "\n" + "\n", product_name, product_version); + fclose (f); + free (sv); + label = grub_util_path_concat (2, core_services, ".disk_label"); + char *label_string = xasprintf ("%s %s", product_name, product_version); + grub_util_render_label (label_font, label_bgcolor ? : "white", + label_color ? : "black", label_string, label); + free (label); + label_text = grub_util_path_concat (2, core_services, ".disk_label.contentDetails"); + f = grub_util_fopen (label_text, "wb"); + fprintf (f, "%s\n", label_string); + fclose (f); + free (label_string); + free (label_text); + if (system_area == SYS_AREA_COMMON) + { + xorriso_push ("-hfsplus"); + xorriso_push ("-apm-block-size"); + xorriso_push ("2048"); + xorriso_push ("-hfsplus-file-creator-type"); + xorriso_push ("chrp"); + xorriso_push ("tbxj"); + xorriso_push ("/System/Library/CoreServices/.disk_label"); + + if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI]) + { + xorriso_push ("-hfs-bless-by"); + xorriso_push ("i"); + xorriso_push ("/System/Library/CoreServices/boot.efi"); + } + } + } + + if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_IA64_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_ARM_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_ARM64_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_MIPS64EL_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_RISCV32_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_RISCV64_EFI]) + { + char *efidir = grub_util_make_temporary_dir (); + char *efidir_efi = grub_util_path_concat (2, efidir, "efi"); + char *efidir_efi_boot = grub_util_path_concat (3, efidir, "efi", "boot"); + char *imgname, *img32, *img64, *img_mac = NULL; + char *efiimgfat; + grub_install_mkdir_p (efidir_efi_boot); + + grub_install_push_module ("part_gpt"); + grub_install_push_module ("part_msdos"); + + imgname = grub_util_path_concat (2, efidir_efi_boot, "bootia64.efi"); + make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_IA64_EFI, "ia64-efi", imgname); + free (imgname); + + grub_install_push_module ("part_apple"); + img64 = grub_util_path_concat (2, efidir_efi_boot, "bootx64.efi"); + make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_X86_64_EFI, "x86_64-efi", img64); + grub_install_pop_module (); + + grub_install_push_module ("part_apple"); + img32 = grub_util_path_concat (2, efidir_efi_boot, "bootia32.efi"); + make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_I386_EFI, "i386-efi", img32); + grub_install_pop_module (); + + imgname = grub_util_path_concat (2, efidir_efi_boot, "bootarm.efi"); + make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_ARM_EFI, "arm-efi", imgname); + free (imgname); + + imgname = grub_util_path_concat (2, efidir_efi_boot, "bootaa64.efi"); + make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_ARM64_EFI, "arm64-efi", + imgname); + free (imgname); + + imgname = grub_util_path_concat (2, efidir_efi_boot, "bootmips64el.efi"); + make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_MIPS64EL_EFI, "mips64el-efi", + imgname); + free (imgname); + + imgname = grub_util_path_concat (2, efidir_efi_boot, "bootriscv32.efi"); + make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_RISCV32_EFI, "riscv32-efi", + imgname); + free (imgname); + + imgname = grub_util_path_concat (2, efidir_efi_boot, "bootriscv64.efi"); + make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_RISCV64_EFI, "riscv64-efi", + imgname); + free (imgname); + + if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI]) + { + imgname = grub_util_path_concat (2, efidir_efi_boot, "boot.efi"); + /* For old macs. Suggested by Peter Jones. */ + grub_install_copy_file (img32, imgname, 1); + } + + if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI]) + img_mac = grub_util_path_concat (2, core_services, "boot.efi"); + + if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI] + && source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI]) + grub_util_glue_efi (img32, img64, img_mac); + else if (source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI]) + grub_install_copy_file (img64, img_mac, 1); + else if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI]) + grub_install_copy_file (img32, img_mac, 1); + + free (img_mac); + free (img32); + free (img64); + free (efidir_efi_boot); + + efiimgfat = grub_util_path_concat (2, iso9660_dir, "efi.img"); + rv = grub_util_exec ((const char * []) { "mformat", "-C", "-f", "2880", "-L", "16", "-i", + efiimgfat, "::", NULL }); + if (rv != 0) + grub_util_error ("`%s` invocation failed\n", "mformat"); + rv = grub_util_exec ((const char * []) { "mcopy", "-s", "-i", efiimgfat, efidir_efi, "::/", NULL }); + if (rv != 0) + grub_util_error ("`%s` invocation failed\n", "mcopy"); + xorriso_push ("--efi-boot"); + xorriso_push ("efi.img"); + xorriso_push ("-efi-boot-part"); + xorriso_push ("--efi-boot-image"); + + grub_util_unlink_recursive (efidir); + free (efiimgfat); + free (efidir_efi); + free (efidir); + grub_install_pop_module (); + grub_install_pop_module (); + } + + grub_install_push_module ("part_apple"); + make_image_fwdisk (GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275, "powerpc-ieee1275", "powerpc-ieee1275/core.elf"); + grub_install_pop_module (); + + if (source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275]) + { + char *grub_chrp = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275], + "grub.chrp"); + char *bisrc = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275], + "bootinfo.txt"); + char *bootx = grub_util_path_concat (2, core_services, "BootX"); + char *ppc_chrp = grub_util_path_concat (3, iso9660_dir, "ppc", "chrp"); + char *bitgt = grub_util_path_concat (3, iso9660_dir, "ppc", "bootinfo.txt"); + grub_install_copy_file (grub_chrp, bootx, 1); + grub_install_mkdir_p (ppc_chrp); + grub_install_copy_file (bisrc, bitgt, 1); + xorriso_link ("/System/Library/CoreServices/grub.elf", "/boot/grub/powerpc-ieee1275/core.elf"); + xorriso_link ("/boot/grub/powerpc.elf", "/boot/grub/powerpc-ieee1275/core.elf"); + /* FIXME: add PreP */ + if (system_area == SYS_AREA_COMMON) + { + xorriso_push ("-hfsplus-file-creator-type"); + xorriso_push ("chrp"); + xorriso_push ("tbxi"); + xorriso_push ("/System/Library/CoreServices/BootX"); + xorriso_push ("-hfs-bless-by"); + xorriso_push ("p"); + xorriso_push ("/System/Library/CoreServices"); + } + xorriso_push ("-sysid"); + xorriso_push ("PPC"); + } + + make_image_fwdisk (GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275, + "sparc64-ieee1275-cdcore", "sparc64-ieee1275/core.img"); + + if (source_dirs[GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275] + && system_area == SYS_AREA_SPARC) + { + char *cdboot; + FILE *in, *out; + char buf[512]; + sysarea_img = grub_util_make_temporary_file (); + cdboot = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275], + "cdboot.img"); + in = grub_util_fopen (cdboot, "rb"); + if (!in) + grub_util_error (_("cannot open `%s': %s"), cdboot, + strerror (errno)); + out = grub_util_fopen (sysarea_img, "wb"); + if (!out) + grub_util_error (_("cannot open `%s': %s"), sysarea_img, + strerror (errno)); + memset (buf, 0, 512); + fwrite (buf, 1, 512, out); + if (fread (buf, 1, 512, in) != 512) + grub_util_error (_("cannot read `%s': %s"), cdboot, + strerror (errno)); + fwrite (buf, 1, 512, out); + fclose (in); + fclose (out); + xorriso_push ("-G"); + xorriso_push (sysarea_img); + xorriso_push ("-B"); + xorriso_push (","); + xorriso_push ("--grub2-sparc-core"); + xorriso_push ("/boot/grub/sparc64-ieee1275/core.img"); + } + + make_image_fwdisk (GRUB_INSTALL_PLATFORM_MIPS_ARC, "mips-arc", "mips-arc/core.img"); + + if (source_dirs[GRUB_INSTALL_PLATFORM_MIPS_ARC]) + { + xorriso_link ("/boot/grub/mips-arc/grub", "/boot/grub/mips-arc/core.img"); + xorriso_link ("/boot/grub/mips-arc/sashARCS", "/boot/grub/mips-arc/core.img"); + xorriso_link ("/boot/grub/mips-arc/sash", "/boot/grub/mips-arc/core.img"); + } + if (source_dirs[GRUB_INSTALL_PLATFORM_MIPS_ARC] && system_area == SYS_AREA_ARCS) + { + xorriso_push ("-mips-boot"); + xorriso_push ("/boot/grub/mips-arc/sashARCS"); + xorriso_push ("-mips-boot"); + xorriso_push ("/boot/grub/mips-arc/sash"); + xorriso_push ("-mips-boot"); + xorriso_push ("/boot/grub/mips-arc/grub"); + } + + make_image_fwdisk (GRUB_INSTALL_PLATFORM_MIPSEL_ARC, "mipsel-arc", "arc.exe"); + + grub_install_push_module ("pata"); + make_image (GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS, "mipsel-qemu_mips-elf", "roms/mipsel-qemu_mips.elf"); + + make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-loongson-elf", "loongson.elf"); + + make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-yeeloong-flash", "mipsel-yeeloong.bin"); + make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-fuloong2f-flash", "mipsel-fuloong2f.bin"); + + make_image (GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS, "mips-qemu_mips-elf", "roms/mips-qemu_mips.elf"); + + grub_install_push_module ("at_keyboard"); + + make_image (GRUB_INSTALL_PLATFORM_I386_QEMU, "i386-qemu", "roms/qemu.img"); + + grub_install_push_module ("ahci"); + + make_image (GRUB_INSTALL_PLATFORM_I386_COREBOOT, "i386-coreboot", "roms/coreboot.elf"); + grub_install_pop_module (); + grub_install_pop_module (); + grub_install_pop_module (); + + if (rom_directory) + { + const struct + { + enum grub_install_plat plat; + const char *from, *to; + } roms[] = + { + {GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS, "roms/mipsel-qemu_mips.elf", "mipsel-qemu_mips.elf"}, + {GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "loongson.elf", "mipsel-loongson.elf"}, + {GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "roms/mipsel-yeeloong.bin", "mipsel-yeeloong.bin"}, + {GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "roms/mipsel-fulong.bin", "mipsel-fulong.bin"}, + {GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS, "roms/mips-qemu_mips.elf", "mips-qemu_mips.elf"}, + {GRUB_INSTALL_PLATFORM_I386_QEMU, "roms/qemu.img", "qemu.img"}, + {GRUB_INSTALL_PLATFORM_I386_COREBOOT, "roms/coreboot.elf", "coreboot.elf"}, + }; + grub_size_t i; + for (i = 0; i < ARRAY_SIZE (roms); i++) + { + char *from = grub_util_path_concat (2, boot_grub, roms[i].from); + char *to = grub_util_path_concat (2, rom_directory, roms[i].to); + grub_install_copy_file (from, to, 0); + } + } + + xorriso_push ("--protective-msdos-label"); + xorriso_push ("-o"); + xorriso_push (output_image); + xorriso_push ("-r"); + xorriso_push (iso9660_dir); + xorriso_push ("--sort-weight"); + xorriso_push ("0"); + xorriso_push ("/"); + xorriso_push ("--sort-weight"); + xorriso_push ("1"); + xorriso_push ("/boot"); + int i; + for (i = 0; i < xorriso_tail_argc; i++) + xorriso_push (xorriso_tail_argv[i]); + + xorriso_argv[xorriso_argc] = NULL; + + rv = grub_util_exec ((const char *const *)xorriso_argv); + if (rv != 0) + grub_util_error ("`%s` invocation failed\n", "xorriso"); + + grub_util_unlink_recursive (iso9660_dir); + + if (sysarea_img) + grub_util_unlink (sysarea_img); + + free (core_services); + free (romdir); + return 0; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/util/grub-module-verifier.c b/GRUB2/MOD_SRC/grub-2.04/util/grub-module-verifier.c new file mode 100644 index 0000000..c1c053d --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/util/grub-module-verifier.c @@ -0,0 +1,247 @@ +#include +#include + +#include +#include +#include +#include + +struct grub_module_verifier_arch archs[] = { + { "i386", 4, 0, EM_386, GRUB_MODULE_VERIFY_SUPPORTS_REL, (int[]){ + R_386_32, + R_386_PC32, + -1 + } }, + { "x86_64", 8, 0, EM_X86_64, GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){ + R_X86_64_64, + R_X86_64_PC64, + /* R_X86_64_32, R_X86_64_32S are supported but shouldn't be used because of their limited range. */ + -1 + }, (int[]){ + R_X86_64_PC32, + R_X86_64_PLT32, + -1 + } + }, + { "powerpc", 4, 1, EM_PPC, GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){ + GRUB_ELF_R_PPC_ADDR16_LO, + GRUB_ELF_R_PPC_REL24, /* It has limited range but GRUB adds trampolines when necessarry. */ + GRUB_ELF_R_PPC_ADDR16_HA, + GRUB_ELF_R_PPC_ADDR32, + GRUB_ELF_R_PPC_REL32, + GRUB_ELF_R_PPC_PLTREL24, + -1 + } }, + { "sparc64", 8, 1, EM_SPARCV9, GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){ + R_SPARC_WDISP30, /* It has limited range but GRUB adds trampolines when necessarry. */ + R_SPARC_HH22, + R_SPARC_HM10, + R_SPARC_LM22, + R_SPARC_LO10, + R_SPARC_64, + R_SPARC_OLO10, + /* Following 2 relocations have limited range but unfortunately + clang generates them, as it doesn't implement mcmodel=large properly. + At least our heap and core are under 4G, so it's not a problem + usually. */ + R_SPARC_HI22, + R_SPARC_32, + -1 + } }, + { "ia64", 8, 0, EM_IA_64, GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){ + R_IA64_PCREL21B, /* We should verify that it's pointing either + to a function or to a section in the same module. + Checking that external symbol is a function is + non-trivial and I have never seen this relocation used + for anything else, so assume that it always points to a + function. + */ + R_IA64_SEGREL64LSB, + R_IA64_FPTR64LSB, + R_IA64_DIR64LSB, + R_IA64_PCREL64LSB, + R_IA64_LTOFF22X, + R_IA64_LTOFF22, + R_IA64_GPREL64I, + R_IA64_LTOFF_FPTR22, + R_IA64_LDXMOV, + -1 + }, (int[]){ + R_IA64_GPREL22, + -1 + } }, + { "mipsel", 4, 0, EM_MIPS, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){ + R_MIPS_HI16, + R_MIPS_LO16, + R_MIPS_32, + R_MIPS_GPREL32, + R_MIPS_26, + R_MIPS_GOT16, + R_MIPS_CALL16, + R_MIPS_JALR, + -1 + } }, + { "mips", 4, 1, EM_MIPS, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){ + R_MIPS_HI16, + R_MIPS_LO16, + R_MIPS_32, + R_MIPS_GPREL32, + R_MIPS_26, + R_MIPS_GOT16, + R_MIPS_CALL16, + R_MIPS_JALR, + -1 + } }, + { "arm", 4, 0, EM_ARM, GRUB_MODULE_VERIFY_SUPPORTS_REL, (int[]){ + /* Some relocations are range-limited but trampolines are added when necessarry. */ + R_ARM_ABS32, + R_ARM_CALL, + R_ARM_JUMP24, + R_ARM_THM_CALL, + R_ARM_THM_JUMP24, + R_ARM_V4BX, + R_ARM_THM_MOVW_ABS_NC, + R_ARM_THM_MOVT_ABS, + R_ARM_THM_JUMP19, + -1 + } }, + { "arm64", 8, 0, EM_AARCH64, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){ + R_AARCH64_ABS64, + R_AARCH64_CALL26, + R_AARCH64_JUMP26, + R_AARCH64_ADR_GOT_PAGE, + R_AARCH64_LD64_GOT_LO12_NC, + -1 + }, (int[]){ + R_AARCH64_ADR_PREL_PG_HI21, + R_AARCH64_ADD_ABS_LO12_NC, + R_AARCH64_LDST64_ABS_LO12_NC, + R_AARCH64_PREL32, + -1 + } }, + { "mips64el", 8, 0, EM_MIPS, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){ + R_MIPS_64, + R_MIPS_32, + R_MIPS_26, + R_MIPS_LO16, + R_MIPS_HI16, + R_MIPS_HIGHER, + R_MIPS_HIGHEST, + -1 + }, (int[]){ + -1 + } + }, + { "riscv32", 4, 0, EM_RISCV, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){ + R_RISCV_32, + R_RISCV_64, + R_RISCV_ADD8, + R_RISCV_ADD16, + R_RISCV_ADD32, + R_RISCV_ADD64, + R_RISCV_SUB8, + R_RISCV_SUB16, + R_RISCV_SUB32, + R_RISCV_SUB64, + R_RISCV_ALIGN, + R_RISCV_BRANCH, + R_RISCV_CALL, + R_RISCV_CALL_PLT, + R_RISCV_GOT_HI20, + R_RISCV_HI20, + R_RISCV_JAL, + R_RISCV_LO12_I, + R_RISCV_LO12_S, + R_RISCV_PCREL_HI20, + R_RISCV_PCREL_LO12_I, + R_RISCV_PCREL_LO12_S, + R_RISCV_RELAX, + R_RISCV_RVC_BRANCH, + R_RISCV_RVC_JUMP, + -1 + } }, + { "riscv64", 8, 0, EM_RISCV, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){ + R_RISCV_32, + R_RISCV_64, + R_RISCV_ADD8, + R_RISCV_ADD16, + R_RISCV_ADD32, + R_RISCV_ADD64, + R_RISCV_SUB8, + R_RISCV_SUB16, + R_RISCV_SUB32, + R_RISCV_SUB64, + R_RISCV_ALIGN, + R_RISCV_BRANCH, + R_RISCV_CALL, + R_RISCV_CALL_PLT, + R_RISCV_GOT_HI20, + R_RISCV_HI20, + R_RISCV_JAL, + R_RISCV_LO12_I, + R_RISCV_LO12_S, + R_RISCV_PCREL_HI20, + R_RISCV_PCREL_LO12_I, + R_RISCV_PCREL_LO12_S, + R_RISCV_RELAX, + R_RISCV_RVC_BRANCH, + R_RISCV_RVC_JUMP, + -1 + } + }, +}; + +struct platform_whitelist { + const char *arch; + const char *platform; + const char **whitelist_empty; +}; + +static struct platform_whitelist whitelists[] = { + {"i386", "xen", (const char *[]) {"all_video", 0}}, + {"i386", "xen_pvh", (const char *[]) {"all_video", 0}}, + {"x86_64", "xen", (const char *[]) {"all_video", 0}}, + {"sparc64", "ieee1275", (const char *[]) {"all_video", 0}}, + + /* video is compiled-in on MIPS. */ + {"mipsel", "loongson", (const char *[]) {"all_video", 0}}, + {"mipsel", "qemu_mips", (const char *[]) {"all_video", 0}}, + {"mipsel", "arc", (const char *[]) {"all_video", 0}}, + {"mips", "qemu_mips", (const char *[]) {"all_video", 0}}, + {"mips", "arc", (const char *[]) {"all_video", 0}}, +}; + + +int +main (int argc, char **argv) +{ + size_t module_size; + unsigned arch, whitelist; + const char **whitelist_empty = 0; + char *module_img; + if (argc != 4) { + fprintf (stderr, "usage: %s FILE ARCH PLATFORM\n", argv[0]); + return 1; + } + + for (arch = 0; arch < ARRAY_SIZE(archs); arch++) + if (strcmp(archs[arch].name, argv[2]) == 0) + break; + if (arch == ARRAY_SIZE(archs)) + grub_util_error("%s: unknown arch: %s", argv[1], argv[2]); + + for (whitelist = 0; whitelist < ARRAY_SIZE(whitelists); whitelist++) + if (strcmp(whitelists[whitelist].arch, argv[2]) == 0 + && strcmp(whitelists[whitelist].platform, argv[3]) == 0) + break; + if (whitelist != ARRAY_SIZE(whitelists)) + whitelist_empty = whitelists[whitelist].whitelist_empty; + + module_size = grub_util_get_image_size (argv[1]); + module_img = grub_util_read_image (argv[1]); + if (archs[arch].voidp_sizeof == 8) + grub_module_verify64(argv[1], module_img, module_size, &archs[arch], whitelist_empty); + else + grub_module_verify32(argv[1], module_img, module_size, &archs[arch], whitelist_empty); + return 0; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/util/grub-module-verifierXX.c b/GRUB2/MOD_SRC/grub-2.04/util/grub-module-verifierXX.c new file mode 100644 index 0000000..b0ae428 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/util/grub-module-verifierXX.c @@ -0,0 +1,446 @@ +#include + +#include +#include +#include + +#if defined(MODULEVERIFIER_ELF32) +# define SUFFIX(x) x ## 32 +# define ELFCLASSXX ELFCLASS32 +# define Elf_Ehdr Elf32_Ehdr +# define Elf_Phdr Elf32_Phdr +# define Elf_Nhdr Elf32_Nhdr +# define Elf_Addr Elf32_Addr +# define Elf_Sym Elf32_Sym +# define Elf_Off Elf32_Off +# define Elf_Shdr Elf32_Shdr +# define Elf_Rela Elf32_Rela +# define Elf_Rel Elf32_Rel +# define Elf_Word Elf32_Word +# define Elf_Half Elf32_Half +# define Elf_Section Elf32_Section +# define ELF_R_SYM(val) ELF32_R_SYM(val) +# define ELF_R_TYPE(val) ELF32_R_TYPE(val) +# define ELF_ST_TYPE(val) ELF32_ST_TYPE(val) +#elif defined(MODULEVERIFIER_ELF64) +# define SUFFIX(x) x ## 64 +# define ELFCLASSXX ELFCLASS64 +# define Elf_Ehdr Elf64_Ehdr +# define Elf_Phdr Elf64_Phdr +# define Elf_Nhdr Elf64_Nhdr +# define Elf_Addr Elf64_Addr +# define Elf_Sym Elf64_Sym +# define Elf_Off Elf64_Off +# define Elf_Shdr Elf64_Shdr +# define Elf_Rela Elf64_Rela +# define Elf_Rel Elf64_Rel +# define Elf_Word Elf64_Word +# define Elf_Half Elf64_Half +# define Elf_Section Elf64_Section +# define ELF_R_SYM(val) ELF64_R_SYM(val) +# define ELF_R_TYPE(val) ELF64_R_TYPE(val) +# define ELF_ST_TYPE(val) ELF64_ST_TYPE(val) +#else +#error "I'm confused" +#endif + +#define grub_target_to_host32(x) (grub_target_to_host32_real (arch, (x))) +#define grub_host_to_target32(x) (grub_host_to_target32_real (arch, (x))) +#define grub_target_to_host64(x) (grub_target_to_host64_real (arch, (x))) +#define grub_host_to_target64(x) (grub_host_to_target64_real (arch, (x))) +#define grub_host_to_target_addr(x) (grub_host_to_target_addr_real (arch, (x))) +#define grub_target_to_host16(x) (grub_target_to_host16_real (arch, (x))) +#define grub_host_to_target16(x) (grub_host_to_target16_real (arch, (x))) +#define grub_target_to_host(val) grub_target_to_host_real(arch, (val)) + +static inline grub_uint32_t +grub_target_to_host32_real (const struct grub_module_verifier_arch *arch, + grub_uint32_t in) +{ + if (arch->bigendian) + return grub_be_to_cpu32 (in); + else + return grub_le_to_cpu32 (in); +} + +static inline grub_uint64_t +grub_target_to_host64_real (const struct grub_module_verifier_arch *arch, + grub_uint64_t in) +{ + if (arch->bigendian) + return grub_be_to_cpu64 (in); + else + return grub_le_to_cpu64 (in); +} + +static inline grub_uint64_t +grub_host_to_target64_real (const struct grub_module_verifier_arch *arch, + grub_uint64_t in) +{ + if (arch->bigendian) + return grub_cpu_to_be64 (in); + else + return grub_cpu_to_le64 (in); +} + +static inline grub_uint32_t +grub_host_to_target32_real (const struct grub_module_verifier_arch *arch, + grub_uint32_t in) +{ + if (arch->bigendian) + return grub_cpu_to_be32 (in); + else + return grub_cpu_to_le32 (in); +} + +static inline grub_uint16_t +grub_target_to_host16_real (const struct grub_module_verifier_arch *arch, + grub_uint16_t in) +{ + if (arch->bigendian) + return grub_be_to_cpu16 (in); + else + return grub_le_to_cpu16 (in); +} + +static inline grub_uint16_t +grub_host_to_target16_real (const struct grub_module_verifier_arch *arch, + grub_uint16_t in) +{ + if (arch->bigendian) + return grub_cpu_to_be16 (in); + else + return grub_cpu_to_le16 (in); +} + +static inline grub_uint64_t +grub_host_to_target_addr_real (const struct grub_module_verifier_arch *arch, grub_uint64_t in) +{ + if (arch->voidp_sizeof == 8) + return grub_host_to_target64_real (arch, in); + else + return grub_host_to_target32_real (arch, in); +} + +static inline grub_uint64_t +grub_target_to_host_real (const struct grub_module_verifier_arch *arch, grub_uint64_t in) +{ + if (arch->voidp_sizeof == 8) + return grub_target_to_host64_real (arch, in); + else + return grub_target_to_host32_real (arch, in); +} + + +static Elf_Shdr * +find_section (const struct grub_module_verifier_arch *arch, Elf_Ehdr *e, const char *name) +{ + Elf_Shdr *s; + const char *str; + unsigned i; + + s = (Elf_Shdr *) ((char *) e + grub_target_to_host (e->e_shoff) + grub_target_to_host16 (e->e_shstrndx) * grub_target_to_host16 (e->e_shentsize)); + str = (char *) e + grub_target_to_host (s->sh_offset); + + for (i = 0, s = (Elf_Shdr *) ((char *) e + grub_target_to_host (e->e_shoff)); + i < grub_target_to_host16 (e->e_shnum); + i++, s = (Elf_Shdr *) ((char *) s + grub_target_to_host16 (e->e_shentsize))) + if (strcmp (str + grub_target_to_host32 (s->sh_name), name) == 0) + return s; + return NULL; +} + +static void +check_license (const char * const filename, + const struct grub_module_verifier_arch *arch, Elf_Ehdr *e) +{ + Elf_Shdr *s = find_section (arch, e, ".module_license"); + if (s && (strcmp ((char *) e + grub_target_to_host(s->sh_offset), "LICENSE=GPLv3") == 0 + || strcmp ((char *) e + grub_target_to_host(s->sh_offset), "LICENSE=GPLv3+") == 0 + || strcmp ((char *) e + grub_target_to_host(s->sh_offset), "LICENSE=GPLv2+") == 0)) + return; + grub_util_error ("%s: incompatible license", filename); +} + +static Elf_Sym * +get_symtab (const struct grub_module_verifier_arch *arch, Elf_Ehdr *e, Elf_Word *size, Elf_Word *entsize) +{ + unsigned i; + Elf_Shdr *s, *sections; + Elf_Sym *sym; + + sections = (Elf_Shdr *) ((char *) e + grub_target_to_host (e->e_shoff)); + for (i = 0, s = sections; + i < grub_target_to_host16 (e->e_shnum); + i++, s = (Elf_Shdr *) ((char *) s + grub_target_to_host16 (e->e_shentsize))) + if (grub_target_to_host32 (s->sh_type) == SHT_SYMTAB) + break; + + if (i == grub_target_to_host16 (e->e_shnum)) + return NULL; + + sym = (Elf_Sym *) ((char *) e + grub_target_to_host (s->sh_offset)); + *size = grub_target_to_host (s->sh_size); + *entsize = grub_target_to_host (s->sh_entsize); + return sym; +} + +static int +is_whitelisted (const char *modname, const char **whitelist) +{ + const char **ptr; + if (!whitelist) + return 0; + if (!modname) + return 0; + for (ptr = whitelist; *ptr; ptr++) + if (strcmp (modname, *ptr) == 0) + return 1; + return 0; +} + +static void +check_symbols (const struct grub_module_verifier_arch *arch, + Elf_Ehdr *e, const char *modname, + const char **whitelist_empty) +{ + Elf_Sym *sym; + Elf_Word size, entsize; + unsigned i; + + /* Module without symbol table and without .moddeps section is useless + at boot time, so catch it early to prevent build errors */ + sym = get_symtab (arch, e, &size, &entsize); + if (!sym) + { + Elf_Shdr *s; + + /* However some modules are dependencies-only, + e.g. insmod all_video pulls in all video drivers. + Some platforms e.g. xen have no video drivers, so + the module does nothing. */ + if (is_whitelisted (modname, whitelist_empty)) + return; + + s = find_section (arch, e, ".moddeps"); + + if (!s) + grub_util_error ("%s: no symbol table and no .moddeps section", modname); + + if (!s->sh_size) + grub_util_error ("%s: no symbol table and empty .moddeps section", modname); + + return; + } + + for (i = 0; + i < size / entsize; + i++, sym = (Elf_Sym *) ((char *) sym + entsize)) + { + unsigned char type = ELF_ST_TYPE (sym->st_info); + + switch (type) + { + case STT_NOTYPE: + case STT_OBJECT: + case STT_FUNC: + case STT_SECTION: + case STT_FILE: + break; + + default: + return grub_util_error ("%s: unknown symbol type `%d'", modname, (int) type); + } + } +} + +static int +is_symbol_local(Elf_Sym *sym) +{ + switch (ELF_ST_TYPE (sym->st_info)) + { + case STT_NOTYPE: + case STT_OBJECT: + if (sym->st_name != 0 && sym->st_shndx == 0) + return 0; + return 1; + + case STT_FUNC: + case STT_SECTION: + return 1; + + default: + return 0; + } +} + +static void +section_check_relocations (const char * const modname, + const struct grub_module_verifier_arch *arch, void *ehdr, + Elf_Shdr *s, size_t target_seg_size) +{ + Elf_Rel *rel, *max; + Elf_Sym *symtab; + Elf_Word symtabsize, symtabentsize; + + symtab = get_symtab (arch, ehdr, &symtabsize, &symtabentsize); + if (!symtab) + grub_util_error ("%s: relocation without symbol table", modname); + + for (rel = (Elf_Rel *) ((char *) ehdr + grub_target_to_host (s->sh_offset)), + max = (Elf_Rel *) ((char *) rel + grub_target_to_host (s->sh_size)); + rel < max; + rel = (Elf_Rel *) ((char *) rel + grub_target_to_host (s->sh_entsize))) + { + Elf_Sym *sym; + unsigned i; + + if (target_seg_size < grub_target_to_host (rel->r_offset)) + grub_util_error ("%s: reloc offset is out of the segment", modname); + + grub_size_t r_info; + if (arch->machine == EM_MIPS && arch->voidp_sizeof == 8) + r_info = ((grub_uint64_t) rel->r_info << 32) | + (grub_uint32_t) grub_be_to_cpu64 (rel->r_info); + else + r_info = grub_target_to_host (rel->r_info); + + grub_uint32_t type = ELF_R_TYPE (r_info); + + if (arch->machine == EM_SPARCV9) + type &= 0xff; + + for (i = 0; arch->supported_relocations[i] != -1; i++) + if (type == arch->supported_relocations[i]) + break; + if (arch->supported_relocations[i] != -1) + continue; + if (!arch->short_relocations) + grub_util_error ("%s: unsupported relocation 0x%x", modname, type); + for (i = 0; arch->short_relocations[i] != -1; i++) + if (type == arch->short_relocations[i]) + break; + if (arch->short_relocations[i] == -1) + grub_util_error ("%s: unsupported relocation 0x%x", modname, type); + sym = (Elf_Sym *) ((char *) symtab + symtabentsize * ELF_R_SYM (r_info)); + + if (is_symbol_local (sym)) + continue; + grub_util_error ("%s: relocation 0x%x is not module-local", modname, type); + } +#if defined(MODULEVERIFIER_ELF64) + if (arch->machine == EM_AARCH64) + { + unsigned unmatched_adr_got_page = 0; + Elf_Rela *rel2; + for (rel = (Elf_Rel *) ((char *) ehdr + grub_target_to_host (s->sh_offset)), + max = (Elf_Rel *) ((char *) rel + grub_target_to_host (s->sh_size)); + rel < max; + rel = (Elf_Rel *) ((char *) rel + grub_target_to_host (s->sh_entsize))) + { + switch (ELF_R_TYPE (grub_target_to_host (rel->r_info))) + { + case R_AARCH64_ADR_GOT_PAGE: + unmatched_adr_got_page++; + for (rel2 = (Elf_Rela *) ((char *) rel + grub_target_to_host (s->sh_entsize)); + rel2 < (Elf_Rela *) max; + rel2 = (Elf_Rela *) ((char *) rel2 + grub_target_to_host (s->sh_entsize))) + if (ELF_R_SYM (rel2->r_info) + == ELF_R_SYM (rel->r_info) + && ((Elf_Rela *) rel)->r_addend == rel2->r_addend + && ELF_R_TYPE (rel2->r_info) == R_AARCH64_LD64_GOT_LO12_NC) + break; + if (rel2 >= (Elf_Rela *) max) + grub_util_error ("%s: ADR_GOT_PAGE without matching LD64_GOT_LO12_NC", modname); + break; + case R_AARCH64_LD64_GOT_LO12_NC: + if (unmatched_adr_got_page == 0) + grub_util_error ("%s: LD64_GOT_LO12_NC without matching ADR_GOT_PAGE", modname); + unmatched_adr_got_page--; + break; + } + } + } +#endif +} + +static void +check_relocations (const char * const modname, + const struct grub_module_verifier_arch *arch, Elf_Ehdr *e) +{ + Elf_Shdr *s; + unsigned i; + + for (i = 0, s = (Elf_Shdr *) ((char *) e + grub_target_to_host (e->e_shoff)); + i < grub_target_to_host16 (e->e_shnum); + i++, s = (Elf_Shdr *) ((char *) s + grub_target_to_host16 (e->e_shentsize))) + if (grub_target_to_host32 (s->sh_type) == SHT_REL || grub_target_to_host32 (s->sh_type) == SHT_RELA) + { + Elf_Shdr *ts; + + if (grub_target_to_host32 (s->sh_type) == SHT_REL && !(arch->flags & GRUB_MODULE_VERIFY_SUPPORTS_REL)) + grub_util_error ("%s: unsupported SHT_REL", modname); + if (grub_target_to_host32 (s->sh_type) == SHT_RELA && !(arch->flags & GRUB_MODULE_VERIFY_SUPPORTS_RELA)) + grub_util_error ("%s: unsupported SHT_RELA", modname); + + /* Find the target segment. */ + if (grub_target_to_host32 (s->sh_info) >= grub_target_to_host16 (e->e_shnum)) + grub_util_error ("%s: orphaned reloc section", modname); + ts = (Elf_Shdr *) ((char *) e + grub_target_to_host (e->e_shoff) + grub_target_to_host32 (s->sh_info) * grub_target_to_host16 (e->e_shentsize)); + + section_check_relocations (modname, arch, e, s, grub_target_to_host (ts->sh_size)); + } +} + +void +SUFFIX(grub_module_verify) (const char * const filename, + void *module_img, size_t size, + const struct grub_module_verifier_arch *arch, + const char **whitelist_empty) +{ + Elf_Ehdr *e = module_img; + + /* Check the header size. */ + if (size < sizeof (Elf_Ehdr)) + grub_util_error ("%s: ELF header smaller than expected", filename); + + /* Check the magic numbers. */ + if (e->e_ident[EI_MAG0] != ELFMAG0 + || e->e_ident[EI_MAG1] != ELFMAG1 + || e->e_ident[EI_MAG2] != ELFMAG2 + || e->e_ident[EI_MAG3] != ELFMAG3 + || e->e_ident[EI_VERSION] != EV_CURRENT + || grub_target_to_host32 (e->e_version) != EV_CURRENT) + grub_util_error ("%s: invalid arch-independent ELF magic", filename); + + if (e->e_ident[EI_CLASS] != ELFCLASSXX + || e->e_ident[EI_DATA] != (arch->bigendian ? ELFDATA2MSB : ELFDATA2LSB) + || grub_target_to_host16 (e->e_machine) != arch->machine) + grub_util_error ("%s: invalid arch-dependent ELF magic", filename); + + if (grub_target_to_host16 (e->e_type) != ET_REL) + { + grub_util_error ("%s: this ELF file is not of the right type", filename); + } + + /* Make sure that every section is within the core. */ + if (size < grub_target_to_host (e->e_shoff) + + (grub_uint32_t) grub_target_to_host16 (e->e_shentsize) * grub_target_to_host16(e->e_shnum)) + { + grub_util_error ("%s: ELF sections outside core", filename); + } + + check_license (filename, arch, e); + + Elf_Shdr *s; + const char *modname; + + s = find_section (arch, e, ".modname"); + if (!s) + grub_util_error ("%s: no module name found", filename); + + modname = (const char *) e + grub_target_to_host (s->sh_offset); + + check_symbols(arch, e, modname, whitelist_empty); + check_relocations(modname, arch, e); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/util/mkimage.c b/GRUB2/MOD_SRC/grub-2.04/util/mkimage.c new file mode 100644 index 0000000..766ab01 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/util/mkimage.c @@ -0,0 +1,1776 @@ +/* grub-mkimage.c - make a bootable image */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ALIGN_ADDR(x) (ALIGN_UP((x), image_target->voidp_sizeof)) + +#ifdef USE_LIBLZMA +#include +#endif + +#pragma GCC diagnostic ignored "-Wcast-align" + +#define TARGET_NO_FIELD 0xffffffff + +/* use 2015-01-01T00:00:00+0000 as a stock timestamp */ +#define STABLE_EMBEDDING_TIMESTAMP 1420070400 + +#define EFI32_HEADER_SIZE ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE \ + + GRUB_PE32_SIGNATURE_SIZE \ + + sizeof (struct grub_pe32_coff_header) \ + + sizeof (struct grub_pe32_optional_header) \ + + 4 * sizeof (struct grub_pe32_section_table), \ + GRUB_PE32_FILE_ALIGNMENT) + +#define EFI64_HEADER_SIZE ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE \ + + GRUB_PE32_SIGNATURE_SIZE \ + + sizeof (struct grub_pe32_coff_header) \ + + sizeof (struct grub_pe64_optional_header) \ + + 4 * sizeof (struct grub_pe32_section_table), \ + GRUB_PE32_FILE_ALIGNMENT) + +static const struct grub_install_image_target_desc image_targets[] = + { + { + .dirname = "i386-coreboot", + .names = { "i386-coreboot", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_COREBOOT, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .reloc_table_offset = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_I386_COREBOOT_LINK_ADDR, + .elf_target = EM_386, + .link_align = 4, + .mod_gap = GRUB_KERNEL_I386_COREBOOT_MOD_GAP, + .mod_align = GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN + }, + { + .dirname = "i386-multiboot", + .names = { "i386-multiboot", NULL}, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_COREBOOT, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_I386_COREBOOT_LINK_ADDR, + .elf_target = EM_386, + .link_align = 4, + .mod_gap = GRUB_KERNEL_I386_COREBOOT_MOD_GAP, + .mod_align = GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN + }, + { + .dirname = "i386-pc", + .names = { "i386-pc", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_I386_PC, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_I386_PC_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_I386_PC_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR, + .default_compression = GRUB_COMPRESSION_LZMA + }, + { + .dirname = "i386-xen_pvh", + .names = { "i386-xen_pvh", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_XEN_PVH, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .elf_target = EM_386, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_I386_XEN_PVH_LINK_ADDR, + .mod_align = GRUB_KERNEL_I386_XEN_PVH_MOD_ALIGN, + .link_align = 4 + }, + { + .dirname = "i386-pc", + .names = { "i386-pc-pxe", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_I386_PC_PXE, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_I386_PC_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_I386_PC_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR, + .default_compression = GRUB_COMPRESSION_LZMA + }, + { + .dirname = "i386-pc", + .names = { "i386-pc-eltorito", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_I386_PC_ELTORITO, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_I386_PC_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_I386_PC_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR, + .default_compression = GRUB_COMPRESSION_LZMA + }, + { + .dirname = "i386-efi", + .names = { "i386-efi", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_EFI, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = EFI32_HEADER_SIZE, + .pe_target = GRUB_PE32_MACHINE_I386, + .elf_target = EM_386, + }, + { + .dirname = "i386-ieee1275", + .names = { "i386-ieee1275", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_I386_IEEE1275, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_I386_IEEE1275_LINK_ADDR, + .elf_target = EM_386, + .mod_gap = GRUB_KERNEL_I386_IEEE1275_MOD_GAP, + .mod_align = GRUB_KERNEL_I386_IEEE1275_MOD_ALIGN, + .link_align = 4, + }, + { + .dirname = "i386-qemu", + .names = { "i386-qemu", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_QEMU, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_I386_QEMU_LINK_ADDR + }, + { + .dirname = "x86_64-efi", + .names = { "x86_64-efi", NULL }, + .voidp_sizeof = 8, + .bigendian = 0, + .id = IMAGE_EFI, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = EFI64_HEADER_SIZE, + .pe_target = GRUB_PE32_MACHINE_X86_64, + .elf_target = EM_X86_64, + }, + { + .dirname = "i386-xen", + .names = { "i386-xen", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_XEN, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = 0, + .elf_target = EM_386, + .mod_gap = GRUB_KERNEL_I386_XEN_MOD_GAP, + .mod_align = GRUB_KERNEL_I386_XEN_MOD_ALIGN, + .link_align = 4 + }, + { + .dirname = "x86_64-xen", + .names = { "x86_64-xen", NULL }, + .voidp_sizeof = 8, + .bigendian = 0, + .id = IMAGE_XEN, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = 0, + .elf_target = EM_X86_64, + .mod_gap = GRUB_KERNEL_X86_64_XEN_MOD_GAP, + .mod_align = GRUB_KERNEL_X86_64_XEN_MOD_ALIGN, + .link_align = 8 + }, + { + .dirname = "mipsel-loongson", + .names = { "mipsel-yeeloong-flash", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_YEELOONG_FLASH, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR, + .elf_target = EM_MIPS, + .link_align = GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN, + .default_compression = GRUB_COMPRESSION_NONE + }, + { + .dirname = "mipsel-loongson", + .names = { "mipsel-fuloong2f-flash", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_FULOONG2F_FLASH, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR, + .elf_target = EM_MIPS, + .link_align = GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN, + .default_compression = GRUB_COMPRESSION_NONE + }, + { + .dirname = "mipsel-loongson", + .names = { "mipsel-loongson-elf", "mipsel-yeeloong-elf", + "mipsel-fuloong2f-elf", "mipsel-fuloong2e-elf", + "mipsel-fuloong-elf", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_LOONGSON_ELF, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR, + .elf_target = EM_MIPS, + .link_align = GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN, + .default_compression = GRUB_COMPRESSION_NONE + }, + { + .dirname = "powerpc-ieee1275", + .names = { "powerpc-ieee1275", NULL }, + .voidp_sizeof = 4, + .bigendian = 1, + .id = IMAGE_PPC, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR, + .elf_target = EM_PPC, + .mod_gap = GRUB_KERNEL_POWERPC_IEEE1275_MOD_GAP, + .mod_align = GRUB_KERNEL_POWERPC_IEEE1275_MOD_ALIGN, + .link_align = 4 + }, + { + .dirname = "sparc64-ieee1275", + .names = { "sparc64-ieee1275-raw", NULL }, + .voidp_sizeof = 8, + .bigendian = 1, + .id = IMAGE_SPARC64_RAW, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR, + .mod_align = GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN, + }, + { + .dirname = "sparc64-ieee1275", + .names = { "sparc64-ieee1275-cdcore", NULL }, + .voidp_sizeof = 8, + .bigendian = 1, + .id = IMAGE_SPARC64_CDCORE, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR, + .mod_align = GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN, + }, + { + .dirname = "sparc64-ieee1275", + .names = { "sparc64-ieee1275-aout", NULL }, + .voidp_sizeof = 8, + .bigendian = 1, + .id = IMAGE_SPARC64_AOUT, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR, + .mod_align = GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN, + }, + { + .dirname = "ia64-efi", + .names = {"ia64-efi", NULL}, + .voidp_sizeof = 8, + .bigendian = 0, + .id = IMAGE_EFI, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = EFI64_HEADER_SIZE, + .pe_target = GRUB_PE32_MACHINE_IA64, + .elf_target = EM_IA_64, + }, + { + .dirname = "mips-arc", + .names = {"mips-arc", NULL}, + .voidp_sizeof = 4, + .bigendian = 1, + .id = IMAGE_MIPS_ARC, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size = GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_MIPS_ARC_LINK_ADDR, + .elf_target = EM_MIPS, + .link_align = GRUB_KERNEL_MIPS_ARC_LINK_ALIGN, + .default_compression = GRUB_COMPRESSION_NONE + }, + { + .dirname = "mipsel-arc", + .names = {"mipsel-arc", NULL}, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_MIPS_ARC, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size = GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_MIPSEL_ARC_LINK_ADDR, + .elf_target = EM_MIPS, + .link_align = GRUB_KERNEL_MIPS_ARC_LINK_ALIGN, + .default_compression = GRUB_COMPRESSION_NONE + }, + { + .dirname = "mipsel-qemu_mips", + .names = { "mipsel-qemu_mips-elf", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_LOONGSON_ELF, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR, + .elf_target = EM_MIPS, + .link_align = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN, + .default_compression = GRUB_COMPRESSION_NONE + }, + { + .dirname = "mips-qemu_mips", + .names = { "mips-qemu_mips-flash", NULL }, + .voidp_sizeof = 4, + .bigendian = 1, + .id = IMAGE_QEMU_MIPS_FLASH, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR, + .elf_target = EM_MIPS, + .link_align = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN, + .default_compression = GRUB_COMPRESSION_NONE + }, + { + .dirname = "mipsel-qemu_mips", + .names = { "mipsel-qemu_mips-flash", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_QEMU_MIPS_FLASH, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR, + .elf_target = EM_MIPS, + .link_align = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN, + .default_compression = GRUB_COMPRESSION_NONE + }, + { + .dirname = "mips-qemu_mips", + .names = { "mips-qemu_mips-elf", NULL }, + .voidp_sizeof = 4, + .bigendian = 1, + .id = IMAGE_LOONGSON_ELF, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR, + .elf_target = EM_MIPS, + .link_align = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN, + .default_compression = GRUB_COMPRESSION_NONE + }, + { + .dirname = "arm-uboot", + .names = { "arm-uboot", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_UBOOT, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = GRUB_KERNEL_ARM_UBOOT_TOTAL_MODULE_SIZE, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = GRUB_KERNEL_ARM_UBOOT_MOD_ALIGN, + .vaddr_offset = 0, + .elf_target = EM_ARM, + .mod_gap = GRUB_KERNEL_ARM_UBOOT_MOD_GAP, + .mod_align = GRUB_KERNEL_ARM_UBOOT_MOD_ALIGN, + .link_align = 4 + }, + /* For coreboot versions that don't support self-relocating images. */ + { + .dirname = "arm-coreboot-vexpress", + .names = { "arm-coreboot-vexpress", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_COREBOOT, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = GRUB_KERNEL_ARM_COREBOOT_TOTAL_MODULE_SIZE, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = GRUB_KERNEL_ARM_COREBOOT_MOD_ALIGN, + .vaddr_offset = 0, + .elf_target = EM_ARM, + .mod_gap = GRUB_KERNEL_ARM_COREBOOT_MOD_GAP, + .mod_align = GRUB_KERNEL_ARM_COREBOOT_MOD_ALIGN, + .link_align = 4, + .link_addr = 0x62000000, + }, + { + .dirname = "arm-coreboot-veyron", + .names = { "arm-coreboot-veyron", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_COREBOOT, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = GRUB_KERNEL_ARM_COREBOOT_TOTAL_MODULE_SIZE, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = GRUB_KERNEL_ARM_COREBOOT_MOD_ALIGN, + .vaddr_offset = 0, + .elf_target = EM_ARM, + .mod_gap = GRUB_KERNEL_ARM_COREBOOT_MOD_GAP, + .mod_align = GRUB_KERNEL_ARM_COREBOOT_MOD_ALIGN, + .link_align = 4, + .link_addr = 0x43000000, + }, + { + .dirname = "arm-efi", + .names = { "arm-efi", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_EFI, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = EFI32_HEADER_SIZE, + .pe_target = GRUB_PE32_MACHINE_ARMTHUMB_MIXED, + .elf_target = EM_ARM, + }, + { + .dirname = "arm64-efi", + .names = { "arm64-efi", NULL }, + .voidp_sizeof = 8, + .bigendian = 0, + .id = IMAGE_EFI, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = EFI64_HEADER_SIZE, + .pe_target = GRUB_PE32_MACHINE_ARM64, + .elf_target = EM_AARCH64, + }, + { + .dirname = "mips64el-efi", + .names = { "mips64el-efi", NULL }, + .voidp_sizeof = 8, + .bigendian = 0, + .id = IMAGE_EFI, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = EFI64_HEADER_SIZE, + .pe_target = GRUB_PE32_MACHINE_MIPS, + .elf_target = EM_MIPS, + }, + { + .dirname = "riscv32-efi", + .names = { "riscv32-efi", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_EFI, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = EFI32_HEADER_SIZE, + .pe_target = GRUB_PE32_MACHINE_RISCV32, + .elf_target = EM_RISCV, + }, + { + .dirname = "riscv64-efi", + .names = { "riscv64-efi", NULL }, + .voidp_sizeof = 8, + .bigendian = 0, + .id = IMAGE_EFI, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = EFI64_HEADER_SIZE, + .pe_target = GRUB_PE32_MACHINE_RISCV64, + .elf_target = EM_RISCV, + }, + }; + +#include + +static void *SzAlloc(void *p __attribute__ ((unused)), size_t size) { return xmalloc(size); } +static void SzFree(void *p __attribute__ ((unused)), void *address) { free(address); } +static ISzAlloc g_Alloc = { SzAlloc, SzFree }; + +static void +compress_kernel_lzma (char *kernel_img, size_t kernel_size, + char **core_img, size_t *core_size) +{ + CLzmaEncProps props; + unsigned char out_props[5]; + size_t out_props_size = 5; + + LzmaEncProps_Init(&props); + props.dictSize = 1 << 16; + props.lc = 3; + props.lp = 0; + props.pb = 2; + props.numThreads = 1; + + *core_img = xmalloc (kernel_size); + + *core_size = kernel_size; + if (LzmaEncode ((unsigned char *) *core_img, core_size, + (unsigned char *) kernel_img, + kernel_size, + &props, out_props, &out_props_size, + 0, NULL, &g_Alloc, &g_Alloc) != SZ_OK) + grub_util_error ("%s", _("cannot compress the kernel image")); +} + +#ifdef USE_LIBLZMA +static void +compress_kernel_xz (char *kernel_img, size_t kernel_size, + char **core_img, size_t *core_size) +{ + lzma_stream strm = LZMA_STREAM_INIT; + lzma_ret xzret; + lzma_options_lzma lzopts = { + .dict_size = 1 << 16, + .preset_dict = NULL, + .preset_dict_size = 0, + .lc = 3, + .lp = 0, + .pb = 2, + .mode = LZMA_MODE_NORMAL, + .nice_len = 64, + .mf = LZMA_MF_BT4, + .depth = 0, + }; + lzma_filter fltrs[] = { + { .id = LZMA_FILTER_LZMA2, .options = &lzopts}, + { .id = LZMA_VLI_UNKNOWN, .options = NULL} + }; + + xzret = lzma_stream_encoder (&strm, fltrs, LZMA_CHECK_NONE); + if (xzret != LZMA_OK) + grub_util_error ("%s", _("cannot compress the kernel image")); + + *core_img = xmalloc (kernel_size); + + *core_size = kernel_size; + strm.next_in = (unsigned char *) kernel_img; + strm.avail_in = kernel_size; + strm.next_out = (unsigned char *) *core_img; + strm.avail_out = *core_size; + + while (1) + { + xzret = lzma_code (&strm, LZMA_FINISH); + if (xzret == LZMA_OK) + continue; + if (xzret == LZMA_STREAM_END) + break; + grub_util_error ("%s", _("cannot compress the kernel image")); + } + + *core_size -= strm.avail_out; +} +#endif + +static void +compress_kernel (const struct grub_install_image_target_desc *image_target, char *kernel_img, + size_t kernel_size, char **core_img, size_t *core_size, + grub_compression_t comp) +{ + if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS + && (comp == GRUB_COMPRESSION_LZMA)) + { + compress_kernel_lzma (kernel_img, kernel_size, core_img, + core_size); + return; + } + +#ifdef USE_LIBLZMA + if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS + && (comp == GRUB_COMPRESSION_XZ)) + { + compress_kernel_xz (kernel_img, kernel_size, core_img, + core_size); + return; + } +#endif + + if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS + && (comp != GRUB_COMPRESSION_NONE)) + grub_util_error (_("unknown compression %d"), comp); + + *core_img = xmalloc (kernel_size); + memcpy (*core_img, kernel_img, kernel_size); + *core_size = kernel_size; +} + +const struct grub_install_image_target_desc * +grub_install_get_image_target (const char *arg) +{ + unsigned i, j; + for (i = 0; i < ARRAY_SIZE (image_targets); i++) + for (j = 0; j < ARRAY_SIZE (image_targets[i].names) && + image_targets[i].names[j]; j++) + if (strcmp (arg, image_targets[i].names[j]) == 0) + return &image_targets[i]; + return NULL; +} + +const char * +grub_util_get_target_dirname (const struct grub_install_image_target_desc *t) +{ + return t->dirname; +} + +const char * +grub_util_get_target_name (const struct grub_install_image_target_desc *t) +{ + return t->names[0]; +} + +char * +grub_install_get_image_targets_string (void) +{ + int format_len = 0; + char *formats; + char *ptr; + unsigned i; + for (i = 0; i < ARRAY_SIZE (image_targets); i++) + format_len += strlen (image_targets[i].names[0]) + 2; + ptr = formats = xmalloc (format_len); + for (i = 0; i < ARRAY_SIZE (image_targets); i++) + { + strcpy (ptr, image_targets[i].names[0]); + ptr += strlen (image_targets[i].names[0]); + *ptr++ = ','; + *ptr++ = ' '; + } + ptr[-2] = 0; + + return formats; +} + +void +grub_install_generate_image (const char *dir, const char *prefix, + FILE *out, const char *outname, char *mods[], + char *memdisk_path, char **pubkey_paths, + size_t npubkeys, char *config_path, + const struct grub_install_image_target_desc *image_target, + int note, grub_compression_t comp, const char *dtb_path) +{ + char *kernel_img, *core_img; + size_t total_module_size, core_size; + size_t memdisk_size = 0, config_size = 0; + size_t prefix_size = 0, dtb_size = 0; + char *kernel_path; + size_t offset; + struct grub_util_path_list *path_list, *p; + size_t decompress_size = 0; + struct grub_mkimage_layout layout; + + if (comp == GRUB_COMPRESSION_AUTO) + comp = image_target->default_compression; + + if (image_target->id == IMAGE_I386_PC + || image_target->id == IMAGE_I386_PC_PXE + || image_target->id == IMAGE_I386_PC_ELTORITO) + comp = GRUB_COMPRESSION_LZMA; + + path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); + + kernel_path = grub_util_get_path (dir, "kernel.img"); + + if (image_target->voidp_sizeof == 8) + total_module_size = sizeof (struct grub_module_info64); + else + total_module_size = sizeof (struct grub_module_info32); + + { + size_t i; + for (i = 0; i < npubkeys; i++) + { + size_t curs; + curs = ALIGN_ADDR (grub_util_get_image_size (pubkey_paths[i])); + grub_util_info ("the size of public key %u is 0x%" + GRUB_HOST_PRIxLONG_LONG, + (unsigned) i, (unsigned long long) curs); + total_module_size += curs + sizeof (struct grub_module_header); + } + } + + if (memdisk_path) + { + memdisk_size = ALIGN_UP(grub_util_get_image_size (memdisk_path), 512); + grub_util_info ("the size of memory disk is 0x%" GRUB_HOST_PRIxLONG_LONG, + (unsigned long long) memdisk_size); + total_module_size += memdisk_size + sizeof (struct grub_module_header); + } + + if (dtb_path) + { + dtb_size = ALIGN_ADDR(grub_util_get_image_size (dtb_path)); + total_module_size += dtb_size + sizeof (struct grub_module_header); + } + + if (config_path) + { + config_size = ALIGN_ADDR (grub_util_get_image_size (config_path) + 1); + grub_util_info ("the size of config file is 0x%" GRUB_HOST_PRIxLONG_LONG, + (unsigned long long) config_size); + total_module_size += config_size + sizeof (struct grub_module_header); + } + + if (prefix) + { + prefix_size = ALIGN_ADDR (strlen (prefix) + 1); + total_module_size += prefix_size + sizeof (struct grub_module_header); + } + + for (p = path_list; p; p = p->next) + total_module_size += (ALIGN_ADDR (grub_util_get_image_size (p->name)) + + sizeof (struct grub_module_header)); + + grub_util_info ("the total module size is 0x%" GRUB_HOST_PRIxLONG_LONG, + (unsigned long long) total_module_size); + + if (image_target->voidp_sizeof == 4) + kernel_img = grub_mkimage_load_image32 (kernel_path, total_module_size, + &layout, image_target); + else + kernel_img = grub_mkimage_load_image64 (kernel_path, total_module_size, + &layout, image_target); + if ((image_target->id == IMAGE_XEN || image_target->id == IMAGE_XEN_PVH) && + layout.align < 4096) + layout.align = 4096; + + if ((image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS) + && (image_target->total_module_size != TARGET_NO_FIELD)) + *((grub_uint32_t *) (kernel_img + image_target->total_module_size)) + = grub_host_to_target32 (total_module_size); + + if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) + { + memmove (kernel_img + total_module_size, kernel_img, layout.kernel_size); + memset (kernel_img, 0, total_module_size); + } + + if (image_target->voidp_sizeof == 8) + { + /* Fill in the grub_module_info structure. */ + struct grub_module_info64 *modinfo; + if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) + modinfo = (struct grub_module_info64 *) kernel_img; + else + modinfo = (struct grub_module_info64 *) (kernel_img + layout.kernel_size); + modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC); + modinfo->offset = grub_host_to_target_addr (sizeof (struct grub_module_info64)); + modinfo->size = grub_host_to_target_addr (total_module_size); + if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) + offset = sizeof (struct grub_module_info64); + else + offset = layout.kernel_size + sizeof (struct grub_module_info64); + } + else + { + /* Fill in the grub_module_info structure. */ + struct grub_module_info32 *modinfo; + if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) + modinfo = (struct grub_module_info32 *) kernel_img; + else + modinfo = (struct grub_module_info32 *) (kernel_img + layout.kernel_size); + modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC); + modinfo->offset = grub_host_to_target_addr (sizeof (struct grub_module_info32)); + modinfo->size = grub_host_to_target_addr (total_module_size); + if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) + offset = sizeof (struct grub_module_info32); + else + offset = layout.kernel_size + sizeof (struct grub_module_info32); + } + + for (p = path_list; p; p = p->next) + { + struct grub_module_header *header; + size_t mod_size; + + mod_size = ALIGN_ADDR (grub_util_get_image_size (p->name)); + + header = (struct grub_module_header *) (kernel_img + offset); + header->type = grub_host_to_target32 (OBJ_TYPE_ELF); + header->size = grub_host_to_target32 (mod_size + sizeof (*header)); + offset += sizeof (*header); + + grub_util_load_image (p->name, kernel_img + offset); + offset += mod_size; + } + + { + size_t i; + for (i = 0; i < npubkeys; i++) + { + size_t curs; + struct grub_module_header *header; + + curs = grub_util_get_image_size (pubkey_paths[i]); + + header = (struct grub_module_header *) (kernel_img + offset); + header->type = grub_host_to_target32 (OBJ_TYPE_PUBKEY); + header->size = grub_host_to_target32 (curs + sizeof (*header)); + offset += sizeof (*header); + + grub_util_load_image (pubkey_paths[i], kernel_img + offset); + offset += ALIGN_ADDR (curs); + } + } + + if (memdisk_path) + { + struct grub_module_header *header; + + header = (struct grub_module_header *) (kernel_img + offset); + header->type = grub_host_to_target32 (OBJ_TYPE_MEMDISK); + header->size = grub_host_to_target32 (memdisk_size + sizeof (*header)); + offset += sizeof (*header); + + grub_util_load_image (memdisk_path, kernel_img + offset); + offset += memdisk_size; + } + + if (dtb_path) + { + struct grub_module_header *header; + + header = (struct grub_module_header *) (kernel_img + offset); + header->type = grub_host_to_target32 (OBJ_TYPE_DTB); + header->size = grub_host_to_target32 (dtb_size + sizeof (*header)); + offset += sizeof (*header); + + grub_util_load_image (dtb_path, kernel_img + offset); + offset += dtb_size; + } + + if (config_path) + { + struct grub_module_header *header; + + header = (struct grub_module_header *) (kernel_img + offset); + header->type = grub_host_to_target32 (OBJ_TYPE_CONFIG); + header->size = grub_host_to_target32 (config_size + sizeof (*header)); + offset += sizeof (*header); + + grub_util_load_image (config_path, kernel_img + offset); + offset += config_size; + } + + if (prefix) + { + struct grub_module_header *header; + + header = (struct grub_module_header *) (kernel_img + offset); + header->type = grub_host_to_target32 (OBJ_TYPE_PREFIX); + header->size = grub_host_to_target32 (prefix_size + sizeof (*header)); + offset += sizeof (*header); + + grub_strcpy (kernel_img + offset, prefix); + offset += prefix_size; + } + + grub_util_info ("kernel_img=%p, kernel_size=0x%" GRUB_HOST_PRIxLONG_LONG, + kernel_img, + (unsigned long long) layout.kernel_size); + compress_kernel (image_target, kernel_img, layout.kernel_size + total_module_size, + &core_img, &core_size, comp); + free (kernel_img); + + grub_util_info ("the core size is 0x%" GRUB_HOST_PRIxLONG_LONG, + (unsigned long long) core_size); + + if (!(image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS) + && image_target->total_module_size != TARGET_NO_FIELD) + *((grub_uint32_t *) (core_img + image_target->total_module_size)) + = grub_host_to_target32 (total_module_size); + + if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS) + { + char *full_img; + size_t full_size; + char *decompress_path, *decompress_img; + const char *name; + + switch (comp) + { + case GRUB_COMPRESSION_XZ: + name = "xz_decompress.img"; + break; + case GRUB_COMPRESSION_LZMA: + name = "lzma_decompress.img"; + break; + case GRUB_COMPRESSION_NONE: + name = "none_decompress.img"; + break; + default: + grub_util_error (_("unknown compression %d"), comp); + } + + decompress_path = grub_util_get_path (dir, name); + decompress_size = grub_util_get_image_size (decompress_path); + decompress_img = grub_util_read_image (decompress_path); + + if ((image_target->id == IMAGE_I386_PC + || image_target->id == IMAGE_I386_PC_PXE + || image_target->id == IMAGE_I386_PC_ELTORITO) + && decompress_size > GRUB_KERNEL_I386_PC_LINK_ADDR - 0x8200) + grub_util_error ("%s", _("Decompressor is too big")); + + if (image_target->decompressor_compressed_size != TARGET_NO_FIELD) + *((grub_uint32_t *) (decompress_img + + image_target->decompressor_compressed_size)) + = grub_host_to_target32 (core_size); + + if (image_target->decompressor_uncompressed_size != TARGET_NO_FIELD) + *((grub_uint32_t *) (decompress_img + + image_target->decompressor_uncompressed_size)) + = grub_host_to_target32 (layout.kernel_size + total_module_size); + + if (image_target->decompressor_uncompressed_addr != TARGET_NO_FIELD) + { + if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) + *((grub_uint32_t *) (decompress_img + image_target->decompressor_uncompressed_addr)) + = grub_host_to_target_addr (image_target->link_addr - total_module_size); + else + *((grub_uint32_t *) (decompress_img + image_target->decompressor_uncompressed_addr)) + = grub_host_to_target_addr (image_target->link_addr); + } + full_size = core_size + decompress_size; + + full_img = xmalloc (full_size); + + memcpy (full_img, decompress_img, decompress_size); + + memcpy (full_img + decompress_size, core_img, core_size); + + free (core_img); + core_img = full_img; + core_size = full_size; + free (decompress_img); + free (decompress_path); + } + + switch (image_target->id) + { + case IMAGE_I386_PC: + case IMAGE_I386_PC_PXE: + case IMAGE_I386_PC_ELTORITO: + if (GRUB_KERNEL_I386_PC_LINK_ADDR + core_size > 0x78000 + || (core_size > (0xffff << GRUB_DISK_SECTOR_BITS)) + || (layout.kernel_size + layout.bss_size + + GRUB_KERNEL_I386_PC_LINK_ADDR > 0x68000)) + grub_util_error (_("core image is too big (0x%x > 0x%x)"), + GRUB_KERNEL_I386_PC_LINK_ADDR + (unsigned) core_size, + 0x78000); + /* fallthrough */ + case IMAGE_COREBOOT: + case IMAGE_QEMU: + if (image_target->elf_target != EM_ARM && layout.kernel_size + layout.bss_size + GRUB_KERNEL_I386_PC_LINK_ADDR > 0x68000) + grub_util_error (_("kernel image is too big (0x%x > 0x%x)"), + (unsigned) layout.kernel_size + (unsigned) layout.bss_size + + GRUB_KERNEL_I386_PC_LINK_ADDR, + 0x68000); + break; + case IMAGE_LOONGSON_ELF: + case IMAGE_YEELOONG_FLASH: + case IMAGE_FULOONG2F_FLASH: + case IMAGE_EFI: + case IMAGE_MIPS_ARC: + case IMAGE_QEMU_MIPS_FLASH: + case IMAGE_XEN: + case IMAGE_XEN_PVH: + break; + case IMAGE_SPARC64_AOUT: + case IMAGE_SPARC64_RAW: + case IMAGE_SPARC64_CDCORE: + case IMAGE_I386_IEEE1275: + case IMAGE_PPC: + case IMAGE_UBOOT: + break; + } + + switch (image_target->id) + { + case IMAGE_I386_PC: + case IMAGE_I386_PC_PXE: + case IMAGE_I386_PC_ELTORITO: + { + unsigned num; + char *boot_path, *boot_img; + size_t boot_size; + + num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); + if (image_target->id == IMAGE_I386_PC_PXE) + { + char *pxeboot_path, *pxeboot_img; + size_t pxeboot_size; + grub_uint32_t *ptr; + + pxeboot_path = grub_util_get_path (dir, "pxeboot.img"); + pxeboot_size = grub_util_get_image_size (pxeboot_path); + pxeboot_img = grub_util_read_image (pxeboot_path); + + grub_util_write_image (pxeboot_img, pxeboot_size, out, + outname); + free (pxeboot_img); + free (pxeboot_path); + + /* Remove Multiboot header to avoid confusing ipxe. */ + for (ptr = (grub_uint32_t *) core_img; + ptr < (grub_uint32_t *) (core_img + MULTIBOOT_SEARCH); ptr++) + if (*ptr == grub_host_to_target32 (MULTIBOOT_HEADER_MAGIC) + && grub_target_to_host32 (ptr[0]) + + grub_target_to_host32 (ptr[1]) + + grub_target_to_host32 (ptr[2]) == 0) + { + *ptr = 0; + break; + } + } + + if (image_target->id == IMAGE_I386_PC_ELTORITO) + { + char *eltorito_path, *eltorito_img; + size_t eltorito_size; + + eltorito_path = grub_util_get_path (dir, "cdboot.img"); + eltorito_size = grub_util_get_image_size (eltorito_path); + eltorito_img = grub_util_read_image (eltorito_path); + + grub_util_write_image (eltorito_img, eltorito_size, out, + outname); + free (eltorito_img); + free (eltorito_path); + } + + boot_path = grub_util_get_path (dir, "diskboot.img"); + boot_size = grub_util_get_image_size (boot_path); + if (boot_size != GRUB_DISK_SECTOR_SIZE) + grub_util_error (_("diskboot.img size must be %u bytes"), + GRUB_DISK_SECTOR_SIZE); + + boot_img = grub_util_read_image (boot_path); + + { + struct grub_pc_bios_boot_blocklist *block; + block = (struct grub_pc_bios_boot_blocklist *) (boot_img + + GRUB_DISK_SECTOR_SIZE + - sizeof (*block)); + block->len = grub_host_to_target16 (num); + + /* This is filled elsewhere. Verify it just in case. */ + assert (block->segment + == grub_host_to_target16 (GRUB_BOOT_I386_PC_KERNEL_SEG + + (GRUB_DISK_SECTOR_SIZE >> 4))); + } + + grub_util_write_image (boot_img, boot_size, out, outname); + free (boot_img); + free (boot_path); + } + break; + case IMAGE_EFI: + { + void *pe_img; + grub_uint8_t *header; + void *sections; + size_t pe_size; + struct grub_pe32_coff_header *c; + struct grub_pe32_section_table *text_section, *data_section; + struct grub_pe32_section_table *mods_section, *reloc_section; + static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB; + int header_size; + int reloc_addr; + + if (image_target->voidp_sizeof == 4) + header_size = EFI32_HEADER_SIZE; + else + header_size = EFI64_HEADER_SIZE; + + reloc_addr = ALIGN_UP (header_size + core_size, + GRUB_PE32_FILE_ALIGNMENT); + + pe_size = ALIGN_UP (reloc_addr + layout.reloc_size, + GRUB_PE32_FILE_ALIGNMENT); + pe_img = xmalloc (reloc_addr + layout.reloc_size); + memset (pe_img, 0, header_size); + memcpy ((char *) pe_img + header_size, core_img, core_size); + memset ((char *) pe_img + header_size + core_size, 0, reloc_addr - (header_size + core_size)); + memcpy ((char *) pe_img + reloc_addr, layout.reloc_section, layout.reloc_size); + header = pe_img; + + /* The magic. */ + memcpy (header, stub, GRUB_PE32_MSDOS_STUB_SIZE); + memcpy (header + GRUB_PE32_MSDOS_STUB_SIZE, "PE\0\0", + GRUB_PE32_SIGNATURE_SIZE); + + /* The COFF file header. */ + c = (struct grub_pe32_coff_header *) (header + GRUB_PE32_MSDOS_STUB_SIZE + + GRUB_PE32_SIGNATURE_SIZE); + c->machine = grub_host_to_target16 (image_target->pe_target); + + c->num_sections = grub_host_to_target16 (4); + c->time = grub_host_to_target32 (STABLE_EMBEDDING_TIMESTAMP); + c->characteristics = grub_host_to_target16 (GRUB_PE32_EXECUTABLE_IMAGE + | GRUB_PE32_LINE_NUMS_STRIPPED + | ((image_target->voidp_sizeof == 4) + ? GRUB_PE32_32BIT_MACHINE + : 0) + | GRUB_PE32_LOCAL_SYMS_STRIPPED + | GRUB_PE32_DEBUG_STRIPPED); + + /* The PE Optional header. */ + if (image_target->voidp_sizeof == 4) + { + struct grub_pe32_optional_header *o; + + c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe32_optional_header)); + + o = (struct grub_pe32_optional_header *) + (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header)); + o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); + o->code_size = grub_host_to_target32 (layout.exec_size); + o->data_size = grub_cpu_to_le32 (reloc_addr - layout.exec_size + - header_size); + o->bss_size = grub_cpu_to_le32 (layout.bss_size); + o->entry_addr = grub_cpu_to_le32 (layout.start_address); + o->code_base = grub_cpu_to_le32 (header_size); + + o->data_base = grub_host_to_target32 (header_size + layout.exec_size); + + o->image_base = 0; + o->section_alignment = grub_host_to_target32 (image_target->section_align); + o->file_alignment = grub_host_to_target32 (GRUB_PE32_FILE_ALIGNMENT); + o->image_size = grub_host_to_target32 (pe_size); + o->header_size = grub_host_to_target32 (header_size); + o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); + + /* Do these really matter? */ + o->stack_reserve_size = grub_host_to_target32 (0x10000); + o->stack_commit_size = grub_host_to_target32 (0x10000); + o->heap_reserve_size = grub_host_to_target32 (0x10000); + o->heap_commit_size = grub_host_to_target32 (0x10000); + + o->num_data_directories = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); + + o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); + o->base_relocation_table.size = grub_host_to_target32 (layout.reloc_size); + sections = o + 1; + } + else + { + struct grub_pe64_optional_header *o; + + c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe64_optional_header)); + + o = (struct grub_pe64_optional_header *) + (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header)); + o->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC); + o->code_size = grub_host_to_target32 (layout.exec_size); + o->data_size = grub_cpu_to_le32 (reloc_addr - layout.exec_size + - header_size); + o->bss_size = grub_cpu_to_le32 (layout.bss_size); + o->entry_addr = grub_cpu_to_le32 (layout.start_address); + o->code_base = grub_cpu_to_le32 (header_size); + o->image_base = 0; + o->section_alignment = grub_host_to_target32 (image_target->section_align); + o->file_alignment = grub_host_to_target32 (GRUB_PE32_FILE_ALIGNMENT); + o->image_size = grub_host_to_target32 (pe_size); + o->header_size = grub_host_to_target32 (header_size); + o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); + + /* Do these really matter? */ + o->stack_reserve_size = grub_host_to_target64 (0x10000); + o->stack_commit_size = grub_host_to_target64 (0x10000); + o->heap_reserve_size = grub_host_to_target64 (0x10000); + o->heap_commit_size = grub_host_to_target64 (0x10000); + + o->num_data_directories + = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); + + o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); + o->base_relocation_table.size = grub_host_to_target32 (layout.reloc_size); + sections = o + 1; + } + /* The sections. */ + text_section = sections; + strcpy (text_section->name, ".text"); + text_section->virtual_size = grub_cpu_to_le32 (layout.exec_size); + text_section->virtual_address = grub_cpu_to_le32 (header_size); + text_section->raw_data_size = grub_cpu_to_le32 (layout.exec_size); + text_section->raw_data_offset = grub_cpu_to_le32 (header_size); + text_section->characteristics = grub_cpu_to_le32_compile_time ( + GRUB_PE32_SCN_CNT_CODE + | GRUB_PE32_SCN_MEM_EXECUTE + | GRUB_PE32_SCN_MEM_READ); + + data_section = text_section + 1; + strcpy (data_section->name, ".data"); + data_section->virtual_size = grub_cpu_to_le32 (layout.kernel_size - layout.exec_size); + data_section->virtual_address = grub_cpu_to_le32 (header_size + layout.exec_size); + data_section->raw_data_size = grub_cpu_to_le32 (layout.kernel_size - layout.exec_size); + data_section->raw_data_offset = grub_cpu_to_le32 (header_size + layout.exec_size); + data_section->characteristics + = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE); + +#if 0 + bss_section = data_section + 1; + strcpy (bss_section->name, ".bss"); + bss_section->virtual_size = grub_cpu_to_le32 (layout.bss_size); + bss_section->virtual_address = grub_cpu_to_le32 (header_size + layout.kernel_size); + bss_section->raw_data_size = 0; + bss_section->raw_data_offset = 0; + bss_section->characteristics + = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE + | GRUB_PE32_SCN_ALIGN_64BYTES + | GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | 0x80); +#endif + + mods_section = data_section + 1; + strcpy (mods_section->name, "mods"); + mods_section->virtual_size = grub_cpu_to_le32 (reloc_addr - layout.kernel_size - header_size); + mods_section->virtual_address = grub_cpu_to_le32 (header_size + layout.kernel_size + layout.bss_size); + mods_section->raw_data_size = grub_cpu_to_le32 (reloc_addr - layout.kernel_size - header_size); + mods_section->raw_data_offset = grub_cpu_to_le32 (header_size + layout.kernel_size); + mods_section->characteristics + = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE); + + reloc_section = mods_section + 1; + strcpy (reloc_section->name, ".reloc"); + reloc_section->virtual_size = grub_cpu_to_le32 (layout.reloc_size); + reloc_section->virtual_address = grub_cpu_to_le32 (reloc_addr + layout.bss_size); + reloc_section->raw_data_size = grub_cpu_to_le32 (layout.reloc_size); + reloc_section->raw_data_offset = grub_cpu_to_le32 (reloc_addr); + reloc_section->characteristics + = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_DISCARDABLE + | GRUB_PE32_SCN_MEM_READ); + free (core_img); + core_img = pe_img; + core_size = pe_size; + } + break; + case IMAGE_QEMU: + { + char *rom_img; + size_t rom_size; + char *boot_path, *boot_img; + size_t boot_size; + + boot_path = grub_util_get_path (dir, "boot.img"); + boot_size = grub_util_get_image_size (boot_path); + boot_img = grub_util_read_image (boot_path); + + /* Rom sizes must be 64k-aligned. */ + rom_size = ALIGN_UP (core_size + boot_size, 64 * 1024); + + rom_img = xmalloc (rom_size); + memset (rom_img, 0, rom_size); + + *((grub_int32_t *) (core_img + GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR)) + = grub_host_to_target32 ((grub_uint32_t) -rom_size); + + memcpy (rom_img, core_img, core_size); + + *((grub_int32_t *) (boot_img + GRUB_BOOT_I386_QEMU_CORE_ENTRY_ADDR)) + = grub_host_to_target32 ((grub_uint32_t) -rom_size); + + memcpy (rom_img + rom_size - boot_size, boot_img, boot_size); + + free (core_img); + core_img = rom_img; + core_size = rom_size; + + free (boot_img); + free (boot_path); + } + break; + case IMAGE_SPARC64_AOUT: + { + void *aout_img; + size_t aout_size; + struct grub_aout32_header *aout_head; + + aout_size = core_size + sizeof (*aout_head); + aout_img = xmalloc (aout_size); + aout_head = aout_img; + grub_memset (aout_head, 0, sizeof (*aout_head)); + aout_head->a_midmag = grub_host_to_target32 ((AOUT_MID_SUN << 16) + | AOUT32_OMAGIC); + aout_head->a_text = grub_host_to_target32 (core_size); + aout_head->a_entry + = grub_host_to_target32 (GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS); + memcpy ((char *) aout_img + sizeof (*aout_head), core_img, core_size); + + free (core_img); + core_img = aout_img; + core_size = aout_size; + } + break; + case IMAGE_SPARC64_RAW: + { + unsigned int num; + char *boot_path, *boot_img; + size_t boot_size; + + num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); + num <<= GRUB_DISK_SECTOR_BITS; + + boot_path = grub_util_get_path (dir, "diskboot.img"); + boot_size = grub_util_get_image_size (boot_path); + if (boot_size != GRUB_DISK_SECTOR_SIZE) + grub_util_error (_("diskboot.img size must be %u bytes"), + GRUB_DISK_SECTOR_SIZE); + + boot_img = grub_util_read_image (boot_path); + + *((grub_uint32_t *) (boot_img + GRUB_DISK_SECTOR_SIZE + - GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE + 8)) + = grub_host_to_target32 (num); + + grub_util_write_image (boot_img, boot_size, out, outname); + free (boot_img); + free (boot_path); + } + break; + case IMAGE_SPARC64_CDCORE: + break; + case IMAGE_YEELOONG_FLASH: + case IMAGE_FULOONG2F_FLASH: + { + char *rom_img; + size_t rom_size; + char *boot_path, *boot_img; + size_t boot_size; + /* fwstart.img is the only part which can't be tested by using *-elf + target. Check it against the checksum. */ + const grub_uint8_t yeeloong_fwstart_good_hash[512 / 8] = + { + 0x5f, 0x67, 0x46, 0x57, 0x31, 0x30, 0xc5, 0x0a, + 0xe9, 0x98, 0x18, 0xc9, 0xf3, 0xca, 0x45, 0xa5, + 0x75, 0x64, 0x6b, 0xbb, 0x24, 0xcd, 0xb4, 0xbc, + 0xf2, 0x3e, 0x23, 0xf9, 0xc2, 0x6a, 0x8c, 0xde, + 0x3b, 0x94, 0x9c, 0xcc, 0xa5, 0xa7, 0x58, 0xb1, + 0xbe, 0x8b, 0x3d, 0x73, 0x98, 0x18, 0x7e, 0x68, + 0x5e, 0x5f, 0x23, 0x7d, 0x7a, 0xe8, 0x51, 0xf7, + 0x1a, 0xaf, 0x2f, 0x54, 0x11, 0x2e, 0x5c, 0x25 + }; + const grub_uint8_t fuloong2f_fwstart_good_hash[512 / 8] = + { + 0x76, 0x9b, 0xad, 0x6e, 0xa2, 0x39, 0x47, 0x62, + 0x1f, 0xc9, 0x3a, 0x6d, 0x05, 0x5c, 0x43, 0x5c, + 0x29, 0x4a, 0x7e, 0x08, 0x2a, 0x31, 0x8f, 0x5d, + 0x02, 0x84, 0xa0, 0x85, 0xf2, 0xd1, 0xb9, 0x53, + 0xa2, 0xbc, 0xf2, 0xe1, 0x39, 0x1e, 0x51, 0xb5, + 0xaf, 0xec, 0x9e, 0xf2, 0xf1, 0xf3, 0x0a, 0x2f, + 0xe6, 0xf1, 0x08, 0x89, 0xbe, 0xbc, 0x73, 0xab, + 0x46, 0x50, 0xd6, 0x21, 0xce, 0x8e, 0x24, 0xa7 + }; + const grub_uint8_t *fwstart_good_hash; + grub_uint8_t fwstart_hash[512 / 8]; + + if (image_target->id == IMAGE_FULOONG2F_FLASH) + { + fwstart_good_hash = fuloong2f_fwstart_good_hash; + boot_path = grub_util_get_path (dir, "fwstart_fuloong2f.img"); + } + else + { + fwstart_good_hash = yeeloong_fwstart_good_hash; + boot_path = grub_util_get_path (dir, "fwstart.img"); + } + + boot_size = grub_util_get_image_size (boot_path); + boot_img = grub_util_read_image (boot_path); + + grub_crypto_hash (GRUB_MD_SHA512, fwstart_hash, boot_img, boot_size); + + if (grub_memcmp (fwstart_hash, fwstart_good_hash, + GRUB_MD_SHA512->mdlen) != 0) + /* TRANSLATORS: fwstart.img may still be good, just it wasn't checked. */ + grub_util_warn ("%s", + _("fwstart.img doesn't match the known good version. " + "proceed at your own risk")); + + if (core_size + boot_size > 512 * 1024) + grub_util_error ("%s", _("firmware image is too big")); + rom_size = 512 * 1024; + + rom_img = xmalloc (rom_size); + memset (rom_img, 0, rom_size); + + memcpy (rom_img, boot_img, boot_size); + + memcpy (rom_img + boot_size, core_img, core_size); + + memset (rom_img + boot_size + core_size, 0, + rom_size - (boot_size + core_size)); + + free (core_img); + core_img = rom_img; + core_size = rom_size; + free (boot_img); + free (boot_path); + } + break; + case IMAGE_QEMU_MIPS_FLASH: + { + char *rom_img; + size_t rom_size; + + if (core_size > 512 * 1024) + grub_util_error ("%s", _("firmware image is too big")); + rom_size = 512 * 1024; + + rom_img = xmalloc (rom_size); + memset (rom_img, 0, rom_size); + + memcpy (rom_img, core_img, core_size); + + memset (rom_img + core_size, 0, + rom_size - core_size); + + free (core_img); + core_img = rom_img; + core_size = rom_size; + } + break; + + case IMAGE_UBOOT: + { + struct grub_uboot_image_header *hdr; + + hdr = xmalloc (core_size + sizeof (struct grub_uboot_image_header)); + memcpy (hdr + 1, core_img, core_size); + + memset (hdr, 0, sizeof (*hdr)); + hdr->ih_magic = grub_cpu_to_be32_compile_time (GRUB_UBOOT_IH_MAGIC); + hdr->ih_time = grub_cpu_to_be32 (STABLE_EMBEDDING_TIMESTAMP); + hdr->ih_size = grub_cpu_to_be32 (core_size); + hdr->ih_load = 0; + hdr->ih_ep = 0; + hdr->ih_type = GRUB_UBOOT_IH_TYPE_KERNEL_NOLOAD; + hdr->ih_os = GRUB_UBOOT_IH_OS_LINUX; + hdr->ih_arch = GRUB_UBOOT_IH_ARCH_ARM; + hdr->ih_comp = GRUB_UBOOT_IH_COMP_NONE; + + grub_crypto_hash (GRUB_MD_CRC32, &hdr->ih_dcrc, hdr + 1, core_size); + grub_crypto_hash (GRUB_MD_CRC32, &hdr->ih_hcrc, hdr, sizeof (*hdr)); + + free (core_img); + core_img = (char *) hdr; + core_size += sizeof (struct grub_uboot_image_header); + } + break; + + case IMAGE_MIPS_ARC: + { + char *ecoff_img; + struct ecoff_header { + grub_uint16_t magic; + grub_uint16_t nsec; + grub_uint32_t time; + grub_uint32_t syms; + grub_uint32_t nsyms; + grub_uint16_t opt; + grub_uint16_t flags; + grub_uint16_t magic2; + grub_uint16_t version; + grub_uint32_t textsize; + grub_uint32_t datasize; + grub_uint32_t bsssize; + grub_uint32_t entry; + grub_uint32_t text_start; + grub_uint32_t data_start; + grub_uint32_t bss_start; + grub_uint32_t gprmask; + grub_uint32_t cprmask[4]; + grub_uint32_t gp_value; + }; + struct ecoff_section + { + char name[8]; + grub_uint32_t paddr; + grub_uint32_t vaddr; + grub_uint32_t size; + grub_uint32_t file_offset; + grub_uint32_t reloc; + grub_uint32_t gp; + grub_uint16_t nreloc; + grub_uint16_t ngp; + grub_uint32_t flags; + }; + struct ecoff_header *head; + struct ecoff_section *section; + grub_uint32_t target_addr; + size_t program_size; + + program_size = ALIGN_ADDR (core_size); + if (comp == GRUB_COMPRESSION_NONE) + target_addr = (image_target->link_addr - decompress_size); + else + target_addr = ALIGN_UP (image_target->link_addr + + layout.kernel_size + total_module_size, 32); + + ecoff_img = xmalloc (program_size + sizeof (*head) + sizeof (*section)); + grub_memset (ecoff_img, 0, program_size + sizeof (*head) + sizeof (*section)); + head = (void *) ecoff_img; + section = (void *) (head + 1); + head->magic = image_target->bigendian ? grub_host_to_target16 (0x160) + : grub_host_to_target16 (0x166); + head->nsec = grub_host_to_target16 (1); + head->time = grub_host_to_target32 (0); + head->opt = grub_host_to_target16 (0x38); + head->flags = image_target->bigendian + ? grub_host_to_target16 (0x207) + : grub_host_to_target16 (0x103); + head->magic2 = grub_host_to_target16 (0x107); + head->textsize = grub_host_to_target32 (program_size); + head->entry = grub_host_to_target32 (target_addr); + head->text_start = grub_host_to_target32 (target_addr); + head->data_start = grub_host_to_target32 (target_addr + program_size); + grub_memcpy (section->name, ".text", sizeof (".text") - 1); + section->vaddr = grub_host_to_target32 (target_addr); + section->size = grub_host_to_target32 (program_size); + section->file_offset = grub_host_to_target32 (sizeof (*head) + sizeof (*section)); + if (!image_target->bigendian) + { + section->paddr = grub_host_to_target32 (0xaa60); + section->flags = grub_host_to_target32 (0x20); + } + memcpy (section + 1, core_img, core_size); + free (core_img); + core_img = ecoff_img; + core_size = program_size + sizeof (*head) + sizeof (*section); + } + break; + case IMAGE_LOONGSON_ELF: + case IMAGE_PPC: + case IMAGE_XEN: + case IMAGE_XEN_PVH: + case IMAGE_COREBOOT: + case IMAGE_I386_IEEE1275: + { + grub_uint64_t target_addr; + if (image_target->id == IMAGE_LOONGSON_ELF) + { + if (comp == GRUB_COMPRESSION_NONE) + target_addr = (image_target->link_addr - decompress_size); + else + target_addr = ALIGN_UP (image_target->link_addr + + layout.kernel_size + total_module_size, 32); + } + else + target_addr = image_target->link_addr; + if (image_target->voidp_sizeof == 4) + grub_mkimage_generate_elf32 (image_target, note, &core_img, &core_size, + target_addr, &layout); + else + grub_mkimage_generate_elf64 (image_target, note, &core_img, &core_size, + target_addr, &layout); + } + break; + } + + grub_util_write_image (core_img, core_size, out, outname); + free (core_img); + free (kernel_path); + free (layout.reloc_section); + + grub_util_free_path_list (path_list); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/util/setup.c b/GRUB2/MOD_SRC/grub-2.04/util/setup.c new file mode 100644 index 0000000..5d1c3e2 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/util/setup.c @@ -0,0 +1,878 @@ +/* grub-setup.c - make GRUB usable */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef GRUB_SETUP_SPARC64 +#include +#include +#include +#else +#include +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "progname.h" +#include +#include +#include +#include +#include + +#include + +/* On SPARC this program fills in various fields inside of the 'boot' and 'core' + * image files. + * + * The 'boot' image needs to know the OBP path name of the root + * device. It also needs to know the initial block number of + * 'core' (which is 'diskboot' concatenated with 'kernel' and + * all the modules, this is created by grub-mkimage). This resulting + * 'boot' image is 512 bytes in size and is placed in the second block + * of a partition. + * + * The initial 'diskboot' block acts as a loader for the actual GRUB + * kernel. It contains the loading code and then a block list. + * + * The block list of 'core' starts at the end of the 'diskboot' image + * and works it's way backwards towards the end of the code of 'diskboot'. + * + * We patch up the images with the necessary values and write out the + * result. + */ + +#ifdef GRUB_SETUP_SPARC64 +#define grub_target_to_host16(x) grub_be_to_cpu16(x) +#define grub_target_to_host32(x) grub_be_to_cpu32(x) +#define grub_target_to_host64(x) grub_be_to_cpu64(x) +#define grub_host_to_target16(x) grub_cpu_to_be16(x) +#define grub_host_to_target32(x) grub_cpu_to_be32(x) +#define grub_host_to_target64(x) grub_cpu_to_be64(x) +#elif defined (GRUB_SETUP_BIOS) +#define grub_target_to_host16(x) grub_le_to_cpu16(x) +#define grub_target_to_host32(x) grub_le_to_cpu32(x) +#define grub_target_to_host64(x) grub_le_to_cpu64(x) +#define grub_host_to_target16(x) grub_cpu_to_le16(x) +#define grub_host_to_target32(x) grub_cpu_to_le32(x) +#define grub_host_to_target64(x) grub_cpu_to_le64(x) +#else +#error Complete this +#endif + +static void +write_rootdev (grub_device_t root_dev, + char *boot_img, grub_uint64_t first_sector) +{ +#ifdef GRUB_SETUP_BIOS + { + grub_uint8_t *boot_drive; + void *kernel_sector; + boot_drive = (grub_uint8_t *) (boot_img + GRUB_BOOT_MACHINE_BOOT_DRIVE); + kernel_sector = (boot_img + GRUB_BOOT_MACHINE_KERNEL_SECTOR); + + /* FIXME: can this be skipped? */ + *boot_drive = 0xFF; + + grub_set_unaligned64 (kernel_sector, grub_cpu_to_le64 (first_sector)); + } +#endif +#ifdef GRUB_SETUP_SPARC64 + { + void *kernel_byte; + kernel_byte = (boot_img + GRUB_BOOT_AOUT_HEADER_SIZE + + GRUB_BOOT_MACHINE_KERNEL_BYTE); + grub_set_unaligned64 (kernel_byte, + grub_cpu_to_be64 (first_sector << GRUB_DISK_SECTOR_BITS)); + } +#endif +} + +#ifdef GRUB_SETUP_SPARC64 +#define BOOT_SECTOR 1 +#else +#define BOOT_SECTOR 0 +#endif + +/* Helper for setup. */ + +struct blocklists +{ + struct grub_boot_blocklist *first_block, *block; +#ifdef GRUB_SETUP_BIOS + grub_uint16_t current_segment; +#endif +#ifdef GRUB_SETUP_SPARC64 + grub_uint64_t gpt_offset; +#endif + grub_uint16_t last_length; + grub_disk_addr_t first_sector; +}; + +/* Helper for setup. */ +static void +save_blocklists (grub_disk_addr_t sector, unsigned offset, unsigned length, + void *data) +{ + struct blocklists *bl = data; + struct grub_boot_blocklist *prev = bl->block + 1; + grub_uint64_t seclen; + +#ifdef GRUB_SETUP_SPARC64 + sector -= bl->gpt_offset; +#endif + + grub_util_info ("saving <%" GRUB_HOST_PRIuLONG_LONG ",%u,%u>", + (unsigned long long) sector, offset, length); + + if (bl->first_sector == (grub_disk_addr_t) -1) + { + if (offset != 0 || length < GRUB_DISK_SECTOR_SIZE) + grub_util_error ("%s", _("the first sector of the core file is not sector-aligned")); + + bl->first_sector = sector; + sector++; + length -= GRUB_DISK_SECTOR_SIZE; + if (!length) + return; + } + + if (offset != 0 || bl->last_length != 0) + grub_util_error ("%s", _("non-sector-aligned data is found in the core file")); + + seclen = (length + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS; + + if (bl->block != bl->first_block + && (grub_target_to_host64 (prev->start) + + grub_target_to_host16 (prev->len)) == sector) + { + grub_uint16_t t = grub_target_to_host16 (prev->len); + t += seclen; + prev->len = grub_host_to_target16 (t); + } + else + { + bl->block->start = grub_host_to_target64 (sector); + bl->block->len = grub_host_to_target16 (seclen); +#ifdef GRUB_SETUP_BIOS + bl->block->segment = grub_host_to_target16 (bl->current_segment); +#endif + + bl->block--; + if (bl->block->len) + grub_util_error ("%s", _("the sectors of the core file are too fragmented")); + } + + bl->last_length = length & (GRUB_DISK_SECTOR_SIZE - 1); +#ifdef GRUB_SETUP_BIOS + bl->current_segment += seclen << (GRUB_DISK_SECTOR_BITS - 4); +#endif +} + +/* Context for setup/identify_partmap. */ +struct identify_partmap_ctx +{ + grub_partition_map_t dest_partmap; + grub_partition_t container; + int multiple_partmaps; +}; + +/* Helper for setup. + Unlike root_dev, with dest_dev we're interested in the partition map even + if dest_dev itself is a whole disk. */ +static int +identify_partmap (grub_disk_t disk __attribute__ ((unused)), + const grub_partition_t p, void *data) +{ + struct identify_partmap_ctx *ctx = data; + + if (p->parent != ctx->container) + return 0; + /* NetBSD and OpenBSD subpartitions have metadata inside a partition, + so they are safe to ignore. + */ + if (grub_strcmp (p->partmap->name, "netbsd") == 0 + || grub_strcmp (p->partmap->name, "openbsd") == 0) + return 0; + if (ctx->dest_partmap == NULL) + { + ctx->dest_partmap = p->partmap; + return 0; + } + if (ctx->dest_partmap == p->partmap) + return 0; + ctx->multiple_partmaps = 1; + return 1; +} + +#ifdef GRUB_SETUP_BIOS +#define SETUP grub_util_bios_setup +#elif GRUB_SETUP_SPARC64 +#define SETUP grub_util_sparc_setup +#else +#error "Shouldn't happen" +#endif + +void +SETUP (const char *dir, + const char *boot_file, const char *core_file, + const char *dest, int force, + int fs_probe, int allow_floppy, + int add_rs_codes __attribute__ ((unused))) /* unused on sparc64 */ +{ + char *core_path; + char *boot_img, *core_img, *boot_path; + char *root = 0; + size_t boot_size, core_size; + grub_uint16_t core_sectors; + grub_device_t root_dev = 0, dest_dev, core_dev; + grub_util_fd_t fp; + struct blocklists bl; + + bl.first_sector = (grub_disk_addr_t) -1; + +#ifdef GRUB_SETUP_BIOS + bl.current_segment = + GRUB_BOOT_I386_PC_KERNEL_SEG + (GRUB_DISK_SECTOR_SIZE >> 4); +#endif + bl.last_length = 0; + + /* Read the boot image by the OS service. */ + boot_path = grub_util_get_path (dir, boot_file); + boot_size = grub_util_get_image_size (boot_path); + if (boot_size != GRUB_DISK_SECTOR_SIZE) + grub_util_error (_("the size of `%s' is not %u"), + boot_path, GRUB_DISK_SECTOR_SIZE); + boot_img = grub_util_read_image (boot_path); + free (boot_path); + + core_path = grub_util_get_path (dir, core_file); + core_size = grub_util_get_image_size (core_path); + core_sectors = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) + >> GRUB_DISK_SECTOR_BITS); + if (core_size < GRUB_DISK_SECTOR_SIZE) + grub_util_error (_("the size of `%s' is too small"), core_path); +#ifdef GRUB_SETUP_BIOS + if (core_size > 0xFFFF * GRUB_DISK_SECTOR_SIZE) + grub_util_error (_("the size of `%s' is too large"), core_path); +#endif + + core_img = grub_util_read_image (core_path); + + /* Have FIRST_BLOCK to point to the first blocklist. */ + bl.first_block = (struct grub_boot_blocklist *) (core_img + + GRUB_DISK_SECTOR_SIZE + - sizeof (*bl.block)); + + grub_util_info ("Opening dest `%s'", dest); + dest_dev = grub_device_open (dest); + if (! dest_dev) + grub_util_error ("%s", grub_errmsg); + + core_dev = dest_dev; + + { + char **root_devices = grub_guess_root_devices (dir); + char **cur; + int found = 0; + + if (!root_devices) + grub_util_error (_("cannot find a device for %s (is /dev mounted?)"), dir); + + for (cur = root_devices; *cur; cur++) + { + char *drive; + grub_device_t try_dev; + + drive = grub_util_get_grub_dev (*cur); + if (!drive) + continue; + try_dev = grub_device_open (drive); + if (! try_dev) + { + free (drive); + continue; + } + if (!found && try_dev->disk->id == dest_dev->disk->id + && try_dev->disk->dev->id == dest_dev->disk->dev->id) + { + if (root_dev) + grub_device_close (root_dev); + free (root); + root_dev = try_dev; + root = drive; + found = 1; + continue; + } + if (!root_dev) + { + root_dev = try_dev; + root = drive; + continue; + } + grub_device_close (try_dev); + free (drive); + } + if (!root_dev) + { + root = grub_util_get_grub_dev ("/dev/sda"); + root_dev = grub_device_open (root); + if (root_dev) + grub_util_info ("guessing the root device failed, because of `%s'", grub_errmsg); + else + grub_util_error ("guessing the root device failed, because of `%s'", grub_errmsg); + } + grub_util_info ("guessed root_dev `%s' from " + "dir `%s'", root_dev->disk->name, dir); + + for (cur = root_devices; *cur; cur++) + free (*cur); + free (root_devices); + } + + grub_util_info ("setting the root device to `%s'", root); + if (grub_env_set ("root", root) != GRUB_ERR_NONE) + grub_util_error ("%s", grub_errmsg); + + { +#ifdef GRUB_SETUP_BIOS + char *tmp_img; + grub_uint8_t *boot_drive_check; + + /* Read the original sector from the disk. */ + tmp_img = xmalloc (GRUB_DISK_SECTOR_SIZE); + if (grub_disk_read (dest_dev->disk, 0, 0, GRUB_DISK_SECTOR_SIZE, tmp_img)) + grub_util_error ("%s", grub_errmsg); + + boot_drive_check = (grub_uint8_t *) (boot_img + + GRUB_BOOT_MACHINE_DRIVE_CHECK); + /* Copy the possible DOS BPB. */ + memcpy (boot_img + GRUB_BOOT_MACHINE_BPB_START, + tmp_img + GRUB_BOOT_MACHINE_BPB_START, + GRUB_BOOT_MACHINE_BPB_END - GRUB_BOOT_MACHINE_BPB_START); + + /* If DEST_DRIVE is a hard disk, enable the workaround, which is + for buggy BIOSes which don't pass boot drive correctly. Instead, + they pass 0x00 or 0x01 even when booted from 0x80. */ + if (!allow_floppy && !grub_util_biosdisk_is_floppy (dest_dev->disk)) + { + /* Replace the jmp (2 bytes) with double nop's. */ + boot_drive_check[0] = 0x90; + boot_drive_check[1] = 0x90; + } +#endif + + struct identify_partmap_ctx ctx = { + .dest_partmap = NULL, + .container = dest_dev->disk->partition, + .multiple_partmaps = 0 + }; + int is_ldm; + grub_err_t err; + grub_disk_addr_t *sectors; + int i; + grub_fs_t fs; + unsigned int nsec, maxsec; + + grub_partition_iterate (dest_dev->disk, identify_partmap, &ctx); + +#ifdef GRUB_SETUP_BIOS + /* Copy the partition table. */ + if (ctx.dest_partmap || + (!allow_floppy && !grub_util_biosdisk_is_floppy (dest_dev->disk))) + memcpy (boot_img + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC, + tmp_img + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC, + GRUB_BOOT_MACHINE_PART_END - GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC); + + free (tmp_img); +#endif + + if (ctx.container + && grub_strcmp (ctx.container->partmap->name, "msdos") == 0 + && ctx.dest_partmap + && (ctx.container->msdostype == GRUB_PC_PARTITION_TYPE_NETBSD + || ctx.container->msdostype == GRUB_PC_PARTITION_TYPE_OPENBSD)) + { + grub_util_warn ("%s", _("Attempting to install GRUB to a disk with multiple partition labels or both partition label and filesystem. This is not supported yet.")); + goto unable_to_embed; + } + + fs = grub_fs_probe (dest_dev); + if (!fs) + grub_errno = GRUB_ERR_NONE; + + is_ldm = grub_util_is_ldm (dest_dev->disk); + + if (fs_probe) + { + if (!fs && !ctx.dest_partmap) + grub_util_error (_("unable to identify a filesystem in %s; safety check can't be performed"), + dest_dev->disk->name); + if (fs && !fs->reserved_first_sector) + /* TRANSLATORS: Filesystem may reserve the space just GRUB isn't sure about it. */ + grub_util_error (_("%s appears to contain a %s filesystem which isn't known to " + "reserve space for DOS-style boot. Installing GRUB there could " + "result in FILESYSTEM DESTRUCTION if valuable data is overwritten " + "by grub-setup (--skip-fs-probe disables this " + "check, use at your own risk)"), dest_dev->disk->name, fs->name); + + if (ctx.dest_partmap && strcmp (ctx.dest_partmap->name, "msdos") != 0 + && strcmp (ctx.dest_partmap->name, "gpt") != 0 + && strcmp (ctx.dest_partmap->name, "bsd") != 0 + && strcmp (ctx.dest_partmap->name, "netbsd") != 0 + && strcmp (ctx.dest_partmap->name, "openbsd") != 0 + && strcmp (ctx.dest_partmap->name, "sunpc") != 0) + /* TRANSLATORS: Partition map may reserve the space just GRUB isn't sure about it. */ + grub_util_error (_("%s appears to contain a %s partition map which isn't known to " + "reserve space for DOS-style boot. Installing GRUB there could " + "result in FILESYSTEM DESTRUCTION if valuable data is overwritten " + "by grub-setup (--skip-fs-probe disables this " + "check, use at your own risk)"), dest_dev->disk->name, ctx.dest_partmap->name); + if (is_ldm && ctx.dest_partmap && strcmp (ctx.dest_partmap->name, "msdos") != 0 + && strcmp (ctx.dest_partmap->name, "gpt") != 0) + grub_util_error (_("%s appears to contain a %s partition map and " + "LDM which isn't known to be a safe combination." + " Installing GRUB there could " + "result in FILESYSTEM DESTRUCTION if valuable data" + " is overwritten " + "by grub-setup (--skip-fs-probe disables this " + "check, use at your own risk)"), + dest_dev->disk->name, ctx.dest_partmap->name); + + } + + if (! ctx.dest_partmap && ! fs && !is_ldm) + { + grub_util_warn ("%s", _("Attempting to install GRUB to a partitionless disk or to a partition. This is a BAD idea.")); + goto unable_to_embed; + } + if (ctx.multiple_partmaps || (ctx.dest_partmap && fs) || (is_ldm && fs)) + { + grub_util_warn ("%s", _("Attempting to install GRUB to a disk with multiple partition labels. This is not supported yet.")); + goto unable_to_embed; + } + + if (ctx.dest_partmap && !ctx.dest_partmap->embed) + { + grub_util_warn (_("Partition style `%s' doesn't support embedding"), + ctx.dest_partmap->name); + goto unable_to_embed; + } + + if (fs && !fs->fs_embed) + { + grub_util_warn (_("File system `%s' doesn't support embedding"), + fs->name); + goto unable_to_embed; + } + + nsec = core_sectors; + + if (add_rs_codes) + maxsec = 2 * core_sectors; + else + maxsec = core_sectors; + +#ifdef GRUB_SETUP_BIOS + if (maxsec > ((0x78000 - GRUB_KERNEL_I386_PC_LINK_ADDR) + >> GRUB_DISK_SECTOR_BITS)) + maxsec = ((0x78000 - GRUB_KERNEL_I386_PC_LINK_ADDR) + >> GRUB_DISK_SECTOR_BITS); +#endif + +#ifdef GRUB_SETUP_SPARC64 + /* + * On SPARC we need two extra. One is because we are combining the + * core.img with the boot.img. The other is because the boot sector + * starts at 1. + */ + nsec += 2; + maxsec += 2; +#endif + + if (is_ldm) + err = grub_util_ldm_embed (dest_dev->disk, &nsec, maxsec, + GRUB_EMBED_PCBIOS, §ors); + else if (ctx.dest_partmap) + err = ctx.dest_partmap->embed (dest_dev->disk, &nsec, maxsec, + GRUB_EMBED_PCBIOS, §ors); + else + err = fs->fs_embed (dest_dev, &nsec, maxsec, + GRUB_EMBED_PCBIOS, §ors); + if (!err && nsec < core_sectors) + { + err = grub_error (GRUB_ERR_OUT_OF_RANGE, + N_("Your embedding area is unusually small. " + "core.img won't fit in it.")); + } + + if (err) + { + grub_util_warn ("%s", grub_errmsg); + grub_errno = GRUB_ERR_NONE; + goto unable_to_embed; + } + + assert (nsec <= maxsec); + + /* Clean out the blocklists. */ + bl.block = bl.first_block; + while (bl.block->len) + { + grub_memset (bl.block, 0, sizeof (*bl.block)); + + bl.block--; + + if ((char *) bl.block <= core_img) + grub_util_error ("%s", _("no terminator in the core image")); + } + + bl.block = bl.first_block; + for (i = 0; i < nsec; i++) + save_blocklists (sectors[i] + grub_partition_get_start (ctx.container), + 0, GRUB_DISK_SECTOR_SIZE, &bl); + + /* Make sure that the last blocklist is a terminator. */ + if (bl.block == bl.first_block) + bl.block--; + bl.block->start = 0; + bl.block->len = 0; +#ifdef GRUB_SETUP_BIOS + bl.block->segment = 0; +#endif + +#ifdef GRUB_SETUP_SPARC64 + { + /* + * On SPARC, the block-list entries need to be based off the beginning + * of the parition, not the beginning of the disk. + */ + struct grub_boot_blocklist *block; + block = bl.first_block; + + while (block->len) + { + block->start -= bl.first_sector; + block--; + } + } + + /* + * Reserve space for the boot block since it can not be in the + * Parition table on SPARC. + */ + assert (bl.first_block->len > 2); + bl.first_block->start += 2; + bl.first_block->len -= 2; + write_rootdev (root_dev, boot_img, sectors[BOOT_SECTOR + 1] - bl.first_sector); +#endif + +#ifdef GRUB_SETUP_BIOS + write_rootdev (root_dev, boot_img, bl.first_sector); +#endif + + /* Round up to the nearest sector boundary, and zero the extra memory */ + core_img = xrealloc (core_img, nsec * GRUB_DISK_SECTOR_SIZE); + assert (core_img && (nsec * GRUB_DISK_SECTOR_SIZE >= core_size)); + memset (core_img + core_size, 0, nsec * GRUB_DISK_SECTOR_SIZE - core_size); + + bl.first_block = (struct grub_boot_blocklist *) (core_img + + GRUB_DISK_SECTOR_SIZE + - sizeof (*bl.block)); +#if GRUB_SETUP_BIOS + grub_size_t no_rs_length; + no_rs_length = grub_target_to_host16 + (grub_get_unaligned16 (core_img + + GRUB_DISK_SECTOR_SIZE + + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_LENGTH)); + + if (no_rs_length == 0xffff) + grub_util_error ("%s", _("core.img version mismatch")); + + if (add_rs_codes) + { + grub_set_unaligned32 ((core_img + GRUB_DISK_SECTOR_SIZE + + GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY), + grub_host_to_target32 (nsec * GRUB_DISK_SECTOR_SIZE - core_size)); + + void *tmp = xmalloc (core_size); + grub_memcpy (tmp, core_img, core_size); + grub_reed_solomon_add_redundancy (core_img + no_rs_length + GRUB_DISK_SECTOR_SIZE, + core_size - no_rs_length - GRUB_DISK_SECTOR_SIZE, + nsec * GRUB_DISK_SECTOR_SIZE + - core_size); + assert (grub_memcmp (tmp, core_img, core_size) == 0); + free (tmp); + } + + /* Write the core image onto the disk. */ + for (i = 0; i < nsec; i++) + grub_disk_write (dest_dev->disk, sectors[i], 0, + GRUB_DISK_SECTOR_SIZE, + core_img + i * GRUB_DISK_SECTOR_SIZE); +#endif + +#ifdef GRUB_SETUP_SPARC64 + { + int isec = BOOT_SECTOR; + + /* Write the boot image onto the disk. */ + if (grub_disk_write (dest_dev->disk, sectors[isec++], 0, + GRUB_DISK_SECTOR_SIZE, boot_img)) + grub_util_error ("%s", grub_errmsg); + + /* Write the core image onto the disk. */ + for (i = 0 ; isec < nsec; i++, isec++) + { + if (grub_disk_write (dest_dev->disk, sectors[isec], 0, + GRUB_DISK_SECTOR_SIZE, + core_img + i * GRUB_DISK_SECTOR_SIZE)) + grub_util_error ("%s", grub_errmsg); + } + } + +#endif + grub_free (sectors); + + goto finish; + } + +unable_to_embed: + + if (dest_dev->disk->dev->id != root_dev->disk->dev->id) + grub_util_error ("%s", _("embedding is not possible, but this is required for " + "RAID and LVM install")); + + { + grub_fs_t fs; + fs = grub_fs_probe (root_dev); + if (!fs) + grub_util_error (_("can't determine filesystem on %s"), root); + + if (!fs->blocklist_install) + grub_util_error (_("filesystem `%s' doesn't support blocklists"), + fs->name); + } + +#ifdef GRUB_SETUP_BIOS + if (dest_dev->disk->id != root_dev->disk->id + || dest_dev->disk->dev->id != root_dev->disk->dev->id) + /* TRANSLATORS: cross-disk refers to /boot being on one disk + but MBR on another. */ + grub_util_error ("%s", _("embedding is not possible, but this is required for " + "cross-disk install")); +#else + core_dev = root_dev; +#endif + + grub_util_warn ("%s", _("Embedding is not possible. GRUB can only be installed in this " + "setup by using blocklists. However, blocklists are UNRELIABLE and " + "their use is discouraged.")); + if (! force) + /* TRANSLATORS: Here GRUB refuses to continue with blocklist install. */ + grub_util_error ("%s", _("will not proceed with blocklists")); + + /* The core image must be put on a filesystem unfortunately. */ + grub_util_info ("will leave the core image on the filesystem"); + + grub_util_biosdisk_flush (root_dev->disk); + + /* Clean out the blocklists. */ + bl.block = bl.first_block; + while (bl.block->len) + { + bl.block->start = 0; + bl.block->len = 0; +#ifdef GRUB_SETUP_BIOS + bl.block->segment = 0; +#endif + + bl.block--; + + if ((char *) bl.block <= core_img) + grub_util_error ("%s", _("no terminator in the core image")); + } + + bl.block = bl.first_block; + +#ifdef GRUB_SETUP_SPARC64 + { + grub_partition_t container = root_dev->disk->partition; + bl.gpt_offset = 0; + + if (grub_strstr (container->partmap->name, "gpt")) + bl.gpt_offset = grub_partition_get_start (container); + } +#endif + + grub_install_get_blocklist (root_dev, core_path, core_img, core_size, + save_blocklists, &bl); + + if (bl.first_sector == (grub_disk_addr_t)-1) + grub_util_error ("%s", _("can't retrieve blocklists")); + +#ifdef GRUB_SETUP_SPARC64 + { + char *boot_devpath; + boot_devpath = (char *) (boot_img + + GRUB_BOOT_AOUT_HEADER_SIZE + + GRUB_BOOT_MACHINE_BOOT_DEVPATH); + if (dest_dev->disk->id != root_dev->disk->id + || dest_dev->disk->dev->id != root_dev->disk->dev->id) + { + char *dest_ofpath; + dest_ofpath + = grub_util_devname_to_ofpath (grub_util_biosdisk_get_osdev (root_dev->disk)); + /* FIXME handle NULL result */ + grub_util_info ("dest_ofpath is `%s'", dest_ofpath); + strncpy (boot_devpath, dest_ofpath, + GRUB_BOOT_MACHINE_BOOT_DEVPATH_END + - GRUB_BOOT_MACHINE_BOOT_DEVPATH - 1); + boot_devpath[GRUB_BOOT_MACHINE_BOOT_DEVPATH_END + - GRUB_BOOT_MACHINE_BOOT_DEVPATH - 1] = 0; + free (dest_ofpath); + } + else + { + grub_util_info ("non cross-disk install"); + memset (boot_devpath, 0, GRUB_BOOT_MACHINE_BOOT_DEVPATH_END + - GRUB_BOOT_MACHINE_BOOT_DEVPATH); + } + grub_util_info ("boot device path %s", boot_devpath); + } +#endif + + write_rootdev (root_dev, boot_img, bl.first_sector); + + /* Write the first two sectors of the core image onto the disk. */ + grub_util_info ("opening the core image `%s'", core_path); + fp = grub_util_fd_open (core_path, GRUB_UTIL_FD_O_WRONLY); + if (! GRUB_UTIL_FD_IS_VALID (fp)) + grub_util_error (_("cannot open `%s': %s"), core_path, + grub_util_fd_strerror ()); + + if (grub_util_fd_write (fp, core_img, GRUB_DISK_SECTOR_SIZE * 2) + != GRUB_DISK_SECTOR_SIZE * 2) + grub_util_error (_("cannot write to `%s': %s"), + core_path, strerror (errno)); + if (grub_util_fd_sync (fp) < 0) + grub_util_error (_("cannot sync `%s': %s"), core_path, strerror (errno)); + if (grub_util_fd_close (fp) < 0) + grub_util_error (_("cannot close `%s': %s"), core_path, strerror (errno)); + grub_util_biosdisk_flush (root_dev->disk); + + grub_disk_cache_invalidate_all (); + + { + char *buf, *ptr = core_img; + size_t len = core_size; + grub_uint64_t blk, offset = 0; + grub_partition_t container = core_dev->disk->partition; + grub_err_t err; + + core_dev->disk->partition = 0; +#ifdef GRUB_SETUP_SPARC64 + offset = bl.gpt_offset; +#endif + + buf = xmalloc (core_size); + blk = bl.first_sector; + err = grub_disk_read (core_dev->disk, blk + offset, 0, GRUB_DISK_SECTOR_SIZE, buf); + if (err) + grub_util_error (_("cannot read `%s': %s"), core_dev->disk->name, + grub_errmsg); + if (grub_memcmp (buf, ptr, GRUB_DISK_SECTOR_SIZE) != 0) + grub_util_error ("%s", _("blocklists are invalid")); + + ptr += GRUB_DISK_SECTOR_SIZE; + len -= GRUB_DISK_SECTOR_SIZE; + + bl.block = bl.first_block; + while (bl.block->len) + { + size_t cur = grub_target_to_host16 (bl.block->len) << GRUB_DISK_SECTOR_BITS; + blk = grub_target_to_host64 (bl.block->start); + + if (cur > len) + cur = len; + + err = grub_disk_read (core_dev->disk, blk + offset, 0, cur, buf); + if (err) + grub_util_error (_("cannot read `%s': %s"), core_dev->disk->name, + grub_errmsg); + + if (grub_memcmp (buf, ptr, cur) != 0) + grub_util_error ("%s", _("blocklists are invalid")); + + ptr += cur; + len -= cur; + bl.block--; + + if ((char *) bl.block <= core_img) + grub_util_error ("%s", _("no terminator in the core image")); + } + if (len) + grub_util_error ("%s", _("blocklists are incomplete")); + core_dev->disk->partition = container; + free (buf); + } + +#ifdef GRUB_SETUP_BIOS + finish: +#endif + + /* Write the boot image onto the disk. */ + if (grub_disk_write (dest_dev->disk, BOOT_SECTOR, + 0, GRUB_DISK_SECTOR_SIZE, boot_img)) + grub_util_error ("%s", grub_errmsg); + +#ifdef GRUB_SETUP_SPARC64 + finish: +#endif + + grub_util_biosdisk_flush (root_dev->disk); + grub_util_biosdisk_flush (dest_dev->disk); + + free (core_path); + free (core_img); + free (boot_img); + grub_device_close (dest_dev); + grub_device_close (root_dev); +} + diff --git a/GRUB2/buildgrub.sh b/GRUB2/buildgrub.sh new file mode 100644 index 0000000..ce27884 --- /dev/null +++ b/GRUB2/buildgrub.sh @@ -0,0 +1,87 @@ +#!/bin/bash + +VT_GRUB_DIR=$PWD + +rm -rf INSTALL +rm -rf SRC +rm -rf NBP +rm -rf PXE + +mkdir SRC +mkdir NBP +mkdir PXE + +tar -xf grub-2.04.tar.xz -C ./SRC/ + +/bin/cp -a ./MOD_SRC/grub-2.04 ./SRC/ + +cd ./SRC/grub-2.04 + + +# build for x86_64-efi +echo '======== build grub2 for x86_64-efi ===============' +make distclean +./autogen.sh +./configure --with-platform=efi --prefix=$VT_GRUB_DIR/INSTALL/ +make -j 16 || exit 1 +sh install.sh uefi + + +#build for i386-efi +echo '======== build grub2 for i386-efi ===============' +make distclean +./autogen.sh +./configure --target=i386 --with-platform=efi --prefix=$VT_GRUB_DIR/INSTALL/ +make -j 16 || exit 1 +sh install.sh i386efi + + + +#build for arm64 EFI +echo '======== build grub2 for arm64-efi ===============' +PATH=$PATH:/opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/bin +make distclean +./autogen.sh +./configure --prefix=$VT_GRUB_DIR/INSTALL/ \ +--target=aarch64 --with-platform=efi \ +--host=x86_64-linux-gnu \ +HOST_CC=x86_64-linux-gnu-gcc \ +BUILD_CC=gcc \ +TARGET_CC=aarch64-linux-gnu-gcc \ +TARGET_OBJCOPY=aarch64-linux-gnu-objcopy \ +TARGET_STRIP=aarch64-linux-gnu-strip TARGET_NM=aarch64-linux-gnu-nm \ +TARGET_RANLIB=aarch64-linux-gnu-ranlib +make -j 16 || exit 1 +sh install.sh arm64 + + +#build for mips64el EFI +#http://ftp.loongnix.org/os/loongnix-server/1.7/os/Source/SPackages/grub2-2.02-0.40.lns7.14.loongnix.src.rpm +make distclean +./autogen.sh +./configure --prefix=/home/share/Ventoy/GRUB2/INSTALL/ \ +--target=mips64el --with-platform=efi \ +--host=x86_64-linux-gnu \ +HOST_CC=x86_64-linux-gnu-gcc \ +BUILD_CC=gcc \ +TARGET_CC="mips-linux-gnu-gcc -mabi=64 -Wno-error=cast-align -Wno-error=misleading-indentation" \ +TARGET_OBJCOPY=mips-linux-gnu-objcopy \ +TARGET_STRIP=mips-linux-gnu-strip TARGET_NM=mips-linux-gnu-nm \ +TARGET_RANLIB=mips-linux-gnu-ranlib +make -j 16 || exit 1 +sh install.sh mips64el + + + +# build for i386-pc +echo '======== build grub2 for i386-pc ===============' +make distclean +./autogen.sh +./configure --target=i386 --with-platform=pc --prefix=$VT_GRUB_DIR/INSTALL/ +make -j 16 || exit 1 +sh install.sh + + + +cd ../../ + diff --git a/ICON/filechecksum.gif b/ICON/filechecksum.gif new file mode 100644 index 0000000..d526e20 Binary files /dev/null and b/ICON/filechecksum.gif differ diff --git a/ICON/forums.png b/ICON/forums.png new file mode 100644 index 0000000..ca92698 Binary files /dev/null and b/ICON/forums.png differ diff --git a/ICON/logo_128.png b/ICON/logo_128.png new file mode 100644 index 0000000..a13884a Binary files /dev/null and b/ICON/logo_128.png differ diff --git a/ICON/logo_16.png b/ICON/logo_16.png new file mode 100644 index 0000000..a5b068f Binary files /dev/null and b/ICON/logo_16.png differ diff --git a/ICON/logo_256.png b/ICON/logo_256.png new file mode 100644 index 0000000..d6df64f Binary files /dev/null and b/ICON/logo_256.png differ diff --git a/ICON/logo_32.png b/ICON/logo_32.png new file mode 100644 index 0000000..6e6618e Binary files /dev/null and b/ICON/logo_32.png differ diff --git a/ICON/logo_48.png b/ICON/logo_48.png new file mode 100644 index 0000000..9d0a332 Binary files /dev/null and b/ICON/logo_48.png differ diff --git a/ICON/logo_512.png b/ICON/logo_512.png new file mode 100644 index 0000000..6a1ec92 Binary files /dev/null and b/ICON/logo_512.png differ diff --git a/ICON/logo_64.png b/ICON/logo_64.png new file mode 100644 index 0000000..8b23b32 Binary files /dev/null and b/ICON/logo_64.png differ diff --git a/ICON/logo_72.png b/ICON/logo_72.png new file mode 100644 index 0000000..4f24cd0 Binary files /dev/null and b/ICON/logo_72.png differ diff --git a/IMG/cpio/sbin/init b/IMG/cpio/sbin/init new file mode 100644 index 0000000..15686c4 --- /dev/null +++ b/IMG/cpio/sbin/init @@ -0,0 +1,175 @@ +#!/ventoy/busybox/ash +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +#################################################################### +# # +# Step 1 : extract busybox & set busybox environment # +# # +#################################################################### + +export VTOY_ORG_PATH=$PATH +export VTOY_PATH=/ventoy +export BUSYBOX_PATH=$VTOY_PATH/busybox +export VTLOG=$VTOY_PATH/log +export FIND=$BUSYBOX_PATH/find +export GREP=$BUSYBOX_PATH/grep +export EGREP=$BUSYBOX_PATH/egrep +export CAT=$BUSYBOX_PATH/cat +export AWK=$BUSYBOX_PATH/awk +export SED=$BUSYBOX_PATH/sed +export SLEEP=$BUSYBOX_PATH/sleep +export HEAD=$BUSYBOX_PATH/head + +if [ -e $BUSYBOX_PATH/busyboxaa64.xz ]; then + export VTOY_ARCH=aarch64 +elif [ -e $BUSYBOX_PATH/busyboxm64e.xz ]; then + export VTOY_ARCH=mips64el +else + if [ -e $BUSYBOX_PATH/32h ]; then + export VTOY_ARCH=x86_64 + else + export VTOY_ARCH=i386 + fi +fi + +if [ "$VTOY_ARCH" = "i386" ]; then + if $BUSYBOX_PATH/vtchmod32 -6; then + export VTOY_ARCH=x86_64 + fi +fi + +echo $VTOY_ARCH > $VTOY_PATH/ventoy_arch + + +if [ "$VTOY_ARCH" = "aarch64" ]; then + $BUSYBOX_PATH/xzminidecaa64 < $BUSYBOX_PATH/busyboxaa64.xz > $BUSYBOX_PATH/busybox + $BUSYBOX_PATH/vtchmodaa64 $BUSYBOX_PATH/busybox +elif [ "$VTOY_ARCH" = "mips64el" ]; then + $BUSYBOX_PATH/xzminidecm64e < $BUSYBOX_PATH/busyboxm64e.xz > $BUSYBOX_PATH/busybox + $BUSYBOX_PATH/vtchmodm64e $BUSYBOX_PATH/busybox +elif [ "$VTOY_ARCH" = "x86_64" ]; then + $BUSYBOX_PATH/xzminidec64 < $BUSYBOX_PATH/busybox64.xz > $BUSYBOX_PATH/busybox + if [ -s $BUSYBOX_PATH/busybox ]; then + $BUSYBOX_PATH/vtchmod64 $BUSYBOX_PATH/busybox + else + $BUSYBOX_PATH/xzminidec64_musl < $BUSYBOX_PATH/busybox64.xz > $BUSYBOX_PATH/busybox + $BUSYBOX_PATH/vtchmod64_musl $BUSYBOX_PATH/busybox + fi +else + $BUSYBOX_PATH/xzminidec32 < $BUSYBOX_PATH/busybox32.xz > $BUSYBOX_PATH/busybox + $BUSYBOX_PATH/vtchmod32 $BUSYBOX_PATH/busybox +fi + +if [ -e $BUSYBOX_PATH/busybox ]; then + $BUSYBOX_PATH/busybox --install $BUSYBOX_PATH +else + $BUSYBOX_PATH/tmpxz -d $BUSYBOX_PATH/busybox32.xz + $BUSYBOX_PATH/busybox32 --install $BUSYBOX_PATH +fi + +export PATH=$BUSYBOX_PATH/:$VTOY_PATH/tool + +export VTOY_BREAK_LEVEL=$(hexdump -n 1 -s 449 -e '1/1 "%02x"' $VTOY_PATH/ventoy_os_param) +export VTOY_DEBUG_LEVEL=$(hexdump -n 1 -s 450 -e '1/1 "%02x"' $VTOY_PATH/ventoy_os_param) +export VTOY_LINUX_REMOUNT=$(hexdump -n 1 -s 454 -e '1/1 "%02x"' $VTOY_PATH/ventoy_os_param) + +#Fixme: busybox shell output redirect seems to have some bug in rhel5 +if uname -a | grep -q el5; then + VTOY_REDT_BUG=YES +fi + +if [ -z "$VTOY_REDT_BUG" ]; then + echo "============== VENTOY =================" >>$VTLOG +fi + +cd $VTOY_PATH +xz -d ventoy_chain.sh.xz +xz -d ventoy_loop.sh.xz + +if [ -n "$VTOY_REDT_BUG" ]; then + xz -d -c hook.cpio.xz | cpio -idm + xz -d -c tool.cpio.xz | cpio -idm + xz -d -c loop.cpio.xz | cpio -idm +else + xz -d -c hook.cpio.xz | cpio -idm 2>>$VTLOG + xz -d -c tool.cpio.xz | cpio -idm 2>>$VTLOG + xz -d -c loop.cpio.xz | cpio -idm 2>>$VTLOG +fi + + +if [ "$VTOY_ARCH" = "x86_64" ]; then + echo "Use x86_64 busybox toolkit ..." >>$VTLOG + $BUSYBOX_PATH/xzcat $BUSYBOX_PATH/xzcat64_musl.xz > $BUSYBOX_PATH/xzcat_musl + $BUSYBOX_PATH/chmod +x $BUSYBOX_PATH/xzcat_musl + ln -s $BUSYBOX_PATH/xzminidec64 $BUSYBOX_PATH/xzminidec + ln -s $VTOY_PATH/tool/dmsetup64 $VTOY_PATH/tool/dmsetup + ln -s $VTOY_PATH/tool/lunzip64 $VTOY_PATH/tool/lunzip + + rm -f $VTOY_PATH/tool/lz4cat $VTOY_PATH/tool/zstdcat + ln -s $VTOY_PATH/tool/lz4cat64 $VTOY_PATH/tool/lz4cat + ln -s $VTOY_PATH/tool/zstdcat64 $VTOY_PATH/tool/zstdcat +elif [ "$VTOY_ARCH" = "i386" ]; then + echo "Use i386 busybox toolkit ..." >>$VTLOG + $BUSYBOX_PATH/xzcat $BUSYBOX_PATH/xzcat32_musl.xz > $BUSYBOX_PATH/xzcat_musl + $BUSYBOX_PATH/chmod +x $BUSYBOX_PATH/xzcat_musl + ln -s $BUSYBOX_PATH/xzminidec32 $BUSYBOX_PATH/xzminidec + ln -s $VTOY_PATH/tool/dmsetup32 $VTOY_PATH/tool/dmsetup + ln -s $VTOY_PATH/tool/lunzip32 $VTOY_PATH/tool/lunzip + + if uname -a | egrep -q 'x86_64|amd64'; then + echo "zstdcat use 64bit ..." >>$VTLOG + rm -f $VTOY_PATH/tool/zstdcat + ln -s $VTOY_PATH/tool/zstdcat64 $VTOY_PATH/tool/zstdcat + fi +elif [ "$VTOY_ARCH" = "mips64el" ]; then + echo "Use MIPS64 busybox toolkit ..." >>$VTLOG + ln -s $BUSYBOX_PATH/xzminidecm64e $BUSYBOX_PATH/xzminidec + ln -s $VTOY_PATH/tool/dmsetupm64e $VTOY_PATH/tool/dmsetup + + # TBD + #ln -s $VTOY_PATH/tool/lunzipm64e $VTOY_PATH/tool/lunzip + + rm -f $VTOY_PATH/tool/lz4cat $VTOY_PATH/tool/zstdcat + ln -s $VTOY_PATH/tool/lz4catm64e $VTOY_PATH/tool/lz4cat + + # TBD + #ln -s $VTOY_PATH/tool/zstdcataa64 $VTOY_PATH/tool/zstdcat + +elif [ "$VTOY_ARCH" = "aarch64" ]; then + echo "Use ARM64 busybox toolkit ..." >>$VTLOG + ln -s $BUSYBOX_PATH/xzminidecaa64 $BUSYBOX_PATH/xzminidec + ln -s $VTOY_PATH/tool/dmsetupaa64 $VTOY_PATH/tool/dmsetup + ln -s $VTOY_PATH/tool/lunzipaa64 $VTOY_PATH/tool/lunzip + + rm -f $VTOY_PATH/tool/lz4cat $VTOY_PATH/tool/zstdcat + ln -s $VTOY_PATH/tool/lz4cataa64 $VTOY_PATH/tool/lz4cat + ln -s $VTOY_PATH/tool/zstdcataa64 $VTOY_PATH/tool/zstdcat +else + echo "Unknown busybox toolkit ..." >>$VTLOG +fi + +rm -f *.xz +cd / + +#################################################################### +# # +# Step 2 : Hand over to ventoy init # +# # +#################################################################### +exec $BUSYBOX_PATH/sh $VTOY_PATH/init diff --git a/IMG/cpio/ventoy/hook/adelie/disk-hook.sh b/IMG/cpio/ventoy/hook/adelie/disk-hook.sh new file mode 100644 index 0000000..8ee0579 --- /dev/null +++ b/IMG/cpio/ventoy/hook/adelie/disk-hook.sh @@ -0,0 +1,43 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/adelie/ventoy-hook.sh b/IMG/cpio/ventoy/hook/adelie/ventoy-hook.sh new file mode 100644 index 0000000..00d9eb0 --- /dev/null +++ b/IMG/cpio/ventoy/hook/adelie/ventoy-hook.sh @@ -0,0 +1,23 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$VTOY_PATH/hook/adelie/disk-hook.sh & + diff --git a/IMG/cpio/ventoy/hook/alpine/insert.sh b/IMG/cpio/ventoy/hook/alpine/insert.sh new file mode 100644 index 0000000..65c47fa --- /dev/null +++ b/IMG/cpio/ventoy/hook/alpine/insert.sh @@ -0,0 +1,4 @@ +for i in 1 2; do +if [ $i -eq 2 ]; then + /ventoy/busybox/sh /ventoy/hook/alpine/udev_disk_hook.sh +fi diff --git a/IMG/cpio/ventoy/hook/alpine/udev_disk_hook.sh b/IMG/cpio/ventoy/hook/alpine/udev_disk_hook.sh new file mode 100644 index 0000000..df4953e --- /dev/null +++ b/IMG/cpio/ventoy/hook/alpine/udev_disk_hook.sh @@ -0,0 +1,78 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +# +# longpanda: +# Alpine initramfs doesn't contain dm-mod or fuse module, +# and even the worse, the libpthread.so is not included too. +# So here we directly dump the modloop squashfs file from disk to rootfs. +# Fortunately, this file is not too big (< 100MB in alpine 3.11.3). +# After that: +# 1. mount the squashfs file +# 2. find the dm-mod module from the mountpoint and insmod +# 3. unmount and delete the squashfs file +# + +MDEV="${vtdiskname#/dev/}2" + +vtoydm -i -f $VTOY_PATH/ventoy_image_map -d /dev/${MDEV:0:-1} > $VTOY_PATH/iso_file_list + +vtLine=$(grep '[-][-] modloop-lts ' $VTOY_PATH/iso_file_list) +sector=$(echo $vtLine | awk '{print $(NF-1)}') +length=$(echo $vtLine | awk '{print $NF}') + +echo -n "Mounting boot media, please wait ......" +vtoydm -e -f $VTOY_PATH/ventoy_image_map -d /dev/${MDEV:0:-1} -s $sector -l $length -o /vt_modloop +echo "done" + +mkdir -p $VTOY_PATH/mnt +mount /vt_modloop $VTOY_PATH/mnt + +KoModPath=$(find $VTOY_PATH/mnt/ -name 'dm-mod.ko*') +vtlog "KoModPath=$KoModPath" + +if modinfo $KoModPath | grep -q 'depend.*dax'; then + vtlog "First install dax mod ..." + DaxModPath=$(echo $KoModPath | sed 's#md/dm-mod#dax/dax#') + vtlog "insmod $DaxModPath" + insmod $DaxModPath +fi + +insmod $KoModPath + +umount $VTOY_PATH/mnt +rm -f /vt_modloop + +ventoy_udev_disk_common_hook "$MDEV" "noreplace" + +# OK finish +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/alpine/ventoy-hook.sh b/IMG/cpio/ventoy/hook/alpine/ventoy-hook.sh new file mode 100644 index 0000000..f894966 --- /dev/null +++ b/IMG/cpio/ventoy/hook/alpine/ventoy-hook.sh @@ -0,0 +1,35 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +LineBegin=$(grep -n "ebegin.*Mounting boot media" /init | awk -F: '{print $1}') + +grep -n "^eend" /init > /t.list +while read line; do + LineEnd=$(echo $line | awk -F: '{print $1}') + if [ $LineEnd -gt $LineBegin ]; then + sed "${LineEnd}i\done" -i /init + sed "${LineBegin}r /ventoy/hook/alpine/insert.sh" -i /init + break + fi +done < /t.list +rm -f /t.list diff --git a/IMG/cpio/ventoy/hook/alt/udev_disk_hook.sh b/IMG/cpio/ventoy/hook/alt/udev_disk_hook.sh new file mode 100644 index 0000000..9a7fc66 --- /dev/null +++ b/IMG/cpio/ventoy/hook/alt/udev_disk_hook.sh @@ -0,0 +1,47 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished || not_ventoy_disk "${1:0:-1}"; then + exit 0 +fi + +ventoy_udev_disk_common_hook $* "noreplace" + +if ! [ -e $VTOY_DM_PATH ]; then + blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') + mknod -m 0666 $VTOY_DM_PATH b $blkdev_num +fi + +# +# We do a trick for ATL series here. +# Use /dev/vtCheatLoop and wapper it as a cdrom with bind mount. +# Then the installer will accept /dev/vtCheatLoop as the install medium. +# +vtCheatLoop=loop6 +ventoy_copy_device_mapper /dev/$vtCheatLoop +$BUSYBOX_PATH/mkdir -p /tmp/$vtCheatLoop/device/ +echo 5 > /tmp/$vtCheatLoop/device/type +$BUSYBOX_PATH/mount --bind /tmp/$vtCheatLoop /sys/block/$vtCheatLoop >> $VTLOG 2>&1 + + +# OK finish +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/alt/ventoy-hook.sh b/IMG/cpio/ventoy/hook/alt/ventoy-hook.sh new file mode 100644 index 0000000..3fabb01 --- /dev/null +++ b/IMG/cpio/ventoy/hook/alt/ventoy-hook.sh @@ -0,0 +1,24 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +ventoy_systemd_udevd_work_around + +ventoy_add_udev_rule "$VTOY_PATH/hook/alt/udev_disk_hook.sh %k" diff --git a/IMG/cpio/ventoy/hook/android/ventoy-disk.sh b/IMG/cpio/ventoy/hook/android/ventoy-disk.sh new file mode 100644 index 0000000..a9aee8d --- /dev/null +++ b/IMG/cpio/ventoy/hook/android/ventoy-disk.sh @@ -0,0 +1,42 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +if ! [ -e $VTOY_DM_PATH ]; then + blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') + mknod -m 0666 $VTOY_DM_PATH b $blkdev_num +fi + +# OK finish +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/android/ventoy-hook.sh b/IMG/cpio/ventoy/hook/android/ventoy-hook.sh new file mode 100644 index 0000000..4a315be --- /dev/null +++ b/IMG/cpio/ventoy/hook/android/ventoy-hook.sh @@ -0,0 +1,27 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +if ! [ -d /dev ]; then + $BUSYBOX_PATH/mkdir /dev +fi + +$SED "1a\export ROOT=/dev/mapper/ventoy" -i /init +$SED "/check_root \$device/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/android/ventoy-disk.sh" -i /init diff --git a/IMG/cpio/ventoy/hook/arch/ovios-disk.sh b/IMG/cpio/ventoy/hook/arch/ovios-disk.sh new file mode 100644 index 0000000..fe7173d --- /dev/null +++ b/IMG/cpio/ventoy/hook/arch/ovios-disk.sh @@ -0,0 +1,53 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "######### $0 $* ############" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +blkdev_num_mknod=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) + +vtlog "blkdev_num=$blkdev_num blkdev_num_mknod=$blkdev_num_mknod vtDM=$vtDM" + +if [ -b /dev/$vtDM ]; then + vtlog "dev already exist ..." +else + vtlog "mknode dev ..." + mknod -m 660 /dev/$vtDM b $blkdev_num_mknod +fi + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/arch/ventoy-disk.sh b/IMG/cpio/ventoy/hook/arch/ventoy-disk.sh new file mode 100644 index 0000000..31e65f0 --- /dev/null +++ b/IMG/cpio/ventoy/hook/arch/ventoy-disk.sh @@ -0,0 +1,75 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "######### $0 $* ############" + +if is_ventoy_hook_finished; then + exit 0 +fi + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) +vtlog "blkdev_num=$blkdev_num vtDM=$vtDM ..." + +while [ -n "Y" ]; do + if [ -b /dev/$vtDM ]; then + break + else + sleep 0.3 + fi +done + +if [ -n "$1" ]; then + vtlog "ln -s /dev/$vtDM $1" + + if [ -e "$1" ]; then + vtlog "$1 already exist" + else + ln -s /dev/$vtDM "$1" + fi +else + vtLABEL=$($BUSYBOX_PATH/blkid /dev/$vtDM | $SED 's/.*LABEL="\([^"]*\)".*/\1/') + vtlog "vtLABEL is $vtLABEL" + + if [ -z "$vtLABEL" ]; then + vtLABEL=$($SED "s/.*label=\([^ ]*\)/\1/" /proc/cmdline) + vtlog "vtLABEL is $vtLABEL from cmdline" + fi + + if [ -e "/dev/disk/by-label/$vtLABEL" ]; then + vtlog "$1 already exist" + else + ln -s /dev/$vtDM "/dev/disk/by-label/$vtLABEL" + fi +fi + +# OK finish +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/arch/ventoy-hook.sh b/IMG/cpio/ventoy/hook/arch/ventoy-hook.sh new file mode 100644 index 0000000..be5a985 --- /dev/null +++ b/IMG/cpio/ventoy/hook/arch/ventoy-hook.sh @@ -0,0 +1,71 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +if $GREP -q '^"$mount_handler"' /init; then + echo 'use mount_handler1 ...' >> $VTLOG + + vthookfile=/hooks/archiso + + if [ -e /hooks/miso ]; then + vthookfile=/hooks/miso + $SED "/^\"\$mount_handler\"/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/arch/ventoy-disk.sh \"\$misodevice\"" -i /init + elif [ -e /hooks/artix ]; then + vthookfile=/hooks/artix + $SED "/^\"\$mount_handler\"/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/arch/ventoy-disk.sh \"\$artixdevice\"" -i /init + else + $SED "/^\"\$mount_handler\"/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/arch/ventoy-disk.sh \"\$archisodevice\"" -i /init + fi + + if [ -f $vthookfile ]; then + $SED '/while ! poll_device "${dev}"/a\ if /ventoy/busybox/sh /ventoy/hook/arch/ventoy-timeout.sh ${dev}; then break; fi' -i $vthookfile + fi +elif $GREP -q '^$mount_handler' /init; then + echo 'use mount_handler2 ...' >> $VTLOG + $SED "/^\$mount_handler/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/arch/ventoy-disk.sh" -i /init + +elif $GREP -q '^KEEP_SEARCHING' /init; then + echo 'KEEP_SEARCHING found ...' >> $VTLOG + $SED "/^KEEP_SEARCHING/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/arch/ovios-disk.sh " -i /init + + $BUSYBOX_PATH/mkdir -p /dev + $BUSYBOX_PATH/mkdir -p /sys + $BUSYBOX_PATH/mount -t sysfs sys /sys + +else + # some archlinux initramfs doesn't contain device-mapper udev rules file + ARCH_UDEV_DIR=$(ventoy_get_udev_conf_dir) + if [ -s "$ARCH_UDEV_DIR/13-dm-disk.rules" ]; then + echo 'dm-disk rule exist' >> $VTLOG + else + echo 'Copy dm-disk rule file' >> $VTLOG + $CAT $VTOY_PATH/hook/default/13-dm-disk.rules > "$ARCH_UDEV_DIR/13-dm-disk.rules" + fi + + # use default proc + ventoy_systemd_udevd_work_around + + ventoy_add_udev_rule "$VTOY_PATH/hook/default/udev_disk_hook.sh %k" +fi + +if [ -f $VTOY_PATH/ventoy_persistent_map ]; then + $SED "1 aexport cow_label=vtoycow" -i /init + $SED "/parse.*cmdline/aecho cow_label=vtoycow>>/tmp/cmdline" -i /init +fi diff --git a/IMG/cpio/ventoy/hook/arch/ventoy-timeout.sh b/IMG/cpio/ventoy/hook/arch/ventoy-timeout.sh new file mode 100644 index 0000000..fec9cc0 --- /dev/null +++ b/IMG/cpio/ventoy/hook/arch/ventoy-timeout.sh @@ -0,0 +1,36 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "######### $0 $* ############" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) + +if [ -b /dev/$vtDM ]; then + vtlog "ln -s /dev/$vtDM $1" + ln -s /dev/$vtDM "$1" + exit 0 +else + vtlog "Device-mapper not found" + exit 1 +fi + + diff --git a/IMG/cpio/ventoy/hook/aryalinux/disk_hook.sh b/IMG/cpio/ventoy/hook/aryalinux/disk_hook.sh new file mode 100644 index 0000000..d0e1f25 --- /dev/null +++ b/IMG/cpio/ventoy/hook/aryalinux/disk_hook.sh @@ -0,0 +1,54 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +mkdir /sys +mount -t sysfs sys /sys + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +blkdev_num_mknod=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) + +vtlog "blkdev_num=$blkdev_num blkdev_num_mknod=$blkdev_num_mknod vtDM=$vtDM" + +if [ -b /dev/$vtDM ]; then + vtlog "dev already exist ..." +else + vtlog "mknode dev ..." + mknod -m 660 /dev/$vtDM b $blkdev_num_mknod +fi + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/aryalinux/ventoy-hook.sh b/IMG/cpio/ventoy/hook/aryalinux/ventoy-hook.sh new file mode 100644 index 0000000..1900fd0 --- /dev/null +++ b/IMG/cpio/ventoy/hook/aryalinux/ventoy-hook.sh @@ -0,0 +1,26 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$BUSYBOX_PATH/mkdir /dev +$BUSYBOX_PATH/mknod -m 660 /dev/console c 5 1 + +$SED "/for device in/i $BUSYBOX_PATH/sh $VTOY_PATH/hook/aryalinux/disk_hook.sh" -i /init +#$SED "/for device in/i exec $BUSYBOX_PATH/sh" -i /init diff --git a/IMG/cpio/ventoy/hook/austrumi/disk_hook.sh b/IMG/cpio/ventoy/hook/austrumi/disk_hook.sh new file mode 100644 index 0000000..becb5ce --- /dev/null +++ b/IMG/cpio/ventoy/hook/austrumi/disk_hook.sh @@ -0,0 +1,57 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +if check_usb_disk_ready "$vtdiskname"; then + vtlog "check_usb_disk_ready ok" +else + vtlog "check_usb_disk_ready error" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" + +# blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +# blkdev_num_mknod=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +# vtDM=$(ventoy_find_dm_id ${blkdev_num}) + +# vtlog "blkdev_num=$blkdev_num blkdev_num_mknod=$blkdev_num_mknod vtDM=$vtDM" + +# if [ -b /dev/$vtDM ]; then + # vtlog "dev already exist ..." +# else + # vtlog "mknode dev ..." + # mknod -m 660 /dev/$vtDM b $blkdev_num_mknod +# fi + +PATH=$VTPATH_OLD + + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/austrumi/ventoy-hook.sh b/IMG/cpio/ventoy/hook/austrumi/ventoy-hook.sh new file mode 100644 index 0000000..5785dee --- /dev/null +++ b/IMG/cpio/ventoy/hook/austrumi/ventoy-hook.sh @@ -0,0 +1,24 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/find_usb *(/a $BUSYBOX_PATH/sh $VTOY_PATH/hook/austrumi/disk_hook.sh" -i /init +$SED "s/BOOT_TYPE=livecd/BOOT_TYPE=usb/g" -i /init + diff --git a/IMG/cpio/ventoy/hook/berry/ventoy-disk.sh b/IMG/cpio/ventoy/hook/berry/ventoy-disk.sh new file mode 100644 index 0000000..179439b --- /dev/null +++ b/IMG/cpio/ventoy/hook/berry/ventoy-disk.sh @@ -0,0 +1,41 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" + +PATH=$VTPATH_OLD + + +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/berry/ventoy-hook.sh b/IMG/cpio/ventoy/hook/berry/ventoy-hook.sh new file mode 100644 index 0000000..2558523 --- /dev/null +++ b/IMG/cpio/ventoy/hook/berry/ventoy-hook.sh @@ -0,0 +1,20 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +$SED "/for .*\$DEVICES/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/berry/ventoy-disk.sh" -i /init diff --git a/IMG/cpio/ventoy/hook/blackPanther/ventoy-hook.sh b/IMG/cpio/ventoy/hook/blackPanther/ventoy-hook.sh new file mode 100644 index 0000000..e3b19f4 --- /dev/null +++ b/IMG/cpio/ventoy/hook/blackPanther/ventoy-hook.sh @@ -0,0 +1,25 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +ventoy_set_inotify_script blackPanther/ventoy-inotifyd-hook.sh +$BUSYBOX_PATH/cp -a $VTOY_PATH/hook/blackPanther/ventoy-inotifyd-start.sh /lib/dracut/hooks/pre-udev/00-ventoy-inotifyd-start.sh + +$SED "s#printf\(.*\)\$CMDLINE#printf\1 root=/dev/ventoy \$CMDLINE root=/dev/ventoy#" -i /lib/dracut-lib.sh diff --git a/IMG/cpio/ventoy/hook/blackPanther/ventoy-inotifyd-hook.sh b/IMG/cpio/ventoy/hook/blackPanther/ventoy-inotifyd-hook.sh new file mode 100644 index 0000000..caa80d4 --- /dev/null +++ b/IMG/cpio/ventoy/hook/blackPanther/ventoy-inotifyd-hook.sh @@ -0,0 +1,44 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +if is_inotify_ventoy_part $3; then + + vtlog "##### INOTIFYD: $2/$3 is created (YES) ..." + + vtlog "find ventoy partition ..." + $BUSYBOX_PATH/sh $VTOY_PATH/hook/default/udev_disk_hook.sh $3 noreplace + + blkdev_num_dev=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') + mknod -m 660 /dev/ventoy b $blkdev_num_dev + blackPanther-root /dev/ventoy + + set_ventoy_hook_finish +else + vtlog "##### INOTIFYD: $2/$3 is created (NO) ..." +fi + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/blackPanther/ventoy-inotifyd-start.sh b/IMG/cpio/ventoy/hook/blackPanther/ventoy-inotifyd-start.sh new file mode 100644 index 0000000..62e10a3 --- /dev/null +++ b/IMG/cpio/ventoy/hook/blackPanther/ventoy-inotifyd-start.sh @@ -0,0 +1,32 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtHook=$($CAT $VTOY_PATH/inotifyd-hook-script.txt) + +vtdisk=$(get_ventoy_disk_name) +if [ "$vtdisk" = "unknown" ]; then + vtlog "... start inotifyd listen $vtHook ..." + $BUSYBOX_PATH/nohup $VTOY_PATH/tool/inotifyd $vtHook /dev:n 2>&- & +else + vtlog "... $vtdisk already exist ..." + $BUSYBOX_PATH/sh $vtHook n /dev "${vtdisk#/dev/}2" +fi + diff --git a/IMG/cpio/ventoy/hook/cdlinux/disk-hook.sh b/IMG/cpio/ventoy/hook/cdlinux/disk-hook.sh new file mode 100644 index 0000000..3e46fbf --- /dev/null +++ b/IMG/cpio/ventoy/hook/cdlinux/disk-hook.sh @@ -0,0 +1,47 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +mknod -m 0666 /dev/ventoy b $blkdev_num + + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/cdlinux/ventoy-hook.sh b/IMG/cpio/ventoy/hook/cdlinux/ventoy-hook.sh new file mode 100644 index 0000000..0bbe835 --- /dev/null +++ b/IMG/cpio/ventoy/hook/cdlinux/ventoy-hook.sh @@ -0,0 +1,47 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +echo "CDlinux process..." >> $VTLOG + +$BUSYBOX_PATH/mknod -m 0660 /ventoy/ram0 b 1 0 + +$BUSYBOX_PATH/mkdir /vtmnt /ventoy_rdroot +$BUSYBOX_PATH/mount -t squashfs /ventoy/ram0 /vtmnt + +$BUSYBOX_PATH/mount -nt tmpfs -o mode=755 tmpfs /ventoy_rdroot + +$BUSYBOX_PATH/cp -a /vtmnt/* /ventoy_rdroot +$BUSYBOX_PATH/ls -1a /vtmnt/ | $GREP '^\.[^.]' | while read vtLine; do + $BUSYBOX_PATH/cp -a /vtmnt/$vtLine /ventoy_rdroot +done + +$BUSYBOX_PATH/umount /vtmnt && $BUSYBOX_PATH/rm -rf /vtmnt +$BUSYBOX_PATH/cp -a /ventoy /ventoy_rdroot + +if [ -f /etc/default/cdlinux ]; then + echo "CDL_WAIT=60" >> /etc/default/cdlinux +fi + +echo 'echo "CDL_DEV=/dev/mapper/ventoy" >>"$VAR_FILE"' >> /ventoy_rdroot/etc/rc.d/rc.var + +ventoy_set_rule_dir_prefix /ventoy_rdroot +ventoy_systemd_udevd_work_around +ventoy_add_udev_rule "$VTOY_PATH/hook/default/udev_disk_hook.sh %k noreplace" diff --git a/IMG/cpio/ventoy/hook/chimera/disk_hook.sh b/IMG/cpio/ventoy/hook/chimera/disk_hook.sh new file mode 100644 index 0000000..7893b74 --- /dev/null +++ b/IMG/cpio/ventoy/hook/chimera/disk_hook.sh @@ -0,0 +1,35 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +for i in 0 1 2 3 4 5 6 7 8 9; do + vtdiskname=$(get_ventoy_disk_name) + if [ "$vtdiskname" = "unknown" ]; then + vtlog "wait for disk ..." + $SLEEP 3 + else + break + fi +done + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" + +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/chimera/ventoy-hook.sh b/IMG/cpio/ventoy/hook/chimera/ventoy-hook.sh new file mode 100644 index 0000000..a138088 --- /dev/null +++ b/IMG/cpio/ventoy/hook/chimera/ventoy-hook.sh @@ -0,0 +1,22 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/maybe_break *premount/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/chimera/disk_hook.sh" -i /init diff --git a/IMG/cpio/ventoy/hook/clear/disk-hook.sh b/IMG/cpio/ventoy/hook/clear/disk-hook.sh new file mode 100644 index 0000000..8ee0579 --- /dev/null +++ b/IMG/cpio/ventoy/hook/clear/disk-hook.sh @@ -0,0 +1,43 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/clear/hidden-hook.sh b/IMG/cpio/ventoy/hook/clear/hidden-hook.sh new file mode 100644 index 0000000..9b461b0 --- /dev/null +++ b/IMG/cpio/ventoy/hook/clear/hidden-hook.sh @@ -0,0 +1,43 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +NEWROOT=$(grep switch_root /init | awk '{print $3}') + +for i in 'usr/bin' 'usr/sbin'; do + if [ -f $NEWROOT/$i/udevadm ]; then + UPATH=$i + break + fi +done + +blkdev_num=$(dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) + +sed "s#UPATH=.*#UPATH=/$UPATH#" -i /ventoy/hook/clear/udevadm +sed "s#DM=.*#DM=$vtDM#" -i /ventoy/hook/clear/udevadm + + +mv $NEWROOT/$UPATH/udevadm $NEWROOT/$UPATH/udevadm_bk +cp -a /ventoy/hook/clear/udevadm $NEWROOT/$UPATH/udevadm +chmod 777 $NEWROOT/$UPATH/udevadm + diff --git a/IMG/cpio/ventoy/hook/clear/udevadm b/IMG/cpio/ventoy/hook/clear/udevadm new file mode 100644 index 0000000..0977a41 --- /dev/null +++ b/IMG/cpio/ventoy/hook/clear/udevadm @@ -0,0 +1,12 @@ +#!/bin/bash + +UPATH=/usr/bin +DM=dm-0 + +rm -f $UPATH/udevadm +mv $UPATH/udevadm_bk $UPATH/udevadm + +echo 1 > /tmp/vthidden +mount --bind /tmp/vthidden /sys/block/$DM/hidden + +exec $UPATH/udevadm "$@" diff --git a/IMG/cpio/ventoy/hook/clear/ventoy-hook.sh b/IMG/cpio/ventoy/hook/clear/ventoy-hook.sh new file mode 100644 index 0000000..3d7e2b5 --- /dev/null +++ b/IMG/cpio/ventoy/hook/clear/ventoy-hook.sh @@ -0,0 +1,31 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +if $GREP -q find_and_mount_installer /init; then + echo "find_and_mount_installer" >> $VTLOG + $SED "/find_and_mount_installer *$/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/clear/disk-hook.sh" -i /init +else + echo "find_installer" >> $VTLOG + $SED "/\$.*find_installer/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/clear/disk-hook.sh" -i /init +fi + +#issue 1674 +$SED "/switch_root/i $BUSYBOX_PATH/sh $VTOY_PATH/hook/clear/hidden-hook.sh" -i /init diff --git a/IMG/cpio/ventoy/hook/crux/disk_hook.sh b/IMG/cpio/ventoy/hook/crux/disk_hook.sh new file mode 100644 index 0000000..3afa8b9 --- /dev/null +++ b/IMG/cpio/ventoy/hook/crux/disk_hook.sh @@ -0,0 +1,52 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +for i in 0 1 2 3 4 5 6 7 8 9; do + vtdiskname=$(get_ventoy_disk_name) + if [ "$vtdiskname" = "unknown" ]; then + vtlog "wait for disk ..." + $SLEEP 3 + else + break + fi +done + +# no need since 3.6.1 +$BUSYBOX_PATH/modprobe dax > /dev/null 2>&1 +$BUSYBOX_PATH/modprobe dm-mod > /dev/null 2>&1 + +if $GREP -q 'device-mapper' /proc/devices; then + vtlog "dm-mod module check success ..." +else + vtlog "Need to load dm-mod module ..." + ventoy_extract_vtloopex ${vtdiskname}2 crux + + vtKver=$(uname -r) + vtLoopExDir=$VTOY_PATH/vtloopex/crux/vtloopex + + ventoy_check_install_module_xz $vtLoopExDir/dm-mod/$vtKver/64/dax.ko + ventoy_check_install_module_xz $vtLoopExDir/dm-mod/$vtKver/64/dm-mod.ko +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" + +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/crux/ventoy-hook.sh b/IMG/cpio/ventoy/hook/crux/ventoy-hook.sh new file mode 100644 index 0000000..8c5d048 --- /dev/null +++ b/IMG/cpio/ventoy/hook/crux/ventoy-hook.sh @@ -0,0 +1,22 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/find_and_mount_media.*(/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/crux/disk_hook.sh" -i /init diff --git a/IMG/cpio/ventoy/hook/cucumber/disk-hook.sh b/IMG/cpio/ventoy/hook/cucumber/disk-hook.sh new file mode 100644 index 0000000..a5b7b95 --- /dev/null +++ b/IMG/cpio/ventoy/hook/cucumber/disk-hook.sh @@ -0,0 +1,52 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$(dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) + +vtlog "mount media /dev/$vtDM ..." +if ! [ -e /media/install ]; then + mkdir -p /media/install +fi +mount /dev/$vtDM /media/install + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/cucumber/ventoy-hook.sh b/IMG/cpio/ventoy/hook/cucumber/ventoy-hook.sh new file mode 100644 index 0000000..4f0363c --- /dev/null +++ b/IMG/cpio/ventoy/hook/cucumber/ventoy-hook.sh @@ -0,0 +1,26 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +if [ -e /sbin/mount_installer ]; then + echo "hook at mount_installer ..." >> $VTLOG + $SED "1 a $BUSYBOX_PATH/sh $VTOY_PATH/hook/cucumber/disk-hook.sh" -i /sbin/mount_installer +fi + diff --git a/IMG/cpio/ventoy/hook/daphile/disk_hook.sh b/IMG/cpio/ventoy/hook/daphile/disk_hook.sh new file mode 100644 index 0000000..75886f4 --- /dev/null +++ b/IMG/cpio/ventoy/hook/daphile/disk_hook.sh @@ -0,0 +1,44 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +/sbin/mdev -s + +# Just for KVM test environment +$BUSYBOX_PATH/modprobe virtio_blk 2>/dev/null +$BUSYBOX_PATH/modprobe virtio_pci 2>/dev/null + +for i in 0 1 2 3 4 5 6 7 8 9; do + vtdiskname=$(get_ventoy_disk_name) + if [ "$vtdiskname" = "unknown" ]; then + vtlog "wait for disk ..." + $SLEEP 2 + else + break + fi +done + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +$BUSYBOX_PATH/rm -f /dev/dm-* + + +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/daphile/ventoy-hook.sh b/IMG/cpio/ventoy/hook/daphile/ventoy-hook.sh new file mode 100644 index 0000000..8deee62 --- /dev/null +++ b/IMG/cpio/ventoy/hook/daphile/ventoy-hook.sh @@ -0,0 +1,24 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/mount_boot[^(]*$/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/daphile/disk_hook.sh" -i /init + +$SED "s#'\.\*/block/mmcblk[^ ]*'#'\.\*/block/dm-[0-9]*'#" -i /init diff --git a/IMG/cpio/ventoy/hook/debian/antix-disk.sh b/IMG/cpio/ventoy/hook/debian/antix-disk.sh new file mode 100644 index 0000000..c2f26b3 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/antix-disk.sh @@ -0,0 +1,124 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + + +ventoy_os_install_dmsetup_by_unsquashfs() { + vtlog "ventoy_os_install_dmsetup_by_unsquashfs $*" + + vtKoPo=$(ventoy_get_module_postfix) + vtlog "vtKoPo=$vtKoPo" + + vtoydm -i -f $VTOY_PATH/ventoy_image_map -d $1 > $VTOY_PATH/iso_file_list + + vtline=$(grep '[-][-] linuxfs ' $VTOY_PATH/iso_file_list) + sector=$(echo $vtline | awk '{print $(NF-1)}') + length=$(echo $vtline | awk '{print $NF}') + + vtoydm -E -f $VTOY_PATH/ventoy_image_map -d $1 -s $sector -l $length -o $VTOY_PATH/fsdisk + + dmModPath="/usr/lib/modules/$vtKerVer/kernel/drivers/md/dm-mod.$vtKoPo" + echo $dmModPath > $VTOY_PATH/fsextract + vtoy_unsquashfs -d $VTOY_PATH/sqfs -n -q -e $VTOY_PATH/fsextract $VTOY_PATH/fsdisk 2>>$VTLOG + + if ! [ -e $VTOY_PATH/sqfs${dmModPath} ]; then + rm -rf $VTOY_PATH/sqfs + dmModPath="/lib/modules/$vtKerVer/kernel/drivers/md/dm-mod.$vtKoPo" + echo $dmModPath > $VTOY_PATH/fsextract + vtoy_unsquashfs -d $VTOY_PATH/sqfs -n -q -e $VTOY_PATH/fsextract $VTOY_PATH/fsdisk 2>>$VTLOG + fi + + if [ -e $VTOY_PATH/sqfs${dmModPath} ]; then + vtlog "success $VTOY_PATH/sqfs${dmModPath}" + insmod $VTOY_PATH/sqfs${dmModPath} + else + false + fi +} + + +ventoy_os_install_dmsetup_by_fuse() { + vtlog "ventoy_os_install_dmsetup_by_fuse $*" + + mkdir -p $VTOY_PATH/mnt/fuse $VTOY_PATH/mnt/iso $VTOY_PATH/mnt/squashfs + + vtoydm -p -f $VTOY_PATH/ventoy_image_map -d $1 > $VTOY_PATH/ventoy_dm_table + vtoy_fuse_iso -f $VTOY_PATH/ventoy_dm_table -m $VTOY_PATH/mnt/fuse + + mount -t iso9660 $VTOY_PATH/mnt/fuse/ventoy.iso $VTOY_PATH/mnt/iso + mount -t squashfs $VTOY_PATH/mnt/iso/antiX/linuxfs $VTOY_PATH/mnt/squashfs + + KoName=$(ls $VTOY_PATH/mnt/squashfs/lib/modules/$2/kernel/drivers/md/dm-mod.ko*) + vtlog "insmod $KoName" + insmod $KoName + + umount $VTOY_PATH/mnt/squashfs + umount $VTOY_PATH/mnt/iso + umount $VTOY_PATH/mnt/fuse +} + + +ventoy_os_install_dmsetup() { + vtlog "ventoy_os_install_dmsetup" + + if grep -q 'device-mapper' /proc/devices; then + vtlog "device-mapper module already loaded" + return; + fi + + vtKerVer=$(uname -r) + + if ventoy_os_install_dmsetup_by_unsquashfs $1 $vtKerVer; then + vtlog "unsquashfs success" + else + if modprobe fuse 2>>$VTLOG; then + ventoy_os_install_dmsetup_by_fuse $1 $vtKerVer + fi + fi +} + + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_os_install_dmsetup $vtdiskname + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +if ! [ -e $VTOY_DM_PATH ]; then + blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') + mknod -m 0666 $VTOY_DM_PATH b $blkdev_num +fi + +PATH=$VTPATH_OLD + + +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/debian/antix-hook.sh b/IMG/cpio/ventoy/hook/debian/antix-hook.sh new file mode 100644 index 0000000..64ad6ee --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/antix-hook.sh @@ -0,0 +1,38 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +if $GREP -q 'FILTERED_LIST=[^a-zA-Z0-9_]*$' /init; then + $SED 's#FILTERED_LIST=[^a-zA-Z0-9_]*$#FILTERED_LIST=/dev/mapper/ventoy#' -i /init +elif $GREP -q '\[ "$FILTERED_LIST" \]' /init; then + $SED '/\[ "$FILTERED_LIST" \]/i\ FILTERED_LIST="/dev/mapper/ventoy $FILTERED_LIST"' -i /init +fi + +if $GREP -q '_search_for_boot_device_' /init; then + $SED -i "/_search_for_boot_device_/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/antix-disk.sh" /init +elif $GREP -q 'FILTERED_LIST=.*ventoy' /init; then + $SED -i "/FILTERED_LIST=.*ventoy/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/antix-disk.sh" /init +fi + + +if [ -f $VTOY_PATH/ventoy_persistent_map ]; then + $SED 's#for param in $cmdline#for param in persist_all $cmdline#g' -i /init +fi + +# for debug +#$SED -i "/^linuxfs_error/a\exec $VTOY_PATH/busybox/sh" /init diff --git a/IMG/cpio/ventoy/hook/debian/bliss-disk.sh b/IMG/cpio/ventoy/hook/debian/bliss-disk.sh new file mode 100644 index 0000000..b340bbe --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/bliss-disk.sh @@ -0,0 +1,43 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/debian/bliss-hook.sh b/IMG/cpio/ventoy/hook/debian/bliss-hook.sh new file mode 100644 index 0000000..3910ea8 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/bliss-hook.sh @@ -0,0 +1,23 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +$BUSYBOX_PATH/mkdir /dev +$BUSYBOX_PATH/mknod /dev/null c 1 3 + +$SED "/echo.*Detecting/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/bliss-disk.sh" -i /init diff --git a/IMG/cpio/ventoy/hook/debian/default-hook.sh b/IMG/cpio/ventoy/hook/debian/default-hook.sh new file mode 100644 index 0000000..5db56e3 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/default-hook.sh @@ -0,0 +1,90 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +CD_DETECT="/var/lib/dpkg/info/cdrom-detect.postinst" + +if [ -e /init ] && $GREP -q '^mountroot$' /init; then + echo "Here before mountroot ..." >> $VTLOG + + $SED "/^mountroot$/i\\$BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/disk_mount_hook.sh" -i /init + $SED "/^mountroot$/i\\export LIVEMEDIA=/dev/mapper/ventoy" -i /init + $SED "/^mountroot$/i\\export LIVE_MEDIA=/dev/mapper/ventoy" -i /init + + if $GREP -q 'live-media=' /proc/cmdline; then + if [ -f /scripts/casper ] && $GREP -q '^ *LIVEMEDIA=' /scripts/casper; then + $SED "s#^ *LIVEMEDIA=.*#LIVEMEDIA=/dev/mapper/ventoy#" -i /scripts/casper + fi + fi +elif [ -e "$CD_DETECT" ]; then + echo "$CD_DETECT exist, now add hook in it..." >> $VTLOG + $SED "1 a $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/disk_mount_hook.sh" -i "$CD_DETECT" + + if [ -e /bin/list-devices ]; then + mv /bin/list-devices /bin/list-devices-bk + cp -a /ventoy/hook/debian/list-devices /bin/list-devices + fi +elif [ -e /init ] && $GREP -q '/start-udev$' /init; then + echo "Here use notify ..." >> $VTLOG + + ventoy_set_inotify_script debian/ventoy-inotifyd-hook.sh + $SED "/start-udev$/i\\mount -n -o mode=0755 -t devtmpfs devtmpfs /dev" -i /init + $SED "/start-udev$/i\\$BUSYBOX_PATH/sh $VTOY_PATH/hook/default/ventoy-inotifyd-start.sh" -i /init +else + echo "Here use udev hook ..." >> $VTLOG + ventoy_systemd_udevd_work_around + ventoy_add_udev_rule "$VTOY_PATH/hook/debian/udev_disk_hook.sh %k" +fi + +if [ -f $VTOY_PATH/autoinstall ]; then + echo "Do auto install ..." >> $VTLOG + + if $GREP -q '^autoinstall:' $VTOY_PATH/autoinstall; then + echo "cloud-init auto install ..." >> $VTLOG + if $GREP -q "maybe_break init" /init; then + $SED "/maybe_break init/i $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/ventoy-cloud-init.sh \$rootmnt" -i /init + fi + else + if $GREP -q "^mount /proc$" /init; then + $SED "/^mount \/proc/a export file=$VTOY_PATH/autoinstall; export auto='true'; export priority='critical'" -i /init + fi + fi + + # if [ -e /bin/check-missing-firmware ]; then + # $SED "/^#!/a\exit 0" -i /bin/check-missing-firmware + # fi +fi + +#for ARMA aka Omoikane +if [ -f /mod.img ] && [ -f /mod/fs/cramfs.ko ]; then + echo "mount mod.img and install dm-mod.ko" >> $VTLOG + $BUSYBOX_PATH/insmod /mod/fs/cramfs.ko + + $BUSYBOX_PATH/mkdir $VTOY_PATH/modmnt + $BUSYBOX_PATH/mount /mod.img $VTOY_PATH/modmnt + $BUSYBOX_PATH/insmod $VTOY_PATH/modmnt/md/dm-mod.ko + $BUSYBOX_PATH/umount $VTOY_PATH/modmnt + + $BUSYBOX_PATH/rmmod cramfs +fi + +#for siduction-patience-nox- +if [ -f /scripts/fll ]; then + $SED "/unset FINGERED/a\\echo '/dev/mapper/ventoy';return;" -i /scripts/fll +fi + diff --git a/IMG/cpio/ventoy/hook/debian/devuan-disk.sh b/IMG/cpio/ventoy/hook/debian/devuan-disk.sh new file mode 100644 index 0000000..b340bbe --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/devuan-disk.sh @@ -0,0 +1,43 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/debian/devuan-hook.sh b/IMG/cpio/ventoy/hook/debian/devuan-hook.sh new file mode 100644 index 0000000..dd975f0 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/devuan-hook.sh @@ -0,0 +1,21 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +$SED "/Mount.*cdrom/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/devuan-disk.sh" -i /init + diff --git a/IMG/cpio/ventoy/hook/debian/disk_mount_hook.sh b/IMG/cpio/ventoy/hook/debian/disk_mount_hook.sh new file mode 100644 index 0000000..4e00b8f --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/disk_mount_hook.sh @@ -0,0 +1,40 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +vtlog "${vtdiskname#/dev/}2 found..." +$BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/udev_disk_hook.sh "${vtdiskname#/dev/}2" + +if [ -f /ventoy/autoinstall ]; then + sh /ventoy/hook/default/auto_install_varexp.sh /ventoy/autoinstall +fi diff --git a/IMG/cpio/ventoy/hook/debian/kerio-disk.sh b/IMG/cpio/ventoy/hook/debian/kerio-disk.sh new file mode 100644 index 0000000..a589d8f --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/kerio-disk.sh @@ -0,0 +1,79 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + + +ventoy_os_install_dmsetup_by_ko() { + vtlog "ventoy_os_install_dmsetup_by_ko $1" + + vtVer=$(uname -r) + if uname -m | $GREP -q 64; then + vtBit=64 + else + vtBit=32 + fi + + ventoy_extract_vtloopex $1 kerio + vtLoopExDir=$VTOY_PATH/vtloopex/kerio/vtloopex + + if [ -e $vtLoopExDir/dm-mod/$vtVer/$vtBit/dm-mod.ko.xz ]; then + $BUSYBOX_PATH/xz -d $vtLoopExDir/dm-mod/$vtVer/$vtBit/dm-mod.ko.xz + insmod $vtLoopExDir/dm-mod/$vtVer/$vtBit/dm-mod.ko + fi +} + + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +if echo $vtdiskname | $EGREP -q "nvme|mmc|nbd"; then + ventoy_os_install_dmsetup_by_ko "${vtdiskname}p2" +else + ventoy_os_install_dmsetup_by_ko "${vtdiskname}2" +fi + + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) + +vtlog "/dev/$vtDM" +mount -t iso9660 /dev/$vtDM /cdrom +modprobe squashfs +echo "/dev/$vtDM" > /ventoy/vtDM + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/debian/kerio-hook.sh b/IMG/cpio/ventoy/hook/debian/kerio-hook.sh new file mode 100644 index 0000000..864292b --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/kerio-hook.sh @@ -0,0 +1,20 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +$SED "/for drive in/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/kerio-disk.sh >/dev/null 2>&1; cat /ventoy/vtDM; exit 0" -i /installer/install_init diff --git a/IMG/cpio/ventoy/hook/debian/knoppix-disk.sh b/IMG/cpio/ventoy/hook/debian/knoppix-disk.sh new file mode 100644 index 0000000..e7cfe47 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/knoppix-disk.sh @@ -0,0 +1,46 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +if ! [ -e $VTOY_DM_PATH ]; then + blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') + mknod -m 0666 $VTOY_DM_PATH b $blkdev_num +fi + +PATH=$VTPATH_OLD + + +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/debian/knoppix-hook.sh b/IMG/cpio/ventoy/hook/debian/knoppix-hook.sh new file mode 100644 index 0000000..b57fd15 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/knoppix-hook.sh @@ -0,0 +1,23 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +$SED '/^findknoppix/a\ return 0' -i /init +$SED '/^findknoppix/a\ trymount $ROOTDEV /mnt-system >/dev/null 2>&1' -i /init +$SED '/^findknoppix/a\ ROOTDEV=/dev/mapper/ventoy' -i /init +$SED "/^findknoppix/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/knoppix-disk.sh" -i /init diff --git a/IMG/cpio/ventoy/hook/debian/kylin-disk.sh b/IMG/cpio/ventoy/hook/debian/kylin-disk.sh new file mode 100644 index 0000000..0bfb285 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/kylin-disk.sh @@ -0,0 +1,68 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + + +ventoy_os_install_dmsetup_by_fuse() { + vtlog "ventoy_os_install_dmsetup_by_fuse $*" + + mkdir -p $VTOY_PATH/mnt/fuse $VTOY_PATH/mnt/iso $VTOY_PATH/mnt/squashfs + + vtoydm -p -f $VTOY_PATH/ventoy_image_map -d $1 > $VTOY_PATH/ventoy_dm_table + vtoy_fuse_iso -f $VTOY_PATH/ventoy_dm_table -m $VTOY_PATH/mnt/fuse + + mount -t iso9660 $VTOY_PATH/mnt/fuse/ventoy.iso $VTOY_PATH/mnt/iso + + sfsfile=$VTOY_PATH/mnt/iso/casper/filesystem.squashfs + + mount -t squashfs $sfsfile $VTOY_PATH/mnt/squashfs + + kVer=$(uname -r) + KoName=$(ls $VTOY_PATH/mnt/squashfs/lib/modules/$kVer/kernel/drivers/md/dm-mod.ko*) + vtlog "insmod $KoName" + insmod $KoName + + umount $VTOY_PATH/mnt/squashfs + umount $VTOY_PATH/mnt/iso + umount $VTOY_PATH/mnt/fuse +} + + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +if ! grep -q 'device-mapper' /proc/devices; then + ventoy_os_install_dmsetup_by_fuse $vtdiskname +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +PATH=$VTPATH_OLD + +# OK finish +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/debian/kylin-hook.sh b/IMG/cpio/ventoy/hook/debian/kylin-hook.sh new file mode 100644 index 0000000..051ec4a --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/kylin-hook.sh @@ -0,0 +1,26 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +if [ -e /init ] && $GREP -q '^mountroot$' /init; then + echo "Here before mountroot ..." >> $VTLOG + + $SED "/^mountroot$/i\\$BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/kylin-disk.sh" -i /init + $SED "/^mountroot$/i\\export LIVEMEDIA=/dev/mapper/ventoy" -i /init + $SED "/^mountroot$/i\\export LIVE_MEDIA=/dev/mapper/ventoy" -i /init +fi diff --git a/IMG/cpio/ventoy/hook/debian/linuxconsole-disk.sh b/IMG/cpio/ventoy/hook/debian/linuxconsole-disk.sh new file mode 100644 index 0000000..e5bb7cb --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/linuxconsole-disk.sh @@ -0,0 +1,71 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + + +vtoydm -i -f $VTOY_PATH/ventoy_image_map -d $vtdiskname > $VTOY_PATH/iso_file_list + +vtline=$(grep '[-][-] drivers-.*\.squashfs' $VTOY_PATH/iso_file_list) +sector=$(echo $vtline | awk '{print $(NF-1)}') +length=$(echo $vtline | awk '{print $NF}') + +vtoydm -e -f $VTOY_PATH/ventoy_image_map -d $vtdiskname -s $sector -l $length -o $VTOY_PATH/driver.squashfs +mount -t squashfs $VTOY_PATH/driver.squashfs /lib/modules +modprobe dm-mod + +umount /lib/modules +rm -f $VTOY_PATH/driver.squashfs + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +blkdev_dev=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) + +if ! [ -b /dev/$vtDM ]; then + mknod -m 0660 /dev/$vtDM b $blkdev_dev +fi + +if mount /dev/$vtDM /media/ydfs; then + vtlog "mount success" +else + vtlog "mount failed" +fi + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/debian/linuxconsole-hook.sh b/IMG/cpio/ventoy/hook/debian/linuxconsole-hook.sh new file mode 100644 index 0000000..a8e1db7 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/linuxconsole-hook.sh @@ -0,0 +1,23 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +$SED "s#/busybox/bin/sleep 2#/busybox/bin/sleep 10#" -i /etc/init.d/tty1 +$SED "/install *-d *.media.ydfs/a return" -i /ydfs/detect/media +$SED "/install *-d *.media.ydfs/a $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/linuxconsole-disk.sh" -i /ydfs/detect/media + diff --git a/IMG/cpio/ventoy/hook/debian/list-devices b/IMG/cpio/ventoy/hook/debian/list-devices new file mode 100644 index 0000000..874bb68 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/list-devices @@ -0,0 +1,9 @@ +#! /bin/sh + +if [ "$1" = "usb-partition" -a -z "$2" ]; then + if [ -f /ventoy/list-devices-usb-part ]; then + cat /ventoy/list-devices-usb-part + fi +fi + +/bin/list-devices-bk $* diff --git a/IMG/cpio/ventoy/hook/debian/minios-disk.sh b/IMG/cpio/ventoy/hook/debian/minios-disk.sh new file mode 100644 index 0000000..4197485 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/minios-disk.sh @@ -0,0 +1,85 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + + +ventoy_os_install_dmsetup_by_fuse() { + vtlog "ventoy_os_install_dmsetup_by_fuse $*" + + mkdir -p $VTOY_PATH/mnt/fuse $VTOY_PATH/mnt/iso $VTOY_PATH/mnt/squashfs + + vtoydm -p -f $VTOY_PATH/ventoy_image_map -d $1 > $VTOY_PATH/ventoy_dm_table + vtoy_fuse_iso -f $VTOY_PATH/ventoy_dm_table -m $VTOY_PATH/mnt/fuse + + mount -t iso9660 $VTOY_PATH/mnt/fuse/ventoy.iso $VTOY_PATH/mnt/iso + mount -t squashfs $VTOY_PATH/mnt/iso/minios/0*-core*.sb $VTOY_PATH/mnt/squashfs + + KoName=$(ls $VTOY_PATH/mnt/squashfs/lib/modules/$2/kernel/drivers/md/dm-mod.ko*) + vtlog "insmod $KoName" + insmod $KoName + + umount $VTOY_PATH/mnt/squashfs + umount $VTOY_PATH/mnt/iso + umount $VTOY_PATH/mnt/fuse +} + + +ventoy_os_install_dmsetup() { + vtlog "ventoy_os_install_dmsetup" + + if grep -q 'device-mapper' /proc/devices; then + vtlog "device-mapper module already loaded" + return; + fi + + vtKerVer=$(uname -r) + + if modprobe fuse 2>>$VTLOG; then + ventoy_os_install_dmsetup_by_fuse $1 $vtKerVer + fi +} + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +if check_usb_disk_ready "$vtdiskname"; then + vtlog "check_usb_disk_ready ok" +else + vtlog "check_usb_disk_ready error" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_os_install_dmsetup $vtdiskname + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/debian/minios-hook.sh b/IMG/cpio/ventoy/hook/debian/minios-hook.sh new file mode 100644 index 0000000..09f6e63 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/minios-hook.sh @@ -0,0 +1,24 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +if [ -f /lib/livekitlib ] && $GREP -q 'debug_log.*find_data_try' /lib/livekitlib; then + $SED "/debug_log.*find_data_try/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/minios-disk.sh" -i /lib/livekitlib +else + $SED "/find_data/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/minios-disk.sh" -i /init +fi diff --git a/IMG/cpio/ventoy/hook/debian/mll-disk.sh b/IMG/cpio/ventoy/hook/debian/mll-disk.sh new file mode 100644 index 0000000..8ee0579 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/mll-disk.sh @@ -0,0 +1,43 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/debian/mll-hook.sh b/IMG/cpio/ventoy/hook/debian/mll-hook.sh new file mode 100644 index 0000000..5186f02 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/mll-hook.sh @@ -0,0 +1,21 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +$SED "/^for DEVICE in/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/mll-disk.sh" -i /etc/02_overlay.sh + diff --git a/IMG/cpio/ventoy/hook/debian/mocaccino-disk.sh b/IMG/cpio/ventoy/hook/debian/mocaccino-disk.sh new file mode 100644 index 0000000..7d87654 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/mocaccino-disk.sh @@ -0,0 +1,47 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) +vtlog "/dev/$vtDM" + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/debian/mocaccino-hook.sh b/IMG/cpio/ventoy/hook/debian/mocaccino-hook.sh new file mode 100644 index 0000000..31143c3 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/mocaccino-hook.sh @@ -0,0 +1,20 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +$SED "/mount_system *$/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/mocaccino-disk.sh" -i /loader diff --git a/IMG/cpio/ventoy/hook/debian/porteus-disk.sh b/IMG/cpio/ventoy/hook/debian/porteus-disk.sh new file mode 100644 index 0000000..d2643ab --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/porteus-disk.sh @@ -0,0 +1,80 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + + +ventoy_os_install_dmsetup_by_fuse() { + vtlog "ventoy_os_install_dmsetup_by_fuse $*" + + mkdir -p $VTOY_PATH/mnt/fuse $VTOY_PATH/mnt/iso $VTOY_PATH/mnt/squashfs + + vtoydm -p -f $VTOY_PATH/ventoy_image_map -d $1 > $VTOY_PATH/ventoy_dm_table + vtoy_fuse_iso -f $VTOY_PATH/ventoy_dm_table -m $VTOY_PATH/mnt/fuse + + mount -t iso9660 $VTOY_PATH/mnt/fuse/ventoy.iso $VTOY_PATH/mnt/iso + + sfsfile=$(ls $VTOY_PATH/mnt/iso/porteus/base/*kernel.xzm) + + mount -t squashfs $sfsfile $VTOY_PATH/mnt/squashfs + + KoName=$(ls $VTOY_PATH/mnt/squashfs/lib/modules/$2/kernel/drivers/md/dm-mod.ko*) + vtlog "insmod $KoName" + insmod $KoName + + umount $VTOY_PATH/mnt/squashfs + umount $VTOY_PATH/mnt/iso + umount $VTOY_PATH/mnt/fuse +} + +ventoy_os_install_dmsetup() { + vtlog "ventoy_os_install_dmsetup" + + if grep -q 'device-mapper' /proc/devices; then + vtlog "device-mapper module already loaded" + return; + fi + + vtKerVer=$(uname -r) + + ventoy_os_install_dmsetup_by_fuse $1 $vtKerVer +} + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_os_install_dmsetup $vtdiskname + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +PATH=$VTPATH_OLD + + +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/debian/porteus-hook.sh b/IMG/cpio/ventoy/hook/debian/porteus-hook.sh new file mode 100644 index 0000000..86863b7 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/porteus-hook.sh @@ -0,0 +1,77 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +porteus_hook() { + $SED "/searching *for *\$SGN *file/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/porteus-disk.sh" -i $1 + $SED "/searching *for *\$CFG *file/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/porteus-disk.sh" -i $1 +} + +vtPath=$($VTOY_PATH/tool/vtoydump -p $VTOY_PATH/ventoy_os_param) +echo $vtPath | $GREP -q " " +_vtRet1=$? + +$GREP -q exfat /proc/filesystems +_vtRet2=$? + +echo "_vtRet1=$_vtRet1 _vtRet2=$_vtRet2 ..." >> $VTLOG + +if [ $_vtRet1 -ne 0 -a $_vtRet2 -eq 0 ]; then + vtFindFlag=0 + $GREP '`value from`' /usr/* -r | $AWK -F: '{print $1}' > $VTOY_PATH/.porteus + while read vtline; do + echo "hooking $vtline ..." >> $VTLOG + $SED "s#\`value from\`#$vtPath#g" -i $vtline + vtFindFlag=1 + done < $VTOY_PATH/.porteus + rm -f $VTOY_PATH/.porteus + + if [ $vtFindFlag -eq 0 ]; then + if $GREP -q '`value from`' /linuxrc; then + if $GREP -q "searching *for *\$CFG *file" /linuxrc; then + echo "hooking linuxrc CFG..." >> $VTLOG + $SED "/searching *for *\$CFG *file/i$BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/porteus-path.sh" -i /linuxrc + $SED "/searching *for *\$CFG *file/iFROM=\$(cat /porteus-from)" -i /linuxrc + $SED "/searching *for *\$CFG *file/iISO=\$(cat /porteus-from)" -i /linuxrc + vtFindFlag=1 + else + echo "hooking linuxrc SGN..." >> $VTLOG + $SED "/searching *for *\$SGN *file/i$BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/porteus-path.sh" -i /linuxrc + $SED "/searching *for *\$SGN *file/iFROM=\$(cat /porteus-from)" -i /linuxrc + $SED "/searching *for *\$SGN *file/iISO=\$(cat /porteus-from)" -i /linuxrc + vtFindFlag=1 + fi + fi + fi + +else + for vtfile in '/linuxrc' '/init'; do + if [ -e $vtfile ]; then + if ! $GREP -q ventoy $vtfile; then + echo "hooking disk $vtfile ..." >> $VTLOG + porteus_hook $vtfile + fi + fi + done +fi + + +# replace blkid in system +vtblkid=$($BUSYBOX_PATH/which blkid) +$BUSYBOX_PATH/rm -f $vtblkid +$BUSYBOX_PATH/cp -a $BUSYBOX_PATH/blkid $vtblkid diff --git a/IMG/cpio/ventoy/hook/debian/porteus-path.sh b/IMG/cpio/ventoy/hook/debian/porteus-path.sh new file mode 100644 index 0000000..16297de --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/porteus-path.sh @@ -0,0 +1,38 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) + +vtPath=$(vtoydump -p $VTOY_PATH/ventoy_os_param) + +if echo $vtdiskname | egrep -q "nvme|mmc|nbd"; then + echo ${vtdiskname}p1${vtPath} > /porteus-from +else + echo ${vtdiskname}1${vtPath} > /porteus-from +fi + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/debian/puppy-disk.sh b/IMG/cpio/ventoy/hook/debian/puppy-disk.sh new file mode 100644 index 0000000..17c715f --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/puppy-disk.sh @@ -0,0 +1,90 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +ventoy_os_install_dmsetup_by_fuse() { + vtlog "ventoy_os_install_dmsetup_by_fuse $*" + + mkdir -p $VTOY_PATH/mnt/fuse $VTOY_PATH/mnt/iso $VTOY_PATH/mnt/squashfs + + vtoydm -p -f $VTOY_PATH/ventoy_image_map -d $1 > $VTOY_PATH/ventoy_dm_table + vtoy_fuse_iso -f $VTOY_PATH/ventoy_dm_table -m $VTOY_PATH/mnt/fuse + + mount -t iso9660 $VTOY_PATH/mnt/fuse/ventoy.iso $VTOY_PATH/mnt/iso + + if ls $VTOY_PATH/mnt/iso/zdrv_*.sfs 2>/dev/null; then + sfsfile=$(ls $VTOY_PATH/mnt/iso/zdrv_*.sfs) + else + sfsfile=$(ls $VTOY_PATH/mnt/iso/*.sfs) + fi + + mount -t squashfs $sfsfile $VTOY_PATH/mnt/squashfs + + kVer=$(uname -r) + KoName=$(ls $VTOY_PATH/mnt/squashfs/lib/modules/$kVer/kernel/drivers/md/dm-mod.ko*) + if [ -z "$KoName" ]; then + KoName=$(ls $VTOY_PATH/mnt/squashfs/usr/lib/modules/$kVer/kernel/drivers/md/dm-mod.ko*) + fi + + vtlog "insmod $KoName" + insmod $KoName + + umount $VTOY_PATH/mnt/squashfs + umount $VTOY_PATH/mnt/iso + umount $VTOY_PATH/mnt/fuse +} + + + + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +if grep -q 'device-mapper' /proc/devices; then + vtlog "device-mapper module exist" +else + ventoy_os_install_dmsetup_by_fuse $vtdiskname +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +if ! [ -e $VTOY_DM_PATH ]; then + blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') + mknod -m 0666 $VTOY_DM_PATH b $blkdev_num +fi +cp -a $VTOY_DM_PATH /dev/ventoy + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/debian/puppy-hook.sh b/IMG/cpio/ventoy/hook/debian/puppy-hook.sh new file mode 100644 index 0000000..d2e1563 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/puppy-hook.sh @@ -0,0 +1,35 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +$SED '1 apmedia=usbhd' -i /init + +if $GREP -q 'HAVE_PARTS=' /init; then + $SED "/^ *HAVE_PARTS=/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/puppy-disk.sh" -i /init + $SED "/^ *HAVE_PARTS=/a\ HAVE_PARTS='ventoy|iso9660'" -i /init +elif $GREP -q 'LESSPARTS=' /init; then + $SED "/^ *LESSPARTS=/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/puppy-disk.sh" -i /init + $SED "/^ *LESSPARTS=/a\ LESSPARTS='ventoy|iso9660'" -i /init +fi + + +if [ -f /DISTRO_SPECS ]; then + if ! [ -d /dev ]; then + $BUSYBOX_PATH/mkdir /dev + fi +fi diff --git a/IMG/cpio/ventoy/hook/debian/pve-disk.sh b/IMG/cpio/ventoy/hook/debian/pve-disk.sh new file mode 100644 index 0000000..8ee0579 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/pve-disk.sh @@ -0,0 +1,43 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/debian/pve-hook.sh b/IMG/cpio/ventoy/hook/debian/pve-hook.sh new file mode 100644 index 0000000..559441c --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/pve-hook.sh @@ -0,0 +1,26 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +if $GREP -q 'rdinit=/vtoy/vtoy' /proc/cmdline; then + echo "fix rdinit" >> $VTLOG + $SED "/switch_root.*\/mnt\/.installer-mp/i\ sh $VTOY_PATH/hook/debian/pve-wa.sh /mnt/.installer-mp/sbin/unconfigured.sh" -i /init +fi + +$SED "/\/sys\/block\/hd\*/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/pve-disk.sh" -i /init +$SED "s#/sys/block/hd\*#/sys/block/dm* /sys/block/hd*#" -i /init diff --git a/IMG/cpio/ventoy/hook/debian/pve-wa.sh b/IMG/cpio/ventoy/hook/debian/pve-wa.sh new file mode 100644 index 0000000..a2b9244 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/pve-wa.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +script=$1 +tmpscript=${script}.tmp + +LINE=$(grep -n 'proc.*proc.*proc' $script | awk -F':' '{print $1}') + +sed -n "1,${LINE}p" $script >> $tmpscript + +echo "if grep -q 'rdinit=/vtoy/vtoy' /proc/cmdline; then" >> $tmpscript +echo " sed 's#rdinit=/vtoy/vtoy##g' /proc/cmdline > /etc/cmdline" >> $tmpscript +echo " mount --bind /etc/cmdline /proc/cmdline" >> $tmpscript +echo "fi" >> $tmpscript + + +let LINE++ +sed -n "${LINE},\$p" $script >> $tmpscript + +cat $tmpscript > $script + diff --git a/IMG/cpio/ventoy/hook/debian/pyabr-disk.sh b/IMG/cpio/ventoy/hook/debian/pyabr-disk.sh new file mode 100644 index 0000000..993b4d2 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/pyabr-disk.sh @@ -0,0 +1,91 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +ventoy_os_install_dmsetup_by_fuse() { + vtlog "ventoy_os_install_dmsetup_by_fuse $*" + + mkdir -p $VTOY_PATH/mnt/fuse $VTOY_PATH/mnt/iso $VTOY_PATH/mnt/squashfs + + vtoydm -p -f $VTOY_PATH/ventoy_image_map -d $1 > $VTOY_PATH/ventoy_dm_table + vtoy_fuse_iso -f $VTOY_PATH/ventoy_dm_table -m $VTOY_PATH/mnt/fuse + + mount -t iso9660 $VTOY_PATH/mnt/fuse/ventoy.iso $VTOY_PATH/mnt/iso + mount -t squashfs $VTOY_PATH/mnt/iso/pyabr/01-core.sb $VTOY_PATH/mnt/squashfs + + KoName=$(ls $VTOY_PATH/mnt/squashfs/lib/modules/$2/kernel/drivers/md/dm-mod.ko*) + vtlog "insmod $KoName" + insmod $KoName + + umount $VTOY_PATH/mnt/squashfs + umount $VTOY_PATH/mnt/iso + umount $VTOY_PATH/mnt/fuse +} + +while [ -n "Y" ]; do + vtdiskname=$(get_ventoy_disk_name) + if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + if [ -r /proc/sys/kernel/hotplug ]; then + echo /sbin/mdev > /proc/sys/kernel/hotplug + fi + mdev -s + sleep 1 + else + if check_usb_disk_ready "$vtdiskname"; then + vtlog "check_usb_disk_ready $vtdiskname ok" + break + else + vtlog "check_usb_disk_ready $vtdiskname error" + if [ -r /proc/sys/kernel/hotplug ]; then + echo /sbin/mdev > /proc/sys/kernel/hotplug + fi + mdev -s + sleep 1 + fi + fi +done + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +modprobe fuse +modprobe cuse + +vtKver=$(uname -r) +ventoy_os_install_dmsetup_by_fuse $vtdiskname $vtKver + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/debian/pyabr-hook.sh b/IMG/cpio/ventoy/hook/debian/pyabr-hook.sh new file mode 100644 index 0000000..25a7978 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/pyabr-hook.sh @@ -0,0 +1,20 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +$SED "/find_data/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/pyabr-disk.sh" -i /init diff --git a/IMG/cpio/ventoy/hook/debian/slax-disk.sh b/IMG/cpio/ventoy/hook/debian/slax-disk.sh new file mode 100644 index 0000000..bfac96e --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/slax-disk.sh @@ -0,0 +1,86 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + + +ventoy_os_install_dmsetup_by_fuse() { + vtlog "ventoy_os_install_dmsetup_by_fuse $*" + + mkdir -p $VTOY_PATH/mnt/fuse $VTOY_PATH/mnt/iso $VTOY_PATH/mnt/squashfs + + vtoydm -p -f $VTOY_PATH/ventoy_image_map -d $1 > $VTOY_PATH/ventoy_dm_table + vtoy_fuse_iso -f $VTOY_PATH/ventoy_dm_table -m $VTOY_PATH/mnt/fuse + + mount -t iso9660 $VTOY_PATH/mnt/fuse/ventoy.iso $VTOY_PATH/mnt/iso + mount -t squashfs $VTOY_PATH/mnt/iso/slax/01-core.sb $VTOY_PATH/mnt/squashfs + + KoName=$(ls $VTOY_PATH/mnt/squashfs/lib/modules/$2/kernel/drivers/md/dm-mod.ko*) + vtlog "insmod $KoName" + insmod $KoName + + umount $VTOY_PATH/mnt/squashfs + umount $VTOY_PATH/mnt/iso + umount $VTOY_PATH/mnt/fuse +} + + +ventoy_os_install_dmsetup() { + vtlog "ventoy_os_install_dmsetup" + + if grep -q 'device-mapper' /proc/devices; then + vtlog "device-mapper module already loaded" + return; + fi + + vtKerVer=$(uname -r) + + if modprobe fuse 2>>$VTLOG; then + ventoy_os_install_dmsetup_by_fuse $1 $vtKerVer + fi +} + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +if check_usb_disk_ready "$vtdiskname"; then + vtlog "check_usb_disk_ready ok" +else + vtlog "check_usb_disk_ready error" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_os_install_dmsetup $vtdiskname + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +PATH=$VTPATH_OLD + + +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/debian/slax-hook.sh b/IMG/cpio/ventoy/hook/debian/slax-hook.sh new file mode 100644 index 0000000..5663c0e --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/slax-hook.sh @@ -0,0 +1,24 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +if [ -f /lib/livekitlib ] && $GREP -q 'debug_log.*find_data_try' /lib/livekitlib; then + $SED "/debug_log.*find_data_try/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/slax-disk.sh" -i /lib/livekitlib +else + $SED "/find_data/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/slax-disk.sh" -i /init +fi diff --git a/IMG/cpio/ventoy/hook/debian/stratodesk-disk.sh b/IMG/cpio/ventoy/hook/debian/stratodesk-disk.sh new file mode 100644 index 0000000..cf671bc --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/stratodesk-disk.sh @@ -0,0 +1,46 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" + +mkdir /root +chmod -R 0755 /root + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/debian/stratodesk-hook.sh b/IMG/cpio/ventoy/hook/debian/stratodesk-hook.sh new file mode 100644 index 0000000..6d045b7 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/stratodesk-hook.sh @@ -0,0 +1,20 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +$SED "/maybe_break *post_modules/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/stratodesk-disk.sh" -i /init diff --git a/IMG/cpio/ventoy/hook/debian/tails-hook.sh b/IMG/cpio/ventoy/hook/debian/tails-hook.sh new file mode 100644 index 0000000..34ef31d --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/tails-hook.sh @@ -0,0 +1,35 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +$SED "s#.*livefs_root=.*find_livefs.*#$BUSYBOX_PATH/mount -t iso9660 /dev/mapper/ventoy \$mountpoint; livefs_root=\$mountpoint#" -i /usr/lib/live/boot/9990-main.sh +$SED "s#.*livefs_root=.*find_livefs.*#$BUSYBOX_PATH/mount -t iso9660 /dev/mapper/ventoy \$mountpoint; livefs_root=\$mountpoint#" -i /usr/bin/boot/9990-main.sh + +if [ -e /init ] && $GREP -q '^mountroot$' /init; then + echo "Here before mountroot ..." >> $VTLOG + $SED "/^mountroot$/i\\$BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/disk_mount_hook.sh" -i /init + + if [ -f /scripts/init-premount/ORDER ]; then + $SED "/\/scripts\/init-premount\/partitioning/,+1d" -i /scripts/init-premount/ORDER + fi + +else + echo "Use default hook ..." >> $VTLOG + ventoy_systemd_udevd_work_around + ventoy_add_udev_rule "$VTOY_PATH/hook/debian/udev_disk_hook.sh %k" +fi diff --git a/IMG/cpio/ventoy/hook/debian/truenas-bottom.sh b/IMG/cpio/ventoy/hook/debian/truenas-bottom.sh new file mode 100644 index 0000000..0fb7df3 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/truenas-bottom.sh @@ -0,0 +1,25 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "mount ventoy.iso" +mkdir -p /root/cdrom >>$VTLOG 2>&1 +mount -t iso9660 $VTOY_PATH/mnt/fuse/ventoy.iso /root/cdrom >>$VTLOG 2>&1 + diff --git a/IMG/cpio/ventoy/hook/debian/truenas-disk.sh b/IMG/cpio/ventoy/hook/debian/truenas-disk.sh new file mode 100644 index 0000000..7deda57 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/truenas-disk.sh @@ -0,0 +1,52 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + + +ventoy_run_fuse() { + vtlog "ventoy_run_fuse $*" + + mkdir -p $VTOY_PATH/mnt/fuse $VTOY_PATH/mnt/iso + + vtoydm -p -f $VTOY_PATH/ventoy_image_map -d $1 > $VTOY_PATH/ventoy_dm_table + vtoy_fuse_iso -f $VTOY_PATH/ventoy_dm_table -m $VTOY_PATH/mnt/fuse + + mount -t iso9660 $VTOY_PATH/mnt/fuse/ventoy.iso $VTOY_PATH/mnt/iso +} + + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_run_fuse $vtdiskname + +if [ -f /ventoy/autoinstall ]; then + sh /ventoy/hook/default/auto_install_varexp.sh /ventoy/autoinstall +fi diff --git a/IMG/cpio/ventoy/hook/debian/truenas-hook.sh b/IMG/cpio/ventoy/hook/debian/truenas-hook.sh new file mode 100644 index 0000000..d7d90f4 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/truenas-hook.sh @@ -0,0 +1,27 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +if [ -e /init ] && $GREP -q '^mountroot$' /init; then + echo "Here before mountroot ..." >> $VTLOG + $SED "/^mountroot$/i\\$BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/truenas-disk.sh" -i /init + $SED "/^mountroot$/i\\export LIVEMEDIA=/dev/mapper/ventoy" -i /init + $SED "/^mountroot$/i\\export LIVE_MEDIA=/dev/mapper/ventoy" -i /init + $SED "/^mountroot$/i\\export FROMISO=$VTOY_PATH/mnt/fuse/ventoy.iso" -i /init + $SED "/exec *run-init/i\\$BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/truenas-bottom.sh" -i /init +fi diff --git a/IMG/cpio/ventoy/hook/debian/udev_disk_hook.sh b/IMG/cpio/ventoy/hook/debian/udev_disk_hook.sh new file mode 100644 index 0000000..251f046 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/udev_disk_hook.sh @@ -0,0 +1,151 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +ventoy_os_install_dmsetup() { + + vtlog "ventoy_os_install_dmsetup $1 ..." + + vt_usb_disk=$1 + + # dump iso file location + $VTOY_PATH/tool/vtoydm -i -f $VTOY_PATH/ventoy_image_map -d ${vt_usb_disk} > $VTOY_PATH/iso_file_list + + # install dmsetup + LINE=$($GREP ' dmsetup.*\.udeb' $VTOY_PATH/iso_file_list) + if [ $? -eq 0 ]; then + install_udeb_from_line "$LINE" ${vt_usb_disk} + fi + + # install libdevmapper + LINE=$($GREP ' libdevmapper.*\.udeb' $VTOY_PATH/iso_file_list) + if [ $? -eq 0 ]; then + install_udeb_from_line "$LINE" ${vt_usb_disk} + fi + + # install md-modules + LINE=$($GREP -i ' md-modules.*\.udeb' $VTOY_PATH/iso_file_list) + if [ $? -eq 0 ]; then + LINTCNT=$($GREP -i -c ' md-modules.*\.udeb' $VTOY_PATH/iso_file_list) + if [ $LINTCNT -gt 1 ]; then + vtlog "more than one pkgs, need to filter..." + VER=$($BUSYBOX_PATH/uname -r) + + LINE=$($GREP -i ' md-modules.*\.udeb' $VTOY_PATH/iso_file_list | $GREP -i $VER) + LINTCNT=$($GREP -i ' md-modules.*\.udeb' $VTOY_PATH/iso_file_list | $GREP -i -c $VER) + if [ $LINTCNT -gt 1 ]; then + vtlog "Still more than one pkgs, use the first one..." + LINE=$($GREP -i ' md-modules.*\.udeb' $VTOY_PATH/iso_file_list | $GREP -i -m1 $VER) + fi + fi + install_udeb_from_line "$LINE" ${vt_usb_disk} + fi + + # insmod md-mod if needed + if $GREP -q 'device-mapper' /proc/devices; then + vtlog "device mapper module is loaded" + else + vtlog "device mapper module is NOT loaded, now load it..." + + VER=$($BUSYBOX_PATH/uname -r) + KO=$($FIND /lib/modules/$VER/kernel/drivers/md -name "dm-mod*") + vtlog "KO=$KO" + + insmod $KO + fi + + vtlog "dmsetup install finish, now check it..." + if dmsetup info >> $VTLOG 2>&1; then + vtlog "dmsetup work ok" + else + vtlog "dmsetup not work, now try to load eglibc ..." + + # install eglibc (some ubuntu 32 bit version need it) + LINE=$($GREP 'libc6-.*\.udeb' $VTOY_PATH/iso_file_list) + if [ $? -eq 0 ]; then + install_udeb_from_line "$LINE" ${vt_usb_disk} + fi + + if dmsetup info >> $VTLOG 2>&1; then + vtlog "dmsetup work ok after retry" + else + vtlog "dmsetup still not work after retry" + fi + fi +} + +if is_ventoy_hook_finished || not_ventoy_disk "${1:0:-1}"; then + exit 0 +fi + +vtlog "==== $0 $* ====" + +dmsetup_path=$(ventoy_find_bin_path dmsetup) +if [ -z "$dmsetup_path" ]; then + ventoy_os_install_dmsetup "/dev/${1:0:-1}" +fi + +if ! $GREP -q 'device-mapper' /proc/devices; then + ventoy_os_install_dmsetup "/dev/${1:0:-1}" +fi + +ventoy_udev_disk_common_hook $* + +# +# Some distro default only accept usb partitions as install medium. +# So if ventoy is installed on a non-USB device, we just mount /cdrom here except +# for these has boot=live or boot=casper parameter in cmdline +# +VT_BUS_USB="" +if [ -n "$ID_BUS" ]; then + if echo $ID_BUS | $GREP -q -i usb; then + VT_BUS_USB="YES" + fi +else + if $BUSYBOX_PATH/ls -l /sys/class/block/${1:0:-1} | $GREP -q -i usb; then + VT_BUS_USB="YES" + fi +fi + +if [ -n "$VT_BUS_USB" ]; then + vtlog "$1 is USB device" + echo /dev/$1 > /ventoy/list-devices-usb-part +else + vtlog "$1 is NOT USB device (bus $ID_BUS)" + + if $EGREP -q 'boot=|casper' /proc/cmdline; then + vtlog "boot=, or casper, don't mount" + else + vtlog "No boot param, need to mount" + echo /dev/$1 > /ventoy/list-devices-usb-part + fi +fi + +#special process for Linx +if $BUSYBOX_PATH/uname -r | $GREP -q "^2\.6"; then + if $GREP -q "linx" /proc/version; then + blkdev_num=$($VTOY_PATH/tool/dmsetup ls | $GREP ventoy | $SED 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') + vtDM=$(ventoy_find_dm_id ${blkdev_num}) + echo "/dev/$vtDM" > /ventoy/list-devices-usb-part + fi +fi + +# OK finish +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/debian/veket-disk.sh b/IMG/cpio/ventoy/hook/debian/veket-disk.sh new file mode 100644 index 0000000..1e10180 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/veket-disk.sh @@ -0,0 +1,117 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +ventoy_os_install_dmsetup_by_fuse() { + local drvdir="" + vtlog "ventoy_os_install_dmsetup_by_fuse $*" + + mkdir -p $VTOY_PATH/mnt/fuse $VTOY_PATH/mnt/iso $VTOY_PATH/mnt/squashfs + + vtoydm -p -f $VTOY_PATH/ventoy_image_map -d $1 > $VTOY_PATH/ventoy_dm_table + vtoy_fuse_iso -f $VTOY_PATH/ventoy_dm_table -m $VTOY_PATH/mnt/fuse + + mount -t iso9660 $VTOY_PATH/mnt/fuse/ventoy.iso $VTOY_PATH/mnt/iso + + + for sfsfile in $(ls $VTOY_PATH/mnt/iso/*drv_veket*.sfs); do + mount -t squashfs $sfsfile $VTOY_PATH/mnt/squashfs + if [ -d $VTOY_PATH/mnt/squashfs/lib/modules ]; then + KoName=$(ls $VTOY_PATH/mnt/squashfs/lib/modules/$2/kernel/drivers/md/dm-mod.ko*) + if [ -n "$KoName" -a -f $KoName ]; then + drvdir=$VTOY_PATH/mnt/squashfs/lib/modules/$2 + break + fi + fi + + umount $VTOY_PATH/mnt/squashfs + done + + + if [ -z "$drvdir" ]; then + vtlog "retry for usr/lib dir" + for sfsfile in $(ls $VTOY_PATH/mnt/iso/*drv_veket*.sfs); do + mount -t squashfs $sfsfile $VTOY_PATH/mnt/squashfs + if [ -d $VTOY_PATH/mnt/squashfs/usr/lib/modules ]; then + KoName=$(ls $VTOY_PATH/mnt/squashfs/usr/lib/modules/$2/kernel/drivers/md/dm-mod.ko*) + if [ -n "$KoName" -a -f $KoName ]; then + drvdir=$VTOY_PATH/mnt/squashfs/usr/lib/modules/$2 + break + fi + fi + + umount $VTOY_PATH/mnt/squashfs + done + fi + + + KoName=$(ls $drvdir/kernel/drivers/dax/dax.ko*) + vtlog "insmod $KoName" + insmod $KoName + + KoName=$(ls $drvdir/kernel/drivers/md/dm-mod.ko*) + vtlog "insmod $KoName" + insmod $KoName + + umount $VTOY_PATH/mnt/squashfs + umount $VTOY_PATH/mnt/iso + umount $VTOY_PATH/mnt/fuse +} + +ventoy_os_install_dmsetup() { + vtlog "ventoy_os_install_dmsetup" + + if grep -q 'device-mapper' /proc/devices; then + vtlog "device-mapper module already loaded" + return; + fi + + vtKerVer=$(uname -r) + + ventoy_os_install_dmsetup_by_fuse $1 $vtKerVer +} + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_os_install_dmsetup $vtdiskname + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +mknod -m 0666 /dev/ventoy b $blkdev_num + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/debian/veket-hook.sh b/IMG/cpio/ventoy/hook/debian/veket-hook.sh new file mode 100644 index 0000000..5093cbb --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/veket-hook.sh @@ -0,0 +1,29 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +$SED '1 apmedia=usbhd' -i /init +$SED "/^ *HAVE_PARTS=/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/veket-disk.sh" -i /init +$SED "/^ *HAVE_PARTS=/a\ HAVE_PARTS='ventoy|iso9660'" -i /init + +if [ -d /dev ]; then + [ -e /dev/null ] || $BUSYBOX_PATH/mknod /dev/null c 1 3 +else + $BUSYBOX_PATH/mkdir /dev + $BUSYBOX_PATH/mknod /dev/null c 1 3 +fi diff --git a/IMG/cpio/ventoy/hook/debian/ventoy-cloud-init.sh b/IMG/cpio/ventoy/hook/debian/ventoy-cloud-init.sh new file mode 100644 index 0000000..0663f98 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/ventoy-cloud-init.sh @@ -0,0 +1,68 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +newroot=$1 + +dd if=/dev/zero of=$newroot/tmp/cidata.img bs=1M count=8 status=none +freeloop=$(losetup -f) + +losetup $freeloop $newroot/tmp/cidata.img + +mkfs.vfat -n CIDATA $freeloop + +mkdir /tmpcidata +mount $newroot/tmp/cidata.img /tmpcidata + +vtSplit=$(grep VENTOY_META_DATA_SPLIT $VTOY_PATH/autoinstall | wc -l) +if [ $vtSplit -eq 1 ]; then + vtlog "split autoinstall script to user-data and meta-data" + vtLine=$(grep -n VENTOY_META_DATA_SPLIT $VTOY_PATH/autoinstall | awk -F: '{print $1}') + vtLine1=$(expr $vtLine - 1) + vtLine2=$(expr $vtLine + 1) + vtlog "Line number: $vtLine $vtLine1 $vtLine2" + sed -n "1,${vtLine1}p" $VTOY_PATH/autoinstall >/tmpcidata/user-data + sed -n "${vtLine2},\$p" $VTOY_PATH/autoinstall >/tmpcidata/meta-data + + sh /ventoy/hook/default/auto_install_varexp.sh /tmpcidata/user-data + sh /ventoy/hook/default/auto_install_varexp.sh /tmpcidata/meta-data +else + vtlog "only user-data avaliable" + cp -a $VTOY_PATH/autoinstall /tmpcidata/user-data + touch /tmpcidata/meta-data + + sh /ventoy/hook/default/auto_install_varexp.sh /tmpcidata/user-data +fi + + +umount /tmpcidata +rm -rf /tmpcidata + +vtCMD=$(cat /proc/cmdline) +echo "autoinstall $vtCMD" > $newroot/tmp/kcmdline +mount --bind $newroot/tmp/kcmdline /proc/cmdline + + +PATH=$VTPATH_OLD + diff --git a/IMG/cpio/ventoy/hook/debian/ventoy-hook.sh b/IMG/cpio/ventoy/hook/debian/ventoy-hook.sh new file mode 100644 index 0000000..7a02d33 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/ventoy-hook.sh @@ -0,0 +1,140 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +ventoy_get_debian_distro() { + if [ -d /KNOPPIX ]; then + echo 'knoppix'; return + elif [ -e /etc/initrd-release ]; then + if $EGREP -q "ID=.*antix|ID=.*mx" /etc/initrd-release; then + echo 'antix'; return + fi + elif [ -e /etc/initrd_release ]; then + if $EGREP -q "ID=.*antix|ID=.*mx" /etc/initrd_release; then + echo 'antix'; return + fi + fi + + if [ -e /DISTRO_SPECS ]; then + if $GREP -q veket /DISTRO_SPECS; then + echo 'veket'; return + fi + fi + + if [ -e /init ]; then + if $EGREP -q 'PUPPYSFS|PUPPYFILE' /init; then + if $GREP -q VEKETSFS /init; then + echo 'veket'; return + else + echo 'puppy'; return + fi + elif $GREP -m1 -q 'Minimal.*Linux.*Live' /init; then + echo 'mll'; return + elif $GREP -m1 -q 'stratodesk.com' /init; then + echo 'stratodesk'; return + elif $GREP -q "\bPVE\b" /init; then + echo 'pve'; return + fi + fi + + if [ -e /etc/os-release ]; then + if $GREP -q 'Tails' /etc/os-release; then + echo 'tails'; return + fi + if $GREP -q 'NAME="Kylin"' /etc/os-release; then + echo 'kylin'; return + fi + fi + + if $GREP -q 'slax/' /proc/cmdline; then + echo 'slax'; return + fi + + if $GREP -q 'minios/' /proc/cmdline; then + echo 'minios'; return + fi + + if $GREP -q 'PVE ' /proc/version; then + echo 'pve'; return + fi + + if [ -d /porteus ]; then + echo 'porteus'; return + fi + + if $GREP -q 'porteus' /proc/version; then + echo 'porteus'; return + fi + + if $GREP -q 'linuxconsole' /proc/version; then + echo 'linuxconsole'; return + fi + + if $GREP -q 'vyos' /proc/version; then + echo 'vyos'; return + fi + + if $GREP -q 'kylin' /proc/version; then + echo 'kylin'; return + fi + + if [ -f /scripts/00-ver ]; then + if $GREP -q 'Bliss-OS' /scripts/00-ver; then + echo 'bliss'; return + fi + fi + + if [ -e /opt/kerio ]; then + echo 'kerio'; return + fi + + if $GREP -q 'mocaccino' /proc/version; then + echo 'mocaccino'; return + fi + + if $GREP -q '/pyabr/' /proc/cmdline; then + echo 'pyabr'; return + fi + + if [ -e /devuan-logo.txt ]; then + echo 'devuan'; return + fi + + if $GREP -q 'truenas' /proc/version; then + echo 'truenas'; return + fi + + echo 'default' +} + +DISTRO=$(ventoy_get_debian_distro) + +echo "##### distribution = $DISTRO ######" >> $VTLOG +. $VTOY_PATH/hook/debian/${DISTRO}-hook.sh + +if [ -f /bin/env2debconf ]; then + $SED "1a /bin/sh $VTOY_PATH/hook/debian/ventoy_env2debconf.sh" -i /bin/env2debconf + $SED "s#in *\$(set)#in \$(cat /ventoy/envset)#" -i /bin/env2debconf +fi + + + + + diff --git a/IMG/cpio/ventoy/hook/debian/ventoy-inotifyd-hook.sh b/IMG/cpio/ventoy/hook/debian/ventoy-inotifyd-hook.sh new file mode 100644 index 0000000..e154722 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/ventoy-inotifyd-hook.sh @@ -0,0 +1,37 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +if is_inotify_ventoy_part $3; then + vtlog "##### INOTIFYD: $2/$3 is created (YES) ..." + vtlog "find ventoy partition $3 ..." + $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/udev_disk_hook.sh "$3" +else + vtlog "##### INOTIFYD: $2/$3 is created (NO)..." +fi + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/debian/ventoy_env2debconf.sh b/IMG/cpio/ventoy/hook/debian/ventoy_env2debconf.sh new file mode 100644 index 0000000..53b3eff --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/ventoy_env2debconf.sh @@ -0,0 +1,33 @@ +#!/bin/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +PATH=$PATH:/ventoy/busybox + +set > /ventoy/tmpenvset + +for i in $(cat /proc/cmdline); do + if echo $i | grep -q "="; then + vtKey=${i%=*} + if ! grep -q "^$vtKey" /ventoy/tmpenvset; then + echo $i >> /ventoy/envset + fi + fi +done + +cat /ventoy/tmpenvset >> /ventoy/envset diff --git a/IMG/cpio/ventoy/hook/debian/vyos-disk.sh b/IMG/cpio/ventoy/hook/debian/vyos-disk.sh new file mode 100644 index 0000000..468adfd --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/vyos-disk.sh @@ -0,0 +1,49 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +mkdir -p /live/vtoyfuse /live/vtoyiso + +modprobe fuse +vtoydm -p -f $VTOY_PATH/ventoy_image_map -d $vtdiskname > $VTOY_PATH/ventoy_dm_table +vtoy_fuse_iso -f $VTOY_PATH/ventoy_dm_table -m /live/vtoyfuse + +mount -t iso9660 /live/vtoyfuse/ventoy.iso /live/vtoyiso + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/debian/vyos-hook.sh b/IMG/cpio/ventoy/hook/debian/vyos-hook.sh new file mode 100644 index 0000000..007f823 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/vyos-hook.sh @@ -0,0 +1,25 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +if [ -e /init ] && $GREP -q '^mountroot$' /init; then + echo "Here before mountroot ..." >> $VTLOG + $SED "/^mountroot$/i\\$BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/vyos-disk.sh" -i /init + $SED "/^mountroot$/i\\export LIVE_MEDIA=/live/vtoyiso" -i /init + #$SED "/^mountroot$/i\\exec /ventoy/busybox/sh" -i /init +fi diff --git a/IMG/cpio/ventoy/hook/deepin/disk_mount_hook.sh b/IMG/cpio/ventoy/hook/deepin/disk_mount_hook.sh new file mode 100644 index 0000000..4e00b8f --- /dev/null +++ b/IMG/cpio/ventoy/hook/deepin/disk_mount_hook.sh @@ -0,0 +1,40 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +vtlog "${vtdiskname#/dev/}2 found..." +$BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/udev_disk_hook.sh "${vtdiskname#/dev/}2" + +if [ -f /ventoy/autoinstall ]; then + sh /ventoy/hook/default/auto_install_varexp.sh /ventoy/autoinstall +fi diff --git a/IMG/cpio/ventoy/hook/deepin/udev_disk_hook.sh b/IMG/cpio/ventoy/hook/deepin/udev_disk_hook.sh new file mode 100644 index 0000000..251f046 --- /dev/null +++ b/IMG/cpio/ventoy/hook/deepin/udev_disk_hook.sh @@ -0,0 +1,151 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +ventoy_os_install_dmsetup() { + + vtlog "ventoy_os_install_dmsetup $1 ..." + + vt_usb_disk=$1 + + # dump iso file location + $VTOY_PATH/tool/vtoydm -i -f $VTOY_PATH/ventoy_image_map -d ${vt_usb_disk} > $VTOY_PATH/iso_file_list + + # install dmsetup + LINE=$($GREP ' dmsetup.*\.udeb' $VTOY_PATH/iso_file_list) + if [ $? -eq 0 ]; then + install_udeb_from_line "$LINE" ${vt_usb_disk} + fi + + # install libdevmapper + LINE=$($GREP ' libdevmapper.*\.udeb' $VTOY_PATH/iso_file_list) + if [ $? -eq 0 ]; then + install_udeb_from_line "$LINE" ${vt_usb_disk} + fi + + # install md-modules + LINE=$($GREP -i ' md-modules.*\.udeb' $VTOY_PATH/iso_file_list) + if [ $? -eq 0 ]; then + LINTCNT=$($GREP -i -c ' md-modules.*\.udeb' $VTOY_PATH/iso_file_list) + if [ $LINTCNT -gt 1 ]; then + vtlog "more than one pkgs, need to filter..." + VER=$($BUSYBOX_PATH/uname -r) + + LINE=$($GREP -i ' md-modules.*\.udeb' $VTOY_PATH/iso_file_list | $GREP -i $VER) + LINTCNT=$($GREP -i ' md-modules.*\.udeb' $VTOY_PATH/iso_file_list | $GREP -i -c $VER) + if [ $LINTCNT -gt 1 ]; then + vtlog "Still more than one pkgs, use the first one..." + LINE=$($GREP -i ' md-modules.*\.udeb' $VTOY_PATH/iso_file_list | $GREP -i -m1 $VER) + fi + fi + install_udeb_from_line "$LINE" ${vt_usb_disk} + fi + + # insmod md-mod if needed + if $GREP -q 'device-mapper' /proc/devices; then + vtlog "device mapper module is loaded" + else + vtlog "device mapper module is NOT loaded, now load it..." + + VER=$($BUSYBOX_PATH/uname -r) + KO=$($FIND /lib/modules/$VER/kernel/drivers/md -name "dm-mod*") + vtlog "KO=$KO" + + insmod $KO + fi + + vtlog "dmsetup install finish, now check it..." + if dmsetup info >> $VTLOG 2>&1; then + vtlog "dmsetup work ok" + else + vtlog "dmsetup not work, now try to load eglibc ..." + + # install eglibc (some ubuntu 32 bit version need it) + LINE=$($GREP 'libc6-.*\.udeb' $VTOY_PATH/iso_file_list) + if [ $? -eq 0 ]; then + install_udeb_from_line "$LINE" ${vt_usb_disk} + fi + + if dmsetup info >> $VTLOG 2>&1; then + vtlog "dmsetup work ok after retry" + else + vtlog "dmsetup still not work after retry" + fi + fi +} + +if is_ventoy_hook_finished || not_ventoy_disk "${1:0:-1}"; then + exit 0 +fi + +vtlog "==== $0 $* ====" + +dmsetup_path=$(ventoy_find_bin_path dmsetup) +if [ -z "$dmsetup_path" ]; then + ventoy_os_install_dmsetup "/dev/${1:0:-1}" +fi + +if ! $GREP -q 'device-mapper' /proc/devices; then + ventoy_os_install_dmsetup "/dev/${1:0:-1}" +fi + +ventoy_udev_disk_common_hook $* + +# +# Some distro default only accept usb partitions as install medium. +# So if ventoy is installed on a non-USB device, we just mount /cdrom here except +# for these has boot=live or boot=casper parameter in cmdline +# +VT_BUS_USB="" +if [ -n "$ID_BUS" ]; then + if echo $ID_BUS | $GREP -q -i usb; then + VT_BUS_USB="YES" + fi +else + if $BUSYBOX_PATH/ls -l /sys/class/block/${1:0:-1} | $GREP -q -i usb; then + VT_BUS_USB="YES" + fi +fi + +if [ -n "$VT_BUS_USB" ]; then + vtlog "$1 is USB device" + echo /dev/$1 > /ventoy/list-devices-usb-part +else + vtlog "$1 is NOT USB device (bus $ID_BUS)" + + if $EGREP -q 'boot=|casper' /proc/cmdline; then + vtlog "boot=, or casper, don't mount" + else + vtlog "No boot param, need to mount" + echo /dev/$1 > /ventoy/list-devices-usb-part + fi +fi + +#special process for Linx +if $BUSYBOX_PATH/uname -r | $GREP -q "^2\.6"; then + if $GREP -q "linx" /proc/version; then + blkdev_num=$($VTOY_PATH/tool/dmsetup ls | $GREP ventoy | $SED 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') + vtDM=$(ventoy_find_dm_id ${blkdev_num}) + echo "/dev/$vtDM" > /ventoy/list-devices-usb-part + fi +fi + +# OK finish +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/deepin/ventoy-hook.sh b/IMG/cpio/ventoy/hook/deepin/ventoy-hook.sh new file mode 100644 index 0000000..cbe921f --- /dev/null +++ b/IMG/cpio/ventoy/hook/deepin/ventoy-hook.sh @@ -0,0 +1,46 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +$CAT /proc/cmdline > /ventoy/cmdline +$SED 's#live-media=[^ ]*#live-media=/dev/mapper/ventoy#g' -i /ventoy/cmdline + +if [ -e /init ] && $GREP -q '^mountroot$' /init; then + echo "Here before mountroot ..." >> $VTLOG + + $SED "/^mountroot$/i\\$BUSYBOX_PATH/sh $VTOY_PATH/hook/deepin/disk_mount_hook.sh" -i /init + $SED "/^mountroot$/i\\export LIVEMEDIA=/dev/mapper/ventoy" -i /init + $SED "/^mountroot$/i\\export LIVE_MEDIA=/dev/mapper/ventoy" -i /init + + $SED "/mount *[-]t *proc/a\\mount --bind /ventoy/cmdline /proc/cmdline" -i /init + + if $GREP -q 'live-media=' /proc/cmdline; then + if [ -f /scripts/casper ] && $GREP -q '^ *LIVEMEDIA=' /scripts/casper; then + $SED "s#^ *LIVEMEDIA=.*#LIVEMEDIA=/dev/mapper/ventoy#" -i /scripts/casper + fi + fi +else + echo "Here use udev hook ..." >> $VTLOG + ventoy_systemd_udevd_work_around + ventoy_add_udev_rule "$VTOY_PATH/hook/deepin/udev_disk_hook.sh %k" +fi + +if [ -f $VTOY_PATH/autoinstall ]; then + echo "Do auto install ..." >> $VTLOG + $SED '/maybe_break[[:space:]]*init/i\/ventoy/busybox/sh /ventoy/hook/deepin/ventoy_autoinstall.sh >>/ventoy/autoinstall.log 2>&1' -i /init +fi diff --git a/IMG/cpio/ventoy/hook/deepin/ventoy_autoinstall.sh b/IMG/cpio/ventoy/hook/deepin/ventoy_autoinstall.sh new file mode 100644 index 0000000..5e6f581 --- /dev/null +++ b/IMG/cpio/ventoy/hook/deepin/ventoy_autoinstall.sh @@ -0,0 +1,122 @@ +#!/ventoy/busybox/sh + +. /ventoy/hook/ventoy_hook_lib.sh + +change_var_value() { + local vfile=$1 + local vkey=$2 + local vVal=$3 + local quote=$4 + local vline + + if [ $quote -eq 0 ]; then + vline="$vkey = $vVal" + else + vline="$vkey = \"$vVal\"" + fi + + if grep -q -m1 "^$vkey[[:space:]]*=" $vfile; then + sed "s#^$vkey[[:space:]]*=.*#$vline#g" -i $vfile + else + echo "$vline" >> $vfile + fi +} + +setting_script_process() { + local sfile=$1 + local vItem + local vB64Item + + vItem=$(grep '^language[[:space:]]*=' /ventoy/autoinstall | awk '{print $3}') + if [ -n "$vItem" ]; then + change_var_value $sfile 'select_language_default_locale' "$vItem" 0 + fi + + vItem=$(grep '^timezone[[:space:]]*=' /ventoy/autoinstall | awk '{print $3}') + if [ -n "$vItem" ]; then + change_var_value $sfile 'timezone_default' "$vItem" 0 + fi + + vItem=$(grep '^hostname[[:space:]]*=' /ventoy/autoinstall | awk '{print $3}') + if [ -n "$vItem" ]; then + change_var_value $sfile 'system_info_default_hostname' "$vItem" 1 + change_var_value $sfile 'DI_HOSTNAME' "$vItem" 1 + fi + + vItem=$(grep '^root_password[[:space:]]*=' /ventoy/autoinstall | awk '{print $3}') + if [ -n "$vItem" ]; then + vB64Item=$(echo -n "$vItem" | base64) + change_var_value $sfile 'system_info_default_root_password' "$vB64Item" 1 + change_var_value $sfile 'DI_ROOTPASSWORD' "$vB64Item" 1 + fi + + vItem=$(grep '^default_username[[:space:]]*=' /ventoy/autoinstall | awk '{print $3}') + if [ -n "$vItem" ]; then + change_var_value $sfile 'system_info_default_username' "$vItem" 1 + change_var_value $sfile 'DI_USERNAME' "$vItem" 1 + fi + + vItem=$(grep '^default_password[[:space:]]*=' /ventoy/autoinstall | awk '{print $3}') + if [ -n "$vItem" ]; then + change_var_value $sfile 'system_info_default_password' "$vItem" 1 + change_var_value $sfile 'DI_PASSWORD' "$vItem" 1 + fi + + vItem=$(grep '^install_disk[[:space:]]*=' /ventoy/autoinstall | awk '{print $3}') + if [ -n "$vItem" ]; then + echo "DI_FULLDISK_MULTIDISK_DEVICE = $vItem" >> $sfile + echo "DI_ROOTDISK = $vItem" >> $sfile + echo "DI_BOOTLOADER = $vItem" >> $sfile + fi + + change_var_value $sfile 'skip_virtual_machine_page' 'true' 0 + change_var_value $sfile 'skip_select_language_page' 'true' 0 + change_var_value $sfile 'skip_select_language_page_on_first_boot' 'true' 0 + change_var_value $sfile 'skip_system_keyboard_page' 'true' 0 + change_var_value $sfile 'skip_system_info_page' 'true' 0 + change_var_value $sfile 'skip_qr_code_system_info_page' 'true' 0 + change_var_value $sfile 'skip_timezone_page' 'true' 0 + change_var_value $sfile 'skip_partition_page' 'true' 0 + change_var_value $sfile 'system_info_password_validate_required' '0' 0 + change_var_value $sfile 'system_info_password_strong_check' 'false' 0 + change_var_value $sfile 'partition_do_auto_part' 'true' 0 + change_var_value $sfile 'system_info_disable_license' 'true' 0 + change_var_value $sfile 'system_info_disable_experience' 'true' 0 + change_var_value $sfile 'system_info_disable_privacy_license' 'true' 0 + + #filesystem.squashfs search ini + #first_page_state=0,表示不跳过首页,展示首页让用户自己选择 + #first_page_state=1,表示跳过首页,并且自动点击一键安装 + #first_page_state=2,表示跳过首页,并且自动点击自定义安装 + #first_page_state=3,表示跳过首页,并且直接以全盘安装方式自动安装 + change_var_value $sfile 'first_page_state' '3' 0 +} + +update_settings() { + local script=$1 + local newscript + + echo "update_settings for $script ..." + + newscript=$(basename $script) + cp -a $script /ventoy/vini_${newscript} + setting_script_process /ventoy/vini_${newscript} + + rm -f $script + cp -a /ventoy/vini_${newscript} $script +} + +sh /ventoy/hook/common/auto_install_varexp.sh /ventoy/autoinstall + +update_settings /root/usr/share/deepin-installer/resources/default_settings.ini + +ls -1 /root/usr/share/deepin-installer/resources/override/ | while read line; do + update_settings /root/usr/share/deepin-installer/resources/override/$line +done + +ls -1 /root/usr/share/deepin-installer/resources/oem/ | while read line; do + update_settings /root/usr/share/deepin-installer/resources/oem/$line +done + + + diff --git a/IMG/cpio/ventoy/hook/default/10-dm.rules b/IMG/cpio/ventoy/hook/default/10-dm.rules new file mode 100644 index 0000000..f33df58 --- /dev/null +++ b/IMG/cpio/ventoy/hook/default/10-dm.rules @@ -0,0 +1,150 @@ +# Copyright (C) 2009 Red Hat, Inc. All rights reserved. +# +# This file is part of LVM2. + +# Udev rules for device-mapper devices. +# +# These rules create a DM control node in /dev/mapper directory. +# The rules also create nodes named dm-x (x is a number) in /dev +# directory and symlinks to these nodes with names given by +# the actual DM names. Some udev environment variables are set +# for use in later rules: +# DM_NAME - actual DM device's name +# DM_UUID - UUID set for DM device (blank if not specified) +# DM_SUSPENDED - suspended state of DM device (0 or 1) +# DM_UDEV_RULES_VSN - DM udev rules version +# +# These rules cover only basic device-mapper functionality in udev. +# +# Various DM subsystems may contain further subsystem-specific rules +# in 11-dm-.rules which should be installed together +# with the DM subsystem and which extend these basic rules. +# For example: +# 11-dm-lvm.rules for LVM subsystem +# 11-dm-mpath.rules for multipath subsystem (since version 0.6.0, recommended!) +# +# Even more specific rules may be required by subsystems so always +# check subsystem's upstream repository for recent set of rules. +# Also, keep in mind that recent rules may also require recent +# subsystem-specific binaries. + +KERNEL=="device-mapper", NAME="mapper/control" + +SUBSYSTEM!="block", GOTO="dm_end" +KERNEL!="dm-[0-9]*", GOTO="dm_end" + + +# Device created, major and minor number assigned - "add" event generated. +# Table loaded - no event generated. +# Device resumed (or renamed) - "change" event generated. +# Device removed - "remove" event generated. +# +# The dm-X nodes are always created, even on "add" event, we can't suppress +# that (the node is created even earlier with devtmpfs). All the symlinks +# (e.g. /dev/mapper) are created in right time after a device has its table +# loaded and is properly resumed. For this reason, direct use of dm-X nodes +# is not recommended. +ACTION!="add|change", GOTO="dm_end" + +# Decode udev control flags and set environment variables appropriately. +# These flags are encoded in DM_COOKIE variable that was introduced in +# kernel version 2.6.31. Therefore, we can use this feature with +# kernels >= 2.6.31 only. Cookie is not decoded for remove event. +ENV{DM_COOKIE}=="?*", IMPORT{program}="/usr/sbin/dmsetup udevflags $env{DM_COOKIE}" + +# Rule out easy-to-detect inappropriate events first. +ENV{DISK_RO}=="1", GOTO="dm_disable" + +# There is no cookie set nor any flags encoded in events not originating +# in libdevmapper so we need to detect this and try to behave correctly. +# For such spurious events, regenerate all flags from current udev database content +# (this information would normally be inaccessible for spurious ADD and CHANGE events). +ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", ENV{DM_ACTIVATION}="1", GOTO="dm_flags_done" +IMPORT{db}="DM_UDEV_DISABLE_DM_RULES_FLAG" +IMPORT{db}="DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG" +IMPORT{db}="DM_UDEV_DISABLE_DISK_RULES_FLAG" +IMPORT{db}="DM_UDEV_DISABLE_OTHER_RULES_FLAG" +IMPORT{db}="DM_UDEV_LOW_PRIORITY_FLAG" +IMPORT{db}="DM_UDEV_DISABLE_LIBRARY_FALLBACK_FLAG" +IMPORT{db}="DM_UDEV_PRIMARY_SOURCE_FLAG" +IMPORT{db}="DM_UDEV_FLAG7" +IMPORT{db}="DM_UDEV_RULES_VSN" +LABEL="dm_flags_done" + +# Normally, we operate on "change" events. But when coldplugging, there's an +# "add" event present. We have to recognize this and do our actions in this +# particular situation, too. Also, we don't want the nodes to be created +# prematurely on "add" events while not coldplugging. We check +# DM_UDEV_PRIMARY_SOURCE_FLAG to see if the device was activated correctly +# before and if not, we ignore the "add" event totally. This way we can support +# udev triggers generating "add" events (e.g. "udevadm trigger --action=add" or +# "echo add > /sys/block//uevent"). The trigger with "add" event is +# also used at boot to reevaluate udev rules for all existing devices activated +# before (e.g. in initrd). If udev is used in initrd, we require the udev init +# script to not remove the existing udev database so we can reuse the information +# stored at the time of device activation in the initrd. +ACTION!="add", GOTO="dm_no_coldplug" +ENV{DM_UDEV_RULES_VSN}!="1", ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1", GOTO="dm_disable" +ENV{DM_ACTIVATION}="1" +LABEL="dm_no_coldplug" + +# Putting it together, following table is used to recognize genuine and spurious events. +# N.B. Spurious events are generated based on use of the WATCH udev +# rule or by triggering an event manually by "udevadm trigger" call +# or by "echo > /sys/block/dm-X/uevent". +# +# EVENT DM_UDEV_PRIMARY_SOURCE_FLAG DM_ACTIVATION +# ====================================================================== +# add event (genuine) 0 0 +# change event (genuine) 1 1 +# add event (spurious) +# |_ dev still not active 0 0 +# \_ dev already active 1 1 +# change event (spurious) +# |_ dev still not active 0 0 +# \_ dev already active 1 0 + +# "dm" sysfs subdirectory is available in newer versions of DM +# only (kernels >= 2.6.29). We have to check for its existence +# and use dmsetup tool instead to get the DM name, uuid and +# suspended state if the "dm" subdirectory is not present. +# The "suspended" item was added even later (kernels >= 2.6.31), +# so we also have to call dmsetup if the kernel version used +# is in between these releases. +TEST=="dm", ENV{DM_NAME}="$attr{dm/name}", ENV{DM_UUID}="$attr{dm/uuid}", ENV{DM_SUSPENDED}="$attr{dm/suspended}" +TEST!="dm", IMPORT{program}="/usr/sbin/dmsetup info -j %M -m %m -c --nameprefixes --noheadings --rows -o name,uuid,suspended" +ENV{DM_SUSPENDED}!="?*", IMPORT{program}="/usr/sbin/dmsetup info -j %M -m %m -c --nameprefixes --noheadings --rows -o suspended" + +# dmsetup tool provides suspended state information in textual +# form with values "Suspended"/"Active". We translate it to +# 0/1 respectively to be consistent with sysfs values. +ENV{DM_SUSPENDED}=="Active", ENV{DM_SUSPENDED}="0" +ENV{DM_SUSPENDED}=="Suspended", ENV{DM_SUSPENDED}="1" + +# This variable provides a reliable way to check that device-mapper +# rules were installed. It means that all needed variables are set +# by these rules directly so there's no need to acquire them again +# later. Other rules can alternate the functionality based on this +# fact (e.g. fallback to rules that behave correctly even without +# these rules installed). It also provides versioning for any +# possible future changes. +# VSN 1 - original rules +# VSN 2 - add support for synthesized events +ENV{DM_UDEV_RULES_VSN}="2" + +ENV{DM_UDEV_DISABLE_DM_RULES_FLAG}!="1", ENV{DM_NAME}=="?*", SYMLINK+="mapper/$env{DM_NAME}" + +# Avoid processing and scanning a DM device in the other (foreign) +# rules if it is in suspended state. However, we still keep 'disk' +# and 'DM subsystem' related rules enabled in this case. +ENV{DM_SUSPENDED}=="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" + +GOTO="dm_end" + +LABEL="dm_disable" +ENV{DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG}="1" +ENV{DM_UDEV_DISABLE_DISK_RULES_FLAG}="1" +ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" +OPTIONS:="nowatch" + +LABEL="dm_end" diff --git a/IMG/cpio/ventoy/hook/default/13-dm-disk.rules b/IMG/cpio/ventoy/hook/default/13-dm-disk.rules new file mode 100644 index 0000000..9be707a --- /dev/null +++ b/IMG/cpio/ventoy/hook/default/13-dm-disk.rules @@ -0,0 +1,42 @@ +# Copyright (C) 2009 Red Hat, Inc. All rights reserved. +# +# This file is part of LVM2. + +# Udev rules for device-mapper devices. +# +# These rules create symlinks in /dev/disk directory. +# Symlinks that depend on probing filesystem type, +# label and uuid are created only if the device is not +# suspended. + +# "add" event is processed on coldplug only! +ACTION!="add|change", GOTO="dm_end" +ENV{DM_UDEV_RULES_VSN}!="?*", GOTO="dm_end" +ENV{DM_UDEV_DISABLE_DISK_RULES_FLAG}=="1", GOTO="dm_end" + +SYMLINK+="disk/by-id/dm-name-$env{DM_NAME}" +ENV{DM_UUID}=="?*", SYMLINK+="disk/by-id/dm-uuid-$env{DM_UUID}" + +ENV{DM_SUSPENDED}=="1", GOTO="dm_end" +ENV{DM_NOSCAN}=="1", GOTO="dm_watch" + +IMPORT{builtin}="blkid" +ENV{DM_UDEV_LOW_PRIORITY_FLAG}=="1", OPTIONS="link_priority=-100" +ENV{ID_FS_USAGE}=="filesystem|other|crypto", ENV{ID_FS_UUID_ENC}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID_ENC}" +ENV{ID_FS_USAGE}=="filesystem|other", ENV{ID_FS_LABEL_ENC}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_ENC}" +ENV{ID_PART_ENTRY_UUID}=="?*", SYMLINK+="disk/by-partuuid/$env{ID_PART_ENTRY_UUID}" +ENV{ID_PART_ENTRY_SCHEME}=="gpt", ENV{ID_PART_ENTRY_NAME}=="?*", SYMLINK+="disk/by-partlabel/$env{ID_PART_ENTRY_NAME}" +ENV{ID_PART_ENTRY_SCHEME}=="gpt", ENV{ID_PART_GPT_AUTO_ROOT}=="1", SYMLINK+="gpt-auto-root" + +# Add inotify watch to track changes on this device. +# Using the watch rule is not optimal - it generates a lot of spurious +# and useless events whenever the device opened for read-write is closed. +# The best would be to generete the event directly in the tool changing +# relevant information so only relevant events will be processed +# (like creating a filesystem, changing filesystem label etc.). +# +# But let's use this until we have something better... +LABEL="dm_watch" +OPTIONS+="watch" + +LABEL="dm_end" diff --git a/IMG/cpio/ventoy/hook/default/auto_install_varexp.sh b/IMG/cpio/ventoy/hook/default/auto_install_varexp.sh new file mode 100644 index 0000000..af01d4e --- /dev/null +++ b/IMG/cpio/ventoy/hook/default/auto_install_varexp.sh @@ -0,0 +1,53 @@ +#!/bin/sh +#************************************************************************************ +# Copyright (c) 2022, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +PATH=$PATH:/ventoy/busybox:/ventoy/tool + +vlog() { + echo "$@" >> /ventoy/autoinstall.log +} + +if grep -q '\$\$VT_' /ventoy/autoinstall; then + vlog "======== auto install variables expansion =======" +else + vlog "======== auto install variables expansion no need =======" + exit 0 +fi + +if [ -f /ventoy/ventoy_os_param ]; then + VTOYDISK=$(vtoydump -f /ventoy/ventoy_os_param | awk -F'#' '{print $1}') + vlog VTOYDISK=$VTOYDISK + + if [ -b "$VTOYDISK" ]; then + vlog "$VTOYDISK exist OK" + else + vlog "$VTOYDISK does NOT exist" + exit 0 + fi + + if [ -n "$1" -a -f "$1" ]; then + vtoyexpand "$1" "$VTOYDISK" + else + vlog "File $1 not exist" + fi +else + vlog "os param file not exist" + exit 0 +fi + diff --git a/IMG/cpio/ventoy/hook/default/export.list b/IMG/cpio/ventoy/hook/default/export.list new file mode 100644 index 0000000..821a574 --- /dev/null +++ b/IMG/cpio/ventoy/hook/default/export.list @@ -0,0 +1,7 @@ +preseed/file +debian-installer/locale +console-keymaps-at/keymap +keyboard-configuration/xkb-keymap +keyboard-configuration/layout +simple-cdd/profiles +vga diff --git a/IMG/cpio/ventoy/hook/default/udev_disk_hook.sh b/IMG/cpio/ventoy/hook/default/udev_disk_hook.sh new file mode 100644 index 0000000..633f29e --- /dev/null +++ b/IMG/cpio/ventoy/hook/default/udev_disk_hook.sh @@ -0,0 +1,30 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished || not_ventoy_disk "${1:0:-1}"; then + exit 0 +fi + +ventoy_udev_disk_common_hook $* + +# OK finish +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/default/ventoy-hook.sh b/IMG/cpio/ventoy/hook/default/ventoy-hook.sh new file mode 100644 index 0000000..56e0e35 --- /dev/null +++ b/IMG/cpio/ventoy/hook/default/ventoy-hook.sh @@ -0,0 +1,33 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +ventoy_systemd_udevd_work_around + +ventoy_add_udev_rule "$VTOY_PATH/hook/default/udev_disk_hook.sh %k" + +if [ -f /init ]; then + vtSize=$($BUSYBOX_PATH/stat -c '%s' /init) + if ! [ -L /init ]; then + if [ $vtSize -eq 0 ]; then + rm -f /init + fi + fi +fi diff --git a/IMG/cpio/ventoy/hook/default/ventoy-inotifyd-start.sh b/IMG/cpio/ventoy/hook/default/ventoy-inotifyd-start.sh new file mode 100644 index 0000000..6be8155 --- /dev/null +++ b/IMG/cpio/ventoy/hook/default/ventoy-inotifyd-start.sh @@ -0,0 +1,31 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtHook=$($CAT $VTOY_PATH/inotifyd-hook-script.txt) + +vtdisk=$(get_ventoy_disk_name) +if [ "$vtdisk" = "unknown" ]; then + vtlog "... start inotifyd listen $vtHook ..." + $BUSYBOX_PATH/nohup $VTOY_PATH/tool/inotifyd $vtHook /dev:n 2>&- & +else + vtlog "... $vtdisk already exist ..." + $BUSYBOX_PATH/sh $vtHook n /dev "${vtdisk#/dev/}2" +fi diff --git a/IMG/cpio/ventoy/hook/dragora/disk_hook.sh b/IMG/cpio/ventoy/hook/dragora/disk_hook.sh new file mode 100644 index 0000000..7cc5957 --- /dev/null +++ b/IMG/cpio/ventoy/hook/dragora/disk_hook.sh @@ -0,0 +1,44 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_extract_vtloopex ${vtdiskname}2 dragora +vtLoopExDir=$VTOY_PATH/vtloopex/dragora/vtloopex +$BUSYBOX_PATH/xz -d $vtLoopExDir/dm-mod/$(uname -r)/64/dm-mod.ko.xz +$BUSYBOX_PATH/insmod $vtLoopExDir/dm-mod/$(uname -r)/64/dm-mod.ko + + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/dragora/ventoy-hook.sh b/IMG/cpio/ventoy/hook/dragora/ventoy-hook.sh new file mode 100644 index 0000000..a0a2c19 --- /dev/null +++ b/IMG/cpio/ventoy/hook/dragora/ventoy-hook.sh @@ -0,0 +1,22 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/iso9660/i $BUSYBOX_PATH/sh $VTOY_PATH/hook/dragora/disk_hook.sh" -i /init diff --git a/IMG/cpio/ventoy/hook/easystartup/disk_hook.sh b/IMG/cpio/ventoy/hook/easystartup/disk_hook.sh new file mode 100644 index 0000000..201255c --- /dev/null +++ b/IMG/cpio/ventoy/hook/easystartup/disk_hook.sh @@ -0,0 +1,89 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2021, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +get_rhel_ver() { + if uname -m | grep -q '64'; then + machine='_X64' + fi + + if grep -q '6[.]1' /etc/redhat-release; then + echo "RHAS6U1$machine"; return + fi + + echo "RHAS6U1$machine" +} + +install_dm_mod_ko() { + # dump iso file location + vtoydm -i -f $VTOY_PATH/ventoy_image_map -d ${vtdiskname} > $VTOY_PATH/iso_file_list + + sysver=$(get_rhel_ver) + vtlog "sysver=$sysver" + + LINE=$(grep "$sysver" -n -m1 $VTOY_PATH/iso_file_list | awk -F: '{print $1}') + vtlog "LINE=$LINE" + + LINE=$(sed -n "$LINE,\$p" $VTOY_PATH/iso_file_list | grep -m1 'initrd.img') + vtlog "LINE=$LINE" + + sector=$(echo $LINE | $AWK '{print $(NF-1)}') + length=$(echo $LINE | $AWK '{print $NF}') + vtlog "sector=$sector length=$length" + + mkdir xxx + vtoydm -e -f $VTOY_PATH/ventoy_image_map -d ${vtdiskname} -s $sector -l $length -o ./xxx.img + + cd xxx/ + zcat ../xxx.img | cpio -idmu + ko=$(find -name dm-mod.ko*) + vtlog "ko=$ko ..." + insmod $ko + + cd ../ + rm -f xxx.img + rm -rf xxx +} + +vtdiskname=$(get_ventoy_disk_name) +vtlog "vtdiskname=$vtdiskname ..." +if [ "$vtdiskname" = "unknown" ]; then + exit 0 +fi + +if grep -q 'device-mapper' /proc/devices; then + vtlog "device-mapper module check ko" +else + install_dm_mod_ko +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) +cp -a /dev/$vtDM /dev/ventoy +ln -s /dev/$vtDM /dev/root + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/easystartup/ventoy-hook.sh b/IMG/cpio/ventoy/hook/easystartup/ventoy-hook.sh new file mode 100644 index 0000000..d18d9d5 --- /dev/null +++ b/IMG/cpio/ventoy/hook/easystartup/ventoy-hook.sh @@ -0,0 +1,23 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2021, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "s#^CDROM=.*#CDROM=/dev/ventoy#" -i /init +$BUSYBOX_PATH/cp -a $VTOY_PATH/hook/easystartup/ventoy-initqueue.sh /initqueue/ventoy.sh diff --git a/IMG/cpio/ventoy/hook/easystartup/ventoy-initqueue.sh b/IMG/cpio/ventoy/hook/easystartup/ventoy-initqueue.sh new file mode 100644 index 0000000..d4c8b5f --- /dev/null +++ b/IMG/cpio/ventoy/hook/easystartup/ventoy-initqueue.sh @@ -0,0 +1,20 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2021, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +/ventoy/busybox/sh /ventoy/hook/easystartup/disk_hook.sh $* diff --git a/IMG/cpio/ventoy/hook/euleros/disk_mount_hook.sh b/IMG/cpio/ventoy/hook/euleros/disk_mount_hook.sh new file mode 100644 index 0000000..f12e430 --- /dev/null +++ b/IMG/cpio/ventoy/hook/euleros/disk_mount_hook.sh @@ -0,0 +1,24 @@ +#!/ventoy/busybox/sh + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "######### $0 $* ############" + +if is_ventoy_hook_finished; then + exit 0 +fi + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + exit 0 +fi + +vtlog "vtdiskname=$vtdiskname" + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +# OK finish +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/euleros/hook_func.sh b/IMG/cpio/ventoy/hook/euleros/hook_func.sh new file mode 100644 index 0000000..d1430fe --- /dev/null +++ b/IMG/cpio/ventoy/hook/euleros/hook_func.sh @@ -0,0 +1,7 @@ + +function ft_mountCdromDir() +{ + /ventoy/busybox/sh /ventoy/hook/euleros/disk_mount_hook.sh + ft_mountCdromDirXX "$@" +} + diff --git a/IMG/cpio/ventoy/hook/euleros/ventoy-hook.sh b/IMG/cpio/ventoy/hook/euleros/ventoy-hook.sh new file mode 100644 index 0000000..5750753 --- /dev/null +++ b/IMG/cpio/ventoy/hook/euleros/ventoy-hook.sh @@ -0,0 +1,42 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +TRANSFILE=/usr/Euler/project/load/filetransfer.sh + +LINE=$($GREP -n 'function ft_mountCdromDir' $TRANSFILE | $AWK -F':' '{print $1}') + +echo "LINE=$LINE" >> $VTLOG + +$SED 's#FT_SR_DEV=.*#FT_SR_DEV=/dev/mapper/ventoy#g' -i $TRANSFILE +$SED 's/function ft_mountCdromDir/function ft_mountCdromDirXX/' -i $TRANSFILE + +let LINE-- +$SED -n "1,${LINE}p" $TRANSFILE >> /ventoy/filetransfer.sh + +$CAT $VTOY_PATH/hook/euleros/hook_func.sh >> /ventoy/filetransfer.sh + +let LINE++ +$SED -n "${LINE},\$p" $TRANSFILE >> /ventoy/filetransfer.sh + +$BUSYBOX_PATH/mv /ventoy/filetransfer.sh $TRANSFILE + +#fix the euler os shell script +$SED 's/-z ${harddisk_disk_list}/-z "${harddisk_disk_list}"/' -i /usr/Euler/project/disk/disk_tool.sh diff --git a/IMG/cpio/ventoy/hook/ewe/ventoy-disk.sh b/IMG/cpio/ventoy/hook/ewe/ventoy-disk.sh new file mode 100644 index 0000000..30b3f3a --- /dev/null +++ b/IMG/cpio/ventoy/hook/ewe/ventoy-disk.sh @@ -0,0 +1,75 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "######### $0 $* ############" + +if is_ventoy_hook_finished; then + exit 0 +fi + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | $GREP ventoy | $SED 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) +vtlog "blkdev_num=$blkdev_num vtDM=$vtDM ..." + +while [ -n "Y" ]; do + if [ -b /dev/$vtDM ]; then + break + else + sleep 0.3 + fi +done + +if [ -n "$1" ]; then + vtlog "ln -s /dev/$vtDM $1" + + if [ -e "$1" ]; then + vtlog "$1 already exist" + else + ln -s /dev/$vtDM "$1" + fi +else + vtLABEL=$($BUSYBOX_PATH/blkid /dev/$vtDM | $SED 's/.*LABEL="\([^"]*\)".*/\1/') + vtlog "vtLABEL is $vtLABEL" + + if [ -z "$vtLABEL" ]; then + vtLABEL=$($SED "s/.*label=\([^ ]*\)/\1/" /proc/cmdline) + vtlog "vtLABEL is $vtLABEL from cmdline" + fi + + if [ -e "/dev/disk/by-label/$vtLABEL" ]; then + vtlog "$1 already exist" + else + ln -s /dev/$vtDM "/dev/disk/by-label/$vtLABEL" + fi +fi + +# OK finish +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/ewe/ventoy-hook.sh b/IMG/cpio/ventoy/hook/ewe/ventoy-hook.sh new file mode 100644 index 0000000..590415f --- /dev/null +++ b/IMG/cpio/ventoy/hook/ewe/ventoy-hook.sh @@ -0,0 +1,25 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +echo "hook live.init" >> $VTLOG + +$SED "1i $BUSYBOX_PATH/sh $VTOY_PATH/hook/ewe/ventoy-disk.sh" -i /lib/tinyramfs/hook.d/live/live.init + diff --git a/IMG/cpio/ventoy/hook/fatdog/disk-hook.sh b/IMG/cpio/ventoy/hook/fatdog/disk-hook.sh new file mode 100644 index 0000000..8ee0579 --- /dev/null +++ b/IMG/cpio/ventoy/hook/fatdog/disk-hook.sh @@ -0,0 +1,43 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/fatdog/ventoy-hook.sh b/IMG/cpio/ventoy/hook/fatdog/ventoy-hook.sh new file mode 100644 index 0000000..8b16432 --- /dev/null +++ b/IMG/cpio/ventoy/hook/fatdog/ventoy-hook.sh @@ -0,0 +1,23 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/find_local_device *(/a $BUSYBOX_PATH/sh $VTOY_PATH/hook/fatdog/disk-hook.sh" -i /init +$SED "/find_and_choose_local_device *(/a $BUSYBOX_PATH/sh $VTOY_PATH/hook/fatdog/disk-hook.sh" -i /init diff --git a/IMG/cpio/ventoy/hook/gentoo/disk_hook.sh b/IMG/cpio/ventoy/hook/gentoo/disk_hook.sh new file mode 100644 index 0000000..455cbbf --- /dev/null +++ b/IMG/cpio/ventoy/hook/gentoo/disk_hook.sh @@ -0,0 +1,39 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +# Just for KVM test environment +$BUSYBOX_PATH/modprobe virtio_blk 2>/dev/null +$BUSYBOX_PATH/modprobe virtio_pci 2>/dev/null + +for i in 0 1 2 3 4 5 6 7 8 9; do + vtdiskname=$(get_ventoy_disk_name) + if [ "$vtdiskname" = "unknown" ]; then + vtlog "wait for disk ..." + $SLEEP 2 + else + break + fi +done + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/gentoo/ventoy-hook.sh b/IMG/cpio/ventoy/hook/gentoo/ventoy-hook.sh new file mode 100644 index 0000000..d0ba02a --- /dev/null +++ b/IMG/cpio/ventoy/hook/gentoo/ventoy-hook.sh @@ -0,0 +1,35 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +if $GREP -q kaspersky /proc/version; then + $SED "/sysresccd_stage1_normal[^(]*$/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/gentoo/disk_hook.sh" -i /init + if [ -f /ventoy/ventoy_persistent_map ]; then + $SED "/sysresccd_parsecmdline[^(]*$/a\ BACKSTORE_CMD='LABEL=casper-rw,noloop'" -i /init + fi +elif $GREP -q 'setting up the root filesystem' /init; then + $SED "/setting up the root filesystem/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/gentoo/disk_hook.sh" -i /init + $SED "/setting up the root filesystem/a\ export CDROOT_DEV=/dev/mapper/ventoy" -i /init +elif [ -d /etc/udev/rules.d ] || [ -d /lib/udev/rules.d ]; then + ventoy_systemd_udevd_work_around + ventoy_add_udev_rule "$VTOY_PATH/hook/default/udev_disk_hook.sh %k noreplace" +else + $SED "/mdev *-s/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/gentoo/disk_hook.sh" -i /init +fi diff --git a/IMG/cpio/ventoy/hook/gobo/ventoy-hook.sh b/IMG/cpio/ventoy/hook/gobo/ventoy-hook.sh new file mode 100644 index 0000000..eb22a28 --- /dev/null +++ b/IMG/cpio/ventoy/hook/gobo/ventoy-hook.sh @@ -0,0 +1,26 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "s#printf\(.*\)\$CMDLINE#printf\1\$CMDLINE root=live:/dev/mapper/ventoy#" -i /lib/dracut-lib.sh + +ventoy_set_inotify_script gobo/ventoy-inotifyd-hook.sh + +$BUSYBOX_PATH/cp -a $VTOY_PATH/hook/gobo/ventoy-inotifyd-start.sh /lib/dracut/hooks/pre-udev/01-ventoy-inotifyd-start.sh diff --git a/IMG/cpio/ventoy/hook/gobo/ventoy-inotifyd-hook.sh b/IMG/cpio/ventoy/hook/gobo/ventoy-inotifyd-hook.sh new file mode 100644 index 0000000..34a70a0 --- /dev/null +++ b/IMG/cpio/ventoy/hook/gobo/ventoy-inotifyd-hook.sh @@ -0,0 +1,39 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +if is_inotify_ventoy_part $3; then + vtlog "##### INOTIFYD: $2/$3 is created (YES)..." + + vtlog "find ventoy partition $3 ..." + $BUSYBOX_PATH/sh $VTOY_PATH/hook/default/udev_disk_hook.sh $3 noreplace + + set_ventoy_hook_finish +else + vtlog "##### INOTIFYD: $2/$3 is created (NO)..." +fi + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/gobo/ventoy-inotifyd-start.sh b/IMG/cpio/ventoy/hook/gobo/ventoy-inotifyd-start.sh new file mode 100644 index 0000000..6be8155 --- /dev/null +++ b/IMG/cpio/ventoy/hook/gobo/ventoy-inotifyd-start.sh @@ -0,0 +1,31 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtHook=$($CAT $VTOY_PATH/inotifyd-hook-script.txt) + +vtdisk=$(get_ventoy_disk_name) +if [ "$vtdisk" = "unknown" ]; then + vtlog "... start inotifyd listen $vtHook ..." + $BUSYBOX_PATH/nohup $VTOY_PATH/tool/inotifyd $vtHook /dev:n 2>&- & +else + vtlog "... $vtdisk already exist ..." + $BUSYBOX_PATH/sh $vtHook n /dev "${vtdisk#/dev/}2" +fi diff --git a/IMG/cpio/ventoy/hook/guix/ventoy-before-init.sh b/IMG/cpio/ventoy/hook/guix/ventoy-before-init.sh new file mode 100644 index 0000000..c29ca07 --- /dev/null +++ b/IMG/cpio/ventoy/hook/guix/ventoy-before-init.sh @@ -0,0 +1,26 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$BUSYBOX_PATH/mkdir /dev +$BUSYBOX_PATH/mknod -m 0660 /dev/null c 1 3 + +$BUSYBOX_PATH/sh $VTOY_PATH/hook/guix/ventoy-disk.sh & + diff --git a/IMG/cpio/ventoy/hook/guix/ventoy-disk.sh b/IMG/cpio/ventoy/hook/guix/ventoy-disk.sh new file mode 100644 index 0000000..fe7173d --- /dev/null +++ b/IMG/cpio/ventoy/hook/guix/ventoy-disk.sh @@ -0,0 +1,53 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "######### $0 $* ############" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +blkdev_num_mknod=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) + +vtlog "blkdev_num=$blkdev_num blkdev_num_mknod=$blkdev_num_mknod vtDM=$vtDM" + +if [ -b /dev/$vtDM ]; then + vtlog "dev already exist ..." +else + vtlog "mknode dev ..." + mknod -m 660 /dev/$vtDM b $blkdev_num_mknod +fi + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/guix/ventoy-hook.sh b/IMG/cpio/ventoy/hook/guix/ventoy-hook.sh new file mode 100644 index 0000000..dc6474e --- /dev/null +++ b/IMG/cpio/ventoy/hook/guix/ventoy-hook.sh @@ -0,0 +1,20 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh diff --git a/IMG/cpio/ventoy/hook/hyperbola/ventoy-disk.sh b/IMG/cpio/ventoy/hook/hyperbola/ventoy-disk.sh new file mode 100644 index 0000000..356c77f --- /dev/null +++ b/IMG/cpio/ventoy/hook/hyperbola/ventoy-disk.sh @@ -0,0 +1,48 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "######### $0 $* ############" + +if is_ventoy_hook_finished; then + exit 0 +fi + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +if [ -n "$1" ]; then + blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') + vtDM=$(ventoy_find_dm_id ${blkdev_num}) + + vtlog "ln -s /dev/$vtDM $1" + ln -s /dev/$vtDM "$1" +fi + +# OK finish +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/hyperbola/ventoy-hook.sh b/IMG/cpio/ventoy/hook/hyperbola/ventoy-hook.sh new file mode 100644 index 0000000..aebe57a --- /dev/null +++ b/IMG/cpio/ventoy/hook/hyperbola/ventoy-hook.sh @@ -0,0 +1,44 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +if $GREP -q '^"$mount_handler"' /init; then + echo 'use mount_handler ...' >> $VTLOG + $SED "/^\"\$mount_handler\"/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/hyperbola/ventoy-disk.sh \"\$hyperisodevice\"" -i /init + + if [ -f /hooks/parabolaiso ]; then + $SED '/while ! poll_device "${dev}"/a\ if /ventoy/busybox/sh /ventoy/hook/hyperbola/ventoy-timeout.sh ${dev}; then break; fi' -i /hooks/hyperiso + fi + +else + # some archlinux initramfs doesn't contain device-mapper udev rules file + ARCH_UDEV_DIR=$(ventoy_get_udev_conf_dir) + if [ -s "$ARCH_UDEV_DIR/13-dm-disk.rules" ]; then + echo 'dm-disk rule exist' >> $VTLOG + else + echo 'Copy dm-disk rule file' >> $VTLOG + $CAT $VTOY_PATH/hook/default/13-dm-disk.rules > "$ARCH_UDEV_DIR/13-dm-disk.rules" + fi + + # use default proc + ventoy_systemd_udevd_work_around + + ventoy_add_udev_rule "$VTOY_PATH/hook/default/udev_disk_hook.sh %k" +fi diff --git a/IMG/cpio/ventoy/hook/hyperbola/ventoy-timeout.sh b/IMG/cpio/ventoy/hook/hyperbola/ventoy-timeout.sh new file mode 100644 index 0000000..fec9cc0 --- /dev/null +++ b/IMG/cpio/ventoy/hook/hyperbola/ventoy-timeout.sh @@ -0,0 +1,36 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "######### $0 $* ############" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) + +if [ -b /dev/$vtDM ]; then + vtlog "ln -s /dev/$vtDM $1" + ln -s /dev/$vtDM "$1" + exit 0 +else + vtlog "Device-mapper not found" + exit 1 +fi + + diff --git a/IMG/cpio/ventoy/hook/kaos/ventoy-disk.sh b/IMG/cpio/ventoy/hook/kaos/ventoy-disk.sh new file mode 100644 index 0000000..42569cc --- /dev/null +++ b/IMG/cpio/ventoy/hook/kaos/ventoy-disk.sh @@ -0,0 +1,118 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "######### $0 $* ############" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + + +ventoy_os_install_dmsetup_by_fuse() { + vtlog "ventoy_os_install_dmsetup_by_fuse $*" + + mkdir -p $VTOY_PATH/mnt/fuse $VTOY_PATH/mnt/iso $VTOY_PATH/mnt/squashfs + + vtoydm -p -f $VTOY_PATH/ventoy_image_map -d $1 > $VTOY_PATH/ventoy_dm_table + vtoy_fuse_iso -f $VTOY_PATH/ventoy_dm_table -m $VTOY_PATH/mnt/fuse + + mount -t iso9660 $VTOY_PATH/mnt/fuse/ventoy.iso $VTOY_PATH/mnt/iso + + sfsfile=$VTOY_PATH/mnt/iso/kdeos/x86_64/root-image.sqfs + + mount -t squashfs $sfsfile $VTOY_PATH/mnt/squashfs + + kVer=$(uname -r) + KoName=$(ls $VTOY_PATH/mnt/squashfs/lib/modules/$kVer/kernel/drivers/md/dm-mod.ko*) + vtlog "insmod $KoName" + + if echo $KoName | grep -q '\.zst'; then + zstdcat $KoName > $VTOY_PATH/dm-mod.ko + insmod $VTOY_PATH/dm-mod.ko + else + insmod $KoName + fi + + ventoy_check_umount $VTOY_PATH/mnt/squashfs + ventoy_check_umount $VTOY_PATH/mnt/iso + ventoy_check_umount $VTOY_PATH/mnt/fuse + vtlog "umount done" +} + + +if is_ventoy_hook_finished; then + exit 0 +fi + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + exit 0 +fi + +if grep -q 'device-mapper' /proc/devices; then + vtlog "device-mapper module exist" +else + ventoy_os_install_dmsetup_by_fuse $vtdiskname +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) +vtlog "blkdev_num=$blkdev_num vtDM=$vtDM ..." + +while [ -n "Y" ]; do + if [ -b /dev/$vtDM ]; then + break + else + sleep 0.3 + fi +done + +if [ -n "$1" ]; then + vtlog "ln -s /dev/$vtDM $1" + + if [ -e "$1" ]; then + vtlog "$1 already exist" + else + ln -s /dev/$vtDM "$1" + fi +else + vtLABEL=$($BUSYBOX_PATH/blkid /dev/$vtDM | $SED 's/.*LABEL="\([^"]*\)".*/\1/') + vtlog "vtLABEL is $vtLABEL" + + if [ -z "$vtLABEL" ]; then + vtLABEL=$($SED "s/.*label=\([^ ]*\)/\1/" /proc/cmdline) + vtlog "vtLABEL is $vtLABEL from cmdline" + fi + + if [ -e "/dev/disk/by-label/$vtLABEL" ]; then + vtlog "$1 already exist" + else + ln -s /dev/$vtDM "/dev/disk/by-label/$vtLABEL" + fi +fi + +PATH=$VTPATH_OLD + +# OK finish +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/kaos/ventoy-hook.sh b/IMG/cpio/ventoy/hook/kaos/ventoy-hook.sh new file mode 100644 index 0000000..84aadc0 --- /dev/null +++ b/IMG/cpio/ventoy/hook/kaos/ventoy-hook.sh @@ -0,0 +1,15 @@ +#!/ventoy/busybox/sh + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +if $GREP -q '^"$mount_handler"' /init; then + echo 'use mount_handler1 ...' >> $VTLOG + $SED "/^\"\$mount_handler\"/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/kaos/ventoy-disk.sh" -i /init +elif $GREP -q '^$mount_handler' /init; then + echo 'use mount_handler2 ...' >> $VTLOG + $SED "/^\$mount_handler/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/kaos/ventoy-disk.sh" -i /init +fi + +if [ -f $VTOY_PATH/ventoy_persistent_map ]; then + $SED "1 aexport cow_label=vtoycow" -i /init +fi diff --git a/IMG/cpio/ventoy/hook/kiosk/ventoy-disk.sh b/IMG/cpio/ventoy/hook/kiosk/ventoy-disk.sh new file mode 100644 index 0000000..0e0eb44 --- /dev/null +++ b/IMG/cpio/ventoy/hook/kiosk/ventoy-disk.sh @@ -0,0 +1,73 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +ventoy_os_install_dmsetup_by_unsquashfs() { + vtlog "ventoy_os_install_dmsetup_by_unsquashfs $*" + + vtKerVer=$(uname -r) + vtKoPo=$(ventoy_get_module_postfix) + vtlog "vtKerVer=$vtKerVer vtKoPo=$vtKoPo" + + vtoydm -i -f $VTOY_PATH/ventoy_image_map -d $1 > $VTOY_PATH/iso_file_list + + vtline=$(grep '[-][-] .*kernel.xzm ' $VTOY_PATH/iso_file_list) + sector=$(echo $vtline | awk '{print $(NF-1)}') + length=$(echo $vtline | awk '{print $NF}') + + vtlog "vtline=$vtline sector=$sector length=$length" + + vtoydm -e -f $VTOY_PATH/ventoy_image_map -d $1 -s $sector -l $length -o $VTOY_PATH/kernel.xzm + mkdir -p $VTOY_PATH/sqfs + mount $VTOY_PATH/kernel.xzm $VTOY_PATH/sqfs + + dmModPath="/lib/modules/$vtKerVer/kernel/drivers/md/dm-mod.$vtKoPo" + + if [ -e $VTOY_PATH/sqfs${dmModPath} ]; then + vtlog "success $VTOY_PATH/sqfs${dmModPath}" + insmod $VTOY_PATH/sqfs${dmModPath} + else + vterr "failed $VTOY_PATH/sqfs${dmModPath}" + false + fi + + umount $VTOY_PATH/sqfs + rm -f $VTOY_PATH/kernel.xzm +} + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_os_install_dmsetup_by_unsquashfs $vtdiskname + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/kiosk/ventoy-hook.sh b/IMG/cpio/ventoy/hook/kiosk/ventoy-hook.sh new file mode 100644 index 0000000..31e5b96 --- /dev/null +++ b/IMG/cpio/ventoy/hook/kiosk/ventoy-hook.sh @@ -0,0 +1,22 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED '/^ *search [^(]*$/i\ /ventoy/busybox/sh /ventoy/hook/kiosk/ventoy-disk.sh' -i /init diff --git a/IMG/cpio/ventoy/hook/kwort/disk-hook.sh b/IMG/cpio/ventoy/hook/kwort/disk-hook.sh new file mode 100644 index 0000000..8ee0579 --- /dev/null +++ b/IMG/cpio/ventoy/hook/kwort/disk-hook.sh @@ -0,0 +1,43 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/kwort/ventoy-hook.sh b/IMG/cpio/ventoy/hook/kwort/ventoy-hook.sh new file mode 100644 index 0000000..78f5615 --- /dev/null +++ b/IMG/cpio/ventoy/hook/kwort/ventoy-hook.sh @@ -0,0 +1,22 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "1 a $BUSYBOX_PATH/sh $VTOY_PATH/hook/kwort/disk-hook.sh" -i /etc/rc.d/init/media diff --git a/IMG/cpio/ventoy/hook/lunar/ventoy-hook.sh b/IMG/cpio/ventoy/hook/lunar/ventoy-hook.sh new file mode 100644 index 0000000..31744f6 --- /dev/null +++ b/IMG/cpio/ventoy/hook/lunar/ventoy-hook.sh @@ -0,0 +1,27 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "s#printf\(.*\)\$CMDLINE#printf\1\$CMDLINE root=/dev/ventoy#" -i /lib/dracut-lib.sh + +$BUSYBOX_PATH/rm -f /usr/lib/systemd/system-generators/systemd-fstab-generator /lib/systemd/system-generators/systemd-fstab-generator + +ventoy_set_inotify_script lunar/ventoy-inotifyd-hook.sh +$BUSYBOX_PATH/cp -a $VTOY_PATH/hook/lunar/ventoy-inotifyd-start.sh /lib/dracut/hooks/pre-udev/01-ventoy-inotifyd-start.sh diff --git a/IMG/cpio/ventoy/hook/lunar/ventoy-inotifyd-hook.sh b/IMG/cpio/ventoy/hook/lunar/ventoy-inotifyd-hook.sh new file mode 100644 index 0000000..2ddc120 --- /dev/null +++ b/IMG/cpio/ventoy/hook/lunar/ventoy-inotifyd-hook.sh @@ -0,0 +1,46 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +if is_inotify_ventoy_part $3; then + + vtlog "##### INOTIFYD: $2/$3 is created (YES) ..." + + vtlog "find ventoy partition ..." + $BUSYBOX_PATH/sh $VTOY_PATH/hook/default/udev_disk_hook.sh $3 noreplace + + blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') + vtDM=$(ventoy_find_dm_id ${blkdev_num}) + + cp -a /dev/$vtDM /dev/ventoy + mount -t iso9660 /dev/ventoy /sysroot + + set_ventoy_hook_finish +else + vtlog "##### INOTIFYD: $2/$3 is created (NO) ..." +fi + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/lunar/ventoy-inotifyd-start.sh b/IMG/cpio/ventoy/hook/lunar/ventoy-inotifyd-start.sh new file mode 100644 index 0000000..6be8155 --- /dev/null +++ b/IMG/cpio/ventoy/hook/lunar/ventoy-inotifyd-start.sh @@ -0,0 +1,31 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtHook=$($CAT $VTOY_PATH/inotifyd-hook-script.txt) + +vtdisk=$(get_ventoy_disk_name) +if [ "$vtdisk" = "unknown" ]; then + vtlog "... start inotifyd listen $vtHook ..." + $BUSYBOX_PATH/nohup $VTOY_PATH/tool/inotifyd $vtHook /dev:n 2>&- & +else + vtlog "... $vtdisk already exist ..." + $BUSYBOX_PATH/sh $vtHook n /dev "${vtdisk#/dev/}2" +fi diff --git a/IMG/cpio/ventoy/hook/mageia/ventoy-hook.sh b/IMG/cpio/ventoy/hook/mageia/ventoy-hook.sh new file mode 100644 index 0000000..05c6c41 --- /dev/null +++ b/IMG/cpio/ventoy/hook/mageia/ventoy-hook.sh @@ -0,0 +1,29 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +#ventoy_systemd_udevd_work_around +#ventoy_add_udev_rule "$VTOY_PATH/hook/mageia/udev_disk_hook.sh %k noreplace" + +ventoy_set_inotify_script mageia/ventoy-inotifyd-hook.sh +$BUSYBOX_PATH/cp -a $VTOY_PATH/hook/mageia/ventoy-inotifyd-start.sh /lib/dracut/hooks/pre-udev/99-ventoy-inotifyd-start.sh + + + diff --git a/IMG/cpio/ventoy/hook/mageia/ventoy-inotifyd-hook.sh b/IMG/cpio/ventoy/hook/mageia/ventoy-inotifyd-hook.sh new file mode 100644 index 0000000..61e50ef --- /dev/null +++ b/IMG/cpio/ventoy/hook/mageia/ventoy-inotifyd-hook.sh @@ -0,0 +1,70 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +if is_inotify_ventoy_part $3; then + vtlog "##### INOTIFYD: $2/$3 is created (YES) ..." + + vtlog "find ventoy partition ..." + $BUSYBOX_PATH/sh $VTOY_PATH/hook/default/udev_disk_hook.sh $3 noreplace + + blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') + vtDM=$(ventoy_find_dm_id ${blkdev_num}) + vtLABEL=$($BUSYBOX_PATH/blkid /dev/$vtDM | $AWK '{print $2}' | $SED 's/.*"\(.*\)".*/\1/') + + vtlog "blkdev_num=$blkdev_num vtDM=$vtDM label $vtLABEL ..." + + if [ -n "$vtLABEL" ]; then + $BUSYBOX_PATH/mkdir -p /dev/disk/by-label/ + ln -s /dev/$vtDM /dev/disk/by-label/$vtLABEL + fi + + # + # cheatcode for mageia + # + # From mageia/soft/drakx/mdk-stage1 source code, we see that the stage1 binary will search + # /tmp/syslog file to determin whether there is a DAC960 cdrom in the system. + # So we insert some string to /tmp/syslog file to cheat the stage1 program. + # + $BUSYBOX_PATH/mkdir -p /dev/rd + ventoy_copy_device_mapper "/dev/rd/ventoy" + echo 'ventoy cheatcode /dev/rd/ventoy: model' >> /tmp/syslog + + if [ -e /sbin/mgalive-root ]; then + vtlog "set mgalive-root ..." + + $BUSYBOX_PATH/cp -a $BUSYBOX_PATH/blkid /sbin/blkid + $BUSYBOX_PATH/mkdir -p /dev/mapper + ln -s /dev/$vtDM /dev/mapper/ventoy + /sbin/mgalive-root /dev/$vtDM + fi + + set_ventoy_hook_finish +else + vtlog "##### INOTIFYD: $2/$3 is created (NO) ..." +fi + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/mageia/ventoy-inotifyd-start.sh b/IMG/cpio/ventoy/hook/mageia/ventoy-inotifyd-start.sh new file mode 100644 index 0000000..6be8155 --- /dev/null +++ b/IMG/cpio/ventoy/hook/mageia/ventoy-inotifyd-start.sh @@ -0,0 +1,31 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtHook=$($CAT $VTOY_PATH/inotifyd-hook-script.txt) + +vtdisk=$(get_ventoy_disk_name) +if [ "$vtdisk" = "unknown" ]; then + vtlog "... start inotifyd listen $vtHook ..." + $BUSYBOX_PATH/nohup $VTOY_PATH/tool/inotifyd $vtHook /dev:n 2>&- & +else + vtlog "... $vtdisk already exist ..." + $BUSYBOX_PATH/sh $vtHook n /dev "${vtdisk#/dev/}2" +fi diff --git a/IMG/cpio/ventoy/hook/manjaro/ventoy-disk.sh b/IMG/cpio/ventoy/hook/manjaro/ventoy-disk.sh new file mode 100644 index 0000000..d23fe49 --- /dev/null +++ b/IMG/cpio/ventoy/hook/manjaro/ventoy-disk.sh @@ -0,0 +1,75 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "######### $0 $* ############" + +if is_ventoy_hook_finished; then + exit 0 +fi + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) +vtlog "blkdev_num=$blkdev_num vtDM=$vtDM ..." + +while [ -n "Y" ]; do + if [ -b /dev/$vtDM ]; then + break + else + sleep 0.3 + fi +done + +if [ -n "$1" ]; then + vtlog "ln -s /dev/$vtDM $1" + + if [ -e "$1" ]; then + vtlog "$1 already exist" + else + ln -s /dev/$vtDM "$1" + fi +else + vtLABEL=$($BUSYBOX_PATH/blkid /dev/$vtDM | $SED 's/.*LABEL="\([^"]*\)".*/\1/') + vtlog "vtLABEL is $vtLABEL" + + if [ -z "$vtLABEL" ]; then + vtLABEL=$($SED "s/.*label=\([^ ]*\)/\1/" /proc/cmdline) + vtlog "vtLABEL is $vtLABEL from cmdline" + fi + + if [ -e "/dev/disk/by-label/$vtLABEL" ]; then + vtlog "/dev/disk/by-label/$vtLABEL already exist" + else + ln -s /dev/$vtDM "/dev/disk/by-label/$vtLABEL" + fi +fi + +# OK finish +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/manjaro/ventoy-hook.sh b/IMG/cpio/ventoy/hook/manjaro/ventoy-hook.sh new file mode 100644 index 0000000..f5cdcf5 --- /dev/null +++ b/IMG/cpio/ventoy/hook/manjaro/ventoy-hook.sh @@ -0,0 +1,54 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +# some distro initramfs doesn't contain device-mapper udev rules file +DISTRO_UDEV_DIR=$(ventoy_get_udev_conf_dir) +if [ -s "$DISTRO_UDEV_DIR/13-dm-disk.rules" ]; then + echo 'dm-disk rule exist' >> $VTLOG +else + echo 'Copy dm-disk rule file' >> $VTLOG + $CAT $VTOY_PATH/hook/default/13-dm-disk.rules > "$DISTRO_UDEV_DIR/13-dm-disk.rules" +fi + +if $GREP -q '^"$mount_handler"' /init; then + echo 'use mount_handler ...' >> $VTLOG + + vthookfile=/hooks/archiso + + if [ -e /hooks/miso ]; then + vthookfile=/hooks/miso + $SED "/^\"\$mount_handler\"/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/manjaro/ventoy-disk.sh \"\$misodevice\"" -i /init + else + $SED "/^\"\$mount_handler\"/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/manjaro/ventoy-disk.sh \"\$archisodevice\"" -i /init + fi + + if [ -f $vthookfile ]; then + $SED '/while ! poll_device "${dev}"/a\ if /ventoy/busybox/sh /ventoy/hook/manjaro/ventoy-timeout.sh ${dev}; then break; fi' -i $vthookfile + fi +elif $GREP -q '^mount_setup$' init; then + echo "Here use notify ..." >> $VTLOG + + ventoy_set_inotify_script manjaro/ventoy-inotifyd-hook.sh + $SED "/^mount_setup$/a\\$BUSYBOX_PATH/sh $VTOY_PATH/hook/default/ventoy-inotifyd-start.sh" -i /init +else + ventoy_systemd_udevd_work_around + ventoy_add_udev_rule "$VTOY_PATH/hook/default/udev_disk_hook.sh %k" +fi diff --git a/IMG/cpio/ventoy/hook/manjaro/ventoy-inotifyd-hook.sh b/IMG/cpio/ventoy/hook/manjaro/ventoy-inotifyd-hook.sh new file mode 100644 index 0000000..5f2d45c --- /dev/null +++ b/IMG/cpio/ventoy/hook/manjaro/ventoy-inotifyd-hook.sh @@ -0,0 +1,47 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +if is_inotify_ventoy_part $3; then + vtlog "##### INOTIFYD: $2/$3 is created (YES) ..." + vtlog "find ventoy partition $3 ..." + $BUSYBOX_PATH/sh $VTOY_PATH/hook/default/udev_disk_hook.sh "$3" + + blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') + vtDM=$(ventoy_find_dm_id ${blkdev_num}) + vtLABEL=$($BUSYBOX_PATH/blkid /dev/$vtDM | $AWK '{print $2}' | $SED 's/.*"\(.*\)".*/\1/') + + vtlog "blkdev_num=$blkdev_num vtDM=$vtDM label $vtLABEL ..." + + if ! [ -d /dev/disk/by-label ]; then + mkdir -p /dev/disk/by-label + fi + $BUSYBOX_PATH/cp -a /dev/$vtDM /dev/disk/by-label/$vtLABEL +else + vtlog "##### INOTIFYD: $2/$3 is created (NO) ..." +fi + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/nixos/udev_disk_hook.sh b/IMG/cpio/ventoy/hook/nixos/udev_disk_hook.sh new file mode 100644 index 0000000..633f29e --- /dev/null +++ b/IMG/cpio/ventoy/hook/nixos/udev_disk_hook.sh @@ -0,0 +1,30 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished || not_ventoy_disk "${1:0:-1}"; then + exit 0 +fi + +ventoy_udev_disk_common_hook $* + +# OK finish +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/nixos/ventoy-hook.sh b/IMG/cpio/ventoy/hook/nixos/ventoy-hook.sh new file mode 100644 index 0000000..7b01c13 --- /dev/null +++ b/IMG/cpio/ventoy/hook/nixos/ventoy-hook.sh @@ -0,0 +1,25 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +vtRuleFile=$($FIND / -name '*.rules' -type f | $GREP udev | $HEAD -n1) + +ventoy_add_udev_rule_with_path "$VTOY_PATH/hook/default/udev_disk_hook.sh %k noreplace" "${vtRuleFile%/*}/99-ventoy.rules" + diff --git a/IMG/cpio/ventoy/hook/nutyx/ventoy-disk.sh b/IMG/cpio/ventoy/hook/nutyx/ventoy-disk.sh new file mode 100644 index 0000000..44c5038 --- /dev/null +++ b/IMG/cpio/ventoy/hook/nutyx/ventoy-disk.sh @@ -0,0 +1,50 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +if is_ventoy_hook_finished; then + exit 0 +fi + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" + +blkdev_num=$(dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) + +vtlog "link /dev/$vtDM $VTOY_DM_PATH" +ln -s /dev/$vtDM $VTOY_DM_PATH + +set_ventoy_hook_finish + +PATH=$VTPATH_OLD + diff --git a/IMG/cpio/ventoy/hook/nutyx/ventoy-hook.sh b/IMG/cpio/ventoy/hook/nutyx/ventoy-hook.sh new file mode 100644 index 0000000..17bf538 --- /dev/null +++ b/IMG/cpio/ventoy/hook/nutyx/ventoy-hook.sh @@ -0,0 +1,22 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/find_media$/i $BUSYBOX_PATH/sh $VTOY_PATH/hook/nutyx/ventoy-disk.sh" -i /init diff --git a/IMG/cpio/ventoy/hook/openEuler/ventoy-autoexp.sh b/IMG/cpio/ventoy/hook/openEuler/ventoy-autoexp.sh new file mode 100644 index 0000000..661d436 --- /dev/null +++ b/IMG/cpio/ventoy/hook/openEuler/ventoy-autoexp.sh @@ -0,0 +1,24 @@ +#!/bin/sh +#************************************************************************************ +# Copyright (c) 2022, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +if [ -f /run/install/ks.cfg ]; then + sh /ventoy/hook/default/auto_install_varexp.sh /run/install/ks.cfg +fi + +exit 0 diff --git a/IMG/cpio/ventoy/hook/openEuler/ventoy-hook.sh b/IMG/cpio/ventoy/hook/openEuler/ventoy-hook.sh new file mode 100644 index 0000000..40d67d5 --- /dev/null +++ b/IMG/cpio/ventoy/hook/openEuler/ventoy-hook.sh @@ -0,0 +1,113 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +if [ -f $VTOY_PATH/autoinstall ]; then + VTKS="inst.ks=file:$VTOY_PATH/autoinstall" +else + for vtParam in $($CAT /proc/cmdline); do + if echo $vtParam | $GREP -q 'inst.ks=hd:LABEL='; then + vtRawKsFull="$vtParam" + vtRawKs=$(echo $vtParam | $AWK -F: '{print $NF}') + VTKS="inst.ks=hd:/dev/ventoy:$vtRawKs" + break + fi + + if echo $vtParam | $GREP -q '^ks=.*:/'; then + vtRawKsFull="$vtParam" + vtRawKs=$(echo $vtParam | $AWK -F: '{print $NF}') + VTKS="ks=hd:/dev/ventoy:$vtRawKs" + break + fi + + if echo $vtParam | $GREP -q '^inst.ks=.*:/'; then + vtRawKsFull="$vtParam" + vtRawKs=$(echo $vtParam | $AWK -F: '{print $NF}') + VTKS="inst.ks=hd:/dev/ventoy:$vtRawKs" + break + fi + done +fi + +if [ -f $VTOY_PATH/ventoy_persistent_map ]; then + VTOVERLAY="rd.live.overlay=/dev/dm-1:/vtoyoverlayfs/overlayfs" + + if [ -e /sbin/dmsquash-live-root ]; then + echo "patch /sbin/dmsquash-live-root for persistent ..." >> $VTLOG + $SED "/mount.*devspec.*\/run\/initramfs\/overlayfs/a . /ventoy/hook/openEuler/ventoy-overlay.sh" -i /sbin/dmsquash-live-root + fi + + #close selinux + $BUSYBOX_PATH/mkdir -p $VTOY_PATH/selinuxfs + if $BUSYBOX_PATH/mount -t selinuxfs selinuxfs $VTOY_PATH/selinuxfs; then + echo 1 > $VTOY_PATH/selinuxfs/disable + $BUSYBOX_PATH/umount $VTOY_PATH/selinuxfs + fi + $BUSYBOX_PATH/rm -rf $VTOY_PATH/selinuxfs +fi + +echo "VTKS=$VTKS VTOVERLAY=$VTOVERLAY" >> $VTLOG + +if [ -n "$vtRawKs" ]; then + if echo $vtRawKsFull | $EGREP -q "=http|=https|=ftp|=nfs|=hmc"; then + echo "vtRawKsFull=$vtRawKsFull no patch needed." >> $VTLOG + vtRawKs="" + VTKS="" + else + echo "$vtRawKs" > $VTOY_PATH/ventoy_ks_rootpath + fi +fi + +if ls $VTOY_PATH | $GREP -q 'ventoy_dud[0-9]'; then + for vtDud in $(ls $VTOY_PATH/ventoy_dud*); do + vtInstDD="$vtInstDD inst.dd=file:$vtDud" + done +fi +echo "vtInstDD=$vtInstDD" >> $VTLOG + +$SED "s#printf\(.*\)\$CMDLINE#printf\1\$CMDLINE inst.stage2=hd:/dev/ventoy $VTKS $VTOVERLAY $vtInstDD#" -i /lib/dracut-lib.sh + +ventoy_set_inotify_script openEuler/ventoy-inotifyd-hook.sh + +#Fedora +if $BUSYBOX_PATH/which dmsquash-live-root > /dev/null; then + vtPriority=99 +else + vtPriority=01 +fi + +$BUSYBOX_PATH/cp -a $VTOY_PATH/hook/openEuler/ventoy-inotifyd-start.sh /lib/dracut/hooks/pre-udev/${vtPriority}-ventoy-inotifyd-start.sh +$BUSYBOX_PATH/cp -a $VTOY_PATH/hook/openEuler/ventoy-timeout.sh /lib/dracut/hooks/initqueue/timeout/${vtPriority}-ventoy-timeout.sh +$BUSYBOX_PATH/cp -a $VTOY_PATH/hook/openEuler/ventoy-repo.sh /lib/dracut/hooks/pre-pivot/99-ventoy-repo.sh + +if [ -f /sbin/dmsquash-live-root ]; then + echo "patch /sbin/dmsquash-live-root ..." >> $VTLOG + $SED "1 a $BUSYBOX_PATH/sh $VTOY_PATH/hook/openEuler/ventoy-make-link.sh" -i /sbin/dmsquash-live-root +fi + +# suppress write protected mount warning +if [ -f /usr/sbin/anaconda-diskroot ]; then + $SED 's/^mount $dev $repodir/mount -oro $dev $repodir/' -i /usr/sbin/anaconda-diskroot +fi + + +if [ -f $VTOY_PATH/autoinstall ]; then + cp -a $VTOY_PATH/hook/openEuler/ventoy-autoexp.sh /lib/dracut/hooks/pre-mount/99-ventoy-autoexp.sh +fi diff --git a/IMG/cpio/ventoy/hook/openEuler/ventoy-inotifyd-hook.sh b/IMG/cpio/ventoy/hook/openEuler/ventoy-inotifyd-hook.sh new file mode 100644 index 0000000..afbaec7 --- /dev/null +++ b/IMG/cpio/ventoy/hook/openEuler/ventoy-inotifyd-hook.sh @@ -0,0 +1,65 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +if is_inotify_ventoy_part $3; then + + vtlog "##### INOTIFYD: $2/$3 is created (YES) ..." + + vtlog "find ventoy partition ..." + + #vtReplaceOpt=noreplace + + $BUSYBOX_PATH/sh $VTOY_PATH/hook/default/udev_disk_hook.sh $3 + + blkdev_num_mknod=$($VTOY_PATH/tool/dmsetup ls | $GREP ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') + $BUSYBOX_PATH/mknod -m 660 /dev/ventoy b $blkdev_num_mknod + $BUSYBOX_PATH/modprobe isofs >/dev/null 2>&1 + vtlog "mknod /dev/ventoy $blkdev_num_mknod" + + if [ -f $VTOY_PATH/ventoy_ks_rootpath ]; then + vt_ks_rootpath=$(cat $VTOY_PATH/ventoy_ks_rootpath) + vtlog "ks rootpath <$vt_ks_rootpath>" + if [ -e /sbin/fetch-kickstart-disk ]; then + vtlog "fetch-kickstart-disk ..." + /sbin/fetch-kickstart-disk /dev/ventoy "$vt_ks_rootpath" + fi + fi + + if [ -e /sbin/anaconda-diskroot ]; then + vtlog "set anaconda-diskroot ..." + + #busybox cp doesn't support -t option (issue 1900) + /bin/cp -a /bin/cp $BUSYBOX_PATH/cp + /sbin/anaconda-diskroot /dev/ventoy + fi + + set_ventoy_hook_finish +else + vtlog "##### INOTIFYD: $2/$3 is created (NO) ..." +fi + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/openEuler/ventoy-inotifyd-start.sh b/IMG/cpio/ventoy/hook/openEuler/ventoy-inotifyd-start.sh new file mode 100644 index 0000000..6be8155 --- /dev/null +++ b/IMG/cpio/ventoy/hook/openEuler/ventoy-inotifyd-start.sh @@ -0,0 +1,31 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtHook=$($CAT $VTOY_PATH/inotifyd-hook-script.txt) + +vtdisk=$(get_ventoy_disk_name) +if [ "$vtdisk" = "unknown" ]; then + vtlog "... start inotifyd listen $vtHook ..." + $BUSYBOX_PATH/nohup $VTOY_PATH/tool/inotifyd $vtHook /dev:n 2>&- & +else + vtlog "... $vtdisk already exist ..." + $BUSYBOX_PATH/sh $vtHook n /dev "${vtdisk#/dev/}2" +fi diff --git a/IMG/cpio/ventoy/hook/openEuler/ventoy-make-link.sh b/IMG/cpio/ventoy/hook/openEuler/ventoy-make-link.sh new file mode 100644 index 0000000..a692336 --- /dev/null +++ b/IMG/cpio/ventoy/hook/openEuler/ventoy-make-link.sh @@ -0,0 +1,42 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if [ ! -e /dev/dm-0 ]; then + exit 0 +fi + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) + +if ! [ -e /dev/mapper/ventoy ]; then + vtlog "link /dev/$vtDM to /dev/mapper/ventoy" + ln -s /dev/$vtDM /dev/mapper/ventoy +fi + +VTLABEL=$($BUSYBOX_PATH/blkid /dev/$vtDM | $SED 's/.*LABEL="\([^"]*\)".*/\1/') +vtlog "VTLABEL=$VTLABEL" + +if [ -n "$VTLABEL" ]; then + if ! [ -e "/dev/disk/by-label/$VTLABEL" ]; then + vtlog "link /dev/$vtDM to /dev/disk/by-label/$VTLABEL" + ln -s /dev/$vtDM "/dev/disk/by-label/$VTLABEL" + fi +fi diff --git a/IMG/cpio/ventoy/hook/openEuler/ventoy-overlay.sh b/IMG/cpio/ventoy/hook/openEuler/ventoy-overlay.sh new file mode 100644 index 0000000..d8fe079 --- /dev/null +++ b/IMG/cpio/ventoy/hook/openEuler/ventoy-overlay.sh @@ -0,0 +1,21 @@ +#!/bin/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +[ -d /run/initramfs/overlayfs$pathspec ] || mkdir -p /run/initramfs/overlayfs$pathspec +[ -d /run/initramfs/overlayfs$pathspec/../ovlwork ] || mkdir -p /run/initramfs/overlayfs$pathspec/../ovlwork diff --git a/IMG/cpio/ventoy/hook/openEuler/ventoy-repo.sh b/IMG/cpio/ventoy/hook/openEuler/ventoy-repo.sh new file mode 100644 index 0000000..af85beb --- /dev/null +++ b/IMG/cpio/ventoy/hook/openEuler/ventoy-repo.sh @@ -0,0 +1,29 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "##### $0 $* ..." + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +repodev=$(ls $VTOY_PATH/dev_backup*) +echo "inst.repo=hd:/dev/${repodev#*dev_backup_}" >> /sysroot/etc/cmdline + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/openEuler/ventoy-timeout.sh b/IMG/cpio/ventoy/hook/openEuler/ventoy-timeout.sh new file mode 100644 index 0000000..cfd339f --- /dev/null +++ b/IMG/cpio/ventoy/hook/openEuler/ventoy-timeout.sh @@ -0,0 +1,48 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "##### $0 $* ..." + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +if [ ! -e /dev/ventoy ]; then + blkdev_num_mknod=$(dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') + mknod -m 660 /dev/ventoy b $blkdev_num_mknod +fi + +if [ -f $VTOY_PATH/ventoy_ks_rootpath ]; then + vt_ks_rootpath=$(cat $VTOY_PATH/ventoy_ks_rootpath) + vtlog "ks rootpath <$vt_ks_rootpath>" + if [ -e /sbin/fetch-kickstart-disk ]; then + vtlog "fetch-kickstart-disk ..." + /sbin/fetch-kickstart-disk /dev/ventoy "$vt_ks_rootpath" + fi +fi + +if [ -e /sbin/anaconda-diskroot ]; then + vtlog "set anaconda-diskroot /dev/ventoy ..." + + #busybox cp doesn't support -t option (issue 1900) + /bin/cp -a /bin/cp $BUSYBOX_PATH/cp + /sbin/anaconda-diskroot /dev/ventoy +fi + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/parabola/ventoy-disk.sh b/IMG/cpio/ventoy/hook/parabola/ventoy-disk.sh new file mode 100644 index 0000000..356c77f --- /dev/null +++ b/IMG/cpio/ventoy/hook/parabola/ventoy-disk.sh @@ -0,0 +1,48 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "######### $0 $* ############" + +if is_ventoy_hook_finished; then + exit 0 +fi + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +if [ -n "$1" ]; then + blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') + vtDM=$(ventoy_find_dm_id ${blkdev_num}) + + vtlog "ln -s /dev/$vtDM $1" + ln -s /dev/$vtDM "$1" +fi + +# OK finish +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/parabola/ventoy-hook.sh b/IMG/cpio/ventoy/hook/parabola/ventoy-hook.sh new file mode 100644 index 0000000..b8b3a5d --- /dev/null +++ b/IMG/cpio/ventoy/hook/parabola/ventoy-hook.sh @@ -0,0 +1,44 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +if $GREP -q '^"$mount_handler"' /init; then + echo 'use mount_handler ...' >> $VTLOG + $SED "/^\"\$mount_handler\"/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/parabola/ventoy-disk.sh \"\$parabolaisodevice\"" -i /init + + if [ -f /hooks/parabolaiso ]; then + $SED '/while ! poll_device "${dev}"/a\ if /ventoy/busybox/sh /ventoy/hook/parabola/ventoy-timeout.sh ${dev}; then break; fi' -i /hooks/parabolaiso + fi + +else + # some archlinux initramfs doesn't contain device-mapper udev rules file + ARCH_UDEV_DIR=$(ventoy_get_udev_conf_dir) + if [ -s "$ARCH_UDEV_DIR/13-dm-disk.rules" ]; then + echo 'dm-disk rule exist' >> $VTLOG + else + echo 'Copy dm-disk rule file' >> $VTLOG + $CAT $VTOY_PATH/hook/default/13-dm-disk.rules > "$ARCH_UDEV_DIR/13-dm-disk.rules" + fi + + # use default proc + ventoy_systemd_udevd_work_around + + ventoy_add_udev_rule "$VTOY_PATH/hook/default/udev_disk_hook.sh %k" +fi diff --git a/IMG/cpio/ventoy/hook/parabola/ventoy-timeout.sh b/IMG/cpio/ventoy/hook/parabola/ventoy-timeout.sh new file mode 100644 index 0000000..fec9cc0 --- /dev/null +++ b/IMG/cpio/ventoy/hook/parabola/ventoy-timeout.sh @@ -0,0 +1,36 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "######### $0 $* ############" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) + +if [ -b /dev/$vtDM ]; then + vtlog "ln -s /dev/$vtDM $1" + ln -s /dev/$vtDM "$1" + exit 0 +else + vtlog "Device-mapper not found" + exit 1 +fi + + diff --git a/IMG/cpio/ventoy/hook/pclos/disk_hook.sh b/IMG/cpio/ventoy/hook/pclos/disk_hook.sh new file mode 100644 index 0000000..0969dad --- /dev/null +++ b/IMG/cpio/ventoy/hook/pclos/disk_hook.sh @@ -0,0 +1,77 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +ventoy_os_install_device_mapper_by_unsquashfs() { + vtlog "ventoy_os_install_device_mapper_by_unsquashfs $*" + + vtKoExt=$(ventoy_get_module_postfix) + vtlog "vtKoExt=$vtKoExt" + + vtoydm -i -f $VTOY_PATH/ventoy_image_map -d $1 > $VTOY_PATH/iso_file_list + + vtline=$(grep '[-][-] livecd.sqfs ' $VTOY_PATH/iso_file_list) + sector=$(echo $vtline | awk '{print $(NF-1)}') + length=$(echo $vtline | awk '{print $NF}') + + vtoydm -E -f $VTOY_PATH/ventoy_image_map -d $1 -s $sector -l $length -o $VTOY_PATH/fsdisk + + dmModPath="/lib/modules/$2/kernel/drivers/md/dm-mod.$vtKoExt" + echo $dmModPath > $VTOY_PATH/fsextract + vtoy_unsquashfs -d $VTOY_PATH/sqfs -n -q -e $VTOY_PATH/fsextract $VTOY_PATH/fsdisk + + if [ -e $VTOY_PATH/sqfs${dmModPath} ]; then + vtlog "success $VTOY_PATH/sqfs${dmModPath}" + insmod $VTOY_PATH/sqfs${dmModPath} + else + false + fi +} + + +ventoy_os_install_device_mapper() { + vtlog "ventoy_os_install_device_mapper" + + if grep -q 'device-mapper' /proc/devices; then + vtlog "device-mapper module already loaded" + return; + fi + + vtKerVer=$(uname -r) + if ventoy_os_install_device_mapper_by_unsquashfs $1 $vtKerVer; then + vtlog "unsquashfs success" + else + vterr "unsquashfs failed" + fi +} + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +ventoy_os_install_device_mapper $vtdiskname + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/pclos/ventoy-hook.sh b/IMG/cpio/ventoy/hook/pclos/ventoy-hook.sh new file mode 100644 index 0000000..d082453 --- /dev/null +++ b/IMG/cpio/ventoy/hook/pclos/ventoy-hook.sh @@ -0,0 +1,57 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +# Step 1: dd initrd file to ramdisk +vtRamdiskFile=$($BUSYBOX_PATH/ls /initrd* | $HEAD -n1) +$BUSYBOX_PATH/mknod -m 0666 /ram0 b 1 0 +$BUSYBOX_PATH/dd if=$vtRamdiskFile of=/ram0 status=none +$BUSYBOX_PATH/rm -f $vtRamdiskFile + +# Step 2: mount ramdisk +$BUSYBOX_PATH/mkdir -p /ventoy_rdroot +ventoy_close_printk +$BUSYBOX_PATH/mount /ram0 /ventoy_rdroot +ventoy_restore_printk + +# Step 3: Copy ventoy tool to new root directory. +# Here we make a tmpfs mount to avoid ramdisk out of space (additional space is for log). +vtSize=$($BUSYBOX_PATH/du -m -s $VTOY_PATH | $BUSYBOX_PATH/awk '{print $1}') +let vtSize=vtSize+4 + +$BUSYBOX_PATH/mkdir -p /ventoy_rdroot/ventoy +$BUSYBOX_PATH/mount -t tmpfs -o size=${vtSize}m tmpfs /ventoy_rdroot/ventoy +$BUSYBOX_PATH/cp -a /ventoy/* /ventoy_rdroot/ventoy/ + + +# Step 4: add hook in linuxrc&rc.sysinit script file +vtLine=$($GREP -n "^find_cdrom" /ventoy_rdroot/linuxrc | $GREP -v '(' | $AWK -F: '{print $1}') +$SED "$vtLine aif test -d /ventoy; then $BUSYBOX_PATH/sh $VTOY_PATH/hook/pclos/disk_hook.sh; fi" -i /ventoy_rdroot/linuxrc +$SED "$vtLine aif test -d /initrd/ventoy; then ln -s /initrd/ventoy /ventoy; fi" -i /ventoy_rdroot/linuxrc + + +vtRcInit=$($BUSYBOX_PATH/tail /ventoy_rdroot/linuxrc | $GREP 'exec ' | $AWK '{print $2}') +if [ -e /ventoy_rdroot$vtRcInit ]; then + vtRcInit=/ventoy_rdroot$vtRcInit +else + vtRcInit=/ventoy_rdroot/etc/rc.d/rc.sysinit +fi + +echo 'exec /sbin/init' >> $vtRcInit diff --git a/IMG/cpio/ventoy/hook/phoenixos/disk_hook.sh b/IMG/cpio/ventoy/hook/phoenixos/disk_hook.sh new file mode 100644 index 0000000..56b97b2 --- /dev/null +++ b/IMG/cpio/ventoy/hook/phoenixos/disk_hook.sh @@ -0,0 +1,47 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +for i in 0 1 2 3 4 5 6 7 8 9; do + vtdiskname=$(get_ventoy_disk_name) + if [ "$vtdiskname" = "unknown" ]; then + vtlog "wait for disk ..." + sleep 3 + else + break + fi +done + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +mknod -m 0666 /dev/ventoy b $blkdev_num + +set_ventoy_hook_finish + +PATH=$VTPATH_OLD + + diff --git a/IMG/cpio/ventoy/hook/phoenixos/ventoy-hook.sh b/IMG/cpio/ventoy/hook/phoenixos/ventoy-hook.sh new file mode 100644 index 0000000..0ead131 --- /dev/null +++ b/IMG/cpio/ventoy/hook/phoenixos/ventoy-hook.sh @@ -0,0 +1,24 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$BUSYBOX_PATH/mkdir /dev +$SED "/for device in/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/phoenixos/disk_hook.sh" -i /init +$SED "s#for device in #for device in /dev/ventoy #" -i /init diff --git a/IMG/cpio/ventoy/hook/photon/ventoy-hook.sh b/IMG/cpio/ventoy/hook/photon/ventoy-hook.sh new file mode 100644 index 0000000..9a29807 --- /dev/null +++ b/IMG/cpio/ventoy/hook/photon/ventoy-hook.sh @@ -0,0 +1,34 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED 's#/dev/cdrom#/dev/ventoy#' -i /installer/isoInstaller.py + +ventoy_set_inotify_script photon/ventoy-inotifyd-hook.sh + +[ -d /dev ] || $BUSYBOX_PATH/mkdir /dev +[ -d /sys ] || $BUSYBOX_PATH/mkdir /sys + +$BUSYBOX_PATH/mount -t devtmpfs -o mode=0755,noexec,nosuid,strictatime devtmpfs /dev +$BUSYBOX_PATH/mount -t sysfs sys /sys + +$BUSYBOX_PATH/rm -f /init +$BUSYBOX_PATH/sh $VTOY_PATH/hook/photon/ventoy-inotifyd-start.sh + diff --git a/IMG/cpio/ventoy/hook/photon/ventoy-inotifyd-hook.sh b/IMG/cpio/ventoy/hook/photon/ventoy-inotifyd-hook.sh new file mode 100644 index 0000000..424d84e --- /dev/null +++ b/IMG/cpio/ventoy/hook/photon/ventoy-inotifyd-hook.sh @@ -0,0 +1,43 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +if is_inotify_ventoy_part $3; then + + vtlog "##### INOTIFYD: $2/$3 is created (YES) ..." + + vtlog "find ventoy partition ..." + $BUSYBOX_PATH/sh $VTOY_PATH/hook/default/udev_disk_hook.sh $3 noreplace + + blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') + mknod -m 0660 /dev/ventoy b $blkdev_num + + set_ventoy_hook_finish +else + vtlog "##### INOTIFYD: $2/$3 is created (NO) ..." +fi + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/photon/ventoy-inotifyd-start.sh b/IMG/cpio/ventoy/hook/photon/ventoy-inotifyd-start.sh new file mode 100644 index 0000000..6be8155 --- /dev/null +++ b/IMG/cpio/ventoy/hook/photon/ventoy-inotifyd-start.sh @@ -0,0 +1,31 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtHook=$($CAT $VTOY_PATH/inotifyd-hook-script.txt) + +vtdisk=$(get_ventoy_disk_name) +if [ "$vtdisk" = "unknown" ]; then + vtlog "... start inotifyd listen $vtHook ..." + $BUSYBOX_PATH/nohup $VTOY_PATH/tool/inotifyd $vtHook /dev:n 2>&- & +else + vtlog "... $vtdisk already exist ..." + $BUSYBOX_PATH/sh $vtHook n /dev "${vtdisk#/dev/}2" +fi diff --git a/IMG/cpio/ventoy/hook/pisilinux/ventoy-disk.sh b/IMG/cpio/ventoy/hook/pisilinux/ventoy-disk.sh new file mode 100644 index 0000000..891cd90 --- /dev/null +++ b/IMG/cpio/ventoy/hook/pisilinux/ventoy-disk.sh @@ -0,0 +1,47 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$(dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +mknod -m 660 /dev/ventoy b $blkdev_num + + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/pisilinux/ventoy-hook.sh b/IMG/cpio/ventoy/hook/pisilinux/ventoy-hook.sh new file mode 100644 index 0000000..9fc1fc5 --- /dev/null +++ b/IMG/cpio/ventoy/hook/pisilinux/ventoy-hook.sh @@ -0,0 +1,24 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/^\"\$mount_handler\"/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/pisilinux/ventoy-disk.sh" -i /init +$SED "/^\"\$mount_handler\"/i\ export root=/dev/ventoy" -i /init + diff --git a/IMG/cpio/ventoy/hook/ploplinux/disk_hook.sh b/IMG/cpio/ventoy/hook/ploplinux/disk_hook.sh new file mode 100644 index 0000000..60e597d --- /dev/null +++ b/IMG/cpio/ventoy/hook/ploplinux/disk_hook.sh @@ -0,0 +1,41 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +mknod -m 0660 /dev/ventoy b $blkdev_num + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/ploplinux/ventoy-hook.sh b/IMG/cpio/ventoy/hook/ploplinux/ventoy-hook.sh new file mode 100644 index 0000000..8eaef67 --- /dev/null +++ b/IMG/cpio/ventoy/hook/ploplinux/ventoy-hook.sh @@ -0,0 +1,24 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/export *CMDLINE/i CMDLINE=\"root=/dev/ventoy \${CMDLINE}\"" -i /etc/rc.d/init.d/rc.S +$SED "1a $BUSYBOX_PATH/sh $VTOY_PATH/hook/ploplinux/disk_hook.sh" -i /etc/rc.d/init.d/rootmount + diff --git a/IMG/cpio/ventoy/hook/pmagic/disk-hook.sh b/IMG/cpio/ventoy/hook/pmagic/disk-hook.sh new file mode 100644 index 0000000..3e46fbf --- /dev/null +++ b/IMG/cpio/ventoy/hook/pmagic/disk-hook.sh @@ -0,0 +1,47 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +mknod -m 0666 /dev/ventoy b $blkdev_num + + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/pmagic/udev_disk_hook.sh b/IMG/cpio/ventoy/hook/pmagic/udev_disk_hook.sh new file mode 100644 index 0000000..93e0548 --- /dev/null +++ b/IMG/cpio/ventoy/hook/pmagic/udev_disk_hook.sh @@ -0,0 +1,32 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished || not_ventoy_disk "${1:0:-1}"; then + exit 0 +fi + +ventoy_udev_disk_common_hook $* "noreplace" +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +mknod -m 0666 /dev/ventoy b $blkdev_num + +# OK finish +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/pmagic/ventoy-hook.sh b/IMG/cpio/ventoy/hook/pmagic/ventoy-hook.sh new file mode 100644 index 0000000..d476887 --- /dev/null +++ b/IMG/cpio/ventoy/hook/pmagic/ventoy-hook.sh @@ -0,0 +1,31 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +if $GREP -q 'Searching *for *PMAGIC' /init; then + echo "Find Searching PMAGIC" >> $VTLOG + $SED "/Searching *for *PMAGIC/a\ root=/dev/ventoy" -i /init + $SED "/Searching *for *PMAGIC/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/pmagic/disk-hook.sh" -i /init +else + echo "Use default..." >> $VTLOG + $SED "s#^root=.*cmdline.*#root=/dev/ventoy#g'" -i /init + ventoy_systemd_udevd_work_around + ventoy_add_udev_rule "$VTOY_PATH/hook/pmagic/udev_disk_hook.sh %k" +fi diff --git a/IMG/cpio/ventoy/hook/primeos/ventoy-disk.sh b/IMG/cpio/ventoy/hook/primeos/ventoy-disk.sh new file mode 100644 index 0000000..f2c55c8 --- /dev/null +++ b/IMG/cpio/ventoy/hook/primeos/ventoy-disk.sh @@ -0,0 +1,41 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) +echo -n "/dev/$vtDM" > /ventoy/rootdev + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/primeos/ventoy-hook.sh b/IMG/cpio/ventoy/hook/primeos/ventoy-hook.sh new file mode 100644 index 0000000..8cf543d --- /dev/null +++ b/IMG/cpio/ventoy/hook/primeos/ventoy-hook.sh @@ -0,0 +1,32 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$BUSYBOX_PATH/mkdir /dev + +if $GREP -q 'Detecting *PrimeOS' /init; then + $SED '/Detecting *PrimeOS/a\ ROOT=$(cat /ventoy/rootdev)' -i /init + $SED "/Detecting *PrimeOS/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/primeos/ventoy-disk.sh" -i /init +elif $GREP -q 'Detecting *PRIMEOS' /init; then + $SED '/Detecting *PRIMEOS/a\ ROOT=$(cat /ventoy/rootdev)' -i /init + $SED "/Detecting *PRIMEOS/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/primeos/ventoy-disk.sh" -i /init +else + echo "not detecting found" >> $VTLOG +fi diff --git a/IMG/cpio/ventoy/hook/rancher/disk_hook.sh b/IMG/cpio/ventoy/hook/rancher/disk_hook.sh new file mode 100644 index 0000000..60e597d --- /dev/null +++ b/IMG/cpio/ventoy/hook/rancher/disk_hook.sh @@ -0,0 +1,41 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +mknod -m 0660 /dev/ventoy b $blkdev_num + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/rancher/ventoy-hook.sh b/IMG/cpio/ventoy/hook/rancher/ventoy-hook.sh new file mode 100644 index 0000000..e2f27fa --- /dev/null +++ b/IMG/cpio/ventoy/hook/rancher/ventoy-hook.sh @@ -0,0 +1,21 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + diff --git a/IMG/cpio/ventoy/hook/rhel5/ventoy-hook.sh b/IMG/cpio/ventoy/hook/rhel5/ventoy-hook.sh new file mode 100644 index 0000000..c028991 --- /dev/null +++ b/IMG/cpio/ventoy/hook/rhel5/ventoy-hook.sh @@ -0,0 +1,23 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +#if [ -e $VTOY_PATH/hook/rhel5/loader ]; then +# $BUSYBOX_PATH/cp -a $VTOY_PATH/hook/rhel5/loader /sbin/loader +#fi +#$BUSYBOX_PATH/cp -a $VTOY_PATH/hook/rhel5/ventoy-loader.sh $VTOY_PATH/tool/ diff --git a/IMG/cpio/ventoy/hook/rhel5/ventoy-loader.sh b/IMG/cpio/ventoy/hook/rhel5/ventoy-loader.sh new file mode 100644 index 0000000..3582ed8 --- /dev/null +++ b/IMG/cpio/ventoy/hook/rhel5/ventoy-loader.sh @@ -0,0 +1,70 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +ventoy_os_install_dmsetup() { + vtlog "ventoy_os_install_dmsetup $1" + + vt_usb_disk=$1 + + # dump iso file location + $VTOY_PATH/tool/vtoydm -i -f $VTOY_PATH/ventoy_image_map -d ${vt_usb_disk} > $VTOY_PATH/iso_file_list + + # install dmsetup + LINE=$($GREP 'minstg2.img' $VTOY_PATH/iso_file_list) + if [ $? -eq 0 ]; then + extract_file_from_line "$LINE" ${vt_usb_disk} /tmp/minstg2.img + + mkdir -p /tmp/ramfs/minstg2.img + mount -t squashfs /tmp/minstg2.img /tmp/ramfs/minstg2.img + + $BUSYBOX_PATH/ln -s /tmp/ramfs/minstg2.img/lib64 /lib64 + $BUSYBOX_PATH/ln -s /tmp/ramfs/minstg2.img/usr /usr + fi + + vtlog "dmsetup install finish, now check it..." + + dmsetup_path=$(ventoy_find_bin_path dmsetup) + if [ -z "$dmsetup_path" ]; then + vterr "dmsetup still not found after install" + elif $dmsetup_path info >> $VTLOG 2>&1; then + vtlog "$dmsetup_path work ok" + else + vterr "$dmsetup_path not work" + fi +} + +vtlog "##### $0 $* ########" + +vtdiskname=$(get_ventoy_disk_name) + +dmsetup_path=$(ventoy_find_bin_path dmsetup) +if [ -z "$dmsetup_path" ]; then + ventoy_os_install_dmsetup "$vtdiskname" + ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + + $BUSYBOX_PATH/unlink /lib64 + $BUSYBOX_PATH/unlink /usr + umount /tmp/ramfs/minstg2.img + rm -rf /tmp/ramfs/minstg2.img + rm -f /tmp/minstg2.img +else + ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" +fi diff --git a/IMG/cpio/ventoy/hook/rhel6/anaconda-repo-listen.sh b/IMG/cpio/ventoy/hook/rhel6/anaconda-repo-listen.sh new file mode 100644 index 0000000..5cadb79 --- /dev/null +++ b/IMG/cpio/ventoy/hook/rhel6/anaconda-repo-listen.sh @@ -0,0 +1,20 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +sed -i "s/^enabled.*/enabled=0/g" $2/$3 diff --git a/IMG/cpio/ventoy/hook/rhel6/udev_disk_hook.sh b/IMG/cpio/ventoy/hook/rhel6/udev_disk_hook.sh new file mode 100644 index 0000000..0cad7db --- /dev/null +++ b/IMG/cpio/ventoy/hook/rhel6/udev_disk_hook.sh @@ -0,0 +1,93 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtCheatLoop=loop6 + +ventoy_os_install_dmsetup() { + vtlog "ventoy_os_install_dmsetup $1" + + vt_usb_disk=$1 + + $BUSYBOX_PATH/modprobe dm-mod + $BUSYBOX_PATH/modprobe linear + + # dump iso file location + $VTOY_PATH/tool/vtoydm -i -f $VTOY_PATH/ventoy_image_map -d ${vt_usb_disk} > $VTOY_PATH/iso_file_list + + # install dmsetup + LINE=$($GREP 'device-mapper-[0-9].*\.rpm' $VTOY_PATH/iso_file_list) + if [ $? -eq 0 ]; then + install_rpm_from_line "$LINE" ${vt_usb_disk} + fi + + vtlog "dmsetup install finish, now check it..." + + dmsetup_path=$(ventoy_find_bin_path dmsetup) + if [ -z "$dmsetup_path" ]; then + vterr "dmsetup still not found after install" + elif $dmsetup_path info >> $VTLOG 2>&1; then + vtlog "$dmsetup_path work ok" + else + vterr "$dmsetup_path not work" + fi +} + + +if is_ventoy_hook_finished || not_ventoy_disk "${1:0:-1}"; then + # /dev/vtCheatLoop come first + if [ "$1" = "$vtCheatLoop" ] && [ -b $VTOY_DM_PATH ]; then + ventoy_copy_device_mapper /dev/$vtCheatLoop + fi + exit 0 +fi + +dmsetup_path=$(ventoy_find_bin_path dmsetup) +if [ -z "$dmsetup_path" ]; then + ventoy_os_install_dmsetup "/dev/${1:0:-1}" +fi + + +#some distro add there repo file to /etc/anaconda.repos.d/ which will cause error during installation +#$BUSYBOX_PATH/nohup $VTOY_PATH/tool/inotifyd $VTOY_PATH/hook/rhel6/anaconda-repo-listen.sh /etc/anaconda.repos.d:n & + +ventoy_udev_disk_common_hook $* "noreplace" + +$BUSYBOX_PATH/mount $VTOY_DM_PATH /mnt/ventoy + +#fix Oracle Linux 6.9 install issue +if $GREP -q -i 'Oracle Linux' /mnt/ventoy/.discinfo; then + ln -s /mnt/ventoy /mnt/source +fi + + +# +# We do a trick for rhel6 series here. +# Use /dev/$vtCheatLoop and wapper it as a removable cdrom with bind mount. +# Then the anaconda installer will accept /dev/$vtCheatLoop as the install medium. +# +ventoy_copy_device_mapper /dev/$vtCheatLoop + +$BUSYBOX_PATH/cp -a /sys/devices/virtual/block/$vtCheatLoop /tmp/ >> $VTLOG 2>&1 +echo 19 > /tmp/$vtCheatLoop/capability +$BUSYBOX_PATH/mount --bind /tmp/$vtCheatLoop /sys/block/$vtCheatLoop >> $VTLOG 2>&1 + +# OK finish +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/rhel6/ventoy-hook.sh b/IMG/cpio/ventoy/hook/rhel6/ventoy-hook.sh new file mode 100644 index 0000000..c3c33b6 --- /dev/null +++ b/IMG/cpio/ventoy/hook/rhel6/ventoy-hook.sh @@ -0,0 +1,40 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$BUSYBOX_PATH/mkdir -p /etc/anaconda.repos.d /mnt/ventoy +ventoy_print_yum_repo "ventoy" "file:///mnt/ventoy" > /etc/anaconda.repos.d/ventoy.repo + +ventoy_add_udev_rule "$VTOY_PATH/hook/rhel6/udev_disk_hook.sh %k" + +#loop7 was used by loader +ventoy_add_kernel_udev_rule "loop6" "$VTOY_PATH/hook/rhel6/udev_disk_hook.sh %k" + +if [ -f $VTOY_PATH/autoinstall ]; then + $BUSYBOX_PATH/mv /sbin/loader /sbin/loader_bk + $BUSYBOX_PATH/cp -a $VTOY_PATH/tool/loader /sbin/loader + + RawCmdLine=$($BUSYBOX_PATH/cat /proc/cmdline) + echo -n "/sbin/loader_bk" > "/ventoy/loader_exec_file" + echo -n "--cmdline=$RawCmdLine ks=file:$VTOY_PATH/autoinstall" > "/ventoy/loader_exec_cmdline" + #echo 111 > "/ventoy/loader_debug" + + echo "/bin/sh /ventoy/hook/rhel6/ventoy-varexp.sh" > "/ventoy/loader_hook_cmd" +fi diff --git a/IMG/cpio/ventoy/hook/rhel6/ventoy-varexp.sh b/IMG/cpio/ventoy/hook/rhel6/ventoy-varexp.sh new file mode 100644 index 0000000..99c23a2 --- /dev/null +++ b/IMG/cpio/ventoy/hook/rhel6/ventoy-varexp.sh @@ -0,0 +1,37 @@ +#!/bin/sh +#************************************************************************************ +# Copyright (c) 2022, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +PATH=$PATH:/ventoy/busybox:/ventoy/tool + +if grep -q '\$\$VT_' /ventoy/autoinstall; then + : +else + exit 0 +fi + +if [ -f /sbin/hald ]; then + mv /sbin/hald /sbin/hald_bk + cp -a /ventoy/tool/hald /sbin/hald + + rm -f "/ventoy/loader_exec_cmdline" + echo "/bin/sh /ventoy/hook/default/auto_install_varexp.sh /ventoy/autoinstall" > "/ventoy/loader_hook_cmd" + echo -n "/sbin/hald_bk" > "/ventoy/loader_exec_file" +fi + +exit 0 diff --git a/IMG/cpio/ventoy/hook/rhel7/ventoy-autoexp.sh b/IMG/cpio/ventoy/hook/rhel7/ventoy-autoexp.sh new file mode 100644 index 0000000..661d436 --- /dev/null +++ b/IMG/cpio/ventoy/hook/rhel7/ventoy-autoexp.sh @@ -0,0 +1,24 @@ +#!/bin/sh +#************************************************************************************ +# Copyright (c) 2022, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +if [ -f /run/install/ks.cfg ]; then + sh /ventoy/hook/default/auto_install_varexp.sh /run/install/ks.cfg +fi + +exit 0 diff --git a/IMG/cpio/ventoy/hook/rhel7/ventoy-hook.sh b/IMG/cpio/ventoy/hook/rhel7/ventoy-hook.sh new file mode 100644 index 0000000..613fa76 --- /dev/null +++ b/IMG/cpio/ventoy/hook/rhel7/ventoy-hook.sh @@ -0,0 +1,198 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +#ventoy_systemd_udevd_work_around +#ventoy_add_udev_rule "$VTOY_PATH/hook/default/udev_disk_hook.sh %k noreplace" + +if [ -f $VTOY_PATH/autoinstall ]; then + VTKS="inst.ks=file:$VTOY_PATH/autoinstall" + cp -a $VTOY_PATH/hook/rhel7/ventoy-autoexp.sh /lib/dracut/hooks/pre-mount/99-ventoy-autoexp.sh +else + for vtParam in $($CAT /proc/cmdline); do + if echo $vtParam | $GREP -q 'ks=file:/'; then + continue + fi + + if echo $vtParam | $GREP -q 'inst.ks=hd:LABEL='; then + vtRawKsFull="$vtParam" + vtRawKs=$(echo $vtParam | $AWK -F: '{print $NF}') + VTKS="inst.ks=hd:/dev/ventoy:$vtRawKs" + break + fi + + if echo $vtParam | $GREP -q '^ks=.*:/'; then + vtRawKsFull="$vtParam" + vtRawKs=$(echo $vtParam | $AWK -F: '{print $NF}') + VTKS="ks=hd:/dev/ventoy:$vtRawKs" + break + fi + + if echo $vtParam | $GREP -q '^inst.ks=.*:/'; then + vtRawKsFull="$vtParam" + vtRawKs=$(echo $vtParam | $AWK -F: '{print $NF}') + VTKS="inst.ks=hd:/dev/ventoy:$vtRawKs" + break + fi + done +fi + +if [ -f $VTOY_PATH/ventoy_persistent_map ]; then + VTOVERLAY="rd.live.overlay=/dev/dm-1:/vtoyoverlayfs/overlayfs" + + if [ -e /sbin/dmsquash-live-root ]; then + echo "patch /sbin/dmsquash-live-root for persistent ..." >> $VTLOG + $SED "/mount.*devspec.*\/run\/initramfs\/overlayfs/a . /ventoy/hook/rhel7/ventoy-overlay.sh" -i /sbin/dmsquash-live-root + $SED "s/osmin.img/osmin.imgxxxx/g" -i /sbin/dmsquash-live-root + fi + + #close selinux + $BUSYBOX_PATH/mkdir -p $VTOY_PATH/selinuxfs + if $BUSYBOX_PATH/mount -t selinuxfs selinuxfs $VTOY_PATH/selinuxfs; then + echo 1 > $VTOY_PATH/selinuxfs/disable + $BUSYBOX_PATH/umount $VTOY_PATH/selinuxfs + fi + $BUSYBOX_PATH/rm -rf $VTOY_PATH/selinuxfs +fi + +echo "VTKS=$VTKS VTOVERLAY=$VTOVERLAY" >> $VTLOG + +if [ -n "$vtRawKs" ]; then + if echo $vtRawKsFull | $EGREP -q "=http|=https|=ftp|=nfs|=hmc"; then + echo "vtRawKsFull=$vtRawKsFull no patch needed." >> $VTLOG + vtRawKs="" + VTKS="" + else + echo "$vtRawKs" > $VTOY_PATH/ventoy_ks_rootpath + fi +fi + +if ls $VTOY_PATH | $GREP -q 'ventoy_dud[0-9]'; then + for vtDud in $(ls $VTOY_PATH/ventoy_dud*); do + vtInstDD="$vtInstDD inst.dd=file:$vtDud" + done +fi +echo "vtInstDD=$vtInstDD" >> $VTLOG + + + +vtNeedRepo= +if [ -f /etc/system-release ]; then + if $GREP -q 'RED OS' /etc/system-release; then + vtNeedRepo="yes" + fi +fi + +if $GREP -q 'el[89]' /proc/version; then + vtNeedRepo="yes" +fi + +if $GREP -i -q Fedora /proc/version; then + if $GREP -q 'Server Edition' /etc/os-release; then + vtNeedRepo="yes" + fi +fi + +if $GREP -i -q Fedora /etc/os-release; then + if $GREP -q 'Server Edition' /etc/os-release; then + vtNeedRepo="yes" + fi +fi + +echo "vtNeedRepo=$vtNeedRepo" >> $VTLOG + +if [ "$vtNeedRepo" = "yes" ]; then + $BUSYBOX_PATH/cp -a $VTOY_PATH/hook/rhel7/ventoy-repo.sh /lib/dracut/hooks/pre-pivot/99-ventoy-repo.sh +fi + + +#iso-scan (currently only for Fedora) +if $GREP -q Fedora /etc/os-release; then +if /ventoy/tool/vtoydump -a /ventoy/ventoy_os_param; then + if ventoy_iso_scan_check; then + echo "iso_scan process ..." >> $VTLOG + + vtIsoPath=$(/ventoy/tool/vtoydump -p /ventoy/ventoy_os_param) + VTISO_SCAN="iso-scan/filename=$vtIsoPath" + echo -n $vtIsoPath > /ventoy/vtoy_iso_scan + + $SED "s#printf\(.*\)\$CMDLINE#printf\1\$CMDLINE $VTISO_SCAN $VTKS $VTOVERLAY $vtInstDD#" -i /lib/dracut-lib.sh + if [ "$VTOY_LINUX_REMOUNT" = "01" -a "$vtNeedRepo" != "yes" ]; then + ventoy_rw_iso_scan + fi + + exit 0 + fi +fi +fi + + +echo "common process ..." >> $VTLOG +if $GREP -q 'root=live' /proc/cmdline; then + $SED "s#printf\(.*\)\$CMDLINE#printf\1\$CMDLINE root=live:/dev/ventoy $VTKS $VTOVERLAY $VTISO_SCAN $vtInstDD#" -i /lib/dracut-lib.sh +else + $SED "s#printf\(.*\)\$CMDLINE#printf\1\$CMDLINE inst.stage2=hd:/dev/ventoy $VTKS $VTOVERLAY $VTISO_SCAN $vtInstDD#" -i /lib/dracut-lib.sh +fi + + +ventoy_set_inotify_script rhel7/ventoy-inotifyd-hook.sh + +#Fedora +if $BUSYBOX_PATH/which dmsquash-live-root > /dev/null; then + vtPriority=99 +else + vtPriority=01 +fi + +$BUSYBOX_PATH/cp -a $VTOY_PATH/hook/rhel7/ventoy-inotifyd-start.sh /lib/dracut/hooks/pre-udev/${vtPriority}-ventoy-inotifyd-start.sh +$BUSYBOX_PATH/cp -a $VTOY_PATH/hook/rhel7/ventoy-timeout.sh /lib/dracut/hooks/initqueue/timeout/${vtPriority}-ventoy-timeout.sh + + +if [ -e /sbin/dmsquash-live-root ]; then + echo "patch /sbin/dmsquash-live-root ..." >> $VTLOG + $SED "1 a $BUSYBOX_PATH/sh $VTOY_PATH/hook/rhel7/ventoy-make-link.sh" -i /sbin/dmsquash-live-root +fi + +# suppress write protected mount warning +if [ -e /usr/sbin/anaconda-diskroot ]; then + $SED 's/^mount $dev $repodir/mount -oro $dev $repodir/' -i /usr/sbin/anaconda-diskroot +fi + +#For Fedora CoreOS +if $GREP -i -q 'fedora.*coreos' /etc/os-release; then + $SED "s#isosrc=.*#isosrc=/dev/mapper/ventoy#" -i /lib/systemd/system-generators/live-generator + cp -a $VTOY_PATH/hook/rhel7/ventoy-make-link.sh /lib/dracut/hooks/pre-mount/99-ventoy-premount-mklink.sh +fi + + +#special distro magic +$BUSYBOX_PATH/mkdir -p $VTOY_PATH/distmagic +if $GREP -q SCRE /proc/cmdline; then + echo 1 > $VTOY_PATH/distmagic/SCRE +fi + +if $GREP -qw 'SA[.]1' /proc/cmdline; then +if $GREP -qw 'writable.fsimg' /proc/cmdline; then +if $GREP -qw 'rw' /proc/cmdline; then + echo 1 > $VTOY_PATH/distmagic/DELL_PER +fi +fi +fi + diff --git a/IMG/cpio/ventoy/hook/rhel7/ventoy-inotifyd-call.sh b/IMG/cpio/ventoy/hook/rhel7/ventoy-inotifyd-call.sh new file mode 100644 index 0000000..f1a909a --- /dev/null +++ b/IMG/cpio/ventoy/hook/rhel7/ventoy-inotifyd-call.sh @@ -0,0 +1,26 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2023, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtHook=$($CAT $VTOY_PATH/inotifyd-hook-script.txt) + +vtdisk=$(get_ventoy_disk_name) +vtlog "... $vtdisk already exist ..." +$BUSYBOX_PATH/sh $vtHook n /dev "${vtdisk#/dev/}2" diff --git a/IMG/cpio/ventoy/hook/rhel7/ventoy-inotifyd-hook.sh b/IMG/cpio/ventoy/hook/rhel7/ventoy-inotifyd-hook.sh new file mode 100644 index 0000000..0ab5947 --- /dev/null +++ b/IMG/cpio/ventoy/hook/rhel7/ventoy-inotifyd-hook.sh @@ -0,0 +1,88 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +if is_inotify_ventoy_part $3; then + + vtlog "##### INOTIFYD: $2/$3 is created (YES) ..." + + + + vtlog "find ventoy partition ..." + + vtReplaceOpt=noreplace + if [ -f /lib/dracut/hooks/pre-pivot/99-ventoy-repo.sh ]; then + vtReplaceOpt="" + fi + + $BUSYBOX_PATH/sh $VTOY_PATH/hook/default/udev_disk_hook.sh $3 $vtReplaceOpt + + blkdev_num_mknod=$($VTOY_PATH/tool/dmsetup ls | $GREP ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') + $BUSYBOX_PATH/mknod -m 660 /dev/ventoy b $blkdev_num_mknod + $BUSYBOX_PATH/modprobe isofs >/dev/null 2>&1 + vtlog "mknod /dev/ventoy $blkdev_num_mknod" + + vtGenRulFile='/etc/udev/rules.d/99-live-squash.rules' + if [ -e $vtGenRulFile ] && $GREP -q dmsquash $vtGenRulFile; then + vtScript=$($GREP -m1 'RUN.=' $vtGenRulFile | $AWK -F'RUN.=' '{print $2}' | $SED 's/"\(.*\)".*/\1/') + vtlog "vtScript=$vtScript" + + if [ -f $VTOY_PATH/distmagic/SCRE ]; then + /sbin/dmsquash-live-root /dev/ventoy + elif [ -f $VTOY_PATH/distmagic/DELL_PER ]; then + sed 's/liverw=[^ ]*/liverw=ro/g' -i /sbin/dmsquash-live-root + sed 's/writable_fsimg=[^ ]*/writable_fsimg=""/g' -i /sbin/dmsquash-live-root + /sbin/dmsquash-live-root /dev/ventoy + else + $vtScript + fi + else + vtlog "$vtGenRulFile not exist..." + fi + + if [ -f $VTOY_PATH/ventoy_ks_rootpath ]; then + vt_ks_rootpath=$(cat $VTOY_PATH/ventoy_ks_rootpath) + vtlog "ks rootpath <$vt_ks_rootpath>" + if [ -e /sbin/fetch-kickstart-disk ]; then + vtlog "fetch-kickstart-disk ..." + /sbin/fetch-kickstart-disk /dev/ventoy "$vt_ks_rootpath" + fi + fi + + if [ -e /sbin/anaconda-diskroot ]; then + vtlog "set anaconda-diskroot ..." + + #busybox cp doesn't support -t option (issue 1900) + /bin/cp -a /bin/cp $BUSYBOX_PATH/cp + /sbin/anaconda-diskroot /dev/ventoy + fi + + set_ventoy_hook_finish +else + vtlog "##### INOTIFYD: $2/$3 is created (NO) ..." +fi + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/rhel7/ventoy-inotifyd-start.sh b/IMG/cpio/ventoy/hook/rhel7/ventoy-inotifyd-start.sh new file mode 100644 index 0000000..21920c4 --- /dev/null +++ b/IMG/cpio/ventoy/hook/rhel7/ventoy-inotifyd-start.sh @@ -0,0 +1,34 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtHook=$($CAT $VTOY_PATH/inotifyd-hook-script.txt) + +vtdisk=$(get_ventoy_disk_name) +if [ "$vtdisk" = "unknown" ]; then + vtlog "... start inotifyd listen $vtHook ..." + $BUSYBOX_PATH/nohup $VTOY_PATH/tool/inotifyd $vtHook /dev:n 2>&- & +else + vtlog "... $vtdisk already exist ..." + + #don't call it too early issue 2225 + #$BUSYBOX_PATH/sh $vtHook n /dev "${vtdisk#/dev/}2" + cp -a $VTOY_PATH/hook/rhel7/ventoy-inotifyd-call.sh /lib/dracut/hooks/initqueue/settled/90-ventoy-inotifyd-call.sh +fi diff --git a/IMG/cpio/ventoy/hook/rhel7/ventoy-make-link.sh b/IMG/cpio/ventoy/hook/rhel7/ventoy-make-link.sh new file mode 100644 index 0000000..100815a --- /dev/null +++ b/IMG/cpio/ventoy/hook/rhel7/ventoy-make-link.sh @@ -0,0 +1,50 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if [ ! -e /dev/dm-0 ]; then + exit 0 +fi + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) + +if [ -e /dev/mapper/ventoy ]; then + vtlog "/dev/mapper/ventoy already exist" +else + vtlog "link /dev/$vtDM to /dev/mapper/ventoy" + ln -s /dev/$vtDM /dev/mapper/ventoy +fi + +VTLABEL=$($BUSYBOX_PATH/blkid /dev/$vtDM | $SED 's/.*LABEL="\([^"]*\)".*/\1/') +vtlog "VTLABEL=$VTLABEL" + +if [ -n "$VTLABEL" ]; then + if ! [ -d /dev/disk/by-label ]; then + mkdir -p /dev/disk/by-label + fi + + if [ -e "/dev/disk/by-label/$VTLABEL" ]; then + vtlog "/dev/disk/by-label/$VTLABEL already exist" + else + vtlog "link /dev/$vtDM to /dev/disk/by-label/$VTLABEL" + ln -s /dev/$vtDM "/dev/disk/by-label/$VTLABEL" + fi +fi diff --git a/IMG/cpio/ventoy/hook/rhel7/ventoy-overlay.sh b/IMG/cpio/ventoy/hook/rhel7/ventoy-overlay.sh new file mode 100644 index 0000000..d8fe079 --- /dev/null +++ b/IMG/cpio/ventoy/hook/rhel7/ventoy-overlay.sh @@ -0,0 +1,21 @@ +#!/bin/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +[ -d /run/initramfs/overlayfs$pathspec ] || mkdir -p /run/initramfs/overlayfs$pathspec +[ -d /run/initramfs/overlayfs$pathspec/../ovlwork ] || mkdir -p /run/initramfs/overlayfs$pathspec/../ovlwork diff --git a/IMG/cpio/ventoy/hook/rhel7/ventoy-repo.sh b/IMG/cpio/ventoy/hook/rhel7/ventoy-repo.sh new file mode 100644 index 0000000..002aa5e --- /dev/null +++ b/IMG/cpio/ventoy/hook/rhel7/ventoy-repo.sh @@ -0,0 +1,40 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "##### $0 $* ..." + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +if [ -f /ventoy/vtoy_iso_scan ]; then + repopath=$(cat /ventoy/vtoy_iso_scan) + repodev=$(vtoydump -f /ventoy/ventoy_os_param | awk -F'#' '{print $1}') + if echo $repodev | egrep -q "nvme|mmc|nbd"; then + vtpart1=${repodev}p1 + else + vtpart1=${repodev}1 + fi + echo "inst.repo=hd:${vtpart1}:${repopath}" >> /sysroot/etc/cmdline +else + repodev=$(ls $VTOY_PATH/dev_backup*) + echo "inst.repo=hd:/dev/${repodev#*dev_backup_}" >> /sysroot/etc/cmdline +fi + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/rhel7/ventoy-timeout.sh b/IMG/cpio/ventoy/hook/rhel7/ventoy-timeout.sh new file mode 100644 index 0000000..cfd339f --- /dev/null +++ b/IMG/cpio/ventoy/hook/rhel7/ventoy-timeout.sh @@ -0,0 +1,48 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "##### $0 $* ..." + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +if [ ! -e /dev/ventoy ]; then + blkdev_num_mknod=$(dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') + mknod -m 660 /dev/ventoy b $blkdev_num_mknod +fi + +if [ -f $VTOY_PATH/ventoy_ks_rootpath ]; then + vt_ks_rootpath=$(cat $VTOY_PATH/ventoy_ks_rootpath) + vtlog "ks rootpath <$vt_ks_rootpath>" + if [ -e /sbin/fetch-kickstart-disk ]; then + vtlog "fetch-kickstart-disk ..." + /sbin/fetch-kickstart-disk /dev/ventoy "$vt_ks_rootpath" + fi +fi + +if [ -e /sbin/anaconda-diskroot ]; then + vtlog "set anaconda-diskroot /dev/ventoy ..." + + #busybox cp doesn't support -t option (issue 1900) + /bin/cp -a /bin/cp $BUSYBOX_PATH/cp + /sbin/anaconda-diskroot /dev/ventoy +fi + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/slackware/disk_hook.sh b/IMG/cpio/ventoy/hook/slackware/disk_hook.sh new file mode 100644 index 0000000..68a1ce7 --- /dev/null +++ b/IMG/cpio/ventoy/hook/slackware/disk_hook.sh @@ -0,0 +1,38 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/slackware/udev_disk_hook.sh b/IMG/cpio/ventoy/hook/slackware/udev_disk_hook.sh new file mode 100644 index 0000000..9b06483 --- /dev/null +++ b/IMG/cpio/ventoy/hook/slackware/udev_disk_hook.sh @@ -0,0 +1,41 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished || not_ventoy_disk "${1:0:-1}"; then + exit 0 +fi + +ventoy_udev_disk_common_hook $* + +# +# make a fake cdrom link +# +if [ -e /dev/sr3 ]; then + if ! [ -e /dev/hdp ]; then + ln -s $VTOY_DM_PATH /dev/hdp + fi +else + ln -s $VTOY_DM_PATH /dev/sr3 +fi + +# OK finish +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/slackware/ventoy-hook.sh b/IMG/cpio/ventoy/hook/slackware/ventoy-hook.sh new file mode 100644 index 0000000..1b3f048 --- /dev/null +++ b/IMG/cpio/ventoy/hook/slackware/ventoy-hook.sh @@ -0,0 +1,12 @@ +#!/ventoy/busybox/sh + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +if $GREP '^mediadetected=' /init; then + $SED "/^mediadetected=/i $BUSYBOX_PATH/sh $VTOY_PATH/hook/slackware/disk_hook.sh" -i /init +else + ventoy_systemd_udevd_work_around + ventoy_add_udev_rule "$VTOY_PATH/hook/slackware/udev_disk_hook.sh %k noreplace" +fi + + diff --git a/IMG/cpio/ventoy/hook/smgl/disk_hook.sh b/IMG/cpio/ventoy/hook/smgl/disk_hook.sh new file mode 100644 index 0000000..7a99ab3 --- /dev/null +++ b/IMG/cpio/ventoy/hook/smgl/disk_hook.sh @@ -0,0 +1,45 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +#exec /ventoy/busybox/sh + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +mknod -m 660 /dev/ventoy b $blkdev_num + +echo "/dev/ventoy" > cdrom.hint + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/smgl/ventoy-hook.sh b/IMG/cpio/ventoy/hook/smgl/ventoy-hook.sh new file mode 100644 index 0000000..9eb20d5 --- /dev/null +++ b/IMG/cpio/ventoy/hook/smgl/ventoy-hook.sh @@ -0,0 +1,45 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +PATH=$PATH:$VTOY_PATH/busybox + +mkdir /ventoy_rdroot + +mknod -m 660 /ram0 b 1 0 + +dd if=/initrd001 of=/ram0 +rm -f /initrd001 + +mount /ram0 /ventoy_rdroot + +vtSize=$(du -m -s $VTOY_PATH | awk '{print $1}') +let vtSize=vtSize+4 + +mkdir -p /ventoy_rdroot/ventoy +mount -t tmpfs -o size=${vtSize}m tmpfs /ventoy_rdroot/ventoy +cp -a /ventoy/* /ventoy_rdroot/ventoy/ + + +cd /ventoy_rdroot + +sed "/scan_cdroms *$/i $BUSYBOX_PATH/sh $VTOY_PATH/hook/smgl/disk_hook.sh" -i sbin/smgl.init + + diff --git a/IMG/cpio/ventoy/hook/smoothwall/cd_list.sh b/IMG/cpio/ventoy/hook/smoothwall/cd_list.sh new file mode 100644 index 0000000..5e7cbab --- /dev/null +++ b/IMG/cpio/ventoy/hook/smoothwall/cd_list.sh @@ -0,0 +1,33 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) +vtSize=$(cat /sys/block/$vtDM/size) + +cp -a /tmp/cd.list /tmp/cd_new.list +echo "$vtDM $vtSize UNK_MODEL " > /tmp/cd.list +cat /tmp/cd_new.list >> /tmp/cd.list +rm -f /tmp/cd_new.list + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/smoothwall/disk_hook.sh b/IMG/cpio/ventoy/hook/smoothwall/disk_hook.sh new file mode 100644 index 0000000..b6ae8c6 --- /dev/null +++ b/IMG/cpio/ventoy/hook/smoothwall/disk_hook.sh @@ -0,0 +1,55 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) + +if [ "$1" = "fakecdrom" ]; then + if [ -e /dev/sr0 ]; then + for i in 0 1 2 3 4 5 6 7 8; do + if ! [ -e /dev/sr$i ]; then + mv /dev/sr0 /dev/sr$i + cp -a /dev/$vtDM /dev/sr0 + break + fi + done + else + cp -a /dev/$vtDM /dev/sr0 + fi +fi + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/smoothwall/ventoy-hook.sh b/IMG/cpio/ventoy/hook/smoothwall/ventoy-hook.sh new file mode 100644 index 0000000..c2dd611 --- /dev/null +++ b/IMG/cpio/ventoy/hook/smoothwall/ventoy-hook.sh @@ -0,0 +1,25 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/Running installer/i $BUSYBOX_PATH/sh $VTOY_PATH/hook/smoothwall/disk_hook.sh fakecdrom" -i /etc/install.rc + +$SED "/cd \/sys\/block/a $BUSYBOX_PATH/sh $VTOY_PATH/hook/smoothwall/disk_hook.sh" -i /etc/config-install.rc +$SED "/wc *-l *\/tmp\/cd.list/i $BUSYBOX_PATH/sh $VTOY_PATH/hook/smoothwall/cd_list.sh" -i /etc/config-install.rc diff --git a/IMG/cpio/ventoy/hook/suse/disk_hook.sh b/IMG/cpio/ventoy/hook/suse/disk_hook.sh new file mode 100644 index 0000000..4a56ecc --- /dev/null +++ b/IMG/cpio/ventoy/hook/suse/disk_hook.sh @@ -0,0 +1,68 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + + +ventoy_os_install_dmsetup_by_fuse() { + vtlog "ventoy_os_install_dmsetup_by_fuse $*" + + mkdir -p $VTOY_PATH/mnt/fuse $VTOY_PATH/mnt/iso $VTOY_PATH/mnt/squashfs + + vtoydm -p -f $VTOY_PATH/ventoy_image_map -d $1 > $VTOY_PATH/ventoy_dm_table + vtoy_fuse_iso -f $VTOY_PATH/ventoy_dm_table -m $VTOY_PATH/mnt/fuse + + mount -t iso9660 $VTOY_PATH/mnt/fuse/ventoy.iso $VTOY_PATH/mnt/iso + + [ -f $VTOY_PATH/mnt/iso/system/squashfs_sys.img ] && mount -t squashfs $VTOY_PATH/mnt/iso/system/squashfs_sys.img $VTOY_PATH/mnt/squashfs + [ -f $VTOY_PATH/mnt/iso/system/squashfs.img ] && mount -t squashfs $VTOY_PATH/mnt/iso/system/squashfs.img $VTOY_PATH/mnt/squashfs + + KoName=$(ls $VTOY_PATH/mnt/squashfs/lib/modules/$2/kernel/drivers/md/dm-mod.ko*) + vtlog "insmod $KoName" + insmod $KoName + + umount $VTOY_PATH/mnt/squashfs 2>>$VTLOG + umount $VTOY_PATH/mnt/iso 2>>$VTLOG + umount $VTOY_PATH/mnt/fuse 2>>$VTLOG +} + + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +modprobe fuse +ventoy_os_install_dmsetup_by_fuse $vtdiskname $(uname -r) + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +mknod -m 0660 /dev/ventoy b $blkdev_num + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/suse/udev_disk_hook.sh b/IMG/cpio/ventoy/hook/suse/udev_disk_hook.sh new file mode 100644 index 0000000..d5e8170 --- /dev/null +++ b/IMG/cpio/ventoy/hook/suse/udev_disk_hook.sh @@ -0,0 +1,75 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +ventoy_os_install_dmsetup() { + vtlog "ventoy_os_install_dmsetup $1" + + vt_usb_disk=$1 + + # dump iso file location + $VTOY_PATH/tool/vtoydm -i -f $VTOY_PATH/ventoy_image_map -d ${vt_usb_disk} > $VTOY_PATH/iso_file_list + + # install dmsetup + LINE=$($GREP 'device-mapper-[0-9]\..*\.rpm' $VTOY_PATH/iso_file_list) + if [ $? -eq 0 ]; then + install_rpm_from_line "$LINE" ${vt_usb_disk} + fi + + vtlog "dmsetup install finish, now check it..." + + dmsetup_path=$(ventoy_find_bin_path dmsetup) + if [ -z "$dmsetup_path" ]; then + vterr "dmsetup still not found after install" + elif $dmsetup_path info >> $VTLOG 2>&1; then + vtlog "$dmsetup_path work ok" + else + vterr "$dmsetup_path not work" + fi +} + +if is_ventoy_hook_finished || not_ventoy_disk "${1:0:-1}"; then + exit 0 +fi + +dmsetup_path=$(ventoy_find_bin_path dmsetup) +if [ -z "$dmsetup_path" ]; then + ventoy_os_install_dmsetup "/dev/${1:0:-1}" +fi + +if [ -f /proc/devices ]; then + vtlog "/proc/devices exist OK" +else + for i in 1 2 3 4 5 6 7 8 9; do + if [ -f /proc/devices ]; then + vtlog "/proc/devices exist OK now" + break + else + vtlog "/proc/devices NOT exist, wait $i" + $BUSYBOX_PATH/sleep 1 + fi + done +fi + + +ventoy_udev_disk_common_hook $* + +# OK finish +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/suse/udev_setup_hook.sh b/IMG/cpio/ventoy/hook/suse/udev_setup_hook.sh new file mode 100644 index 0000000..d222f66 --- /dev/null +++ b/IMG/cpio/ventoy/hook/suse/udev_setup_hook.sh @@ -0,0 +1,50 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + exit 0 +fi + +vtlog "wait_for_usb_disk_ready $vtdiskname ..." + +if echo $vtdiskname | $EGREP -q "nvme|mmc|nbd"; then + vtpart2=${vtdiskname}p2 +else + vtpart2=${vtdiskname}2 +fi + +/ventoy/busybox/sh /ventoy/hook/suse/udev_disk_hook.sh "${vtpart2#/dev/}" + +if $GREP -q 'mediacheck=1' /proc/cmdline; then + ventoy_copy_device_mapper "${vtdiskname}" +fi + +if [ -f /ventoy/autoinstall ]; then + sh /ventoy/hook/default/auto_install_varexp.sh /ventoy/autoinstall +fi +if [ -f /autoinst.xml ]; then + sh /ventoy/hook/default/auto_install_varexp.sh /autoinst.xml +fi + diff --git a/IMG/cpio/ventoy/hook/suse/ventoy-hook.sh b/IMG/cpio/ventoy/hook/suse/ventoy-hook.sh new file mode 100644 index 0000000..cc90cc5 --- /dev/null +++ b/IMG/cpio/ventoy/hook/suse/ventoy-hook.sh @@ -0,0 +1,79 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +if [ -f $VTOY_PATH/autoinstall ]; then + if [ -f /linuxrc.config ]; then + echo "AutoYaST: file:///ventoy/autoinstall" >> /info-ventoy + $SED "1 iinfo: file:/info-ventoy" -i /linuxrc.config + fi +fi + +if $GREP -q 'rdinit=/vtoy/vtoy' /proc/cmdline; then + echo "remove rdinit param" >> $VTLOG + echo "ptoptions=+rdinit" >> /linuxrc.config +fi + + +if $BUSYBOX_PATH/ls $VTOY_PATH | $GREP -q 'ventoy_dud[0-9]'; then + if [ -f /linuxrc.config ]; then + vtKerVer=$($BUSYBOX_PATH/uname -r) + ventoy_check_insmod /modules/loop.ko + ventoy_check_insmod /modules/squashfs.ko + + ventoy_check_mount /parts/00_lib /modules + ventoy_check_insmod /modules/lib/modules/$vtKerVer/initrd/isofs.ko + $BUSYBOX_PATH/umount /modules + + for vtDud in $($BUSYBOX_PATH/ls $VTOY_PATH/ventoy_dud*); do + $BUSYBOX_PATH/mkdir -p ${vtDud%.*}_mnt + if $BUSYBOX_PATH/mount $vtDud ${vtDud%.*}_mnt > /dev/null 2>&1; then + $BUSYBOX_PATH/cp -a ${vtDud%.*}_mnt ${vtDud%.*}_data + $BUSYBOX_PATH/umount ${vtDud%.*}_mnt + echo "dud: file://${vtDud%.*}_data" >> /linuxrc.config + else + echo "mount $vtDud failed" >> $VTLOG + fi + done + + $BUSYBOX_PATH/rmmod isofs >> $VTLOG 2>&1 + $BUSYBOX_PATH/rmmod squashfs >> $VTLOG 2>&1 + $BUSYBOX_PATH/rmmod loop >> $VTLOG 2>&1 + fi +fi + +#echo "Exec: /bin/sh $VTOY_PATH/hook/suse/cdrom-hook.sh" >> /info-ventoy +#echo "install: hd:/?device=/dev/mapper/ventoy" >> /info-ventoy +#$SED "1 iinfo: file:/info-ventoy" -i /linuxrc.config + +if [ -e /etc/initrd.functions ] && $GREP -q 'HPIP' /etc/initrd.functions; then + echo "HPIP" >> $VTLOG + $BUSYBOX_PATH/mkdir /dev + $BUSYBOX_PATH/mknod -m 660 /dev/console c 5 1 + $SED "/CD_DEVICES=/a $BUSYBOX_PATH/sh $VTOY_PATH/hook/suse/disk_hook.sh" -i /etc/initrd.functions + $SED "/CD_DEVICES=/a CD_DEVICES=\"/dev/ventoy \$CD_DEVICES\"" -i /etc/initrd.functions +elif [ -f /scripts/udev_setup ]; then + echo "udev_setup" >> $VTLOG + echo "/ventoy/busybox/sh /ventoy/hook/suse/udev_setup_hook.sh" >> /scripts/udev_setup +else + echo "SUSE" >> $VTLOG + ventoy_systemd_udevd_work_around + ventoy_add_udev_rule "$VTOY_PATH/hook/suse/udev_disk_hook.sh %k" +fi diff --git a/IMG/cpio/ventoy/hook/t2/disk_hook.sh b/IMG/cpio/ventoy/hook/t2/disk_hook.sh new file mode 100644 index 0000000..b977f71 --- /dev/null +++ b/IMG/cpio/ventoy/hook/t2/disk_hook.sh @@ -0,0 +1,59 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +vtlog "Loading dax and dm-mod module ..." +$BUSYBOX_PATH/modprobe dax > /dev/null 2>&1 +$BUSYBOX_PATH/modprobe dm-mod > /dev/null 2>&1 + +if $GREP -q 'device-mapper' /proc/devices; then + vtlog "dm-mod module check success ..." +else + vtlog "Need to extract dax and dm-mod module ..." + $VTOY_PATH/tool/zstdcat /lib/modules/$(uname -r)/drivers/dax/dax.ko.zst > $VTOY_PATH/extract_dax.ko + $BUSYBOX_PATH/insmod $VTOY_PATH/extract_dax.ko + $VTOY_PATH/tool/zstdcat /lib/modules/$(uname -r)/drivers/md/dm-mod.ko.zst > $VTOY_PATH/extract_dm_mod.ko + $BUSYBOX_PATH/insmod $VTOY_PATH/extract_dm_mod.ko +fi + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +mknod -m 0660 /dev/ventoy b $blkdev_num + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/t2/ventoy-hook.sh b/IMG/cpio/ventoy/hook/t2/ventoy-hook.sh new file mode 100644 index 0000000..97a5828 --- /dev/null +++ b/IMG/cpio/ventoy/hook/t2/ventoy-hook.sh @@ -0,0 +1,26 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/Searching/i $BUSYBOX_PATH/sh $VTOY_PATH/hook/t2/disk_hook.sh" -i /init +$SED "/disktype/i x=/dev/ventoy" -i /init +$SED "/getdevice *devicefile/i $BUSYBOX_PATH/sh $VTOY_PATH/hook/t2/disk_hook.sh" -i /init +$SED "/getdevice *devicefile/a devicefile=/dev/ventoy" -i /init + diff --git a/IMG/cpio/ventoy/hook/tinycore/ventoy-disk.sh b/IMG/cpio/ventoy/hook/tinycore/ventoy-disk.sh new file mode 100644 index 0000000..86dce82 --- /dev/null +++ b/IMG/cpio/ventoy/hook/tinycore/ventoy-disk.sh @@ -0,0 +1,80 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +if echo $vtdiskname | egrep -q "nvme.*p[0-9]$|mmc.*p[0-9]$|nbd.*p[0-9]$"; then + vPart="${vtdiskname}p2" +else + vPart="${vtdiskname}2" +fi + +# TinyCore linux distro doesn't contain dmsetup, we use aoe here +sudo modprobe aoe aoe_iflist=lo +if [ -e /sys/module/aoe ]; then + + if ! [ -d /lib64 ]; then + vtlog "link lib64" + NEED_UNLIB64=1 + ln -s /lib /lib64 + fi + + VBLADE_BIN=$(ventoy_get_vblade_bin) + + sudo nohup $VBLADE_BIN -r -f $VTOY_PATH/ventoy_image_map 9 0 lo "$vtdiskname" > /dev/null & + sleep 2 + + while ! [ -b /dev/etherd/e9.0 ]; do + vtlog 'Wait for /dev/etherd/e9.0 ....' + sleep 2 + done + + sudo cp -a /dev/etherd/e9.0 "$vPart" + + if [ -n "$NEED_UNLIB64" ]; then + vtlog "unlink lib64" + unlink /lib64 + fi + + ventoy_find_bin_run rebuildfstab +else + vterr "aoe driver module load failed..." +fi + +# OK finish +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/tinycore/ventoy-hook.sh b/IMG/cpio/ventoy/hook/tinycore/ventoy-hook.sh new file mode 100644 index 0000000..2bd18b3 --- /dev/null +++ b/IMG/cpio/ventoy/hook/tinycore/ventoy-hook.sh @@ -0,0 +1,23 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/\[.*-n.*WAITUSB/i\WAITUSB=10" -i /etc/init.d/tc-config +$SED "/\[.*-n.*AOE/i\$VTOY_PATH/hook/tinycore/ventoy-disk.sh" -i /etc/init.d/tc-config diff --git a/IMG/cpio/ventoy/hook/ventoy-hook-lib.sh b/IMG/cpio/ventoy/hook/ventoy-hook-lib.sh new file mode 100644 index 0000000..2b413a4 --- /dev/null +++ b/IMG/cpio/ventoy/hook/ventoy-hook-lib.sh @@ -0,0 +1,726 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +VTOY_PATH=/ventoy +BUSYBOX_PATH=$VTOY_PATH/busybox +VTLOG=$VTOY_PATH/log +FIND=$BUSYBOX_PATH/find +GREP=$BUSYBOX_PATH/grep +EGREP=$BUSYBOX_PATH/egrep +CAT=$BUSYBOX_PATH/cat +AWK=$BUSYBOX_PATH/awk +SED=$BUSYBOX_PATH/sed +SLEEP=$BUSYBOX_PATH/sleep +HEAD=$BUSYBOX_PATH/head +VTOY_DM_PATH=/dev/mapper/ventoy +VTOY_DEBUG_LEVEL=$($BUSYBOX_PATH/hexdump -n 1 -s 450 -e '1/1 "%02x"' $VTOY_PATH/ventoy_os_param) +VTOY_LINUX_REMOUNT=$($BUSYBOX_PATH/hexdump -n 1 -s 454 -e '1/1 "%02x"' $VTOY_PATH/ventoy_os_param) +VTOY_VLNK_BOOT=$($BUSYBOX_PATH/hexdump -n 1 -s 455 -e '1/1 "%02x"' $VTOY_PATH/ventoy_os_param) + +if [ "$VTOY_DEBUG_LEVEL" = "01" ]; then + if [ -e /dev/console ]; then + VTLOG=/dev/console + fi +fi + +vtlog() { + if [ "$VTLOG" = "$VTOY_PATH/log" ]; then + echo "$*" >>$VTLOG + else + echo -e "\033[32m $* \033[0m" > $VTLOG + $SLEEP 2 + fi +} + +vterr() { + if [ "$VTLOG" = "$VTOY_PATH/log" ]; then + echo "$*" >>$VTLOG + else + echo -e "\n\033[31m $* \033[0m" > $VTLOG + $SLEEP 30 + fi +} + + +is_ventoy_hook_finished() { + [ -e $VTOY_PATH/hook_finish ] +} + +set_ventoy_hook_finish() { + echo 'Y' > $VTOY_PATH/hook_finish + + if [ -f /ventoy/ventoy_iso_part_dm_cmd ]; then + echo "### create iso part raw dm" >> $VTLOG + $CAT $VTOY_PATH/ventoy_raw_table >> $VTLOG + echo "### iso part dm cmd" >> $VTLOG + $CAT /ventoy/ventoy_iso_part_dm_cmd >> $VTLOG + $BUSYBOX_PATH/sh /ventoy/ventoy_iso_part_dm_cmd >>$VTLOG 2>&1 + #$BUSYBOX_PATH/rm -f /ventoy/ventoy_iso_part_dm_cmd + fi +} + +get_ventoy_disk_name() { + if [ "$VTOY_VLNK_BOOT" = "01" ]; then + $VTOY_PATH/tool/vtoydump -t /ventoy/ventoy_os_param + else + line=$($VTOY_PATH/tool/vtoydump -f /ventoy/ventoy_os_param) + if [ $? -eq 0 ]; then + echo ${line%%#*} + else + echo "unknown" + fi + fi +} + +get_ventoy_iso_name() { + line=$($VTOY_PATH/tool/vtoydump -f /ventoy/ventoy_os_param) + if [ $? -eq 0 ]; then + echo ${line##*#} + else + echo "unknown" + fi +} + +wait_for_usb_disk_ready() { + vtloop=0 + while [ -n "Y" ]; do + usb_disk=$(get_ventoy_disk_name) + vtlog "wait_for_usb_disk_ready $usb_disk ..." + + if echo $usb_disk | $EGREP -q "nvme|mmc|nbd"; then + vtpart2=${usb_disk}p2 + else + vtpart2=${usb_disk}2 + fi + + if [ -e "${vtpart2}" ]; then + vtlog "wait_for_usb_disk_ready $usb_disk finish" + break + else + let vtloop=vtloop+1 + if [ $vtloop -gt 2 ]; then + if [ "$VTLOG" != "$VTOY_PATH/log" ]; then + $VTOY_PATH/tool/vtoydump -f /ventoy/ventoy_os_param -v > $VTLOG + fi + fi + $SLEEP 0.3 + fi + done +} + + +check_usb_disk_ready() { + if echo $1 | $EGREP -q "nvme|mmc|nbd"; then + vtpart2=${1}p2 + else + vtpart2=${1}2 + fi + + [ -e "${vtpart2}" ] +} + +not_ventoy_disk() { + if echo $1 | $EGREP -q "nvme.*p$|mmc.*p$|nbd.*p$"; then + vtDiskName=${1:0:-1} + else + vtDiskName=$1 + fi + + if [ "$VTOY_VLNK_BOOT" = "01" ]; then + vtVtoyDisk=$($VTOY_PATH/tool/vtoydump -t $VTOY_PATH/ventoy_os_param) + [ "$vtVtoyDisk" != "/dev/$vtDiskName" ] + else + if $VTOY_PATH/tool/vtoydump -f $VTOY_PATH/ventoy_os_param -c "$vtDiskName"; then + $BUSYBOX_PATH/false + else + $BUSYBOX_PATH/true + fi + fi +} + +ventoy_get_vblade_bin() { + if $VTOY_PATH/tool/vblade_64 -t >>$VTLOG 2>&1; then + echo $VTOY_PATH/tool/vblade_64 + else + echo $VTOY_PATH/tool/vblade_32 + fi +} + +ventoy_find_bin_path() { + #must use built-in dmsetup, so first try ventoy path. Otherwise ubuntu installer unhappy. #3567 + if $BUSYBOX_PATH/which "$1" > /dev/null; then + $BUSYBOX_PATH/which "$1"; return + fi + for vt_path in '/bin' '/sbin' '/usr/bin' '/usr/sbin' '/usr/local/bin' '/usr/local/sbin' '/root/bin'; do + if [ -e "$vt_path/$1" ]; then + echo "$vt_path/$1"; return + fi + done + + echo "" +} + + +ventoy_find_bin_run() { + vtsudo=0 + if [ "$1" = "sudo" ]; then + shift + vtsudo=1 + fi + + vtbinpath=$(ventoy_find_bin_path "$1") + if [ -n "$vtbinpath" ]; then + shift + + if [ $vtsudo -eq 0 ]; then + vtlog "$vtbinpath $*" + $vtbinpath $* + else + vtlog "sudo $vtbinpath $*" + sudo $vtbinpath $* + fi + fi +} + +ventoy_get_module_postfix() { + vtKerVer=$($BUSYBOX_PATH/uname -r) + vtLine=$($FIND /lib/modules/$vtKerVer/ -name *.ko* | $HEAD -n1) + vtComp=${vtLine##*/*.ko} + echo "ko$vtComp" +} + +ventoy_check_dm_module() { + if $GREP -q 'device-mapper' /proc/devices; then + $BUSYBOX_PATH/true; return + fi + + vtlog "device-mapper NOT found in /proc/devices, try to load kernel module" + $BUSYBOX_PATH/modprobe dm_mod >>$VTLOG 2>&1 + $BUSYBOX_PATH/modprobe dm-mod >>$VTLOG 2>&1 + + if ! $GREP -q 'device-mapper' /proc/devices; then + vtlog "modprobe failed, now try to insmod ko..." + + $FIND /lib/modules/ -name "dm-mod.ko*" | while read vtline; do + vtlog "insmod $vtline " + $BUSYBOX_PATH/insmod $vtline >>$VTLOG 2>&1 + if [ $? -eq 0 ]; then + vtlog "insmod success" + else + vtlog "insmod failed, try decompress" + if echo $vtline | $GREP -q "\.zst"; then + $VTOY_PATH/tool/zstdcat $vtline > $VTOY_PATH/extract_dm_mod.ko + $BUSYBOX_PATH/insmod $VTOY_PATH/extract_dm_mod.ko >>$VTLOG 2>&1 + fi + fi + done + fi + + if $GREP -q 'device-mapper' /proc/devices; then + vtlog "device-mapper found in /proc/devices after retry" + $BUSYBOX_PATH/true; return + else + vtlog "device-mapper still NOT found in /proc/devices after retry" + $BUSYBOX_PATH/false; return + fi +} + + +create_ventoy_device_mapper() { + vtlog "create_ventoy_device_mapper $*" + + VT_DM_BIN=$(ventoy_find_bin_path dmsetup) + if [ -z "$VT_DM_BIN" ]; then + vtlog "no dmsetup avaliable, lastly try inbox dmsetup" + VT_DM_BIN=$VTOY_PATH/tool/dmsetup + fi + + vtlog "dmsetup avaliable in system $VT_DM_BIN" + + if ventoy_check_dm_module "$1"; then + vtlog "device-mapper module check success" + else + vterr "Error: no dm module avaliable" + fi + + $VTOY_PATH/tool/vtoydm -p -f $VTOY_PATH/ventoy_image_map -d $1 > $VTOY_PATH/ventoy_dm_table + $VTOY_PATH/tool/vtoydm -r -f $VTOY_PATH/ventoy_image_map -d $1 > $VTOY_PATH/ventoy_raw_table + + if [ -z "$2" ]; then + $VT_DM_BIN create ventoy $VTOY_PATH/ventoy_dm_table >>$VTLOG 2>&1 + else + $VT_DM_BIN "$2" create ventoy $VTOY_PATH/ventoy_dm_table >>$VTLOG 2>&1 + fi + + RAWDISKNAME=$($HEAD -n1 $VTOY_PATH/ventoy_raw_table | $AWK '{print $4}') + echo "$VT_DM_BIN create ${RAWDISKNAME#/dev/} $VTOY_PATH/ventoy_raw_table" > /ventoy/ventoy_iso_part_dm_cmd + #echo "$VT_DM_BIN mknodes ${RAWDISKNAME#/dev/}" >> /ventoy/ventoy_iso_part_dm_cmd + #echo "$VT_DM_BIN ls" >> /ventoy/ventoy_iso_part_dm_cmd +} + +create_persistent_device_mapper() { + vtlog "create_persistent_device_mapper $*" + + VT_DM_BIN=$(ventoy_find_bin_path dmsetup) + if [ -z "$VT_DM_BIN" ]; then + vtlog "no dmsetup avaliable, lastly try inbox dmsetup" + VT_DM_BIN=$VTOY_PATH/tool/dmsetup + fi + + vtlog "dmsetup avaliable in system $VT_DM_BIN" + + if ventoy_check_dm_module "$1"; then + vtlog "device-mapper module check success" + else + vterr "Error: no dm module avaliable" + fi + + $VTOY_PATH/tool/vtoydm -p -f $VTOY_PATH/ventoy_persistent_map -d $1 > $VTOY_PATH/persistent_dm_table + $VT_DM_BIN create vtoy_persistent $VTOY_PATH/persistent_dm_table >>$VTLOG 2>&1 +} + + + +wait_for_ventoy_dm_disk_label() { + DM=$($BUSYBOX_PATH/readlink $VTOY_DM_PATH) + vtlog "wait_for_ventoy_dm_disk_label $DM ..." + + for i in 0 1 2 3 4 5 6 7 8 9; do + vtlog "i=$i ####### ls /dev/disk/by-label/" + ls -l /dev/disk/by-label/ >> $VTLOG + + if ls -l /dev/disk/by-label/ | $GREP -q "$DM"; then + break + else + $SLEEP 1 + fi + done +} + +install_udeb_pkg() { + if ! [ -e "$1" ]; then + $BUSYBOX_PATH/false + return + fi + + if [ -d /tmp/vtoy_udeb ]; then + $BUSYBOX_PATH/rm -rf /tmp/vtoy_udeb + fi + + $BUSYBOX_PATH/mkdir -p /tmp/vtoy_udeb + $BUSYBOX_PATH/cp -a "$1" /tmp/vtoy_udeb/ + + CURDIR=$($BUSYBOX_PATH/pwd) + cd /tmp/vtoy_udeb + + $BUSYBOX_PATH/ar x "$1" + + if [ -e 'data.tar.gz' ]; then + $BUSYBOX_PATH/tar -xzf data.tar.gz -C / + elif [ -e 'data.tar.xz' ]; then + $BUSYBOX_PATH/tar -xJf data.tar.xz -C / + elif [ -e 'data.tar.bz2' ]; then + $BUSYBOX_PATH/tar -xjf data.tar.bz2 -C / + elif [ -e 'data.tar.lzma' ]; then + $BUSYBOX_PATH/tar -xaf data.tar.lzma -C / + fi + + if [ -e 'control.tar.gz' ]; then + $BUSYBOX_PATH/tar -xzf control.tar.gz -C / + elif [ -e 'control.tar.xz' ]; then + $BUSYBOX_PATH/tar -xJf control.tar.xz -C / + elif [ -e 'control.tar.bz2' ]; then + $BUSYBOX_PATH/tar -xjf control.tar.bz2 -C / + elif [ -e 'control.tar.lzma' ]; then + $BUSYBOX_PATH/tar -xaf control.tar.lzma -C / + fi + + cd $CURDIR + $BUSYBOX_PATH/rm -rf /tmp/vtoy_udeb + $BUSYBOX_PATH/true +} + + +install_udeb_from_line() { + vtlog "install_udeb_from_line $1" + + if ! [ -b "$2" ]; then + vterr "disk #$2# not exist" + return + fi + + sector=$(echo $1 | $AWK '{print $(NF-1)}') + length=$(echo $1 | $AWK '{print $NF}') + vtlog "sector=$sector length=$length" + + $VTOY_PATH/tool/vtoydm -e -f $VTOY_PATH/ventoy_image_map -d ${2} -s $sector -l $length -o /tmp/xxx.udeb + if [ -e /tmp/xxx.udeb ]; then + vtlog "extract udeb file from iso success" + else + vterr "extract udeb file from iso fail" + return + fi + + install_udeb_pkg /tmp/xxx.udeb + $BUSYBOX_PATH/rm -f /tmp/xxx.udeb +} + +extract_file_from_line() { + vtlog "extract_file_from_line $1 disk=#$2#" + if ! [ -b "$2" ]; then + vterr "disk #$2# not exist" + return + fi + + sector=$(echo $1 | $AWK '{print $(NF-1)}') + length=$(echo $1 | $AWK '{print $NF}') + vtlog "sector=$sector length=$length" + + $VTOY_PATH/tool/vtoydm -e -f $VTOY_PATH/ventoy_image_map -d ${2} -s $sector -l $length -o $3 + if [ -e $3 ]; then + vtlog "extract file from iso success" + $BUSYBOX_PATH/true + else + vterr "extract file from iso fail" + $BUSYBOX_PATH/false + fi +} + +extract_rpm_from_line() { + vtlog "extract_rpm_from_line $1 disk=#$2#" + + if ! [ -b "$2" ]; then + vterr "disk #$2# not exist" + return + fi + + sector=$(echo $1 | $AWK '{print $(NF-1)}') + length=$(echo $1 | $AWK '{print $NF}') + vtlog "sector=$sector length=$length" + + $VTOY_PATH/tool/vtoydm -e -f $VTOY_PATH/ventoy_image_map -d ${2} -s $sector -l $length -o /tmp/xxx.rpm + if [ -e /tmp/xxx.rpm ]; then + vtlog "extract rpm file from iso success" + else + vterr "extract rpm file from iso fail" + return + fi + + CURPWD=$($BUSYBOX_PATH/pwd) + + $BUSYBOX_PATH/mkdir -p $VTOY_PATH/rpm + cd $VTOY_PATH/rpm + vtlog "extract rpm..." + $BUSYBOX_PATH/rpm2cpio /tmp/xxx.rpm | $BUSYBOX_PATH/cpio -idm 2>>$VTLOG + cd $CURPWD + + $BUSYBOX_PATH/rm -f /tmp/xxx.rpm +} + +install_rpm_from_line() { + vtlog "install_rpm_from_line $1 disk=#$2#" + + if ! [ -b "$2" ]; then + vterr "disk #$2# not exist" + return + fi + + sector=$(echo $1 | $AWK '{print $(NF-1)}') + length=$(echo $1 | $AWK '{print $NF}') + vtlog "sector=$sector length=$length" + + $VTOY_PATH/tool/vtoydm -e -f $VTOY_PATH/ventoy_image_map -d ${2} -s $sector -l $length -o /tmp/xxx.rpm + if [ -e /tmp/xxx.rpm ]; then + vtlog "extract rpm file from iso success" + else + vterr "extract rpm file from iso fail" + return + fi + + CURPWD=$($BUSYBOX_PATH/pwd) + + cd / + vtlog "install rpm..." + $BUSYBOX_PATH/rpm2cpio /tmp/xxx.rpm | $BUSYBOX_PATH/cpio -idm 2>>$VTLOG + cd $CURPWD + + $BUSYBOX_PATH/rm -f /tmp/xxx.rpm +} + +dump_whole_iso_file() { + $VTOY_PATH/tool/vtoydm -p -f $VTOY_PATH/ventoy_image_map -d $usb_disk | while read vtline; do + vtlog "dmtable line: $vtline" + vtcount=$(echo $vtline | $AWK '{print $2}') + vtoffset=$(echo $vtline | $AWK '{print $NF}') + $BUSYBOX_PATH/dd if=$usb_disk of="$1" bs=512 count=$vtcount skip=$vtoffset oflag=append conv=notrunc + done +} + +ventoy_copy_device_mapper() { + if [ -L $VTOY_DM_PATH ]; then + vtlog "replace block device link $1..." + $BUSYBOX_PATH/mv "$1" $VTOY_PATH/dev_backup_${1#/dev/} + VT_MAPPER_LINK=$($BUSYBOX_PATH/readlink $VTOY_DM_PATH) + $BUSYBOX_PATH/cp -a "/dev/mapper/$VT_MAPPER_LINK" "$1" + elif [ -b $VTOY_DM_PATH ]; then + vtlog "replace block device $1..." + $BUSYBOX_PATH/mv "$1" $VTOY_PATH/dev_backup_${1#/dev/} + $BUSYBOX_PATH/cp -a "$VTOY_DM_PATH" "$1" + else + + vtlog "$VTOY_DM_PATH not exist, now check /dev/dm-X ..." + VT_DM_BIN=$(ventoy_find_bin_path dmsetup) + if [ -z "$VT_DM_BIN" ]; then + vtlog "no dmsetup avaliable, lastly try inbox dmsetup" + VT_DM_BIN=$VTOY_PATH/tool/dmsetup + fi + + DM_VT_ID=$($VT_DM_BIN ls | $GREP ventoy | $SED 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') + vtlog "DM_VT_ID=$DM_VT_ID ..." + $BUSYBOX_PATH/mv "$1" $VTOY_PATH/dev_backup_${1#/dev/} + $BUSYBOX_PATH/mknod -m 0666 "$1" b $DM_VT_ID + fi +} + +# create link for device-mapper +ventoy_create_persistent_link() { + blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep vtoy_persistent | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') + vtDM=$(ventoy_find_dm_id ${blkdev_num}) + + if ! [ -d /dev/disk/by-label ]; then + mkdir -p /dev/disk/by-label + fi + + VTLABEL=$($BUSYBOX_PATH/blkid /dev/$vtDM | $SED 's/.*LABEL="\([^"]*\)".*/\1/') + if [ -z "$VTLABEL" ]; then + VTLABEL=casper-rw + fi + + vtlog "Persistent Label: ##${VTLABEL}##" + + if ! [ -e /dev/disk/by-label/$VTLABEL ]; then + vtOldDir=$PWD + cd /dev/disk/by-label + ln -s ../../$vtDM $VTLABEL + cd $vtOldDir + fi +} + +ventoy_partname_to_diskname() { + if echo $1 | $EGREP -q "nvme.*p[0-9]$|mmc.*p[0-9]$|nbd.*p[0-9]$"; then + echo -n "${1:0:-2}" + else + echo -n "${1:0:-1}" + fi +} + +ventoy_diskname_to_partname() { + if echo $1 | $EGREP -q "nvme.*p[0-9]$|mmc.*p[0-9]$|nbd.*p[0-9]$"; then + echo -n "${1}p$2" + else + echo -n "${1}$2" + fi +} + +ventoy_udev_disk_common_hook() { + if echo $1 | $EGREP -q "nvme.*p[0-9]$|mmc.*p[0-9]$|nbd.*p[0-9]$"; then + VTDISK="${1:0:-2}" + else + VTDISK="${1:0:-1}" + fi + + if [ -e /vtoy/vtoy ]; then + VTRWMOD="" + else + VTRWMOD="--readonly" + fi + + # create device mapper for iso image file + if create_ventoy_device_mapper "/dev/$VTDISK" $VTRWMOD; then + vtlog "==== create ventoy device mapper success ====" + else + vtlog "==== create ventoy device mapper failed ====" + + $SLEEP 3 + + if $GREP -q "/dev/$VTDISK" /proc/mounts; then + $GREP "/dev/$VTDISK" /proc/mounts | while read vtLine; do + vtPart=$(echo $vtLine | $AWK '{print $1}') + vtMnt=$(echo $vtLine | $AWK '{print $2}') + vtlog "$vtPart is mounted on $vtMnt now umount it ..." + $BUSYBOX_PATH/umount $vtMnt + done + fi + + if create_ventoy_device_mapper "/dev/$VTDISK" $VTRWMOD; then + vtlog "==== create ventoy device mapper success after retry ====" + else + vtlog "==== create ventoy device mapper failed after retry ====" + return + fi + fi + + if [ "$2" = "noreplace" ]; then + vtlog "no need to replace block device" + else + ventoy_copy_device_mapper "/dev/$1" + fi + + if [ -f $VTOY_PATH/ventoy_persistent_map ]; then + create_persistent_device_mapper "/dev/$VTDISK" + ventoy_create_persistent_link + fi +} + +ventoy_create_dev_ventoy_part() { + blkdev_num=$($VTOY_PATH/tool/dmsetup ls | $GREP ventoy | $SED 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') + $BUSYBOX_PATH/mknod -m 0666 /dev/ventoy b $blkdev_num + + if [ -e /vtoy_dm_table ]; then + vtPartid=1 + $CAT /vtoy_dm_table | while read vtline; do + echo $vtline > /ventoy/dm_table_part${vtPartid} + $VTOY_PATH/tool/dmsetup create ventoy${vtPartid} /ventoy/dm_table_part${vtPartid} + + blkdev_num=$($VTOY_PATH/tool/dmsetup ls | $GREP ventoy${vtPartid} | $SED 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') + $BUSYBOX_PATH/mknod -m 0666 /dev/ventoy${vtPartid} b $blkdev_num + + vtPartid=$(expr $vtPartid + 1) + done + fi +} + + +ventoy_create_chromeos_ventoy_part() { + blkdev_num=$($VTOY_PATH/tool/dmsetup ls | $GREP ventoy | $SED 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') + $BUSYBOX_PATH/mknod -m 0666 /dev/ventoy b $blkdev_num + + if [ -e /vtoy_dm_table ]; then + vtPartid=1 + + $CAT /vtoy_dm_table | while read vtline; do + echo $vtline > /ventoy/dm_table_part${vtPartid} + + if [ $vtPartid -eq $1 ]; then + $VTOY_PATH/tool/dmsetup create ventoy${vtPartid} /ventoy/dm_table_part${vtPartid} --readonly + else + $VTOY_PATH/tool/dmsetup create ventoy${vtPartid} /ventoy/dm_table_part${vtPartid} + fi + + blkdev_num=$($VTOY_PATH/tool/dmsetup ls | $GREP ventoy${vtPartid} | $SED 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') + $BUSYBOX_PATH/mknod -m 0666 /dev/ventoy${vtPartid} b $blkdev_num + + vtPartid=$(expr $vtPartid + 1) + done + fi +} + +is_inotify_ventoy_part() { + if echo $1 | $GREP -q "2$"; then + if ! [ -e /sys/block/$1 ]; then + if [ -e /sys/class/block/$1 ]; then + if echo $1 | $EGREP -q "nvme|mmc|nbd"; then + vtShortName=${1:0:-2} + else + vtShortName=${1:0:-1} + fi + + if [ -e /dev/$vtShortName ]; then + if [ "$VTOY_VLNK_BOOT" = "01" ]; then + vtOrgDiskName=$($VTOY_PATH/tool/vtoydump -t $VTOY_PATH/ventoy_os_param) + [ "$vtOrgDiskName" = "/dev/$vtShortName" ] + else + $VTOY_PATH/tool/vtoydump -f $VTOY_PATH/ventoy_os_param -c $vtShortName + fi + return + fi + fi + fi + fi + + [ "1" = "0" ] +} + +ventoy_find_dm_id() { + for vt in $($BUSYBOX_PATH/ls /sys/block/); do + if [ "${vt:0:3}" = "dm-" ]; then + vtMajorMinor=$($CAT /sys/block/$vt/dev) + if [ "$vtMajorMinor" = "$1" ]; then + echo ${vt} + return + fi + fi + done + echo 'xx' +} + +ventoy_swap_device() { + mv $1 $VTOY_PATH/swap_tmp_dev + mv $2 $1 + mv $VTOY_PATH/swap_tmp_dev $2 +} + +ventoy_extract_vtloopex() { + vtCurPwd=$PWD + $BUSYBOX_PATH/mkdir -p $VTOY_PATH/partmnt $VTOY_PATH/vtloopex + $BUSYBOX_PATH/mount -o ro -t vfat $1 $VTOY_PATH/partmnt + cd $VTOY_PATH/vtloopex + $CAT $VTOY_PATH/partmnt/ventoy/vtloopex.cpio | $BUSYBOX_PATH/cpio -idm >> $VTLOG 2>&1 + $BUSYBOX_PATH/umount $VTOY_PATH/partmnt + $BUSYBOX_PATH/rm -rf $VTOY_PATH/partmnt + + if [ -n "$2" ]; then + cd $VTOY_PATH/vtloopex/$2/ + $BUSYBOX_PATH/tar -xJf vtloopex.tar.xz + fi + + cd $vtCurPwd +} + +ventoy_check_install_module_xz() { + if [ -f "${1}.xz" ]; then + $BUSYBOX_PATH/xz -d "${1}.xz" + $BUSYBOX_PATH/insmod "$1" + fi +} + +ventoy_check_umount() { + for vtLoop in 0 1 2 3 4 5 6 7 8 9; do + $BUSYBOX_PATH/umount "$1" > /dev/null 2>&1 + if $BUSYBOX_PATH/mountpoint -q "$1"; then + $SLEEP 1 + else + break + fi + done +} + +ventoy_wait_dir() { + vtdir=$1 + vtsec=0 + + while [ $vtsec -lt $2 ]; do + if [ -d "$vtdir" ]; then + break + else + $SLEEP 1 + vtsec=$(expr $vtsec + 1) + fi + done +} diff --git a/IMG/cpio/ventoy/hook/ventoy-os-lib.sh b/IMG/cpio/ventoy/hook/ventoy-os-lib.sh new file mode 100644 index 0000000..a52cd74 --- /dev/null +++ b/IMG/cpio/ventoy/hook/ventoy-os-lib.sh @@ -0,0 +1,173 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +VT_RULE_DIR_PREFIX="" +VT_PRINTK_LEVEL=0 +VT_UDEV_RULE_FILE_NAME="99-ventoy.rules" +VT_UDEV_RULE_PREFIX="ACTION==\"add\", SUBSYSTEM==\"block\"," + +ventoy_close_printk() { + VT_PRINTK_LEVEL=$($CAT /proc/sys/kernel/printk | $AWK '{print $1}') + if [ -e /proc/sys/kernel/printk ]; then + echo 0 > /proc/sys/kernel/printk + fi +} + +ventoy_restore_printk() { + if [ -e /proc/sys/kernel/printk ]; then + echo $VT_PRINTK_LEVEL > /proc/sys/kernel/printk + fi +} + +ventoy_set_rule_dir_prefix() { + VT_RULE_DIR_PREFIX=$1 +} + +ventoy_get_udev_conf_dir() { + if [ -d $VT_RULE_DIR_PREFIX/etc/udev/rules.d ]; then + VT_RULE_PATH=$VT_RULE_DIR_PREFIX/etc/udev/rules.d + elif [ -d $VT_RULE_DIR_PREFIX/lib/udev/rules.d ]; then + VT_RULE_PATH=$VT_RULE_DIR_PREFIX/lib/udev/rules.d + else + $BUSYBOX_PATH/mkdir -p $VT_RULE_DIR_PREFIX/etc/udev/rules.d + VT_RULE_PATH=$VT_RULE_DIR_PREFIX/etc/udev/rules.d + fi + echo -n "$VT_RULE_PATH" +} + +ventoy_get_udev_conf_path() { + VT_RULE_DIR=$(ventoy_get_udev_conf_dir) + echo "$VT_RULE_DIR/$VT_UDEV_RULE_FILE_NAME" +} + +ventoy_add_kernel_udev_rule() { + VT_UDEV_RULE_PATH=$(ventoy_get_udev_conf_path) + echo "KERNEL==\"$1\", $VT_UDEV_RULE_PREFIX RUN+=\"$2\"" >> $VT_UDEV_RULE_PATH +} + +ventoy_add_udev_rule_with_name() { + VT_UDEV_RULE_DIR=$(ventoy_get_udev_conf_dir) + echo "KERNEL==\"*2\", $VT_UDEV_RULE_PREFIX RUN+=\"$1\"" >> $VT_UDEV_RULE_DIR/$2 +} + +ventoy_add_udev_rule_with_path() { + echo "KERNEL==\"*2\", $VT_UDEV_RULE_PREFIX RUN+=\"$1\"" >> $2 +} + +ventoy_add_udev_rule() { + VT_UDEV_RULE_PATH=$(ventoy_get_udev_conf_path) + echo "KERNEL==\"*2\", $VT_UDEV_RULE_PREFIX RUN+=\"$1\"" >> $VT_UDEV_RULE_PATH +} + +# +# It seems there is a bug in somw version of systemd-udevd +# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=869719 +# +ventoy_systemd_udevd_work_around() { + for vtdir in 'lib' 'usr/lib'; do + + VTSYSTEMUDEV="$VT_RULE_DIR_PREFIX/$vtdir/systemd/system/systemd-udevd.service" + if [ -e $VTSYSTEMUDEV ]; then + if $GREP -q 'SystemCallArchitectures.*native' $VTSYSTEMUDEV; then + $SED "s/.*\(SystemCallArchitectures.*native\)/#\1/g" -i $VTSYSTEMUDEV + break + fi + fi + done +} + + +ventoy_print_yum_repo() { + echo "[$1]" + echo "name=$1" + echo "baseurl=$2" + echo "enabled=1" + echo "gpgcheck=0" + echo "priority=0" +} + +ventoy_set_inotify_script() { + echo $VTOY_PATH/hook/$1 > $VTOY_PATH/inotifyd-hook-script.txt +} + +ventoy_set_loop_inotify_script() { + echo $VTOY_PATH/loop/$1 > $VTOY_PATH/inotifyd-loop-script.txt +} + +ventoy_check_insmod() { + if [ -e $1 ]; then + $BUSYBOX_PATH/insmod $1 + fi +} + +ventoy_check_mount() { + if [ -e $1 ]; then + $BUSYBOX_PATH/mount $1 $2 + fi +} + +ventoy_has_exfat_ko() { + vtExfat='' + vtKerVer=$($BUSYBOX_PATH/uname -r) + if [ -d /lib/modules/$vtKerVer/kernel/fs/exfat ]; then + vtExfat=$(ls /lib/modules/$vtKerVer/kernel/fs/exfat/) + fi + [ -n "$vtExfat" ] +} + +ventoy_is_exfat_part() { + $VTOY_PATH/tool/vtoydump -s /ventoy/ventoy_os_param | $GREP -q exfat +} + +ventoy_iso_scan_path() { + if [ -f /sbin/iso-scan ]; then + echo -n '/sbin/iso-scan' + elif [ -f /bin/iso-scan ]; then + echo -n '/bin/iso-scan' + else + echo -n '' + fi +} + +ventoy_has_iso_scan() { + vtScanPath=$(ventoy_iso_scan_path) + [ -n "$vtScanPath" ] +} + +ventoy_rw_iso_scan() { + vtScanPath=$(ventoy_iso_scan_path) + if [ -n "$vtScanPath" ]; then + if $GREP -q 'mount.* ro .*isoscan' $vtScanPath; then + $SED -i 's/\(mount.*-o.*\) ro /\1 rw /' $vtScanPath + fi + fi +} + +ventoy_iso_scan_check() { + vtCheckOk=0 + if ventoy_is_exfat_part; then + if ventoy_has_exfat_ko; then + if ventoy_has_iso_scan; then + vtCheckOk=1 + fi + fi + fi + + [ $vtCheckOk -eq 1 ] +} diff --git a/IMG/cpio/ventoy/hook/vine/dev-listen.sh b/IMG/cpio/ventoy/hook/vine/dev-listen.sh new file mode 100644 index 0000000..a358fc1 --- /dev/null +++ b/IMG/cpio/ventoy/hook/vine/dev-listen.sh @@ -0,0 +1,63 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vine_wait_for_exist() { + while [ -n "1" ]; do + if [ -e $1 ]; then + break + else + $SLEEP 0.5 + fi + done +} + +vine_wait_for_exist /dev/null +vine_wait_for_exist /sys/block +vine_wait_for_exist /proc/ide + + +while [ -n "Y" ]; do + vtdiskname=$(get_ventoy_disk_name) + if [ "$vtdiskname" != "unknown" ]; then + break + else + $SLEEP 0.5 + fi +done + +vtshortdev=${vtdiskname#/dev/} + +if ! [ -b $vtdiskname ]; then + blkdev=$($CAT /sys/class/block/$vtshortdev/dev | $SED 's/:/ /g') + $BUSYBOX_PATH/mknod -m 0660 $vtdiskname b $blkdev +fi + +if ! [ -b "${vtdiskname}1" ]; then + blkdev=$($CAT /sys/class/block/${vtshortdev}1/dev | $SED 's/:/ /g') + $BUSYBOX_PATH/mknod -m 0660 "${vtdiskname}1" b $blkdev +fi + +if ! [ -b "${vtdiskname}2" ]; then + blkdev=$($CAT /sys/class/block/${vtshortdev}2/dev | $SED 's/:/ /g') + $BUSYBOX_PATH/mknod -m 0660 "${vtdiskname}2" b $blkdev +fi + +$BUSYBOX_PATH/sh $VTOY_PATH/hook/vine/udev_disk_hook.sh "${vtdiskname#/dev/}2" diff --git a/IMG/cpio/ventoy/hook/vine/udev_disk_hook.sh b/IMG/cpio/ventoy/hook/vine/udev_disk_hook.sh new file mode 100644 index 0000000..1ea6d67 --- /dev/null +++ b/IMG/cpio/ventoy/hook/vine/udev_disk_hook.sh @@ -0,0 +1,95 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +ventoy_os_install_dmsetup_by_ko() { + vtlog "ventoy_os_install_dmsetup_by_ko $1" + + vtVer=$($BUSYBOX_PATH/uname -r) + if $BUSYBOX_PATH/uname -m | $GREP -q 64; then + vtBit=64 + else + vtBit=32 + fi + + ventoy_extract_vtloopex $1 vine + vtLoopExDir=$VTOY_PATH/vtloopex/vine/vtloopex + + if [ -e $vtLoopExDir/dm-mod/$vtVer/$vtBit/dm-mod.ko.xz ]; then + $BUSYBOX_PATH/xz -d $vtLoopExDir/dm-mod/$vtVer/$vtBit/dm-mod.ko.xz + insmod $vtLoopExDir/dm-mod/$vtVer/$vtBit/dm-mod.ko + fi +} + +ventoy_os_install_dmsetup_by_rpm() { + vtlog "ventoy_os_install_dmsetup_by_rpm $1" + + vt_usb_disk=$1 + + # dump iso file location + $VTOY_PATH/tool/vtoydm -i -f $VTOY_PATH/ventoy_image_map -d ${vt_usb_disk} > $VTOY_PATH/iso_file_list + + # install dmsetup + LINE=$($GREP 'kernel-[0-9].*\.rpm' $VTOY_PATH/iso_file_list) + if [ $? -eq 0 ]; then + extract_rpm_from_line "$LINE" ${vt_usb_disk} + fi + + vtKoName=$($BUSYBOX_PATH/find $VTOY_PATH/rpm/ -name dm-mod.ko*) + vtlog "vtKoName=$vtKoName" + + insmod $vtKoName + + $BUSYBOX_PATH/rm -rf $VTOY_PATH/rpm/ +} + +if is_ventoy_hook_finished || not_ventoy_disk "${1:0:-1}"; then + exit 0 +fi + +ventoy_os_install_dmsetup_by_ko "/dev/$1" +if $GREP -q 'device.mapper' /proc/devices; then + vtlog "device-mapper module install OK" +else + ventoy_os_install_dmsetup_by_rpm "/dev/${1:0:-1}" +fi + +ventoy_udev_disk_common_hook $* + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | $GREP ventoy | $SED 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +blkdev_num_dev=$($VTOY_PATH/tool/dmsetup ls | $GREP ventoy | $SED 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) + +[ -b /dev/$vtDM ] || $BUSYBOX_PATH/mknod -m 0660 /dev/$vtDM b $blkdev_num_dev +$BUSYBOX_PATH/rm -rf /dev/mapper + +#Create a fake IDE-CDROM driver can't be ide-scsi /proc has been patched to /vtoy +$BUSYBOX_PATH/mkdir -p /vtoy +$BUSYBOX_PATH/cp -a /proc/ide /vtoy/ +$BUSYBOX_PATH/mkdir -p /vtoy/ide/aztcd + +echo 'ide' > /vtoy/ide/aztcd/driver +echo 'cdrom' > /vtoy/ide/aztcd/media + + +# OK finish +set_ventoy_hook_finish + +exit 0 diff --git a/IMG/cpio/ventoy/hook/vine/ventoy-hook.sh b/IMG/cpio/ventoy/hook/vine/ventoy-hook.sh new file mode 100644 index 0000000..d10c2ea --- /dev/null +++ b/IMG/cpio/ventoy/hook/vine/ventoy-hook.sh @@ -0,0 +1,26 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$BUSYBOX_PATH/cp -a /sbin/loader /sbin/loader_bk +$VTOY_PATH/tool/vine_patch_loader /sbin/loader 253 -v >> $VTLOG + +$BUSYBOX_PATH/mknod -m 0660 /dev/null c 1 3 +$VTOY_PATH/hook/vine/dev-listen.sh & diff --git a/IMG/cpio/ventoy/hook/wifislax/disk_hook.sh b/IMG/cpio/ventoy/hook/wifislax/disk_hook.sh new file mode 100644 index 0000000..274d692 --- /dev/null +++ b/IMG/cpio/ventoy/hook/wifislax/disk_hook.sh @@ -0,0 +1,51 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +vtlog "##### $0 $* #####" + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +while true; do + if blkid | grep -q '/dev/dm'; then + vtlog 'Find /dev/dm ...' + break + else + vtlog 'Wait /dev/dm ...' + sleep 0.3 + fi +done + + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/wifislax/ventoy-hook.sh b/IMG/cpio/ventoy/hook/wifislax/ventoy-hook.sh new file mode 100644 index 0000000..cc0be88 --- /dev/null +++ b/IMG/cpio/ventoy/hook/wifislax/ventoy-hook.sh @@ -0,0 +1,32 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +if [ -e /linuxrc ]; then + INITFILE=/linuxrc +elif [ -e /init ]; then + INITFILE=/init +fi + +$SED "/mount.*devtmpfs/a $BUSYBOX_PATH/sh $VTOY_PATH/hook/wifislax/disk_hook.sh" -i $INITFILE + +#replace original blkid +$BUSYBOX_PATH/rm -f /usr/bin/blkid +$BUSYBOX_PATH/cp -a $BUSYBOX_PATH/blkid /usr/bin/blkid diff --git a/IMG/cpio/ventoy/hook/xen/udev_disk_hook.sh b/IMG/cpio/ventoy/hook/xen/udev_disk_hook.sh new file mode 100644 index 0000000..b25c1fb --- /dev/null +++ b/IMG/cpio/ventoy/hook/xen/udev_disk_hook.sh @@ -0,0 +1,32 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished || not_ventoy_disk "${1:0:-1}"; then + exit 0 +fi + +ventoy_udev_disk_common_hook $* + +# trick for xen6 +ventoy_copy_device_mapper /dev/sr7 + +# OK finish +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/xen/ventoy-hook.sh b/IMG/cpio/ventoy/hook/xen/ventoy-hook.sh new file mode 100644 index 0000000..1260ce1 --- /dev/null +++ b/IMG/cpio/ventoy/hook/xen/ventoy-hook.sh @@ -0,0 +1,24 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +ventoy_systemd_udevd_work_around + +ventoy_add_udev_rule "$VTOY_PATH/hook/xen/udev_disk_hook.sh %k" diff --git a/IMG/cpio/ventoy/hook/zeroshell/disk_hook.sh b/IMG/cpio/ventoy/hook/zeroshell/disk_hook.sh new file mode 100644 index 0000000..00304f6 --- /dev/null +++ b/IMG/cpio/ventoy/hook/zeroshell/disk_hook.sh @@ -0,0 +1,45 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +if ! [ -e $VTOY_DM_PATH ]; then + blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') + mknod -m 0666 $VTOY_DM_PATH b $blkdev_num +fi + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/zeroshell/ventoy-hook.sh b/IMG/cpio/ventoy/hook/zeroshell/ventoy-hook.sh new file mode 100644 index 0000000..e08252d --- /dev/null +++ b/IMG/cpio/ventoy/hook/zeroshell/ventoy-hook.sh @@ -0,0 +1,24 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + + +$SED "/while.*\$device/i\ device=/dev/mapper/ventoy" -i /init +$SED "/while.*\$device/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/zeroshell/disk_hook.sh" -i /init diff --git a/IMG/cpio/ventoy/init b/IMG/cpio/ventoy/init new file mode 100644 index 0000000..b1040bc --- /dev/null +++ b/IMG/cpio/ventoy/init @@ -0,0 +1,64 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + + +################################################################### +# # +# Step 1 : parse kernel debug parameter # +# # +#################################################################### + +if ! [ -d /proc ]; then + mkdir /proc + vtrmproc='Y' +fi + +mount -t proc proc /proc +export vtcmdline=$(cat /proc/cmdline) +export vtkerver=$(cat /proc/version) +umount /proc; + +if [ "$vtrmproc" = "Y" ]; then + rm -rf /proc +fi + +echo "kenel version=$vtkerver" >>$VTLOG +echo "kenel cmdline=$vtcmdline" >>$VTLOG + +#break here for debug +if [ "$VTOY_BREAK_LEVEL" = "01" ] || [ "$VTOY_BREAK_LEVEL" = "11" ]; then + sleep 5 + echo -e "\n\n\033[32m ################################################# \033[0m" + echo -e "\033[32m ################ VENTOY DEBUG ################### \033[0m" + echo -e "\033[32m ################################################# \033[0m \n" + + if [ "$VTOY_BREAK_LEVEL" = "11" ]; then + cat $VTLOG + fi + exec $BUSYBOX_PATH/sh +fi + +if echo $vtcmdline | grep -q 'rdinit=/vtoy/vtoy'; then + echo "handover to init_loop" >>$VTLOG + rm -f /xxxx /vtoyxrc + exec $BUSYBOX_PATH/sh $VTOY_PATH/init_loop +else + echo "handover to init_chain" >>$VTLOG + exec $BUSYBOX_PATH/sh $VTOY_PATH/init_chain +fi diff --git a/IMG/cpio/ventoy/init_chain b/IMG/cpio/ventoy/init_chain new file mode 100644 index 0000000..6034370 --- /dev/null +++ b/IMG/cpio/ventoy/init_chain @@ -0,0 +1,238 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + + +#################################################################### +# # +# Step 1 : extract real initramfs to / # +# # +#################################################################### +cd / +rm -rf /init /linuxrc /dev/ /root + +vtSbinFileNum=$(ls -1 /sbin | wc -l) +if [ $vtSbinFileNum -eq 1 ]; then + echo "remove whole sbin directory" >> $VTLOG + rm -rf /sbin +else + echo "remove only sbin/init file" >> $VTLOG + ls -l /sbin >> $VTLOG + rm -f /sbin/init +fi + +ventoy_is_initrd_ramdisk() { + #As I known, PCLinuxOS/smgl use ramdisk + if echo $vtkerver | grep -i -q 'PCLinuxOS'; then + true + elif echo $vtkerver | grep -i -q 'SMGL-'; then + true + else + false + fi +} + +ventoy_mount_squashfs() { + mkdir /dev + mount -t devtmpfs devtmpfs /dev + dd if=$1 of=/dev/ram0 status=none + umount /dev && rm -rf /dev +} + +# param: file skip magic tmp +ventoy_unpack_initramfs() { + vtfile=$1; vtskip=$2; vtmagic=$3; vttmp=$4 + echo "=====ventoy_unpack_initramfs: #$*#" >> $VTLOG + + #special process + #if [ "${vtmagic:0:4}" = '5678' ]; then + # echo -en '\x1F\x8B' | dd status=none of=$vtfile bs=1 count=2 conv=notrunc + # vtmagic='1F8B' + #fi + + if [ "${vtmagic:0:4}" = '6873' ]; then + ventoy_mount_squashfs $vtfile + return + fi + + for vtx in '1F8B zcat' '1F9E zcat' '425A bzcat' '5D00 lzcat' 'FD37 xzcat' '894C lzopcat' '0221 lz4cat' '28B5 zstdcat' '3037 cat' '4C5A lunzip -c'; do + if [ "${vtx:0:4}" = "${vtmagic:0:4}" ]; then + echo "vtx=$vtx" >> $VTLOG + if [ $vtskip -ne 0 ]; then + dd if=$vtfile skip=$vtskip iflag=skip_bytes status=none > ${vtfile}.skip + rm -f $vtfile + mv ${vtfile}.skip $vtfile + fi + + if [ "${vtx:5}" = "xzcat" ]; then + rm -f $VTOY_PATH/xzlog + ${vtx:5} $vtfile 2> $VTOY_PATH/xzlog | (cpio -idmu 2>>$VTLOG; cat > $vttmp) + if grep -q 'corrupted data' $VTOY_PATH/xzlog; then + echo 'xzcat failed, now try xzminidec...' >> $VTLOG + rm -f $VTOY_PATH/xzlog + cat $vtfile | xzminidec 2> $VTOY_PATH/xzlog | (cpio -idmu 2>>$VTLOG; cat > $vttmp) + + if grep -q 'limit' $VTOY_PATH/xzlog; then + echo 'xzminidec failed, now try xzcat_musl ...' >> $VTLOG + xzcat_musl $vtfile | (cpio -idmu 2>>$VTLOG; cat > $vttmp) + fi + fi + else + ${vtx:5} $vtfile | (cpio -idmu 2>>$VTLOG; cat > $vttmp) + fi + break + fi + done +} + +# param: file magic tmp +ventoy_unpack_initrd() { + vtfile=$1; vtmagic=$2; vttmp=$3 + echo "=====ventoy_unpack_initrd: #$*#" >> $VTLOG + + for vtx in '1F8B zcat' '1F9E zcat' '425A bzcat' '5D00 lzcat' 'FD37 xzcat' '894C lzopcat' '0221 lz4cat' '28B5 zstdcat' '3037 cat'; do + if [ "${vtx:0:4}" = "${vtmagic:0:4}" ]; then + echo "vtx=$vtx" >> $VTLOG + ${vtx:5} $vtfile > $vttmp + break + fi + done +} + +vtfile_head_zero() { + local vsize + local voffset + local vfile + local vzero + local vdump + + voffset=0 + vfile=$1 + vsize=$(stat -c '%s' ${vfile}) + vzero=$(hexdump -n 512 -e '512/1 "%02X"' $vfile) + + while [ $voffset -lt $vsize ]; do + vdump=$(hexdump -s $voffset -n 512 -e '512/1 "%02X"' $vfile) + if [ "$vdump" != "$vzero" ]; then + echo $voffset + return + fi + voffset=$($BUSYBOX_PATH/expr $voffset + 512) + done + echo 0 +} + +# This export is for busybox cpio command +export EXTRACT_UNSAFE_SYMLINKS=1 + +for vtfile in $(ls /initrd*); do + #decompress first initrd + vtmagic=$(hexdump -n 2 -e '2/1 "%02X"' $vtfile) + + if ventoy_is_initrd_ramdisk; then + ventoy_unpack_initrd $vtfile $vtmagic ${vtfile}_tmp + mv ${vtfile}_tmp $vtfile + break + else + ventoy_unpack_initramfs $vtfile 0 $vtmagic ${vtfile}_tmp + fi + + #only for cpio,cpio,...,initrd sequence, initrd,cpio or initrd,initrd sequence is not supported + while [ -e ${vtfile}_tmp ] && [ $(stat -c '%s' ${vtfile}_tmp) -gt 512 ]; do + mv ${vtfile}_tmp $vtfile + + vtdump=$(hexdump -n 512 -e '512/1 "%02X"' $vtfile) + vtmagic=$(echo $vtdump | sed 's/^\(00\)*//') + let vtoffset="(${#vtdump}-${#vtmagic})/2" + + if [ -z "$vtmagic" ]; then + vtHeadZero=$(vtfile_head_zero $vtfile) + if [ $vtHeadZero -gt 0 ]; then + vtdump=$(hexdump -s $vtHeadZero -n 512 -e '512/1 "%02X"' $vtfile) + vtmagic=$(echo $vtdump | sed 's/^\(00\)*//') + let vtoffset="(${#vtdump}-${#vtmagic})/2+$vtHeadZero" + echo "skip head $vtHeadZero zeros with magic ${vtmagic:0:4}" >> $VTLOG + else + echo "terminate with all zero data file" >> $VTLOG + break + fi + fi + + ventoy_unpack_initramfs $vtfile $vtoffset ${vtmagic:0:4} ${vtfile}_tmp + done + + rm -f $vtfile ${vtfile}_tmp +done + + +#break here for debug +if [ "$VTOY_BREAK_LEVEL" = "02" ] || [ "$VTOY_BREAK_LEVEL" = "12" ]; then + sleep 5 + echo -e "\n\n\033[32m ################################################# \033[0m" + echo -e "\033[32m ################ VENTOY DEBUG ################### \033[0m" + echo -e "\033[32m ################################################# \033[0m \n" + if [ "$VTOY_BREAK_LEVEL" = "12" ]; then + cat $VTOY_PATH/log + fi + exec $BUSYBOX_PATH/sh +fi + + +#################################################################### +# # +# Step 3 : Extract injection archive # +# # +#################################################################### +ventoy_unpack_injection() { + vtmagic=$(hexdump -n 2 -e '2/1 "%02X"' $VTOY_PATH/ventoy_injection) + echo "ventoy_unpack_injection vtmagic=$vtmagic ..." + + if [ "1F8B" = "$vtmagic" ] || [ "1F9E" = "$vtmagic" ]; then + echo "tar.gz tar -xzvf" + tar -xzvf $VTOY_PATH/ventoy_injection -C / + elif [ "425A" = "$vtmagic" ]; then + echo "tar.bz2 tar -xjvf" + tar -xjvf $VTOY_PATH/ventoy_injection -C / + elif [ "FD37" = "$vtmagic" ]; then + echo "tar.xz tar -xJvf" + tar -xJvf $VTOY_PATH/ventoy_injection -C / + elif [ "5D00" = "$vtmagic" ]; then + echo "tar.lzma tar -xavf" + tar -xavf $VTOY_PATH/ventoy_injection -C / + else + echo "unzip -o" + unzip -o $VTOY_PATH/ventoy_injection -d / + fi +} + +if [ -e $VTOY_PATH/ventoy_injection ]; then + echo "### decompress injection ... ###" >>$VTLOG + ventoy_unpack_injection > $VTOY_PATH/injection.log 2>&1 +fi + + +#################################################################### +# # +# Step 4 : Hand over to ventoy_chain.sh # +# # +#################################################################### +echo "Now hand over to ventoy.sh" >>$VTLOG +. $VTOY_PATH/tool/vtoytool_install.sh + +export PATH=$VTOY_ORG_PATH +exec $BUSYBOX_PATH/sh $VTOY_PATH/ventoy_chain.sh diff --git a/IMG/cpio/ventoy/init_loop b/IMG/cpio/ventoy/init_loop new file mode 100644 index 0000000..9288633 --- /dev/null +++ b/IMG/cpio/ventoy/init_loop @@ -0,0 +1,63 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + + +#################################################################### +# # +# Step 1 : Extract injection archive # +# # +#################################################################### +ventoy_unpack_injection() { + vtmagic=$(hexdump -n 2 -e '2/1 "%02X"' $VTOY_PATH/ventoy_injection) + echo "ventoy_unpack_injection vtmagic=$vtmagic ..." + + if [ "1F8B" = "$vtmagic" ] || [ "1F9E" = "$vtmagic" ]; then + echo "tar.gz tar -xzvf" + tar -xzvf $VTOY_PATH/ventoy_injection -C / + elif [ "425A" = "$vtmagic" ]; then + echo "tar.bz2 tar -xjvf" + tar -xjvf $VTOY_PATH/ventoy_injection -C / + elif [ "FD37" = "$vtmagic" ]; then + echo "tar.xz tar -xJvf" + tar -xJvf $VTOY_PATH/ventoy_injection -C / + elif [ "5D00" = "$vtmagic" ]; then + echo "tar.lzma tar -xavf" + tar -xavf $VTOY_PATH/ventoy_injection -C / + else + echo "unzip -o" + unzip -o $VTOY_PATH/ventoy_injection -d / + fi +} + +if [ -e $VTOY_PATH/ventoy_injection ]; then + echo "### decompress injection ... ###" >>$VTLOG + ventoy_unpack_injection > $VTOY_PATH/injection.log 2>&1 +fi + + +#################################################################### +# # +# Step 3 : Hand over to ventoy_loop.sh # +# # +#################################################################### +echo "Now hand over to ventoy.sh" >>$VTLOG +. $VTOY_PATH/tool/vtoytool_install.sh + +export PATH=$VTOY_ORG_PATH +exec $BUSYBOX_PATH/sh $VTOY_PATH/ventoy_loop.sh diff --git a/IMG/cpio/ventoy/loop/LibreELEC/ventoy-disk.sh b/IMG/cpio/ventoy/loop/LibreELEC/ventoy-disk.sh new file mode 100644 index 0000000..8acbb36 --- /dev/null +++ b/IMG/cpio/ventoy/loop/LibreELEC/ventoy-disk.sh @@ -0,0 +1,65 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +vtKerVer=$(uname -r) +if uname -m | grep -q 64; then + vtBit=64 +else + vtBit=32 +fi + +if [ -f $VTOY_PATH/vtloopex/dm-mod/$vtKerVer/$vtBit/dm-mod.ko.xz ]; then + xz -d $VTOY_PATH/vtloopex/dm-mod/$vtKerVer/$vtBit/dm-mod.ko.xz + insmod $VTOY_PATH/vtloopex/dm-mod/$vtKerVer/$vtBit/dm-mod.ko +elif [ -f $VTOY_PATH/modules/dm-mod.ko ]; then + insmod $VTOY_PATH/modules/dm-mod.ko +fi + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +ventoy_create_dev_ventoy_part + +mkdir /ventoy/mnt +mount /dev/ventoy2 /ventoy/mnt +rm -f /ventoy/mnt/.please_resize_me +sync +umount /ventoy/mnt + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/loop/LibreELEC/ventoy-hook.sh b/IMG/cpio/ventoy/loop/LibreELEC/ventoy-hook.sh new file mode 100644 index 0000000..1636632 --- /dev/null +++ b/IMG/cpio/ventoy/loop/LibreELEC/ventoy-hook.sh @@ -0,0 +1,23 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/mount_flash.*{/a\ $BUSYBOX_PATH/sh $VTOY_PATH/loop/LibreELEC/ventoy-disk.sh" -i /init + diff --git a/IMG/cpio/ventoy/loop/batocera/ventoy-disk.sh b/IMG/cpio/ventoy/loop/batocera/ventoy-disk.sh new file mode 100644 index 0000000..6281cc7 --- /dev/null +++ b/IMG/cpio/ventoy/loop/batocera/ventoy-disk.sh @@ -0,0 +1,45 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" +ventoy_create_dev_ventoy_part + + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/loop/batocera/ventoy-hook.sh b/IMG/cpio/ventoy/loop/batocera/ventoy-hook.sh new file mode 100644 index 0000000..2bb7c8e --- /dev/null +++ b/IMG/cpio/ventoy/loop/batocera/ventoy-hook.sh @@ -0,0 +1,23 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/mount.*devtmpfs/a\ $BUSYBOX_PATH/sh $VTOY_PATH/loop/batocera/ventoy-disk.sh" -i /init + diff --git a/IMG/cpio/ventoy/loop/cloudready/ventoy-hook.sh b/IMG/cpio/ventoy/loop/cloudready/ventoy-hook.sh new file mode 100644 index 0000000..666a4e0 --- /dev/null +++ b/IMG/cpio/ventoy/loop/cloudready/ventoy-hook.sh @@ -0,0 +1,205 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2021, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +mkdir /sys +mount -t sysfs sys /sys +mdev -s +sleep 2 + +while [ -n "Y" ]; do + usb_disk=$(get_ventoy_disk_name) + + if echo $usb_disk | egrep -q "nvme|mmc|nbd"; then + vtpart2=${usb_disk}p2 + else + vtpart2=${usb_disk}2 + fi + + if [ -e "${vtpart2}" ]; then + break + else + sleep 2 + mdev -s + fi +done + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) +echo -n $vtDM > /ventoy/vtDM + +ventoy_create_chromeos_ventoy_part 3 +mdev -s + +vtlog "copy out the e2fsck program ..." + +copy_lib() { + cp -a /ventoy_rdroot/usr/lib64/$1 /usr/lib64/ + cp -a /ventoy_rdroot/lib64/$1 /lib64/ +} + +mkdir /ventoy_rdroot +mkdir -p /lib /lib64 /usr/lib64 /sbin + +mount -o ro /dev/ventoy3 /ventoy_rdroot >>$VTLOG 2>&1 +cp -a /ventoy_rdroot/sbin/e2fsck /sbin/ +cp -a /ventoy_rdroot/sbin/dmsetup /sbin/ + +copy_lib libext2fs* +copy_lib libcom_err* +copy_lib libe2p* +copy_lib libblk* +copy_lib libuuid* +copy_lib libdl.* +copy_lib libdl-* +copy_lib libc.* +copy_lib libc-* +copy_lib libpthread* +copy_lib ld-* +copy_lib libdevmapper* +copy_lib libudev* +copy_lib libm.* +copy_lib libm-* +copy_lib librt* +copy_lib libpopt* +copy_lib libgpg-error* +copy_lib libselinux* +copy_lib libsepol* +copy_lib libpcre* +copy_lib libcap* +copy_lib libdw* +copy_lib libgcc_s* +copy_lib libattr* +copy_lib libelf* +copy_lib libz.* +copy_lib libbz2* +copy_lib libgcrypt* +copy_lib liblvm* + +ln -s /lib64/libdevmapper.so.1.02 /lib64/libdevmapper.so.1.02.1 + +umount /ventoy_rdroot + +vtlog "=========================================" +vtlog "===== e2fsck -y -v /dev/ventoy1 =====" +e2fsck -y -v /dev/ventoy1 >>$VTLOG 2>&1 +#vtlog "===== e2fsck -y -v /dev/ventoy3 =====" +#e2fsck -y -v /dev/ventoy3 >>$VTLOG 2>&1 +vtlog "===== e2fsck -y -v /dev/ventoy8 =====" +e2fsck -y -v /dev/ventoy8 >>$VTLOG 2>&1 +vtlog "=========================================" + +/sbin/dmsetup --version >>$VTLOG 2>&1 +veritysetup --version >>$VTLOG 2>&1 + +vtlog "proc devtmpfs ..." +mkdir /newdev +mount -t devtmpfs dev /newdev + +cp -a /dev/mapper/ventoy* /newdev/mapper/ +cp -a /dev/ventoy* /newdev/ + +if [ "$VTOY_VLNK_BOOT" = "01" ]; then + vtLine=$($VTOY_PATH/tool/vtoydump -f /ventoy/ventoy_os_param) + vtdiskname=${vtLine%%#*} +fi + +vtshortname="${vtdiskname#/dev/}" +mv /newdev/${vtshortname} /newdev/backup_${vtshortname} +cp -a /dev/ventoy /newdev/${vtshortname} + +for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do + if [ -e /dev/ventoy${i} ]; then + if echo $vtdiskname | egrep -q "nvme|mmc|nbd"; then + vtpart=p$i + else + vtpart=$i + fi + + if [ -e /newdev/${vtshortname}${vtpart} ]; then + mv /newdev/${vtshortname}${vtpart} /newdev/backup_${vtshortname}${vtpart} + fi + + cp -a /dev/ventoy${i} /newdev/${vtshortname}${vtpart} + + if [ $i -eq 3 ]; then + [ -e /dev/${vtshortname}${vtpart} ] && rm -f /dev/${vtshortname}${vtpart} + cp -a /dev/ventoy${i} /dev/${vtshortname}${vtpart} + vt_root_dev="/dev/${vtshortname}${vtpart}" + vtlog "vt_root_dev=$vt_root_dev" + fi + fi +done + + +# if grep -q 'DM=' /proc/cmdline; then + # vtlog "Boot verified image ..." + + # dmP1=$(sed "s/.*\(0 [0-9]* verity\).*/\1/" /proc/cmdline) + # alg=$(sed "s/.*alg=\([^ ]*\).*/\1/" /proc/cmdline) + # hexdigest=$(sed "s/.*root_hexdigest=\([0-9a-fA-F][0-9a-fA-F]*\).*/\1/" /proc/cmdline) + # salt=$(sed "s/.*salt=\([0-9a-fA-F][0-9a-fA-F]*\).*/\1/" /proc/cmdline) + # hashstart=$(sed "s/.*hashstart=\([0-9][0-9]*\).*/\1/" /proc/cmdline) + + #512 to 4096 + # blocknum=$(expr $hashstart / 8) + # hashoffset=$(expr $hashstart \* 512) + + # vtlog "veritysetup create vroot $vt_root_dev $vt_root_dev $hexdigest --data-block-size=4096 --hash-block-size=4096 --data-blocks=$blocknum --hash-offset=$hashoffset --salt=$salt --hash=$alg --no-superblock --format=0" + # veritysetup create vroot $vt_root_dev $vt_root_dev $hexdigest --data-block-size=4096 --hash-block-size=4096 --data-blocks=$blocknum --hash-offset=$hashoffset --salt=$salt --hash=$alg --no-superblock --format=0 + # sleep 1 + # mdev -s + + # blkdev_num=$(dmsetup ls | grep vroot | sed 's/.*(\([0-9][0-9]*\),[^0-9]*\([0-9][0-9]*\).*/\1:\2/') + # vtDM=$(ventoy_find_dm_id ${blkdev_num}) + # vtlog "blkdev_num=$blkdev_num vtDM=$vtDM" + + # if [ -b /dev/$vtDM ]; then + # veritysetup status vroot >> $VTLOG 2>&1 + # mount -o ro /dev/$vtDM /ventoy_rdroot + # else + # mount -o ro $vt_root_dev /ventoy_rdroot + # fi +# else + # vtlog "Boot normal image ..." + # mount -o ro $vt_root_dev /ventoy_rdroot +# fi + +vtlog "Boot normal image ..." +mount -o ro $vt_root_dev /ventoy_rdroot + +cp -a $VTLOG /newdev/ventoy.log +umount /newdev +mount -t devtmpfs dev /ventoy_rdroot/dev + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/loop/easyos/ventoy-disk.sh b/IMG/cpio/ventoy/loop/easyos/ventoy-disk.sh new file mode 100644 index 0000000..13a9706 --- /dev/null +++ b/IMG/cpio/ventoy/loop/easyos/ventoy-disk.sh @@ -0,0 +1,53 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +[ -f $VTOY_PATH/modules/dax.ko ] && $BUSYBOX_PATH/insmod $VTOY_PATH/modules/dax.ko +[ -f $VTOY_PATH/modules/dm-mod.ko ] && $BUSYBOX_PATH/insmod $VTOY_PATH/modules/dm-mod.ko + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) +echo -n $vtDM > /ventoy/vtDM + +ventoy_create_dev_ventoy_part +mdev -s + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/loop/easyos/ventoy-hook.sh b/IMG/cpio/ventoy/loop/easyos/ventoy-hook.sh new file mode 100644 index 0000000..75eabc6 --- /dev/null +++ b/IMG/cpio/ventoy/loop/easyos/ventoy-hook.sh @@ -0,0 +1,35 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2022, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/find drives/i $BUSYBOX_PATH/sh $VTOY_PATH/loop/easyos/ventoy-disk.sh; vtDM=\$(cat /ventoy/vtDM)" -i /init + +$SED "1a boot_dev=ventoy1;wkg_dev=ventoy2" -i /init + +$SED 's#\(dd *if=/dev/.*WKG_DRV.* *of=/dev/null.*skip\)=[0-9]*#\1=1048576#' -i /init +$SED "s#WKG_DEV=\"\"#WKG_DEV=ventoy2#g" -i /init + +#check for ssd will read /sys/block/ventoy, will no exist, need a workaround +$SED "s#/sys/block/\${WKG_DRV}/#/sys/block/\$vtDM/#g" -i /init + +#resizing process +$SED "s#partprobe.*#$BUSYBOX_PATH/sh $VTOY_PATH/loop/easyos/ventoy-resize.sh \$WKG_DEV#g" -i /init + + diff --git a/IMG/cpio/ventoy/loop/easyos/ventoy-resize.sh b/IMG/cpio/ventoy/loop/easyos/ventoy-resize.sh new file mode 100644 index 0000000..3732e0a --- /dev/null +++ b/IMG/cpio/ventoy/loop/easyos/ventoy-resize.sh @@ -0,0 +1,45 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2022, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM0=$(ventoy_find_dm_id ${blkdev_num}) +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy2 | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM2=$(ventoy_find_dm_id ${blkdev_num}) +vtlog "vtDM0=$vtDM0 vtDM2=$vtDM2" + +vtSize=$(cat /sys/block/$vtDM0/size) +vtSize1=$(sed -n "1p" /vtoy_dm_table | awk '{print $2}') +vtStart1=$(sed -n "1p" /vtoy_dm_table | awk '{print $5}') +vtSize2=$(sed -n "2p" /vtoy_dm_table | awk '{print $2}') +vtNewSize2=$(expr $vtSize - $vtSize1 - $vtStart1) +vtlog "vtSize=$vtSize vtSize1=$vtSize1 vtStart1=$vtStart1 vtSize2=$vtSize2 vtNewSize2=$vtNewSize2" + + +sed -n "2p" /vtoy_dm_table > /ventoy/resize_table +sed -i "s/$vtSize2/$vtNewSize2/" /ventoy/resize_table + +dmsetup remove ventoy2 +dmsetup create ventoy2 /ventoy/resize_table + diff --git a/IMG/cpio/ventoy/loop/endless/ventoy-hook.sh b/IMG/cpio/ventoy/loop/endless/ventoy-hook.sh new file mode 100644 index 0000000..7d0820d --- /dev/null +++ b/IMG/cpio/ventoy/loop/endless/ventoy-hook.sh @@ -0,0 +1,36 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +END_UDEV_DIR=$(ventoy_get_udev_conf_dir) + +if ! [ -e "$END_UDEV_DIR/10-dm.rules" ]; then + echo 'Copy dm rule file' >> $VTLOG + $CAT $VTOY_PATH/hook/default/10-dm.rules > "$END_UDEV_DIR/10-dm.rules" +fi + +if ! [ -e "$END_UDEV_DIR/13-dm-disk.rules" ]; then + echo 'Copy dm-disk rule file' >> $VTLOG + $CAT $VTOY_PATH/hook/default/13-dm-disk.rules > "$END_UDEV_DIR/13-dm-disk.rules" +fi + +ventoy_set_loop_inotify_script endless/ventoy-inotifyd-hook.sh +$BUSYBOX_PATH/cp -a $VTOY_PATH/loop/endless/ventoy-inotifyd-start.sh /lib/dracut/hooks/pre-udev/01-ventoy-inotifyd-start.sh + diff --git a/IMG/cpio/ventoy/loop/endless/ventoy-inotifyd-hook.sh b/IMG/cpio/ventoy/loop/endless/ventoy-inotifyd-hook.sh new file mode 100644 index 0000000..cc9050d --- /dev/null +++ b/IMG/cpio/ventoy/loop/endless/ventoy-inotifyd-hook.sh @@ -0,0 +1,37 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +VTPATH_OLD=$PATH; PATH=$PATH:$BUSYBOX_PATH:$VTOY_PATH/tool + +if is_inotify_ventoy_part $3; then + vtlog "##### INOTIFYD: $2/$3 is created (YES) ..." + + ventoy_udev_disk_common_hook "$3" "noreplace" + set_ventoy_hook_finish +else + vtlog "##### INOTIFYD: $2/$3 is created (NO) ..." +fi + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/loop/endless/ventoy-inotifyd-start.sh b/IMG/cpio/ventoy/loop/endless/ventoy-inotifyd-start.sh new file mode 100644 index 0000000..6375dc5 --- /dev/null +++ b/IMG/cpio/ventoy/loop/endless/ventoy-inotifyd-start.sh @@ -0,0 +1,31 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtHook=$($CAT $VTOY_PATH/inotifyd-loop-script.txt) + +vtdisk=$(get_ventoy_disk_name) +if [ "$vtdisk" = "unknown" ]; then + vtlog "... start inotifyd listen $vtHook ..." + $BUSYBOX_PATH/nohup $VTOY_PATH/tool/inotifyd $vtHook /dev:n 2>&- & +else + vtlog "... $vtdisk already exist ..." + $BUSYBOX_PATH/sh $vtHook n /dev "${vtdisk#/dev/}2" +fi diff --git a/IMG/cpio/ventoy/loop/esysrescue/ventoy-disk.sh b/IMG/cpio/ventoy/loop/esysrescue/ventoy-disk.sh new file mode 100644 index 0000000..f50c7d4 --- /dev/null +++ b/IMG/cpio/ventoy/loop/esysrescue/ventoy-disk.sh @@ -0,0 +1,47 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +ventoy_create_dev_ventoy_part + +ln -s "../../ventoy1" /dev/disk/by-label/ESYSRESCUE + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/loop/esysrescue/ventoy-hook.sh b/IMG/cpio/ventoy/loop/esysrescue/ventoy-hook.sh new file mode 100644 index 0000000..5420f8c --- /dev/null +++ b/IMG/cpio/ventoy/loop/esysrescue/ventoy-hook.sh @@ -0,0 +1,26 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/maybe_break premount/i\ $BUSYBOX_PATH/sh $VTOY_PATH/loop/esysrescue/ventoy-disk.sh" -i /init + +if [ -f /scripts/casper-bottom/09format_esr_data_partition ]; then + $SED '/mkfs.vfat.*edev.3/icp -a /dev/dm-3 /dev/ventoy3' -i /scripts/casper-bottom/09format_esr_data_partition +fi diff --git a/IMG/cpio/ventoy/loop/freedombox/ventoy-disk.sh b/IMG/cpio/ventoy/loop/freedombox/ventoy-disk.sh new file mode 100644 index 0000000..5ebc7f9 --- /dev/null +++ b/IMG/cpio/ventoy/loop/freedombox/ventoy-disk.sh @@ -0,0 +1,47 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +insmod $VTOY_PATH/modules/dm-mod.ko + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +ventoy_create_dev_ventoy_part + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/loop/freedombox/ventoy-hook.sh b/IMG/cpio/ventoy/loop/freedombox/ventoy-hook.sh new file mode 100644 index 0000000..2585391 --- /dev/null +++ b/IMG/cpio/ventoy/loop/freedombox/ventoy-hook.sh @@ -0,0 +1,22 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/local_mount_root *$/i $BUSYBOX_PATH/sh $VTOY_PATH/loop/freedombox/ventoy-disk.sh" -i /scripts/local diff --git a/IMG/cpio/ventoy/loop/fwts/ventoy-disk.sh b/IMG/cpio/ventoy/loop/fwts/ventoy-disk.sh new file mode 100644 index 0000000..8b24925 --- /dev/null +++ b/IMG/cpio/ventoy/loop/fwts/ventoy-disk.sh @@ -0,0 +1,46 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +ventoy_create_dev_ventoy_part +mdev -s + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/loop/fwts/ventoy-hook.sh b/IMG/cpio/ventoy/loop/fwts/ventoy-hook.sh new file mode 100644 index 0000000..1da4fb9 --- /dev/null +++ b/IMG/cpio/ventoy/loop/fwts/ventoy-hook.sh @@ -0,0 +1,23 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/^mountroot$/i\\$BUSYBOX_PATH/sh $VTOY_PATH/loop/fwts/ventoy-disk.sh" -i /init +#$SED "/^mountroot$/i\\export ROOT=/dev/mapper/ventoy" -i /init diff --git a/IMG/cpio/ventoy/loop/fydeos/ventoy-hook.sh b/IMG/cpio/ventoy/loop/fydeos/ventoy-hook.sh new file mode 100644 index 0000000..666a4e0 --- /dev/null +++ b/IMG/cpio/ventoy/loop/fydeos/ventoy-hook.sh @@ -0,0 +1,205 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2021, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +mkdir /sys +mount -t sysfs sys /sys +mdev -s +sleep 2 + +while [ -n "Y" ]; do + usb_disk=$(get_ventoy_disk_name) + + if echo $usb_disk | egrep -q "nvme|mmc|nbd"; then + vtpart2=${usb_disk}p2 + else + vtpart2=${usb_disk}2 + fi + + if [ -e "${vtpart2}" ]; then + break + else + sleep 2 + mdev -s + fi +done + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) +echo -n $vtDM > /ventoy/vtDM + +ventoy_create_chromeos_ventoy_part 3 +mdev -s + +vtlog "copy out the e2fsck program ..." + +copy_lib() { + cp -a /ventoy_rdroot/usr/lib64/$1 /usr/lib64/ + cp -a /ventoy_rdroot/lib64/$1 /lib64/ +} + +mkdir /ventoy_rdroot +mkdir -p /lib /lib64 /usr/lib64 /sbin + +mount -o ro /dev/ventoy3 /ventoy_rdroot >>$VTLOG 2>&1 +cp -a /ventoy_rdroot/sbin/e2fsck /sbin/ +cp -a /ventoy_rdroot/sbin/dmsetup /sbin/ + +copy_lib libext2fs* +copy_lib libcom_err* +copy_lib libe2p* +copy_lib libblk* +copy_lib libuuid* +copy_lib libdl.* +copy_lib libdl-* +copy_lib libc.* +copy_lib libc-* +copy_lib libpthread* +copy_lib ld-* +copy_lib libdevmapper* +copy_lib libudev* +copy_lib libm.* +copy_lib libm-* +copy_lib librt* +copy_lib libpopt* +copy_lib libgpg-error* +copy_lib libselinux* +copy_lib libsepol* +copy_lib libpcre* +copy_lib libcap* +copy_lib libdw* +copy_lib libgcc_s* +copy_lib libattr* +copy_lib libelf* +copy_lib libz.* +copy_lib libbz2* +copy_lib libgcrypt* +copy_lib liblvm* + +ln -s /lib64/libdevmapper.so.1.02 /lib64/libdevmapper.so.1.02.1 + +umount /ventoy_rdroot + +vtlog "=========================================" +vtlog "===== e2fsck -y -v /dev/ventoy1 =====" +e2fsck -y -v /dev/ventoy1 >>$VTLOG 2>&1 +#vtlog "===== e2fsck -y -v /dev/ventoy3 =====" +#e2fsck -y -v /dev/ventoy3 >>$VTLOG 2>&1 +vtlog "===== e2fsck -y -v /dev/ventoy8 =====" +e2fsck -y -v /dev/ventoy8 >>$VTLOG 2>&1 +vtlog "=========================================" + +/sbin/dmsetup --version >>$VTLOG 2>&1 +veritysetup --version >>$VTLOG 2>&1 + +vtlog "proc devtmpfs ..." +mkdir /newdev +mount -t devtmpfs dev /newdev + +cp -a /dev/mapper/ventoy* /newdev/mapper/ +cp -a /dev/ventoy* /newdev/ + +if [ "$VTOY_VLNK_BOOT" = "01" ]; then + vtLine=$($VTOY_PATH/tool/vtoydump -f /ventoy/ventoy_os_param) + vtdiskname=${vtLine%%#*} +fi + +vtshortname="${vtdiskname#/dev/}" +mv /newdev/${vtshortname} /newdev/backup_${vtshortname} +cp -a /dev/ventoy /newdev/${vtshortname} + +for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do + if [ -e /dev/ventoy${i} ]; then + if echo $vtdiskname | egrep -q "nvme|mmc|nbd"; then + vtpart=p$i + else + vtpart=$i + fi + + if [ -e /newdev/${vtshortname}${vtpart} ]; then + mv /newdev/${vtshortname}${vtpart} /newdev/backup_${vtshortname}${vtpart} + fi + + cp -a /dev/ventoy${i} /newdev/${vtshortname}${vtpart} + + if [ $i -eq 3 ]; then + [ -e /dev/${vtshortname}${vtpart} ] && rm -f /dev/${vtshortname}${vtpart} + cp -a /dev/ventoy${i} /dev/${vtshortname}${vtpart} + vt_root_dev="/dev/${vtshortname}${vtpart}" + vtlog "vt_root_dev=$vt_root_dev" + fi + fi +done + + +# if grep -q 'DM=' /proc/cmdline; then + # vtlog "Boot verified image ..." + + # dmP1=$(sed "s/.*\(0 [0-9]* verity\).*/\1/" /proc/cmdline) + # alg=$(sed "s/.*alg=\([^ ]*\).*/\1/" /proc/cmdline) + # hexdigest=$(sed "s/.*root_hexdigest=\([0-9a-fA-F][0-9a-fA-F]*\).*/\1/" /proc/cmdline) + # salt=$(sed "s/.*salt=\([0-9a-fA-F][0-9a-fA-F]*\).*/\1/" /proc/cmdline) + # hashstart=$(sed "s/.*hashstart=\([0-9][0-9]*\).*/\1/" /proc/cmdline) + + #512 to 4096 + # blocknum=$(expr $hashstart / 8) + # hashoffset=$(expr $hashstart \* 512) + + # vtlog "veritysetup create vroot $vt_root_dev $vt_root_dev $hexdigest --data-block-size=4096 --hash-block-size=4096 --data-blocks=$blocknum --hash-offset=$hashoffset --salt=$salt --hash=$alg --no-superblock --format=0" + # veritysetup create vroot $vt_root_dev $vt_root_dev $hexdigest --data-block-size=4096 --hash-block-size=4096 --data-blocks=$blocknum --hash-offset=$hashoffset --salt=$salt --hash=$alg --no-superblock --format=0 + # sleep 1 + # mdev -s + + # blkdev_num=$(dmsetup ls | grep vroot | sed 's/.*(\([0-9][0-9]*\),[^0-9]*\([0-9][0-9]*\).*/\1:\2/') + # vtDM=$(ventoy_find_dm_id ${blkdev_num}) + # vtlog "blkdev_num=$blkdev_num vtDM=$vtDM" + + # if [ -b /dev/$vtDM ]; then + # veritysetup status vroot >> $VTLOG 2>&1 + # mount -o ro /dev/$vtDM /ventoy_rdroot + # else + # mount -o ro $vt_root_dev /ventoy_rdroot + # fi +# else + # vtlog "Boot normal image ..." + # mount -o ro $vt_root_dev /ventoy_rdroot +# fi + +vtlog "Boot normal image ..." +mount -o ro $vt_root_dev /ventoy_rdroot + +cp -a $VTLOG /newdev/ventoy.log +umount /newdev +mount -t devtmpfs dev /ventoy_rdroot/dev + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/loop/lakka/ventoy-disk.sh b/IMG/cpio/ventoy/loop/lakka/ventoy-disk.sh new file mode 100644 index 0000000..42a8e7f --- /dev/null +++ b/IMG/cpio/ventoy/loop/lakka/ventoy-disk.sh @@ -0,0 +1,72 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +vtKerVer=$(uname -r) +if uname -m | grep -q 64; then + vtBit=64 +else + vtBit=32 +fi + +if grep -q "device-mapper" /proc/devices; then + vtlog "device-mapper enabled by system" +else + if [ -f $VTOY_PATH/vtloopex/dm-mod/$vtKerVer/$vtBit/dax.ko.xz ]; then + xz -d $VTOY_PATH/vtloopex/dm-mod/$vtKerVer/$vtBit/dax.ko.xz + insmod $VTOY_PATH/vtloopex/dm-mod/$vtKerVer/$vtBit/dax.ko + fi + + if [ -f $VTOY_PATH/vtloopex/dm-mod/$vtKerVer/$vtBit/dm-mod.ko.xz ]; then + xz -d $VTOY_PATH/vtloopex/dm-mod/$vtKerVer/$vtBit/dm-mod.ko.xz + insmod $VTOY_PATH/vtloopex/dm-mod/$vtKerVer/$vtBit/dm-mod.ko + fi +fi + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +ventoy_create_dev_ventoy_part + +mkdir /ventoy/mnt +mount /dev/ventoy2 /ventoy/mnt +rm -f /ventoy/mnt/.please_resize_me +sync +umount /ventoy/mnt + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/loop/lakka/ventoy-hook.sh b/IMG/cpio/ventoy/loop/lakka/ventoy-hook.sh new file mode 100644 index 0000000..0fd0180 --- /dev/null +++ b/IMG/cpio/ventoy/loop/lakka/ventoy-hook.sh @@ -0,0 +1,23 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/mount_flash.*{/a\ $BUSYBOX_PATH/sh $VTOY_PATH/loop/lakka/ventoy-disk.sh" -i /init + diff --git a/IMG/cpio/ventoy/loop/openwrt/ventoy-disk.sh b/IMG/cpio/ventoy/loop/openwrt/ventoy-disk.sh new file mode 100644 index 0000000..52f46d6 --- /dev/null +++ b/IMG/cpio/ventoy/loop/openwrt/ventoy-disk.sh @@ -0,0 +1,131 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +check_mkdev_node() { + for i in $(ls /sys/class/block/); do + if ! [ -e /dev/$i ]; then + blkdev_num=$(sed 's/:/ /g' /sys/class/block/$i/dev) + vtlog "mknod -m 0666 /dev/$i b $blkdev_num" + mknod -m 0666 /dev/$i b $blkdev_num + fi + done +} + +check_insmod() { + if [ -f "$1" ]; then + vtlog "insmod $1" + insmod "$1" >> $VTOY_PATH/log 2>&1 + else + vtlog "$1 not exist" + fi +} + +wrt_insmod() { + kbit=$1 + kv=$(uname -r) + + vtlog "insmod $kv $kbit" + + check_insmod /ventoy_openwrt/$kv/$kbit/dax.ko + check_insmod /ventoy_openwrt/$kv/$kbit/dm-mod.ko +} + +insmod_dm_mod() { + if grep -q "device-mapper" /proc/devices; then + vtlog "device-mapper enabled by system 0" + return + fi + + check_insmod /ventoy/modules/dax.ko + check_insmod /ventoy/modules/dm-mod.ko + + if grep -q "device-mapper" /proc/devices; then + vtlog "device-mapper enabled by system 1" + return + fi + + if [ -f /ventoy_openwrt.xz ]; then + tar xf /ventoy_openwrt.xz -C / + rm -f /ventoy_openwrt.xz + fi + + if uname -m | egrep -q "amd64|x86_64"; then + wrt_insmod 64 + else + wrt_insmod generic + if lsmod | grep -q 'dm-mod'; then + vterr "insmod generic failed" + else + wrt_insmod legacy + fi + fi +} + +insmod_dm_mod + +check_mkdev_node +sleep 1 + +while [ -n "Y" ]; do + vtusb_disk=$(get_ventoy_disk_name) + if check_usb_disk_ready "$vtusb_disk"; then + vtlog "get_ventoy_disk_name $vtusb_disk ready" + break; + else + vtlog "get_ventoy_disk_name $vtusb_disk not ready" + sleep 2 + check_mkdev_node + fi +done + + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) +echo -n $vtDM > /ventoy/vtDM + +ventoy_create_dev_ventoy_part +mdev -s +check_mkdev_node + + +mkdir /ventoy_rdroot +mount /dev/ventoy2 /ventoy_rdroot + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/loop/openwrt/ventoy-hook.sh b/IMG/cpio/ventoy/loop/openwrt/ventoy-hook.sh new file mode 100644 index 0000000..f6c1c8c --- /dev/null +++ b/IMG/cpio/ventoy/loop/openwrt/ventoy-hook.sh @@ -0,0 +1,28 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +mkdir /sys +mount -t sysfs sys /sys +mdev -s + +sh $VTOY_PATH/loop/openwrt/ventoy-disk.sh diff --git a/IMG/cpio/ventoy/loop/paldo/ventoy-disk.sh b/IMG/cpio/ventoy/loop/paldo/ventoy-disk.sh new file mode 100644 index 0000000..ef45f04 --- /dev/null +++ b/IMG/cpio/ventoy/loop/paldo/ventoy-disk.sh @@ -0,0 +1,47 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +modprobe dm-mod + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +ventoy_create_dev_ventoy_part + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/loop/paldo/ventoy-hook.sh b/IMG/cpio/ventoy/loop/paldo/ventoy-hook.sh new file mode 100644 index 0000000..efdff62 --- /dev/null +++ b/IMG/cpio/ventoy/loop/paldo/ventoy-hook.sh @@ -0,0 +1,22 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/for *dev *in .*root/i $BUSYBOX_PATH/sh $VTOY_PATH/loop/paldo/ventoy-disk.sh" -i /init diff --git a/IMG/cpio/ventoy/loop/recalbox/ventoy-create-part.sh b/IMG/cpio/ventoy/loop/recalbox/ventoy-create-part.sh new file mode 100644 index 0000000..e7edeb0 --- /dev/null +++ b/IMG/cpio/ventoy/loop/recalbox/ventoy-create-part.sh @@ -0,0 +1,45 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +if [ -f /vtoy_dm_table ]; then + vtPartCnt=$(cat /vtoy_dm_table | wc -l) + if [ $vtPartCnt -ne 1 ]; then + exit 0 + fi +else + exit 0 +fi + +vtlog "try patch init script" + +if [ -f /new_root/etc/init.d/S11share ]; then + cp -a /new_root/etc/init.d/S11share /new_root/overlay/S11share + sed "/^ *createMissingPartitions *$/r $VTOY_PATH/loop/recalbox/ventoy-share.sh" -i /new_root/overlay/S11share + + vtFile=$(ls -1 /new_root/etc/init.d/ | grep -m1 S01) + + mount --bind /new_root/overlay/S11share /new_root/etc/init.d/$vtFile + vtlog "patch S11share to $vtFile" +fi + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/loop/recalbox/ventoy-disk.sh b/IMG/cpio/ventoy/loop/recalbox/ventoy-disk.sh new file mode 100644 index 0000000..3c6b6ee --- /dev/null +++ b/IMG/cpio/ventoy/loop/recalbox/ventoy-disk.sh @@ -0,0 +1,50 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +if [ -f $VTOY_PATH/modules/dm-mod.ko ]; then + insmod $VTOY_PATH/modules/dm-mod.ko +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +ventoy_create_dev_ventoy_part + + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/loop/recalbox/ventoy-hook.sh b/IMG/cpio/ventoy/loop/recalbox/ventoy-hook.sh new file mode 100644 index 0000000..881c236 --- /dev/null +++ b/IMG/cpio/ventoy/loop/recalbox/ventoy-hook.sh @@ -0,0 +1,25 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/mount.*devtmpfs/a\ $BUSYBOX_PATH/sh $VTOY_PATH/loop/recalbox/ventoy-disk.sh" -i /init +$SED "/switch_root/i\ $BUSYBOX_PATH/sh $VTOY_PATH/loop/recalbox/ventoy-create-part.sh" -i /init + +#$SED "/switch_root/i\ exec /ventoy/busybox/sh" -i /init diff --git a/IMG/cpio/ventoy/loop/recalbox/ventoy-share.sh b/IMG/cpio/ventoy/loop/recalbox/ventoy-share.sh new file mode 100644 index 0000000..d016be4 --- /dev/null +++ b/IMG/cpio/ventoy/loop/recalbox/ventoy-share.sh @@ -0,0 +1,21 @@ +sync + +while [ -n "Y" ]; do + clear > /dev/console + echo '################################################' > /dev/console + echo '################################################' > /dev/console + echo '### Please reboot and load from Ventoy again ###' > /dev/console + echo '### This only needed for the first boot time ###' > /dev/console + echo '################################################' > /dev/console + echo '################################################' > /dev/console + + clear > /dev/tty0 + echo '################################################' > /dev/tty0 + echo '################################################' > /dev/tty0 + echo '### Please reboot and load from Ventoy again ###' > /dev/tty0 + echo '### This only needed for the first boot time ###' > /dev/tty0 + echo '################################################' > /dev/tty0 + echo '################################################' > /dev/tty0 + sleep 1 +done + diff --git a/IMG/cpio/ventoy/loop/tails/ventoy-disk.sh b/IMG/cpio/ventoy/loop/tails/ventoy-disk.sh new file mode 100644 index 0000000..a4e4706 --- /dev/null +++ b/IMG/cpio/ventoy/loop/tails/ventoy-disk.sh @@ -0,0 +1,61 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +modprobe dm-mod + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +ventoy_create_dev_ventoy_part + +if [ -n "${FSUUID}" ]; then + vtPartid=0 + MaxPart=$(cat /vtoy_dm_table|wc -l) + + while [ $vtPartid -le $MaxPart ]; do + if blkid /dev/dm-${vtPartid} | grep -q "${FSUUID}"; then + ln -s ../../dm-${vtPartid} "/dev/disk/by-uuid/${FSUUID}" + break + fi + vtPartid=$(expr $vtPartid + 1) + done +fi + + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/loop/tails/ventoy-hook.sh b/IMG/cpio/ventoy/loop/tails/ventoy-hook.sh new file mode 100644 index 0000000..4eec2ae --- /dev/null +++ b/IMG/cpio/ventoy/loop/tails/ventoy-hook.sh @@ -0,0 +1,26 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/^mount_premount$/i\\$BUSYBOX_PATH/sh $VTOY_PATH/loop/tails/ventoy-disk.sh" -i /init + +if [ -f /scripts/init-premount/partitioning ]; then + $SED "1a exit 0" -i /scripts/init-premount/partitioning +fi diff --git a/IMG/cpio/ventoy/loop/ubos/newroot-hook.sh b/IMG/cpio/ventoy/loop/ubos/newroot-hook.sh new file mode 100644 index 0000000..ecc0f18 --- /dev/null +++ b/IMG/cpio/ventoy/loop/ubos/newroot-hook.sh @@ -0,0 +1,26 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +sed "/.* \/boot /d" -i /new_root/etc/fstab + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/loop/ubos/ventoy-disk.sh b/IMG/cpio/ventoy/loop/ubos/ventoy-disk.sh new file mode 100644 index 0000000..a095067 --- /dev/null +++ b/IMG/cpio/ventoy/loop/ubos/ventoy-disk.sh @@ -0,0 +1,48 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +xz -d $VTOY_PATH/modules/dm-mod.ko.xz +insmod $VTOY_PATH/modules/dm-mod.ko + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +ventoy_create_dev_ventoy_part + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/loop/ubos/ventoy-hook.sh b/IMG/cpio/ventoy/loop/ubos/ventoy-hook.sh new file mode 100644 index 0000000..ef79b2a --- /dev/null +++ b/IMG/cpio/ventoy/loop/ubos/ventoy-hook.sh @@ -0,0 +1,30 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$BUSYBOX_PATH/cp -a $VTOY_PATH/hook/default/10-dm.rules /lib/udev/rules.d/ +$BUSYBOX_PATH/cp -a $VTOY_PATH/hook/default/13-dm-disk.rules /lib/udev/rules.d/ + +$SED "/^\"\$mount_handler\"/i\ $BUSYBOX_PATH/sh $VTOY_PATH/loop/ubos/ventoy-disk.sh" -i /init + +$SED "/^\"\$mount_handler\"/a\ $BUSYBOX_PATH/sh $VTOY_PATH/loop/ubos/newroot-hook.sh" -i /init + +$SED "/^\"\$mount_handler\"/a\ init=/usr/lib/systemd/systemd" -i /init + diff --git a/IMG/cpio/ventoy/loop/volumio/ventoy-disk.sh b/IMG/cpio/ventoy/loop/volumio/ventoy-disk.sh new file mode 100644 index 0000000..8b24925 --- /dev/null +++ b/IMG/cpio/ventoy/loop/volumio/ventoy-disk.sh @@ -0,0 +1,46 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +ventoy_create_dev_ventoy_part +mdev -s + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/loop/volumio/ventoy-hook.sh b/IMG/cpio/ventoy/loop/volumio/ventoy-hook.sh new file mode 100644 index 0000000..7b616d2 --- /dev/null +++ b/IMG/cpio/ventoy/loop/volumio/ventoy-hook.sh @@ -0,0 +1,28 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/^CMDLINE=/i $BUSYBOX_PATH/sh $VTOY_PATH/loop/volumio/ventoy-disk.sh" -i /init + +#skip the resizing process +$SED "/^FREESIZE=/a FREESIZE=0" -i /init + +$SED "/exec.*switch_root/i $SED 's@\\\\(.*/boot \\\\)@#\\\\1@' -i /mnt/ext/union/etc/fstab" -i /init + diff --git a/IMG/cpio/ventoy/ventoy_chain.sh b/IMG/cpio/ventoy/ventoy_chain.sh new file mode 100644 index 0000000..e16da36 --- /dev/null +++ b/IMG/cpio/ventoy/ventoy_chain.sh @@ -0,0 +1,511 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +#################################################################### +# # +# Step 1 : Parse kernel parameter # +# # +#################################################################### +if ! [ -e /proc ]; then + $BUSYBOX_PATH/mkdir /proc + rmproc='Y' +fi +$BUSYBOX_PATH/mount -t proc proc /proc + +# vtinit=xxx to replace rdinit=xxx +vtcmdline=$($CAT /proc/cmdline) +for i in $vtcmdline; do + if echo $i | $GREP -q vtinit; then + user_rdinit=${i#vtinit=} + echo "user set user_rdinit=${user_rdinit}" >>$VTLOG + fi +done + +#################################################################### +# # +# Step 2 : Do OS specific hook # +# # +#################################################################### +ventoy_get_os_type() { + echo "kernel version" >> $VTLOG + $CAT /proc/version >> $VTLOG + + if [ -d /twres ]; then + if $GREP -q 'Phoenix' /init; then + echo 'phoenixos'; return + fi + fi + + # Parted Magic + if [ -d /pmagic ]; then + echo 'pmagic'; return + fi + + # PrimeOS : + if $GREP -q 'PrimeOS' /proc/version; then + echo 'primeos'; return + + # Debian : + elif $GREP -q '[Dd]ebian' /proc/version; then + echo 'debian'; return + + # Ubuntu : do the same process with debian + elif $GREP -q '[Uu]buntu' /proc/version; then + echo 'debian'; return + + # Deepin : + elif $GREP -q '[Dd]eepin' /proc/version; then + echo 'deepin'; return + + # rhel5/CentOS5 and all other distributions based on them + elif $GREP -q 'el5' /proc/version; then + echo 'rhel5'; return + + # rhel6/CentOS6 and all other distributions based on them + elif $GREP -q 'el6' /proc/version; then + if [ -f /sbin/detectcd ]; then + if $GREP -q -i 'LENOVO-EasyStartup' /sbin/detectcd; then + echo 'easystartup'; return + fi + fi + + echo 'rhel6'; return + + # rhel7/CentOS7/rhel8/CentOS8 and all other distributions based on them + elif $GREP -q 'el[78]' /proc/version; then + echo 'rhel7'; return + + # Maybe rhel9 rhel1x use the same way? Who knows! + elif $EGREP -q 'el9|el1[0-9]' /proc/version; then + echo 'rhel7'; return + + # Fedora : do the same process with rhel7 + elif $GREP -q '\.fc[0-9][0-9]\.' /proc/version; then + echo 'rhel7'; return + + elif $GREP -q 'euleros' /proc/version; then + if [ -d /usr/Euler/project/init ]; then + echo 'euleros'; return + else + echo 'rhel7'; return + fi + + # SUSE + elif $GREP -q 'SUSE' /proc/version; then + echo 'suse'; return + + # ArchLinux + elif $EGREP -q 'archlinux|ARCH' /proc/version; then + echo 'arch'; return + + # kiosk + elif $EGREP -q 'kiosk' /proc/version; then + echo 'kiosk'; return + + # gentoo + elif $EGREP -q '[Gg]entoo' /proc/version; then + if $GREP -q 'daphile' /proc/version; then + echo 'daphile'; return + fi + + echo 'gentoo'; return + + # TinyCore + elif $EGREP -q 'tinycore' /proc/version; then + echo 'tinycore'; return + + # manjaro + elif $EGREP -q 'manjaro|MANJARO' /proc/version; then + echo 'manjaro'; return + + # mageia + elif $EGREP -q 'mageia' /proc/version; then + echo 'mageia'; return + + # pclinux OS + elif $GREP -i -q 'PCLinuxOS' /proc/version; then + echo 'pclos'; return + + # KaOS + elif $GREP -i -q 'kaos' /proc/version; then + echo 'kaos'; return + + # Alpine + elif $GREP -q 'Alpine' /proc/version; then + echo 'alpine'; return + + elif $GREP -i -q 'PhoenixOS' /proc/version; then + echo 'phoenixos'; return + + # NixOS + elif $GREP -i -q 'NixOS' /proc/version; then + echo 'nixos'; return + + + fi + + if [ -e /lib/debian-installer ]; then + echo 'debian'; return + fi + + if [ -e /etc/os-release ]; then + if $GREP -q 'XenServer' /etc/os-release; then + echo 'xen'; return + elif $GREP -q 'SUSE ' /etc/os-release; then + echo 'suse'; return + elif $GREP -q 'uruk' /etc/os-release; then + echo 'debian'; return + elif $GREP -q 'Solus' /etc/os-release; then + echo 'rhel7'; return + elif $GREP -q -i 'openEuler' /etc/os-release; then + echo 'openEuler'; return + elif $GREP -q 'fuyu' /etc/os-release; then + echo 'openEuler'; return + elif $GREP -q 'deepin' /etc/os-release; then + echo 'deepin'; return + elif $GREP -q 'chinauos' /etc/os-release; then + echo 'deepin'; return + elif $GREP -qi 'aerynos' /etc/os-release; then + echo 'rhel7'; return + elif $GREP -qi 'ID_LIKE=debian' /etc/os-release; then + echo 'debian'; return + fi + fi + + if $BUSYBOX_PATH/dmesg | $GREP -q -m1 "Xen:"; then + echo 'xen'; return + fi + + + if [ -e /etc/HOSTNAME ] && $GREP -i -q 'slackware' /etc/HOSTNAME; then + echo 'slackware'; return + fi + + if [ -e /init ]; then + if $GREP -i -q zeroshell /init; then + echo 'zeroshell'; return + fi + fi + + if $EGREP -q 'ALT ' /proc/version; then + echo 'alt'; return + fi + + if $EGREP -q 'porteus' /proc/version; then + echo 'debian'; return + fi + + if $GREP -q 'Clear Linux ' /proc/version; then + echo 'clear'; return + fi + + if $GREP -q 'artix' /proc/version; then + echo 'arch'; return + fi + + if $GREP -q 'berry ' /proc/version; then + echo 'berry'; return + fi + + if $GREP -q 'Gobo ' /proc/version; then + echo 'gobo'; return + fi + + if $GREP -q 'NuTyX' /proc/version; then + echo 'nutyx'; return + fi + + if [ -d /gnu ]; then + vtLineNum=$($FIND /gnu/ -name guix | $BUSYBOX_PATH/wc -l) + if [ $vtLineNum -gt 0 ]; then + echo 'guix'; return + fi + fi + + if $GREP -q 'android.x86' /proc/version; then + echo 'android'; return + fi + + if $GREP -q 'android.google' /proc/version; then + echo 'android'; return + fi + + if $GREP -q 'adelielinux' /proc/version; then + echo 'adelie'; return + fi + + if $GREP -q 'CDlinux' /proc/cmdline; then + echo 'cdlinux'; return + fi + + if $GREP -q 'parabola' /proc/version; then + echo 'parabola'; return + fi + + if $GREP -q 'cucumber' /proc/version; then + echo 'cucumber'; return + fi + + if $GREP -q 'fatdog' /proc/version; then + echo 'fatdog'; return + fi + + if $GREP -q 'KWORT' /proc/version; then + echo 'kwort'; return + fi + + if $GREP -q 'iwamoto' /proc/version; then + echo 'vine'; return + fi + + if $GREP -q 'hyperbola' /proc/cmdline; then + echo 'hyperbola'; return + fi + + if $GREP -q 'CRUX' /proc/version; then + echo 'crux'; return + fi + + if [ -f /init ]; then + if $GREP -q 'AryaLinux' /init; then + echo 'aryalinux'; return + elif $GREP -q 'Dragora' /init; then + echo 'dragora'; return + + fi + fi + + if $GREP -q 'slackware' /proc/version; then + echo 'slackware'; return + fi + + if $BUSYBOX_PATH/hostname | $GREP -q 'smoothwall'; then + echo 'smoothwall'; return + fi + + if $GREP -q 'photon' /proc/version; then + echo 'photon'; return + fi + + if $GREP -q 'ploplinux' /proc/version; then + echo 'ploplinux'; return + fi + + if $GREP -q 'lunar' /proc/version; then + echo 'lunar'; return + fi + + if $GREP -q 'SMGL-' /proc/version; then + echo 'smgl'; return + fi + + if $GREP -q 'rancher' /proc/version; then + echo 'rancher'; return + fi + + + if [ -e /etc/initrd-release ]; then + if $GREP -q -m1 't2sde' /etc/initrd-release; then + echo 't2'; return + fi + fi + + if $GREP -q 'wifislax' /proc/version; then + echo 'wifislax'; return + fi + + if $GREP -q 'pisilinux' /proc/version; then + echo 'pisilinux'; return + fi + + if $GREP -q 'blackPanther' /proc/version; then + echo 'blackPanther'; return + fi + + if $GREP -q 'primeos' /proc/version; then + echo 'primeos'; return + fi + + if $GREP -q 'austrumi' /proc/version; then + echo 'austrumi'; return + fi + + if [ -f /DISTRO_SPECS ]; then + if $GREP -q '[Pp]uppy' /DISTRO_SPECS; then + echo 'debian'; return + elif $GREP -q 'veket' /DISTRO_SPECS; then + echo 'debian'; return + fi + fi + + if [ -f /etc/openEuler-release ]; then + echo "openEuler"; return + fi + + + #special arch based iso file check + if [ -f /init ]; then + if $GREP -q 'mount_handler' /init; then + if [ -d /hooks ]; then + if $BUSYBOX_PATH/ls -1 /hooks/ | $GREP -q '.*iso$'; then + echo "arch"; return + fi + elif [ -d /hook ]; then + if $BUSYBOX_PATH/ls -1 /hook/ | $GREP -q '.*iso$'; then + echo "arch"; return + fi + fi + fi + fi + + + #Kylin V10 Server + if [ -f /usr/sbin/dhclient ]; then + if $BUSYBOX_PATH/strings /usr/sbin/dhclient | $GREP -i -q -m1 openeuler; then + echo 'openEuler'; return + fi + fi + if [ -f /etc/kylin-release ]; then + if $GREP -i -q -m1 'Kylin.*Server.* V1[1-9] ' /etc/kylin-release; then + echo 'openEuler'; return + fi + fi + + + + if $GREP -q 'chimera' /proc/version; then + echo 'chimera'; return + fi + + + if $GREP -q '4.19.' /proc/version; then + if [ -d /lib/dracut/hooks ]; then + echo 'openEuler'; return + fi + fi + + if [ -f /etc/tinyramfs/config ]; then + if $GREP -q 'EWE_ISO' /etc/tinyramfs/config; then + echo "ewe"; return + fi + fi + + + echo "default" +} + +VTOS=$(ventoy_get_os_type) +echo "OS=###${VTOS}###" >>$VTLOG +if [ -e "$VTOY_PATH/hook/$VTOS/ventoy-hook.sh" ]; then + $BUSYBOX_PATH/sh "$VTOY_PATH/hook/$VTOS/ventoy-hook.sh" +fi + + + +if $GREP -q -i Untangle /proc/version; then + for vtPara in $($CAT /proc/cmdline); do + vtItemkey=$(echo $vtPara | $AWK -F= '{print $1}') + vtItemVal=$(echo $vtPara | $AWK -F= '{print $2}') + if $GREP -q -m1 "^$vtItemkey\$" $VTOY_PATH/hook/default/export.list; then + vtEnvExport="$vtEnvExport $vtItemkey=$vtItemVal" + fi + done + + echo "================ env export ================" >> $VTLOG + echo $vtEnvExport >> $VTLOG + echo "============================================" >> $VTLOG +fi + + + +#################################################################### +# # +# Step 3 : Run LiveInjection Hook # +# # +#################################################################### +if [ -f "/live_injection_7ed136ec_7a61_4b54_adc3_ae494d5106ea/hook.sh" ]; then + echo "==== Begin Call live injection hook.sh $VTOS" >> $VTLOG + $BUSYBOX_PATH/sh "/live_injection_7ed136ec_7a61_4b54_adc3_ae494d5106ea/hook.sh" $VTOS >>$VTLOG 2>&1 + echo "==== Finish Call live injection hook.sh $VTOS" >> $VTLOG +else + echo "No live injection" >> $VTLOG +fi + + +#################################################################### +# # +# Step 4 : Check for debug break # +# # +#################################################################### +if [ "$VTOY_BREAK_LEVEL" = "03" ] || [ "$VTOY_BREAK_LEVEL" = "13" ]; then + $SLEEP 5 + echo -e "\n\n\033[32m ################################################# \033[0m" + echo -e "\033[32m ################ VENTOY DEBUG ################### \033[0m" + echo -e "\033[32m ################################################# \033[0m \n" + if [ "$VTOY_BREAK_LEVEL" = "13" ]; then + $CAT $VTOY_PATH/log + fi + exec $BUSYBOX_PATH/sh +fi + + +#################################################################### +# # +# Step 5 : Hand over to real init # +# # +#################################################################### +$BUSYBOX_PATH/umount /proc +if [ "$rmproc" = "Y" ]; then + $BUSYBOX_PATH/rm -rf /proc +fi + +if [ -f $VTOY_PATH/ventoy_persistent_map ]; then + export PERSISTENT='YES' + export PERSISTENCE='true' +fi + +cd / + +unset VTLOG FIND GREP EGREP CAT AWK SED SLEEP HEAD vtcmdline + +for vtinit in $user_rdinit /init /sbin/init /linuxrc; do + if [ -d /ventoy_rdroot ]; then + if [ -e "/ventoy_rdroot$vtinit" ]; then + # switch_root will check /init file, this is a cheat code + echo 'switch_root' > /init + exec $BUSYBOX_PATH/switch_root /ventoy_rdroot "$vtinit" + fi + else + if [ -e "$vtinit" ];then + if [ -f "$VTOY_PATH/hook/$VTOS/ventoy-before-init.sh" ]; then + $BUSYBOX_PATH/sh "$VTOY_PATH/hook/$VTOS/ventoy-before-init.sh" + fi + + if [ -z "$vtEnvExport" ]; then + exec "$vtinit" + else + exec env $vtEnvExport "$vtinit" + fi + fi + fi +done + +# Should never reach here +echo -e "\n\n\033[31m ############ INIT NOT FOUND ############### \033[0m \n" +exec $BUSYBOX_PATH/sh diff --git a/IMG/cpio/ventoy/ventoy_loop.sh b/IMG/cpio/ventoy/ventoy_loop.sh new file mode 100644 index 0000000..532faaa --- /dev/null +++ b/IMG/cpio/ventoy/ventoy_loop.sh @@ -0,0 +1,452 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +#################################################################### +# # +# Step 1 : Parse kernel parameter # +# # +#################################################################### +if ! [ -e /proc ]; then + $BUSYBOX_PATH/mkdir /proc + rmproc='Y' +fi +$BUSYBOX_PATH/mount -t proc proc /proc + +# vtinit=xxx to replace rdinit=xxx +vtcmdline=$($CAT /proc/cmdline) +for i in $vtcmdline; do + if echo $i | $GREP -q vtinit; then + user_rdinit=${i#vtinit=} + echo "user set user_rdinit=${user_rdinit}" >>$VTLOG + fi +done + +#################################################################### +# # +# Step 2 : Process ko # +# # +#################################################################### +$BUSYBOX_PATH/mkdir -p /ventoy/modules +$BUSYBOX_PATH/ls -1a / | $EGREP '\.ko$|\.ko.[gx]z$' | while read vtline; do + if [ "${vtline:0:1}" = "." ]; then + $BUSYBOX_PATH/mv /${vtline} /ventoy/modules/${vtline:1} + else + $BUSYBOX_PATH/mv /${vtline} /ventoy/modules/ + fi +done + +if [ -e /vtloopex.tar.xz ]; then + echo "extract vtloopex ..." >> $VTLOG + $BUSYBOX_PATH/tar -xJf /vtloopex.tar.xz -C $VTOY_PATH/ + $BUSYBOX_PATH/rm -f /vtloopex.tar.xz +fi + + +#################################################################### +# # +# Step 3 : Do OS specific hook # +# # +#################################################################### +ventoy_get_os_type() { + echo "kernel version" >> $VTLOG + $CAT /proc/version >> $VTLOG + + if $GREP -q 'endless' /proc/version; then + echo 'endless'; return + fi + + if $GREP -q 'OpenWrt' /proc/version; then + echo 'openwrt'; return + fi + + if $GREP -q 'easyos' /proc/cmdline; then + echo 'easyos'; return + fi + + if [ -e /BOOT_SPECS ]; then + if $GREP -q 'easyos' /BOOT_SPECS; then + echo 'easyos'; return + fi + fi + + if [ -e /etc/os-release ]; then + if $GREP -q 'volumio' /etc/os-release; then + echo 'volumio'; return + fi + fi + + if $GREP -q 'ventoyos=' /proc/cmdline; then + $SED "s/.*ventoyos=\([a-zA-Z0-9_-]*\).*/\1/" /proc/cmdline; return + fi + + if [ -d /twres ]; then + if $GREP -q 'Phoenix' /init; then + echo 'phoenixos'; return + fi + fi + + # Parted Magic + if [ -d /pmagic ]; then + echo 'pmagic'; return + fi + + # rhel5/CentOS5 and all other distributions based on them + if $GREP -q 'el5' /proc/version; then + echo 'rhel5'; return + + # rhel6/CentOS6 and all other distributions based on them + elif $GREP -q 'el6' /proc/version; then + echo 'rhel6'; return + + # rhel7/CentOS7/rhel8/CentOS8 and all other distributions based on them + elif $GREP -q 'el[78]' /proc/version; then + echo 'rhel7'; return + + # Maybe rhel9 rhel1x use the same way? Who knows! + elif $EGREP -q 'el9|el1[0-9]' /proc/version; then + echo 'rhel7'; return + + # Fedora : do the same process with rhel7 + elif $GREP -q '\.fc[0-9][0-9]\.' /proc/version; then + echo 'rhel7'; return + + # Debian : + elif $GREP -q '[Dd]ebian' /proc/version; then + echo 'debian'; return + + # Ubuntu : do the same process with debian + elif $GREP -q '[Uu]buntu' /proc/version; then + echo 'debian'; return + + # Deepin : do the same process with debian + elif $GREP -q '[Dd]eepin' /proc/version; then + echo 'debian'; return + + # SUSE + elif $GREP -q 'SUSE' /proc/version; then + echo 'suse'; return + + # ArchLinux + elif $EGREP -q 'archlinux|ARCH' /proc/version; then + echo 'arch'; return + + # kiosk + elif $EGREP -q 'kiosk' /proc/version; then + echo 'kiosk'; return + + # gentoo + elif $EGREP -q '[Gg]entoo' /proc/version; then + if $GREP -q 'daphile' /proc/version; then + echo 'daphile'; return + fi + + echo 'gentoo'; return + + # TinyCore + elif $EGREP -q 'tinycore' /proc/version; then + echo 'tinycore'; return + + # manjaro + elif $EGREP -q 'manjaro|MANJARO' /proc/version; then + echo 'manjaro'; return + + # mageia + elif $EGREP -q 'mageia' /proc/version; then + echo 'mageia'; return + + # pclinux OS + elif $GREP -i -q 'PCLinuxOS' /proc/version; then + echo 'pclos'; return + + # KaOS + elif $GREP -i -q 'kaos' /proc/version; then + echo 'kaos'; return + + # Alpine + elif $GREP -q 'Alpine' /proc/version; then + echo 'alpine'; return + + elif $GREP -i -q 'PhoenixOS' /proc/version; then + echo 'phoenixos'; return + + # NixOS + elif $GREP -i -q 'NixOS' /proc/version; then + echo 'nixos'; return + + + fi + + if [ -e /lib/debian-installer ]; then + echo 'debian'; return + fi + + if [ -e /etc/os-release ]; then + if $GREP -q 'XenServer' /etc/os-release; then + echo 'xen'; return + elif $GREP -q 'SUSE ' /etc/os-release; then + echo 'suse'; return + elif $GREP -q 'uruk' /etc/os-release; then + echo 'debian'; return + elif $GREP -q 'Solus' /etc/os-release; then + echo 'rhel7'; return + elif $GREP -q -i 'openEuler' /etc/os-release; then + echo 'openEuler'; return + elif $GREP -q 'fuyu' /etc/os-release; then + echo 'openEuler'; return + elif $GREP -q 'deepin' /etc/os-release; then + echo 'debian'; return + elif $GREP -q 'chinauos' /etc/os-release; then + echo 'debian'; return + fi + fi + + if $BUSYBOX_PATH/dmesg | $GREP -q -m1 "Xen:"; then + echo 'xen'; return + fi + + + if [ -e /etc/HOSTNAME ] && $GREP -i -q 'slackware' /etc/HOSTNAME; then + echo 'slackware'; return + fi + + if [ -e /init ]; then + if $GREP -i -q zeroshell /init; then + echo 'zeroshell'; return + fi + fi + + if $EGREP -q 'ALT ' /proc/version; then + echo 'alt'; return + fi + + if $EGREP -q 'porteus' /proc/version; then + echo 'debian'; return + fi + + if $GREP -q 'Clear Linux ' /proc/version; then + echo 'clear'; return + fi + + if $GREP -q 'artix' /proc/version; then + echo 'arch'; return + fi + + if $GREP -q 'berry ' /proc/version; then + echo 'berry'; return + fi + + if $GREP -q 'Gobo ' /proc/version; then + echo 'gobo'; return + fi + + if $GREP -q 'NuTyX' /proc/version; then + echo 'nutyx'; return + fi + + if [ -d /gnu ]; then + vtLineNum=$($FIND /gnu/ -name guix | $BUSYBOX_PATH/wc -l) + if [ $vtLineNum -gt 0 ]; then + echo 'guix'; return + fi + fi + + if $GREP -q 'android.x86' /proc/version; then + echo 'android'; return + fi + + if $GREP -q 'adelielinux' /proc/version; then + echo 'adelie'; return + fi + + if $GREP -q 'CDlinux' /proc/cmdline; then + echo 'cdlinux'; return + fi + + if $GREP -q 'parabola' /proc/version; then + echo 'parabola'; return + fi + + if $GREP -q 'cucumber' /proc/version; then + echo 'cucumber'; return + fi + + if $GREP -q 'fatdog' /proc/version; then + echo 'fatdog'; return + fi + + if $GREP -q 'KWORT' /proc/version; then + echo 'kwort'; return + fi + + if $GREP -q 'iwamoto' /proc/version; then + echo 'vine'; return + fi + + if $GREP -q 'hyperbola' /proc/cmdline; then + echo 'hyperbola'; return + fi + + if $GREP -q 'CRUX' /proc/version; then + echo 'crux'; return + fi + + if [ -f /init ]; then + if $GREP -q 'AryaLinux' /init; then + echo 'aryalinux'; return + elif $GREP -q 'Dragora' /init; then + echo 'dragora'; return + + fi + fi + + if $GREP -q 'slackware' /proc/version; then + echo 'slackware'; return + fi + + if $BUSYBOX_PATH/hostname | $GREP -q 'smoothwall'; then + echo 'smoothwall'; return + fi + + if $GREP -q 'photon' /proc/version; then + echo 'photon'; return + fi + + if $GREP -q 'ploplinux' /proc/version; then + echo 'ploplinux'; return + fi + + if $GREP -q 'lunar' /proc/version; then + echo 'lunar'; return + fi + + if $GREP -q 'SMGL-' /proc/version; then + echo 'smgl'; return + fi + + if $GREP -q 'rancher' /proc/version; then + echo 'rancher'; return + fi + + + if [ -e /etc/initrd-release ]; then + if $GREP -q -m1 't2sde' /etc/initrd-release; then + echo 't2'; return + fi + fi + + if $GREP -q 'wifislax' /proc/version; then + echo 'wifislax'; return + fi + + if $GREP -q 'pisilinux' /proc/version; then + echo 'pisilinux'; return + fi + + if $GREP -q 'blackPanther' /proc/version; then + echo 'blackPanther'; return + fi + + if $GREP -q 'primeos' /proc/version; then + echo 'primeos'; return + fi + + if $GREP -q 'austrumi' /proc/version; then + echo 'austrumi'; return + fi + + if [ -f /DISTRO_SPECS ]; then + if $GREP -q '[Pp]uppy' /DISTRO_SPECS; then + echo 'debian'; return + elif $GREP -q 'veket' /DISTRO_SPECS; then + echo 'debian'; return + fi + fi + + if [ -f /etc/openEuler-release ]; then + echo "openEuler"; return + fi + + echo "default" +} + +VTOS=$(ventoy_get_os_type) +echo "OS=###${VTOS}###" >>$VTLOG +if [ -e "$VTOY_PATH/loop/$VTOS/ventoy-hook.sh" ]; then + $BUSYBOX_PATH/sh "$VTOY_PATH/loop/$VTOS/ventoy-hook.sh" +elif [ -e "$VTOY_PATH/hook/$VTOS/ventoy-hook.sh" ]; then + $BUSYBOX_PATH/sh "$VTOY_PATH/hook/$VTOS/ventoy-hook.sh" +fi + + +#################################################################### +# # +# Step 4 : Check for debug break # +# # +#################################################################### +if [ "$VTOY_BREAK_LEVEL" = "03" ] || [ "$VTOY_BREAK_LEVEL" = "13" ]; then + $SLEEP 5 + echo -e "\n\n\033[32m ################################################# \033[0m" + echo -e "\033[32m ################ VENTOY DEBUG ################### \033[0m" + echo -e "\033[32m ################################################# \033[0m \n" + if [ "$VTOY_BREAK_LEVEL" = "13" ]; then + $CAT $VTOY_PATH/log + fi + exec $BUSYBOX_PATH/sh +fi + + +#################################################################### +# # +# Step 5 : Hand over to real init # +# # +#################################################################### +$BUSYBOX_PATH/umount /proc +if [ "$rmproc" = "Y" ]; then + $BUSYBOX_PATH/rm -rf /proc +fi + +if [ -f $VTOY_PATH/ventoy_persistent_map ]; then + export PERSISTENT='YES' + export PERSISTENCE='true' +fi + +cd / + +unset VTLOG FIND GREP EGREP CAT AWK SED SLEEP HEAD vtcmdline + +for vtinit in $user_rdinit /init /sbin/init /linuxrc; do + if [ -d /ventoy_rdroot ]; then + if [ -e "/ventoy_rdroot$vtinit" ]; then + # switch_root will check /init file, this is a cheat code + echo 'switch_root' > /init + exec $BUSYBOX_PATH/switch_root /ventoy_rdroot "$vtinit" + fi + else + if [ -e "$vtinit" ];then + if [ -f "$VTOY_PATH/hook/$VTOS/ventoy-before-init.sh" ]; then + $BUSYBOX_PATH/sh "$VTOY_PATH/hook/$VTOS/ventoy-before-init.sh" + fi + exec "$vtinit" + fi + fi +done + +# Should never reach here +echo -e "\n\n\033[31m ############ INIT NOT FOUND ############### \033[0m \n" +exec $BUSYBOX_PATH/sh diff --git a/IMG/cpio_arm64/ventoy/busybox/a64 b/IMG/cpio_arm64/ventoy/busybox/a64 new file mode 100644 index 0000000..55eb145 Binary files /dev/null and b/IMG/cpio_arm64/ventoy/busybox/a64 differ diff --git a/IMG/cpio_arm64/ventoy/busybox/busyboxaa64.xz b/IMG/cpio_arm64/ventoy/busybox/busyboxaa64.xz new file mode 100644 index 0000000..f171481 Binary files /dev/null and b/IMG/cpio_arm64/ventoy/busybox/busyboxaa64.xz differ diff --git a/IMG/cpio_arm64/ventoy/busybox/vtchmodaa64 b/IMG/cpio_arm64/ventoy/busybox/vtchmodaa64 new file mode 100644 index 0000000..6c3811a Binary files /dev/null and b/IMG/cpio_arm64/ventoy/busybox/vtchmodaa64 differ diff --git a/IMG/cpio_arm64/ventoy/busybox/xzminidecaa64 b/IMG/cpio_arm64/ventoy/busybox/xzminidecaa64 new file mode 100644 index 0000000..914eba6 Binary files /dev/null and b/IMG/cpio_arm64/ventoy/busybox/xzminidecaa64 differ diff --git a/IMG/cpio_arm64/ventoy/tool/lz4cataa64 b/IMG/cpio_arm64/ventoy/tool/lz4cataa64 new file mode 100644 index 0000000..7e025d4 Binary files /dev/null and b/IMG/cpio_arm64/ventoy/tool/lz4cataa64 differ diff --git a/IMG/cpio_arm64/ventoy/tool/zstdcataa64 b/IMG/cpio_arm64/ventoy/tool/zstdcataa64 new file mode 100644 index 0000000..513f495 Binary files /dev/null and b/IMG/cpio_arm64/ventoy/tool/zstdcataa64 differ diff --git a/IMG/cpio_mips64/ventoy/busybox/busyboxm64e.xz b/IMG/cpio_mips64/ventoy/busybox/busyboxm64e.xz new file mode 100644 index 0000000..3cab6d5 Binary files /dev/null and b/IMG/cpio_mips64/ventoy/busybox/busyboxm64e.xz differ diff --git a/IMG/cpio_mips64/ventoy/busybox/m64 b/IMG/cpio_mips64/ventoy/busybox/m64 new file mode 100644 index 0000000..039e82a Binary files /dev/null and b/IMG/cpio_mips64/ventoy/busybox/m64 differ diff --git a/IMG/cpio_mips64/ventoy/busybox/vtchmodm64e b/IMG/cpio_mips64/ventoy/busybox/vtchmodm64e new file mode 100644 index 0000000..dc623d5 Binary files /dev/null and b/IMG/cpio_mips64/ventoy/busybox/vtchmodm64e differ diff --git a/IMG/cpio_mips64/ventoy/busybox/xzminidecm64e b/IMG/cpio_mips64/ventoy/busybox/xzminidecm64e new file mode 100644 index 0000000..5d44c72 Binary files /dev/null and b/IMG/cpio_mips64/ventoy/busybox/xzminidecm64e differ diff --git a/IMG/cpio_mips64/ventoy/tool/lz4catm64e b/IMG/cpio_mips64/ventoy/tool/lz4catm64e new file mode 100644 index 0000000..3d80330 Binary files /dev/null and b/IMG/cpio_mips64/ventoy/tool/lz4catm64e differ diff --git a/IMG/cpio_x86/ventoy/busybox/64h b/IMG/cpio_x86/ventoy/busybox/64h new file mode 100644 index 0000000..a137ff3 Binary files /dev/null and b/IMG/cpio_x86/ventoy/busybox/64h differ diff --git a/IMG/cpio_x86/ventoy/busybox/ash b/IMG/cpio_x86/ventoy/busybox/ash new file mode 100644 index 0000000..9944a11 Binary files /dev/null and b/IMG/cpio_x86/ventoy/busybox/ash differ diff --git a/IMG/cpio_x86/ventoy/busybox/busybox32.xz b/IMG/cpio_x86/ventoy/busybox/busybox32.xz new file mode 100644 index 0000000..17bd64b Binary files /dev/null and b/IMG/cpio_x86/ventoy/busybox/busybox32.xz differ diff --git a/IMG/cpio_x86/ventoy/busybox/busybox64.xz b/IMG/cpio_x86/ventoy/busybox/busybox64.xz new file mode 100644 index 0000000..df9d768 Binary files /dev/null and b/IMG/cpio_x86/ventoy/busybox/busybox64.xz differ diff --git a/IMG/cpio_x86/ventoy/busybox/vtchmod32 b/IMG/cpio_x86/ventoy/busybox/vtchmod32 new file mode 100644 index 0000000..2647afb Binary files /dev/null and b/IMG/cpio_x86/ventoy/busybox/vtchmod32 differ diff --git a/IMG/cpio_x86/ventoy/busybox/vtchmod64 b/IMG/cpio_x86/ventoy/busybox/vtchmod64 new file mode 100644 index 0000000..4d27c57 Binary files /dev/null and b/IMG/cpio_x86/ventoy/busybox/vtchmod64 differ diff --git a/IMG/cpio_x86/ventoy/busybox/vtchmod64_musl b/IMG/cpio_x86/ventoy/busybox/vtchmod64_musl new file mode 100644 index 0000000..01c80f2 Binary files /dev/null and b/IMG/cpio_x86/ventoy/busybox/vtchmod64_musl differ diff --git a/IMG/cpio_x86/ventoy/busybox/xzcat32_musl.xz b/IMG/cpio_x86/ventoy/busybox/xzcat32_musl.xz new file mode 100644 index 0000000..78563c4 Binary files /dev/null and b/IMG/cpio_x86/ventoy/busybox/xzcat32_musl.xz differ diff --git a/IMG/cpio_x86/ventoy/busybox/xzcat64_musl.xz b/IMG/cpio_x86/ventoy/busybox/xzcat64_musl.xz new file mode 100644 index 0000000..98e453b Binary files /dev/null and b/IMG/cpio_x86/ventoy/busybox/xzcat64_musl.xz differ diff --git a/IMG/cpio_x86/ventoy/busybox/xzminidec32 b/IMG/cpio_x86/ventoy/busybox/xzminidec32 new file mode 100644 index 0000000..b2c2056 Binary files /dev/null and b/IMG/cpio_x86/ventoy/busybox/xzminidec32 differ diff --git a/IMG/cpio_x86/ventoy/busybox/xzminidec64 b/IMG/cpio_x86/ventoy/busybox/xzminidec64 new file mode 100644 index 0000000..e2dde49 Binary files /dev/null and b/IMG/cpio_x86/ventoy/busybox/xzminidec64 differ diff --git a/IMG/cpio_x86/ventoy/busybox/xzminidec64_musl b/IMG/cpio_x86/ventoy/busybox/xzminidec64_musl new file mode 100644 index 0000000..de7fa3d Binary files /dev/null and b/IMG/cpio_x86/ventoy/busybox/xzminidec64_musl differ diff --git a/IMG/cpio_x86/ventoy/tool/ar b/IMG/cpio_x86/ventoy/tool/ar new file mode 100644 index 0000000..fd443b2 Binary files /dev/null and b/IMG/cpio_x86/ventoy/tool/ar differ diff --git a/IMG/cpio_x86/ventoy/tool/inotifyd b/IMG/cpio_x86/ventoy/tool/inotifyd new file mode 100644 index 0000000..29c70d2 Binary files /dev/null and b/IMG/cpio_x86/ventoy/tool/inotifyd differ diff --git a/IMG/cpio_x86/ventoy/tool/lz4cat b/IMG/cpio_x86/ventoy/tool/lz4cat new file mode 100644 index 0000000..bccad01 Binary files /dev/null and b/IMG/cpio_x86/ventoy/tool/lz4cat differ diff --git a/IMG/cpio_x86/ventoy/tool/lz4cat64 b/IMG/cpio_x86/ventoy/tool/lz4cat64 new file mode 100644 index 0000000..2790fa9 Binary files /dev/null and b/IMG/cpio_x86/ventoy/tool/lz4cat64 differ diff --git a/IMG/cpio_x86/ventoy/tool/ventoy_loader.sh b/IMG/cpio_x86/ventoy/tool/ventoy_loader.sh new file mode 100644 index 0000000..5844cbd --- /dev/null +++ b/IMG/cpio_x86/ventoy/tool/ventoy_loader.sh @@ -0,0 +1,20 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +exec /ventoy/busybox/sh diff --git a/IMG/cpio_x86/ventoy/tool/vtoytool_install.sh b/IMG/cpio_x86/ventoy/tool/vtoytool_install.sh new file mode 100644 index 0000000..1ccadd1 --- /dev/null +++ b/IMG/cpio_x86/ventoy/tool/vtoytool_install.sh @@ -0,0 +1,98 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +echo "#### install vtoytool #####" >> $VTLOG + +for app in ar inotifyd; do + if [ -e $BUSYBOX_PATH/$app ]; then + $BUSYBOX_PATH/rm -f $VTOY_PATH/tool/$app + $BUSYBOX_PATH/ln -s $BUSYBOX_PATH/$app $VTOY_PATH/tool/$app + else + $BUSYBOX_PATH/ln -s $VTOY_PATH/tool/$app $BUSYBOX_PATH/$app + fi +done + + +if $GREP -q aarch64 $VTOY_PATH/ventoy_arch; then + for vtdir in $(ls $VTOY_PATH/tool/vtoytool/); do + echo "try $VTOY_PATH/tool/vtoytool/$vtdir/ ..." >> $VTLOG + if $VTOY_PATH/tool/vtoytool/$vtdir/vtoytool_aa64 --install 2>>$VTLOG; then + echo "vtoytool_aa64 OK" >> $VTLOG + break + fi + done + + $BUSYBOX_PATH/cp -a $VTOY_PATH/tool/vtoy_fuse_iso_aa64 $VTOY_PATH/tool/vtoy_fuse_iso + $BUSYBOX_PATH/cp -a $VTOY_PATH/tool/unsquashfs_aa64 $VTOY_PATH/tool/vtoy_unsquashfs +elif $GREP -q mips64el $VTOY_PATH/ventoy_arch; then + for vtdir in $(ls $VTOY_PATH/tool/vtoytool/); do + echo "try $VTOY_PATH/tool/vtoytool/$vtdir/ ..." >> $VTLOG + if $VTOY_PATH/tool/vtoytool/$vtdir/vtoytool_m64e --install 2>>$VTLOG; then + echo "vtoytool_m64e OK" >> $VTLOG + break + fi + done + + # TBD + #$BUSYBOX_PATH/cp -a $VTOY_PATH/tool/vtoy_fuse_iso_aa64 $VTOY_PATH/tool/vtoy_fuse_iso + #$BUSYBOX_PATH/cp -a $VTOY_PATH/tool/unsquashfs_aa64 $VTOY_PATH/tool/vtoy_unsquashfs +else + for vtdir in $(ls $VTOY_PATH/tool/vtoytool/); do + echo "try $VTOY_PATH/tool/vtoytool/$vtdir/ ..." >> $VTLOG + if $VTOY_PATH/tool/vtoytool/$vtdir/vtoytool_64 --install 2>>$VTLOG; then + echo "vtoytool_64 OK" >> $VTLOG + break + fi + + if $VTOY_PATH/tool/vtoytool/$vtdir/vtoytool_32 --install 2>>$VTLOG; then + echo "vtoytool_32 OK" >> $VTLOG + break + fi + done + + if $VTOY_PATH/tool/vtoy_fuse_iso_64 -t 2>>$VTLOG; then + echo "use vtoy_fuse_iso_64" >>$VTLOG + $BUSYBOX_PATH/cp -a $VTOY_PATH/tool/vtoy_fuse_iso_64 $VTOY_PATH/tool/vtoy_fuse_iso + else + echo "use vtoy_fuse_iso_32" >>$VTLOG + $BUSYBOX_PATH/cp -a $VTOY_PATH/tool/vtoy_fuse_iso_32 $VTOY_PATH/tool/vtoy_fuse_iso + fi + + if $VTOY_PATH/tool/unsquashfs_64 -t 2>>$VTLOG; then + echo "use unsquashfs_64" >>$VTLOG + $BUSYBOX_PATH/cp -a $VTOY_PATH/tool/unsquashfs_64 $VTOY_PATH/tool/vtoy_unsquashfs + else + echo "use unsquashfs_32" >>$VTLOG + $BUSYBOX_PATH/cp -a $VTOY_PATH/tool/unsquashfs_32 $VTOY_PATH/tool/vtoy_unsquashfs + fi + + if $GREP -q 64 $VTOY_PATH/ventoy_arch; then + echo "use veritysetup64" >>$VTLOG + if [ -f $VTOY_PATH/tool/veritysetup64 ]; then + $BUSYBOX_PATH/cp -a $VTOY_PATH/tool/veritysetup64 $VTOY_PATH/tool/veritysetup + fi + else + echo "use veritysetup32" >>$VTLOG + + if [ -f $VTOY_PATH/tool/veritysetup32 ]; then + $BUSYBOX_PATH/cp -a $VTOY_PATH/tool/veritysetup32 $VTOY_PATH/tool/veritysetup + fi + fi +fi + diff --git a/IMG/cpio_x86/ventoy/tool/zstdcat b/IMG/cpio_x86/ventoy/tool/zstdcat new file mode 100644 index 0000000..e8657c6 Binary files /dev/null and b/IMG/cpio_x86/ventoy/tool/zstdcat differ diff --git a/IMG/cpio_x86/ventoy/tool/zstdcat64 b/IMG/cpio_x86/ventoy/tool/zstdcat64 new file mode 100644 index 0000000..eb4045a Binary files /dev/null and b/IMG/cpio_x86/ventoy/tool/zstdcat64 differ diff --git a/IMG/mkcpio.sh b/IMG/mkcpio.sh new file mode 100644 index 0000000..c204336 --- /dev/null +++ b/IMG/mkcpio.sh @@ -0,0 +1,156 @@ +#!/bin/bash + +VENTOY_PATH=$PWD/../ + + +if [ -d cpio_tmp ]; then + rm -rf cpio_tmp +fi + + +############### cpio ############ +chmod -R 777 cpio +rm -f ventoy.cpio ventoy_x86.cpio ventoy_arm64.cpio ventoy_mips64.cpio + +cp -a cpio cpio_tmp + +cd cpio_tmp +rm -f init +ln -s sbin/init init +ln -s sbin/init linuxrc + +cd ventoy + +find ./loop | cpio -o -H newc --owner=root:root >loop.cpio +xz loop.cpio +rm -rf loop + +xz ventoy_chain.sh +xz ventoy_loop.sh + +find ./hook | cpio -o -H newc --owner=root:root >hook.cpio +xz hook.cpio +rm -rf hook +cd .. + +find .| cpio -o -H newc --owner=root:root >../ventoy.cpio + +cd .. +rm -rf cpio_tmp + + + + +########## cpio_x86 ############## +chmod -R 777 cpio_x86 +cp -a cpio_x86 cpio_tmp + +cd cpio_tmp/ventoy + +cp -a $VENTOY_PATH/DMSETUP/dmsetup32 tool/ +cp -a $VENTOY_PATH/DMSETUP/dmsetup64 tool/ +cp -a $VENTOY_PATH/SQUASHFS/unsquashfs_32 tool/ +cp -a $VENTOY_PATH/SQUASHFS/unsquashfs_64 tool/ +cp -a $VENTOY_PATH/FUSEISO/vtoy_fuse_iso_32 tool/ +cp -a $VENTOY_PATH/FUSEISO/vtoy_fuse_iso_64 tool/ +cp -a $VENTOY_PATH/VtoyTool/vtoytool tool/ +rm -f tool/vtoytool/00/vtoytool_aa64 +rm -f tool/vtoytool/00/vtoytool_m64e +cp -a $VENTOY_PATH/VBLADE/vblade-master/vblade_32 tool/ +cp -a $VENTOY_PATH/VBLADE/vblade-master/vblade_64 tool/ + +cp -a $VENTOY_PATH/LZIP/lunzip32 tool/ +cp -a $VENTOY_PATH/LZIP/lunzip64 tool/ + +cp -a $VENTOY_PATH/cryptsetup/veritysetup32 tool/ +cp -a $VENTOY_PATH/cryptsetup/veritysetup64 tool/ + +chmod -R 777 ./tool + +find ./tool | cpio -o -H newc --owner=root:root >tool.cpio +xz tool.cpio +rm -rf tool + +cd .. +find .| cpio -o -H newc --owner=root:root >../ventoy_x86.cpio + +cd .. +rm -rf cpio_tmp + + +########## cpio_arm64 ############## +chmod -R 777 cpio_arm64 +cp -a cpio_arm64 cpio_tmp +cp -a cpio_x86/ventoy/tool/*.sh cpio_tmp/ventoy/tool/ + +cd cpio_tmp/ventoy + +cp -a $VENTOY_PATH/DMSETUP/dmsetupaa64 tool/ +cp -a $VENTOY_PATH/SQUASHFS/unsquashfs_aa64 tool/ +cp -a $VENTOY_PATH/FUSEISO/vtoy_fuse_iso_aa64 tool/ +cp -a $VENTOY_PATH/VtoyTool/vtoytool tool/ +rm -f tool/vtoytool/00/vtoytool_32 +rm -f tool/vtoytool/00/vtoytool_64 +rm -f tool/vtoytool/00/vtoytool_m64e +cp -a $VENTOY_PATH/VBLADE/vblade-master/vblade_aa64 tool/ + +cp -a $VENTOY_PATH/LZIP/lunzipaa64 tool/ + +chmod -R 777 ./tool + +find ./tool | cpio -o -H newc --owner=root:root >tool.cpio +xz tool.cpio +rm -rf tool + +cd .. +find .| cpio -o -H newc --owner=root:root >../ventoy_arm64.cpio + +cd .. +rm -rf cpio_tmp + + + +########## cpio_mips64 ############## +chmod -R 777 cpio_mips64 +cp -a cpio_mips64 cpio_tmp +cp -a cpio_x86/ventoy/tool/*.sh cpio_tmp/ventoy/tool/ + +cd cpio_tmp/ventoy + +cp -a $VENTOY_PATH/DMSETUP/dmsetupm64e tool/ +# cp -a $VENTOY_PATH/SQUASHFS/unsquashfs_m64e tool/ +# cp -a $VENTOY_PATH/FUSEISO/vtoy_fuse_iso_m64e tool/ +cp -a $VENTOY_PATH/VtoyTool/vtoytool tool/ +rm -f tool/vtoytool/00/vtoytool_32 +rm -f tool/vtoytool/00/vtoytool_64 +rm -f tool/vtoytool/00/vtoytool_aa64 +# cp -a $VENTOY_PATH/VBLADE/vblade-master/vblade_m64e tool/ + +# cp -a $VENTOY_PATH/LZIP/lunzipaa64 tool/ + +chmod -R 777 ./tool + +find ./tool | cpio -o -H newc --owner=root:root >tool.cpio +xz tool.cpio +rm -rf tool + +cd .. +find .| cpio -o -H newc --owner=root:root >../ventoy_mips64.cpio + +cd .. +rm -rf cpio_tmp + + + + +echo '======== SUCCESS =============' + +rm -f $VENTOY_PATH/INSTALL/ventoy/ventoy.cpio +rm -f $VENTOY_PATH/INSTALL/ventoy/ventoy_x86.cpio +rm -f $VENTOY_PATH/INSTALL/ventoy/ventoy_arm64.cpio +rm -f $VENTOY_PATH/INSTALL/ventoy/ventoy_mips64.cpio +cp -a ventoy.cpio $VENTOY_PATH/INSTALL/ventoy/ +cp -a ventoy_x86.cpio $VENTOY_PATH/INSTALL/ventoy/ +cp -a ventoy_arm64.cpio $VENTOY_PATH/INSTALL/ventoy/ +cp -a ventoy_mips64.cpio $VENTOY_PATH/INSTALL/ventoy/ + diff --git a/IMG/mkloopex.sh b/IMG/mkloopex.sh new file mode 100644 index 0000000..1a87dec --- /dev/null +++ b/IMG/mkloopex.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +VENTOY_PATH=$PWD/../ + +rm -f vtloopex.cpio +cp -a vtloopex vtloopex_tmp +cd vtloopex_tmp + + +for dir in $(ls); do + cd $dir + tar -cJf vtloopex.tar.xz vtloopex + rm -rf vtloopex + cd .. +done + +find . | cpio -o -H newc --owner=root:root >../vtloopex.cpio + +cd .. + +rm -rf vtloopex_tmp + +rm -f $VENTOY_PATH/INSTALL/ventoy/vtloopex.cpio +cp -a vtloopex.cpio $VENTOY_PATH/INSTALL/ventoy/ + +echo '======== SUCCESS =============' + diff --git a/IMG/vtloopex/LibreELEC/vtloopex/dm-mod/5.1.16/64/dm-mod.ko.xz b/IMG/vtloopex/LibreELEC/vtloopex/dm-mod/5.1.16/64/dm-mod.ko.xz new file mode 100644 index 0000000..e4a5d79 Binary files /dev/null and b/IMG/vtloopex/LibreELEC/vtloopex/dm-mod/5.1.16/64/dm-mod.ko.xz differ diff --git a/IMG/vtloopex/LibreELEC/vtloopex/dm-mod/5.10.76/64/dm-mod.ko.xz b/IMG/vtloopex/LibreELEC/vtloopex/dm-mod/5.10.76/64/dm-mod.ko.xz new file mode 100644 index 0000000..5b078cf Binary files /dev/null and b/IMG/vtloopex/LibreELEC/vtloopex/dm-mod/5.10.76/64/dm-mod.ko.xz differ diff --git a/IMG/vtloopex/crux/vtloopex/dm-mod/4.19.48/64/dax.ko.xz b/IMG/vtloopex/crux/vtloopex/dm-mod/4.19.48/64/dax.ko.xz new file mode 100644 index 0000000..7b9e0df Binary files /dev/null and b/IMG/vtloopex/crux/vtloopex/dm-mod/4.19.48/64/dax.ko.xz differ diff --git a/IMG/vtloopex/crux/vtloopex/dm-mod/4.19.48/64/dm-mod.ko.xz b/IMG/vtloopex/crux/vtloopex/dm-mod/4.19.48/64/dm-mod.ko.xz new file mode 100644 index 0000000..bfefb61 Binary files /dev/null and b/IMG/vtloopex/crux/vtloopex/dm-mod/4.19.48/64/dm-mod.ko.xz differ diff --git a/IMG/vtloopex/dragora/vtloopex/dm-mod/4.19.79-gnu/64/dm-mod.ko.xz b/IMG/vtloopex/dragora/vtloopex/dm-mod/4.19.79-gnu/64/dm-mod.ko.xz new file mode 100644 index 0000000..14ff12f Binary files /dev/null and b/IMG/vtloopex/dragora/vtloopex/dm-mod/4.19.79-gnu/64/dm-mod.ko.xz differ diff --git a/IMG/vtloopex/kerio/vtloopex/dm-mod/3.16.0-k5-kerio-amd64/64/dm-mod.ko.xz b/IMG/vtloopex/kerio/vtloopex/dm-mod/3.16.0-k5-kerio-amd64/64/dm-mod.ko.xz new file mode 100644 index 0000000..27d9fcb Binary files /dev/null and b/IMG/vtloopex/kerio/vtloopex/dm-mod/3.16.0-k5-kerio-amd64/64/dm-mod.ko.xz differ diff --git a/IMG/vtloopex/lakka/vtloopex/dm-mod/4.11.12-rt14/64/dm-mod.ko.xz b/IMG/vtloopex/lakka/vtloopex/dm-mod/4.11.12-rt14/64/dm-mod.ko.xz new file mode 100644 index 0000000..20a1a7f Binary files /dev/null and b/IMG/vtloopex/lakka/vtloopex/dm-mod/4.11.12-rt14/64/dm-mod.ko.xz differ diff --git a/IMG/vtloopex/lakka/vtloopex/dm-mod/5.10.35/64/dax.ko.xz b/IMG/vtloopex/lakka/vtloopex/dm-mod/5.10.35/64/dax.ko.xz new file mode 100644 index 0000000..36d89ed Binary files /dev/null and b/IMG/vtloopex/lakka/vtloopex/dm-mod/5.10.35/64/dax.ko.xz differ diff --git a/IMG/vtloopex/lakka/vtloopex/dm-mod/5.10.35/64/dm-mod.ko.xz b/IMG/vtloopex/lakka/vtloopex/dm-mod/5.10.35/64/dm-mod.ko.xz new file mode 100644 index 0000000..347aa8a Binary files /dev/null and b/IMG/vtloopex/lakka/vtloopex/dm-mod/5.10.35/64/dm-mod.ko.xz differ diff --git a/IMG/vtloopex/openwrt/vtloopex/dm-mod/4.14.180/64/dm-mod.ko.xz b/IMG/vtloopex/openwrt/vtloopex/dm-mod/4.14.180/64/dm-mod.ko.xz new file mode 100644 index 0000000..b201ca3 Binary files /dev/null and b/IMG/vtloopex/openwrt/vtloopex/dm-mod/4.14.180/64/dm-mod.ko.xz differ diff --git a/IMG/vtloopex/vine/vtloopex/dm-mod/4.4.52-2vl6/64/dm-mod.ko.xz b/IMG/vtloopex/vine/vtloopex/dm-mod/4.4.52-2vl6/64/dm-mod.ko.xz new file mode 100644 index 0000000..84084f6 Binary files /dev/null and b/IMG/vtloopex/vine/vtloopex/dm-mod/4.4.52-2vl6/64/dm-mod.ko.xz differ diff --git a/INSTALL/CreatePersistentImg.sh b/INSTALL/CreatePersistentImg.sh new file mode 100644 index 0000000..21d65c4 --- /dev/null +++ b/INSTALL/CreatePersistentImg.sh @@ -0,0 +1,140 @@ +#!/bin/bash + +size=1024 +fstype=ext4 +label=casper-rw +config='' +outputfile=persistence.dat + +print_usage() { + echo 'Usage: sudo ./CreatePersistentImg.sh [ -s size ] [ -t fstype ] [ -l LABEL ] [ -c CFG ] [ -e ]' + echo ' OPTION: (optional)' + echo ' -s size in MB, default is 1024' + echo ' -t filesystem type, default is ext4 ext2/ext3/ext4/xfs are supported now' + echo ' -l label, default is casper-rw' + echo ' -c configfile name inside the persistence file. File content is "/ union"' + echo ' -o outputfile name, default is persistence.dat' + echo ' -e enable encryption, disabled by default (only few distros support this)' + echo '' +} + +print_err() { + echo "" + echo "$*" + echo "" +} + +uid=$(id -u) +if [ $uid -ne 0 ]; then + print_err "Please use sudo or run the script as root." + exit 1 +fi + +while [ -n "$1" ]; do + if [ "$1" = "-s" ]; then + shift + size=$1 + elif [ "$1" = "-t" ]; then + shift + fstype=$1 + elif [ "$1" = "-l" ]; then + shift + label=$1 + elif [ "$1" = "-c" ]; then + shift + config=$1 + elif [ "$1" = "-o" ]; then + shift + outputfile=$1 + elif [ "$1" = "-e" ]; then + read -s -p "Encryption passphrase: " passphrase + echo + elif [ "$1" = "-h" ] || [ "$1" = "--help" ]; then + print_usage + exit 0 + else + print_usage + exit 1 + fi + shift +done + + +# check label +if [ -z "$label" ]; then + echo "The label can NOT be empty." + exit 1 +fi + +# check size +if echo $size | grep -q "^[0-9][0-9]*$"; then + vtMinSize=1 + if echo $fstype | grep -q '^xfs$'; then + vtMinSize=16 + fi + + if [ $size -lt $vtMinSize ]; then + echo "size too small ($size)" + exit 1 + fi +else + echo "Invalid size $size" + exit 1 +fi + + +# check file system type +# nodiscard must be set for ext2/3/4 +# -K must be set for xfs +if echo $fstype | grep -q '^ext[234]$'; then + fsopt='-E nodiscard' +elif [ "$fstype" = "xfs" ]; then + fsopt='-K' +else + echo "unsupported file system $fstype" + exit 1 +fi + +if [ "$outputdir" != "persistence.dat" ]; then + mkdir -p "$(dirname "$outputfile")" +fi + +# 00->ff avoid sparse file +dd if=/dev/zero bs=1M count=$size | tr '\000' '\377' > "$outputfile" +sync + +freeloop=$(losetup -f) + +losetup $freeloop "$outputfile" + +if [ ! -z "$passphrase" ]; then + printf "$passphrase" | cryptsetup -q --verbose luksFormat $freeloop - + printf "$passphrase" | cryptsetup -q --verbose luksOpen $freeloop persist_decrypted - + _freeloop=$freeloop + freeloop="/dev/mapper/persist_decrypted" +fi + +mkfs -t $fstype $fsopt -L $label $freeloop + +sync + +if [ -n "$config" ]; then + if [ -d ./persist_tmp_mnt ]; then + rm -rf ./persist_tmp_mnt + fi + + mkdir ./persist_tmp_mnt + if mount $freeloop ./persist_tmp_mnt; then + echo '/ union' > ./persist_tmp_mnt/$config + sync + umount ./persist_tmp_mnt + fi + rm -rf ./persist_tmp_mnt +fi + +if [ ! -z "$passphrase" ]; then + cryptsetup luksClose $freeloop + freeloop=$_freeloop +fi + +losetup -d $freeloop diff --git a/INSTALL/DO_NOT_RUN_Ventoy2Disk_HERE.txt b/INSTALL/DO_NOT_RUN_Ventoy2Disk_HERE.txt new file mode 100644 index 0000000..1562085 --- /dev/null +++ b/INSTALL/DO_NOT_RUN_Ventoy2Disk_HERE.txt @@ -0,0 +1,5 @@ +For Ventoy2Disk.exe (Windows) or Ventoy2Disk.sh (Linux). + +You should download the install package, decompress it, and run the exe/sh there. +They should NOT be run in the source tree(INSTALL directory). + diff --git a/INSTALL/EFI/BOOT/BOOTAA64.EFI b/INSTALL/EFI/BOOT/BOOTAA64.EFI new file mode 100644 index 0000000..c7134c2 Binary files /dev/null and b/INSTALL/EFI/BOOT/BOOTAA64.EFI differ diff --git a/INSTALL/EFI/BOOT/BOOTIA32.EFI b/INSTALL/EFI/BOOT/BOOTIA32.EFI new file mode 100644 index 0000000..2db79d9 Binary files /dev/null and b/INSTALL/EFI/BOOT/BOOTIA32.EFI differ diff --git a/INSTALL/EFI/BOOT/BOOTMIPS.EFI b/INSTALL/EFI/BOOT/BOOTMIPS.EFI new file mode 100644 index 0000000..dfae576 Binary files /dev/null and b/INSTALL/EFI/BOOT/BOOTMIPS.EFI differ diff --git a/INSTALL/EFI/BOOT/BOOTX64.EFI b/INSTALL/EFI/BOOT/BOOTX64.EFI new file mode 100644 index 0000000..8e56af7 Binary files /dev/null and b/INSTALL/EFI/BOOT/BOOTX64.EFI differ diff --git a/INSTALL/EFI/BOOT/grubia32.efi b/INSTALL/EFI/BOOT/grubia32.efi new file mode 100644 index 0000000..2d7ea64 Binary files /dev/null and b/INSTALL/EFI/BOOT/grubia32.efi differ diff --git a/INSTALL/EFI/BOOT/grubia32_real.efi b/INSTALL/EFI/BOOT/grubia32_real.efi new file mode 100644 index 0000000..b917fec Binary files /dev/null and b/INSTALL/EFI/BOOT/grubia32_real.efi differ diff --git a/INSTALL/EFI/BOOT/grubx64_real.efi b/INSTALL/EFI/BOOT/grubx64_real.efi new file mode 100644 index 0000000..15bcfa1 Binary files /dev/null and b/INSTALL/EFI/BOOT/grubx64_real.efi differ diff --git a/INSTALL/EFI/BOOT/mmia32.efi b/INSTALL/EFI/BOOT/mmia32.efi new file mode 100644 index 0000000..f59515f Binary files /dev/null and b/INSTALL/EFI/BOOT/mmia32.efi differ diff --git a/INSTALL/EFI/BOOT/mmx64.efi b/INSTALL/EFI/BOOT/mmx64.efi new file mode 100644 index 0000000..38ab7c1 Binary files /dev/null and b/INSTALL/EFI/BOOT/mmx64.efi differ diff --git a/INSTALL/ExtendPersistentImg.sh b/INSTALL/ExtendPersistentImg.sh new file mode 100644 index 0000000..5f8b852 --- /dev/null +++ b/INSTALL/ExtendPersistentImg.sh @@ -0,0 +1,145 @@ +#!/bin/bash + +print_usage() { + echo 'Usage: ExtendPersistentImg.sh file size' + echo ' file persistent dat file' + echo ' size extend size in MB' + echo 'Examples:' + echo ' sh ExtendPersistentImg.sh ubuntu.dat 2048 - This command would extend ubuntu.dat by 2048MB (2GB)' + echo ' sh ExtendPersistentImg.sh ubuntu.dat -2048 - This command reduces ubuntu.dat by 2048MB (-2GB)' + echo '' +} + +if [ -z "$1" -o "$1" = "-h" ]; then + print_usage + exit 1 +fi + +if [ -z "$2" ]; then + print_usage + exit 1 +fi + +uid=$(id -u) +if [ $uid -ne 0 ]; then + print_err "Please use sudo or run the script as root." + exit 1 +fi + +if [ "$1" = "__vbash__" ]; then + shift +else + if readlink /bin/sh | grep -q bash; then + : + else + exec /bin/bash $0 "__vbash__" "$@" + fi +fi + + +file=$1 +size=$2 + +if [ ! -f "$file" ]; then + echo "$file not exist." + exit 1 +fi + +if echo $size | grep -q "^-"; then + mode="Shrink" + size=${size:1} +else + mode="Extend" +fi + +if echo $size | grep -q "[^0-9]"; then + print_usage + exit 1 +fi + +fsize=$(stat -c '%s' $file) + +fsmod=$(expr $fsize % 1024) +if [ $fsmod -ne 0 ]; then + echo "File size of $file is not aligned by 1MB, please check." + exit 1 +fi + + +fsMB=$(expr $fsize / 1024 / 1024) + +if [ "$mode" = "Extend" ]; then + total=$(expr $fsMB + $size) +else + if [ $fsMB -le $size ]; then + echo "File size of $file is less than ${size}MB." + exit 1 + fi + total=$(expr $fsMB - $size) +fi + + +magic=$(hexdump -n3 -e '3/1 "%02X"' $file) +if [ "$magic" = "584653" ]; then + if [ "$mode" = "Shrink" ]; then + echo "Shrink is not supported for XFS filesystem." + exit 1 + fi + + if which xfs_growfs >/dev/null 2>&1; then + cmd=xfs_growfs + else + echo 'xfs_growfs not found, please install xfsprogs first' + exit 1 + fi +else + if which resize2fs >/dev/null 2>&1; then + cmd=resize2fs + else + echo 'resize2fs not found, please install e2fsprogs first' + exit 1 + fi +fi + +if [ "$mode" = "Extend" ]; then + echo "$mode dat file... (current is ${fsMB}MB, append ${size}MB, total ${total}MB)" + dd if=/dev/zero bs=1M count=$size status=none >> "$file" + sync +else + echo "$mode dat file... (current is ${fsMB}MB, reduce ${size}MB, finally ${total}MB)" +fi + + +freeloop=$(losetup -f) +losetup $freeloop "$file" + +if [ "$cmd" = "resize2fs" ]; then + echo "$mode ext filesystem by resize2fs ..." + echo "resize2fs $freeloop ${total}M" + e2fsck -f $freeloop + resize2fs $freeloop ${total}M + ret=$? +else + echo "$mode xfs filesystem by xfs_growfs ..." + tmpdir=$(mktemp -d) + mount $freeloop $tmpdir + xfs_growfs $freeloop + ret=$? + umount $tmpdir && rm -rf $tmpdir +fi + +losetup -d $freeloop + +if [ $ret -eq 0 -a "$mode" = "Shrink" ]; then + echo "truncate persistent file ..." + truncate "$file" -s ${total}M + ret=$? +fi + +echo "" +if [ $ret -eq 0 ]; then + echo "======= SUCCESS =========" +else + echo "======= FAILED =========" +fi +echo "" diff --git a/INSTALL/FOR_X64_ARM.txt b/INSTALL/FOR_X64_ARM.txt new file mode 100644 index 0000000..d1b82ae --- /dev/null +++ b/INSTALL/FOR_X64_ARM.txt @@ -0,0 +1,12 @@ +============ Ventoy2Disk.exe for x86_64/ARM/ARM64 ================= +Ventoy2Disk.exe is a x86_32 application and supports both 32-bit and 64-bit Windows PC with intel/amd processor. +Since 1.0.58, Ventoy also provides Ventoy2Disk_X64.exe/Ventoy2Disk_ARM.exe/Ventoy2Disk_ARM64.exe you can use them if needed. +These exe files are in altexe directory of the installation package. +You must copy them to the upper directory to use them. (The same location with Ventoy2Disk.exe) + + +============ x86_64/ARM/ARM64 版本 Ventoy2Disk.exe ================= +默认的 Ventoy2Disk.exe 是32位x86程序,同时支持最常见的32位和64位Windows系统,绝大部分情况下使用它就可以。 +从1.0.58版本开始,Ventoy还同时提供了 Ventoy2Disk_X64.exe/Ventoy2Disk_ARM.exe/Ventoy2Disk_ARM64.exe 可以根据需要使用。 +这些文件位于安装包内的altexe目录下,使用时需要将其拷贝到上一层目录(即和 Ventoy2Disk.exe 同一位置)。 + diff --git a/INSTALL/README b/INSTALL/README new file mode 100644 index 0000000..fc86d90 --- /dev/null +++ b/INSTALL/README @@ -0,0 +1,66 @@ + +========== Ventoy2Disk.sh =============== + +sudo bash Ventoy2Disk.sh { -i | -I | -u } /dev/sdX sdX is the USB device, for example /dev/sdb. + +Ventoy2Disk.sh CMD [ OPTION ] /dev/sdX + CMD: + -i install ventoy to sdX (fail if disk already installed with ventoy) + -I force install ventoy to sdX (no matter installed or not) + -u update ventoy in sdX + + OPTION: (optional) + -r SIZE_MB preserve some space at the bottom of the disk (only for install) + -s enable secure boot support (default is enabled) + -S disable secure boot support (default is enabled) + -g use GPT partition style, default is MBR style (only for install) + +Please refer https://www.ventoy.net/en/doc_start.html for details. + + +========== VentoyWeb.sh =============== +1. sudo bash VentoyWeb.sh +2. open your browser and visit http://127.0.0.1:24680 + + +========== VentoyPlugson.sh =============== +1. sudo bash VentoyPlugson.sh /dev/sdX +2. open your browser and visit http://127.0.0.1:24681 + +========== VentoyVlnk.sh =============== +Usage: sudo bash VentoyVlnk.sh CMD FILE + CMD: + -c FILE create vlnk for FILE + -l VLNK parse vlnk file + -v print verbose info + -h print this help + + +========= VentoyGUI =================== +VentoyGUI is native GUI program for Linux (GTK/QT) +1. Just double-click the file (e.g. VentoyGUI.x86_64) +2. If it can not startup after double-click, you can open the terminal and just execute the file (e.g. ./VentoyGUI.x86_64) + + +========== CreatePersistentImg.sh =============== + +sudo bash CreatePersistentImg.sh [ -s SIZE_IN_MB ] [ -t FSTYPE ] [ -l LABEL ] for example: + +bash CreatePersistentImg.sh ----> persistence.dat in 1GB size and ext4 filesystem and casper-rw label +bash CreatePersistentImg.sh -l MX-Persist ----> persistence.dat in 1GB size and ext4 filesystem and MX-Persist label +bash CreatePersistentImg.sh -s 2048 ----> persistence.dat in 2GB size and ext4 filesystem and casper-rw label +bash CreatePersistentImg.sh -s 4096 -t xfs ----> persistence.dat in 4GB size and xfs filesystem (ext2/3/4 xfs are supported) and casper-rw label + +Please refer https://www.ventoy.net/en/plugin_persistence.html for details. + + + +========== ExtendPersistentImg.sh =============== +sudo bash ExtendPersistentImg.sh file size +For example: +bash ExtendPersistentImg.sh persistence.dat 2048 ----> Extend persistence.dat by 2048MB +That is to say, persistence.dat file will grow to 3GB size (assume that it is 1GB size before extend) + +Please refer https://www.ventoy.net/en/plugin_persistence.html for details. + + diff --git a/INSTALL/Ventoy2Disk.exe b/INSTALL/Ventoy2Disk.exe new file mode 100644 index 0000000..dd04b5c Binary files /dev/null and b/INSTALL/Ventoy2Disk.exe differ diff --git a/INSTALL/Ventoy2Disk.sh b/INSTALL/Ventoy2Disk.sh new file mode 100644 index 0000000..6156804 --- /dev/null +++ b/INSTALL/Ventoy2Disk.sh @@ -0,0 +1,88 @@ +#!/bin/sh + +if ! [ -f ./tool/ventoy_lib.sh ]; then + if [ -f ${0%Ventoy2Disk.sh}/tool/ventoy_lib.sh ]; then + cd ${0%Ventoy2Disk.sh} + fi +fi + +if [ -f ./ventoy/version ]; then + curver=$(cat ./ventoy/version) +fi + +if uname -m | grep -E -q 'aarch64|arm64'; then + export TOOLDIR=aarch64 +elif uname -m | grep -E -q 'x86_64|amd64'; then + export TOOLDIR=x86_64 +elif uname -m | grep -E -q 'mips64'; then + export TOOLDIR=mips64el +else + export TOOLDIR=i386 +fi +export PATH="$(pwd)/tool/$TOOLDIR:$PATH" + + +echo '' +echo '**********************************************' +echo " Ventoy: $curver $TOOLDIR" +echo " longpanda admin@ventoy.net" +echo " https://www.ventoy.net" +echo '**********************************************' +echo '' + + +if ! [ -f ./boot/boot.img ]; then + if [ -d ./grub ]; then + echo "Don't run Ventoy2Disk.sh here, please download the released install package, and run the script in it." + else + echo "Please run under the correct directory!" + fi + exit 1 +fi + +echo "############# Ventoy2Disk $* [$TOOLDIR] ################" >> ./log.txt +date >> ./log.txt + +#decompress tool +echo "decompress tools" >> ./log.txt +cd ./tool/$TOOLDIR + +ls *.xz > /dev/null 2>&1 +if [ $? -eq 0 ]; then + [ -f ./xzcat ] && chmod +x ./xzcat + + for file in $(ls *.xz); do + echo "decompress $file" >> ./log.txt + xzcat $file > ${file%.xz} + [ -f ./${file%.xz} ] && chmod +x ./${file%.xz} + [ -f ./$file ] && rm -f ./$file + done +fi + +#use static linked mkexfatfs for musl-libc environment +if [ -f mkexfatfs_static ]; then + if ldd --version 2>&1 | grep -qi musl; then + mv mkexfatfs mkexfatfs_shared + mv mkexfatfs_static mkexfatfs + else + if ./mkexfatfs -V > /dev/null 2>&1; then + echo "mkexfatfs can not run, check static version" >> ./log.txt + else + if ./mkexfatfs_static -V > /dev/null 2>&1; then + echo "Use static version of mkexfatfs" >> ./log.txt + mv mkexfatfs mkexfatfs_shared + mv mkexfatfs_static mkexfatfs + fi + fi + fi +fi + +cd ../../ +chmod +x -R ./tool/$TOOLDIR + + +if [ -f /bin/bash ]; then + /bin/bash ./tool/VentoyWorker.sh $* +else + ash ./tool/VentoyWorker.sh $* +fi diff --git a/INSTALL/Ventoy2Disk_ARM.exe b/INSTALL/Ventoy2Disk_ARM.exe new file mode 100644 index 0000000..3d31509 Binary files /dev/null and b/INSTALL/Ventoy2Disk_ARM.exe differ diff --git a/INSTALL/Ventoy2Disk_ARM64.exe b/INSTALL/Ventoy2Disk_ARM64.exe new file mode 100644 index 0000000..a822bd4 Binary files /dev/null and b/INSTALL/Ventoy2Disk_ARM64.exe differ diff --git a/INSTALL/Ventoy2Disk_X64.exe b/INSTALL/Ventoy2Disk_X64.exe new file mode 100644 index 0000000..2a9635c Binary files /dev/null and b/INSTALL/Ventoy2Disk_X64.exe differ diff --git a/INSTALL/VentoyGUI.aarch64 b/INSTALL/VentoyGUI.aarch64 new file mode 100644 index 0000000..632562e Binary files /dev/null and b/INSTALL/VentoyGUI.aarch64 differ diff --git a/INSTALL/VentoyGUI.i386 b/INSTALL/VentoyGUI.i386 new file mode 100644 index 0000000..412e939 Binary files /dev/null and b/INSTALL/VentoyGUI.i386 differ diff --git a/INSTALL/VentoyGUI.mips64el b/INSTALL/VentoyGUI.mips64el new file mode 100644 index 0000000..44125d5 Binary files /dev/null and b/INSTALL/VentoyGUI.mips64el differ diff --git a/INSTALL/VentoyGUI.x86_64 b/INSTALL/VentoyGUI.x86_64 new file mode 100644 index 0000000..d9e1944 Binary files /dev/null and b/INSTALL/VentoyGUI.x86_64 differ diff --git a/INSTALL/VentoyPlugson.sh b/INSTALL/VentoyPlugson.sh new file mode 100644 index 0000000..255c5f6 --- /dev/null +++ b/INSTALL/VentoyPlugson.sh @@ -0,0 +1,227 @@ +#!/bin/bash + +. ./tool/ventoy_lib.sh + +print_usage() { + echo 'Usage: sudo bash VentoyPlugson.sh [OPTION] /dev/sdX' + echo ' OPTION: (optional)' + echo ' -H x.x.x.x http server IP address (default is 127.0.0.1)' + echo ' -P PORT http server PORT (default is 24681)' + echo ' -h print this help' + echo '' +} + +uid=$(id -u) +if [ $uid -ne 0 ]; then + echo "Please use sudo or run the script as root." + exit 1 +fi + +if [ "$1" = "__vbash__" ]; then + shift +else + if readlink /bin/sh | grep -q bash; then + : + else + exec /bin/bash $0 "__vbash__" "$@" + fi +fi + +OLDDIR=$(pwd) + +machine=$(uname -m) +if echo $machine | grep -E -q 'aarch64|arm64'; then + TOOLDIR=aarch64 +elif echo $machine | grep -E -q 'x86_64|amd64'; then + TOOLDIR=x86_64 +elif echo $machine | grep -E -q 'mips64'; then + TOOLDIR=mips64el +elif echo $machine | grep -E -q 'i[3-6]86'; then + TOOLDIR=i386 +else + echo "Unsupported machine type $machine" + exit 1 +fi + + +if ! [ -f "$OLDDIR/tool/plugson.tar.xz" ]; then + echo "Please run under the correct directory!" + exit 1 +fi + +echo "############# VentoyPlugson $* [$TOOLDIR] ################" >> ./VentoyPlugson.log +date >> ./VentoyPlugson.log + +echo "decompress tools" >> ./VentoyPlugson.log +cd ./tool/$TOOLDIR + +ls *.xz > /dev/null 2>&1 +if [ $? -eq 0 ]; then + [ -f ./xzcat ] && chmod +x ./xzcat + + for file in $(ls *.xz); do + echo "decompress $file" >> ./VentoyPlugson.log + xzcat $file > ${file%.xz} + [ -f ./${file%.xz} ] && chmod +x ./${file%.xz} + [ -f ./$file ] && rm -f ./$file + done +fi + +cd ../../ +chmod +x -R ./tool/$TOOLDIR + +if ! [ -f "$OLDDIR/tool/$TOOLDIR/Plugson" ]; then + echo "$OLDDIR/tool/$TOOLDIR/Plugson does not exist!" + exit 1 +fi + + +PATH=./tool/$TOOLDIR:$PATH + +HOST="127.0.0.1" +PORT=24681 + +while [ -n "$1" ]; do + if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then + print_usage + exit 0 + elif [ "$1" = "-H" ]; then + shift + if echo $1 | grep -q '[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*'; then + HOST="$1" + else + echo "Invalid host $1" + exit 1 + fi + elif [ "$1" = "-P" ]; then + shift + if [ $1 -gt 0 -a $1 -le 65535 ]; then + PORT="$1" + else + echo "Invalid port $1" + exit 1 + fi + else + DISK=$1 + fi + + shift +done + +if [ -z "$DISK" ]; then + print_usage + exit 0 +fi + +if ps -ef | grep "tool/$TOOLDIR/Plugson.*$HOST.*$PORT" | grep -q -v grep; then + echo "Another ventoy server is running now, please close it first." + exit 1 +fi + +if echo $DISK | grep -q "[a-z]d[a-z][1-9]"; then + DISK=${DISK:0:-1} +fi + +if echo $DISK | grep -E -q "/dev/nvme|/dev/mmcblk/dev/nbd"; then + if echo $DISK | grep -q "p[1-9]$"; then + DISK=${DISK:0:-2} + fi +fi + + +if [ ! -b "$DISK" ]; then + echo "$DISK does NOT exist." + exit 1 +fi + + +version=$(get_disk_ventoy_version $DISK) +if [ $? -eq 0 ]; then + echo "Ventoy version in Disk: $version" + + vtPart1Type=$(dd if=$DISK bs=1 count=1 skip=450 status=none | hexdump -n1 -e '1/1 "%02X"') + if [ "$vtPart1Type" = "EE" ]; then + echo "Disk Partition Style : GPT" + partstyle=1 + else + echo "Disk Partition Style : MBR" + partstyle=0 + fi + + if check_disk_secure_boot $DISK; then + echo "Secure Boot Support : YES" + secureboot=1 + else + echo "Secure Boot Support : NO" + secureboot=0 + fi +else + echo "$DISK is NOT Ventoy disk." + exit 1 +fi + +PART1=$(get_disk_part_name $DISK 1) + +if grep -q "^$PART1 " /proc/mounts; then + mtpnt=$(grep "^$PART1 " /proc/mounts | awk '{print $2}' | sed 's/\\040/ /g') + fstype=$(grep "^$PART1 " /proc/mounts | awk '{print $3}') + + if echo $fstype | grep -q -i 'fuse'; then + if hexdump -C -n 16 $PART1 | grep -q -i "EXFAT"; then + fstype="exFAT" + elif hexdump -C -n 16 $PART1 | grep -q -i "NTFS"; then + fstype="NTFS" + fi + fi + + echo "$PART1 is mounted at $mtpnt $fstype" +else + echo "$PART1 is NOT mounted, please mount it first!" + exit 1 +fi + +if [ -d "$mtpnt/ventoy" ]; then + echo "ventoy directory exist OK" +else + echo "create ventoy directory" + mkdir -p "$mtpnt/ventoy" + if [ -d "$mtpnt/ventoy" ]; then + chmod -R 0755 "$mtpnt/ventoy" + else + echo "Failed to create directory $mtpnt/ventoy" + exit 1 + fi +fi + + +#change current directory to Ventoy disk +cd "$mtpnt" +"$OLDDIR/tool/$TOOLDIR/Plugson" "$HOST" "$PORT" "$OLDDIR" "$DISK" $version "$fstype" $partstyle $secureboot & +wID=$! +sleep 1 + +if [ -f /proc/$wID/maps ]; then + echo "" + echo "===============================================================" + if [ "$LANG" = "zh_CN.UTF-8" ]; then + echo " Ventoy Plugson Server 已经启动 ..." + echo " 请打开浏览器,访问 http://${HOST}:${PORT}" + else + echo " Ventoy Plugson Server is running ..." + echo " Please open your browser and visit http://${HOST}:${PORT}" + fi + echo "===============================================================" + echo "" + echo "################## Press Ctrl + C to exit #####################" + echo "" + + wait $wID +fi + + +if [ -n "$OLDDIR" ]; then + CURDIR=$(pwd) + if [ "$CURDIR" != "$OLDDIR" ]; then + cd "$OLDDIR" + fi +fi diff --git a/INSTALL/VentoyWeb.sh b/INSTALL/VentoyWeb.sh new file mode 100644 index 0000000..537348a --- /dev/null +++ b/INSTALL/VentoyWeb.sh @@ -0,0 +1,130 @@ +#!/bin/bash + +print_usage() { + echo 'Usage: VentoyWeb.sh [ OPTION ]' + echo ' OPTION: (optional)' + echo ' -H x.x.x.x http server IP address (default is 127.0.0.1)' + echo ' -p PORT http server PORT (default is 24680)' + echo ' -h print this help' + echo '' +} + +print_err() { + echo "" + echo "$*" + echo "" +} + +uid=$(id -u) +if [ $uid -ne 0 ]; then + print_err "Please use sudo or run the script as root." + exit 1 +fi + +OLDDIR=$(pwd) + +if uname -m | grep -E -q 'aarch64|arm64'; then + TOOLDIR=aarch64 +elif uname -m | grep -E -q 'x86_64|amd64'; then + TOOLDIR=x86_64 +elif uname -m | grep -E -q 'mips64'; then + TOOLDIR=mips64el +else + TOOLDIR=i386 +fi + +if [ ! -f ./tool/$TOOLDIR/V2DServer ]; then + if [ -f ${0%VentoyWeb.sh}/tool/$TOOLDIR/V2DServer ]; then + cd ${0%VentoyWeb.sh} + fi +fi + +PATH=./tool/$TOOLDIR:$PATH + +if [ ! -f ./boot/boot.img ]; then + if [ -d ./grub ]; then + echo "Don't run VentoyWeb.sh here, please download the released install package, and run the script in it." + else + echo "Current directory is $PWD" + echo "Please run under the correct directory!" + fi + exit 1 +fi + +HOST="127.0.0.1" +PORT=24680 + +while [ -n "$1" ]; do + if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then + print_usage + exit 0 + elif [ "$1" = "-H" ]; then + shift + if echo $1 | grep -q '[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*'; then + HOST="$1" + else + print_err "Invalid host $1" + exit 1 + fi + elif [ "$1" = "-p" ]; then + shift + if [ $1 -gt 0 -a $1 -le 65535 ]; then + PORT="$1" + else + print_err "Invalid port $1" + exit 1 + fi + fi + + shift +done + + +if ps -ef | grep "V2DServer.*$HOST.*$PORT" | grep -q -v grep; then + print_err "Another ventoy server is running now, please close it first." + exit 1 +fi + +LOGFILE=log.txt +#delete the log.txt if it's more than 8MB +if [ -f $LOGFILE ]; then + logsize=$(stat -c '%s' $LOGFILE) + if [ $logsize -gt 8388608 ]; then + rm -f $LOGFILE + fi +fi + + +if [ -f ./tool/$TOOLDIR/V2DServer.xz ]; then + xz -d ./tool/$TOOLDIR/V2DServer.xz + chmod +x ./tool/$TOOLDIR/V2DServer +fi + + +V2DServer "$HOST" "$PORT" & +wID=$! +sleep 1 + +vtVer=$(cat ventoy/version) +echo "" +echo "===============================================================" +if [ "$LANG" = "zh_CN.UTF-8" ]; then + echo " Ventoy Server $vtVer 已经启动 ..." + echo " 请打开浏览器,访问 http://${HOST}:${PORT}" +else + echo " Ventoy Server $vtVer is running ..." + echo " Please open your browser and visit http://${HOST}:${PORT}" +fi +echo "===============================================================" +echo "" +echo "################## Press Ctrl + C to exit #####################" +echo "" + +wait $wID + +if [ -n "$OLDDIR" ]; then + CURDIR=$(pwd) + if [ "$CURDIR" != "$OLDDIR" ]; then + cd "$OLDDIR" + fi +fi diff --git a/INSTALL/all_in_one.sh b/INSTALL/all_in_one.sh new file mode 100644 index 0000000..827c80b --- /dev/null +++ b/INSTALL/all_in_one.sh @@ -0,0 +1,81 @@ +#!/bin/sh + +VTOY_PATH=$PWD/.. + +cilog() { + datestr=$(date +"%Y/%m/%d %H:%M:%S") + echo "$datestr $*" +} + +LOG=$VTOY_PATH/DOC/build.log +[ -f $LOG ] && rm -f $LOG + +cd $VTOY_PATH/DOC +cilog "prepare_env ..." +sh prepare_env.sh + +export PATH=$PATH:/opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/bin:/opt/aarch64--uclibc--stable-2020.08-1/bin:/opt/mips-loongson-gcc7.3-linux-gnu/2019.06-29/bin/:/opt/mips64el-linux-musl-gcc730/bin/ + +cilog "build grub2 ..." +cd $VTOY_PATH/GRUB2 +sh buildgrub.sh >> $LOG 2>&1 || exit 1 + +cilog "build ipxe ..." +cd $VTOY_PATH/IPXE +sh buildipxe.sh >> $LOG 2>&1 || exit 1 + +cilog "build edk2 ..." +cd $VTOY_PATH/EDK2 +sh buildedk.sh >> $LOG 2>&1 || exit 1 + + + +# +# We almost rarely modifiy these code, so no need to build them everytime +# If you want to rebuild them, just uncomment them. +# + +#cd $VTOY_PATH/VtoyTool +#sh build.sh || exit 1 + +#cd $VTOY_PATH/vtoycli/fat_io_lib +#sh buildlib.sh + +#cd $VTOY_PATH/vtoycli +#sh build.sh || exit 1 + +#cd $VTOY_PATH/FUSEISO +#sh build_libfuse.sh +#sh build.sh + + +# cd $VTOY_PATH/ExFAT +# sh buidlibfuse.sh || exit 1 +# sh buidexfat.sh || exit 1 +# /bin/cp -a EXFAT/shared/mkexfatfs $VTOY_PATH/INSTALL/tool/mkexfatfs_64 +# /bin/cp -a EXFAT/shared/mount.exfat-fuse $VTOY_PATH/INSTALL/tool/mount.exfat-fuse_64 + + +# cd $VTOY_PATH/SQUASHFS/SRC +# sh build_lz4.sh +# sh build_lzma.sh +# sh build_lzo.sh +# sh build_zstd.sh + +# cd $VTOY_PATH/SQUASHFS/squashfs-tools-4.4/squashfs-tools +# sh build.sh + +# cd $VTOY_PATH/VBLADE/vblade-master +# sh build.sh + +cd $VTOY_PATH/INSTALL + +if [ "$1" = "CI" ]; then + Ver=$(date +%m%d%H%M) + sed "s/VENTOY_VERSION=.*/VENTOY_VERSION=\"$Ver\"/" -i ./grub/grub.cfg +fi + +cilog "packing ventoy-$Ver ..." +sh ventoy_pack.sh $1 >> $LOG 2>&1 || exit 1 + +echo -e '\n============== SUCCESS ==================\n' diff --git a/INSTALL/docker_ci_build.sh b/INSTALL/docker_ci_build.sh new file mode 100644 index 0000000..63583a0 --- /dev/null +++ b/INSTALL/docker_ci_build.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +VTOY_PATH=$PWD/.. + +date +"%Y/%m/%d %H:%M:%S" +echo downloading environment ... + +wget -q -P $VTOY_PATH/DOC/ https://github.com/ventoy/vtoytoolchain/releases/download/1.0/dietlibc-0.34.tar.xz +wget -q -P $VTOY_PATH/DOC/ https://github.com/ventoy/vtoytoolchain/releases/download/1.0/musl-1.2.1.tar.gz +wget -q -P $VTOY_PATH/GRUB2/ https://github.com/ventoy/vtoytoolchain/releases/download/1.0/grub-2.04.tar.xz +wget -q -O $VTOY_PATH/EDK2/edk2-edk2-stable201911.zip https://codeload.github.com/tianocore/edk2/zip/edk2-stable201911 +wget -q -P /opt/ https://github.com/ventoy/vtoytoolchain/releases/download/1.0/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz +wget -q -P /opt/ https://github.com/ventoy/vtoytoolchain/releases/download/1.0/aarch64--uclibc--stable-2020.08-1.tar.bz2 +wget -q -P /opt/ https://github.com/ventoy/vtoytoolchain/releases/download/1.0/mips-loongson-gcc7.3-2019.06-29-linux-gnu.tar.gz + +date +"%Y/%m/%d %H:%M:%S" +echo downloading environment finish... + +sh all_in_one.sh CI diff --git a/INSTALL/grub/arm64-efi/adler32.mod b/INSTALL/grub/arm64-efi/adler32.mod new file mode 100644 index 0000000..806c5da Binary files /dev/null and b/INSTALL/grub/arm64-efi/adler32.mod differ diff --git a/INSTALL/grub/arm64-efi/affs.mod b/INSTALL/grub/arm64-efi/affs.mod new file mode 100644 index 0000000..2042c17 Binary files /dev/null and b/INSTALL/grub/arm64-efi/affs.mod differ diff --git a/INSTALL/grub/arm64-efi/afs.mod b/INSTALL/grub/arm64-efi/afs.mod new file mode 100644 index 0000000..5bc5cb1 Binary files /dev/null and b/INSTALL/grub/arm64-efi/afs.mod differ diff --git a/INSTALL/grub/arm64-efi/archelp.mod b/INSTALL/grub/arm64-efi/archelp.mod new file mode 100644 index 0000000..c4729ba Binary files /dev/null and b/INSTALL/grub/arm64-efi/archelp.mod differ diff --git a/INSTALL/grub/arm64-efi/bfs.mod b/INSTALL/grub/arm64-efi/bfs.mod new file mode 100644 index 0000000..fc7dae2 Binary files /dev/null and b/INSTALL/grub/arm64-efi/bfs.mod differ diff --git a/INSTALL/grub/arm64-efi/blscfg.mod b/INSTALL/grub/arm64-efi/blscfg.mod new file mode 100644 index 0000000..26112ee Binary files /dev/null and b/INSTALL/grub/arm64-efi/blscfg.mod differ diff --git a/INSTALL/grub/arm64-efi/bswap_test.mod b/INSTALL/grub/arm64-efi/bswap_test.mod new file mode 100644 index 0000000..9435014 Binary files /dev/null and b/INSTALL/grub/arm64-efi/bswap_test.mod differ diff --git a/INSTALL/grub/arm64-efi/btrfs.mod b/INSTALL/grub/arm64-efi/btrfs.mod new file mode 100644 index 0000000..ee54672 Binary files /dev/null and b/INSTALL/grub/arm64-efi/btrfs.mod differ diff --git a/INSTALL/grub/arm64-efi/cbfs.mod b/INSTALL/grub/arm64-efi/cbfs.mod new file mode 100644 index 0000000..882413a Binary files /dev/null and b/INSTALL/grub/arm64-efi/cbfs.mod differ diff --git a/INSTALL/grub/arm64-efi/cmdline_cat_test.mod b/INSTALL/grub/arm64-efi/cmdline_cat_test.mod new file mode 100644 index 0000000..cbdca10 Binary files /dev/null and b/INSTALL/grub/arm64-efi/cmdline_cat_test.mod differ diff --git a/INSTALL/grub/arm64-efi/cmp.mod b/INSTALL/grub/arm64-efi/cmp.mod new file mode 100644 index 0000000..28e828f Binary files /dev/null and b/INSTALL/grub/arm64-efi/cmp.mod differ diff --git a/INSTALL/grub/arm64-efi/cmp_test.mod b/INSTALL/grub/arm64-efi/cmp_test.mod new file mode 100644 index 0000000..51164f4 Binary files /dev/null and b/INSTALL/grub/arm64-efi/cmp_test.mod differ diff --git a/INSTALL/grub/arm64-efi/command.lst b/INSTALL/grub/arm64-efi/command.lst new file mode 100644 index 0000000..aefec3f Binary files /dev/null and b/INSTALL/grub/arm64-efi/command.lst differ diff --git a/INSTALL/grub/arm64-efi/cpio.mod b/INSTALL/grub/arm64-efi/cpio.mod new file mode 100644 index 0000000..387d4b7 Binary files /dev/null and b/INSTALL/grub/arm64-efi/cpio.mod differ diff --git a/INSTALL/grub/arm64-efi/cpio_be.mod b/INSTALL/grub/arm64-efi/cpio_be.mod new file mode 100644 index 0000000..b2193f6 Binary files /dev/null and b/INSTALL/grub/arm64-efi/cpio_be.mod differ diff --git a/INSTALL/grub/arm64-efi/crc64.mod b/INSTALL/grub/arm64-efi/crc64.mod new file mode 100644 index 0000000..57c0e17 Binary files /dev/null and b/INSTALL/grub/arm64-efi/crc64.mod differ diff --git a/INSTALL/grub/arm64-efi/crypto.lst b/INSTALL/grub/arm64-efi/crypto.lst new file mode 100644 index 0000000..bd0a97c Binary files /dev/null and b/INSTALL/grub/arm64-efi/crypto.lst differ diff --git a/INSTALL/grub/arm64-efi/cryptodisk.mod b/INSTALL/grub/arm64-efi/cryptodisk.mod new file mode 100644 index 0000000..ec574a2 Binary files /dev/null and b/INSTALL/grub/arm64-efi/cryptodisk.mod differ diff --git a/INSTALL/grub/arm64-efi/ctz_test.mod b/INSTALL/grub/arm64-efi/ctz_test.mod new file mode 100644 index 0000000..f1a6a7e Binary files /dev/null and b/INSTALL/grub/arm64-efi/ctz_test.mod differ diff --git a/INSTALL/grub/arm64-efi/date.mod b/INSTALL/grub/arm64-efi/date.mod new file mode 100644 index 0000000..aaf9248 Binary files /dev/null and b/INSTALL/grub/arm64-efi/date.mod differ diff --git a/INSTALL/grub/arm64-efi/datehook.mod b/INSTALL/grub/arm64-efi/datehook.mod new file mode 100644 index 0000000..9817cbe Binary files /dev/null and b/INSTALL/grub/arm64-efi/datehook.mod differ diff --git a/INSTALL/grub/arm64-efi/disk.mod b/INSTALL/grub/arm64-efi/disk.mod new file mode 100644 index 0000000..bdc2c8b Binary files /dev/null and b/INSTALL/grub/arm64-efi/disk.mod differ diff --git a/INSTALL/grub/arm64-efi/div.mod b/INSTALL/grub/arm64-efi/div.mod new file mode 100644 index 0000000..281406f Binary files /dev/null and b/INSTALL/grub/arm64-efi/div.mod differ diff --git a/INSTALL/grub/arm64-efi/div_test.mod b/INSTALL/grub/arm64-efi/div_test.mod new file mode 100644 index 0000000..d79e6cf Binary files /dev/null and b/INSTALL/grub/arm64-efi/div_test.mod differ diff --git a/INSTALL/grub/arm64-efi/dm_nv.mod b/INSTALL/grub/arm64-efi/dm_nv.mod new file mode 100644 index 0000000..089b613 Binary files /dev/null and b/INSTALL/grub/arm64-efi/dm_nv.mod differ diff --git a/INSTALL/grub/arm64-efi/efinet.mod b/INSTALL/grub/arm64-efi/efinet.mod new file mode 100644 index 0000000..6aa4d86 Binary files /dev/null and b/INSTALL/grub/arm64-efi/efinet.mod differ diff --git a/INSTALL/grub/arm64-efi/elf.mod b/INSTALL/grub/arm64-efi/elf.mod new file mode 100644 index 0000000..88ce4ab Binary files /dev/null and b/INSTALL/grub/arm64-efi/elf.mod differ diff --git a/INSTALL/grub/arm64-efi/eval.mod b/INSTALL/grub/arm64-efi/eval.mod new file mode 100644 index 0000000..370f3a4 Binary files /dev/null and b/INSTALL/grub/arm64-efi/eval.mod differ diff --git a/INSTALL/grub/arm64-efi/exfctest.mod b/INSTALL/grub/arm64-efi/exfctest.mod new file mode 100644 index 0000000..a8b3cd2 Binary files /dev/null and b/INSTALL/grub/arm64-efi/exfctest.mod differ diff --git a/INSTALL/grub/arm64-efi/f2fs.mod b/INSTALL/grub/arm64-efi/f2fs.mod new file mode 100644 index 0000000..381880d Binary files /dev/null and b/INSTALL/grub/arm64-efi/f2fs.mod differ diff --git a/INSTALL/grub/arm64-efi/fdt.lst b/INSTALL/grub/arm64-efi/fdt.lst new file mode 100644 index 0000000..ea28d9e Binary files /dev/null and b/INSTALL/grub/arm64-efi/fdt.lst differ diff --git a/INSTALL/grub/arm64-efi/fdt.mod b/INSTALL/grub/arm64-efi/fdt.mod new file mode 100644 index 0000000..c624b64 Binary files /dev/null and b/INSTALL/grub/arm64-efi/fdt.mod differ diff --git a/INSTALL/grub/arm64-efi/fs.lst b/INSTALL/grub/arm64-efi/fs.lst new file mode 100644 index 0000000..12c6c9d Binary files /dev/null and b/INSTALL/grub/arm64-efi/fs.lst differ diff --git a/INSTALL/grub/arm64-efi/functional_test.mod b/INSTALL/grub/arm64-efi/functional_test.mod new file mode 100644 index 0000000..bab2b83 Binary files /dev/null and b/INSTALL/grub/arm64-efi/functional_test.mod differ diff --git a/INSTALL/grub/arm64-efi/fwload.mod b/INSTALL/grub/arm64-efi/fwload.mod new file mode 100644 index 0000000..0024623 Binary files /dev/null and b/INSTALL/grub/arm64-efi/fwload.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_arcfour.mod b/INSTALL/grub/arm64-efi/gcry_arcfour.mod new file mode 100644 index 0000000..fa6a146 Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_arcfour.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_blowfish.mod b/INSTALL/grub/arm64-efi/gcry_blowfish.mod new file mode 100644 index 0000000..71c1e56 Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_blowfish.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_camellia.mod b/INSTALL/grub/arm64-efi/gcry_camellia.mod new file mode 100644 index 0000000..ff60824 Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_camellia.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_cast5.mod b/INSTALL/grub/arm64-efi/gcry_cast5.mod new file mode 100644 index 0000000..779c31e Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_cast5.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_crc.mod b/INSTALL/grub/arm64-efi/gcry_crc.mod new file mode 100644 index 0000000..072c484 Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_crc.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_des.mod b/INSTALL/grub/arm64-efi/gcry_des.mod new file mode 100644 index 0000000..1d12ed0 Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_des.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_dsa.mod b/INSTALL/grub/arm64-efi/gcry_dsa.mod new file mode 100644 index 0000000..4288cd4 Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_dsa.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_idea.mod b/INSTALL/grub/arm64-efi/gcry_idea.mod new file mode 100644 index 0000000..03b17d8 Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_idea.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_md4.mod b/INSTALL/grub/arm64-efi/gcry_md4.mod new file mode 100644 index 0000000..b84b1f3 Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_md4.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_rfc2268.mod b/INSTALL/grub/arm64-efi/gcry_rfc2268.mod new file mode 100644 index 0000000..633ee22 Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_rfc2268.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_rijndael.mod b/INSTALL/grub/arm64-efi/gcry_rijndael.mod new file mode 100644 index 0000000..721eaa0 Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_rijndael.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_rmd160.mod b/INSTALL/grub/arm64-efi/gcry_rmd160.mod new file mode 100644 index 0000000..3688d8b Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_rmd160.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_rsa.mod b/INSTALL/grub/arm64-efi/gcry_rsa.mod new file mode 100644 index 0000000..e33a0fe Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_rsa.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_seed.mod b/INSTALL/grub/arm64-efi/gcry_seed.mod new file mode 100644 index 0000000..636bc99 Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_seed.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_serpent.mod b/INSTALL/grub/arm64-efi/gcry_serpent.mod new file mode 100644 index 0000000..70c3257 Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_serpent.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_sha1.mod b/INSTALL/grub/arm64-efi/gcry_sha1.mod new file mode 100644 index 0000000..55eeb12 Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_sha1.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_sha256.mod b/INSTALL/grub/arm64-efi/gcry_sha256.mod new file mode 100644 index 0000000..b00f799 Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_sha256.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_tiger.mod b/INSTALL/grub/arm64-efi/gcry_tiger.mod new file mode 100644 index 0000000..ec6a983 Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_tiger.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_twofish.mod b/INSTALL/grub/arm64-efi/gcry_twofish.mod new file mode 100644 index 0000000..1ce7bb2 Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_twofish.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_whirlpool.mod b/INSTALL/grub/arm64-efi/gcry_whirlpool.mod new file mode 100644 index 0000000..885a3ce Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_whirlpool.mod differ diff --git a/INSTALL/grub/arm64-efi/geli.mod b/INSTALL/grub/arm64-efi/geli.mod new file mode 100644 index 0000000..74835b1 Binary files /dev/null and b/INSTALL/grub/arm64-efi/geli.mod differ diff --git a/INSTALL/grub/arm64-efi/gptsync.mod b/INSTALL/grub/arm64-efi/gptsync.mod new file mode 100644 index 0000000..7a2f95f Binary files /dev/null and b/INSTALL/grub/arm64-efi/gptsync.mod differ diff --git a/INSTALL/grub/arm64-efi/hello.mod b/INSTALL/grub/arm64-efi/hello.mod new file mode 100644 index 0000000..cd60a48 Binary files /dev/null and b/INSTALL/grub/arm64-efi/hello.mod differ diff --git a/INSTALL/grub/arm64-efi/help.mod b/INSTALL/grub/arm64-efi/help.mod new file mode 100644 index 0000000..a12f6e2 Binary files /dev/null and b/INSTALL/grub/arm64-efi/help.mod differ diff --git a/INSTALL/grub/arm64-efi/hexdump.mod b/INSTALL/grub/arm64-efi/hexdump.mod new file mode 100644 index 0000000..3874910 Binary files /dev/null and b/INSTALL/grub/arm64-efi/hexdump.mod differ diff --git a/INSTALL/grub/arm64-efi/hfs.mod b/INSTALL/grub/arm64-efi/hfs.mod new file mode 100644 index 0000000..f4113b9 Binary files /dev/null and b/INSTALL/grub/arm64-efi/hfs.mod differ diff --git a/INSTALL/grub/arm64-efi/hfspluscomp.mod b/INSTALL/grub/arm64-efi/hfspluscomp.mod new file mode 100644 index 0000000..bbeca9d Binary files /dev/null and b/INSTALL/grub/arm64-efi/hfspluscomp.mod differ diff --git a/INSTALL/grub/arm64-efi/jfs.mod b/INSTALL/grub/arm64-efi/jfs.mod new file mode 100644 index 0000000..c9139a1 Binary files /dev/null and b/INSTALL/grub/arm64-efi/jfs.mod differ diff --git a/INSTALL/grub/arm64-efi/keystatus.mod b/INSTALL/grub/arm64-efi/keystatus.mod new file mode 100644 index 0000000..a228443 Binary files /dev/null and b/INSTALL/grub/arm64-efi/keystatus.mod differ diff --git a/INSTALL/grub/arm64-efi/ldm.mod b/INSTALL/grub/arm64-efi/ldm.mod new file mode 100644 index 0000000..d7ba301 Binary files /dev/null and b/INSTALL/grub/arm64-efi/ldm.mod differ diff --git a/INSTALL/grub/arm64-efi/loadenv.mod b/INSTALL/grub/arm64-efi/loadenv.mod new file mode 100644 index 0000000..eeb7f27 Binary files /dev/null and b/INSTALL/grub/arm64-efi/loadenv.mod differ diff --git a/INSTALL/grub/arm64-efi/lsacpi.mod b/INSTALL/grub/arm64-efi/lsacpi.mod new file mode 100644 index 0000000..841862f Binary files /dev/null and b/INSTALL/grub/arm64-efi/lsacpi.mod differ diff --git a/INSTALL/grub/arm64-efi/lsefi.mod b/INSTALL/grub/arm64-efi/lsefi.mod new file mode 100644 index 0000000..3d48f26 Binary files /dev/null and b/INSTALL/grub/arm64-efi/lsefi.mod differ diff --git a/INSTALL/grub/arm64-efi/lsefimmap.mod b/INSTALL/grub/arm64-efi/lsefimmap.mod new file mode 100644 index 0000000..2fe1126 Binary files /dev/null and b/INSTALL/grub/arm64-efi/lsefimmap.mod differ diff --git a/INSTALL/grub/arm64-efi/lsefisystab.mod b/INSTALL/grub/arm64-efi/lsefisystab.mod new file mode 100644 index 0000000..571f4ae Binary files /dev/null and b/INSTALL/grub/arm64-efi/lsefisystab.mod differ diff --git a/INSTALL/grub/arm64-efi/lsmmap.mod b/INSTALL/grub/arm64-efi/lsmmap.mod new file mode 100644 index 0000000..813af7f Binary files /dev/null and b/INSTALL/grub/arm64-efi/lsmmap.mod differ diff --git a/INSTALL/grub/arm64-efi/lssal.mod b/INSTALL/grub/arm64-efi/lssal.mod new file mode 100644 index 0000000..e80f9ae Binary files /dev/null and b/INSTALL/grub/arm64-efi/lssal.mod differ diff --git a/INSTALL/grub/arm64-efi/luks.mod b/INSTALL/grub/arm64-efi/luks.mod new file mode 100644 index 0000000..8f9e6c4 Binary files /dev/null and b/INSTALL/grub/arm64-efi/luks.mod differ diff --git a/INSTALL/grub/arm64-efi/lvm.mod b/INSTALL/grub/arm64-efi/lvm.mod new file mode 100644 index 0000000..ab681fe Binary files /dev/null and b/INSTALL/grub/arm64-efi/lvm.mod differ diff --git a/INSTALL/grub/arm64-efi/macbless.mod b/INSTALL/grub/arm64-efi/macbless.mod new file mode 100644 index 0000000..ce130c8 Binary files /dev/null and b/INSTALL/grub/arm64-efi/macbless.mod differ diff --git a/INSTALL/grub/arm64-efi/macho.mod b/INSTALL/grub/arm64-efi/macho.mod new file mode 100644 index 0000000..c2f1eb6 Binary files /dev/null and b/INSTALL/grub/arm64-efi/macho.mod differ diff --git a/INSTALL/grub/arm64-efi/mdraid09.mod b/INSTALL/grub/arm64-efi/mdraid09.mod new file mode 100644 index 0000000..250059d Binary files /dev/null and b/INSTALL/grub/arm64-efi/mdraid09.mod differ diff --git a/INSTALL/grub/arm64-efi/mdraid09_be.mod b/INSTALL/grub/arm64-efi/mdraid09_be.mod new file mode 100644 index 0000000..85a250a Binary files /dev/null and b/INSTALL/grub/arm64-efi/mdraid09_be.mod differ diff --git a/INSTALL/grub/arm64-efi/mdraid1x.mod b/INSTALL/grub/arm64-efi/mdraid1x.mod new file mode 100644 index 0000000..7c32ded Binary files /dev/null and b/INSTALL/grub/arm64-efi/mdraid1x.mod differ diff --git a/INSTALL/grub/arm64-efi/memdisk.mod b/INSTALL/grub/arm64-efi/memdisk.mod new file mode 100644 index 0000000..c2b769e Binary files /dev/null and b/INSTALL/grub/arm64-efi/memdisk.mod differ diff --git a/INSTALL/grub/arm64-efi/memrw.mod b/INSTALL/grub/arm64-efi/memrw.mod new file mode 100644 index 0000000..760d644 Binary files /dev/null and b/INSTALL/grub/arm64-efi/memrw.mod differ diff --git a/INSTALL/grub/arm64-efi/minix.mod b/INSTALL/grub/arm64-efi/minix.mod new file mode 100644 index 0000000..39dec9a Binary files /dev/null and b/INSTALL/grub/arm64-efi/minix.mod differ diff --git a/INSTALL/grub/arm64-efi/minix2.mod b/INSTALL/grub/arm64-efi/minix2.mod new file mode 100644 index 0000000..1c027b4 Binary files /dev/null and b/INSTALL/grub/arm64-efi/minix2.mod differ diff --git a/INSTALL/grub/arm64-efi/minix2_be.mod b/INSTALL/grub/arm64-efi/minix2_be.mod new file mode 100644 index 0000000..20b6276 Binary files /dev/null and b/INSTALL/grub/arm64-efi/minix2_be.mod differ diff --git a/INSTALL/grub/arm64-efi/minix3.mod b/INSTALL/grub/arm64-efi/minix3.mod new file mode 100644 index 0000000..6585c7f Binary files /dev/null and b/INSTALL/grub/arm64-efi/minix3.mod differ diff --git a/INSTALL/grub/arm64-efi/minix3_be.mod b/INSTALL/grub/arm64-efi/minix3_be.mod new file mode 100644 index 0000000..2192a11 Binary files /dev/null and b/INSTALL/grub/arm64-efi/minix3_be.mod differ diff --git a/INSTALL/grub/arm64-efi/minix_be.mod b/INSTALL/grub/arm64-efi/minix_be.mod new file mode 100644 index 0000000..154c4ab Binary files /dev/null and b/INSTALL/grub/arm64-efi/minix_be.mod differ diff --git a/INSTALL/grub/arm64-efi/moddep.lst b/INSTALL/grub/arm64-efi/moddep.lst new file mode 100644 index 0000000..c3cca20 Binary files /dev/null and b/INSTALL/grub/arm64-efi/moddep.lst differ diff --git a/INSTALL/grub/arm64-efi/mouse.mod b/INSTALL/grub/arm64-efi/mouse.mod new file mode 100644 index 0000000..a76800a Binary files /dev/null and b/INSTALL/grub/arm64-efi/mouse.mod differ diff --git a/INSTALL/grub/arm64-efi/mpi.mod b/INSTALL/grub/arm64-efi/mpi.mod new file mode 100644 index 0000000..d862e7c Binary files /dev/null and b/INSTALL/grub/arm64-efi/mpi.mod differ diff --git a/INSTALL/grub/arm64-efi/msdospart.mod b/INSTALL/grub/arm64-efi/msdospart.mod new file mode 100644 index 0000000..cafa47e Binary files /dev/null and b/INSTALL/grub/arm64-efi/msdospart.mod differ diff --git a/INSTALL/grub/arm64-efi/mul_test.mod b/INSTALL/grub/arm64-efi/mul_test.mod new file mode 100644 index 0000000..7d27403 Binary files /dev/null and b/INSTALL/grub/arm64-efi/mul_test.mod differ diff --git a/INSTALL/grub/arm64-efi/nilfs2.mod b/INSTALL/grub/arm64-efi/nilfs2.mod new file mode 100644 index 0000000..c207df9 Binary files /dev/null and b/INSTALL/grub/arm64-efi/nilfs2.mod differ diff --git a/INSTALL/grub/arm64-efi/normal.mod b/INSTALL/grub/arm64-efi/normal.mod new file mode 100644 index 0000000..bac443a Binary files /dev/null and b/INSTALL/grub/arm64-efi/normal.mod differ diff --git a/INSTALL/grub/arm64-efi/ntfscomp.mod b/INSTALL/grub/arm64-efi/ntfscomp.mod new file mode 100644 index 0000000..1d197b7 Binary files /dev/null and b/INSTALL/grub/arm64-efi/ntfscomp.mod differ diff --git a/INSTALL/grub/arm64-efi/odc.mod b/INSTALL/grub/arm64-efi/odc.mod new file mode 100644 index 0000000..3ed3c1c Binary files /dev/null and b/INSTALL/grub/arm64-efi/odc.mod differ diff --git a/INSTALL/grub/arm64-efi/offsetio.mod b/INSTALL/grub/arm64-efi/offsetio.mod new file mode 100644 index 0000000..397a162 Binary files /dev/null and b/INSTALL/grub/arm64-efi/offsetio.mod differ diff --git a/INSTALL/grub/arm64-efi/part_acorn.mod b/INSTALL/grub/arm64-efi/part_acorn.mod new file mode 100644 index 0000000..eddef74 Binary files /dev/null and b/INSTALL/grub/arm64-efi/part_acorn.mod differ diff --git a/INSTALL/grub/arm64-efi/part_amiga.mod b/INSTALL/grub/arm64-efi/part_amiga.mod new file mode 100644 index 0000000..eb05470 Binary files /dev/null and b/INSTALL/grub/arm64-efi/part_amiga.mod differ diff --git a/INSTALL/grub/arm64-efi/part_bsd.mod b/INSTALL/grub/arm64-efi/part_bsd.mod new file mode 100644 index 0000000..e9fa701 Binary files /dev/null and b/INSTALL/grub/arm64-efi/part_bsd.mod differ diff --git a/INSTALL/grub/arm64-efi/part_dfly.mod b/INSTALL/grub/arm64-efi/part_dfly.mod new file mode 100644 index 0000000..f88550b Binary files /dev/null and b/INSTALL/grub/arm64-efi/part_dfly.mod differ diff --git a/INSTALL/grub/arm64-efi/part_dvh.mod b/INSTALL/grub/arm64-efi/part_dvh.mod new file mode 100644 index 0000000..48da642 Binary files /dev/null and b/INSTALL/grub/arm64-efi/part_dvh.mod differ diff --git a/INSTALL/grub/arm64-efi/part_plan.mod b/INSTALL/grub/arm64-efi/part_plan.mod new file mode 100644 index 0000000..b88e432 Binary files /dev/null and b/INSTALL/grub/arm64-efi/part_plan.mod differ diff --git a/INSTALL/grub/arm64-efi/part_sun.mod b/INSTALL/grub/arm64-efi/part_sun.mod new file mode 100644 index 0000000..6937d36 Binary files /dev/null and b/INSTALL/grub/arm64-efi/part_sun.mod differ diff --git a/INSTALL/grub/arm64-efi/part_sunpc.mod b/INSTALL/grub/arm64-efi/part_sunpc.mod new file mode 100644 index 0000000..c86ec82 Binary files /dev/null and b/INSTALL/grub/arm64-efi/part_sunpc.mod differ diff --git a/INSTALL/grub/arm64-efi/partmap.lst b/INSTALL/grub/arm64-efi/partmap.lst new file mode 100644 index 0000000..720c55e Binary files /dev/null and b/INSTALL/grub/arm64-efi/partmap.lst differ diff --git a/INSTALL/grub/arm64-efi/parttool.lst b/INSTALL/grub/arm64-efi/parttool.lst new file mode 100644 index 0000000..bfa2d4a Binary files /dev/null and b/INSTALL/grub/arm64-efi/parttool.lst differ diff --git a/INSTALL/grub/arm64-efi/parttool.mod b/INSTALL/grub/arm64-efi/parttool.mod new file mode 100644 index 0000000..bbf25f4 Binary files /dev/null and b/INSTALL/grub/arm64-efi/parttool.mod differ diff --git a/INSTALL/grub/arm64-efi/password.mod b/INSTALL/grub/arm64-efi/password.mod new file mode 100644 index 0000000..79ea75e Binary files /dev/null and b/INSTALL/grub/arm64-efi/password.mod differ diff --git a/INSTALL/grub/arm64-efi/pbkdf2_test.mod b/INSTALL/grub/arm64-efi/pbkdf2_test.mod new file mode 100644 index 0000000..74067c9 Binary files /dev/null and b/INSTALL/grub/arm64-efi/pbkdf2_test.mod differ diff --git a/INSTALL/grub/arm64-efi/pgp.mod b/INSTALL/grub/arm64-efi/pgp.mod new file mode 100644 index 0000000..c041eee Binary files /dev/null and b/INSTALL/grub/arm64-efi/pgp.mod differ diff --git a/INSTALL/grub/arm64-efi/probe.mod b/INSTALL/grub/arm64-efi/probe.mod new file mode 100644 index 0000000..ee3a926 Binary files /dev/null and b/INSTALL/grub/arm64-efi/probe.mod differ diff --git a/INSTALL/grub/arm64-efi/procfs.mod b/INSTALL/grub/arm64-efi/procfs.mod new file mode 100644 index 0000000..1c69332 Binary files /dev/null and b/INSTALL/grub/arm64-efi/procfs.mod differ diff --git a/INSTALL/grub/arm64-efi/progress.mod b/INSTALL/grub/arm64-efi/progress.mod new file mode 100644 index 0000000..da0883d Binary files /dev/null and b/INSTALL/grub/arm64-efi/progress.mod differ diff --git a/INSTALL/grub/arm64-efi/raid5rec.mod b/INSTALL/grub/arm64-efi/raid5rec.mod new file mode 100644 index 0000000..efff74e Binary files /dev/null and b/INSTALL/grub/arm64-efi/raid5rec.mod differ diff --git a/INSTALL/grub/arm64-efi/raid6rec.mod b/INSTALL/grub/arm64-efi/raid6rec.mod new file mode 100644 index 0000000..15dc7e5 Binary files /dev/null and b/INSTALL/grub/arm64-efi/raid6rec.mod differ diff --git a/INSTALL/grub/arm64-efi/reiserfs.mod b/INSTALL/grub/arm64-efi/reiserfs.mod new file mode 100644 index 0000000..c011260 Binary files /dev/null and b/INSTALL/grub/arm64-efi/reiserfs.mod differ diff --git a/INSTALL/grub/arm64-efi/romfs.mod b/INSTALL/grub/arm64-efi/romfs.mod new file mode 100644 index 0000000..31c30ab Binary files /dev/null and b/INSTALL/grub/arm64-efi/romfs.mod differ diff --git a/INSTALL/grub/arm64-efi/scsi.mod b/INSTALL/grub/arm64-efi/scsi.mod new file mode 100644 index 0000000..533d074 Binary files /dev/null and b/INSTALL/grub/arm64-efi/scsi.mod differ diff --git a/INSTALL/grub/arm64-efi/search_fs_file.mod b/INSTALL/grub/arm64-efi/search_fs_file.mod new file mode 100644 index 0000000..fe93343 Binary files /dev/null and b/INSTALL/grub/arm64-efi/search_fs_file.mod differ diff --git a/INSTALL/grub/arm64-efi/search_fs_uuid.mod b/INSTALL/grub/arm64-efi/search_fs_uuid.mod new file mode 100644 index 0000000..431faf1 Binary files /dev/null and b/INSTALL/grub/arm64-efi/search_fs_uuid.mod differ diff --git a/INSTALL/grub/arm64-efi/search_label.mod b/INSTALL/grub/arm64-efi/search_label.mod new file mode 100644 index 0000000..e0fd6fe Binary files /dev/null and b/INSTALL/grub/arm64-efi/search_label.mod differ diff --git a/INSTALL/grub/arm64-efi/setjmp.mod b/INSTALL/grub/arm64-efi/setjmp.mod new file mode 100644 index 0000000..b7e7877 Binary files /dev/null and b/INSTALL/grub/arm64-efi/setjmp.mod differ diff --git a/INSTALL/grub/arm64-efi/setjmp_test.mod b/INSTALL/grub/arm64-efi/setjmp_test.mod new file mode 100644 index 0000000..d003e85 Binary files /dev/null and b/INSTALL/grub/arm64-efi/setjmp_test.mod differ diff --git a/INSTALL/grub/arm64-efi/sfs.mod b/INSTALL/grub/arm64-efi/sfs.mod new file mode 100644 index 0000000..ae09a2e Binary files /dev/null and b/INSTALL/grub/arm64-efi/sfs.mod differ diff --git a/INSTALL/grub/arm64-efi/shift_test.mod b/INSTALL/grub/arm64-efi/shift_test.mod new file mode 100644 index 0000000..cb25250 Binary files /dev/null and b/INSTALL/grub/arm64-efi/shift_test.mod differ diff --git a/INSTALL/grub/arm64-efi/signature_test.mod b/INSTALL/grub/arm64-efi/signature_test.mod new file mode 100644 index 0000000..95eb0f1 Binary files /dev/null and b/INSTALL/grub/arm64-efi/signature_test.mod differ diff --git a/INSTALL/grub/arm64-efi/sleep_test.mod b/INSTALL/grub/arm64-efi/sleep_test.mod new file mode 100644 index 0000000..b5a9fe3 Binary files /dev/null and b/INSTALL/grub/arm64-efi/sleep_test.mod differ diff --git a/INSTALL/grub/arm64-efi/smbios.mod b/INSTALL/grub/arm64-efi/smbios.mod new file mode 100644 index 0000000..8b60677 Binary files /dev/null and b/INSTALL/grub/arm64-efi/smbios.mod differ diff --git a/INSTALL/grub/arm64-efi/strtoull_test.mod b/INSTALL/grub/arm64-efi/strtoull_test.mod new file mode 100644 index 0000000..3b9136c Binary files /dev/null and b/INSTALL/grub/arm64-efi/strtoull_test.mod differ diff --git a/INSTALL/grub/arm64-efi/syslinuxcfg.mod b/INSTALL/grub/arm64-efi/syslinuxcfg.mod new file mode 100644 index 0000000..90192c3 Binary files /dev/null and b/INSTALL/grub/arm64-efi/syslinuxcfg.mod differ diff --git a/INSTALL/grub/arm64-efi/terminal.lst b/INSTALL/grub/arm64-efi/terminal.lst new file mode 100644 index 0000000..0f853df Binary files /dev/null and b/INSTALL/grub/arm64-efi/terminal.lst differ diff --git a/INSTALL/grub/arm64-efi/test_blockarg.mod b/INSTALL/grub/arm64-efi/test_blockarg.mod new file mode 100644 index 0000000..c1c8b21 Binary files /dev/null and b/INSTALL/grub/arm64-efi/test_blockarg.mod differ diff --git a/INSTALL/grub/arm64-efi/testload.mod b/INSTALL/grub/arm64-efi/testload.mod new file mode 100644 index 0000000..c066065 Binary files /dev/null and b/INSTALL/grub/arm64-efi/testload.mod differ diff --git a/INSTALL/grub/arm64-efi/testspeed.mod b/INSTALL/grub/arm64-efi/testspeed.mod new file mode 100644 index 0000000..35e6489 Binary files /dev/null and b/INSTALL/grub/arm64-efi/testspeed.mod differ diff --git a/INSTALL/grub/arm64-efi/tga.mod b/INSTALL/grub/arm64-efi/tga.mod new file mode 100644 index 0000000..778b672 Binary files /dev/null and b/INSTALL/grub/arm64-efi/tga.mod differ diff --git a/INSTALL/grub/arm64-efi/time.mod b/INSTALL/grub/arm64-efi/time.mod new file mode 100644 index 0000000..0bcbc03 Binary files /dev/null and b/INSTALL/grub/arm64-efi/time.mod differ diff --git a/INSTALL/grub/arm64-efi/tr.mod b/INSTALL/grub/arm64-efi/tr.mod new file mode 100644 index 0000000..e39da7c Binary files /dev/null and b/INSTALL/grub/arm64-efi/tr.mod differ diff --git a/INSTALL/grub/arm64-efi/ufs1.mod b/INSTALL/grub/arm64-efi/ufs1.mod new file mode 100644 index 0000000..a6d9495 Binary files /dev/null and b/INSTALL/grub/arm64-efi/ufs1.mod differ diff --git a/INSTALL/grub/arm64-efi/ufs1_be.mod b/INSTALL/grub/arm64-efi/ufs1_be.mod new file mode 100644 index 0000000..90fdc23 Binary files /dev/null and b/INSTALL/grub/arm64-efi/ufs1_be.mod differ diff --git a/INSTALL/grub/arm64-efi/ufs2.mod b/INSTALL/grub/arm64-efi/ufs2.mod new file mode 100644 index 0000000..7b52727 Binary files /dev/null and b/INSTALL/grub/arm64-efi/ufs2.mod differ diff --git a/INSTALL/grub/arm64-efi/verifiers.mod b/INSTALL/grub/arm64-efi/verifiers.mod new file mode 100644 index 0000000..bee98f5 Binary files /dev/null and b/INSTALL/grub/arm64-efi/verifiers.mod differ diff --git a/INSTALL/grub/arm64-efi/video.lst b/INSTALL/grub/arm64-efi/video.lst new file mode 100644 index 0000000..ad1dbd0 Binary files /dev/null and b/INSTALL/grub/arm64-efi/video.lst differ diff --git a/INSTALL/grub/arm64-efi/videoinfo.mod b/INSTALL/grub/arm64-efi/videoinfo.mod new file mode 100644 index 0000000..f3f88b0 Binary files /dev/null and b/INSTALL/grub/arm64-efi/videoinfo.mod differ diff --git a/INSTALL/grub/arm64-efi/videotest.mod b/INSTALL/grub/arm64-efi/videotest.mod new file mode 100644 index 0000000..f8383a0 Binary files /dev/null and b/INSTALL/grub/arm64-efi/videotest.mod differ diff --git a/INSTALL/grub/arm64-efi/videotest_checksum.mod b/INSTALL/grub/arm64-efi/videotest_checksum.mod new file mode 100644 index 0000000..bb4a325 Binary files /dev/null and b/INSTALL/grub/arm64-efi/videotest_checksum.mod differ diff --git a/INSTALL/grub/arm64-efi/xen_boot.mod b/INSTALL/grub/arm64-efi/xen_boot.mod new file mode 100644 index 0000000..6d8d274 Binary files /dev/null and b/INSTALL/grub/arm64-efi/xen_boot.mod differ diff --git a/INSTALL/grub/arm64-efi/xnu_uuid.mod b/INSTALL/grub/arm64-efi/xnu_uuid.mod new file mode 100644 index 0000000..d3f711b Binary files /dev/null and b/INSTALL/grub/arm64-efi/xnu_uuid.mod differ diff --git a/INSTALL/grub/arm64-efi/xnu_uuid_test.mod b/INSTALL/grub/arm64-efi/xnu_uuid_test.mod new file mode 100644 index 0000000..0d84ebd Binary files /dev/null and b/INSTALL/grub/arm64-efi/xnu_uuid_test.mod differ diff --git a/INSTALL/grub/arm64-efi/zfs.mod b/INSTALL/grub/arm64-efi/zfs.mod new file mode 100644 index 0000000..5c0a3c4 Binary files /dev/null and b/INSTALL/grub/arm64-efi/zfs.mod differ diff --git a/INSTALL/grub/arm64-efi/zfscrypt.mod b/INSTALL/grub/arm64-efi/zfscrypt.mod new file mode 100644 index 0000000..59c516e Binary files /dev/null and b/INSTALL/grub/arm64-efi/zfscrypt.mod differ diff --git a/INSTALL/grub/arm64-efi/zfsinfo.mod b/INSTALL/grub/arm64-efi/zfsinfo.mod new file mode 100644 index 0000000..afe286f Binary files /dev/null and b/INSTALL/grub/arm64-efi/zfsinfo.mod differ diff --git a/INSTALL/grub/arm64-efi/zstd.mod b/INSTALL/grub/arm64-efi/zstd.mod new file mode 100644 index 0000000..aeef157 Binary files /dev/null and b/INSTALL/grub/arm64-efi/zstd.mod differ diff --git a/INSTALL/grub/checksum.cfg b/INSTALL/grub/checksum.cfg new file mode 100644 index 0000000..df045ec --- /dev/null +++ b/INSTALL/grub/checksum.cfg @@ -0,0 +1,96 @@ + +unset vtchkdef +vt_vtoychksum_exist "${VTOY_CHKSUM_FILE_PATH}" + +if [ "$VT_EXIST_MD5" = "1" ]; then + if [ -z "$vtchkdef" ]; then + set default=0 + set vtchkdef=1 + fi + menuentry "$VTLANG_CHKSUM_MD5_CALC_CHK" --class=checksum_md5 { + md5sum "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}" + vt_cmp_checksum 0 "${VTOY_CHKSUM_FILE_PATH}" + + echo -en "\n\n$VTLANG_ENTER_EXIT ..." + read vtInputKey + } +else + menuentry "$VTLANG_CHKSUM_MD5_CALC" --class=checksum_md5 { + md5sum "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}" + + echo -en "\n\n$VTLANG_ENTER_EXIT ..." + read vtInputKey + } +fi + +if [ "$VT_EXIST_SHA1" = "1" ]; then + if [ -z "$vtchkdef" ]; then + set default=1 + set vtchkdef=1 + fi + menuentry "$VTLANG_CHKSUM_SHA1_CALC_CHK" --class=checksum_sha1 { + sha1sum "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}" + vt_cmp_checksum 1 "${VTOY_CHKSUM_FILE_PATH}" + + echo -en "\n\n$VTLANG_ENTER_EXIT ..." + read vtInputKey + } +else + menuentry "$VTLANG_CHKSUM_SHA1_CALC" --class=checksum_sha1 { + sha1sum "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}" + + echo -en "\n\n$VTLANG_ENTER_EXIT ..." + read vtInputKey + } +fi + + + +if [ "$VT_EXIST_SHA256" = "1" ]; then + if [ -z "$vtchkdef" ]; then + set default=2 + set vtchkdef=1 + fi + menuentry "$VTLANG_CHKSUM_SHA256_CALC_CHK" --class=checksum_sha256 { + sha256sum "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}" + vt_cmp_checksum 2 "${VTOY_CHKSUM_FILE_PATH}" + + echo -en "\n\n$VTLANG_ENTER_EXIT ..." + read vtInputKey + } +else + menuentry "$VTLANG_CHKSUM_SHA256_CALC" --class=checksum_sha256 { + sha256sum "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}" + + echo -en "\n\n$VTLANG_ENTER_EXIT ..." + read vtInputKey + } +fi + + + +if [ "$VT_EXIST_SHA512" = "1" ]; then + if [ -z "$vtchkdef" ]; then + set default=3 + set vtchkdef=1 + fi + menuentry "$VTLANG_CHKSUM_SHA512_CALC_CHK" --class=checksum_sha512{ + sha512sum "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}" + vt_cmp_checksum 3 "${VTOY_CHKSUM_FILE_PATH}" + + echo -en "\n\n$VTLANG_ENTER_EXIT ..." + read vtInputKey + } +else + menuentry "$VTLANG_CHKSUM_SHA512_CALC" --class=checksum_sha512{ + sha512sum "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}" + + echo -en "\n\n$VTLANG_ENTER_EXIT ..." + read vtInputKey + } +fi + + +menuentry "$VTLANG_RETURN_PREVIOUS" --class=vtoyret VTOY_RET { + echo 'Return ...' +} diff --git a/INSTALL/grub/debug.cfg b/INSTALL/grub/debug.cfg new file mode 100644 index 0000000..10f3248 --- /dev/null +++ b/INSTALL/grub/debug.cfg @@ -0,0 +1,294 @@ +# +# VTLANG_CTRL_TEMP_SET must be the first +# And the inside item order can not be changed +# +submenu "$VTLANG_CTRL_TEMP_SET" --class=debug_temp_set --class=F5tool { + menuentry "[ $VTOY_WIN11_BYPASS_CHECK ] $VTLANG_WIN11_BYPASS_CHECK" --class=debug_temp_win11_bypass --class=debug_temp_set --class=F5tool \ + VTOY_RUN_SET_0_0 { + if [ "$VTOY_WIN11_BYPASS_CHECK" = "0" ]; then + set VTOY_WIN11_BYPASS_CHECK=1 + else + set VTOY_WIN11_BYPASS_CHECK=0 + fi + } + + menuentry "[ $VTOY_WIN11_BYPASS_NRO ] $VTLANG_WIN11_BYPASS_NRO" --class=debug_temp_win11_nro --class=debug_temp_set --class=F5tool \ + VTOY_RUN_SET_1_0 { + if [ "$VTOY_WIN11_BYPASS_NRO" = "0" ]; then + set VTOY_WIN11_BYPASS_NRO=1 + else + set VTOY_WIN11_BYPASS_NRO=0 + fi + } + + menuentry "[ $VTOY_SECONDARY_BOOT_MENU ] $VTLANG_SECONDARY_BOOT_MENU" --class=debug_temp_second_menu --class=debug_temp_set --class=F5tool \ + VTOY_RUN_SET_2_0 { + if [ "$VTOY_SECONDARY_BOOT_MENU" = "0" ]; then + set VTOY_SECONDARY_BOOT_MENU=1 + else + set VTOY_SECONDARY_BOOT_MENU=0 + fi + } + + menuentry "$VTLANG_RETURN_PREVIOUS" --class=vtoyret VTOY_RET { + echo "Return ..." + } +} + + +if [ "$grub_platform" != "pc" ]; then + submenu "$VTLANG_WIN_UEFI_RES_LOCK" --class=debug_uefi_res_lock --class=F5tool { + set vtActive0="[ ]" + set vtActive1="[ ]" + set vtActive2="[ ]" + set vtActive3="[ ]" + if [ "$VTOY_WIN_UEFI_RES_LOCK" = "0" ]; then + set vtActive0="[*]" + elif [ "$VTOY_WIN_UEFI_RES_LOCK" = "1" ]; then + set vtActive1="[*]" + elif [ "$VTOY_WIN_UEFI_RES_LOCK" = "2" ]; then + set vtActive2="[*]" + elif [ "$VTOY_WIN_UEFI_RES_LOCK" = "3" ]; then + set vtActive3="[*]" + fi + + menuentry "$vtActive0 $VTLANG_UEFI_RES_LOCK_NONE" --class=debug_uefi_res_lock0 --class=F5tool VTOY_RUN_SET_0_1 { + set VTOY_WIN_UEFI_RES_LOCK=0 + } + menuentry "$vtActive1 $VTLANG_UEFI_RES_LOCK_MAX" --class=debug_uefi_res_lock1 --class=F5tool VTOY_RUN_SET_1_1 { + set VTOY_WIN_UEFI_RES_LOCK=1 + } + menuentry "$vtActive2 $VTLANG_UEFI_RES_LOCK_1024_768" --class=debug_uefi_res_lock2 --class=F5tool VTOY_RUN_SET_2_1 { + set VTOY_WIN_UEFI_RES_LOCK=2 + } + menuentry "$vtActive3 $VTLANG_UEFI_RES_LOCK_BE1024_768" --class=debug_uefi_res_lock3 --class=F5tool VTOY_RUN_SET_3_1 { + set VTOY_WIN_UEFI_RES_LOCK=3 + } + + menuentry "$VTLANG_RETURN_PREVIOUS" --class=vtoyret VTOY_RET { + echo "Return ..." + } + } +fi + + +submenu "$VTLANG_MENU_LANG" --class=debug_menu_lang --class=F5tool { + source $prefix/menulang.cfg +} + +source $prefix/power.cfg +source $prefix/hwinfo.cfg +source $prefix/keyboard.cfg + +submenu "$VTLANG_RESOLUTION_CFG" --class=debug_resolution --class=F5tool { + menuentry "$VTLANG_RETURN_PREVIOUS" --class=vtoyret VTOY_RET { + echo "Return ..." + } + + vt_update_cur_video_mode VT_CUR_MODE + set vdid=0 + while [ $vdid -lt $VTOY_VIDEO_MODE_NUM ]; do + vt_get_video_mode $vdid vtCurMode + + unset vtActive + if [ "$vtCurMode" = "$VT_CUR_MODE" ]; then + set vtActive="[*]" + fi + + menuentry "$vtCurMode $vtActive" --class=debug_videomode --class=debug_resolution --class=F5tool VTOY_RUN_RET { + terminal_output console + set gfxmode=$1 + terminal_output gfxterm + if [ "$vtoy_res_fit" = "1" ]; then + vt_set_theme switch + fi + } + + vt_incr vdid 1 + done +} + +submenu "$VTLANG_SCREEN_MODE" --class=debug_screen_mode --class=F5tool { + menuentry "$VTLANG_SCREEN_TEXT_MODE" --class=debug_text_mode --class=debug_screen_mode --class=F5tool { + vt_push_menu_lang en_US + terminal_output console + } + menuentry "$VTLANG_SCREEN_GUI_MODE" --class=debug_gui_mode --class=debug_screen_mode --class=F5tool { + terminal_output gfxterm + vt_pop_menu_lang + } + menuentry "$VTLANG_RETURN_PREVIOUS" --class=vtoyret VTOY_RET { + echo "Return ..." + } +} + +if [ -n "$VTOY_THEME_COUNT" -a $VTOY_THEME_COUNT -gt 1 ]; then + submenu "$VTLANG_THEME_SELECT" --class=debug_theme_select --class=F5tool { + vt_select_theme_cfg + } +fi + +if [ "$grub_platform" != "pc" ]; then + submenu "$VTLANG_UEFI_UTIL" --class=debug_util --class=F5tool { + menuentry "$VTLANG_UTIL_SHOW_EFI_DRV" --class=debug_util_efidrv --class=debug_util --class=F5tool { + vt_push_pager + chainloader ${vtoy_path}/vtoyutil_${VTOY_EFI_ARCH}.efi env_param=${env_param} ${vtdebug_flag} feature=show_efi_drivers + boot + vt_pop_pager + echo -en "\n$VTLANG_ENTER_EXIT ..." + read vtInputKey + } + + menuentry "$VTLANG_UTIL_FIX_BLINIT_FAIL" --class=debug_util_blinit --class=debug_util --class=F5tool { + chainloader ${vtoy_path}/vtoyutil_${VTOY_EFI_ARCH}.efi env_param=${env_param} ${vtdebug_flag} feature=fix_windows_mmap + boot + echo -en "\n$VTLANG_ENTER_EXIT ..." + read vtInputKey + } + + menuentry "$VTLANG_RETURN_PREVIOUS" --class=vtoyret VTOY_RET { + echo "Return ..." + } + } +fi + + +submenu "$VTLANG_JSON_CHK_JSON" --class=debug_json --class=F5tool { + menuentry "$VTLANG_JSON_CHK_CONTROL" --class=debug_control --class=debug_json --class=F5tool { + set pager=1 + vt_check_plugin_json $vt_plugin_path control $vtoy_iso_part + + echo -en "\n$VTLANG_ENTER_EXIT ..." + read vtInputKey + unset pager + } + + menuentry "$VTLANG_JSON_CHK_THEME" --class=debug_theme --class=debug_json --class=F5tool { + set pager=1 + vt_check_plugin_json $vt_plugin_path theme $vtoy_iso_part + + echo -en "\n$VTLANG_ENTER_EXIT ..." + read vtInputKey + unset pager + } + + menuentry "$VTLANG_JSON_CHK_AUTOINS" --class=debug_autoinstall --class=debug_json --class=F5tool { + set pager=1 + vt_check_plugin_json $vt_plugin_path auto_install $vtoy_iso_part + + echo -en "\n$VTLANG_ENTER_EXIT ..." + read vtInputKey + unset pager + } + + menuentry "$VTLANG_JSON_CHK_PERSIST" --class=debug_persistence --class=debug_json --class=F5tool { + set pager=1 + vt_check_plugin_json $vt_plugin_path persistence $vtoy_iso_part + + echo -e "\n############### dump persistence ###############" + vt_dump_persistence + + echo -en "\n$VTLANG_ENTER_EXIT ..." + read vtInputKey + unset pager + } + + menuentry "$VTLANG_JSON_CHK_MENU_ALIAS" --class=debug_menualias --class=debug_json --class=F5tool { + set pager=1 + vt_check_plugin_json $vt_plugin_path menu_alias $vtoy_iso_part + + echo -en "\n$VTLANG_ENTER_EXIT ..." + read vtInputKey + unset pager + } + + menuentry "$VTLANG_JSON_CHK_MENU_TIP" --class=debug_menutip --class=debug_json --class=F5tool { + set pager=1 + vt_check_plugin_json $vt_plugin_path menu_tip $vtoy_iso_part + + echo -en "\n$VTLANG_ENTER_EXIT ..." + read vtInputKey + unset pager + } + + menuentry "$VTLANG_JSON_CHK_MENU_CLASS" --class=debug_menuclass --class=debug_json --class=F5tool { + set pager=1 + vt_check_plugin_json $vt_plugin_path menu_class $vtoy_iso_part + + echo -en "\n$VTLANG_ENTER_EXIT ..." + read vtInputKey + unset pager + } + + menuentry "$VTLANG_JSON_CHK_INJECTION" --class=debug_injection --class=debug_json --class=F5tool { + set pager=1 + vt_check_plugin_json $vt_plugin_path injection $vtoy_iso_part + + echo -en "\n$VTLANG_ENTER_EXIT ..." + read vtInputKey + unset pager + } + + menuentry "$VTLANG_JSON_CHK_AUTO_MEMDISK" --class=debug_automemdisk --class=debug_json --class=F5tool { + set pager=1 + vt_check_plugin_json $vt_plugin_path auto_memdisk $vtoy_iso_part + + echo -en "\n$VTLANG_ENTER_EXIT ..." + read vtInputKey + unset pager + } + + menuentry "$VTLANG_JSON_CHK_IMG_LIST" --class=debug_imagelist --class=debug_json --class=F5tool { + set pager=1 + vt_check_plugin_json $vt_plugin_path image_list $vtoy_iso_part + + echo -en "\n$VTLANG_ENTER_EXIT ..." + read vtInputKey + unset pager + } + + menuentry "$VTLANG_JSON_CHK_IMG_BLIST" --class=debug_imageblacklist --class=debug_json --class=F5tool { + set pager=1 + vt_check_plugin_json $vt_plugin_path image_blacklist $vtoy_iso_part + + echo -en "\n$VTLANG_ENTER_EXIT ..." + read vtInputKey + unset pager + } + + menuentry "$VTLANG_JSON_CHK_CONF_REPLACE" --class=debug_bootconf_replace --class=debug_json --class=F5tool { + set pager=1 + vt_check_plugin_json $vt_plugin_path conf_replace $vtoy_iso_part + + echo -en "\n$VTLANG_ENTER_EXIT ..." + read vtInputKey + unset pager + } + + menuentry "$VTLANG_JSON_CHK_DUD" --class=debug_dud --class=debug_json --class=F5tool { + set pager=1 + vt_check_plugin_json $vt_plugin_path dud $vtoy_iso_part + + echo -en "\n$VTLANG_ENTER_EXIT ..." + read vtInputKey + unset pager + } + + menuentry "$VTLANG_JSON_CHK_PASSWORD" --class=debug_pwd --class=debug_json --class=F5tool { + set pager=1 + vt_check_plugin_json $vt_plugin_path password $vtoy_iso_part + + echo -en "\n$VTLANG_ENTER_EXIT ..." + read vtInputKey + unset pager + } + + menuentry "$VTLANG_RETURN_PREVIOUS" --class=vtoyret VTOY_RET { + echo "Return ..." + } +} + + +menuentry "$VTLANG_RETURN_PREVIOUS" --class=vtoyret VTOY_RET { + echo "Return ..." +} diff --git a/INSTALL/grub/distro/fwts.cfg b/INSTALL/grub/distro/fwts.cfg new file mode 100644 index 0000000..6b138dc --- /dev/null +++ b/INSTALL/grub/distro/fwts.cfg @@ -0,0 +1,15 @@ +set label="writable" + +menuentry 'Firmware Test Suite' --class ubuntu --class gnu-linux --class gnu --class os { + set root='vtimghd,4' + linux /boot/vmlinuz root=LABEL=$label ro console=tty1 console=ttyS0 quiet + initrd /boot/initrd.img +} + +menuentry 'Firmware Test Suite (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os { + set root='vtimghd,4' + echo 'Loading Linux ...' + linux /boot/vmlinuz root=LABEL=$label ro recovery nomodeset + echo 'Loading initial ramdisk ...' + initrd /boot/initrd.img +} diff --git a/INSTALL/grub/fonts/ascii.pf2 b/INSTALL/grub/fonts/ascii.pf2 new file mode 100644 index 0000000..d81ac8b Binary files /dev/null and b/INSTALL/grub/fonts/ascii.pf2 differ diff --git a/INSTALL/grub/fonts/unicode.pf2 b/INSTALL/grub/fonts/unicode.pf2 new file mode 100644 index 0000000..b340859 Binary files /dev/null and b/INSTALL/grub/fonts/unicode.pf2 differ diff --git a/INSTALL/grub/grub.cfg b/INSTALL/grub/grub.cfg new file mode 100644 index 0000000..0c7ef9d --- /dev/null +++ b/INSTALL/grub/grub.cfg @@ -0,0 +1,2760 @@ +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +if [ "$grub_platform" = "pc" ]; then + insmod setkey + insmod regexp +fi + +function ventoy_pause { + echo "press Enter to continue ......" + read vtTmpPause +} + +function ventoy_debug_pause { + if [ -n "${vtdebug_flag}" ]; then + echo "press Enter to continue ......" + read vtTmpPause + fi +} + + +function ventoy_cli_console { + if [ -z "$vtoy_display_mode" ]; then + terminal_output console + elif [ "$vtoy_display_mode" = "GUI" ]; then + terminal_output console + fi +} + +function ventoy_gui_console { + if [ -z "$vtoy_display_mode" ]; then + terminal_output gfxterm + elif [ "$vtoy_display_mode" = "GUI" ]; then + terminal_output gfxterm + fi +} + +function ventoy_acpi_param { + if [ "$VTOY_PARAM_NO_ACPI" != "1" ]; then + vt_acpi_param "$1" "$2" + fi +} + +function vt_vcfg_pre_proc { + vt_img_sector "${vtoy_iso_part}${vt_chosen_path}" + vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" + vt_trailer_cpio $vtoy_iso_part "$vt_chosen_path" +} + +function ventoy_vcfg_proc { + if vt_check_custom_boot "${1}" vt_vcfg; then + set vtoy_chosen_path="${1}" + vt_file_basefile "${vtoy_chosen_path}" vtoy_chosen_file + + export vtoy_chosen_path + export vtoy_chosen_file + ventoy_debug_pause + configfile "${vtoy_iso_part}${vt_vcfg}" + true + else + false + fi +} + +function ventoy_language { + configfile $prefix/menulang.cfg +} + +function ventoy_diagnosis { + vt_enum_video_mode + configfile $prefix/debug.cfg +} + +function ventoy_localboot { + configfile $prefix/localboot.cfg +} + +function ventoy_ext_menu { + if [ -e $vt_plugin_path/ventoy/ventoy_grub.cfg ]; then + set ventoy_new_context=1 + configfile $vt_plugin_path/ventoy/ventoy_grub.cfg + unset ventoy_new_context + else + echo "ventoy_grub.cfg NOT exist." + echo -en "\n$VTLANG_ENTER_EXIT ..." + read vtInputKey + fi +} + +function ventoy_checksum { + if [ -f "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}" ]; then + configfile $prefix/checksum.cfg + fi +} + +function ventoy_show_help { + if [ -f $prefix/help.tar.gz ]; then + if [ -z "$vtoy_help_txt_mem_addr" ]; then + vt_load_file_to_mem "auto" $prefix/help.tar.gz vtoy_help_txt_mem + fi + + loopback vt_help_tarfs mem:${vtoy_help_txt_mem_addr}:size:${vtoy_help_txt_mem_size} + vt_cur_menu_lang vtCurLang + if [ -f "(vt_help_tarfs)/help/${vtCurLang}.txt" ]; then + cat "(vt_help_tarfs)/help/${vtCurLang}.txt" + else + cat "(vt_help_tarfs)/help/en_US.txt" + fi + loopback -d vt_help_tarfs + fi +} + +function ventoy_load_menu_lang_file { + vt_load_file_to_mem "auto" $prefix/menu.tar.gz vtoy_menu_lang_mem + loopback vt_menu_tarfs mem:${vtoy_menu_lang_mem_addr}:size:${vtoy_menu_lang_mem_size} +} + +function get_os_type { + set vtoy_os=Linux + export vtoy_os + + if vt_str_begin "$vt_volume_id" "DLC Boot"; then + if [ -f (loop)/DLCBoot.exe ]; then + set vtoy_os=Windows + fi + else + for file in "efi/microsoft/boot/bcd" "sources/boot.wim" "boot/bcd" "bootmgr.efi" "boot/etfsboot.com" ; do + if vt_file_exist_nocase (loop)/$file; then + set vtoy_os=Windows + break + fi + done + fi + + if [ "$vtoy_os" = "Linux" ]; then + if vt_strstr "$vt_system_id" "FreeBSD"; then + set vtoy_os=Unix + set vt_unix_type=FreeBSD + elif [ -e (loop)/bin/freebsd-version ]; then + set vtoy_os=Unix + set vt_unix_type=FreeBSD + elif [ -e (loop)/boot/kernel/geom_ventoy.ko ]; then + set vtoy_os=Unix + set vt_unix_type=FreeBSD + elif vt_str_begin "$vt_system_id" "DragonFly"; then + set vtoy_os=Unix + set vt_unix_type=DragonFly + + + elif [ -e (loop)/boot/kernel/kernel ]; then + if file --is-x86-kfreebsd (loop)/boot/kernel/kernel; then + set vtoy_os=Unix + set vt_unix_type=FreeBSD + elif file --is-x86-knetbsd (loop)/boot/kernel/kernel; then + set vtoy_os=Unix + set vt_unix_type=NetBSD + fi + fi + fi + + if [ -n "${vtdebug_flag}" ]; then + echo ISO is "$vtoy_os" + fi +} + +function vt_check_compatible_pe { + #Check for PE without external tools + #set compatible if ISO file is less than 80MB + if [ $vt_chosen_size -GT 33554432 -a $vt_chosen_size -LE 83886080 ]; then + set ventoy_compatible=YES + fi + + return +} + +function vt_check_compatible_linux { + if vt_str_begin "$vt_volume_id" "embootkit"; then + set ventoy_compatible=YES + elif [ -e "$1/casper/tinycore.gz" ]; then + set ventoy_compatible=YES + fi + + return +} + +function locate_initrd { + vt_linux_locate_initrd + + if [ -n "${vtdebug_flag}" ]; then + vt_linux_dump_initrd + ventoy_debug_pause + fi +} + +function locate_wim { + vt_windows_locate_wim_patch (loop) "$1" + + if [ -n "${vtdebug_flag}" ]; then + echo '###############################################' + vt_dump_wim_patch + echo '###############################################' + ventoy_debug_pause + fi +} + +function distro_specify_wim_patch { + if [ -d (loop)/h3pe ]; then + vt_windows_collect_wim_patch wim /BOOT/H3_10PE.WIM + vt_windows_collect_wim_patch wim /BOOT/H3_7PE.WIM + vt_windows_collect_wim_patch wim /BOOT/H3_8PE.WIM + vt_windows_collect_wim_patch wim /BOOT/H3_81PE.WIM + elif [ -d (loop)/2k10/winpe ]; then + vt_windows_collect_wim_patch wim /2k10/winpe/w1086pe.wim + vt_windows_collect_wim_patch wim /2k10/winpe/w8x86pe.wim + vt_windows_collect_wim_patch wim /2k10/winpe/w7x86pe.wim + fi +} + +function distro_specify_wim_patch_phase2 { + if [ -f (loop)/boot/boot.wim ]; then + vt_windows_collect_wim_patch wim /boot/boot.wim + elif [ -f (loop)/sources/boot.wim ]; then + vt_windows_collect_wim_patch wim /sources/boot.wim + fi + + if vt_str_begin "$vt_volume_id" "DLC Boot"; then + for vwfile in "/DLC1/WinPE/W11x64.wim" "/DLC1/WinPE/W10x64.wim" "/DLC1/WinPE/W10x86.wim"; do + if [ -f (loop)/$vwfile ]; then + vt_windows_collect_wim_patch wim $vwfile + fi + done + fi + +} + + +function distro_specify_initrd_file { + if [ -e (loop)/boot/all.rdz ]; then + vt_linux_specify_initrd_file /boot/all.rdz + elif [ -e (loop)/boot/xen.gz ]; then + if [ -e (loop)/install.img ]; then + vt_linux_specify_initrd_file /install.img + fi + elif [ -d (loop)/casper ]; then + if [ -e (loop)/casper/initrd ]; then + vt_linux_specify_initrd_file /casper/initrd + fi + if [ -e (loop)/casper/initrd.gz ]; then + vt_linux_specify_initrd_file /casper/initrd.gz + fi + if [ -e (loop)/casper/initrd-oem ]; then + vt_linux_specify_initrd_file /casper/initrd-oem + fi + elif [ -e (loop)/boot/grub/initrd.xz ]; then + vt_linux_specify_initrd_file /boot/grub/initrd.xz + elif [ -e (loop)/initrd.gz ]; then + vt_linux_specify_initrd_file /initrd.gz + elif [ -e (loop)/slax/boot/initrfs.img ]; then + vt_linux_specify_initrd_file /slax/boot/initrfs.img + elif [ -e (loop)/minios/boot/initrfs.img ]; then + vt_linux_specify_initrd_file /minios/boot/initrfs.img + elif [ -e (loop)/pmagic/initrd.img ]; then + vt_linux_specify_initrd_file /pmagic/initrd.img + elif [ -e (loop)/boot/initrd.xz ]; then + vt_linux_specify_initrd_file /boot/initrd.xz + elif [ -e (loop)/boot/initrd.gz ]; then + vt_linux_specify_initrd_file /boot/initrd.gz + elif [ -f (loop)/boot/initrd ]; then + vt_linux_specify_initrd_file /boot/initrd + elif [ -f (loop)/boot/x86_64/loader/initrd ]; then + vt_linux_specify_initrd_file /boot/x86_64/loader/initrd + elif [ -f (loop)/boot/initramfs-x86_64.img ]; then + vt_linux_specify_initrd_file /boot/initramfs-x86_64.img + elif [ -f (loop)/boot/isolinux/initramfs_data64.cpio.gz ]; then + vt_linux_specify_initrd_file /boot/isolinux/initramfs_data64.cpio.gz + elif [ -f (loop)/boot/initrd.img ]; then + vt_linux_specify_initrd_file /boot/initrd.img + + fi + + if [ -f (loop)/isolinux/initrd.gz ]; then + vt_linux_specify_initrd_file /isolinux/initrd.gz + fi + + if vt_str_begin "$vt_volume_id" "QUBES"; then + vt_linux_specify_initrd_file /images/pxeboot/initrd.img + fi + + if [ "$vt_chosen_size" = "1133375488" ]; then + if [ -d (loop)/boot/grub/x86_64-efi ]; then + vt_cpio_busybox64 "64h" + fi + fi +} + + +function distro_specify_initrd_file_phase2 { + if [ -f (loop)/boot/initrd.img ]; then + vt_linux_specify_initrd_file /boot/initrd.img + elif [ -f (loop)/Setup/initrd.gz ]; then + vt_linux_specify_initrd_file /Setup/initrd.gz + elif [ -f (loop)/isolinux/initramfs ]; then + vt_linux_specify_initrd_file /isolinux/initramfs + elif [ -f (loop)/boot/iniramfs.igz ]; then + vt_linux_specify_initrd_file /boot/iniramfs.igz + elif [ -f (loop)/initrd-x86_64 ]; then + vt_linux_specify_initrd_file /initrd-x86_64 + elif [ -f (loop)/live/initrd.img ]; then + vt_linux_specify_initrd_file /live/initrd.img + elif [ -f (loop)/initrd.img ]; then + vt_linux_specify_initrd_file /initrd.img + elif [ -f (loop)/sysresccd/boot/x86_64/sysresccd.img ]; then + vt_linux_specify_initrd_file /sysresccd/boot/x86_64/sysresccd.img + elif [ -f (loop)/CDlinux/initrd ]; then + vt_linux_specify_initrd_file /CDlinux/initrd + elif [ -f (loop)/parabola/boot/x86_64/parabolaiso.img ]; then + vt_linux_specify_initrd_file /parabola/boot/x86_64/parabolaiso.img + if [ -f (loop)/parabola/boot/i686/parabolaiso.img ]; then + vt_linux_specify_initrd_file /parabola/boot/i686/parabolaiso.img + fi + elif [ -f (loop)/parabola/boot/x86_64/initramfs-linux-libre.img ]; then + vt_linux_specify_initrd_file /parabola/boot/x86_64/initramfs-linux-libre.img + if [ -f (loop)/parabola/boot/i686/initramfs-linux-libre.img ]; then + vt_linux_specify_initrd_file /parabola/boot/i686/initramfs-linux-libre.img + fi + elif [ -f (loop)/hyperbola/boot/x86_64/hyperiso.img ]; then + vt_linux_specify_initrd_file /hyperbola/boot/x86_64/hyperiso.img + if [ -f (loop)/hyperbola/boot/i686/hyperiso.img ]; then + vt_linux_specify_initrd_file /hyperbola/boot/i686/hyperiso.img + fi + elif [ -f (loop)/EFI/BOOT/initrd.img ]; then + #Qubes + vt_linux_specify_initrd_file /EFI/BOOT/initrd.img + if [ "$grub_platform" != "pc" ]; then + vt_add_replace_file 0 "initrd.img" + fi + elif [ -f (loop)/initrd ]; then + vt_linux_specify_initrd_file /initrd + elif [ -f (loop)/live/initrd1 ]; then + vt_linux_specify_initrd_file /live/initrd1 + elif [ -f (loop)/isolinux/initrd.img ]; then + vt_linux_specify_initrd_file /isolinux/initrd.img + elif [ -f (loop)/isolinux/initrd.gz ]; then + vt_linux_specify_initrd_file /isolinux/initrd.gz + elif [ -f (loop)/syslinux/kernel/initramfs.gz ]; then + vt_linux_specify_initrd_file /syslinux/kernel/initramfs.gz + elif vt_strstr "$vt_volume_id" "Daphile"; then + vt_linux_parse_initrd_isolinux (loop)/isolinux/ + elif [ -f (loop)/boot/rootfs.xz ]; then + vt_linux_specify_initrd_file /boot/rootfs.xz + if [ "$grub_platform" != "pc" ]; then + vt_add_replace_file 0 "minimal\\x86_64\\rootfs.xz" + fi + elif [ -f (loop)/arch/boot/x86_64/archiso.img ]; then + vt_linux_specify_initrd_file /arch/boot/x86_64/archiso.img + if [ "$grub_platform" != "pc" ]; then + vt_add_replace_file 0 "EFI\\archiso\\archiso.img" + fi + elif [ -f (loop)/blackarch/boot/x86_64/archiso.img ]; then + vt_linux_specify_initrd_file /blackarch/boot/x86_64/archiso.img + elif [ -f (loop)/blackarch/boot/x86_64/initramfs-linux.img ]; then + vt_linux_specify_initrd_file /blackarch/boot/x86_64/initramfs-linux.img + + elif [ -f (loop)/install.amd/initrd.gz ]; then + vt_linux_specify_initrd_file /live/initrd2.img + vt_linux_specify_initrd_file /install.amd/initrd.gz + vt_linux_specify_initrd_file /install.amd/gtk/initrd.gz + elif [ -f (loop)/boot/grub/kernels.cfg ]; then + vt_linux_parse_initrd_grub file (loop)/boot/grub/kernels.cfg + elif [ -f (loop)/austrumi/initrd.gz ]; then + vt_linux_specify_initrd_file /austrumi/initrd.gz + if [ -f (loop)/EFI/BOOT/bootx64.efi ]; then + vt_cpio_busybox64 "64h" + fi + elif [ -f (loop)/boot/initfs.x86_64-efi ]; then + vt_linux_specify_initrd_file /boot/initfs.x86_64-efi + if [ -f (loop)/boot/initfs.i386-pc ]; then + vt_linux_specify_initrd_file /boot/initfs.i386-pc + fi + elif [ -f (loop)/antiX/initrd.gz ]; then + vt_linux_specify_initrd_file /antiX/initrd.gz + elif [ -f (loop)/360Disk/initrd.gz ]; then + vt_linux_specify_initrd_file /360Disk/initrd.gz + elif [ -f (loop)/porteus/initrd.xz ]; then + vt_linux_specify_initrd_file /porteus/initrd.xz + elif [ -f (loop)/pyabr/boot/initrfs.img ]; then + vt_linux_specify_initrd_file /pyabr/boot/initrfs.img + elif [ -f (loop)/initrd0.img ]; then + vt_linux_specify_initrd_file /initrd0.img + elif [ -f (loop)/sysresccd/boot/i686/sysresccd.img ]; then + vt_linux_specify_initrd_file /sysresccd/boot/i686/sysresccd.img + elif [ -f (loop)/boot/full.cz ]; then + vt_linux_specify_initrd_file /boot/full.cz + elif [ -f (loop)/images/pxeboot/initrd.img ]; then + vt_linux_specify_initrd_file /images/pxeboot/initrd.img + elif [ -f (loop)/live/initrd ]; then + vt_linux_specify_initrd_file /live/initrd + elif [ -f (loop)/initramfs-linux.img ]; then + vt_linux_specify_initrd_file /initramfs-linux.img + elif [ -f (loop)/boot/isolinux/initrd.gz ]; then + vt_linux_specify_initrd_file /boot/isolinux/initrd.gz + elif vt_str_begin "$vt_volume_id" "AERYNOS"; then + vt_vcfg_pre_proc + + loopback va "${vtoy_iso_part}${vt_chosen_path}" + loopback vb (va)/EFI/Boot/efiboot.img + + set root=(vb) + vt_systemd_menu (vb) vt_sys_menu_mem vt_linux_initrd + configfile "mem:${vt_sys_menu_mem_addr}:size:${vt_sys_menu_mem_size}" + + fi +} + + +function ventoy_get_ghostbsd_ver { + # fallback to parse version from elf /boot/kernel/kernel + set vt_freebsd_ver=xx +} + +function ventoy_get_furybsd_ver { + set vt_freebsd_ver=12.x + if regexp --set 1:vtFuryVer "(14|13)\.[0-9]" "$2"; then + set vt_freebsd_ver=${vtFuryVer}.x + fi +} + +function ventoy_get_freenas_ver { + set vt_freebsd_ver=11.x + + if [ -e (loop)/FreeNAS-MANIFEST ]; then + vt_parse_freenas_ver (loop)/FreeNAS-MANIFEST vt_freenas_ver + if regexp --set 1:vtNasVer "^(14|13|12|11)\.[0-9]" "$vt_freenas_ver"; then + set vt_freebsd_ver=${vtNasVer}.x + fi + fi +} + +function ventoy_get_truenas_ver { + set vt_freebsd_ver=12.x + + if [ -e (loop)/TrueNAS-MANIFEST ]; then + vt_parse_freenas_ver (loop)/TrueNAS-MANIFEST vt_truenas_ver + if regexp --set 1:vtTNasVer "^(14|13|12|11)\.[0-9]" "$vt_truenas_ver"; then + set vt_freebsd_ver=${vtTNasVer}.x + fi + fi +} + +function ventoy_get_midnightbsd_ver { + if vt_str_begin "$vt_volume_id" "1_"; then + set vt_freebsd_ver=11.x + elif vt_str_begin "$vt_volume_id" "2_"; then + set vt_freebsd_ver=2.x + elif vt_str_begin "$vt_volume_id" "3_"; then + set vt_freebsd_ver=3.x + fi +} + +function ventoy_freebsd_proc { + set vtFreeBsdDistro=FreeBSD + set vt_freebsd_ver=xx + + if [ -e (loop)/boot/kernel/geom_ventoy.ko ]; then + vt_unix_ko_fillmap /boot/kernel/geom_ventoy.ko + return + fi + + if vt_strstr "$vt_volume_id" "GHOSTBSD"; then + ventoy_get_ghostbsd_ver "$1" "${chosen_path}" + elif vt_strstr "$vt_volume_id" "FREENAS"; then + ventoy_get_freenas_ver "$1" "${chosen_path}" + elif vt_strstr "$vt_volume_id" "TRUENAS"; then + ventoy_get_truenas_ver "$1" "${chosen_path}" + elif vt_strstr "$vt_volume_id" "FURYBSD"; then + ventoy_get_furybsd_ver "$1" "${chosen_path}" + elif regexp --set 1:vtBsdVerNum "^(1[0-9]|9)_[0-9]" "$vt_volume_id"; then + set vt_freebsd_ver=${vtBsdVerNum}.x + elif [ -d (loop)/usr/midnightbsd-dist ]; then + ventoy_get_midnightbsd_ver "$1" "${chosen_path}" + set vtFreeBsdDistro=MidnightBSD + elif [ -e (loop)/bin/freebsd-version ]; then + vt_unix_parse_freebsd_ver (loop)/bin/freebsd-version vt_userland_ver + if regexp --set 1:vtBsdVerNum "\"(1[0-9]|9)\.[0-9]-" "$vt_userland_ver"; then + set vt_freebsd_ver=${vtBsdVerNum}.x + fi + elif [ -e (loop)/README.TXT ]; then + vt_1st_line (loop)/README.TXT vt_freebsd_line1 + if regexp --set 1:vtBsdVerNum "FreeBSD (1[0-9]|9)\.[0-9]-" "$vt_freebsd_line1"; then + set vt_freebsd_ver=${vtBsdVerNum}.x + fi + elif vt_strstr "${chosen_path}" "MidnightBSD"; then + set vt_freebsd_ver=9.x + fi + + + if [ -e (loop)/usr/freebsd-dist/cloninst.sh ]; then + set vtFreeBsdDistro=ClonOS + fi + + set vt_freebsd_bit=64 + for file in "/boot/kernel/kernel" "/boot/kernel/kernel.gz"; do + if [ -e (loop)/$file ]; then + if file --is-i386-kfreebsd (loop)/$file; then + set vt_freebsd_bit=32 + fi + break + fi + done + + if [ "$vt_freebsd_ver" = "xx" ]; then + if [ -e (loop)/boot/kernel/kernel ]; then + vt_unix_parse_freebsd_ver_elf (loop)/boot/kernel/kernel $vt_freebsd_bit vt_freebsd_ver + elif [ -e (loop)/boot/kernel/kernel.gz ]; then + vt_unix_parse_freebsd_ver_elf (loop)/boot/kernel/kernel.gz $vt_freebsd_bit vt_freebsd_ver + fi + + if [ "$vt_freebsd_ver" = "xx" ]; then + set vt_freebsd_ver=15.x + fi + fi + + if [ "$vt_freebsd_ver" = "14.x" ]; then + if [ -e (loop)/boot/lua/brand-pfSense.lua ]; then + set vtFreeBsdDistro=pfSense + fi + fi + + + if [ -n "${vtdebug_flag}" ]; then + echo "This is $vtFreeBsdDistro $vt_freebsd_ver ${vt_freebsd_bit}bit" + fi + + unset vt_unix_mod_path + for file in "/COPYRIGHT" "/FreeNAS-MANIFEST" "/TrueNAS-MANIFEST" "/version" "/etc/fstab"; do + if [ -e (loop)${file} ]; then + set vt_unix_mod_path=${file} + break + fi + done + + if [ -n "$vt_unix_mod_path" ]; then + vt_unix_replace_ko $vt_unix_mod_path (vtunix)/ventoy_unix/$vtFreeBsdDistro/geom_ventoy_ko/$vt_freebsd_ver/$vt_freebsd_bit/geom_ventoy.ko.xz + vt_unix_replace_conf FreeBSD "${1}${chosen_path}" + elif [ -e (loop)/easyre.ufs.uzip ]; then + vt_unix_replace_ko "/boot/grub/i386-pc/linux.mod" (vtunix)/ventoy_unix/$vtFreeBsdDistro/geom_ventoy_ko/$vt_freebsd_ver/$vt_freebsd_bit/geom_ventoy.ko.xz + if [ "$grub_platform" = "pc" ]; then + vt_unix_replace_grub_conf "/boot/grub/i386-pc/linux.mod" "cd9" + else + vt_unix_replace_conf FreeBSD "${1}${chosen_path}" "cd9" + fi + fi +} + +function ventoy_dragonfly_proc { + + unset vt_unix_mod_path + for file in "/boot/kernel/initrd.img.gz"; do + if [ -e (loop)${file} ]; then + set vt_unix_mod_path=${file} + break + fi + done + + vt_unix_replace_ko $vt_unix_mod_path ${vtoy_path}/dragonfly.mfs.xz + vt_unix_fill_image_desc + vt_unix_gzip_new_ko + vt_unix_replace_conf DragonFly "${1}${chosen_path}" +} + +function ventoy_unix_comm_proc { + vt_unix_reset + + vt_unix_check_vlnk "${1}${chosen_path}" + + if [ "$ventoy_compatible" = "NO" ]; then + loopback vtunix $vtoy_efi_part/ventoy/ventoy_unix.cpio + + if [ "$vt_unix_type" = "FreeBSD" ]; then + ventoy_freebsd_proc "$1" "${chosen_path}" + elif [ "$vt_unix_type" = "DragonFly" ]; then + ventoy_dragonfly_proc "$1" "${chosen_path}" + elif [ "$vt_unix_type" = "NetBSD" ]; then + echo "NetBSD not supported" + + + else + if [ -n "${vtdebug_flag}" ]; then + echo "Unknown unix type" + fi + fi + fi + + vt_unix_chain_data "${1}${chosen_path}" + ventoy_debug_pause +} + + +function uefi_windows_menu_func { + vt_windows_reset + + unset vt_cur_wimboot_mode + if vt_check_mode 4 "$vt_chosen_name"; then + set vt_cur_wimboot_mode=1 + fi + + if [ "$ventoy_compatible" = "NO" -o "$vt_cur_wimboot_mode" = "1" ]; then + if [ "$ventoy_fs_probe" = "iso9660" ]; then + loopback -d loop + vt_iso9660_nojoliet 1 + loopback loop "$1$2" + fi + + for file in "efi/microsoft/boot/bcd"; do + vt_windows_collect_wim_patch bcd (loop)/$file + done + + vt_windows_count_wim_patch vt_wim_cnt + if [ $vt_wim_cnt -eq 0 ]; then + distro_specify_wim_patch_phase2 + fi + + ventoy_debug_pause + locate_wim "${chosen_path}" + fi + + vt_windows_chain_data "${1}${chosen_path}" + ventoy_debug_pause + + if [ "$vt_cur_wimboot_mode" = "1" ]; then + vtoy_wimboot_func + fi + + if [ -n "$vtoy_chain_mem_addr" ]; then + ventoy_acpi_param ${vtoy_chain_mem_addr} 2048 + chainloader ${vtoy_path}/ventoy_${VTOY_EFI_ARCH}.efi env_param=${env_param} isoefi=${LoadIsoEfiDriver} iso_${ventoy_fs_probe} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} + boot + else + echo "chain empty failed" + ventoy_pause + fi +} + +function uefi_find_replace_initrd { + if vt_get_efi_vdisk_offset "${1}${2}" vt_efivdisk_offset; then + loopback -s $vt_efivdisk_offset vtefivdisk "${1}${2}" + + unset vt_rp_initrd + vt_search_replace_initrd (vtefivdisk) vt_rp_initrd + + if [ -n "$vt_rp_initrd" ]; then + vt_add_replace_file $3 "$vt_rp_initrd" + fi + + loopback -d vtefivdisk + ventoy_debug_pause + fi +} + +function uefi_linux_menu_func { + + if [ "$ventoy_compatible" = "NO" ]; then + + if [ "$ventoy_fs_probe" = "udf" ]; then + loopback -d loop + set ventoy_fs_probe=iso9660 + loopback loop "$1$2" + fi + + vt_load_cpio $vtoy_path "$2" "$1" "busybox=$ventoy_busybox_ver" + + vt_linux_clear_initrd + + if [ -d (loop)/pmagic ]; then + vt_linux_specify_initrd_file /pmagic/initrd.img + else + for file in "boot/grub/grub.cfg" "EFI/BOOT/grub.cfg" "EFI/boot/grub.cfg" "efi/boot/grub.cfg" "EFI/BOOT/BOOTX64.conf" "/grub/grub.cfg" "EFI/BOOT/grub/grub.cfg"; do + if [ -e (loop)/$file ]; then + vt_linux_parse_initrd_grub file (loop)/$file + fi + done + fi + + # special process for special distros + if [ -d (loop)/loader/entries ]; then + vt_linux_parse_initrd_grub dir (loop)/loader/entries/ + elif [ -d (loop)/boot/grub ]; then + vt_linux_parse_initrd_grub dir (loop)/boot/grub/ + fi + + distro_specify_initrd_file + + vt_linux_initrd_count vtcount + + if [ $vtcount -eq 0 ]; then + if [ -e (loop)/EFI/boot/livegrub.cfg ]; then + vt_linux_parse_initrd_grub file (loop)/EFI/boot/livegrub.cfg + fi + distro_specify_initrd_file_phase2 + + if [ "$vt_efi_dir" = "NO" ]; then + if [ -f (loop)/efi.img ]; then + vt_add_replace_file 0 "initrd" + fi + fi + fi + + locate_initrd + + if [ -d (loop)/loader/entries ]; then + vt_linux_get_main_initrd_index vtindex + + if [ -d (loop)/arch ]; then + if [ -f (loop)/arch/boot/x86_64/archiso.img ]; then + vt_add_replace_file $vtindex "EFI\\archiso\\archiso.img" + elif [ -f (loop)/arch/boot/x86_64/initramfs-linux.img ]; then + vt_add_replace_file $vtindex "arch\\boot\\x86_64\\initramfs-linux.img" + elif [ -f (loop)/boot/initramfs_x86_64.img ]; then + vt_add_replace_file $vtindex "boot\\initramfs_x86_64.img" + elif [ -f (loop)/arch/boot/x86_64/initramfs-linux-aegis-offensive.img ]; then + vt_add_replace_file $vtindex "arch\\boot\\x86_64\\initramfs-linux-aegis-offensive.img" + fi + elif [ -d (loop)/blackarch ]; then + if [ -f (loop)/blackarch/boot/x86_64/archiso.img ]; then + vt_add_replace_file $vtindex "EFI\\archiso\\archiso.img" + elif [ -f (loop)/blackarch/boot/x86_64/initramfs-linux.img ]; then + vt_add_replace_file $vtindex "blackarch\\boot\\x86_64\\initramfs-linux.img" + fi + elif [ -d (loop)/anarchy ]; then + if [ -f (loop)/anarchy/boot/x86_64/initramfs-linux.img ]; then + vt_add_replace_file $vtindex "anarchy\\boot\\x86_64\\initramfs-linux.img" + fi + elif [ -d (loop)/parabola ]; then + if [ -f (loop)/parabola/boot/x86_64/parabolaiso.img ]; then + vt_add_replace_file $vtindex "EFI\\parabolaiso\\parabolaiso.img" + elif [ -f (loop)/parabola/boot/x86_64/initramfs-linux-libre.img ]; then + vt_add_replace_file $vtindex "parabola\\boot\\x86_64\\initramfs-linux-libre.img" + fi + elif [ -f (loop)/EFI/BOOT/initrd.gz ]; then + vt_add_replace_file $vtindex "EFI\\BOOT\\initrd.gz" + elif [ -f (loop)/loader/entries/thinstation.conf ]; then + vt_add_replace_file $vtindex "boot\\initrd" + elif [ -f (loop)/loader/entries/pisi-efi-x86_64.conf ]; then + vt_add_replace_file $vtindex "EFI\\pisi\\initrd.img" + fi + + vt_get_replace_file_cnt vt_replace_cnt + if [ $vt_replace_cnt -eq 0 ]; then + uefi_find_replace_initrd "$1" "$2" $vtindex + fi + elif [ -d (loop)/EFI/boot/entries ]; then + if [ -f (loop)/parabola/boot/x86_64/parabolaiso.img ]; then + vt_add_replace_file 0 "EFI\\parabolaiso\\parabolaiso.img" + elif [ -f (loop)/hyperbola/boot/x86_64/hyperiso.img ]; then + vt_add_replace_file 0 "EFI\\hyperiso\\hyperiso.img" + fi + elif [ -d (loop)/EFI/BOOT/entries ]; then + vt_linux_get_main_initrd_index vtindex + + if [ -f (loop)/parabola/boot/x86_64/parabolaiso.img ]; then + vt_add_replace_file 0 "EFI\\parabolaiso\\parabolaiso.img" + elif [ -f (loop)/parabola/boot/x86_64/initramfs-linux-libre.img ]; then + vt_add_replace_file $vtindex "parabola\\boot\\x86_64\\initramfs-linux-libre.img" + fi + elif [ -e (loop)/syslinux/alt0/full.cz ]; then + vt_add_replace_file 0 "EFI\\BOOT\\full.cz" + set FirstTryBootFile='@EFI@BOOT@grubx64.efi' + + elif vt_str_begin "$vt_volume_id" "SolusLive"; then + vt_add_replace_file 0 "initrd" + + fi + + fi + + vt_linux_chain_data "${1}${chosen_path}" + + if [ -n "$LoadIsoEfiDriver" -a $vt_chosen_size -LT 104857600 ]; then + if [ -f (loop)/efi/clover/cloverx64.efi ]; then + unset LoadIsoEfiDriver + fi + fi + + if [ -n "$vtoy_chain_mem_addr" ]; then + ventoy_acpi_param ${vtoy_chain_mem_addr} 2048 + ventoy_cli_console + + unset vtGrub2Mode + if vt_check_mode 3 "$vt_chosen_name"; then + set vtGrub2Mode=1 + elif vt_str_begin "$vt_volume_id" "HOLO_"; then + if [ -d (loop)/loader/entries ]; then + set vtGrub2Mode=1 + fi + elif vt_str_begin "$vt_volume_id" "KRD"; then + if [ -f (loop)/boot/grub/grub.cfg.sig ]; then + set vtGrub2Mode=1 + fi + fi + + if [ -n "$vtGrub2Mode" ]; then + ventoy_debug_pause + else + if [ "$VTOY_EFI_ARCH" != "mips" ]; then + chainloader ${vtoy_path}/ventoy_${VTOY_EFI_ARCH}.efi fallback env_param=${env_param} isoefi=${LoadIsoEfiDriver} FirstTry=${FirstTryBootFile} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} + boot + fi + fi + + # fallback + set vtback_root=$root + vt_push_last_entry + set vtback_theme=$theme + unset theme + + vt_trailer_cpio "$vtoy_iso_part" "$vt_chosen_path" noinit + vt_set_boot_opt rdinit=/vtoy/vtoy + + set root=(loop) + set vtback_cfg_find=0 + for cfg in "/boot/grub/grub.cfg" "/EFI/BOOT/grub.cfg" "/EFI/debian/grub.cfg" "EFI/boot/grub.cfg" "efi/boot/grub.cfg" "/grub/grub.cfg" "EFI/BOOT/BOOTX64.conf"; do + if [ -e "$cfg" ]; then + set vtback_cfg_find=1 + configfile "$cfg" + break + fi + done + if [ $vtback_cfg_find -eq 0 ]; then + if [ -f (loop)/loader/loader.conf -a -d (loop)/loader/entries ]; then + if vt_str_begin "$vt_volume_id" "HOLO_"; then + set root=(loop,2) + vt_systemd_menu (loop,2) vt_sys_menu_mem + else + vt_systemd_menu (loop) vt_sys_menu_mem + fi + set vtback_cfg_find=1 + configfile "mem:${vt_sys_menu_mem_addr}:size:${vt_sys_menu_mem_size}" + fi + fi + + if [ $vtback_cfg_find -eq 0 ]; then + if [ -f (loop)/boot/isolinux/syslnx64.cfg ]; then + syslinux_configfile (loop)/boot/isolinux/syslnx64.cfg + set vtback_cfg_find=1 + elif [ -f (loop)/boot/syslinux/porteus.cfg ]; then + syslinux_configfile (loop)/boot/syslinux/porteus.cfg + set vtback_cfg_find=1 + fi + fi + + if [ "$vtback_cfg_find" = "0" ]; then + echo " " + echo "No bootfile found for UEFI!" + echo "Maybe the image does not support $VTOY_EFI_ARCH UEFI" + echo " " + sleep 30 + fi + + vt_unset_boot_opt + set root=$vtback_root + set theme=$vtback_theme + vt_pop_last_entry + ventoy_gui_console + else + echo "chain empty failed" + ventoy_pause + fi +} + +function uefi_unix_menu_func { + ventoy_unix_comm_proc $1 "${chosen_path}" + + if [ -n "$vtoy_chain_mem_addr" ]; then + ventoy_acpi_param ${vtoy_chain_mem_addr} 2048 + ventoy_cli_console + chainloader ${vtoy_path}/ventoy_${VTOY_EFI_ARCH}.efi env_param=${env_param} isoefi=${LoadIsoEfiDriver} FirstTry=${FirstTryBootFile} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} + boot + else + echo "chain empty failed" + ventoy_pause + fi +} + +function ventoy_reset_nojoliet { + if vt_str_begin "$vt_volume_id" "ARCARESCUE"; then + vt_iso9660_nojoliet 1 + else + vt_iso9660_nojoliet 0 + fi + + vt_append_extra_sector 0 +} + +function uefi_iso_menu_func { + if [ -n "$vtisouefi" ]; then + set LoadIsoEfiDriver=on + unset vtisouefi + elif vt_check_mode 2 "$vt_chosen_name"; then + set LoadIsoEfiDriver=on + else + unset LoadIsoEfiDriver + fi + + set chosen_path="$2" + vt_select_auto_install "${chosen_path}" + vt_select_persistence "${chosen_path}" + + if ! vt_is_udf "${1}${chosen_path}"; then + # Lenovo EasyStartup need an addional sector for boundary check + if vt_str_begin "$vt_volume_id" "EasyStartup"; then + vt_skip_svd "${vtoy_iso_part}${vt_chosen_path}" + vt_append_extra_sector 1 + fi + fi + + if [ -d (loop)/EFI ]; then + set vt_efi_dir=YES + elif [ -d (loop)/efi ]; then + set vt_efi_dir=YES + else + set vt_efi_dir=NO + fi + + if [ -n "$vtcompat" ]; then + set ventoy_compatible=YES + unset vtcompat + elif vt_check_mode 1 "$vt_chosen_name"; then + set ventoy_compatible=YES + else + vt_check_compatible (loop) + fi + + vt_img_sector "${1}${chosen_path}" + + if [ "$ventoy_fs_probe" = "iso9660" ]; then + vt_select_conf_replace "${1}" "${chosen_path}" + fi + + if [ "$vtoy_os" = "Windows" ]; then + vt_check_compatible_pe (loop) + uefi_windows_menu_func "$1" "${chosen_path}" + elif [ "$vtoy_os" = "Unix" ]; then + uefi_unix_menu_func "$1" "${chosen_path}" + else + vt_check_compatible_linux (loop) + uefi_linux_menu_func "$1" "${chosen_path}" + fi + + ventoy_gui_console +} + +function uefi_iso_memdisk { + echo 'Loading ISO file to memory ...' + vt_load_img_memdisk "${1}${2}" vtoy_iso_buf + + ventoy_cli_console + chainloader ${vtoy_path}/ventoy_${VTOY_EFI_ARCH}.efi memdisk env_param=${env_param} isoefi=${LoadIsoEfiDriver} ${vtdebug_flag} mem:${vtoy_iso_buf_addr}:size:${vtoy_iso_buf_size} + boot + + ventoy_gui_console +} + +function vtoy_windows_wimboot { + if [ -f (loop)/x86/sources/boot.wim -a -f (loop)/x64/sources/boot.wim ]; then + vt_sel_wimboot vtoy_wimboot_bit + if [ "$vtoy_wimboot_bit" = "32" ]; then + set vtoy_wimboot_prefix=(loop)/x86 + else + set vtoy_wimboot_prefix=(loop)/x64 + fi + else + set vtoy_wimboot_prefix=(loop) + if vt_is_pe64 $vtoy_wimboot_prefix/setup.exe; then + set vtoy_wimboot_bit=64 + else + set vtoy_wimboot_bit=32 + fi + fi + + if [ -n "${vtdebug_flag}" ]; then + echo vtoy_wimboot_prefix=$vtoy_wimboot_prefix vtoy_wimboot_bit=$vtoy_wimboot_bit vt_wimkernel=$vt_wimkernel + fi + + vt_windows_wimboot_data "$vtoy_wimboot_prefix/sources/boot.wim" vtoy_init_exe vtoy_wim_bit + + if [ "$grub_platform" = "pc" ]; then + linux16 "$vtoy_path/$vt_wimkernel" quiet + ventoy_debug_pause + + vt_set_wim_load_prompt 1 "Loading files......" + initrd16 newc:winpeshl.exe:mem:${vtoy_wimboot_mem_addr}:size:${vtoy_wimboot_mem_size} \ + newc:vtoy_wimboot:$vtoy_wimboot_prefix/boot/bcd \ + newc:bcd:$vtoy_wimboot_prefix/boot/bcd \ + newc:boot.sdi:$vtoy_wimboot_prefix/boot/boot.sdi \ + newc:boot.wim:$vtoy_wimboot_prefix/sources/boot.wim + vt_set_wim_load_prompt 0 + boot + else + vt_set_wim_load_prompt 1 "Loading files......" + vt_load_file_to_mem "nodecompress" $vtoy_wimboot_prefix/sources/boot.wim vtoy_wimfile_mem + vt_set_wim_load_prompt 0 + + if [ $? -eq 0 ]; then + set vtoy_wimfile_path=mem:${vtoy_wimfile_mem_addr}:size:${vtoy_wimfile_mem_size} + else + set vtoy_wimfile_path=$vtoy_wimboot_prefix/sources/boot.wim + fi + + ventoy_cli_console + chainloader "$vtoy_path/$vt_wimkernel" quiet \ + "vf=winpeshl.exe:mem:${vtoy_wimboot_mem_addr}:size:${vtoy_wimboot_mem_size}" \ + "vf=vtoy_wimboot:$vtoy_wimboot_prefix/boot/bcd" \ + "vf=bcd:$vtoy_wimboot_prefix/boot/bcd" \ + "vf=boot.sdi:$vtoy_wimboot_prefix/boot/boot.sdi" \ + "vf=boot.wim:$vtoy_wimfile_path" \ + pfsize=$vtoy_chain_file_size \ + pfread=$vtoy_chain_file_read + boot + ventoy_gui_console + fi +} + +function vtoy_winpe_wimboot { + unset vtoy_boot_sdi_legacy + unset vtoy_boot_sdi_efi + + set vtoy_wimboot_prefix=(loop) + set vtoy_wim_path="$1" + + if [ -n "${vtdebug_flag}" ]; then + echo "winpe_wimboot $1 $2 $3" + fi + + if [ "$2" != "0" ]; then + set vtoy_boot_sdi_legacy="newc:boot.sdi:$vtoy_wimboot_prefix/$2" + set vtoy_boot_sdi_efi="vf=boot.sdi:$vtoy_wimboot_prefix/$2" + fi + + vt_windows_wimboot_data $vtoy_wimboot_prefix/$vtoy_wim_path vtoy_init_exe vtoy_wim_bit + + if [ "$grub_platform" = "pc" ]; then + linux16 "$vtoy_path/$vt_wimkernel" quiet + ventoy_debug_pause + + vt_set_wim_load_prompt 1 "Loading files......" + initrd16 newc:$vtoy_init_exe:mem:${vtoy_wimboot_mem_addr}:size:${vtoy_wimboot_mem_size} \ + newc:vtoy_wimboot:$vtoy_path/$vt_wimkernel \ + newc:bootmgr.exe:mem:${vtoy_pe_bootmgr_mem_addr}:size:${vtoy_pe_bootmgr_mem_size} \ + newc:bcd:mem:${vtoy_pe_bcd_mem_addr}:size:${vtoy_pe_bcd_mem_size} \ + $vtoy_boot_sdi_legacy \ + newc:boot.wim:$vtoy_wimboot_prefix/$vtoy_wim_path + vt_set_wim_load_prompt 0 + boot + else + if [ "$VTOY_EFI_ARCH" = "x64" -a "$vtoy_wim_bit" = "32" ]; then + echo -e "\nThis is 32bit Windows and does NOT support x86_64 UEFI firmware.\n" + echo -e "这是32位的 Windows 系统,不支持当前的64位 UEFI 环境。\n" + fi + + vt_set_wim_load_prompt 1 "Loading files......" + vt_load_file_to_mem "nodecompress" $vtoy_wimboot_prefix/$vtoy_wim_path vtoy_wimfile_mem + vt_set_wim_load_prompt 0 + + if [ $? -eq 0 ]; then + set vtoy_wimfile_path=mem:${vtoy_wimfile_mem_addr}:size:${vtoy_wimfile_mem_size} + else + set vtoy_wimfile_path=$vtoy_wimboot_prefix/$vtoy_wim_path + fi + + unset vtoy_boot_efi_path + if [ -F (loop)/efi/boot/boot${VTOY_EFI_ARCH}.efi ]; then + set vtoy_boot_efi_path="vf=bootx64.efi:(loop)/efi/boot/boot${VTOY_EFI_ARCH}.efi" + fi + + ventoy_cli_console + chainloader "$vtoy_path/$vt_wimkernel" quiet \ + "vf=$vtoy_init_exe:mem:${vtoy_wimboot_mem_addr}:size:${vtoy_wimboot_mem_size}" \ + "vf=vtoy_wimboot:$vtoy_path/$vt_wimkernel" \ + "vf=bcd:mem:${vtoy_pe_bcd_mem_addr}:size:${vtoy_pe_bcd_mem_size}" \ + "$vtoy_boot_sdi_efi" \ + "$vtoy_boot_efi_path" \ + "vf=boot.wim:$vtoy_wimfile_path" \ + pfsize=$vtoy_chain_file_size \ + pfread=$vtoy_chain_file_read + boot + ventoy_gui_console + fi +} + +function vtoy_wimboot_func { + if [ "$grub_platform" = "pc" ]; then + set vt_wimkernel=wimboot.x86_64.xz + else + if [ "$grub_cpu" = "i386" ]; then + set vt_wimkernel=wimboot.i386.efi.xz + else + set vt_wimkernel=wimboot.x86_64.xz + fi + fi + + if vt_is_standard_winiso (loop); then + echo -e "\n==================== VENTOY WIMBOOT ==================\n" + vtoy_windows_wimboot + else + vt_sel_winpe_wim (loop) + if [ -n "$vtoy_pe_wim_path" ]; then + echo -e "\n==================== VENTOY WIMBOOT ==================\n" + + vt_fs_ignore_case 1 + vt_load_file_to_mem "auto" $vtoy_path/common_bcd.xz vtoy_pe_bcd_mem + + set vt_sdi_path=0 + for vsdi in "boot/boot.sdi" "2K10/FONTS/boot.sdi" "SSTR/boot.sdi" "ISPE/BOOT.SDI" \ + "boot/uqi.sdi" "ISYL/boot.sdi" "WEPE/WEPE.SDI" ; do + if [ -F "(loop)/$vsdi" ]; then + set vt_sdi_path=$vsdi + break + fi + done + + if [ "$grub_platform" = "pc" ]; then + vt_load_file_to_mem "auto" $vtoy_path/common_bootmgr.xz vtoy_pe_bootmgr_mem + vtoy_winpe_wimboot "$vtoy_pe_wim_path" "$vt_sdi_path" 1 + else + vtoy_winpe_wimboot "$vtoy_pe_wim_path" "$vt_sdi_path" 0 + fi + + vt_fs_ignore_case 0 + fi + fi +} + +function legacy_windows_menu_func { + vt_windows_reset + + unset vt_cur_wimboot_mode + if vt_check_mode 4 "$vt_chosen_name"; then + set vt_cur_wimboot_mode=1 + fi + + if [ "$ventoy_compatible" = "NO" -o "$vt_cur_wimboot_mode" = "1" ]; then + if [ "$ventoy_fs_probe" = "iso9660" ]; then + loopback -d loop + vt_iso9660_nojoliet 1 + loopback loop "$1$2" + fi + + for file in "boot/bcd" "/efi/microsoft/boot/bcd" "SSTR/BCD" "boot/bce"; do + vt_windows_collect_wim_patch bcd (loop)/$file + done + + distro_specify_wim_patch + + vt_windows_count_wim_patch vt_wim_cnt + if [ $vt_wim_cnt -eq 0 ]; then + distro_specify_wim_patch_phase2 + fi + + ventoy_debug_pause + if [ -z "$vt_cur_wimboot_mode" ]; then + locate_wim "${chosen_path}" + fi + fi + + vt_windows_chain_data "${1}${chosen_path}" + ventoy_debug_pause + + if [ "$vt_cur_wimboot_mode" = "1" ]; then + vtoy_wimboot_func + fi + + if [ -n "$vtoy_chain_mem_addr" ]; then + ventoy_acpi_param ${vtoy_chain_mem_addr} 2048 + if [ "$ventoy_compatible" = "NO" ]; then + linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} + else + linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} ibft mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} + fi + boot + else + echo "chain empty failed" + ventoy_pause + fi +} + +function legacy_linux_menu_func { + if [ "$ventoy_compatible" = "NO" ]; then + + if [ "$ventoy_fs_probe" = "udf" ]; then + loopback -d loop + set ventoy_fs_probe=iso9660 + loopback loop "$1$2" + fi + + + if vt_syslinux_need_nojoliet "$1$2"; then + vt_iso9660_nojoliet 1 + loopback -d loop + loopback loop "$1$2" + fi + + vt_load_cpio $vtoy_path "$2" "$1" "busybox=$ventoy_busybox_ver" + + vt_linux_clear_initrd + + if [ -d (loop)/pmagic ]; then + vt_linux_specify_initrd_file /pmagic/initrd.img + else + for dir in "isolinux" "boot/isolinux" "boot/x86_64/loader" "syslinux" "boot/syslinux"; do + if [ -d (loop)/$dir ]; then + vt_linux_parse_initrd_isolinux (loop)/$dir/ + fi + done + fi + + # special process for special distros + #archlinux + if [ -d (loop)/arch/boot/syslinux ]; then + vt_linux_parse_initrd_isolinux (loop)/arch/boot/syslinux/ /arch/ + vt_linux_parse_initrd_isolinux (loop)/arch/boot/syslinux/ /arch/boot/syslinux/ + elif [ -d (loop)/anarchy/boot/syslinux ]; then + vt_linux_parse_initrd_isolinux (loop)/anarchy/boot/syslinux/ /anarchy/ + + #manjaro + elif [ -d (loop)/manjaro ]; then + if [ -e (loop)/boot/grub/kernels.cfg ]; then + vt_linux_parse_initrd_grub file (loop)/boot/grub/kernels.cfg + fi + elif [ -e (loop)/boot/grub/grub.cfg ]; then + vt_linux_parse_initrd_grub file (loop)/boot/grub/grub.cfg + fi + + distro_specify_initrd_file + + vt_linux_initrd_count vtcount + if [ $vtcount -eq 0 ]; then + if [ -d (loop)/rancheros ]; then + vt_linux_parse_initrd_isolinux (loop)/boot/ /boot/isolinux/ + fi + + distro_specify_initrd_file_phase2 + fi + + locate_initrd + fi + + vt_linux_chain_data "${1}${chosen_path}" + ventoy_debug_pause + + if [ -n "$vtoy_chain_mem_addr" ]; then + unset vtGrub2Mode + if vt_check_mode 3 "$vt_chosen_name"; then + set vtGrub2Mode=1 + elif vt_str_begin "$vt_volume_id" "HOLO_"; then + if [ -d (loop)/loader/entries ]; then + set vtGrub2Mode=1 + fi + fi + + if [ -n "$vtGrub2Mode" ]; then + ventoy_acpi_param ${vtoy_chain_mem_addr} 2048 + ventoy_cli_console + + # fallback + set vtback_root=$root + vt_push_last_entry + set vtback_theme=$theme + unset theme + + vt_trailer_cpio "$vtoy_iso_part" "$vt_chosen_path" noinit + vt_set_boot_opt rdinit=/vtoy/vtoy + + set root=(loop) + set vtback_cfg_find=0 + for cfg in "/boot/grub/grub.cfg" "/EFI/BOOT/grub.cfg" "/EFI/debian/grub.cfg" "EFI/boot/grub.cfg" "efi/boot/grub.cfg" "/grub/grub.cfg" "EFI/BOOT/BOOTX64.conf"; do + if [ -e "$cfg" ]; then + set vtback_cfg_find=1 + configfile "$cfg" + break + fi + done + if [ $vtback_cfg_find -eq 0 ]; then + if [ -f (loop)/loader/loader.conf -a -d (loop)/loader/entries ]; then + if vt_str_begin "$vt_volume_id" "HOLO_"; then + set root=(loop,2) + vt_systemd_menu (loop,2) vt_sys_menu_mem + else + vt_systemd_menu (loop) vt_sys_menu_mem + fi + set vtback_cfg_find=1 + configfile "mem:${vt_sys_menu_mem_addr}:size:${vt_sys_menu_mem_size}" + fi + fi + + if [ $vtback_cfg_find -eq 0 ]; then + if [ -f (loop)/boot/isolinux/syslnx64.cfg ]; then + syslinux_configfile (loop)/boot/isolinux/syslnx64.cfg + set vtback_cfg_find=1 + elif [ -f (loop)/boot/syslinux/porteus.cfg ]; then + syslinux_configfile (loop)/boot/syslinux/porteus.cfg + set vtback_cfg_find=1 + fi + fi + + vt_unset_boot_opt + set root=$vtback_root + set theme=$vtback_theme + vt_pop_last_entry + ventoy_gui_console + else + ventoy_acpi_param ${vtoy_chain_mem_addr} 2048 + linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} + boot + fi + else + echo "chain empty failed" + ventoy_pause + fi +} + + +function legacy_unix_menu_func { + ventoy_unix_comm_proc $1 "${chosen_path}" + + if [ -n "$vtoy_chain_mem_addr" ]; then + #ventoy_acpi_param ${vtoy_chain_mem_addr} 2048 + linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} + boot + else + echo "chain empty failed" + ventoy_pause + fi +} + + +function legacy_iso_menu_func { + set chosen_path="$2" + + vt_select_auto_install "${chosen_path}" + vt_select_persistence "${chosen_path}" + + if [ -n "$vtcompat" ]; then + set ventoy_compatible=YES + unset vtcompat + elif vt_check_mode 1 "$vt_chosen_name"; then + set ventoy_compatible=YES + else + vt_check_compatible (loop) + fi + + vt_img_sector "${1}${chosen_path}" + + if [ "$ventoy_fs_probe" = "iso9660" ]; then + vt_select_conf_replace "${1}" "${chosen_path}" + fi + + if [ "$vtoy_os" = "Windows" ]; then + vt_check_compatible_pe (loop) + legacy_windows_menu_func "$1" "${chosen_path}" + elif [ "$vtoy_os" = "Unix" ]; then + legacy_unix_menu_func "$1" "${chosen_path}" + else + vt_check_compatible_linux (loop) + legacy_linux_menu_func "$1" "${chosen_path}" + fi + vt_secondary_recover_mode +} + +function legacy_iso_memdisk { + + linux16 $vtoy_path/memdisk iso raw + echo "Loading ISO file to memory ..." + initrd16 "${1}${2}" + boot +} + + +function iso_endless_os_proc { + if [ -d (loop)/ ]; then + loopback -d loop + fi + + loopback loop "${1}${2}" + vt_img_sector "${1}${2}" + + vt_load_cpio $vtoy_path "$2" "$1" "busybox=$ventoy_busybox_ver" + vt_trailer_cpio "$1" "$2" noinit + + ventoy_debug_pause + + vt_set_boot_opt '@kparams' rdinit=/vtoy/vtoy + + set eosimage=loop + set ventoy_bls_bootdev=/boot + set ventoy_loading_tip="Loading files ......" + + export eosimage + configfile (loop)/endless/grub/grub.cfg + + unset eosimage + unset ventoy_bls_bootdev + unset ventoy_loading_tip + + vt_unset_boot_opt +} + + +function ventoy_iso_busybox_ver { + + if [ "$VTOY_EFI_ARCH" = "aa64" ]; then + set ventoy_busybox_ver=a64 + elif [ "$VTOY_EFI_ARCH" = "mips" ]; then + set ventoy_busybox_ver=m64 + else + set ventoy_busybox_ver=32 + + #special process for deepin-live iso + if [ "$vt_chosen_size" = "403701760" ]; then + if vt_strstr "$vt_chosen_path" "/deepin-live"; then + set ventoy_busybox_ver=64 + fi + elif vt_str_begin "$vt_volume_id" "PHOTON_"; then + set ventoy_busybox_ver=64 + elif vt_str_begin "$vt_volume_id" "smgl-test-quinq-x86_64"; then + set ventoy_busybox_ver=64 + elif vt_str_begin "$vt_volume_id" "LDiagBootable"; then + set ventoy_busybox_ver=64 + elif vt_str_begin "$vt_volume_id" "KAOS_"; then + set ventoy_busybox_ver=64 + elif vt_strstr "$vt_volume_id" "x86_64"; then + set ventoy_busybox_ver=64 + elif vt_istrstr "${vt_chosen_path}" "x86_64"; then + set ventoy_busybox_ver=64 + elif vt_istrstr "${vt_chosen_path}" "amd64"; then + set ventoy_busybox_ver=64 + fi + fi +} + + +function iso_common_menuentry { + unset vt_system_id + unset vt_volume_id + + vt_chosen_img_path vt_chosen_path vt_chosen_size vt_chosen_name + + vt_parse_iso_volume "${vtoy_iso_part}${vt_chosen_path}" vt_system_id vt_volume_id vt_volume_space + if [ $vt_volume_space -NE $vt_chosen_size ]; then + vt_mod $vt_chosen_size 2048 vt_chosen_size_mod + if [ $vt_chosen_size_mod -ne 0 ]; then + echo -e "\n $vt_volume_space $vt_chosen_size $vt_chosen_size_mod\n" + echo -e "\n The size of the iso file \"$vt_chosen_size\" is invalid. File corrupted ?\n" + echo -e " 此ISO文件的大小 \"$vt_chosen_size\" 有问题,请确认文件是否损坏。\n" + echo -en "\n$VTLANG_ENTER_CONTINUE ..." + read vtInputKey + fi + fi + + if vt_check_password "${vt_chosen_path}"; then + return + fi + + if ventoy_vcfg_proc "${vt_chosen_path}"; then + return + fi + + + + #secondary boot menu + if vt_is_udf "${vtoy_iso_part}${vt_chosen_path}"; then + set ventoy_fs_probe=udf + else + set ventoy_fs_probe=iso9660 + ventoy_reset_nojoliet + fi + + if [ -d (loop)/ ]; then + loopback -d loop + fi + loopback loop "${vtoy_iso_part}${vt_chosen_path}" + + get_os_type (loop) + + ventoy_debug_pause + + if vt_need_secondary_menu "$vt_chosen_name"; then + vt_show_secondary_menu "$vt_chosen_path" "$vtoy_os" $vt_chosen_size + if [ "$VTOY_SECOND_EXIT" = "1" ]; then + return + fi + fi + + + if vt_str_begin "$vt_volume_id" "Avira"; then + vt_skip_svd "${vtoy_iso_part}${vt_chosen_path}" + fi + + ventoy_iso_busybox_ver + + #special process for Endless OS + if vt_str_begin "$vt_volume_id" "Endless-OS"; then + iso_endless_os_proc $vtoy_iso_part "$vt_chosen_path" + elif vt_str_begin "$vt_volume_id" "TENS-Public"; then + set vtcompat=1 + fi + + + # auto memdisk mode for some special ISO files + vt_iso_vd_id_parse "${vtoy_iso_part}${vt_chosen_path}" + unset vtMemDiskBoot + if vt_check_mode 0 "$vt_chosen_name"; then + set vtMemDiskBoot=1 + else + if [ "$grub_platform" = "pc" ]; then + if vt_iso_vd_id_begin 1 0 "Memtest86+"; then + set vtMemDiskBoot=1 + elif vt_iso_vd_id_begin 0 1 "KolibriOS"; then + set vtMemDiskBoot=1 + fi + fi + + #For iKuai8 (<64MB) + if [ $vt_chosen_size -LE 67108864 ]; then + if vt_str_begin "$vt_chosen_name" "iKuai"; then + set vtMemDiskBoot=1 + fi + fi + fi + vt_iso_vd_id_clear + + + if [ "$grub_platform" = "pc" ]; then + if [ -n "$vtMemDiskBoot" ]; then + legacy_iso_memdisk $vtoy_iso_part "$vt_chosen_path" + else + legacy_iso_menu_func $vtoy_iso_part "$vt_chosen_path" + fi + else + if [ -n "$vtMemDiskBoot" ]; then + uefi_iso_memdisk $vtoy_iso_part "$vt_chosen_path" + else + uefi_iso_menu_func $vtoy_iso_part "$vt_chosen_path" + fi + fi + + vt_secondary_recover_mode +} + +function miso_common_menuentry { + vt_chosen_img_path vt_chosen_path vt_chosen_size vt_chosen_name + + if vt_check_password "${vt_chosen_path}"; then + return + fi + + echo "memdisk mode boot for $vt_chosen_path" + echo "" + ventoy_debug_pause + + if [ "$grub_platform" = "pc" ]; then + legacy_iso_memdisk $vtoy_iso_part "$vt_chosen_path" + else + uefi_iso_memdisk $vtoy_iso_part "$vt_chosen_path" + fi +} + + +function common_unsupport_menuentry { + echo -e "\n The name of the iso file could NOT contain space or non-ascii characters. \n" + echo -e " 文件名中不能有中文或空格 \n" + echo -en "\n$VTLANG_ENTER_EXIT ..." + read vtInputKey +} + +function miso_unsupport_menuentry { + common_unsupport_menuentry +} + +function iso_unsupport_menuentry { + common_unsupport_menuentry +} + +function wim_common_menuentry { + vt_chosen_img_path vt_chosen_path vt_chosen_size vt_chosen_name + + if vt_check_password "${vt_chosen_path}"; then + return + fi + + if ventoy_vcfg_proc "${vt_chosen_path}"; then + return + fi + + if vt_wim_check_bootable "${vtoy_iso_part}${vt_chosen_path}"; then + vt_wim_chain_data "${vtoy_iso_part}${vt_chosen_path}" + else + echo -e "\n This is NOT a bootable WIM file. \n" + echo -e " 这不是一个可启动的 WIM 文件。\n" + fi + + ventoy_debug_pause + + if [ -n "$vtoy_chain_mem_addr" ]; then + if [ "$grub_platform" = "pc" ]; then + linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} + else + ventoy_cli_console + chainloader ${vtoy_path}/ventoy_${VTOY_EFI_ARCH}.efi env_param=${env_param} isoefi=${LoadIsoEfiDriver} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} + ventoy_gui_console + fi + boot + else + echo "chain empty failed" + ventoy_pause + fi +} + +function wim_unsupport_menuentry { + common_unsupport_menuentry +} + +function efi_common_menuentry { + vt_chosen_img_path vt_chosen_path vt_chosen_size vt_chosen_name + + if vt_check_password "${vt_chosen_path}"; then + return + fi + + if ventoy_vcfg_proc "${vt_chosen_path}"; then + return + fi + + unset vt_vlnk_dst + if vt_is_vlnk_name "${vt_chosen_path}"; then + vt_get_vlnk_dst "${vtoy_iso_part}${vt_chosen_path}" vt_vlnk_dst + if [ -z "$vt_vlnk_dst" ]; then + echo -e "\n### VLNK FILE NOT FOUND ###\n### VLNK 文件不存在 ###\n" + ventoy_pause + return + fi + else + vt_vlnk_dst="${vtoy_iso_part}${vt_chosen_path}" + fi + + ventoy_debug_pause + + ventoy_cli_console + + #first try with chainload + set vtOldRoot=$root + set root=$vtoy_iso_part + chainloader "${vt_vlnk_dst}" + boot + + #retry with isoboot + set root=$vtOldRoot + vt_concat_efi_iso "${vt_vlnk_dst}" vtoy_iso_buf + chainloader ${vtoy_path}/ventoy_${VTOY_EFI_ARCH}.efi memdisk env_param=${env_param} dotefi isoefi=on ${vtdebug_flag} mem:${vtoy_iso_buf_addr}:size:${vtoy_iso_buf_size} + boot + + ventoy_gui_console +} + +function efi_unsupport_menuentry { + common_unsupport_menuentry +} + +function vhdboot_common_func { + vt_patch_vhdboot "$1" + + ventoy_debug_pause + + if [ -n "$vtoy_vhd_buf_addr" ]; then + if [ "$grub_platform" = "pc" ]; then + ventoy_cli_console + linux16 $vtoy_path/memdisk iso raw + initrd16 mem:${vtoy_vhd_buf_addr}:size:${vtoy_vhd_buf_size} + boot + ventoy_gui_console + else + ventoy_cli_console + chainloader ${vtoy_path}/ventoy_${VTOY_EFI_ARCH}.efi memdisk env_param=${env_param} isoefi=${LoadIsoEfiDriver} ${vtdebug_flag} mem:${vtoy_vhd_buf_addr}:size:${vtoy_vhd_buf_size} + boot + ventoy_gui_console + fi + else + echo "Please put the right ventoy_vhdboot.img file to the 1st partition" + ventoy_pause + fi +} + +function vhd_common_menuentry { + vt_chosen_img_path vt_chosen_path vt_chosen_size vt_chosen_name + + if vt_check_password "${vt_chosen_path}"; then + return + fi + + if ventoy_vcfg_proc "${vt_chosen_path}"; then + return + fi + + unset vt_vlnk_dst + if vt_is_vlnk_name "${vt_chosen_path}"; then + vt_get_vlnk_dst "${vtoy_iso_part}${vt_chosen_path}" vt_vlnk_dst + if [ -z "$vt_vlnk_dst" ]; then + echo -e "\n### VLNK FILE NOT FOUND ###\n### VLNK 文件不存在 ###\n" + ventoy_pause + return + fi + else + vt_vlnk_dst="${vt_chosen_path}" + if [ "$VTOY_VHD_NO_WARNING" != "1" ]; then + if [ "$vtoy_iso_fs" != "ntfs" ]; then + echo -e "!!! WARNING !!!\n" + echo -e "\nPartition1 ($vtoy_iso_fs) is NOT ntfs, the VHD(x) file may not boot normally \n" + echo -e "\nVHD(x) 文件所在分区不是 ntfs 格式, 可能无法正常启动 \n\n" + echo -en "\n$VTLANG_ENTER_CONTINUE ..." + read vtInputKey + fi + fi + fi + + vhdboot_common_func "${vt_vlnk_dst}" +} + +function vhd_unsupport_menuentry { + common_unsupport_menuentry +} + +function vtoyboot_common_func { + set AltBootPart=0 + set vtoysupport=0 + + vt_get_vtoy_type "${1}" vtoytype parttype AltBootPart + + if vt_str_begin $vtoytype vhd; then + set vtoysupport=1 + elif [ "$vtoytype" = "raw" ]; then + set vtoysupport=1 + elif [ "$vtoytype" = "vdi" ]; then + set vtoysupport=1 + fi + + if [ $vtoysupport -eq 1 ]; then + if [ "$grub_platform" = "pc" ]; then + if [ "$parttype" = "gpt" -a $AltBootPart -eq 0 ]; then + echo "The OS in the vdisk was created in UEFI mode, but current is Legacy BIOS mode." + echo "虚拟磁盘内的系统是在UEFI模式下创建的,而当前系统是Legacy BIOS模式,可能无法正常启动。" + ventoy_pause + fi + else + if [ "$parttype" = "mbr" -a $AltBootPart -eq 0 ]; then + echo "The OS in the vdisk was created in Legacy BIOS mode, but current is UEFI mode." + echo "虚拟磁盘内的系统是在Legacy BIOS模式下创建的,而当前系统是UEFI模式,可能无法正常启动。" + ventoy_pause + fi + fi + + vt_img_sector "${1}" + vt_raw_chain_data "${1}" + + ventoy_debug_pause + + if [ -n "$vtoy_chain_mem_addr" ]; then + if [ "$grub_platform" = "pc" ]; then + vt_acpi_param ${vtoy_chain_mem_addr} 512 + linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} bios80 sector512 mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} + boot + else + if vt_check_secureboot_var; then + vt_acpi_param ${vtoy_chain_mem_addr} 512 + fi + ventoy_cli_console + chainloader ${vtoy_path}/ventoy_${VTOY_EFI_ARCH}.efi sector512 env_param=${ventoy_env_param} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} + boot + ventoy_gui_console + fi + else + echo "chain empty failed!" + ventoy_pause + fi + else + echo "Unsupported vtoy type $vtoytype" + ventoy_pause + fi +} + +function vtoy_common_menuentry { + vt_chosen_img_path vt_chosen_path vt_chosen_size vt_chosen_name + + if vt_check_password "${vt_chosen_path}"; then + return + fi + + if ventoy_vcfg_proc "${vt_chosen_path}"; then + return + fi + + unset vt_vlnk_dst + if vt_is_vlnk_name "${vt_chosen_path}"; then + vt_get_vlnk_dst "${vtoy_iso_part}${vt_chosen_path}" vt_vlnk_dst + if [ -z "$vt_vlnk_dst" ]; then + echo -e "\n### VLNK FILE NOT FOUND ###\n### VLNK 文件不存在 ###\n" + ventoy_pause + return + fi + else + vt_vlnk_dst="${vtoy_iso_part}${vt_chosen_path}" + fi + + vtoyboot_common_func "${vt_vlnk_dst}" +} + +function vtoy_unsupport_menuentry { + common_unsupport_menuentry +} + +# +#============================================================# +# IMG file boot process # +#============================================================# +# + +function only_uefi_tip { + echo -e "\n This IMG file is only supported in UEFI mode. \n" + echo -en "\n$VTLANG_ENTER_EXIT ..." + read vtInputKey +} + +function ventoy_img_easyos { + vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit + + loopback easysfs (vtimghd,1)/easy.sfs + vt_get_lib_module_ver (easysfs) /lib/modules/ vt_module_ver + + if [ -n "$vt_module_ver" ]; then + for mod in "kernel/drivers/md/dm-mod.ko" "kernel/drivers/dax/dax.ko"; do + if [ -e (easysfs)/lib/modules/$vt_module_ver/$mod ]; then + vt_img_extra_initrd_append (easysfs)/lib/modules/$vt_module_ver/$mod + fi + done + fi + + ventoy_debug_pause + + #boot image file + vt_set_boot_opt rdinit=/vtoy/vtoy + vt_img_hook_root + + syslinux_configfile (vtimghd,1)/syslinux.cfg + + vt_img_unhook_root + vt_unset_boot_opt + loopback -d easysfs +} + +function ventoy_img_easyos2 { + vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit + + if [ -e (vtimghd,2)/easyos/easy.sfs ]; then + loopback easysfs (vtimghd,2)/easyos/easy.sfs + elif [ -d (vtimghd,2)/easyos/releases ]; then + vt_fs_enum_1st_dir (vtimghd,2) /easyos/releases/ vt_dir_name + loopback easysfs (vtimghd,2)/easyos/releases/$vt_dir_name/easy.sfs + fi + + vt_get_lib_module_ver (easysfs) /lib/modules/ vt_module_ver + + if [ -n "$vt_module_ver" ]; then + for mod in "kernel/drivers/md/dm-mod.ko" "kernel/drivers/dax/dax.ko"; do + if [ -e (easysfs)/lib/modules/$vt_module_ver/$mod ]; then + vt_img_extra_initrd_append (easysfs)/lib/modules/$vt_module_ver/$mod + fi + done + fi + + ventoy_debug_pause + + #boot image file + vt_set_boot_opt rdinit=/vtoy/vtoy + vt_img_hook_root + + vt_limine_menu (vtimghd,1)/limine.cfg vt_sys_menu_mem + configfile "mem:${vt_sys_menu_mem_addr}:size:${vt_sys_menu_mem_size}" + + vt_img_unhook_root + vt_unset_boot_opt + loopback -d easysfs +} + +function ventoy_img_volumio { + vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit + + ventoy_debug_pause + + #boot image file + vt_set_boot_opt rdinit=/vtoy/vtoy imgpart=/dev/ventoy2 bootpart=/dev/ventoy1 + vt_img_hook_root + + syslinux_configfile (vtimghd,1)/syslinux.cfg + + vt_img_unhook_root + vt_unset_boot_opt +} + +function ventoy_img_openelec { + elec_ver=$1 + + if [ "$elec_ver" = "LibreELEC" ]; then + if vt_strstr "$vt_chosen_name" "x86_64"; then + set ventoy_busybox_ver=64 + fi + fi + + vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit + + loopback vtloopex $vtoy_efi_part/ventoy/vtloopex.cpio + vt_img_extra_initrd_append (vtloopex)/$elec_ver/vtloopex.tar.xz + + if [ "$elec_ver" = "LibreELEC" ]; then + if [ -f (vtimghd,1)/system ]; then + loopback elecsfs (vtimghd,1)/system + vt_get_lib_module_ver (elecsfs) /usr/lib/kernel-overlays/base/lib/modules/ vt_module_ver + if [ -n "$vt_module_ver" ]; then + for mod in "kernel/drivers/md/dm-mod.ko"; do + if [ -e (elecsfs)/usr/lib/kernel-overlays/base/lib/modules/$vt_module_ver/$mod ]; then + vt_img_extra_initrd_append (elecsfs)/usr/lib/kernel-overlays/base/lib/modules/$vt_module_ver/$mod + fi + done + fi + fi + fi + + ventoy_debug_pause + + #boot image file + vt_set_boot_opt rdinit=/vtoy/vtoy ventoyos=$elec_ver + vt_img_hook_root + + set root=(vtimghd,1) + syslinux_configfile (vtimghd,1)/syslinux.cfg + + vt_img_unhook_root + vt_unset_boot_opt + loopback -d vtloopex + loopback -d elecsfs +} + + +function ventoy_img_freedombox { + vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit + + vt_get_lib_module_ver (vtimghd,1) /lib/modules/ vt_module_ver + if [ -n "$vt_module_ver" ]; then + vt_img_extra_initrd_append (vtimghd,1)/lib/modules/$vt_module_ver/kernel/drivers/md/dm-mod.ko + fi + + ventoy_debug_pause + + #boot image file + vt_set_boot_opt rdinit=/vtoy/vtoy ventoyos=freedombox + vt_img_hook_root + + configfile (vtimghd,1)/boot/grub/grub.cfg + + vt_img_unhook_root + vt_unset_boot_opt +} + +function ventoy_img_paldo { + vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit + + ventoy_debug_pause + + #boot image file + vt_set_boot_opt rdinit=/vtoy/vtoy ventoyos=paldo + vt_img_hook_root + + vt_fs_enum_1st_file (vtimghd,1) /loader/entries/ vt_paldo_entry_conf + vt_file_basename $vt_paldo_entry_conf vtPaldoVer + + echo loading file... + linux (vtimghd,1)/linux-${vtPaldoVer} root=/dev/ventoy1 rootfstype=vfat + initrd (vtimghd,1)/initramfs-${vtPaldoVer} + boot + + vt_img_unhook_root + vt_unset_boot_opt +} + +function ventoy_img_ubos { + vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit + + vt_get_lib_module_ver (vtimghd,3) /lib/modules/ vt_module_ver + if [ -n "$vt_module_ver" ]; then + vt_img_extra_initrd_append (vtimghd,3)/lib/modules/$vt_module_ver/kernel/drivers/md/dm-mod.ko.xz + fi + + ventoy_debug_pause + + #boot image file + vt_set_boot_opt rdinit=/vtoy/vtoy ventoyos=ubos + vt_img_hook_root + + echo loading file... + linux (vtimghd,2)/vmlinuz-linux root=/dev/ventoy3 rw + initrd (vtimghd,2)/initramfs-linux.img + boot + + vt_img_unhook_root + vt_unset_boot_opt +} + +function ventoy_img_recalbox { + if [ $vtoy_img_max_part_end -GT $vt_chosen_size ]; then + echo -e "\nPlease extend the img file size before boot it. \n" + ventoy_pause + return + fi + + vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit + + if [ -e (vtimghd,1)/boot/recalbox ]; then + loopback recalbox (vtimghd,1)/boot/recalbox + vt_get_lib_module_ver (recalbox) /lib/modules/ vt_module_ver + if [ -n "$vt_module_ver" ]; then + vt_img_extra_initrd_append (recalbox)/lib/modules/$vt_module_ver/kernel/drivers/md/dm-mod.ko + fi + fi + + ventoy_debug_pause + + #boot image file + vt_set_boot_opt rdinit=/vtoy/vtoy ventoyos=recalbox + vt_img_hook_root + + set root=(vtimghd,1) + configfile (vtimghd,1)/boot/grub/grub.cfg + + vt_img_unhook_root + vt_unset_boot_opt +} + +function ventoy_img_esysrescue { + vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit + + ventoy_debug_pause + + #boot image file + vt_set_boot_opt rdinit=/vtoy/vtoy ventoyos=esysrescue + vt_img_hook_root + + set root=(vtimghd,1) + configfile (vtimghd,1)/boot/grub/grub.cfg + + vt_img_unhook_root + vt_unset_boot_opt +} + +function ventoy_img_batocera { + vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit + + ventoy_debug_pause + + #boot image file + vt_set_boot_opt rdinit=/vtoy/vtoy ventoyos=batocera + vt_img_hook_root + + set root=(vtimghd,1) + syslinux_configfile (vtimghd,1)/boot/syslinux/syslinux.cfg + + vt_img_unhook_root + vt_unset_boot_opt +} + +function ventoy_img_openwrt { + if [ -e (vtimghd,2)/lib64 ]; then + set ventoy_busybox_ver=64 + fi + + vt_fs_enum_1st_dir (vtimghd,2) /lib/modules/ vt_dir_name + + if [ -f (vtimghd,2)/lib/modules/$vt_dir_name/dm-mod.ko ]; then + set openwrt_plugin_need=0 + vt_img_extra_initrd_append (vtimghd,2)/lib/modules/$vt_dir_name/dm-mod.ko + if [ -f (vtimghd,2)/lib/modules/$vt_dir_name/dax.ko ]; then + vt_img_extra_initrd_append (vtimghd,2)/lib/modules/$vt_dir_name/dax.ko + fi + else + set openwrt_plugin_need=1 + if [ ! -f ${vtoy_iso_part}/ventoy/ventoy_openwrt.xz ]; then + ventoy_gui_console + echo -e "\n ventoy_openwrt.xz not found. Please refer https://www.ventoy.net/en/doc_openwrt.html.\n" + echo -e " 未找到 ventoy_openwrt.xz 文件。请参考 https://www.ventoy.net/cn/doc_openwrt.html\n" + echo -en "\n$VTLANG_ENTER_EXIT ..." + read vtInputKey + ventoy_cli_console + return + fi + fi + + if vt_img_check_range "${vtoy_iso_part}${vt_chosen_path}"; then + ventoy_debug_pause + else + ventoy_gui_console + echo -e "\n IMG file need processed. Please refer https://www.ventoy.net/en/doc_openwrt.html.\n" + echo -e " 此 IMG 文件必须处理之后才能支持。请参考 https://www.ventoy.net/cn/doc_openwrt.html\n" + echo -e "\n press ENTER to exit (请按 回车 键返回) ..." + read vtInputKey + ventoy_cli_console + return + fi + + vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit + + if [ $openwrt_plugin_need -eq 1 ]; then + if [ -f ${vtoy_iso_part}/ventoy/ventoy_openwrt.xz ]; then + vt_img_extra_initrd_append ${vtoy_iso_part}/ventoy/ventoy_openwrt.xz + fi + fi + + #boot image file + vt_set_boot_opt rdinit=/vtoy/vtoy ventoyos=openwrt + vt_img_hook_root + + set root=(vtimghd,1) + configfile (vtimghd,1)/boot/grub/grub.cfg + + vt_img_unhook_root + vt_unset_boot_opt +} + +function ventoy_img_tails { + vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit + + ventoy_debug_pause + + #boot image file + vt_set_boot_opt rdinit=/vtoy/vtoy live-media=/dev/dm-1 ventoyos=tails + vt_img_hook_root + + set root=(vtimghd,1) + configfile (vtimghd,1)/efi/debian/grub.cfg + + vt_img_unhook_root + vt_unset_boot_opt +} + +function ventoy_img_fydeos { + if [ "$grub_platform" = "pc" ]; then + only_uefi_tip + return + fi + + vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=64" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit + + ventoy_debug_pause + + #boot image file + vt_set_boot_opt rdinit=/vtoy/vtoy ventoyos=fydeos + vt_img_hook_root + + set grubdisk=vtimghd + set grubpartA=(vtimghd,3) + set grubpartB=(vtimghd,5) + set linuxpartA=(sda,3) + set linuxpartB=(sda,5) + + set root=(vtimghd,12) + configfile (vtimghd,12)/efi/boot/grub.cfg + + vt_img_unhook_root + vt_unset_boot_opt + + unset grubdisk + unset grubpartA + unset grubpartB + unset linuxpartA + unset linuxpartB +} + +function ventoy_img_cloudready { + if [ "$grub_platform" = "pc" ]; then + only_uefi_tip + return + fi + + vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=64" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit + + ventoy_debug_pause + + #boot image file + vt_set_boot_opt rdinit=/vtoy/vtoy ventoyos=cloudready + vt_img_hook_root + + set grubdisk=vtimghd + set grubpartA=(vtimghd,3) + set grubpartB=(vtimghd,5) + set linuxpartA=(sda,3) + set linuxpartB=(sda,5) + + set root=(vtimghd,12) + configfile (vtimghd,12)/efi/boot/grub.cfg + + vt_img_unhook_root + vt_unset_boot_opt + + unset grubdisk + unset grubpartA + unset grubpartB + unset linuxpartA + unset linuxpartB +} + + +function ventoy_img_fwts { + vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit + + ventoy_debug_pause + + #boot image file + vt_set_boot_opt rdinit=/vtoy/vtoy ventoyos=fwts + vt_img_hook_root + + configfile $prefix/distro/fwts.cfg + + vt_img_unhook_root + vt_unset_boot_opt +} + +function ventoy_img_memtest86 { + chainloader (vtimghd,1)/efi/boot/BOOTX64.efi + boot +} + +function img_unsupport_tip { + echo -e "\n This IMG file is NOT supported now. \n" + echo -e " 当前不支持启动此 IMG 文件 \n" + echo -en "\n$VTLANG_ENTER_EXIT ..." + read vtInputKey +} + +function legacy_img_memdisk { + linux16 $vtoy_path/memdisk + echo "Loading img file to memory ..." + initrd16 "${1}${2}" + + ventoy_cli_console + boot +} + +function img_common_menuentry { + set ventoy_compatible=YES + set ventoy_busybox_ver=32 + unset LoadIsoEfiDriver + + vt_chosen_img_path vt_chosen_path vt_chosen_size vt_chosen_name + + if vt_check_password "${vt_chosen_path}"; then + return + fi + + if ventoy_vcfg_proc "${vt_chosen_path}"; then + return + fi + + if [ "$grub_platform" = "pc" ]; then + if vt_check_mode 0 "$vt_chosen_name"; then + legacy_img_memdisk $vtoy_iso_part "$vt_chosen_path" + return + fi + fi + + loopback vtimghd "${vtoy_iso_part}${vt_chosen_path}" + vt_img_sector "${vtoy_iso_part}${vt_chosen_path}" + + vt_img_part_info (vtimghd) + + set vtback_root=$root + ventoy_cli_console + vt_push_last_entry + set vtback_theme=$theme + unset theme + + vt_img_extra_initrd_reset + + + vt_get_fs_label (vtimghd,1) vtImgHd1Label + + if [ "$vtImgHd1Label" = "STATE" ]; then + vt_get_fs_label (vtimghd,3) vtImgHd3Label + elif [ -d (vtimghd,2)/lib ]; then + vt_get_fs_label (vtimghd,2) vtImgHd2Label + fi + + if [ -z "$vtImgHd1Label" ]; then + if [ -d (vtimghd,2)/efi ]; then + vt_get_fs_label (vtimghd,3) vtImgHd3Label + elif [ -d (vtimghd,12)/efi ]; then + vt_get_fs_label (vtimghd,3) vtImgHd3Label + fi + fi + + if [ -e (vtimghd,1)/etc/hostname ]; then + vt_1st_line (vtimghd,1)/etc/hostname vtImgHostname + fi + + if vt_str_begin "$vtImgHd3Label" "ROOT-"; then + if [ -f (vtimghd,3)/etc/os-release.d/ID ]; then + vt_1st_line (vtimghd,3)/etc/os-release.d/ID vt_release_line1 + if vt_str_begin "$vt_release_line1" "FydeOS"; then + ventoy_img_fydeos + else + ventoy_img_cloudready + fi + elif [ -f (vtimghd,3)/etc/cloudready-release ]; then + ventoy_img_cloudready + elif [ -f (vtimghd,3)/etc/chrome_dev.conf ]; then + ventoy_img_cloudready + fi + elif vt_str_begin "$vtImgHd3Label" "fwts-result"; then + ventoy_img_fwts + elif vt_str_begin "$vtImgHd1Label" "LAKKA"; then + ventoy_img_openelec lakka + elif vt_str_begin "$vtImgHd1Label" "LIBREELEC"; then + ventoy_img_openelec LibreELEC + elif vt_str_begin "$vtImgHd1Label" "paldo-live"; then + ventoy_img_paldo + elif vt_str_begin "$vtImgHostname" "freedombox"; then + ventoy_img_freedombox + elif vt_str_begin "$vtImgHd1Label" "BATOCERA"; then + ventoy_img_batocera + elif vt_str_begin "$vtImgHd1Label" "Tails"; then + ventoy_img_tails + elif [ "$vtImgHd2Label" = "RECALBOX" -o "$vtImgHd1Label" = "RECALBOX" ]; then + ventoy_img_recalbox + elif [ "$vtImgHd1Label" = "ESYSRESCUE" ]; then + ventoy_img_esysrescue + elif [ -e (vtimghd,1)/easy.sfs ]; then + ventoy_img_easyos + elif [ -d (vtimghd,2)/easyos ]; then + ventoy_img_easyos2 + elif [ -e (vtimghd,1)/volumio.initrd ]; then + ventoy_img_volumio + elif [ -f (vtimghd,2)/loader/entries/ubos.conf ]; then + ventoy_img_ubos + elif [ -f (vtimghd,2)/etc/openwrt_version ]; then + ventoy_img_openwrt + else + if [ -f (vtimghd,1)/efi/boot/mt86.png ]; then + if [ "$grub_platform" = "pc" ]; then + img_unsupport_tip + fi + fi + + #common chain + vt_linux_chain_data "${vtoy_iso_part}${vt_chosen_path}" + ventoy_acpi_param ${vtoy_chain_mem_addr} 512 + if [ "$grub_platform" = "pc" ]; then + linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} sector512 mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} + boot + else + chainloader ${vtoy_path}/ventoy_${VTOY_EFI_ARCH}.efi sector512 env_param=${env_param} isoefi=${LoadIsoEfiDriver} FirstTry=${FirstTryBootFile} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} + boot + fi + fi + + loopback -d vtimghd + + set root=$vtback_root + vt_pop_last_entry + set theme=$vtback_theme + ventoy_gui_console + set ventoy_compatible=NO +} + +function img_unsupport_menuentry { + common_unsupport_menuentry +} + +function mimg_common_menuentry { + vt_chosen_img_path vt_chosen_path vt_chosen_size vt_chosen_name + + if vt_check_password "${vt_chosen_path}"; then + return + fi + + echo "memdisk mode boot for $vt_chosen_path" + echo "" + ventoy_debug_pause + + if [ "$grub_platform" = "pc" ]; then + legacy_img_memdisk $vtoy_iso_part "$vt_chosen_path" + else + vt_load_img_memdisk "$vtoy_iso_part$vt_chosen_path" vtoy_img_buf + ventoy_cli_console + chainloader ${vtoy_path}/ventoy_${VTOY_EFI_ARCH}.efi memdisk env_param=${env_param} isoefi=${LoadIsoEfiDriver} ${vtdebug_flag} mem:${vtoy_img_buf_addr}:size:${vtoy_img_buf_size} + boot + ventoy_gui_console + fi +} + +############################################################# +############################################################# +############################################################# +####### Main Process ########### +############################################################# +############################################################# +############################################################# + +set VENTOY_VERSION="1.1.17" + +#ACPI not compatible with Window7/8, so disable by default +set VTOY_PARAM_NO_ACPI=1 + +# Default menu display mode, you can change it as you want. +# 0: List mode +# 1: TreeView mode +set VTOY_DEFAULT_MENU_MODE=0 + +set VTOY_MEM_DISK_STR="[Memdisk]" +set VTOY_ISO_RAW_STR="Compatible Mode" +set VTOY_GRUB2_MODE_STR="GRUB2 Mode" +set VTOY_WIMBOOT_MODE_STR="WIMBOOT Mode" +set VTOY_ISO_UEFI_DRV_STR="UEFI FS" + +set VTOY_F2_CMD="vt_browser_disk" +set VTOY_F4_CMD="ventoy_localboot" +set VTOY_F5_CMD="ventoy_diagnosis" +set VTOY_F6_CMD="ventoy_ext_menu" +set VTOY_HELP_CMD="ventoy_show_help" +set VTOY_CHKSUM_CMD="ventoy_checksum" +set VTOY_HELP_TXT_LANGUAGE="en_US" +set VTOY_CHKSUM_FILE_PATH="X" +set VTOY_LANG_CMD="ventoy_language" + + +if [ "$grub_platform" = "pc" ]; then + set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION BIOS www.ventoy.net" +else + if [ "$grub_cpu" = "i386" ]; then + set VTOY_EFI_ARCH=ia32 + set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION IA32 www.ventoy.net" + elif [ "$grub_cpu" = "arm64" ]; then + set VTOY_EFI_ARCH=aa64 + set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION AA64 www.ventoy.net" + elif [ "$grub_cpu" = "mips64el" ]; then + set VTOY_EFI_ARCH=mips + set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION MIPS www.ventoy.net" + else + set VTOY_EFI_ARCH=x64 + set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION UEFI www.ventoy.net" + fi +fi + +vt_device $root vtoy_dev + +if [ "$vtoy_dev" = "tftp" ]; then + set vtoy_path=($root) + for vtid in 0 1 2 3; do + if [ -f (hd$vtid,2)/ventoy/ventoy.cpio ]; then + set vtoy_iso_part=(hd$vtid,1) + set vtoy_efi_part=(hd$vtid,2) + set vtoydev=hd$vtid + break + fi + done + loadfont ascii + + if [ -n "$vtoy_efi_part" ]; then + vt_load_file_to_mem "auto" $vtoy_efi_part/grub/fonts/unicode.pf2 vtoy_font_mem + loadfont mem:${vtoy_font_mem_addr}:size:${vtoy_font_mem_size} + fi + + if [ -f $vtoy_iso_part/ventoy/ventoy.json ]; then + set vt_plugin_path=$vtoy_iso_part + else + set vt_plugin_path=$prefix + vt_load_plugin $vt_plugin_path + fi +else + if [ "$prefix" = "(ventoydisk)/grub" ]; then + set vtoy_path=(ventoydisk)/ventoy + else + set vtoy_path=($root)/ventoy + fi + + set vtoydev=$vtoy_dev + set vtoy_iso_part=($vtoy_dev,1) + set vtoy_efi_part=($vtoy_dev,2) + + vt_load_file_to_mem "auto" $prefix/fonts/unicode.pf2 vtoy_font_mem + loadfont mem:${vtoy_font_mem_addr}:size:${vtoy_font_mem_size} + + set vt_plugin_path=$vtoy_iso_part +fi + +#Load Partition Table +vt_load_part_table $vtoydev + +#Load menu lang file +ventoy_load_menu_lang_file + +#Load Plugin +if [ -f $vtoy_iso_part/ventoy/ventoy.json ]; then + clear + vt_load_plugin $vtoy_iso_part + clear +else + vt_check_json_path_case $vtoy_iso_part +fi + +#Update Secure Boot Policy +vt_update_sb_policy + + +if [ -n "$VTOY_MENU_LANGUAGE" ]; then + vt_init_menu_lang "$VTOY_MENU_LANGUAGE" +else + vt_init_menu_lang en_US +fi + +if [ -n "$VTOY_MENU_TIMEOUT" ]; then + set timeout=$VTOY_MENU_TIMEOUT +else + unset timeout +fi + +if [ -f $vtoy_iso_part/ventoy/ventoy_wimboot.img ]; then + vt_load_wimboot $vtoy_iso_part/ventoy/ventoy_wimboot.img +elif [ -f $vtoy_efi_part/ventoy/ventoy_wimboot.img ]; then + vt_load_wimboot $vtoy_efi_part/ventoy/ventoy_wimboot.img +fi + +if [ -f $vtoy_iso_part/ventoy/ventoy_vhdboot.img ]; then + vt_load_vhdboot $vtoy_iso_part/ventoy/ventoy_vhdboot.img +elif [ -f $vtoy_efi_part/ventoy/ventoy_vhdboot.img ]; then + vt_load_vhdboot $vtoy_efi_part/ventoy/ventoy_vhdboot.img +fi + + +if [ $VTOY_DEFAULT_MENU_MODE -eq 0 ]; then + set VTOY_F3_CMD="vt_dynamic_menu 1 1" +else + set VTOY_F3_CMD="vt_dynamic_menu 1 0" +fi + +terminal_output console + +if [ -n "$vtoy_gfxmode" ]; then + set gfxmode=$vtoy_gfxmode + set gfxpayload=keep +else + set gfxmode=1024x768 + set gfxpayload=keep +fi + + +if [ "$vtoy_display_mode" = "CLI" ]; then + terminal_output console +elif [ "$vtoy_display_mode" = "serial" ]; then + if [ -n "$vtoy_serial_param" ]; then + serial $vtoy_serial_param + fi + terminal_input serial + terminal_output serial +elif [ "$vtoy_display_mode" = "serial_console" ]; then + if [ -n "$vtoy_serial_param" ]; then + serial $vtoy_serial_param + fi + terminal_input serial console + terminal_output serial console +else + if [ "$vtoy_gfxmode" = "max" ]; then + set gfxmode=1024x768 + terminal_output gfxterm + + vt_enum_video_mode + vt_get_video_mode 0 vtCurMode + terminal_output console + set gfxmode=$vtCurMode + terminal_output gfxterm + elif [ "$vtoy_res_fit" = "1" ]; then + terminal_output gfxterm + fi + + if [ -n "$vtoy_theme" ]; then + vt_set_theme + else + set theme=$prefix/themes/ventoy/theme.txt + fi + terminal_output gfxterm +fi + +if [ "$grub_platform" = "efi" ]; then + set mouse_delta=4000 + # terminal_input --append mouse +fi + +if [ -n "$VTOY_DEFAULT_KBD_LAYOUT" ]; then + set_keyboard_layout "$VTOY_DEFAULT_KBD_LAYOUT" +fi + +if [ -n "$VTOY_PLUGIN_PATH_CASE_MISMATCH" ]; then + clear + echo "$VTOY_PLUGIN_PATH_CASE_MISMATCH" + echo -e "\n\nPath case does not match! ventoy directory and ventoy.json MUST be all lowercase!" + echo -e "\n路径大小写不匹配!ventoy 目录和 ventoy.json 文件的名字必须是全部小写,请修正!" + echo -e "\n\npress ENTER to continue (请按回车键继续) ..." + read vtInputKey +fi + +if [ -n "$VTOY_PLUGIN_SYNTAX_ERROR" ]; then + clear + if [ -n "$VTOY_PLUGIN_ENCODE_ERROR" ]; then + echo -e "\n Encoding type for ventoy.json is not supported, please convert to UTF-8.\n" + echo -e " ventoy.json 文件编码格式不支持,请转换为 UTF-8 编码格式!\n" + else + echo -e "\n Syntax error detected in ventoy.json, please check! \n" + echo -e " ventoy.json 文件中有语法错误,所有配置都不会生效,请检查!\n" + fi + + echo -e "\n press ENTER to continue (请按 回车 键继续) ..." + read vtInputKey +fi + + +for vtTFile in ventoy.json ventoy_grub.cfg; do + if [ -f $vtoy_efi_part/ventoy/$vtTFile ]; then + clear + echo -e "\n You need to put $vtTFile in the 1st partition which hold the ISO files.\n" + echo -e " $vtTFile 放错分区了,请放到镜像分区里的 ventoy 目录下(此目录需要手动创建)!\n" + echo -e "\n press ENTER to continue (请按 回车 键继续) ..." + read vtInputKey + fi +done + +#clear all input key before show main menu +vt_clear_key + +#export necessary variable +export theme +export gfxmode +export gfxpayload +export vtoydev +export vtoy_path +export vtdebug_flag +export vtoy_iso_fs +export vtoy_iso_part +export vtoy_efi_part +export VENTOY_VERSION +export VTOY_CUR_VIDEO_MODE +export VTOY_EFI_ARCH +export VTOY_MEM_DISK_STR +export VTOY_ISO_RAW_STR +export VTOY_GRUB2_MODE_STR +export VTOY_WIMBOOT_MODE_STR +export VTOY_ISO_UEFI_DRV_STR +export VTOY_F2_CMD +export VTOY_F4_CMD +export VTOY_F5_CMD +export VTOY_F6_CMD +export VTOY_HELP_CMD +export VTOY_CHKSUM_CMD +export VTOY_HELP_TXT_LANGUAGE +export VTOY_CHKSUM_FILE_PATH +export VTOY_LANG_CMD + + +#colect all image files (iso files) +set ventoy_img_count=0 +vt_list_img $vtoy_iso_part ventoy_img_count + +#Main menu +if [ $ventoy_img_count -gt 0 ]; then + if [ $VTOY_DEFAULT_MENU_MODE -eq 0 ]; then + vt_dynamic_menu 0 0 + else + vt_dynamic_menu 0 1 + fi +else + if [ -n "$VTOY_NO_ISO_TIP" ]; then + NO_ISO_MENU="No ISO or supported IMG files found, $VTOY_NO_ISO_TIP" + elif [ -n "$VTOY_DEFAULT_SEARCH_ROOT" ]; then + NO_ISO_MENU="No ISO or supported IMG files found, please check VTOY_DEFAULT_SEARCH_ROOT" + else + NO_ISO_MENU="No ISO or supported IMG files found" + fi + menuentry "$NO_ISO_MENU (Press enter to reboot ...)" { + echo -e "\n Rebooting ... " + reboot + } +fi + + +#special VTOY_DEFAULT_IMAGE process +if [ -n "$VTOY_DEFAULT_IMAGE" ]; then + if regexp --set 1:vtHotkey --set 2:vtDefault "(F[2-9])>(.*)" "$VTOY_DEFAULT_IMAGE"; then + + set default="$vtDefault" + if [ -z "$VTOY_MENU_TIMEOUT" ]; then + set timeout=0 + else + set timeout=$VTOY_MENU_TIMEOUT + fi + + export timeout + export default + + vt_fn_mutex_lock 1 + + if [ "$vtHotkey" = "F2" ]; then + unset timeout + vt_browser_disk + elif [ "$vtHotkey" = "F4" ]; then + ventoy_localboot + elif [ "$vtHotkey" = "F5" ]; then + ventoy_diagnosis + elif [ "$vtHotkey" = "F6" ]; then + ventoy_ext_menu + fi + + vt_fn_mutex_lock 0 + + unset timeout + unset default + fi +fi + diff --git a/INSTALL/grub/help/ar_AR.txt b/INSTALL/grub/help/ar_AR.txt new file mode 100644 index 0000000..e7b07b3 --- /dev/null +++ b/INSTALL/grub/help/ar_AR.txt @@ -0,0 +1,18 @@ + L - اختيار اللغة +F1 - عرض معلومات المساعدة +F2 - استعراض وتشغيل الملفات في القرص المحلي +F3 - تبديل وضع القائمة بين Treeview <-> ListView +F4 - تشغيل ويندوز / لينكس على القرص المحلي +F5 - الأدوات المساعده +F6 - تحميل قائمة Grub2 المخصصة +F7 - التبديل بين وضع الواجهة الرسومية <-> وضع النص + +m / Ctrl + m - تحقق من صحة الملفات الصور (md5 / sha1 / sha256 / sha512) +d / Ctrl + d - وضع Memdisk (فقط للصغير WinPE / LiveCD ISO / IMG) +w / Ctrl + w - وضع WIMBOOT (فقط للويندوز القياسي ISO) +r / Ctrl + r - وضع Grub2 (يدعم بعض توزيعات لينكس) +i / Ctrl + i - وضع متوافق (فقط للتدقيق) +u / Ctrl + u - تحميل برنامج التشغيل EFI ISO (فقط للتدقيق، غير مستخدم رسمي) + + +اضغط على ESC للعودة ...... diff --git a/INSTALL/grub/help/bn_BN.txt b/INSTALL/grub/help/bn_BN.txt new file mode 100644 index 0000000..b9faa3d --- /dev/null +++ b/INSTALL/grub/help/bn_BN.txt @@ -0,0 +1,19 @@ + L - ভাষা নির্বাচন করুন +F1 - এই সাহায্য তথ্য প্রদর্শন করুন +F2 - স্থানীয় ডিস্কে ফাইলটি browse করুন এবং boot করুন +F3 - Treeview <-> ListView এর মধ্যে মেনু মোড পরিবর্তন করুন +F4 - স্থানীয় ডিস্কে Windows/Linux boot করুন +F5 - ইউটিলিটিস +F6 - কাস্টম Grub2 মেনু লোড করুন +F7 - GUI মোড <-> TEXT মোডের মধ্যে স্যুইচ করুন + +m/Ctrl+m - চেকসাম ইমেজ ফাইল (md5/sha1/sha256/sha512) +d/Ctrl+d - Memdisk মোড (শুধুমাত্র ছোট WinPE/LiveCD ISO/IMG জন্য) +w/Ctrl+w - WIMBOOT মোড (শুধুমাত্র Windows/WinPE ISO জন্য) +r/Ctrl+r - Grub2 মোড (শুধুমাত্র কিছু Linux distro জন্য) +i/Ctrl+i - Compatible মোড (শুধুমাত্র debug জন্য) +u/Ctrl+u - ISO efi ড্রাইভার লোড করুন (শুধুমাত্র debug জন্য, সরকারীভাবে ব্যবহার করা যাবে না) + + + +ফিরে আসতে ESC টিপুন ...... diff --git a/INSTALL/grub/help/cs_CZ.txt b/INSTALL/grub/help/cs_CZ.txt new file mode 100644 index 0000000..53a5f0c --- /dev/null +++ b/INSTALL/grub/help/cs_CZ.txt @@ -0,0 +1,19 @@ + L - Výběr jazyka +F1 - Zobrazení nápovědy +F2 - Procházet spouštět soubory na disku +F3 - Přepínat mezi zobrazením stromu a seznamu +F4 - Spustit Windows/Linux na disku +F5 - Nástroje +F6 - Nahrát vlastní Grub2 nabídku +F7 - Přepínat mezi grafickým a textovým režimem + +m/Ctrl+m - Kontrolní součky obrazů (md5/sha1/sha256/sha512) +d/Ctrl+d - Memdisk režim (pouze pro malé WinPE/LiveCD ISO/IMG) +w/Ctrl+w - WIMBOOT režim (pouze pro Windows/WinPE ISO soubory) +r/Ctrl+r - Grub2 režim (pouze pro některé linuxové distribuce) +i/Ctrl+i - Režim kompatibility (pouze pro ladění) +u/Ctrl+u - Nahrát ISO EFI ovladač (pouze pro ladění, oficiálně nejde použít) + + + +Stiskněte ESC pro návrat ...... diff --git a/INSTALL/grub/help/de_DE.txt b/INSTALL/grub/help/de_DE.txt new file mode 100644 index 0000000..8c4c328 --- /dev/null +++ b/INSTALL/grub/help/de_DE.txt @@ -0,0 +1,19 @@ + L - Sprache auswählen +F1 - Zeigt dieses Hilfemenü +F2 - Durchsuchen und starten von Dateien auf lokalem Datenträger +F3 - Wechsel zwischen Baum-/Listenansicht +F4 - Windows/Linux von lokalem Datenträger starten +F5 - Werkzeuge +F6 - Benutzerdefiniertes Grub2-Menü laden +F7 - Wechseln zwischen Grafik-/Text-Modus + +m/Strg+m - Prüfsumme von Abbilddatei prüfen (md5/sha1/sha256/sha512) +d/Strg+d - Memdisk-Modus (Nur für kleine WinPE/LiveCD ISO/IMG) +w/Strg+w - WIMBOOT-Modus (Nur für Windows/WinPE ISO) +r/Strg+r - Grub2-Modus (Nur für einige Linux-Distributionen) +i/Strg+i - Kompatibilitäts-Modus (Nur für Fehleranalyse) +u/Strg+u - ISO EFI-Treiber laden (Nur für Fehleranalyse, darf offiziell nicht benutzt werden) + + + +ESC für Zurück drücken...... diff --git a/INSTALL/grub/help/el_GR.txt b/INSTALL/grub/help/el_GR.txt new file mode 100644 index 0000000..3cc35e9 --- /dev/null +++ b/INSTALL/grub/help/el_GR.txt @@ -0,0 +1,19 @@ + L - Επιλογή Γλώσσας +F1 - Εμφάνιση πληροφοριών βοήθειας +F2 - Περιήγηση και εκκίνηση αρχείων στον τοπικό δίσκο +F3 - Εναλλαγή λειτουργίας μενού μεταξύ Προβολής Δένδρου <-> Προβολή Λίστας +F4 - Εκκίνηση Windows/Linux στον τοπικό δίσκο +F5 - Εργαλεία +F6 - Φόρτωση προσαρμοσμένου μενού Grub2 +F7 - Εναλλαγή μεταξύ Λειτουργίας GUI <-> Λειτουργίας ΚΕΙΜΕΝΟΥ + +m/Ctrl+m - Αρχεία εικόνας Checksum (md5/sha1/sha256/sha512) +d/Ctrl+d - Λειτουργία Memdisk (Μόνο για μικρά WinPE/LiveCD ISO/IMG) +w/Ctrl+w - Λειτουργία WIMBOOT (Μόνο για αρχεία ISO Windows/WinPE) +r/Ctrl+r - Λειτουργία Grub2 (Μόνο για ορισμένες διανομές Linux) +i/Ctrl+i - Λειτουργία Συμβατότητας (Μόνο για εντοπισμό σφαλμάτων - debugging) +u/Ctrl+u - Φόρτωση προγράμματος οδήγησης ISO EFI (Μόνο για εντοπισμό σφαλμάτων - debugging, δεν μπορεί να χρησιμοποιηθεί επίσημα) + + + +Πατήστε ESC για επιστροφή ...... \ No newline at end of file diff --git a/INSTALL/grub/help/en_US.txt b/INSTALL/grub/help/en_US.txt new file mode 100644 index 0000000..a065f70 --- /dev/null +++ b/INSTALL/grub/help/en_US.txt @@ -0,0 +1,19 @@ + L - Language Select +F1 - Display help information +F2 - Browse and boot files in the local disk +F3 - Switch menu mode between Treeview <-> ListView +F4 - Boot Windows/Linux on the local disk +F5 - Utilities +F6 - Load Custom Grub2 Menu +F7 - Switch between GUI Mode <-> TEXT Mode + +m/Ctrl+m - Checksum image files (md5/sha1/sha256/sha512) +d/Ctrl+d - Memdisk Mode (Only for small WinPE/LiveCD ISO/IMG) +w/Ctrl+w - WIMBOOT Mode (Only for Windows/WinPE ISO files) +r/Ctrl+r - Grub2 Mode (Only for some Linux distros) +i/Ctrl+i - Compatible Mode (Only for debugging) +u/Ctrl+u - Load ISO EFI driver (Only for debugging, cannot be used officially) + + + +Press ESC to return ...... diff --git a/INSTALL/grub/help/es_ES.txt b/INSTALL/grub/help/es_ES.txt new file mode 100644 index 0000000..11e144d --- /dev/null +++ b/INSTALL/grub/help/es_ES.txt @@ -0,0 +1,19 @@ + L - Seleccionar idioma +F1 - Mostrar información de ayuda +F2 - Navegar y arrancar archivos en el disco local +F3 - Cambiar modo de menú entre Vista de árbol <-> Vista de lista +F4 - Arrancar Windows/Linux en el disco local +F5 - Utilidades +F6 - Cargar menú de Grub2 personalizado +F7 - Cambiar entre Modo GUI <-> Modo texto + +m/Ctrl+m - Suma de comprobación de archivos de imagen (md5/sha1/sha256/sha512) +d/Ctrl+d - Modo Memdisk (Sólo para WinPE/LiveCD ISO/IMG pequeños) +w/Ctrl+w - Modo WIMBOOT (Sólo para archivos Windows/WinPE ISO) +r/Ctrl+r - Modo Grub2 (Sólo para algunas distros de Linux) +i/Ctrl+i - Modo compatible (Sólo para depuración) +u/Ctrl+u - Cargar controlador ISO EFI (Sólo para depuración, uso no oficial) + + + +Presiona ESC para regresar ...... diff --git a/INSTALL/grub/help/fa_IR.txt b/INSTALL/grub/help/fa_IR.txt new file mode 100644 index 0000000..5d1e8a9 --- /dev/null +++ b/INSTALL/grub/help/fa_IR.txt @@ -0,0 +1,19 @@ + L - انتخاب زبان +F1 - نمایش راهنما +F2 - مرور و بوت کردن فایل‌ها در دیسک محلی +F3 - تغییر حالت منو بین درختی <-> لیستی +F4 - بوت کردن ویندوز/لینوکس روی دیسک محلی +F5 - ابزار های کمکی +F6 - بارگیری منوی سفارشی Grub2 +F7 - تغییر حالت بین حالت GUI <-> حالت TEXT + +m/Ctrl+m - اعتبارسنجی فایل ایمیج (md5/sha1/sha256/sha512) +d/Ctrl+d - حالت Memdisk (فقط برای ایمیج های کوچک WinPE/LiveCD ISO/IMG) +w/Ctrl+w - حالت WIMBOOT (فقط برای فایل های ایزو Windows/WinPE) +r/Ctrl+r - حالت Grub2 (فقط برای برخی از توزیع های لینوکس) +i/Ctrl+i - حالت سازگار (فقط برای مشکل زدایی) +u/Ctrl+u - بارگیری درایور ISO EFI (تنها برای مشکل زدایی، نمیتوان به صورت رسمی استفاده کرد) + + + +جهت بازگشت دکمه ESC را کلیک کنید ...... diff --git a/INSTALL/grub/help/fr_FR.txt b/INSTALL/grub/help/fr_FR.txt new file mode 100644 index 0000000..1c8fa18 --- /dev/null +++ b/INSTALL/grub/help/fr_FR.txt @@ -0,0 +1,19 @@ + L - Sélection de la langue +F1 - Afficher l’aide +F2 - Démarrer à partir d’un disque local +F3 - Basculer l’affichage Vue en arbre <-> Vue en liste +F4 - Démarrer un système Windows ou Linux local +F5 - Utilitaires +F6 - Charger le menu GRUB 2 personnalisé +F7 - Basculer entre le mode graphique <-> mode texte + +m/Ctrl+m - Somme de contrôle des images (md5/sha1/sha256/sha512) +d/Ctrl+d - Mode Memdisk (pour WinPE/LiveCD ISO/IMG uniquement) +w/Ctrl+w - Mode WIMBOOT (pour images Windows/WinPE uniquement) +r/Ctrl+r - Mode GRUB 2 (pour quelques distributions Linux uniquement) +i/Ctrl+i - Mode Compatible (pour débug uniquement) +u/Ctrl+u - Charger l’ISO d’un pilote EFI (pour débug uniquement) + + + +Appuyer sur Echap pour sortir… diff --git a/INSTALL/grub/help/hi_HI.txt b/INSTALL/grub/help/hi_HI.txt new file mode 100644 index 0000000..fb1ed99 --- /dev/null +++ b/INSTALL/grub/help/hi_HI.txt @@ -0,0 +1,19 @@ + L - भाषा का चयन +F1 - इस सहायता जानकारी को प्रदर्शित करें +F2 - स्थानीय डिस्क में फ़ाइलें ब्राउज़ करें और बूट करें +F3 - TreeView <-> ListView के बीच मेन्यू मोड स्विच करें +F4 - स्थानीय डिस्क में Windows/Linux बूट करें +F5 - यूटिलिटीज +F6 - कस्टम Grub2 मेनू लोड करें +F7 - GUI मोड <-> Text मोड के बीच स्विच करें + +m/Ctrl+m - चेकसम इमेज फाइल्स (md5/sha1/sha256/sha512) +d/Ctrl+d - Memdisk मोड (केवल small WinPE/LiveCD ISO/IMG के लिए) +w/Ctrl+w - WIMBOOT मोड (केवल Windows/WinPE ISO के लिए) +r/Ctrl+r - Grub2 मोड (केवल कुछ Linux distros के लिए) +i/Ctrl+i - Compatible मोड (केवल डिबग के लिए) +u/Ctrl+u - ISO efi ड्राइवर लोड करें (केवल debug के लिए, आधिकारिक तौर पर इस्तेमाल नहीं किया जा सकता) + + + +वापस जाने के लिए ESC दबाएं ...... diff --git a/INSTALL/grub/help/hr_HR.txt b/INSTALL/grub/help/hr_HR.txt new file mode 100644 index 0000000..cb2c60d --- /dev/null +++ b/INSTALL/grub/help/hr_HR.txt @@ -0,0 +1,19 @@ + L - Izaberite jezik +F1 - Prikazuje ove informacije +F2 - Pokreće imidž fajlove na lokalnom disku +F3 - Mijenja meni između TreeView <-> ListView +F4 - Pokreće Windows/Linux na lokalnom disku +F5 - Alati +F6 - Učitava prilagođen GRUB2 meni +F7 - Mijenja između GUI <-> TEXT načina rada + +m/Ctrl+m - Generira heš odabranog imidž fajla (md5/sha1/sha256/sha512) +d/Ctrl+d - Memdisk način rada (samo za male WinPE/LiveCD imidž fajlove) +w/Ctrl+w - WIMBOOT način rada (samo za Windows/WinPE imidž fajlove) +r/Ctrl+r - GRUB2 način rada (samo za neke Linux distribucije) +i/Ctrl+i - Kompatibilni način rada (samo za testiranje) +u/Ctrl+u - Učitava EFI drajver za imidž fajlove (samo za testiranje) + + + +Pritisnite ESC za povratak ...... diff --git a/INSTALL/grub/help/hu_HU.txt b/INSTALL/grub/help/hu_HU.txt new file mode 100644 index 0000000..a57e406 --- /dev/null +++ b/INSTALL/grub/help/hu_HU.txt @@ -0,0 +1,19 @@ + L - Nyelv kiválasztása +F1 - Súgóinformációk megjelenítése +F2 - Helyi lemezen lévő fájlok tallózása és indítása +F3 - Menü mód váltása fanézet <-> listanézet között +F4 - Windows/Linux indítása a helyi lemezről +F5 - Segédprogramok +F6 - Egyéni Grub2 menü betöltése +F7 - Váltás grafikus mód <-> szöveges mód között + +m/Ctrl+m - Lemezképfájlok ellenőrzőösszege (md5/sha1/sha256/sha512) +d/Ctrl+d - Memórialemez mód (csak kis WinPE/LiveCD ISO/IMG esetén) +w/Ctrl+w - WIMBOOT mód (csak Windows/WinPE ISO esetén) +r/Ctrl+r - Grub2 mód (csak néhány Linux disztribúció esetén) +i/Ctrl+i - Kompatibilis mód (csak hibakereséshez) +u/Ctrl+u - ISO EFI illesztőprogram betöltés (csak hibakereséshez, hivatalosan nem használható) + + + +Nyomja meg az ESC billentyűt a visszalépéshez ...... \ No newline at end of file diff --git a/INSTALL/grub/help/id_ID.txt b/INSTALL/grub/help/id_ID.txt new file mode 100644 index 0000000..2d96f24 --- /dev/null +++ b/INSTALL/grub/help/id_ID.txt @@ -0,0 +1,19 @@ + L - Pilih Bahasa +F1 - Tampilkan bantuan informasi ini +F2 - Jelajah dan jalankan boot berkas pada disk lokal +F3 - Beralih mode menu antara Treeview <-> ListView +F4 - Jalankan boot ke Windows/Linux pada disk lokal +F5 - Alat Utilitas +F6 - Memuat ubah suai Grub2 Menu +F7 - Beralih antara mode GUI <-> Mode TEXT + +m/Ctrl+m - Periksa berkas files (md5/sha1/sha256/sha512) +d/Ctrl+d - Mode Memdisk (Hanya untuk ukuran WinPE/LiveCD ISO/IMG yang kecil) +w/Ctrl+w - Mode WIMBOOT (Hanya untuk berkas ISO Windows/WinPE) +r/Ctrl+r - Mode Grub2 (Hanya untuk distro Linux tertentu) +i/Ctrl+i - Mode Kompatibel/Compatible (Hanya untuk debug saja) +u/Ctrl+u - Memuat ISO efi driver (Hanya untuk debug saja, tidak dapat dipakai secara umum) + + + +Tekan ESC untuk kembali ...... diff --git a/INSTALL/grub/help/it_IT.txt b/INSTALL/grub/help/it_IT.txt new file mode 100644 index 0000000..1b14118 --- /dev/null +++ b/INSTALL/grub/help/it_IT.txt @@ -0,0 +1,19 @@ + L - Selezione lingua interfaccia +F1 - Visualizza informazioni Aiuto (questa guida) +F2 - Sfoglia e avvia file nel disco locale +F3 - Cambia modalità menu tra VistaStruttura <-> VistaElenco +F4 - Avvia Windows/Linux dal disco locale +F5 - Utilità +F6 - Carica il menu Grub2 personalizzato +F7 - Cambia modalità GUI <-> modalità TESTO + +m/Ctrl+m - Checksum file immagine (md5/sha1/sha256/sha512) +d/Ctrl+d - Modalità Memdisk (solo per i file ISO/IMG WinPE/LiveCD piccoli) +w/Ctrl+w - Modalità WIMBOOT (solo per i file ISO Windows/WinPE) +r/Ctrl+r - Modalità Grub2 (solo per alcune distro Linux) +i/Ctrl+i - Modalità Compatibile (solo per debugging) +u/Ctrl+u - Carica driver EFI ISO (solo per debugging, non usato ufficialmente) + + + +Premi 'ESC' per continuare... diff --git a/INSTALL/grub/help/ja_JP.txt b/INSTALL/grub/help/ja_JP.txt new file mode 100644 index 0000000..edfa5c5 --- /dev/null +++ b/INSTALL/grub/help/ja_JP.txt @@ -0,0 +1,19 @@ + L - 言語を選択 +F1 - この画面を表示する +F2 - 手元の記憶装置にある起動ファイルを選択して実行する +F3 - 表示形式を切り替える(一覧 ↔ 階層) +F4 - 手元の記憶装置にあるWindowsまたはLinuxを起動する +F5 - 諸機能 +F6 - Grub2の構成を読み込む +F7 - 操作形式を切り替える(GUI ↔ CUI) + +m/Ctrl+m - イメージの検査合計を計算する (md5/sha1/sha256/sha512) +d/Ctrl+d - 主記憶装置上に記憶域を作成する(容量の小さなWinPE・LiveCD専用) +w/Ctrl+w - WIMBOOTモード(Windows/WinPE ISO専用) +r/Ctrl+r - Grub2モード(一部のLinuxディストリビューション専用) +i/Ctrl+i - 互換モード(開発用) +u/Ctrl+u - ISO efiドライバーを読み取る(開発用,非公式) + + + +この画面を閉じるにはESCを押してください ...... diff --git a/INSTALL/grub/help/ka_GE.txt b/INSTALL/grub/help/ka_GE.txt new file mode 100644 index 0000000..6fc55dc --- /dev/null +++ b/INSTALL/grub/help/ka_GE.txt @@ -0,0 +1,19 @@ + L - ინტერფეისის ენის არჩევა +F1 - დამხმარე ინფორმაციის ჩვენება +F2 - ლოკალური დისკის ფაილების დათვალიერება და ჩატვირთვა +F3 - ჩვენების რეჟიმებს შორის გადართვა 'ხის ხედი' <-> 'სიის ხედი' +F4 - ლოკალური დისკიდან Windows/Linux-ის ჩატვირთვა +F5 - ხელსაწყოები +F6 - მომხმარებლის მიერ შექმნილი Grub2 მენიუს ჩატვირთვა +F7 - ჩვენების რეჟიმის გადართვა 'გრაფიკული' <-> 'ტექსტური' + +m/Ctrl+m - ფაილის საკონტროლო ჯამის შემოწმება (md5/sha1/sha256/sha512) +d/Ctrl+d - Memdisk რეჟიმი (განკუთვნილია მხოლოდ პატარა ზომის WinPE/LiveCD ISO/IMG დისტრიბუტივებისთვის) +w/Ctrl+w - WIMBOOT რეჟიმი (განკუთვნილია მხოლოდ სტანდარტული Windows/WinPE ISO დისტრიბუტივებისთვის) +r/Ctrl+r - Grub2 რეჟიმი (განკუთვნილია მხოლოდ ზოგიერთი Linux დისტრიბუტივებისთვის) +i/Ctrl+i - თავსებადი რეჟიმი (განკუთვნილია მხოლოდ გამართვისთვის) +u/Ctrl+u - ISO EFI დრაივერის ჩატვირთვა (განკუთვნილია მხოლოდ გამართვისთვის, დაუშვებელია ოფიციალური გამოყენება) + + + +დააჭირეთ ESC დაბრუნებისთვის ...... diff --git a/INSTALL/grub/help/ko_KR.txt b/INSTALL/grub/help/ko_KR.txt new file mode 100644 index 0000000..d221eed --- /dev/null +++ b/INSTALL/grub/help/ko_KR.txt @@ -0,0 +1,19 @@ + L - 언어 선택 +F1 - 이 도움말 정보 표시 +F2 - 로컬 디스크에서 파일 찾아보기 및 부팅 +F3 - 트리보기 <-> 목록보기 간에 메뉴 모드 전환 +F4 - 로컬 디스크에서 Windows/Linux 부팅 +F5 - 유틸리티 +F6 - 사용자 지정 Grub2 메뉴 불러오기 +F7 - 그래픽 모드 <-> 텍스트 모드 간에 전환 + +m/Ctrl+m - 이미지 파일 체크섬 (md5/sha1/sha256/sha512) +d/Ctrl+d - Memdisk 모드 (작은 WinPE/LiveCD ISO/IMG에만 해당) +w/Ctrl+w - WIMBOOT 모드 (표준 Windows/WinPE ISO에만 해당) +r/Ctrl+r - Grub2 모드 (일반 Linux 배포판에만 해당) +i/Ctrl+i - 호환 모드 (디버그 전용, 공식적으로 사용할 수 없음) +u/Ctrl+u - ISO EFI 드라이버 불러오기 (디버그 전용, 공식적으로 사용할 수 없음) + + + +돌아가려면 ESC를 누르십시오 ...... diff --git a/INSTALL/grub/help/lg_UG.txt b/INSTALL/grub/help/lg_UG.txt new file mode 100644 index 0000000..8cee84e --- /dev/null +++ b/INSTALL/grub/help/lg_UG.txt @@ -0,0 +1,19 @@ +L - Londako Olulimi +F1 - Laga obuyambi +F2 - Nnoonya era kozesa Fayiro eziri ku Disk +F3 - Kyusa endabika ya Menu wakati wa Masaasana (Treeview) ne y'olukalala (ListView) +F4 - Ttandika Windows/Linux ku disk erimu +F5 - Ebikozesebwa ebirala +F6 - Kozesa Grub2 menu gyewerobozza +F7 - Okukyuusa okuva mu Bifaananyi (GUI Mode) <-> Bigambo (TEXT Mode) + +m/Ctrl+m - Okukebera Checksum image files (md5/sha1/sha256/sha512) +d/Ctrl+d - Memdisk Mode (Ya WinPE/LiveCD ISO/IMG entono zokka) +w/Ctrl+w - WIMBOOT Mode (Ya Windows/WinPE ISO zokka) +r/Ctrl+r - Grub2 Mode (Ya nkola za Linux ezimu) +i/Ctrl+i - Compatible Mode (Ya kutereeza kwokka (debugging)) +u/Ctrl+u - Kozesa ISO EFI driver (Ya kutereeza kwokka (debugging), tesobola kukozesebwa mu butongole) + + + +nyiga ESC to okudda emabega ...... diff --git a/INSTALL/grub/help/pl_PL.txt b/INSTALL/grub/help/pl_PL.txt new file mode 100644 index 0000000..590dad1 --- /dev/null +++ b/INSTALL/grub/help/pl_PL.txt @@ -0,0 +1,19 @@ +L - Wybierz język +F1 — Wyświetl informacje pomocy +F2 — przeglądanie i uruchamianie plików na dysku lokalnym +F3 — Przełącz tryb menu pomiędzy Treeview <-> ListView +F4 — Uruchom system Windows/Linux na dysku lokalnym +F5 — Narzędzia +F6 — Załaduj niestandardowe menu Grub2 +F7 - Przełączanie między trybem GUI <-> trybem TEKST + +m/Ctrl+m — Pliki obrazów z sumą kontrolną (md5/sha1/sha256/sha512) +d/Ctrl+d — Tryb Memdisk (tylko dla małych WinPE/LiveCD ISO/IMG) +w/Ctrl+w — tryb WIMBOOT (tylko dla standardowego systemu Windows/WinPE ISO) +r/Ctrl+r — tryb Grub2 (tylko dla niektórych dystrybucji Linuksa) +i/Ctrl+i — tryb zgodności (tylko do debugowania) +u/Ctrl+u — Załaduj sterownik ISO EFI (tylko do debugowania, nie można go oficjalnie używać) + + + +Naciśnij ESC, aby wrócić... \ No newline at end of file diff --git a/INSTALL/grub/help/pt_BR.txt b/INSTALL/grub/help/pt_BR.txt new file mode 100644 index 0000000..b6d29c5 --- /dev/null +++ b/INSTALL/grub/help/pt_BR.txt @@ -0,0 +1,19 @@ + L - Seleção de Idiomas +F1 - Exibir informações de ajuda +F2 - Explorar e inicializar os arquivos no disco local +F3 - Trocar o modo do menu entre Visualização em Árvore <-> Visualização em Lista +F4 - Inicializar o Windows/Linux no disco local +F5 - Utilitários +F6 - Carregar o Menu Personalizado do Grub2 +F7 - Trocar entre o Modo GUI <-> Modo TEXTO + +m/Ctrl+m - Checksum dos arquivos de imagem (md5/sha1/sha256/sha512) +d/Ctrl+d - Modo Memdisk (Só pros pequenos WinPE/LiveCD ISO/IMG) +w/Ctrl+w - Modo WIMBOOT (Só pra arquivos ISO do Windows/WinPE) +r/Ctrl+r - Modo Grub2 (Só pra algumas distros do Linux) +i/Ctrl+i - Modo Compatível (Só pra debugging) +u/Ctrl+u - Carregar o driver EFI da ISO (Só pra debugging, não pode ser usado oficialmente) + + + +Pressione ESC pra retornar... diff --git a/INSTALL/grub/help/pt_PT.txt b/INSTALL/grub/help/pt_PT.txt new file mode 100644 index 0000000..efc5fd0 --- /dev/null +++ b/INSTALL/grub/help/pt_PT.txt @@ -0,0 +1,18 @@ + L - Selecionar idioma +F1 - Mostra esta informação de ajuda +F2 - Navegar e arrancar ficheiros em disco local +F3 - Alternar o modo menu entre Vista de árvore <-> Vista de lista +F4 - Arrancar o Windows/Linux em disco local +F5 - Utilitários +F6 - Carregar menu Grub2 personalizado +F7 - Alternar entre Modo GUI <-> Modo TEXTO + +m/Ctrl+m - Checksum ficheiros de imagem (md5/sha1/sha256/sha512) +d/Ctrl+d - Modo Memdisk (Apenas para pequenos WinPE/LiveCD ISO/IMG) +w/Ctrl+w - Modo WIMBOOT (Apenas para Windows/WinPE ISO padrão) +r/Ctrl+r - Modo Grub2 (Apenas para algumas distros Linux) +i/Ctrl+i - Modo Compatível (Apenas para depuração) +u/Ctrl+u - Carregar o controlador ISO efi (Apenas para depuração, não pode ser utilizado oficialmente) + + +Prima ESC para voltar ...... diff --git a/INSTALL/grub/help/ru_RU.txt b/INSTALL/grub/help/ru_RU.txt new file mode 100644 index 0000000..03d49f1 --- /dev/null +++ b/INSTALL/grub/help/ru_RU.txt @@ -0,0 +1,19 @@ +L - Выбор языка +F1 - Показать эти справочные сведения +F2 - Просмотр и загрузка файлов на локальном диске +F3 - Переключить режим меню между «Вид древом» <-> «Вид списком» +F4 - Загрузка Windows/Linux с локального диска +F5 - Утилиты +F6 - Загрузить пользовательское меню Grub2 +F7 - Переключиться между графическим режимом <-> текстовым режимом + +m/Ctrl+m - Проверить контрольную сумму файлов образа диска (md5/sha1/sha256/sha512) +d/Ctrl+d - Режим Memdisk (только для небольших WinPE/LiveCD ISO/IMG) +w/Ctrl+w - Режим WIMBOOT (только для Windows/WinPE ISO) +r/Ctrl+r - Режим Grub2 (только для некоторых дистрибутивов Linux) +i/Ctrl+i - Совместимый режим (только для отладки) +u/Ctrl+u - Загрузить драйвер ISO EFI (только для отладки, нельзя использовать официально) + + + +Нажмите «ESC», чтобы вернуться ...... diff --git a/INSTALL/grub/help/sl_SI.txt b/INSTALL/grub/help/sl_SI.txt new file mode 100644 index 0000000..cd1b49e --- /dev/null +++ b/INSTALL/grub/help/sl_SI.txt @@ -0,0 +1,19 @@ + L - Izbira jezika +F1 - Prikaz informacij o pomoči +F2 - Brskanje in zagon datotek na lokalnem disku +F3 - Preklop med načinom menija Treeview <-> ListView +F4 - Zagon Windows/Linux na lokalnem disku +F5 - Pripomočki +F6 - Naložitev prilagojenega menija Grub2 +F7 - Preklop med načinom GUI <-> načinom TEXT + +m/Ctrl+m - Preveri kontrolno vsoto slikovnih datotek (md5/sha1/sha256/sha512) +d/Ctrl+d - Način Memdisk (samo za majhne WinPE/LiveCD ISO/IMG) +w/Ctrl+w - Način WIMBOOT (samo za datoteke Windows/WinPE ISO) +r/Ctrl+r – Način Grub2 (samo za nekatere distribucije Linux) +i/Ctrl+i – Združljiv način (samo za odpravljanje napak) +u/Ctrl+u – Naloži ISO EFI gonilnik (samo za odpravljanje napak, uradno se ne more uporabljati) + + + +Pritisnite ESC za vrnitev ...... diff --git a/INSTALL/grub/help/sr_RS.txt b/INSTALL/grub/help/sr_RS.txt new file mode 100644 index 0000000..f00ee59 --- /dev/null +++ b/INSTALL/grub/help/sr_RS.txt @@ -0,0 +1,19 @@ + L - Изаберите језик +F1 - Приказује ове информације +F2 - Покреће имиџ фајлове на локалном диску +F3 - Мења мени између TreeView <-> ListView +F4 - Покреће Windows/Linux на локалном диску +F5 - Алати +F6 - Учитава прилагођен GRUB2 мени +F7 - Мења између GUI <-> TEXT начина рада + +m/Ctrl+m - Генерира хеш одабраног имиџ фајла (md5/sha1/sha256/sha512) +d/Ctrl+d - Memdisk начин рада (само за мале WinPE/LiveCD имиџ фајлове) +w/Ctrl+w - WIMBOOT начин рада (само за стандардне Windows/WinPE имиџ фајлове) +r/Ctrl+r - GRUB2 начин рада (само за неке Linux дистрибуције) +i/Ctrl+i - Компатибилни начин рада (само за тестирање) +u/Ctrl+u - Учитава EFI драјвер за имиџ фајлове (само за тестирање) + + + +Притисните ESC за повратак ...... diff --git a/INSTALL/grub/help/ta_IN.txt b/INSTALL/grub/help/ta_IN.txt new file mode 100644 index 0000000..3404a35 --- /dev/null +++ b/INSTALL/grub/help/ta_IN.txt @@ -0,0 +1,19 @@ + L - மொழி தேர்வு +F1 - இந்த உதவித் தகவலைக் காட்டு +F2 - உள்ளூர் வட்டில் கோப்புகளை உலாவவும் துவக்கவும் +F3 - Treeview (மரப்பார்வை) <-> ListView (பட்டியல்பார்வை) இடையே மெனு பயன்முறையை மாற்றவும் +F4 - விண்டோஸ்/லினக்ஸை உள்ளூர் வட்டில் துவக்கவும் +F5 - பயன்பாடுகள் +F6 - தனிப்பயன் Grub2 மெனுவை ஏற்றவும் +F7 - GUI பயன்முறை <-> TEXT பயன்முறைக்கு இடையில் மாறவும் + +m/Ctrl+m - செக்சம் படக் கோப்புகள் (md5/sha1/sha256/sha512) +d/Ctrl+d - Memdisk பயன்முறை (சிறிய WinPE/LiveCD ISO/IMGக்கு மட்டும்) +w/Ctrl+w - WIMBOOT பயன்முறை (நிலையான Windows/WinPE ISO க்கு மட்டும்) +r/Ctrl+r - Grub2 பயன்முறை (சில லினக்ஸ் டிஸ்ட்ரோக்களுக்கு மட்டும்) +i/Ctrl+i - இணக்கமான பயன்முறை (பிழைத்திருத்தத்திற்கு மட்டும்) +u/Ctrl+u - ISO efi இயக்கியை ஏற்றவும் (பிழைத்திருத்தத்திற்கு மட்டும், அதிகாரப்பூர்வமாக பயன்படுத்த முடியாது) + + + +திரும்புவதற்கு ESC ஐ அழுத்தவும் ...... diff --git a/INSTALL/grub/help/tr_TR.txt b/INSTALL/grub/help/tr_TR.txt new file mode 100644 index 0000000..921379c --- /dev/null +++ b/INSTALL/grub/help/tr_TR.txt @@ -0,0 +1,19 @@ + L - Dil Seçimi +F1 - Yardım bilgilerini göster +F2 - Yerel diskteki önyükleme dosyalarına göz at ve önyükleme yap +F3 - Menü modunu Ağaç Görünümü <-> Liste Görünümü arasında değiştir +F4 - Windows & Linux'u yerel diskten önyükle +F5 - Ventoy araçlar menüsü +F6 - Özelleştirilmiş Grub2 menüsünü yükle +F7 - Grafik(GUI) <--> Metin(Text) modları arasında geçiş yap + +m/Ctrl+m - Görüntü dosyalarının sağlama toplamını al (md5/sha1/sha256/sha512) +d/Ctrl+d - Memdisk Modunu başlat(Yalnızca küçük WinPE/LiveCD ISO/IMG'ler için) +w/Ctrl+w - WIMBOOT Modunu başlat(Yalnızca normal Windows/WinPE ISO'ları için) +r/Ctrl+r - Grub2 Modunu başlat (Yalnızca bazı Linux dağıtımları için) +i/Ctrl+i - Uyumluluk Modu (Yalnızca hata ayıklama için) +u/Ctrl+u - ISO EFI sürücüsünü yükle (Sadece hata ayıklama için, resmi olarak kullanılamaz) + + + +Geri dönmek için ESC tuşuna basınız ...... diff --git a/INSTALL/grub/help/uk_UA.txt b/INSTALL/grub/help/uk_UA.txt new file mode 100644 index 0000000..44acc2e --- /dev/null +++ b/INSTALL/grub/help/uk_UA.txt @@ -0,0 +1,19 @@ +L - Обрати мову +F1 - Показати довідку +F2 - Переглянути та завантажити файли з локального диску +F3 - Переключитись між видами деревом <-> списком +F4 - Завантажити Windows/Linux з локального диску +F5 - Інструменти +F6 - Завантажити Custom Grub2 меню +F7 - Переключитись між графічним інтерфейсом <-> текстовим інтерфейсом + +m/Ctrl + m - Контрольна сума образу диску (md5/sha1/sha256/sha512) +d/Ctrl + d - Режим Memdisk (Тільки для невеликих образів WinPE/LiveCD ISO/IMG) +w/Ctrl + w - Режим WIMBOOT (Тільки для ISO-файлів Windows/WinPE) +r/Ctrl + r - Режим Grub2 (Тільки для деяких дистрибутивів Linux) +i/Ctrl + i - Сумісний режим (Тільки для зневадження) +u/Ctrl + u - Завантажити драйвер ISO EFI (Тільки для зневадження, не офіційно) + + + +Натисність ESC для того, щоб повернутися ...... diff --git a/INSTALL/grub/help/vi_VN.txt b/INSTALL/grub/help/vi_VN.txt new file mode 100644 index 0000000..304d5cc --- /dev/null +++ b/INSTALL/grub/help/vi_VN.txt @@ -0,0 +1,19 @@ + L - Lựa chọn ngôn ngữ +F1 - Hiển thị thông tin trợ giúp +F2 - Duyệt tìm và khởi động tệp từ ổ đĩa trên máy +F3 - Chuyển đổi chế độ bảng chọn giữa dạng cây <-> dạng danh sách. +F4 - Khởi động Windows hoặc GNU/Linux trên đĩa cục bộ +F5 - Các tiện ích +F6 - Tải menu GRUB2 tuỳ chọn +F7 - Chuyển giữa giao diện đồ hoạ <-> giao diện văn bản + +m/Ctrl+m - Checksum các tệp ảnh đĩa (md5/sha1/sha256/sha512) +d/Ctrl+d - Chế độ Memdisk (Chỉ dùng cho các tệp ISO/IMG WinPE/LiveCD có kích thước nhỏ) +w/Ctrl+w - Chế độ WIMBOOT (Chỉ dùng cho các tệp ISO Windows/WinPE) +r/Ctrl+r - Chế độ Grub2 (Chỉ dùng cho một vài bản phân phối của GNU/Linux) +i/Ctrl+i - Chế độ tương thích (Chỉ dùng cho việc sửa lỗi) +u/Ctrl+u - Tải ISO của một driver EFI (Chỉ dùng cho việc sửa lỗi, không thể dùng chính thức) + + + +Nhấn ESC để quay lại ...... diff --git a/INSTALL/grub/help/zh_CN.txt b/INSTALL/grub/help/zh_CN.txt new file mode 100644 index 0000000..932a4f2 --- /dev/null +++ b/INSTALL/grub/help/zh_CN.txt @@ -0,0 +1,18 @@ + L - 选择语言 +F1 - 显示本帮助信息 +F2 - 浏览并启动本地硬盘中的镜像文件 +F3 - 菜单显示模式切换。可在列表模式和目录模式之间自由切换。 +F4 - 启动本地硬盘上的 Windows/Linux 等系统。 +F5 - 各类工具 +F6 - 加载自定义 GRUB2 菜单。 +F7 - 界面在文本模式和图形模式之间切换。 + +m/Ctrl+m - 计算文件校验值(md5/sha1/sha256/sha512) +d/Ctrl+d - MEMDISK 模式,把文件加载到内存启动(只适用于文件很小的 WinPE/LiveCD等) +w/Ctrl+w - WIMBOOT 模式 (只适用于 Windows/WinPE 的ISO文件) +r/Ctrl+r - Grub2 模式 (只适用于常见的一些 Linux 系统ISO文件) +i/Ctrl+i - 兼容模式 (只用作调试目的,不能正式使用) +u/Ctrl+u - 加载 ISO efi 驱动(只用作调试目的,不能正式使用) + + +按 ESC 键返回 ...... diff --git a/INSTALL/grub/help/zh_TW.txt b/INSTALL/grub/help/zh_TW.txt new file mode 100644 index 0000000..bbe4dd2 --- /dev/null +++ b/INSTALL/grub/help/zh_TW.txt @@ -0,0 +1,18 @@ +L - 選擇語言 +F1 - 顯示本説明資訊 +F2 - 瀏覽並啟動本地硬碟中的映像檔 +F3 - 功能表顯示模式切換。可在清單模式和目錄模式之間自由切換。 +F4 - 啟動本地硬碟上的 Windows/Linux 等系統。 +F5 - 各類工具 +F6 - 載入自訂 GRUB2 選單。 +F7 - 介面在文字模式和圖形模式之間切換。 + +m/Ctrl+m - 計算檔案校驗值(md5/sha1/sha256/sha512) +d/Ctrl+d - MEMDISK 模式,把檔載入到記憶體啟動(只適用於檔很小的 WinPE/LiveCD等) +w/Ctrl+w - WIMBOOT 模式 (只適用於 Windows/WinPE ISO檔) +r/Ctrl+r - Grub2 模式 (只適用於常見的一些 Linux 系統ISO檔) +i/Ctrl+i - 相容模式 (只用作調試目的,不能正式使用) +u/Ctrl+u - 載入 ISO efi 驅動(只用作調試目的,不能正式使用) + + +按 ESC 鍵返回 ...... diff --git a/INSTALL/grub/hwinfo.cfg b/INSTALL/grub/hwinfo.cfg new file mode 100644 index 0000000..4bb3057 --- /dev/null +++ b/INSTALL/grub/hwinfo.cfg @@ -0,0 +1,64 @@ +menuentry "$VTLANG_HWINFO" --class=debug_hwinfo --class=F5tool { + smbios -t 4 -s 0x10 --set=cpu_brand + + set system_vendor="-"; + smbios -t 1 -s 0x04 --set=system_vendor; + set system_product="-"; + smbios -t 1 -s 0x05 --set=system_product; + set system_version="-"; + smbios -t 1 -s 0x06 --set=system_version; + + set board_vendor="-"; + smbios -t 2 -s 0x04 --set=board_vendor; + set board_product="-"; + smbios -t 2 -s 0x05 --set=board_product; + set board_version="-"; + smbios -t 2 -s 0x06 --set=board_version; + + set bios_vendor="-"; + smbios -t 0 -s 0x04 --set=bios_vendor; + set bios_version="-"; + smbios -t 0 -s 0x05 --set=bios_ver; + set bios_date="-"; + smbios -t 0 -s 0x08 --set=bios_date; + set bios_size="-"; + smbios -t 0 -b 0x09 --set=bios_size; + + + echo "Platform $grub_cpu-$grub_platform" + if [ "$grub_platform" != "pc" ]; then + echo "UEFI Version $grub_uefi_version" + echo "PI Version $grub_pi_version" + if vt_check_secureboot_var; then + echo "Secure Boot Enabled" + else + echo "Secure Boot Disabled" + fi + + vt_sbinfo + fi + + echo "" + echo "CPU Model $cpu_brand" + echo "Physical RAM $grub_total_ram MB" + + echo "" + echo "Manufacturer $system_vendor" + echo "Product Name $system_product" + echo "Version $system_version" + + echo "" + echo "Board Manufacturer $board_vendor" + echo "Board Name $board_product" + echo "Board Version $board_version" + + echo "" + echo "BIOS Manufacturer $bios_vendor" + echo "BIOS Version $bios_ver" + echo "BIOS Date $bios_date" + echo "BIOS ROM Size $bios_size" + + + echo -en "\n\n\n$VTLANG_ENTER_EXIT ..." + read vtInputKey +} diff --git a/INSTALL/grub/i386-efi/adler32.mod b/INSTALL/grub/i386-efi/adler32.mod new file mode 100644 index 0000000..c92408e Binary files /dev/null and b/INSTALL/grub/i386-efi/adler32.mod differ diff --git a/INSTALL/grub/i386-efi/affs.mod b/INSTALL/grub/i386-efi/affs.mod new file mode 100644 index 0000000..17e12fe Binary files /dev/null and b/INSTALL/grub/i386-efi/affs.mod differ diff --git a/INSTALL/grub/i386-efi/afs.mod b/INSTALL/grub/i386-efi/afs.mod new file mode 100644 index 0000000..eedba84 Binary files /dev/null and b/INSTALL/grub/i386-efi/afs.mod differ diff --git a/INSTALL/grub/i386-efi/ahci.mod b/INSTALL/grub/i386-efi/ahci.mod new file mode 100644 index 0000000..d795e65 Binary files /dev/null and b/INSTALL/grub/i386-efi/ahci.mod differ diff --git a/INSTALL/grub/i386-efi/aout.mod b/INSTALL/grub/i386-efi/aout.mod new file mode 100644 index 0000000..35c79ce Binary files /dev/null and b/INSTALL/grub/i386-efi/aout.mod differ diff --git a/INSTALL/grub/i386-efi/appleldr.mod b/INSTALL/grub/i386-efi/appleldr.mod new file mode 100644 index 0000000..8e49c94 Binary files /dev/null and b/INSTALL/grub/i386-efi/appleldr.mod differ diff --git a/INSTALL/grub/i386-efi/archelp.mod b/INSTALL/grub/i386-efi/archelp.mod new file mode 100644 index 0000000..b07a946 Binary files /dev/null and b/INSTALL/grub/i386-efi/archelp.mod differ diff --git a/INSTALL/grub/i386-efi/ata.mod b/INSTALL/grub/i386-efi/ata.mod new file mode 100644 index 0000000..b0c3b6e Binary files /dev/null and b/INSTALL/grub/i386-efi/ata.mod differ diff --git a/INSTALL/grub/i386-efi/backtrace.mod b/INSTALL/grub/i386-efi/backtrace.mod new file mode 100644 index 0000000..53fdb34 Binary files /dev/null and b/INSTALL/grub/i386-efi/backtrace.mod differ diff --git a/INSTALL/grub/i386-efi/bfs.mod b/INSTALL/grub/i386-efi/bfs.mod new file mode 100644 index 0000000..2a8f9e9 Binary files /dev/null and b/INSTALL/grub/i386-efi/bfs.mod differ diff --git a/INSTALL/grub/i386-efi/blscfg.mod b/INSTALL/grub/i386-efi/blscfg.mod new file mode 100644 index 0000000..a0a1042 Binary files /dev/null and b/INSTALL/grub/i386-efi/blscfg.mod differ diff --git a/INSTALL/grub/i386-efi/bsd.mod b/INSTALL/grub/i386-efi/bsd.mod new file mode 100644 index 0000000..05b6c58 Binary files /dev/null and b/INSTALL/grub/i386-efi/bsd.mod differ diff --git a/INSTALL/grub/i386-efi/bswap_test.mod b/INSTALL/grub/i386-efi/bswap_test.mod new file mode 100644 index 0000000..12e67f0 Binary files /dev/null and b/INSTALL/grub/i386-efi/bswap_test.mod differ diff --git a/INSTALL/grub/i386-efi/btrfs.mod b/INSTALL/grub/i386-efi/btrfs.mod new file mode 100644 index 0000000..1ad0b87 Binary files /dev/null and b/INSTALL/grub/i386-efi/btrfs.mod differ diff --git a/INSTALL/grub/i386-efi/cbfs.mod b/INSTALL/grub/i386-efi/cbfs.mod new file mode 100644 index 0000000..25868f6 Binary files /dev/null and b/INSTALL/grub/i386-efi/cbfs.mod differ diff --git a/INSTALL/grub/i386-efi/cbls.mod b/INSTALL/grub/i386-efi/cbls.mod new file mode 100644 index 0000000..30c278c Binary files /dev/null and b/INSTALL/grub/i386-efi/cbls.mod differ diff --git a/INSTALL/grub/i386-efi/cbmemc.mod b/INSTALL/grub/i386-efi/cbmemc.mod new file mode 100644 index 0000000..2df81ee Binary files /dev/null and b/INSTALL/grub/i386-efi/cbmemc.mod differ diff --git a/INSTALL/grub/i386-efi/cbtable.mod b/INSTALL/grub/i386-efi/cbtable.mod new file mode 100644 index 0000000..c982202 Binary files /dev/null and b/INSTALL/grub/i386-efi/cbtable.mod differ diff --git a/INSTALL/grub/i386-efi/cbtime.mod b/INSTALL/grub/i386-efi/cbtime.mod new file mode 100644 index 0000000..a171c17 Binary files /dev/null and b/INSTALL/grub/i386-efi/cbtime.mod differ diff --git a/INSTALL/grub/i386-efi/cmdline_cat_test.mod b/INSTALL/grub/i386-efi/cmdline_cat_test.mod new file mode 100644 index 0000000..271620b Binary files /dev/null and b/INSTALL/grub/i386-efi/cmdline_cat_test.mod differ diff --git a/INSTALL/grub/i386-efi/cmp.mod b/INSTALL/grub/i386-efi/cmp.mod new file mode 100644 index 0000000..7373cd6 Binary files /dev/null and b/INSTALL/grub/i386-efi/cmp.mod differ diff --git a/INSTALL/grub/i386-efi/cmp_test.mod b/INSTALL/grub/i386-efi/cmp_test.mod new file mode 100644 index 0000000..012426f Binary files /dev/null and b/INSTALL/grub/i386-efi/cmp_test.mod differ diff --git a/INSTALL/grub/i386-efi/command.lst b/INSTALL/grub/i386-efi/command.lst new file mode 100644 index 0000000..896bb3d --- /dev/null +++ b/INSTALL/grub/i386-efi/command.lst @@ -0,0 +1,206 @@ +*acpi: acpi +*all_functional_test: functional_test +*background_image: gfxterm_background +*bls_import: blscfg +*blscfg: blscfg +*cat: cat +*cpuid: cpuid +*crc: hashsum +*cryptomount: cryptodisk +*echo: echo +*extract_syslinux_entries_configfile: syslinuxcfg +*extract_syslinux_entries_source: syslinuxcfg +*file: file +*functional_test: functional_test +*fwconnect: fwload +*fwload: fwload +*gettext: gettext +*hashsum: hashsum +*hdparm: hdparm +*hello: hello +*help: help +*hexdump: hexdump +*inb: iorw +*inl: iorw +*inw: iorw +*keystatus: keystatus +*kfreebsd: bsd +*knetbsd: bsd +*kopenbsd: bsd +*list_env: loadenv +*load_env: loadenv +*loopback: loopback +*ls: ls +*lsacpi: lsacpi +*lspci: lspci +*md5sum: hashsum +*menuentry: normal +*pcidump: pcidump +*probe: probe +*rdmsr: rdmsr +*read_byte: memrw +*read_dword: memrw +*read_word: memrw +*regexp: regexp +*save_env: loadenv +*search: search +*serial: serial +*set_keyboard_layout: setkey +*setkey: setkey +*setpci: setpci +*sha1sum: hashsum +*sha256sum: hashsum +*sha512sum: hashsum +*sleep: sleep +*smbios: smbios +*submenu: normal +*syslinux_configfile: syslinuxcfg +*syslinux_source: syslinuxcfg +*terminfo: terminfo +*test_blockarg: test_blockarg +*testspeed: testspeed +*tr: tr +*trust: pgp +*verify_detached: pgp +*xnu_splash: xnu +*zfskey: zfscrypt +.: configfile +[: test +appleloader: appleldr +authenticate: normal +background_color: gfxterm_background +backtrace: backtrace +badram: mmap +blocklist: blocklist +boot: boot +break: normal +cat: minicmd +cbmemc: cbmemc +chainloader: chain +clear: normal +cmp: cmp +configfile: configfile +continue: normal +coreboot_boottime: cbtime +cutmem: mmap +date: date +distrust: pgp +dump: minicmd +eval: eval +exit: minicmd +export: normal +extract_entries_configfile: configfile +extract_entries_source: configfile +extract_legacy_entries_configfile: legacycfg +extract_legacy_entries_source: legacycfg +fakebios: loadbios +false: true +fix_video: fixvideo +fwsetup: efifwsetup +gdbstub: gdb +gdbstub_break: gdb +gdbstub_stop: gdb +gptsync: gptsync +halt: halt +help: minicmd +hexdump_random: random +initrd16: linux16 +initrd: linux +initrdefi: linux +keymap: keylayouts +kfreebsd_loadenv: bsd +kfreebsd_module: bsd +kfreebsd_module_elf: bsd +knetbsd_module: bsd +knetbsd_module_elf: bsd +kopenbsd_ramdisk: bsd +legacy_check_password: legacycfg +legacy_configfile: legacycfg +legacy_initrd: legacycfg +legacy_initrd_nounzip: legacycfg +legacy_kernel: legacycfg +legacy_password: legacycfg +legacy_source: legacycfg +linux16: linux16 +linux: linux +linuxefi: linux +list_trusted: pgp +loadbios: loadbios +loadfont: font +lscoreboot: cbls +lsefi: lsefi +lsefimmap: lsefimmap +lsefisystab: lsefisystab +lsfonts: font +lsmmap: lsmmap +lsmod: minicmd +lssal: lssal +macppcbless: macbless +mactelbless: macbless +module2: multiboot2 +module: multiboot +multiboot2: multiboot2 +multiboot: multiboot +nativedisk: nativedisk +net_add_addr: net +net_add_dns: net +net_add_route: net +net_bootp: net +net_del_addr: net +net_del_dns: net +net_del_route: net +net_dhcp: net +net_get_dhcp_option: net +net_ipv6_autoconf: net +net_ls_addr: net +net_ls_cards: net +net_ls_dns: net +net_ls_routes: net +net_nslookup: net +normal: normal +normal_exit: normal +outb: iorw +outl: iorw +outw: iorw +parttool: parttool +password: password +password_pbkdf2: password_pbkdf2 +play: play +read: read +reboot: reboot +return: normal +rmmod: minicmd +search.file: search_fs_file +search.fs_label: search_label +search.fs_uuid: search_fs_uuid +setparams: normal +shift: normal +source: configfile +terminal_input: terminal +terminal_output: terminal +test: test +testload: testload +time: time +true: true +usb: usbtest +videoinfo: videoinfo +videotest: videotest +vt_img_extra_initrd_append: linux +vt_img_extra_initrd_reset: linux +vt_set_boot_opt: linux +vt_unset_boot_opt: linux +write_byte: memrw +write_dword: memrw +write_word: memrw +wrmsr: wrmsr +xnu_devprop_load: xnu +xnu_kernel64: xnu +xnu_kernel: xnu +xnu_kext: xnu +xnu_kextdir: xnu +xnu_mkext: xnu +xnu_ramdisk: xnu +xnu_resume: xnu +xnu_uuid: xnu_uuid +zfs-bootfs: zfsinfo +zfsinfo: zfsinfo diff --git a/INSTALL/grub/i386-efi/cpio.mod b/INSTALL/grub/i386-efi/cpio.mod new file mode 100644 index 0000000..b06a589 Binary files /dev/null and b/INSTALL/grub/i386-efi/cpio.mod differ diff --git a/INSTALL/grub/i386-efi/cpio_be.mod b/INSTALL/grub/i386-efi/cpio_be.mod new file mode 100644 index 0000000..e974c65 Binary files /dev/null and b/INSTALL/grub/i386-efi/cpio_be.mod differ diff --git a/INSTALL/grub/i386-efi/cpuid.mod b/INSTALL/grub/i386-efi/cpuid.mod new file mode 100644 index 0000000..2e1f783 Binary files /dev/null and b/INSTALL/grub/i386-efi/cpuid.mod differ diff --git a/INSTALL/grub/i386-efi/crc64.mod b/INSTALL/grub/i386-efi/crc64.mod new file mode 100644 index 0000000..7e111a6 Binary files /dev/null and b/INSTALL/grub/i386-efi/crc64.mod differ diff --git a/INSTALL/grub/i386-efi/crypto.lst b/INSTALL/grub/i386-efi/crypto.lst new file mode 100644 index 0000000..77d9efc --- /dev/null +++ b/INSTALL/grub/i386-efi/crypto.lst @@ -0,0 +1,45 @@ +RIJNDAEL: gcry_rijndael +RIJNDAEL192: gcry_rijndael +RIJNDAEL256: gcry_rijndael +AES128: gcry_rijndael +AES-128: gcry_rijndael +AES-192: gcry_rijndael +AES-256: gcry_rijndael +ADLER32: adler32 +CRC64: crc64 +ARCFOUR: gcry_arcfour +BLOWFISH: gcry_blowfish +CAMELLIA128: gcry_camellia +CAMELLIA192: gcry_camellia +CAMELLIA256: gcry_camellia +CAST5: gcry_cast5 +CRC32: gcry_crc +CRC32RFC1510: gcry_crc +CRC24RFC2440: gcry_crc +DES: gcry_des +3DES: gcry_des +DSA: gcry_dsa +IDEA: gcry_idea +MD4: gcry_md4 +MD5: gcry_md5 +RFC2268_40: gcry_rfc2268 +AES: gcry_rijndael +AES192: gcry_rijndael +AES256: gcry_rijndael +RIPEMD160: gcry_rmd160 +RSA: gcry_rsa +SEED: gcry_seed +SERPENT128: gcry_serpent +SERPENT192: gcry_serpent +SERPENT256: gcry_serpent +SHA1: gcry_sha1 +SHA224: gcry_sha256 +SHA256: gcry_sha256 +SHA512: gcry_sha512 +SHA384: gcry_sha512 +TIGER192: gcry_tiger +TIGER: gcry_tiger +TIGER2: gcry_tiger +TWOFISH: gcry_twofish +TWOFISH128: gcry_twofish +WHIRLPOOL: gcry_whirlpool diff --git a/INSTALL/grub/i386-efi/cryptodisk.mod b/INSTALL/grub/i386-efi/cryptodisk.mod new file mode 100644 index 0000000..18bb82f Binary files /dev/null and b/INSTALL/grub/i386-efi/cryptodisk.mod differ diff --git a/INSTALL/grub/i386-efi/cs5536.mod b/INSTALL/grub/i386-efi/cs5536.mod new file mode 100644 index 0000000..2f2f797 Binary files /dev/null and b/INSTALL/grub/i386-efi/cs5536.mod differ diff --git a/INSTALL/grub/i386-efi/ctz_test.mod b/INSTALL/grub/i386-efi/ctz_test.mod new file mode 100644 index 0000000..7583ee6 Binary files /dev/null and b/INSTALL/grub/i386-efi/ctz_test.mod differ diff --git a/INSTALL/grub/i386-efi/date.mod b/INSTALL/grub/i386-efi/date.mod new file mode 100644 index 0000000..c011608 Binary files /dev/null and b/INSTALL/grub/i386-efi/date.mod differ diff --git a/INSTALL/grub/i386-efi/datehook.mod b/INSTALL/grub/i386-efi/datehook.mod new file mode 100644 index 0000000..9a2d6cb Binary files /dev/null and b/INSTALL/grub/i386-efi/datehook.mod differ diff --git a/INSTALL/grub/i386-efi/disk.mod b/INSTALL/grub/i386-efi/disk.mod new file mode 100644 index 0000000..36498c1 Binary files /dev/null and b/INSTALL/grub/i386-efi/disk.mod differ diff --git a/INSTALL/grub/i386-efi/div.mod b/INSTALL/grub/i386-efi/div.mod new file mode 100644 index 0000000..1102fa2 Binary files /dev/null and b/INSTALL/grub/i386-efi/div.mod differ diff --git a/INSTALL/grub/i386-efi/div_test.mod b/INSTALL/grub/i386-efi/div_test.mod new file mode 100644 index 0000000..7a6a7c0 Binary files /dev/null and b/INSTALL/grub/i386-efi/div_test.mod differ diff --git a/INSTALL/grub/i386-efi/dm_nv.mod b/INSTALL/grub/i386-efi/dm_nv.mod new file mode 100644 index 0000000..e8414d7 Binary files /dev/null and b/INSTALL/grub/i386-efi/dm_nv.mod differ diff --git a/INSTALL/grub/i386-efi/efinet.mod b/INSTALL/grub/i386-efi/efinet.mod new file mode 100644 index 0000000..c811c95 Binary files /dev/null and b/INSTALL/grub/i386-efi/efinet.mod differ diff --git a/INSTALL/grub/i386-efi/ehci.mod b/INSTALL/grub/i386-efi/ehci.mod new file mode 100644 index 0000000..51b92be Binary files /dev/null and b/INSTALL/grub/i386-efi/ehci.mod differ diff --git a/INSTALL/grub/i386-efi/elf.mod b/INSTALL/grub/i386-efi/elf.mod new file mode 100644 index 0000000..5f9edb6 Binary files /dev/null and b/INSTALL/grub/i386-efi/elf.mod differ diff --git a/INSTALL/grub/i386-efi/eval.mod b/INSTALL/grub/i386-efi/eval.mod new file mode 100644 index 0000000..e37e6e8 Binary files /dev/null and b/INSTALL/grub/i386-efi/eval.mod differ diff --git a/INSTALL/grub/i386-efi/exfctest.mod b/INSTALL/grub/i386-efi/exfctest.mod new file mode 100644 index 0000000..65b54a9 Binary files /dev/null and b/INSTALL/grub/i386-efi/exfctest.mod differ diff --git a/INSTALL/grub/i386-efi/f2fs.mod b/INSTALL/grub/i386-efi/f2fs.mod new file mode 100644 index 0000000..3a391f2 Binary files /dev/null and b/INSTALL/grub/i386-efi/f2fs.mod differ diff --git a/INSTALL/grub/i386-efi/fdt.lst b/INSTALL/grub/i386-efi/fdt.lst new file mode 100644 index 0000000..e69de29 diff --git a/INSTALL/grub/i386-efi/fixvideo.mod b/INSTALL/grub/i386-efi/fixvideo.mod new file mode 100644 index 0000000..a959467 Binary files /dev/null and b/INSTALL/grub/i386-efi/fixvideo.mod differ diff --git a/INSTALL/grub/i386-efi/fs.lst b/INSTALL/grub/i386-efi/fs.lst new file mode 100644 index 0000000..0acd240 --- /dev/null +++ b/INSTALL/grub/i386-efi/fs.lst @@ -0,0 +1,37 @@ +affs +afs +bfs +btrfs +cbfs +cpio +cpio_be +exfat +ext2 +f2fs +fat +hfs +hfsplus +iso9660 +jfs +minix +minix2 +minix2_be +minix3 +minix3_be +minix_be +newc +nilfs2 +ntfs +odc +procfs +reiserfs +romfs +sfs +squash4 +tar +udf +ufs1 +ufs1_be +ufs2 +xfs +zfs diff --git a/INSTALL/grub/i386-efi/functional_test.mod b/INSTALL/grub/i386-efi/functional_test.mod new file mode 100644 index 0000000..d45a47c Binary files /dev/null and b/INSTALL/grub/i386-efi/functional_test.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_arcfour.mod b/INSTALL/grub/i386-efi/gcry_arcfour.mod new file mode 100644 index 0000000..b6c5675 Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_arcfour.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_blowfish.mod b/INSTALL/grub/i386-efi/gcry_blowfish.mod new file mode 100644 index 0000000..5e50e93 Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_blowfish.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_camellia.mod b/INSTALL/grub/i386-efi/gcry_camellia.mod new file mode 100644 index 0000000..33f7f28 Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_camellia.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_cast5.mod b/INSTALL/grub/i386-efi/gcry_cast5.mod new file mode 100644 index 0000000..abca73b Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_cast5.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_crc.mod b/INSTALL/grub/i386-efi/gcry_crc.mod new file mode 100644 index 0000000..e5fad44 Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_crc.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_des.mod b/INSTALL/grub/i386-efi/gcry_des.mod new file mode 100644 index 0000000..cba82a4 Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_des.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_dsa.mod b/INSTALL/grub/i386-efi/gcry_dsa.mod new file mode 100644 index 0000000..c8f995e Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_dsa.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_idea.mod b/INSTALL/grub/i386-efi/gcry_idea.mod new file mode 100644 index 0000000..08a0f98 Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_idea.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_md4.mod b/INSTALL/grub/i386-efi/gcry_md4.mod new file mode 100644 index 0000000..438ebe5 Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_md4.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_rfc2268.mod b/INSTALL/grub/i386-efi/gcry_rfc2268.mod new file mode 100644 index 0000000..c2168f1 Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_rfc2268.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_rijndael.mod b/INSTALL/grub/i386-efi/gcry_rijndael.mod new file mode 100644 index 0000000..ff3366c Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_rijndael.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_rmd160.mod b/INSTALL/grub/i386-efi/gcry_rmd160.mod new file mode 100644 index 0000000..c0ca918 Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_rmd160.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_rsa.mod b/INSTALL/grub/i386-efi/gcry_rsa.mod new file mode 100644 index 0000000..7d013c9 Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_rsa.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_seed.mod b/INSTALL/grub/i386-efi/gcry_seed.mod new file mode 100644 index 0000000..338e31e Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_seed.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_serpent.mod b/INSTALL/grub/i386-efi/gcry_serpent.mod new file mode 100644 index 0000000..4bee73e Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_serpent.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_sha1.mod b/INSTALL/grub/i386-efi/gcry_sha1.mod new file mode 100644 index 0000000..c66caea Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_sha1.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_sha256.mod b/INSTALL/grub/i386-efi/gcry_sha256.mod new file mode 100644 index 0000000..cce31ff Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_sha256.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_tiger.mod b/INSTALL/grub/i386-efi/gcry_tiger.mod new file mode 100644 index 0000000..2b841ec Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_tiger.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_twofish.mod b/INSTALL/grub/i386-efi/gcry_twofish.mod new file mode 100644 index 0000000..32db1b0 Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_twofish.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_whirlpool.mod b/INSTALL/grub/i386-efi/gcry_whirlpool.mod new file mode 100644 index 0000000..11f3a74 Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_whirlpool.mod differ diff --git a/INSTALL/grub/i386-efi/gdb.mod b/INSTALL/grub/i386-efi/gdb.mod new file mode 100644 index 0000000..b2fcd3d Binary files /dev/null and b/INSTALL/grub/i386-efi/gdb.mod differ diff --git a/INSTALL/grub/i386-efi/geli.mod b/INSTALL/grub/i386-efi/geli.mod new file mode 100644 index 0000000..4ac7949 Binary files /dev/null and b/INSTALL/grub/i386-efi/geli.mod differ diff --git a/INSTALL/grub/i386-efi/gptsync.mod b/INSTALL/grub/i386-efi/gptsync.mod new file mode 100644 index 0000000..6b47734 Binary files /dev/null and b/INSTALL/grub/i386-efi/gptsync.mod differ diff --git a/INSTALL/grub/i386-efi/hdparm.mod b/INSTALL/grub/i386-efi/hdparm.mod new file mode 100644 index 0000000..7c794b5 Binary files /dev/null and b/INSTALL/grub/i386-efi/hdparm.mod differ diff --git a/INSTALL/grub/i386-efi/hello.mod b/INSTALL/grub/i386-efi/hello.mod new file mode 100644 index 0000000..81a5c36 Binary files /dev/null and b/INSTALL/grub/i386-efi/hello.mod differ diff --git a/INSTALL/grub/i386-efi/help.mod b/INSTALL/grub/i386-efi/help.mod new file mode 100644 index 0000000..5abbb8a Binary files /dev/null and b/INSTALL/grub/i386-efi/help.mod differ diff --git a/INSTALL/grub/i386-efi/hexdump.mod b/INSTALL/grub/i386-efi/hexdump.mod new file mode 100644 index 0000000..f99f586 Binary files /dev/null and b/INSTALL/grub/i386-efi/hexdump.mod differ diff --git a/INSTALL/grub/i386-efi/hfs.mod b/INSTALL/grub/i386-efi/hfs.mod new file mode 100644 index 0000000..abd125c Binary files /dev/null and b/INSTALL/grub/i386-efi/hfs.mod differ diff --git a/INSTALL/grub/i386-efi/hfspluscomp.mod b/INSTALL/grub/i386-efi/hfspluscomp.mod new file mode 100644 index 0000000..2fab99c Binary files /dev/null and b/INSTALL/grub/i386-efi/hfspluscomp.mod differ diff --git a/INSTALL/grub/i386-efi/iorw.mod b/INSTALL/grub/i386-efi/iorw.mod new file mode 100644 index 0000000..89f3ebd Binary files /dev/null and b/INSTALL/grub/i386-efi/iorw.mod differ diff --git a/INSTALL/grub/i386-efi/jfs.mod b/INSTALL/grub/i386-efi/jfs.mod new file mode 100644 index 0000000..0feab32 Binary files /dev/null and b/INSTALL/grub/i386-efi/jfs.mod differ diff --git a/INSTALL/grub/i386-efi/keylayouts.mod b/INSTALL/grub/i386-efi/keylayouts.mod new file mode 100644 index 0000000..3af5cc9 Binary files /dev/null and b/INSTALL/grub/i386-efi/keylayouts.mod differ diff --git a/INSTALL/grub/i386-efi/keystatus.mod b/INSTALL/grub/i386-efi/keystatus.mod new file mode 100644 index 0000000..12a1fc7 Binary files /dev/null and b/INSTALL/grub/i386-efi/keystatus.mod differ diff --git a/INSTALL/grub/i386-efi/ldm.mod b/INSTALL/grub/i386-efi/ldm.mod new file mode 100644 index 0000000..6ca7384 Binary files /dev/null and b/INSTALL/grub/i386-efi/ldm.mod differ diff --git a/INSTALL/grub/i386-efi/legacy_password_test.mod b/INSTALL/grub/i386-efi/legacy_password_test.mod new file mode 100644 index 0000000..08e34bb Binary files /dev/null and b/INSTALL/grub/i386-efi/legacy_password_test.mod differ diff --git a/INSTALL/grub/i386-efi/legacycfg.mod b/INSTALL/grub/i386-efi/legacycfg.mod new file mode 100644 index 0000000..4e040af Binary files /dev/null and b/INSTALL/grub/i386-efi/legacycfg.mod differ diff --git a/INSTALL/grub/i386-efi/linux16.mod b/INSTALL/grub/i386-efi/linux16.mod new file mode 100644 index 0000000..9a0a1b4 Binary files /dev/null and b/INSTALL/grub/i386-efi/linux16.mod differ diff --git a/INSTALL/grub/i386-efi/loadbios.mod b/INSTALL/grub/i386-efi/loadbios.mod new file mode 100644 index 0000000..91f19b4 Binary files /dev/null and b/INSTALL/grub/i386-efi/loadbios.mod differ diff --git a/INSTALL/grub/i386-efi/loadenv.mod b/INSTALL/grub/i386-efi/loadenv.mod new file mode 100644 index 0000000..c7619f5 Binary files /dev/null and b/INSTALL/grub/i386-efi/loadenv.mod differ diff --git a/INSTALL/grub/i386-efi/lsacpi.mod b/INSTALL/grub/i386-efi/lsacpi.mod new file mode 100644 index 0000000..a6bc64c Binary files /dev/null and b/INSTALL/grub/i386-efi/lsacpi.mod differ diff --git a/INSTALL/grub/i386-efi/lsefi.mod b/INSTALL/grub/i386-efi/lsefi.mod new file mode 100644 index 0000000..01c06a6 Binary files /dev/null and b/INSTALL/grub/i386-efi/lsefi.mod differ diff --git a/INSTALL/grub/i386-efi/lsefimmap.mod b/INSTALL/grub/i386-efi/lsefimmap.mod new file mode 100644 index 0000000..b580763 Binary files /dev/null and b/INSTALL/grub/i386-efi/lsefimmap.mod differ diff --git a/INSTALL/grub/i386-efi/lsefisystab.mod b/INSTALL/grub/i386-efi/lsefisystab.mod new file mode 100644 index 0000000..e87988f Binary files /dev/null and b/INSTALL/grub/i386-efi/lsefisystab.mod differ diff --git a/INSTALL/grub/i386-efi/lsmmap.mod b/INSTALL/grub/i386-efi/lsmmap.mod new file mode 100644 index 0000000..77a0184 Binary files /dev/null and b/INSTALL/grub/i386-efi/lsmmap.mod differ diff --git a/INSTALL/grub/i386-efi/lspci.mod b/INSTALL/grub/i386-efi/lspci.mod new file mode 100644 index 0000000..c1aad4d Binary files /dev/null and b/INSTALL/grub/i386-efi/lspci.mod differ diff --git a/INSTALL/grub/i386-efi/lssal.mod b/INSTALL/grub/i386-efi/lssal.mod new file mode 100644 index 0000000..b64092a Binary files /dev/null and b/INSTALL/grub/i386-efi/lssal.mod differ diff --git a/INSTALL/grub/i386-efi/luks.mod b/INSTALL/grub/i386-efi/luks.mod new file mode 100644 index 0000000..9fc8f33 Binary files /dev/null and b/INSTALL/grub/i386-efi/luks.mod differ diff --git a/INSTALL/grub/i386-efi/lvm.mod b/INSTALL/grub/i386-efi/lvm.mod new file mode 100644 index 0000000..4d57017 Binary files /dev/null and b/INSTALL/grub/i386-efi/lvm.mod differ diff --git a/INSTALL/grub/i386-efi/macbless.mod b/INSTALL/grub/i386-efi/macbless.mod new file mode 100644 index 0000000..f14033f Binary files /dev/null and b/INSTALL/grub/i386-efi/macbless.mod differ diff --git a/INSTALL/grub/i386-efi/macho.mod b/INSTALL/grub/i386-efi/macho.mod new file mode 100644 index 0000000..beec10e Binary files /dev/null and b/INSTALL/grub/i386-efi/macho.mod differ diff --git a/INSTALL/grub/i386-efi/mdraid09.mod b/INSTALL/grub/i386-efi/mdraid09.mod new file mode 100644 index 0000000..f78c90e Binary files /dev/null and b/INSTALL/grub/i386-efi/mdraid09.mod differ diff --git a/INSTALL/grub/i386-efi/mdraid09_be.mod b/INSTALL/grub/i386-efi/mdraid09_be.mod new file mode 100644 index 0000000..d31d541 Binary files /dev/null and b/INSTALL/grub/i386-efi/mdraid09_be.mod differ diff --git a/INSTALL/grub/i386-efi/mdraid1x.mod b/INSTALL/grub/i386-efi/mdraid1x.mod new file mode 100644 index 0000000..94ff0b5 Binary files /dev/null and b/INSTALL/grub/i386-efi/mdraid1x.mod differ diff --git a/INSTALL/grub/i386-efi/memdisk.mod b/INSTALL/grub/i386-efi/memdisk.mod new file mode 100644 index 0000000..33ccaf2 Binary files /dev/null and b/INSTALL/grub/i386-efi/memdisk.mod differ diff --git a/INSTALL/grub/i386-efi/memrw.mod b/INSTALL/grub/i386-efi/memrw.mod new file mode 100644 index 0000000..fde7773 Binary files /dev/null and b/INSTALL/grub/i386-efi/memrw.mod differ diff --git a/INSTALL/grub/i386-efi/minix.mod b/INSTALL/grub/i386-efi/minix.mod new file mode 100644 index 0000000..a3d1c02 Binary files /dev/null and b/INSTALL/grub/i386-efi/minix.mod differ diff --git a/INSTALL/grub/i386-efi/minix2.mod b/INSTALL/grub/i386-efi/minix2.mod new file mode 100644 index 0000000..0c73e4e Binary files /dev/null and b/INSTALL/grub/i386-efi/minix2.mod differ diff --git a/INSTALL/grub/i386-efi/minix2_be.mod b/INSTALL/grub/i386-efi/minix2_be.mod new file mode 100644 index 0000000..4b6ce2f Binary files /dev/null and b/INSTALL/grub/i386-efi/minix2_be.mod differ diff --git a/INSTALL/grub/i386-efi/minix3.mod b/INSTALL/grub/i386-efi/minix3.mod new file mode 100644 index 0000000..1f4f704 Binary files /dev/null and b/INSTALL/grub/i386-efi/minix3.mod differ diff --git a/INSTALL/grub/i386-efi/minix3_be.mod b/INSTALL/grub/i386-efi/minix3_be.mod new file mode 100644 index 0000000..194da0f Binary files /dev/null and b/INSTALL/grub/i386-efi/minix3_be.mod differ diff --git a/INSTALL/grub/i386-efi/minix_be.mod b/INSTALL/grub/i386-efi/minix_be.mod new file mode 100644 index 0000000..04ee8f1 Binary files /dev/null and b/INSTALL/grub/i386-efi/minix_be.mod differ diff --git a/INSTALL/grub/i386-efi/moddep.lst b/INSTALL/grub/i386-efi/moddep.lst new file mode 100644 index 0000000..b025ad7 --- /dev/null +++ b/INSTALL/grub/i386-efi/moddep.lst @@ -0,0 +1,269 @@ +videotest: font video gfxmenu +odc: archelp +loopback: extcmd +setkey: extcmd +macho: +gcry_des: crypto +memrw: extcmd +terminfo: extcmd +f2fs: fshelp +part_gpt: +romfs: fshelp +read: +lsefimmap: +aout: +gcry_arcfour: crypto +tftp: net priority_queue +newc: archelp +minix2_be: +elf: +videotest_checksum: font functional_test video_fb +password_pbkdf2: crypto gcry_sha512 pbkdf2 normal +gcry_seed: crypto +pcidump: extcmd +bsd: elf serial crypto gcry_md5 verifiers extcmd aout video boot cpuid relocator mmap +sfs: fshelp +reiserfs: fshelp +part_sunpc: +zstd: +gfxmenu: video_colors trig bitmap_scale gfxterm font normal video bitmap +backtrace: +jfs: +help: extcmd normal +configfile: normal +cbls: cbtable +gfxterm_menu: font functional_test procfs normal video_fb +gcry_idea: crypto +tr: extcmd +shift_test: functional_test +ohci: cs5536 usb boot +afs: fshelp +spkmodem: terminfo +usb_keyboard: keylayouts usb +xzio: crypto +syslinuxcfg: extcmd normal +search_fs_file: +wrmsr: +usbms: scsi usb +test_blockarg: extcmd normal +true: +affs: fshelp +iso9660: fshelp +smbios: extcmd +exfat: fshelp +setjmp_test: setjmp functional_test +gfxterm: font video +efinet: net +disk: +appleldr: boot +xfs: fshelp +testspeed: extcmd normal +cpio_be: archelp +functional_test: btrfs extcmd video video_fb +bswap_test: functional_test +sleep: extcmd normal +memdisk: +gcry_rijndael: crypto +mdraid09_be: diskfilter +gettext: +gcry_sha1: crypto +hfspluscomp: gzio hfsplus +cmp: +random: hexdump +offsetio: +file: elf macho extcmd offsetio +usbserial_usbdebug: serial usb usbserial_common +video_colors: +morse: +hashsum: crypto extcmd normal +usb: +halt: acpi +gdb: serial backtrace +gfxterm_background: video_colors bitmap_scale gfxterm extcmd video bitmap +search_fs_uuid: +gcry_dsa: pgp mpi +keystatus: extcmd +linux: ventoy verifiers video boot relocator mmap +geli: cryptodisk crypto gcry_sha512 pbkdf2 gcry_sha256 +cmdline_cat_test: font functional_test normal procfs video_fb +rdmsr: extcmd +part_sun: +cbtable: +pbkdf2_test: functional_test pbkdf2 gcry_sha1 +video_bochs: video video_fb +verifiers: +bufio: +usbserial_ftdi: serial usb usbserial_common +legacy_password_test: functional_test legacycfg +cpuid: extcmd +blscfg: extcmd normal +hdparm: extcmd hexdump +bfs: fshelp +gcry_blowfish: crypto +test: +nilfs2: fshelp +gcry_rsa: pgp mpi +cryptodisk: crypto extcmd procfs +nativedisk: +minicmd: +signature_test: functional_test procfs +ata: scsi +udf: fshelp +gzio: gcry_crc +xnu_uuid: gcry_md5 +uhci: usb +pata: ata +mul_test: functional_test +adler32: crypto +terminal: +div: +ehci: cs5536 usb boot +crypto: +part_bsd: part_msdos +cs5536: +ventoy: ext2 fshelp elf btrfs crypto font gcry_md5 exfat udf datetime div extcmd normal video gcry_sha1 mmap iso9660 +gcry_sha512: crypto +password: crypto normal +fshelp: +sleep_test: functional_test datetime +iorw: extcmd +xnu: macho bitmap_scale random verifiers extcmd boot video bitmap relocator mmap +mmap: +exfctest: functional_test +zfsinfo: zfs +ldm: part_gpt diskfilter part_msdos +eval: normal +part_dvh: +lssal: +blocklist: +ext2: fshelp +net: priority_queue bufio datetime boot +part_acorn: +videoinfo: video +btrfs: zstd lzopio raid6rec gzio +lsmmap: mmap +strtoull_test: functional_test +bitmap: +ntfs: fshelp +multiboot: net linux video boot relocator mmap +gcry_crc: crypto +png: bufio bitmap +jpeg: bufio bitmap +macbless: disk +div_test: functional_test div +regexp: extcmd normal +parttool: normal +usbserial_pl2303: serial usb usbserial_common +cpio: archelp +gcry_rmd160: crypto +fat: fshelp +ufs1_be: +archelp: +http: net +zfs: gzio +raid6rec: diskfilter +lsefisystab: +minix2: +lsacpi: extcmd acpi +datehook: datetime normal +loadenv: disk extcmd +bitmap_scale: bitmap +probe: extcmd +minix3: +tar: archelp +loadbios: +hfs: fshelp +procfs: archelp +boot: +keylayouts: +progress: normal +kernel: +usbtest: usb +relocator: mmap +acpi: extcmd mmap +tga: bufio bitmap +fwload: extcmd +reboot: +serial: extcmd terminfo +zfscrypt: crypto pbkdf2 extcmd zfs gcry_sha1 gcry_rijndael +efi_uga: video video_fb +dm_nv: diskfilter +cmp_test: functional_test +luks: cryptodisk crypto pbkdf2 +font: bufio video +raid5rec: diskfilter +crc64: crypto +datetime: +efifwsetup: +ctz_test: functional_test +video: +cbmemc: cbtable normal terminfo +hfsplus: fshelp +gcry_cast5: crypto +extcmd: +squash4: fshelp zstd lzopio zfs xzio gzio +part_plan: +minix_be: +gcry_whirlpool: crypto +gcry_tiger: crypto +fixvideo: +search: search_fs_uuid search_fs_file extcmd search_label +lspci: extcmd +cbtime: cbtable +video_fb: +minix3_be: +trig: +msdospart: disk parttool +priority_queue: +gcry_twofish: crypto +part_dfly: +xnu_uuid_test: functional_test +diskfilter: +testload: +part_apple: +hexdump: extcmd +date: datetime normal +pbkdf2: crypto +gcry_sha256: crypto +ls: extcmd normal +usbserial_common: serial usb +ntfscomp: ntfs +mouse: +lzopio: crypto +video_cirrus: video video_fb +hello: extcmd +scsi: +linux16: linux boot video relocator mmap +cat: extcmd +ahci: ata boot +pgp: crypto verifiers extcmd mpi gcry_sha1 +normal: terminal crypto verifiers bufio extcmd boot gettext +ufs1: +mdraid09: diskfilter +lvm: diskfilter +chain: net efinet boot +cbfs: archelp +ufs2: +time: +setpci: extcmd +gptsync: disk +search_label: +setjmp: +multiboot2: linux net video boot relocator mmap acpi +gcry_rfc2268: crypto +mdraid1x: diskfilter +mpi: crypto +legacycfg: crypto password gcry_md5 normal +play: +part_amiga: +efi_gop: video video_fb +minix: +echo: extcmd +lsefi: +gcry_serpent: crypto +gcry_md4: crypto +gcry_md5: crypto +part_msdos: +gcry_camellia: crypto +at_keyboard: keylayouts boot +all_video: efi_gop efi_uga video_bochs video_cirrus diff --git a/INSTALL/grub/i386-efi/morse.mod b/INSTALL/grub/i386-efi/morse.mod new file mode 100644 index 0000000..6788dba Binary files /dev/null and b/INSTALL/grub/i386-efi/morse.mod differ diff --git a/INSTALL/grub/i386-efi/mpi.mod b/INSTALL/grub/i386-efi/mpi.mod new file mode 100644 index 0000000..2f7b62f Binary files /dev/null and b/INSTALL/grub/i386-efi/mpi.mod differ diff --git a/INSTALL/grub/i386-efi/msdospart.mod b/INSTALL/grub/i386-efi/msdospart.mod new file mode 100644 index 0000000..9d54633 Binary files /dev/null and b/INSTALL/grub/i386-efi/msdospart.mod differ diff --git a/INSTALL/grub/i386-efi/mul_test.mod b/INSTALL/grub/i386-efi/mul_test.mod new file mode 100644 index 0000000..39e99bf Binary files /dev/null and b/INSTALL/grub/i386-efi/mul_test.mod differ diff --git a/INSTALL/grub/i386-efi/multiboot.mod b/INSTALL/grub/i386-efi/multiboot.mod new file mode 100644 index 0000000..0a80010 Binary files /dev/null and b/INSTALL/grub/i386-efi/multiboot.mod differ diff --git a/INSTALL/grub/i386-efi/multiboot2.mod b/INSTALL/grub/i386-efi/multiboot2.mod new file mode 100644 index 0000000..ed46eea Binary files /dev/null and b/INSTALL/grub/i386-efi/multiboot2.mod differ diff --git a/INSTALL/grub/i386-efi/nativedisk.mod b/INSTALL/grub/i386-efi/nativedisk.mod new file mode 100644 index 0000000..6063443 Binary files /dev/null and b/INSTALL/grub/i386-efi/nativedisk.mod differ diff --git a/INSTALL/grub/i386-efi/nilfs2.mod b/INSTALL/grub/i386-efi/nilfs2.mod new file mode 100644 index 0000000..02e7572 Binary files /dev/null and b/INSTALL/grub/i386-efi/nilfs2.mod differ diff --git a/INSTALL/grub/i386-efi/normal.mod b/INSTALL/grub/i386-efi/normal.mod new file mode 100644 index 0000000..cc5e1fd Binary files /dev/null and b/INSTALL/grub/i386-efi/normal.mod differ diff --git a/INSTALL/grub/i386-efi/ntfscomp.mod b/INSTALL/grub/i386-efi/ntfscomp.mod new file mode 100644 index 0000000..020c268 Binary files /dev/null and b/INSTALL/grub/i386-efi/ntfscomp.mod differ diff --git a/INSTALL/grub/i386-efi/odc.mod b/INSTALL/grub/i386-efi/odc.mod new file mode 100644 index 0000000..614418a Binary files /dev/null and b/INSTALL/grub/i386-efi/odc.mod differ diff --git a/INSTALL/grub/i386-efi/offsetio.mod b/INSTALL/grub/i386-efi/offsetio.mod new file mode 100644 index 0000000..6250089 Binary files /dev/null and b/INSTALL/grub/i386-efi/offsetio.mod differ diff --git a/INSTALL/grub/i386-efi/ohci.mod b/INSTALL/grub/i386-efi/ohci.mod new file mode 100644 index 0000000..f12eeca Binary files /dev/null and b/INSTALL/grub/i386-efi/ohci.mod differ diff --git a/INSTALL/grub/i386-efi/part_acorn.mod b/INSTALL/grub/i386-efi/part_acorn.mod new file mode 100644 index 0000000..05b0ec3 Binary files /dev/null and b/INSTALL/grub/i386-efi/part_acorn.mod differ diff --git a/INSTALL/grub/i386-efi/part_amiga.mod b/INSTALL/grub/i386-efi/part_amiga.mod new file mode 100644 index 0000000..b4e502f Binary files /dev/null and b/INSTALL/grub/i386-efi/part_amiga.mod differ diff --git a/INSTALL/grub/i386-efi/part_bsd.mod b/INSTALL/grub/i386-efi/part_bsd.mod new file mode 100644 index 0000000..e4b4571 Binary files /dev/null and b/INSTALL/grub/i386-efi/part_bsd.mod differ diff --git a/INSTALL/grub/i386-efi/part_dfly.mod b/INSTALL/grub/i386-efi/part_dfly.mod new file mode 100644 index 0000000..bc4c9d9 Binary files /dev/null and b/INSTALL/grub/i386-efi/part_dfly.mod differ diff --git a/INSTALL/grub/i386-efi/part_dvh.mod b/INSTALL/grub/i386-efi/part_dvh.mod new file mode 100644 index 0000000..c08b518 Binary files /dev/null and b/INSTALL/grub/i386-efi/part_dvh.mod differ diff --git a/INSTALL/grub/i386-efi/part_plan.mod b/INSTALL/grub/i386-efi/part_plan.mod new file mode 100644 index 0000000..e0763fc Binary files /dev/null and b/INSTALL/grub/i386-efi/part_plan.mod differ diff --git a/INSTALL/grub/i386-efi/part_sun.mod b/INSTALL/grub/i386-efi/part_sun.mod new file mode 100644 index 0000000..54a8d50 Binary files /dev/null and b/INSTALL/grub/i386-efi/part_sun.mod differ diff --git a/INSTALL/grub/i386-efi/part_sunpc.mod b/INSTALL/grub/i386-efi/part_sunpc.mod new file mode 100644 index 0000000..09d5c60 Binary files /dev/null and b/INSTALL/grub/i386-efi/part_sunpc.mod differ diff --git a/INSTALL/grub/i386-efi/partmap.lst b/INSTALL/grub/i386-efi/partmap.lst new file mode 100644 index 0000000..761233a --- /dev/null +++ b/INSTALL/grub/i386-efi/partmap.lst @@ -0,0 +1,11 @@ +part_acorn +part_amiga +part_apple +part_bsd +part_dfly +part_dvh +part_gpt +part_msdos +part_plan +part_sun +part_sunpc diff --git a/INSTALL/grub/i386-efi/parttool.lst b/INSTALL/grub/i386-efi/parttool.lst new file mode 100644 index 0000000..68b4b5c --- /dev/null +++ b/INSTALL/grub/i386-efi/parttool.lst @@ -0,0 +1 @@ +msdos: msdospart diff --git a/INSTALL/grub/i386-efi/parttool.mod b/INSTALL/grub/i386-efi/parttool.mod new file mode 100644 index 0000000..a54f0db Binary files /dev/null and b/INSTALL/grub/i386-efi/parttool.mod differ diff --git a/INSTALL/grub/i386-efi/password.mod b/INSTALL/grub/i386-efi/password.mod new file mode 100644 index 0000000..3111329 Binary files /dev/null and b/INSTALL/grub/i386-efi/password.mod differ diff --git a/INSTALL/grub/i386-efi/pata.mod b/INSTALL/grub/i386-efi/pata.mod new file mode 100644 index 0000000..9c14570 Binary files /dev/null and b/INSTALL/grub/i386-efi/pata.mod differ diff --git a/INSTALL/grub/i386-efi/pbkdf2_test.mod b/INSTALL/grub/i386-efi/pbkdf2_test.mod new file mode 100644 index 0000000..0c1edc4 Binary files /dev/null and b/INSTALL/grub/i386-efi/pbkdf2_test.mod differ diff --git a/INSTALL/grub/i386-efi/pcidump.mod b/INSTALL/grub/i386-efi/pcidump.mod new file mode 100644 index 0000000..ac9aedf Binary files /dev/null and b/INSTALL/grub/i386-efi/pcidump.mod differ diff --git a/INSTALL/grub/i386-efi/pgp.mod b/INSTALL/grub/i386-efi/pgp.mod new file mode 100644 index 0000000..0e78e8f Binary files /dev/null and b/INSTALL/grub/i386-efi/pgp.mod differ diff --git a/INSTALL/grub/i386-efi/play.mod b/INSTALL/grub/i386-efi/play.mod new file mode 100644 index 0000000..d781f41 Binary files /dev/null and b/INSTALL/grub/i386-efi/play.mod differ diff --git a/INSTALL/grub/i386-efi/probe.mod b/INSTALL/grub/i386-efi/probe.mod new file mode 100644 index 0000000..3f2175e Binary files /dev/null and b/INSTALL/grub/i386-efi/probe.mod differ diff --git a/INSTALL/grub/i386-efi/procfs.mod b/INSTALL/grub/i386-efi/procfs.mod new file mode 100644 index 0000000..04b27e2 Binary files /dev/null and b/INSTALL/grub/i386-efi/procfs.mod differ diff --git a/INSTALL/grub/i386-efi/progress.mod b/INSTALL/grub/i386-efi/progress.mod new file mode 100644 index 0000000..c8b00fd Binary files /dev/null and b/INSTALL/grub/i386-efi/progress.mod differ diff --git a/INSTALL/grub/i386-efi/raid5rec.mod b/INSTALL/grub/i386-efi/raid5rec.mod new file mode 100644 index 0000000..f9e72d9 Binary files /dev/null and b/INSTALL/grub/i386-efi/raid5rec.mod differ diff --git a/INSTALL/grub/i386-efi/raid6rec.mod b/INSTALL/grub/i386-efi/raid6rec.mod new file mode 100644 index 0000000..3b17884 Binary files /dev/null and b/INSTALL/grub/i386-efi/raid6rec.mod differ diff --git a/INSTALL/grub/i386-efi/random.mod b/INSTALL/grub/i386-efi/random.mod new file mode 100644 index 0000000..82fd034 Binary files /dev/null and b/INSTALL/grub/i386-efi/random.mod differ diff --git a/INSTALL/grub/i386-efi/rdmsr.mod b/INSTALL/grub/i386-efi/rdmsr.mod new file mode 100644 index 0000000..0b99c6a Binary files /dev/null and b/INSTALL/grub/i386-efi/rdmsr.mod differ diff --git a/INSTALL/grub/i386-efi/reiserfs.mod b/INSTALL/grub/i386-efi/reiserfs.mod new file mode 100644 index 0000000..e8dfb86 Binary files /dev/null and b/INSTALL/grub/i386-efi/reiserfs.mod differ diff --git a/INSTALL/grub/i386-efi/romfs.mod b/INSTALL/grub/i386-efi/romfs.mod new file mode 100644 index 0000000..db077c1 Binary files /dev/null and b/INSTALL/grub/i386-efi/romfs.mod differ diff --git a/INSTALL/grub/i386-efi/scsi.mod b/INSTALL/grub/i386-efi/scsi.mod new file mode 100644 index 0000000..5f95855 Binary files /dev/null and b/INSTALL/grub/i386-efi/scsi.mod differ diff --git a/INSTALL/grub/i386-efi/search_fs_file.mod b/INSTALL/grub/i386-efi/search_fs_file.mod new file mode 100644 index 0000000..19bf8b4 Binary files /dev/null and b/INSTALL/grub/i386-efi/search_fs_file.mod differ diff --git a/INSTALL/grub/i386-efi/search_fs_uuid.mod b/INSTALL/grub/i386-efi/search_fs_uuid.mod new file mode 100644 index 0000000..6cfe666 Binary files /dev/null and b/INSTALL/grub/i386-efi/search_fs_uuid.mod differ diff --git a/INSTALL/grub/i386-efi/search_label.mod b/INSTALL/grub/i386-efi/search_label.mod new file mode 100644 index 0000000..961e77a Binary files /dev/null and b/INSTALL/grub/i386-efi/search_label.mod differ diff --git a/INSTALL/grub/i386-efi/setjmp.mod b/INSTALL/grub/i386-efi/setjmp.mod new file mode 100644 index 0000000..2d35023 Binary files /dev/null and b/INSTALL/grub/i386-efi/setjmp.mod differ diff --git a/INSTALL/grub/i386-efi/setjmp_test.mod b/INSTALL/grub/i386-efi/setjmp_test.mod new file mode 100644 index 0000000..aa3aef3 Binary files /dev/null and b/INSTALL/grub/i386-efi/setjmp_test.mod differ diff --git a/INSTALL/grub/i386-efi/setpci.mod b/INSTALL/grub/i386-efi/setpci.mod new file mode 100644 index 0000000..e10da06 Binary files /dev/null and b/INSTALL/grub/i386-efi/setpci.mod differ diff --git a/INSTALL/grub/i386-efi/sfs.mod b/INSTALL/grub/i386-efi/sfs.mod new file mode 100644 index 0000000..8f4eb83 Binary files /dev/null and b/INSTALL/grub/i386-efi/sfs.mod differ diff --git a/INSTALL/grub/i386-efi/shift_test.mod b/INSTALL/grub/i386-efi/shift_test.mod new file mode 100644 index 0000000..b1628b4 Binary files /dev/null and b/INSTALL/grub/i386-efi/shift_test.mod differ diff --git a/INSTALL/grub/i386-efi/signature_test.mod b/INSTALL/grub/i386-efi/signature_test.mod new file mode 100644 index 0000000..61c5e99 Binary files /dev/null and b/INSTALL/grub/i386-efi/signature_test.mod differ diff --git a/INSTALL/grub/i386-efi/sleep_test.mod b/INSTALL/grub/i386-efi/sleep_test.mod new file mode 100644 index 0000000..0d91dd4 Binary files /dev/null and b/INSTALL/grub/i386-efi/sleep_test.mod differ diff --git a/INSTALL/grub/i386-efi/spkmodem.mod b/INSTALL/grub/i386-efi/spkmodem.mod new file mode 100644 index 0000000..ba4fe61 Binary files /dev/null and b/INSTALL/grub/i386-efi/spkmodem.mod differ diff --git a/INSTALL/grub/i386-efi/strtoull_test.mod b/INSTALL/grub/i386-efi/strtoull_test.mod new file mode 100644 index 0000000..5242329 Binary files /dev/null and b/INSTALL/grub/i386-efi/strtoull_test.mod differ diff --git a/INSTALL/grub/i386-efi/syslinuxcfg.mod b/INSTALL/grub/i386-efi/syslinuxcfg.mod new file mode 100644 index 0000000..15561f7 Binary files /dev/null and b/INSTALL/grub/i386-efi/syslinuxcfg.mod differ diff --git a/INSTALL/grub/i386-efi/terminal.lst b/INSTALL/grub/i386-efi/terminal.lst new file mode 100644 index 0000000..9afb9bd --- /dev/null +++ b/INSTALL/grub/i386-efi/terminal.lst @@ -0,0 +1,10 @@ +iat_keyboard: at_keyboard +imouse: mouse +iserial: serial +iserial_*: serial +oaudio: morse +ocbmemc: cbmemc +ogfxterm: gfxterm +oserial: serial +oserial_*: serial +ospkmodem: spkmodem diff --git a/INSTALL/grub/i386-efi/test_blockarg.mod b/INSTALL/grub/i386-efi/test_blockarg.mod new file mode 100644 index 0000000..d22bac4 Binary files /dev/null and b/INSTALL/grub/i386-efi/test_blockarg.mod differ diff --git a/INSTALL/grub/i386-efi/testload.mod b/INSTALL/grub/i386-efi/testload.mod new file mode 100644 index 0000000..addd9ec Binary files /dev/null and b/INSTALL/grub/i386-efi/testload.mod differ diff --git a/INSTALL/grub/i386-efi/testspeed.mod b/INSTALL/grub/i386-efi/testspeed.mod new file mode 100644 index 0000000..dff3844 Binary files /dev/null and b/INSTALL/grub/i386-efi/testspeed.mod differ diff --git a/INSTALL/grub/i386-efi/tga.mod b/INSTALL/grub/i386-efi/tga.mod new file mode 100644 index 0000000..62d9a39 Binary files /dev/null and b/INSTALL/grub/i386-efi/tga.mod differ diff --git a/INSTALL/grub/i386-efi/time.mod b/INSTALL/grub/i386-efi/time.mod new file mode 100644 index 0000000..11a3f32 Binary files /dev/null and b/INSTALL/grub/i386-efi/time.mod differ diff --git a/INSTALL/grub/i386-efi/tr.mod b/INSTALL/grub/i386-efi/tr.mod new file mode 100644 index 0000000..501de88 Binary files /dev/null and b/INSTALL/grub/i386-efi/tr.mod differ diff --git a/INSTALL/grub/i386-efi/ufs1.mod b/INSTALL/grub/i386-efi/ufs1.mod new file mode 100644 index 0000000..70356df Binary files /dev/null and b/INSTALL/grub/i386-efi/ufs1.mod differ diff --git a/INSTALL/grub/i386-efi/ufs1_be.mod b/INSTALL/grub/i386-efi/ufs1_be.mod new file mode 100644 index 0000000..160b7ac Binary files /dev/null and b/INSTALL/grub/i386-efi/ufs1_be.mod differ diff --git a/INSTALL/grub/i386-efi/ufs2.mod b/INSTALL/grub/i386-efi/ufs2.mod new file mode 100644 index 0000000..2754630 Binary files /dev/null and b/INSTALL/grub/i386-efi/ufs2.mod differ diff --git a/INSTALL/grub/i386-efi/uhci.mod b/INSTALL/grub/i386-efi/uhci.mod new file mode 100644 index 0000000..555a50e Binary files /dev/null and b/INSTALL/grub/i386-efi/uhci.mod differ diff --git a/INSTALL/grub/i386-efi/usb.mod b/INSTALL/grub/i386-efi/usb.mod new file mode 100644 index 0000000..465004f Binary files /dev/null and b/INSTALL/grub/i386-efi/usb.mod differ diff --git a/INSTALL/grub/i386-efi/usbms.mod b/INSTALL/grub/i386-efi/usbms.mod new file mode 100644 index 0000000..9a2461f Binary files /dev/null and b/INSTALL/grub/i386-efi/usbms.mod differ diff --git a/INSTALL/grub/i386-efi/usbserial_common.mod b/INSTALL/grub/i386-efi/usbserial_common.mod new file mode 100644 index 0000000..c492b11 Binary files /dev/null and b/INSTALL/grub/i386-efi/usbserial_common.mod differ diff --git a/INSTALL/grub/i386-efi/usbserial_ftdi.mod b/INSTALL/grub/i386-efi/usbserial_ftdi.mod new file mode 100644 index 0000000..e7a9a41 Binary files /dev/null and b/INSTALL/grub/i386-efi/usbserial_ftdi.mod differ diff --git a/INSTALL/grub/i386-efi/usbserial_pl2303.mod b/INSTALL/grub/i386-efi/usbserial_pl2303.mod new file mode 100644 index 0000000..5737ced Binary files /dev/null and b/INSTALL/grub/i386-efi/usbserial_pl2303.mod differ diff --git a/INSTALL/grub/i386-efi/usbserial_usbdebug.mod b/INSTALL/grub/i386-efi/usbserial_usbdebug.mod new file mode 100644 index 0000000..3463ad4 Binary files /dev/null and b/INSTALL/grub/i386-efi/usbserial_usbdebug.mod differ diff --git a/INSTALL/grub/i386-efi/usbtest.mod b/INSTALL/grub/i386-efi/usbtest.mod new file mode 100644 index 0000000..1399684 Binary files /dev/null and b/INSTALL/grub/i386-efi/usbtest.mod differ diff --git a/INSTALL/grub/i386-efi/verifiers.mod b/INSTALL/grub/i386-efi/verifiers.mod new file mode 100644 index 0000000..00ca55f Binary files /dev/null and b/INSTALL/grub/i386-efi/verifiers.mod differ diff --git a/INSTALL/grub/i386-efi/video.lst b/INSTALL/grub/i386-efi/video.lst new file mode 100644 index 0000000..ae9ba23 --- /dev/null +++ b/INSTALL/grub/i386-efi/video.lst @@ -0,0 +1,4 @@ +efi_gop +efi_uga +video_bochs +video_cirrus diff --git a/INSTALL/grub/i386-efi/videoinfo.mod b/INSTALL/grub/i386-efi/videoinfo.mod new file mode 100644 index 0000000..3993528 Binary files /dev/null and b/INSTALL/grub/i386-efi/videoinfo.mod differ diff --git a/INSTALL/grub/i386-efi/videotest.mod b/INSTALL/grub/i386-efi/videotest.mod new file mode 100644 index 0000000..e9a7170 Binary files /dev/null and b/INSTALL/grub/i386-efi/videotest.mod differ diff --git a/INSTALL/grub/i386-efi/videotest_checksum.mod b/INSTALL/grub/i386-efi/videotest_checksum.mod new file mode 100644 index 0000000..da7e93f Binary files /dev/null and b/INSTALL/grub/i386-efi/videotest_checksum.mod differ diff --git a/INSTALL/grub/i386-efi/wrmsr.mod b/INSTALL/grub/i386-efi/wrmsr.mod new file mode 100644 index 0000000..776495d Binary files /dev/null and b/INSTALL/grub/i386-efi/wrmsr.mod differ diff --git a/INSTALL/grub/i386-efi/xnu.mod b/INSTALL/grub/i386-efi/xnu.mod new file mode 100644 index 0000000..b1e874a Binary files /dev/null and b/INSTALL/grub/i386-efi/xnu.mod differ diff --git a/INSTALL/grub/i386-efi/xnu_uuid.mod b/INSTALL/grub/i386-efi/xnu_uuid.mod new file mode 100644 index 0000000..ef4d7f4 Binary files /dev/null and b/INSTALL/grub/i386-efi/xnu_uuid.mod differ diff --git a/INSTALL/grub/i386-efi/xnu_uuid_test.mod b/INSTALL/grub/i386-efi/xnu_uuid_test.mod new file mode 100644 index 0000000..f01872b Binary files /dev/null and b/INSTALL/grub/i386-efi/xnu_uuid_test.mod differ diff --git a/INSTALL/grub/i386-efi/zfs.mod b/INSTALL/grub/i386-efi/zfs.mod new file mode 100644 index 0000000..6953b93 Binary files /dev/null and b/INSTALL/grub/i386-efi/zfs.mod differ diff --git a/INSTALL/grub/i386-efi/zfscrypt.mod b/INSTALL/grub/i386-efi/zfscrypt.mod new file mode 100644 index 0000000..04d5b2b Binary files /dev/null and b/INSTALL/grub/i386-efi/zfscrypt.mod differ diff --git a/INSTALL/grub/i386-efi/zfsinfo.mod b/INSTALL/grub/i386-efi/zfsinfo.mod new file mode 100644 index 0000000..3013887 Binary files /dev/null and b/INSTALL/grub/i386-efi/zfsinfo.mod differ diff --git a/INSTALL/grub/i386-efi/zstd.mod b/INSTALL/grub/i386-efi/zstd.mod new file mode 100644 index 0000000..991b61b Binary files /dev/null and b/INSTALL/grub/i386-efi/zstd.mod differ diff --git a/INSTALL/grub/i386-pc/acpi.mod b/INSTALL/grub/i386-pc/acpi.mod new file mode 100644 index 0000000..1c28ba8 Binary files /dev/null and b/INSTALL/grub/i386-pc/acpi.mod differ diff --git a/INSTALL/grub/i386-pc/adler32.mod b/INSTALL/grub/i386-pc/adler32.mod new file mode 100644 index 0000000..f6b7276 Binary files /dev/null and b/INSTALL/grub/i386-pc/adler32.mod differ diff --git a/INSTALL/grub/i386-pc/affs.mod b/INSTALL/grub/i386-pc/affs.mod new file mode 100644 index 0000000..aad7f0e Binary files /dev/null and b/INSTALL/grub/i386-pc/affs.mod differ diff --git a/INSTALL/grub/i386-pc/afs.mod b/INSTALL/grub/i386-pc/afs.mod new file mode 100644 index 0000000..495bc81 Binary files /dev/null and b/INSTALL/grub/i386-pc/afs.mod differ diff --git a/INSTALL/grub/i386-pc/ahci.mod b/INSTALL/grub/i386-pc/ahci.mod new file mode 100644 index 0000000..7927803 Binary files /dev/null and b/INSTALL/grub/i386-pc/ahci.mod differ diff --git a/INSTALL/grub/i386-pc/aout.mod b/INSTALL/grub/i386-pc/aout.mod new file mode 100644 index 0000000..189c847 Binary files /dev/null and b/INSTALL/grub/i386-pc/aout.mod differ diff --git a/INSTALL/grub/i386-pc/archelp.mod b/INSTALL/grub/i386-pc/archelp.mod new file mode 100644 index 0000000..0aa3bb9 Binary files /dev/null and b/INSTALL/grub/i386-pc/archelp.mod differ diff --git a/INSTALL/grub/i386-pc/ata.mod b/INSTALL/grub/i386-pc/ata.mod new file mode 100644 index 0000000..10d98ed Binary files /dev/null and b/INSTALL/grub/i386-pc/ata.mod differ diff --git a/INSTALL/grub/i386-pc/backtrace.mod b/INSTALL/grub/i386-pc/backtrace.mod new file mode 100644 index 0000000..78c7fc1 Binary files /dev/null and b/INSTALL/grub/i386-pc/backtrace.mod differ diff --git a/INSTALL/grub/i386-pc/bfs.mod b/INSTALL/grub/i386-pc/bfs.mod new file mode 100644 index 0000000..427ce26 Binary files /dev/null and b/INSTALL/grub/i386-pc/bfs.mod differ diff --git a/INSTALL/grub/i386-pc/bitmap.mod b/INSTALL/grub/i386-pc/bitmap.mod new file mode 100644 index 0000000..4240463 Binary files /dev/null and b/INSTALL/grub/i386-pc/bitmap.mod differ diff --git a/INSTALL/grub/i386-pc/bitmap_scale.mod b/INSTALL/grub/i386-pc/bitmap_scale.mod new file mode 100644 index 0000000..02687ff Binary files /dev/null and b/INSTALL/grub/i386-pc/bitmap_scale.mod differ diff --git a/INSTALL/grub/i386-pc/blscfg.mod b/INSTALL/grub/i386-pc/blscfg.mod new file mode 100644 index 0000000..8be0760 Binary files /dev/null and b/INSTALL/grub/i386-pc/blscfg.mod differ diff --git a/INSTALL/grub/i386-pc/boot.img b/INSTALL/grub/i386-pc/boot.img new file mode 100644 index 0000000..eedeba8 Binary files /dev/null and b/INSTALL/grub/i386-pc/boot.img differ diff --git a/INSTALL/grub/i386-pc/bsd.mod b/INSTALL/grub/i386-pc/bsd.mod new file mode 100644 index 0000000..35f1bcb Binary files /dev/null and b/INSTALL/grub/i386-pc/bsd.mod differ diff --git a/INSTALL/grub/i386-pc/bswap_test.mod b/INSTALL/grub/i386-pc/bswap_test.mod new file mode 100644 index 0000000..4112db9 Binary files /dev/null and b/INSTALL/grub/i386-pc/bswap_test.mod differ diff --git a/INSTALL/grub/i386-pc/btrfs.mod b/INSTALL/grub/i386-pc/btrfs.mod new file mode 100644 index 0000000..f56207f Binary files /dev/null and b/INSTALL/grub/i386-pc/btrfs.mod differ diff --git a/INSTALL/grub/i386-pc/bufio.mod b/INSTALL/grub/i386-pc/bufio.mod new file mode 100644 index 0000000..6db404b Binary files /dev/null and b/INSTALL/grub/i386-pc/bufio.mod differ diff --git a/INSTALL/grub/i386-pc/cat.mod b/INSTALL/grub/i386-pc/cat.mod new file mode 100644 index 0000000..4afb29f Binary files /dev/null and b/INSTALL/grub/i386-pc/cat.mod differ diff --git a/INSTALL/grub/i386-pc/cbfs.mod b/INSTALL/grub/i386-pc/cbfs.mod new file mode 100644 index 0000000..987e9aa Binary files /dev/null and b/INSTALL/grub/i386-pc/cbfs.mod differ diff --git a/INSTALL/grub/i386-pc/cbls.mod b/INSTALL/grub/i386-pc/cbls.mod new file mode 100644 index 0000000..bb86e5a Binary files /dev/null and b/INSTALL/grub/i386-pc/cbls.mod differ diff --git a/INSTALL/grub/i386-pc/cbmemc.mod b/INSTALL/grub/i386-pc/cbmemc.mod new file mode 100644 index 0000000..76253f7 Binary files /dev/null and b/INSTALL/grub/i386-pc/cbmemc.mod differ diff --git a/INSTALL/grub/i386-pc/cbtable.mod b/INSTALL/grub/i386-pc/cbtable.mod new file mode 100644 index 0000000..47ebd77 Binary files /dev/null and b/INSTALL/grub/i386-pc/cbtable.mod differ diff --git a/INSTALL/grub/i386-pc/cbtime.mod b/INSTALL/grub/i386-pc/cbtime.mod new file mode 100644 index 0000000..fde0d47 Binary files /dev/null and b/INSTALL/grub/i386-pc/cbtime.mod differ diff --git a/INSTALL/grub/i386-pc/cmdline_cat_test.mod b/INSTALL/grub/i386-pc/cmdline_cat_test.mod new file mode 100644 index 0000000..e22586d Binary files /dev/null and b/INSTALL/grub/i386-pc/cmdline_cat_test.mod differ diff --git a/INSTALL/grub/i386-pc/cmosdump.mod b/INSTALL/grub/i386-pc/cmosdump.mod new file mode 100644 index 0000000..23d4b7d Binary files /dev/null and b/INSTALL/grub/i386-pc/cmosdump.mod differ diff --git a/INSTALL/grub/i386-pc/cmostest.mod b/INSTALL/grub/i386-pc/cmostest.mod new file mode 100644 index 0000000..d94f1c1 Binary files /dev/null and b/INSTALL/grub/i386-pc/cmostest.mod differ diff --git a/INSTALL/grub/i386-pc/cmp.mod b/INSTALL/grub/i386-pc/cmp.mod new file mode 100644 index 0000000..e482c30 Binary files /dev/null and b/INSTALL/grub/i386-pc/cmp.mod differ diff --git a/INSTALL/grub/i386-pc/cmp_test.mod b/INSTALL/grub/i386-pc/cmp_test.mod new file mode 100644 index 0000000..f9a1423 Binary files /dev/null and b/INSTALL/grub/i386-pc/cmp_test.mod differ diff --git a/INSTALL/grub/i386-pc/command.lst b/INSTALL/grub/i386-pc/command.lst new file mode 100644 index 0000000..a21a2f9 --- /dev/null +++ b/INSTALL/grub/i386-pc/command.lst @@ -0,0 +1,212 @@ +*acpi: acpi +*all_functional_test: functional_test +*background_image: gfxterm_background +*bls_import: blscfg +*blscfg: blscfg +*cat: cat +*cpuid: cpuid +*crc: hashsum +*cryptomount: cryptodisk +*drivemap: drivemap +*echo: echo +*extract_syslinux_entries_configfile: syslinuxcfg +*extract_syslinux_entries_source: syslinuxcfg +*file: file +*functional_test: functional_test +*gettext: gettext +*halt: halt +*hashsum: hashsum +*hdparm: hdparm +*hello: hello +*help: help +*hexdump: hexdump +*inb: iorw +*inl: iorw +*inw: iorw +*keystatus: keystatus +*kfreebsd: bsd +*knetbsd: bsd +*kopenbsd: bsd +*list_env: loadenv +*load_env: loadenv +*loopback: loopback +*ls: ls +*lsacpi: lsacpi +*lspci: lspci +*md5sum: hashsum +*menuentry: normal +*pcidump: pcidump +*plan9: plan9 +*probe: probe +*rdmsr: rdmsr +*read_byte: memrw +*read_dword: memrw +*read_word: memrw +*regexp: regexp +*save_env: loadenv +*search: search +*sendkey: sendkey +*serial: serial +*set_keyboard_layout: setkey +*setkey: setkey +*setpci: setpci +*sha1sum: hashsum +*sha256sum: hashsum +*sha512sum: hashsum +*sleep: sleep +*smbios: smbios +*submenu: normal +*syslinux_configfile: syslinuxcfg +*syslinux_source: syslinuxcfg +*terminfo: terminfo +*test_blockarg: test_blockarg +*testspeed: testspeed +*tr: tr +*trust: pgp +*verify_detached: pgp +*xnu_splash: xnu +*zfskey: zfscrypt +.: configfile +[: test +authenticate: normal +background_color: gfxterm_background +backtrace: backtrace +badram: mmap +blocklist: blocklist +boot: boot +break: normal +cat: minicmd +cbmemc: cbmemc +chainloader: chain +clear: normal +cmosclean: cmostest +cmosdump: cmosdump +cmosset: cmostest +cmostest: cmostest +cmp: cmp +configfile: configfile +continue: normal +coreboot_boottime: cbtime +cutmem: mmap +date: date +distrust: pgp +dump: minicmd +efiemu_loadcore: efiemu +efiemu_prepare: efiemu +efiemu_unload: efiemu +eval: eval +exit: minicmd +export: normal +extract_entries_configfile: configfile +extract_entries_source: configfile +extract_legacy_entries_configfile: legacycfg +extract_legacy_entries_source: legacycfg +false: true +freedos: freedos +gdbstub: gdb +gdbstub_break: gdb +gdbstub_stop: gdb +gptsync: gptsync +help: minicmd +hexdump_random: random +initrd16: linux16 +initrd: linux +initrdefi: linux +keymap: keylayouts +kfreebsd_loadenv: bsd +kfreebsd_module: bsd +kfreebsd_module_elf: bsd +knetbsd_module: bsd +knetbsd_module_elf: bsd +kopenbsd_ramdisk: bsd +legacy_check_password: legacycfg +legacy_configfile: legacycfg +legacy_initrd: legacycfg +legacy_initrd_nounzip: legacycfg +legacy_kernel: legacycfg +legacy_password: legacycfg +legacy_source: legacycfg +linux16: linux16 +linux: linux +linuxefi: linux +list_trusted: pgp +loadfont: font +lsapm: lsapm +lscoreboot: cbls +lsfonts: font +lsmmap: lsmmap +lsmod: minicmd +macppcbless: macbless +mactelbless: macbless +module2: multiboot2 +module: multiboot +multiboot2: multiboot2 +multiboot: multiboot +nativedisk: nativedisk +net_add_addr: net +net_add_dns: net +net_add_route: net +net_bootp: net +net_del_addr: net +net_del_dns: net +net_del_route: net +net_dhcp: net +net_get_dhcp_option: net +net_ipv6_autoconf: net +net_ls_addr: net +net_ls_cards: net +net_ls_dns: net +net_ls_routes: net +net_nslookup: net +normal: normal +normal_exit: normal +ntldr: ntldr +outb: iorw +outl: iorw +outw: iorw +parttool: parttool +password: password +password_pbkdf2: password_pbkdf2 +play: play +pxechainloader: pxechain +read: read +reboot: reboot +return: normal +rmmod: minicmd +search.file: search_fs_file +search.fs_label: search_label +search.fs_uuid: search_fs_uuid +setparams: normal +shift: normal +source: configfile +terminal_input: terminal +terminal_output: terminal +test: test +testload: testload +time: time +true: true +truecrypt: truecrypt +usb: usbtest +vbeinfo: videoinfo +vbetest: videotest +videoinfo: videoinfo +videotest: videotest +vt_img_extra_initrd_append: linux +vt_img_extra_initrd_reset: linux +vt_set_boot_opt: linux +vt_unset_boot_opt: linux +write_byte: memrw +write_dword: memrw +write_word: memrw +wrmsr: wrmsr +xnu_devprop_load: xnu +xnu_kernel64: xnu +xnu_kernel: xnu +xnu_kext: xnu +xnu_kextdir: xnu +xnu_mkext: xnu +xnu_ramdisk: xnu +xnu_resume: xnu +xnu_uuid: xnu_uuid +zfs-bootfs: zfsinfo +zfsinfo: zfsinfo diff --git a/INSTALL/grub/i386-pc/core.img b/INSTALL/grub/i386-pc/core.img new file mode 100644 index 0000000..7d14633 Binary files /dev/null and b/INSTALL/grub/i386-pc/core.img differ diff --git a/INSTALL/grub/i386-pc/cpio.mod b/INSTALL/grub/i386-pc/cpio.mod new file mode 100644 index 0000000..6bf0ef0 Binary files /dev/null and b/INSTALL/grub/i386-pc/cpio.mod differ diff --git a/INSTALL/grub/i386-pc/cpio_be.mod b/INSTALL/grub/i386-pc/cpio_be.mod new file mode 100644 index 0000000..3b0df64 Binary files /dev/null and b/INSTALL/grub/i386-pc/cpio_be.mod differ diff --git a/INSTALL/grub/i386-pc/cpuid.mod b/INSTALL/grub/i386-pc/cpuid.mod new file mode 100644 index 0000000..cc4471a Binary files /dev/null and b/INSTALL/grub/i386-pc/cpuid.mod differ diff --git a/INSTALL/grub/i386-pc/crc64.mod b/INSTALL/grub/i386-pc/crc64.mod new file mode 100644 index 0000000..441fc4a Binary files /dev/null and b/INSTALL/grub/i386-pc/crc64.mod differ diff --git a/INSTALL/grub/i386-pc/crypto.lst b/INSTALL/grub/i386-pc/crypto.lst new file mode 100644 index 0000000..77d9efc --- /dev/null +++ b/INSTALL/grub/i386-pc/crypto.lst @@ -0,0 +1,45 @@ +RIJNDAEL: gcry_rijndael +RIJNDAEL192: gcry_rijndael +RIJNDAEL256: gcry_rijndael +AES128: gcry_rijndael +AES-128: gcry_rijndael +AES-192: gcry_rijndael +AES-256: gcry_rijndael +ADLER32: adler32 +CRC64: crc64 +ARCFOUR: gcry_arcfour +BLOWFISH: gcry_blowfish +CAMELLIA128: gcry_camellia +CAMELLIA192: gcry_camellia +CAMELLIA256: gcry_camellia +CAST5: gcry_cast5 +CRC32: gcry_crc +CRC32RFC1510: gcry_crc +CRC24RFC2440: gcry_crc +DES: gcry_des +3DES: gcry_des +DSA: gcry_dsa +IDEA: gcry_idea +MD4: gcry_md4 +MD5: gcry_md5 +RFC2268_40: gcry_rfc2268 +AES: gcry_rijndael +AES192: gcry_rijndael +AES256: gcry_rijndael +RIPEMD160: gcry_rmd160 +RSA: gcry_rsa +SEED: gcry_seed +SERPENT128: gcry_serpent +SERPENT192: gcry_serpent +SERPENT256: gcry_serpent +SHA1: gcry_sha1 +SHA224: gcry_sha256 +SHA256: gcry_sha256 +SHA512: gcry_sha512 +SHA384: gcry_sha512 +TIGER192: gcry_tiger +TIGER: gcry_tiger +TIGER2: gcry_tiger +TWOFISH: gcry_twofish +TWOFISH128: gcry_twofish +WHIRLPOOL: gcry_whirlpool diff --git a/INSTALL/grub/i386-pc/crypto.mod b/INSTALL/grub/i386-pc/crypto.mod new file mode 100644 index 0000000..d9914ae Binary files /dev/null and b/INSTALL/grub/i386-pc/crypto.mod differ diff --git a/INSTALL/grub/i386-pc/cryptodisk.mod b/INSTALL/grub/i386-pc/cryptodisk.mod new file mode 100644 index 0000000..ee52348 Binary files /dev/null and b/INSTALL/grub/i386-pc/cryptodisk.mod differ diff --git a/INSTALL/grub/i386-pc/cs5536.mod b/INSTALL/grub/i386-pc/cs5536.mod new file mode 100644 index 0000000..c8fdce8 Binary files /dev/null and b/INSTALL/grub/i386-pc/cs5536.mod differ diff --git a/INSTALL/grub/i386-pc/ctz_test.mod b/INSTALL/grub/i386-pc/ctz_test.mod new file mode 100644 index 0000000..232ffa8 Binary files /dev/null and b/INSTALL/grub/i386-pc/ctz_test.mod differ diff --git a/INSTALL/grub/i386-pc/datehook.mod b/INSTALL/grub/i386-pc/datehook.mod new file mode 100644 index 0000000..a42ca57 Binary files /dev/null and b/INSTALL/grub/i386-pc/datehook.mod differ diff --git a/INSTALL/grub/i386-pc/datetime.mod b/INSTALL/grub/i386-pc/datetime.mod new file mode 100644 index 0000000..5de1ad4 Binary files /dev/null and b/INSTALL/grub/i386-pc/datetime.mod differ diff --git a/INSTALL/grub/i386-pc/diskfilter.mod b/INSTALL/grub/i386-pc/diskfilter.mod new file mode 100644 index 0000000..cf81580 Binary files /dev/null and b/INSTALL/grub/i386-pc/diskfilter.mod differ diff --git a/INSTALL/grub/i386-pc/div.mod b/INSTALL/grub/i386-pc/div.mod new file mode 100644 index 0000000..f9a5d9d Binary files /dev/null and b/INSTALL/grub/i386-pc/div.mod differ diff --git a/INSTALL/grub/i386-pc/div_test.mod b/INSTALL/grub/i386-pc/div_test.mod new file mode 100644 index 0000000..4ec3622 Binary files /dev/null and b/INSTALL/grub/i386-pc/div_test.mod differ diff --git a/INSTALL/grub/i386-pc/dm_nv.mod b/INSTALL/grub/i386-pc/dm_nv.mod new file mode 100644 index 0000000..8b48ad5 Binary files /dev/null and b/INSTALL/grub/i386-pc/dm_nv.mod differ diff --git a/INSTALL/grub/i386-pc/efiemu.mod b/INSTALL/grub/i386-pc/efiemu.mod new file mode 100644 index 0000000..b6ea698 Binary files /dev/null and b/INSTALL/grub/i386-pc/efiemu.mod differ diff --git a/INSTALL/grub/i386-pc/ehci.mod b/INSTALL/grub/i386-pc/ehci.mod new file mode 100644 index 0000000..17429f5 Binary files /dev/null and b/INSTALL/grub/i386-pc/ehci.mod differ diff --git a/INSTALL/grub/i386-pc/elf.mod b/INSTALL/grub/i386-pc/elf.mod new file mode 100644 index 0000000..c856e11 Binary files /dev/null and b/INSTALL/grub/i386-pc/elf.mod differ diff --git a/INSTALL/grub/i386-pc/eval.mod b/INSTALL/grub/i386-pc/eval.mod new file mode 100644 index 0000000..417bb91 Binary files /dev/null and b/INSTALL/grub/i386-pc/eval.mod differ diff --git a/INSTALL/grub/i386-pc/exfctest.mod b/INSTALL/grub/i386-pc/exfctest.mod new file mode 100644 index 0000000..9cfe492 Binary files /dev/null and b/INSTALL/grub/i386-pc/exfctest.mod differ diff --git a/INSTALL/grub/i386-pc/f2fs.mod b/INSTALL/grub/i386-pc/f2fs.mod new file mode 100644 index 0000000..fa9ed6c Binary files /dev/null and b/INSTALL/grub/i386-pc/f2fs.mod differ diff --git a/INSTALL/grub/i386-pc/fdt.lst b/INSTALL/grub/i386-pc/fdt.lst new file mode 100644 index 0000000..e69de29 diff --git a/INSTALL/grub/i386-pc/file.mod b/INSTALL/grub/i386-pc/file.mod new file mode 100644 index 0000000..29488fc Binary files /dev/null and b/INSTALL/grub/i386-pc/file.mod differ diff --git a/INSTALL/grub/i386-pc/freedos.mod b/INSTALL/grub/i386-pc/freedos.mod new file mode 100644 index 0000000..0ea367b Binary files /dev/null and b/INSTALL/grub/i386-pc/freedos.mod differ diff --git a/INSTALL/grub/i386-pc/fs.lst b/INSTALL/grub/i386-pc/fs.lst new file mode 100644 index 0000000..0acd240 --- /dev/null +++ b/INSTALL/grub/i386-pc/fs.lst @@ -0,0 +1,37 @@ +affs +afs +bfs +btrfs +cbfs +cpio +cpio_be +exfat +ext2 +f2fs +fat +hfs +hfsplus +iso9660 +jfs +minix +minix2 +minix2_be +minix3 +minix3_be +minix_be +newc +nilfs2 +ntfs +odc +procfs +reiserfs +romfs +sfs +squash4 +tar +udf +ufs1 +ufs1_be +ufs2 +xfs +zfs diff --git a/INSTALL/grub/i386-pc/fshelp.mod b/INSTALL/grub/i386-pc/fshelp.mod new file mode 100644 index 0000000..e986d45 Binary files /dev/null and b/INSTALL/grub/i386-pc/fshelp.mod differ diff --git a/INSTALL/grub/i386-pc/functional_test.mod b/INSTALL/grub/i386-pc/functional_test.mod new file mode 100644 index 0000000..2b49846 Binary files /dev/null and b/INSTALL/grub/i386-pc/functional_test.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_arcfour.mod b/INSTALL/grub/i386-pc/gcry_arcfour.mod new file mode 100644 index 0000000..c49de7a Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_arcfour.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_blowfish.mod b/INSTALL/grub/i386-pc/gcry_blowfish.mod new file mode 100644 index 0000000..83285b3 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_blowfish.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_camellia.mod b/INSTALL/grub/i386-pc/gcry_camellia.mod new file mode 100644 index 0000000..337637e Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_camellia.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_cast5.mod b/INSTALL/grub/i386-pc/gcry_cast5.mod new file mode 100644 index 0000000..8a74275 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_cast5.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_crc.mod b/INSTALL/grub/i386-pc/gcry_crc.mod new file mode 100644 index 0000000..d3f30c4 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_crc.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_des.mod b/INSTALL/grub/i386-pc/gcry_des.mod new file mode 100644 index 0000000..2b1f3de Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_des.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_dsa.mod b/INSTALL/grub/i386-pc/gcry_dsa.mod new file mode 100644 index 0000000..ab382c8 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_dsa.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_idea.mod b/INSTALL/grub/i386-pc/gcry_idea.mod new file mode 100644 index 0000000..b939c0d Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_idea.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_md4.mod b/INSTALL/grub/i386-pc/gcry_md4.mod new file mode 100644 index 0000000..16f78fa Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_md4.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_rfc2268.mod b/INSTALL/grub/i386-pc/gcry_rfc2268.mod new file mode 100644 index 0000000..db1c2b7 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_rfc2268.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_rijndael.mod b/INSTALL/grub/i386-pc/gcry_rijndael.mod new file mode 100644 index 0000000..6a93d1b Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_rijndael.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_rmd160.mod b/INSTALL/grub/i386-pc/gcry_rmd160.mod new file mode 100644 index 0000000..24b37c5 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_rmd160.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_rsa.mod b/INSTALL/grub/i386-pc/gcry_rsa.mod new file mode 100644 index 0000000..11dc696 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_rsa.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_seed.mod b/INSTALL/grub/i386-pc/gcry_seed.mod new file mode 100644 index 0000000..157c74c Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_seed.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_serpent.mod b/INSTALL/grub/i386-pc/gcry_serpent.mod new file mode 100644 index 0000000..8ed6364 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_serpent.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_sha1.mod b/INSTALL/grub/i386-pc/gcry_sha1.mod new file mode 100644 index 0000000..855afd6 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_sha1.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_sha256.mod b/INSTALL/grub/i386-pc/gcry_sha256.mod new file mode 100644 index 0000000..fc269cc Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_sha256.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_sha512.mod b/INSTALL/grub/i386-pc/gcry_sha512.mod new file mode 100644 index 0000000..03b48b5 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_sha512.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_tiger.mod b/INSTALL/grub/i386-pc/gcry_tiger.mod new file mode 100644 index 0000000..a91e315 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_tiger.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_twofish.mod b/INSTALL/grub/i386-pc/gcry_twofish.mod new file mode 100644 index 0000000..8b8efae Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_twofish.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_whirlpool.mod b/INSTALL/grub/i386-pc/gcry_whirlpool.mod new file mode 100644 index 0000000..7918540 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_whirlpool.mod differ diff --git a/INSTALL/grub/i386-pc/gdb.mod b/INSTALL/grub/i386-pc/gdb.mod new file mode 100644 index 0000000..fa88b7c Binary files /dev/null and b/INSTALL/grub/i386-pc/gdb.mod differ diff --git a/INSTALL/grub/i386-pc/geli.mod b/INSTALL/grub/i386-pc/geli.mod new file mode 100644 index 0000000..3a59c1a Binary files /dev/null and b/INSTALL/grub/i386-pc/geli.mod differ diff --git a/INSTALL/grub/i386-pc/gfxterm_menu.mod b/INSTALL/grub/i386-pc/gfxterm_menu.mod new file mode 100644 index 0000000..a6aba54 Binary files /dev/null and b/INSTALL/grub/i386-pc/gfxterm_menu.mod differ diff --git a/INSTALL/grub/i386-pc/gptsync.mod b/INSTALL/grub/i386-pc/gptsync.mod new file mode 100644 index 0000000..6c75de0 Binary files /dev/null and b/INSTALL/grub/i386-pc/gptsync.mod differ diff --git a/INSTALL/grub/i386-pc/hdparm.mod b/INSTALL/grub/i386-pc/hdparm.mod new file mode 100644 index 0000000..7cecce6 Binary files /dev/null and b/INSTALL/grub/i386-pc/hdparm.mod differ diff --git a/INSTALL/grub/i386-pc/hello.mod b/INSTALL/grub/i386-pc/hello.mod new file mode 100644 index 0000000..14fd095 Binary files /dev/null and b/INSTALL/grub/i386-pc/hello.mod differ diff --git a/INSTALL/grub/i386-pc/hexdump.mod b/INSTALL/grub/i386-pc/hexdump.mod new file mode 100644 index 0000000..93837fe Binary files /dev/null and b/INSTALL/grub/i386-pc/hexdump.mod differ diff --git a/INSTALL/grub/i386-pc/hfs.mod b/INSTALL/grub/i386-pc/hfs.mod new file mode 100644 index 0000000..a8d2d8f Binary files /dev/null and b/INSTALL/grub/i386-pc/hfs.mod differ diff --git a/INSTALL/grub/i386-pc/hfsplus.mod b/INSTALL/grub/i386-pc/hfsplus.mod new file mode 100644 index 0000000..7293830 Binary files /dev/null and b/INSTALL/grub/i386-pc/hfsplus.mod differ diff --git a/INSTALL/grub/i386-pc/hfspluscomp.mod b/INSTALL/grub/i386-pc/hfspluscomp.mod new file mode 100644 index 0000000..b2b4087 Binary files /dev/null and b/INSTALL/grub/i386-pc/hfspluscomp.mod differ diff --git a/INSTALL/grub/i386-pc/iorw.mod b/INSTALL/grub/i386-pc/iorw.mod new file mode 100644 index 0000000..8b63605 Binary files /dev/null and b/INSTALL/grub/i386-pc/iorw.mod differ diff --git a/INSTALL/grub/i386-pc/jfs.mod b/INSTALL/grub/i386-pc/jfs.mod new file mode 100644 index 0000000..028c658 Binary files /dev/null and b/INSTALL/grub/i386-pc/jfs.mod differ diff --git a/INSTALL/grub/i386-pc/keylayouts.mod b/INSTALL/grub/i386-pc/keylayouts.mod new file mode 100644 index 0000000..50d8183 Binary files /dev/null and b/INSTALL/grub/i386-pc/keylayouts.mod differ diff --git a/INSTALL/grub/i386-pc/keystatus.mod b/INSTALL/grub/i386-pc/keystatus.mod new file mode 100644 index 0000000..8b5088a Binary files /dev/null and b/INSTALL/grub/i386-pc/keystatus.mod differ diff --git a/INSTALL/grub/i386-pc/ldm.mod b/INSTALL/grub/i386-pc/ldm.mod new file mode 100644 index 0000000..f299315 Binary files /dev/null and b/INSTALL/grub/i386-pc/ldm.mod differ diff --git a/INSTALL/grub/i386-pc/legacy_password_test.mod b/INSTALL/grub/i386-pc/legacy_password_test.mod new file mode 100644 index 0000000..b5c58fa Binary files /dev/null and b/INSTALL/grub/i386-pc/legacy_password_test.mod differ diff --git a/INSTALL/grub/i386-pc/legacycfg.mod b/INSTALL/grub/i386-pc/legacycfg.mod new file mode 100644 index 0000000..b910f87 Binary files /dev/null and b/INSTALL/grub/i386-pc/legacycfg.mod differ diff --git a/INSTALL/grub/i386-pc/loadenv.mod b/INSTALL/grub/i386-pc/loadenv.mod new file mode 100644 index 0000000..834e8d9 Binary files /dev/null and b/INSTALL/grub/i386-pc/loadenv.mod differ diff --git a/INSTALL/grub/i386-pc/lsacpi.mod b/INSTALL/grub/i386-pc/lsacpi.mod new file mode 100644 index 0000000..7e94483 Binary files /dev/null and b/INSTALL/grub/i386-pc/lsacpi.mod differ diff --git a/INSTALL/grub/i386-pc/lsapm.mod b/INSTALL/grub/i386-pc/lsapm.mod new file mode 100644 index 0000000..5a053d7 Binary files /dev/null and b/INSTALL/grub/i386-pc/lsapm.mod differ diff --git a/INSTALL/grub/i386-pc/lsmmap.mod b/INSTALL/grub/i386-pc/lsmmap.mod new file mode 100644 index 0000000..683ecfe Binary files /dev/null and b/INSTALL/grub/i386-pc/lsmmap.mod differ diff --git a/INSTALL/grub/i386-pc/luks.mod b/INSTALL/grub/i386-pc/luks.mod new file mode 100644 index 0000000..9c18afa Binary files /dev/null and b/INSTALL/grub/i386-pc/luks.mod differ diff --git a/INSTALL/grub/i386-pc/lvm.mod b/INSTALL/grub/i386-pc/lvm.mod new file mode 100644 index 0000000..10c1267 Binary files /dev/null and b/INSTALL/grub/i386-pc/lvm.mod differ diff --git a/INSTALL/grub/i386-pc/macbless.mod b/INSTALL/grub/i386-pc/macbless.mod new file mode 100644 index 0000000..c7ed444 Binary files /dev/null and b/INSTALL/grub/i386-pc/macbless.mod differ diff --git a/INSTALL/grub/i386-pc/macho.mod b/INSTALL/grub/i386-pc/macho.mod new file mode 100644 index 0000000..6aa4cf5 Binary files /dev/null and b/INSTALL/grub/i386-pc/macho.mod differ diff --git a/INSTALL/grub/i386-pc/mda_text.mod b/INSTALL/grub/i386-pc/mda_text.mod new file mode 100644 index 0000000..8f343cc Binary files /dev/null and b/INSTALL/grub/i386-pc/mda_text.mod differ diff --git a/INSTALL/grub/i386-pc/mdraid09.mod b/INSTALL/grub/i386-pc/mdraid09.mod new file mode 100644 index 0000000..ba29a59 Binary files /dev/null and b/INSTALL/grub/i386-pc/mdraid09.mod differ diff --git a/INSTALL/grub/i386-pc/mdraid09_be.mod b/INSTALL/grub/i386-pc/mdraid09_be.mod new file mode 100644 index 0000000..f53e40f Binary files /dev/null and b/INSTALL/grub/i386-pc/mdraid09_be.mod differ diff --git a/INSTALL/grub/i386-pc/mdraid1x.mod b/INSTALL/grub/i386-pc/mdraid1x.mod new file mode 100644 index 0000000..c00a9af Binary files /dev/null and b/INSTALL/grub/i386-pc/mdraid1x.mod differ diff --git a/INSTALL/grub/i386-pc/memdisk.mod b/INSTALL/grub/i386-pc/memdisk.mod new file mode 100644 index 0000000..83aaf1b Binary files /dev/null and b/INSTALL/grub/i386-pc/memdisk.mod differ diff --git a/INSTALL/grub/i386-pc/memrw.mod b/INSTALL/grub/i386-pc/memrw.mod new file mode 100644 index 0000000..db9ae48 Binary files /dev/null and b/INSTALL/grub/i386-pc/memrw.mod differ diff --git a/INSTALL/grub/i386-pc/minix.mod b/INSTALL/grub/i386-pc/minix.mod new file mode 100644 index 0000000..87064ee Binary files /dev/null and b/INSTALL/grub/i386-pc/minix.mod differ diff --git a/INSTALL/grub/i386-pc/minix2.mod b/INSTALL/grub/i386-pc/minix2.mod new file mode 100644 index 0000000..0d0b6d2 Binary files /dev/null and b/INSTALL/grub/i386-pc/minix2.mod differ diff --git a/INSTALL/grub/i386-pc/minix2_be.mod b/INSTALL/grub/i386-pc/minix2_be.mod new file mode 100644 index 0000000..e383aa5 Binary files /dev/null and b/INSTALL/grub/i386-pc/minix2_be.mod differ diff --git a/INSTALL/grub/i386-pc/minix3.mod b/INSTALL/grub/i386-pc/minix3.mod new file mode 100644 index 0000000..f96fb45 Binary files /dev/null and b/INSTALL/grub/i386-pc/minix3.mod differ diff --git a/INSTALL/grub/i386-pc/minix3_be.mod b/INSTALL/grub/i386-pc/minix3_be.mod new file mode 100644 index 0000000..d3dca21 Binary files /dev/null and b/INSTALL/grub/i386-pc/minix3_be.mod differ diff --git a/INSTALL/grub/i386-pc/minix_be.mod b/INSTALL/grub/i386-pc/minix_be.mod new file mode 100644 index 0000000..604dffe Binary files /dev/null and b/INSTALL/grub/i386-pc/minix_be.mod differ diff --git a/INSTALL/grub/i386-pc/mmap.mod b/INSTALL/grub/i386-pc/mmap.mod new file mode 100644 index 0000000..f8b05f3 Binary files /dev/null and b/INSTALL/grub/i386-pc/mmap.mod differ diff --git a/INSTALL/grub/i386-pc/moddep.lst b/INSTALL/grub/i386-pc/moddep.lst new file mode 100644 index 0000000..de15670 --- /dev/null +++ b/INSTALL/grub/i386-pc/moddep.lst @@ -0,0 +1,274 @@ +videotest: font video gfxmenu +odc: archelp +loopback: extcmd +setkey: extcmd +macho: +gcry_des: crypto +memrw: extcmd +terminfo: extcmd +f2fs: fshelp +part_gpt: +romfs: fshelp +read: +aout: +gcry_arcfour: crypto +vga_text: +tftp: net priority_queue +newc: archelp +minix2_be: +elf: +videotest_checksum: font functional_test video_fb +password_pbkdf2: crypto gcry_sha512 pbkdf2 normal +gcry_seed: crypto +pcidump: extcmd pci +bsd: elf serial crypto gcry_md5 verifiers extcmd vbe aout video boot cpuid relocator mmap +sfs: fshelp +reiserfs: fshelp +part_sunpc: +zstd: +gfxmenu: video_colors trig bitmap_scale gfxterm font normal video bitmap +backtrace: +jfs: +help: extcmd normal +configfile: normal +cbls: cbtable +gfxterm_menu: font functional_test procfs normal video_fb +gcry_idea: crypto +tr: extcmd +shift_test: functional_test +ohci: cs5536 usb boot pci +afs: fshelp +spkmodem: terminfo +usb_keyboard: keylayouts usb +xzio: crypto +syslinuxcfg: extcmd normal +search_fs_file: +wrmsr: +vga: video video_fb +usbms: scsi usb +test_blockarg: extcmd normal +true: +affs: fshelp +iso9660: fshelp +smbios: extcmd acpi +exfat: fshelp +setjmp_test: setjmp functional_test +gfxterm: font video +disk: +xfs: fshelp +testspeed: extcmd normal +cpio_be: archelp +functional_test: btrfs extcmd video video_fb +pxechain: pxe video boot relocator +bswap_test: functional_test +sleep: extcmd normal +memdisk: +gcry_rijndael: crypto +mdraid09_be: diskfilter +gettext: +gcry_sha1: crypto +hfspluscomp: gzio hfsplus +cmp: +random: hexdump acpi +offsetio: +file: elf macho extcmd offsetio +usbserial_usbdebug: serial usb usbserial_common +video_colors: +morse: +hashsum: crypto extcmd normal +usb: pci +halt: extcmd acpi +gdb: serial backtrace +gfxterm_background: video_colors bitmap_scale gfxterm extcmd video bitmap +search_fs_uuid: +gcry_dsa: pgp mpi +keystatus: extcmd +linux: ventoy verifiers vbe normal video boot relocator mmap +geli: cryptodisk crypto gcry_sha512 pbkdf2 gcry_sha256 +cmdline_cat_test: font functional_test normal procfs video_fb +rdmsr: extcmd +part_sun: +cbtable: +plan9: verifiers extcmd boot video relocator +sendkey: extcmd boot +pbkdf2_test: functional_test pbkdf2 gcry_sha1 +video_bochs: pci video video_fb +verifiers: +bufio: +usbserial_ftdi: serial usb usbserial_common +legacy_password_test: functional_test legacycfg +cpuid: extcmd +blscfg: extcmd normal +hdparm: extcmd hexdump +bfs: fshelp +gcry_blowfish: crypto +test: +nilfs2: fshelp +gcry_rsa: pgp mpi +cryptodisk: crypto extcmd procfs +nativedisk: +minicmd: +signature_test: functional_test procfs +ata: scsi +udf: fshelp +gzio: gcry_crc +xnu_uuid: gcry_md5 +uhci: usb pci +pata: ata pci +mul_test: functional_test +adler32: crypto +terminal: +div: +ehci: cs5536 usb boot pci +crypto: +part_bsd: part_msdos +cs5536: pci +biosdisk: +ventoy: ext2 fshelp elf btrfs crypto font gcry_md5 exfat udf div extcmd datetime normal video gcry_sha1 iso9660 reboot acpi +lsapm: +gcry_sha512: crypto +password: crypto normal +efiemu: gcry_crc crypto cpuid acpi +fshelp: +sleep_test: functional_test datetime +iorw: extcmd +xnu: macho bitmap_scale random verifiers extcmd video bitmap boot relocator efiemu mmap +mmap: boot +exfctest: functional_test +zfsinfo: zfs +ldm: part_gpt diskfilter part_msdos +cmostest: +eval: normal +part_dvh: +blocklist: +ext2: fshelp +net: priority_queue bufio datetime boot +drivemap: extcmd boot mmap +part_acorn: +videoinfo: video +btrfs: zstd lzopio raid6rec gzio +lsmmap: +strtoull_test: functional_test +bitmap: +vbe: video video_fb +ntfs: fshelp +multiboot: net linux vbe video boot relocator mmap lsapm +gcry_crc: crypto +png: bufio bitmap +jpeg: bufio bitmap +macbless: disk +div_test: functional_test div +regexp: extcmd normal +parttool: normal +usbserial_pl2303: serial usb usbserial_common +cpio: archelp +gcry_rmd160: crypto +fat: fshelp +ufs1_be: +truecrypt: video boot relocator gzio mmap +archelp: +ntldr: chain boot video relocator +http: net +zfs: gzio +raid6rec: diskfilter +minix2: +mda_text: +lsacpi: extcmd acpi +datehook: datetime normal +loadenv: disk extcmd +bitmap_scale: bitmap +probe: extcmd +minix3: +tar: archelp +hfs: fshelp +procfs: archelp +boot: +keylayouts: +progress: normal +kernel: +usbtest: usb +relocator: mmap +acpi: extcmd mmap +tga: bufio bitmap +reboot: relocator +serial: extcmd terminfo +zfscrypt: crypto pbkdf2 extcmd zfs gcry_sha1 gcry_rijndael +dm_nv: diskfilter +cmp_test: functional_test +luks: cryptodisk crypto pbkdf2 +font: bufio video +raid5rec: diskfilter +crc64: crypto +datetime: +ctz_test: functional_test +video: +pci: +cbmemc: cbtable normal terminfo +cmosdump: +hfsplus: fshelp +gcry_cast5: crypto +extcmd: +squash4: fshelp zstd lzopio zfs xzio gzio +part_plan: +minix_be: +gcry_whirlpool: crypto +pxe: net boot +gcry_tiger: crypto +search: search_fs_uuid search_fs_file extcmd search_label +lspci: extcmd pci +cbtime: cbtable +video_fb: +minix3_be: +trig: +msdospart: disk parttool +priority_queue: +gcry_twofish: crypto +part_dfly: +xnu_uuid_test: functional_test +diskfilter: +testload: +part_apple: +hexdump: extcmd +date: datetime normal +pbkdf2: crypto +gcry_sha256: crypto +ls: extcmd normal +usbserial_common: serial usb +ntfscomp: ntfs +lzopio: crypto +video_cirrus: pci video video_fb +hello: extcmd +scsi: +linux16: linux boot video relocator mmap +cat: extcmd +ahci: ata boot pci +pgp: crypto verifiers extcmd mpi gcry_sha1 +normal: terminal crypto verifiers bufio extcmd boot gettext +ufs1: +mdraid09: diskfilter +lvm: diskfilter +cbfs: archelp +chain: video boot relocator +ufs2: +time: +setpci: extcmd pci +gptsync: disk +freedos: chain boot video relocator +search_label: +setjmp: +multiboot2: linux net vbe boot video relocator mmap lsapm acpi +gcry_rfc2268: crypto +mdraid1x: diskfilter +mpi: crypto +legacycfg: linux crypto password gcry_md5 normal +play: +part_amiga: +minix: +echo: extcmd +gcry_serpent: crypto +gcry_md4: crypto +gcry_md5: crypto +part_msdos: +gcry_camellia: crypto +at_keyboard: keylayouts boot +all_video: vbe vga video_bochs video_cirrus diff --git a/INSTALL/grub/i386-pc/morse.mod b/INSTALL/grub/i386-pc/morse.mod new file mode 100644 index 0000000..b482e26 Binary files /dev/null and b/INSTALL/grub/i386-pc/morse.mod differ diff --git a/INSTALL/grub/i386-pc/mpi.mod b/INSTALL/grub/i386-pc/mpi.mod new file mode 100644 index 0000000..0f9ec71 Binary files /dev/null and b/INSTALL/grub/i386-pc/mpi.mod differ diff --git a/INSTALL/grub/i386-pc/msdospart.mod b/INSTALL/grub/i386-pc/msdospart.mod new file mode 100644 index 0000000..3c9d393 Binary files /dev/null and b/INSTALL/grub/i386-pc/msdospart.mod differ diff --git a/INSTALL/grub/i386-pc/mul_test.mod b/INSTALL/grub/i386-pc/mul_test.mod new file mode 100644 index 0000000..d86701a Binary files /dev/null and b/INSTALL/grub/i386-pc/mul_test.mod differ diff --git a/INSTALL/grub/i386-pc/multiboot.mod b/INSTALL/grub/i386-pc/multiboot.mod new file mode 100644 index 0000000..a327afe Binary files /dev/null and b/INSTALL/grub/i386-pc/multiboot.mod differ diff --git a/INSTALL/grub/i386-pc/multiboot2.mod b/INSTALL/grub/i386-pc/multiboot2.mod new file mode 100644 index 0000000..9f6f775 Binary files /dev/null and b/INSTALL/grub/i386-pc/multiboot2.mod differ diff --git a/INSTALL/grub/i386-pc/nativedisk.mod b/INSTALL/grub/i386-pc/nativedisk.mod new file mode 100644 index 0000000..f77fd13 Binary files /dev/null and b/INSTALL/grub/i386-pc/nativedisk.mod differ diff --git a/INSTALL/grub/i386-pc/net.mod b/INSTALL/grub/i386-pc/net.mod new file mode 100644 index 0000000..182fed5 Binary files /dev/null and b/INSTALL/grub/i386-pc/net.mod differ diff --git a/INSTALL/grub/i386-pc/newc.mod b/INSTALL/grub/i386-pc/newc.mod new file mode 100644 index 0000000..a693778 Binary files /dev/null and b/INSTALL/grub/i386-pc/newc.mod differ diff --git a/INSTALL/grub/i386-pc/nilfs2.mod b/INSTALL/grub/i386-pc/nilfs2.mod new file mode 100644 index 0000000..a1baea3 Binary files /dev/null and b/INSTALL/grub/i386-pc/nilfs2.mod differ diff --git a/INSTALL/grub/i386-pc/ntfscomp.mod b/INSTALL/grub/i386-pc/ntfscomp.mod new file mode 100644 index 0000000..5d0cbc7 Binary files /dev/null and b/INSTALL/grub/i386-pc/ntfscomp.mod differ diff --git a/INSTALL/grub/i386-pc/odc.mod b/INSTALL/grub/i386-pc/odc.mod new file mode 100644 index 0000000..36bda91 Binary files /dev/null and b/INSTALL/grub/i386-pc/odc.mod differ diff --git a/INSTALL/grub/i386-pc/offsetio.mod b/INSTALL/grub/i386-pc/offsetio.mod new file mode 100644 index 0000000..be57ff5 Binary files /dev/null and b/INSTALL/grub/i386-pc/offsetio.mod differ diff --git a/INSTALL/grub/i386-pc/ohci.mod b/INSTALL/grub/i386-pc/ohci.mod new file mode 100644 index 0000000..5206054 Binary files /dev/null and b/INSTALL/grub/i386-pc/ohci.mod differ diff --git a/INSTALL/grub/i386-pc/part_acorn.mod b/INSTALL/grub/i386-pc/part_acorn.mod new file mode 100644 index 0000000..3fe82b0 Binary files /dev/null and b/INSTALL/grub/i386-pc/part_acorn.mod differ diff --git a/INSTALL/grub/i386-pc/part_amiga.mod b/INSTALL/grub/i386-pc/part_amiga.mod new file mode 100644 index 0000000..e56fd4a Binary files /dev/null and b/INSTALL/grub/i386-pc/part_amiga.mod differ diff --git a/INSTALL/grub/i386-pc/part_apple.mod b/INSTALL/grub/i386-pc/part_apple.mod new file mode 100644 index 0000000..62400e3 Binary files /dev/null and b/INSTALL/grub/i386-pc/part_apple.mod differ diff --git a/INSTALL/grub/i386-pc/part_bsd.mod b/INSTALL/grub/i386-pc/part_bsd.mod new file mode 100644 index 0000000..37151c3 Binary files /dev/null and b/INSTALL/grub/i386-pc/part_bsd.mod differ diff --git a/INSTALL/grub/i386-pc/part_dfly.mod b/INSTALL/grub/i386-pc/part_dfly.mod new file mode 100644 index 0000000..cead265 Binary files /dev/null and b/INSTALL/grub/i386-pc/part_dfly.mod differ diff --git a/INSTALL/grub/i386-pc/part_dvh.mod b/INSTALL/grub/i386-pc/part_dvh.mod new file mode 100644 index 0000000..c812065 Binary files /dev/null and b/INSTALL/grub/i386-pc/part_dvh.mod differ diff --git a/INSTALL/grub/i386-pc/part_plan.mod b/INSTALL/grub/i386-pc/part_plan.mod new file mode 100644 index 0000000..7f448fd Binary files /dev/null and b/INSTALL/grub/i386-pc/part_plan.mod differ diff --git a/INSTALL/grub/i386-pc/part_sun.mod b/INSTALL/grub/i386-pc/part_sun.mod new file mode 100644 index 0000000..7e9abf5 Binary files /dev/null and b/INSTALL/grub/i386-pc/part_sun.mod differ diff --git a/INSTALL/grub/i386-pc/part_sunpc.mod b/INSTALL/grub/i386-pc/part_sunpc.mod new file mode 100644 index 0000000..a9246af Binary files /dev/null and b/INSTALL/grub/i386-pc/part_sunpc.mod differ diff --git a/INSTALL/grub/i386-pc/partmap.lst b/INSTALL/grub/i386-pc/partmap.lst new file mode 100644 index 0000000..761233a --- /dev/null +++ b/INSTALL/grub/i386-pc/partmap.lst @@ -0,0 +1,11 @@ +part_acorn +part_amiga +part_apple +part_bsd +part_dfly +part_dvh +part_gpt +part_msdos +part_plan +part_sun +part_sunpc diff --git a/INSTALL/grub/i386-pc/parttool.lst b/INSTALL/grub/i386-pc/parttool.lst new file mode 100644 index 0000000..68b4b5c --- /dev/null +++ b/INSTALL/grub/i386-pc/parttool.lst @@ -0,0 +1 @@ +msdos: msdospart diff --git a/INSTALL/grub/i386-pc/parttool.mod b/INSTALL/grub/i386-pc/parttool.mod new file mode 100644 index 0000000..44ea393 Binary files /dev/null and b/INSTALL/grub/i386-pc/parttool.mod differ diff --git a/INSTALL/grub/i386-pc/password.mod b/INSTALL/grub/i386-pc/password.mod new file mode 100644 index 0000000..783c329 Binary files /dev/null and b/INSTALL/grub/i386-pc/password.mod differ diff --git a/INSTALL/grub/i386-pc/pata.mod b/INSTALL/grub/i386-pc/pata.mod new file mode 100644 index 0000000..0f8a55e Binary files /dev/null and b/INSTALL/grub/i386-pc/pata.mod differ diff --git a/INSTALL/grub/i386-pc/pbkdf2.mod b/INSTALL/grub/i386-pc/pbkdf2.mod new file mode 100644 index 0000000..84f05ea Binary files /dev/null and b/INSTALL/grub/i386-pc/pbkdf2.mod differ diff --git a/INSTALL/grub/i386-pc/pbkdf2_test.mod b/INSTALL/grub/i386-pc/pbkdf2_test.mod new file mode 100644 index 0000000..a204632 Binary files /dev/null and b/INSTALL/grub/i386-pc/pbkdf2_test.mod differ diff --git a/INSTALL/grub/i386-pc/pcidump.mod b/INSTALL/grub/i386-pc/pcidump.mod new file mode 100644 index 0000000..66c1649 Binary files /dev/null and b/INSTALL/grub/i386-pc/pcidump.mod differ diff --git a/INSTALL/grub/i386-pc/pgp.mod b/INSTALL/grub/i386-pc/pgp.mod new file mode 100644 index 0000000..a487fdf Binary files /dev/null and b/INSTALL/grub/i386-pc/pgp.mod differ diff --git a/INSTALL/grub/i386-pc/plan9.mod b/INSTALL/grub/i386-pc/plan9.mod new file mode 100644 index 0000000..2fccdbc Binary files /dev/null and b/INSTALL/grub/i386-pc/plan9.mod differ diff --git a/INSTALL/grub/i386-pc/play.mod b/INSTALL/grub/i386-pc/play.mod new file mode 100644 index 0000000..9317d39 Binary files /dev/null and b/INSTALL/grub/i386-pc/play.mod differ diff --git a/INSTALL/grub/i386-pc/priority_queue.mod b/INSTALL/grub/i386-pc/priority_queue.mod new file mode 100644 index 0000000..4a1e167 Binary files /dev/null and b/INSTALL/grub/i386-pc/priority_queue.mod differ diff --git a/INSTALL/grub/i386-pc/probe.mod b/INSTALL/grub/i386-pc/probe.mod new file mode 100644 index 0000000..f880f85 Binary files /dev/null and b/INSTALL/grub/i386-pc/probe.mod differ diff --git a/INSTALL/grub/i386-pc/procfs.mod b/INSTALL/grub/i386-pc/procfs.mod new file mode 100644 index 0000000..b67ff46 Binary files /dev/null and b/INSTALL/grub/i386-pc/procfs.mod differ diff --git a/INSTALL/grub/i386-pc/progress.mod b/INSTALL/grub/i386-pc/progress.mod new file mode 100644 index 0000000..c93b242 Binary files /dev/null and b/INSTALL/grub/i386-pc/progress.mod differ diff --git a/INSTALL/grub/i386-pc/pxe.mod b/INSTALL/grub/i386-pc/pxe.mod new file mode 100644 index 0000000..1795ffd Binary files /dev/null and b/INSTALL/grub/i386-pc/pxe.mod differ diff --git a/INSTALL/grub/i386-pc/pxechain.mod b/INSTALL/grub/i386-pc/pxechain.mod new file mode 100644 index 0000000..627626e Binary files /dev/null and b/INSTALL/grub/i386-pc/pxechain.mod differ diff --git a/INSTALL/grub/i386-pc/raid5rec.mod b/INSTALL/grub/i386-pc/raid5rec.mod new file mode 100644 index 0000000..c31877f Binary files /dev/null and b/INSTALL/grub/i386-pc/raid5rec.mod differ diff --git a/INSTALL/grub/i386-pc/raid6rec.mod b/INSTALL/grub/i386-pc/raid6rec.mod new file mode 100644 index 0000000..f16634f Binary files /dev/null and b/INSTALL/grub/i386-pc/raid6rec.mod differ diff --git a/INSTALL/grub/i386-pc/random.mod b/INSTALL/grub/i386-pc/random.mod new file mode 100644 index 0000000..e15beb7 Binary files /dev/null and b/INSTALL/grub/i386-pc/random.mod differ diff --git a/INSTALL/grub/i386-pc/rdmsr.mod b/INSTALL/grub/i386-pc/rdmsr.mod new file mode 100644 index 0000000..02db116 Binary files /dev/null and b/INSTALL/grub/i386-pc/rdmsr.mod differ diff --git a/INSTALL/grub/i386-pc/regexp.mod b/INSTALL/grub/i386-pc/regexp.mod new file mode 100644 index 0000000..dba574a Binary files /dev/null and b/INSTALL/grub/i386-pc/regexp.mod differ diff --git a/INSTALL/grub/i386-pc/reiserfs.mod b/INSTALL/grub/i386-pc/reiserfs.mod new file mode 100644 index 0000000..853fe50 Binary files /dev/null and b/INSTALL/grub/i386-pc/reiserfs.mod differ diff --git a/INSTALL/grub/i386-pc/relocator.mod b/INSTALL/grub/i386-pc/relocator.mod new file mode 100644 index 0000000..3f1ebdc Binary files /dev/null and b/INSTALL/grub/i386-pc/relocator.mod differ diff --git a/INSTALL/grub/i386-pc/romfs.mod b/INSTALL/grub/i386-pc/romfs.mod new file mode 100644 index 0000000..e154ab9 Binary files /dev/null and b/INSTALL/grub/i386-pc/romfs.mod differ diff --git a/INSTALL/grub/i386-pc/scsi.mod b/INSTALL/grub/i386-pc/scsi.mod new file mode 100644 index 0000000..e764bcd Binary files /dev/null and b/INSTALL/grub/i386-pc/scsi.mod differ diff --git a/INSTALL/grub/i386-pc/search_fs_file.mod b/INSTALL/grub/i386-pc/search_fs_file.mod new file mode 100644 index 0000000..bdd7b4a Binary files /dev/null and b/INSTALL/grub/i386-pc/search_fs_file.mod differ diff --git a/INSTALL/grub/i386-pc/search_fs_uuid.mod b/INSTALL/grub/i386-pc/search_fs_uuid.mod new file mode 100644 index 0000000..d1ad5d3 Binary files /dev/null and b/INSTALL/grub/i386-pc/search_fs_uuid.mod differ diff --git a/INSTALL/grub/i386-pc/search_label.mod b/INSTALL/grub/i386-pc/search_label.mod new file mode 100644 index 0000000..4f7361e Binary files /dev/null and b/INSTALL/grub/i386-pc/search_label.mod differ diff --git a/INSTALL/grub/i386-pc/sendkey.mod b/INSTALL/grub/i386-pc/sendkey.mod new file mode 100644 index 0000000..d8605d6 Binary files /dev/null and b/INSTALL/grub/i386-pc/sendkey.mod differ diff --git a/INSTALL/grub/i386-pc/serial.mod b/INSTALL/grub/i386-pc/serial.mod new file mode 100644 index 0000000..521e28e Binary files /dev/null and b/INSTALL/grub/i386-pc/serial.mod differ diff --git a/INSTALL/grub/i386-pc/setjmp.mod b/INSTALL/grub/i386-pc/setjmp.mod new file mode 100644 index 0000000..2d35023 Binary files /dev/null and b/INSTALL/grub/i386-pc/setjmp.mod differ diff --git a/INSTALL/grub/i386-pc/setjmp_test.mod b/INSTALL/grub/i386-pc/setjmp_test.mod new file mode 100644 index 0000000..b337f7b Binary files /dev/null and b/INSTALL/grub/i386-pc/setjmp_test.mod differ diff --git a/INSTALL/grub/i386-pc/setkey.mod b/INSTALL/grub/i386-pc/setkey.mod new file mode 100644 index 0000000..e1c55a0 Binary files /dev/null and b/INSTALL/grub/i386-pc/setkey.mod differ diff --git a/INSTALL/grub/i386-pc/setpci.mod b/INSTALL/grub/i386-pc/setpci.mod new file mode 100644 index 0000000..f0b84d9 Binary files /dev/null and b/INSTALL/grub/i386-pc/setpci.mod differ diff --git a/INSTALL/grub/i386-pc/sfs.mod b/INSTALL/grub/i386-pc/sfs.mod new file mode 100644 index 0000000..86240a7 Binary files /dev/null and b/INSTALL/grub/i386-pc/sfs.mod differ diff --git a/INSTALL/grub/i386-pc/shift_test.mod b/INSTALL/grub/i386-pc/shift_test.mod new file mode 100644 index 0000000..8236137 Binary files /dev/null and b/INSTALL/grub/i386-pc/shift_test.mod differ diff --git a/INSTALL/grub/i386-pc/signature_test.mod b/INSTALL/grub/i386-pc/signature_test.mod new file mode 100644 index 0000000..62c1e53 Binary files /dev/null and b/INSTALL/grub/i386-pc/signature_test.mod differ diff --git a/INSTALL/grub/i386-pc/sleep_test.mod b/INSTALL/grub/i386-pc/sleep_test.mod new file mode 100644 index 0000000..78d6648 Binary files /dev/null and b/INSTALL/grub/i386-pc/sleep_test.mod differ diff --git a/INSTALL/grub/i386-pc/smbios.mod b/INSTALL/grub/i386-pc/smbios.mod new file mode 100644 index 0000000..bbd6f8e Binary files /dev/null and b/INSTALL/grub/i386-pc/smbios.mod differ diff --git a/INSTALL/grub/i386-pc/spkmodem.mod b/INSTALL/grub/i386-pc/spkmodem.mod new file mode 100644 index 0000000..c5e06b5 Binary files /dev/null and b/INSTALL/grub/i386-pc/spkmodem.mod differ diff --git a/INSTALL/grub/i386-pc/strtoull_test.mod b/INSTALL/grub/i386-pc/strtoull_test.mod new file mode 100644 index 0000000..38de07e Binary files /dev/null and b/INSTALL/grub/i386-pc/strtoull_test.mod differ diff --git a/INSTALL/grub/i386-pc/syslinuxcfg.mod b/INSTALL/grub/i386-pc/syslinuxcfg.mod new file mode 100644 index 0000000..4369cbe Binary files /dev/null and b/INSTALL/grub/i386-pc/syslinuxcfg.mod differ diff --git a/INSTALL/grub/i386-pc/terminal.lst b/INSTALL/grub/i386-pc/terminal.lst new file mode 100644 index 0000000..2cb224c --- /dev/null +++ b/INSTALL/grub/i386-pc/terminal.lst @@ -0,0 +1,11 @@ +iat_keyboard: at_keyboard +iserial: serial +iserial_*: serial +oaudio: morse +ocbmemc: cbmemc +ogfxterm: gfxterm +omda_text: mda_text +oserial: serial +oserial_*: serial +ospkmodem: spkmodem +ovga_text: vga_text diff --git a/INSTALL/grub/i386-pc/terminfo.mod b/INSTALL/grub/i386-pc/terminfo.mod new file mode 100644 index 0000000..a925b17 Binary files /dev/null and b/INSTALL/grub/i386-pc/terminfo.mod differ diff --git a/INSTALL/grub/i386-pc/test_blockarg.mod b/INSTALL/grub/i386-pc/test_blockarg.mod new file mode 100644 index 0000000..dde95fc Binary files /dev/null and b/INSTALL/grub/i386-pc/test_blockarg.mod differ diff --git a/INSTALL/grub/i386-pc/testload.mod b/INSTALL/grub/i386-pc/testload.mod new file mode 100644 index 0000000..27965de Binary files /dev/null and b/INSTALL/grub/i386-pc/testload.mod differ diff --git a/INSTALL/grub/i386-pc/testspeed.mod b/INSTALL/grub/i386-pc/testspeed.mod new file mode 100644 index 0000000..aa33184 Binary files /dev/null and b/INSTALL/grub/i386-pc/testspeed.mod differ diff --git a/INSTALL/grub/i386-pc/tga.mod b/INSTALL/grub/i386-pc/tga.mod new file mode 100644 index 0000000..9b333d7 Binary files /dev/null and b/INSTALL/grub/i386-pc/tga.mod differ diff --git a/INSTALL/grub/i386-pc/time.mod b/INSTALL/grub/i386-pc/time.mod new file mode 100644 index 0000000..04d482d Binary files /dev/null and b/INSTALL/grub/i386-pc/time.mod differ diff --git a/INSTALL/grub/i386-pc/truecrypt.mod b/INSTALL/grub/i386-pc/truecrypt.mod new file mode 100644 index 0000000..6730bcd Binary files /dev/null and b/INSTALL/grub/i386-pc/truecrypt.mod differ diff --git a/INSTALL/grub/i386-pc/ufs1.mod b/INSTALL/grub/i386-pc/ufs1.mod new file mode 100644 index 0000000..e2e7f9a Binary files /dev/null and b/INSTALL/grub/i386-pc/ufs1.mod differ diff --git a/INSTALL/grub/i386-pc/ufs1_be.mod b/INSTALL/grub/i386-pc/ufs1_be.mod new file mode 100644 index 0000000..f615f3c Binary files /dev/null and b/INSTALL/grub/i386-pc/ufs1_be.mod differ diff --git a/INSTALL/grub/i386-pc/ufs2.mod b/INSTALL/grub/i386-pc/ufs2.mod new file mode 100644 index 0000000..f1b01d7 Binary files /dev/null and b/INSTALL/grub/i386-pc/ufs2.mod differ diff --git a/INSTALL/grub/i386-pc/uhci.mod b/INSTALL/grub/i386-pc/uhci.mod new file mode 100644 index 0000000..0e71428 Binary files /dev/null and b/INSTALL/grub/i386-pc/uhci.mod differ diff --git a/INSTALL/grub/i386-pc/usb.mod b/INSTALL/grub/i386-pc/usb.mod new file mode 100644 index 0000000..3bf851a Binary files /dev/null and b/INSTALL/grub/i386-pc/usb.mod differ diff --git a/INSTALL/grub/i386-pc/usbms.mod b/INSTALL/grub/i386-pc/usbms.mod new file mode 100644 index 0000000..3c41b5c Binary files /dev/null and b/INSTALL/grub/i386-pc/usbms.mod differ diff --git a/INSTALL/grub/i386-pc/usbserial_common.mod b/INSTALL/grub/i386-pc/usbserial_common.mod new file mode 100644 index 0000000..25d8b0a Binary files /dev/null and b/INSTALL/grub/i386-pc/usbserial_common.mod differ diff --git a/INSTALL/grub/i386-pc/usbserial_ftdi.mod b/INSTALL/grub/i386-pc/usbserial_ftdi.mod new file mode 100644 index 0000000..41eac15 Binary files /dev/null and b/INSTALL/grub/i386-pc/usbserial_ftdi.mod differ diff --git a/INSTALL/grub/i386-pc/usbserial_pl2303.mod b/INSTALL/grub/i386-pc/usbserial_pl2303.mod new file mode 100644 index 0000000..4dfbf9a Binary files /dev/null and b/INSTALL/grub/i386-pc/usbserial_pl2303.mod differ diff --git a/INSTALL/grub/i386-pc/usbserial_usbdebug.mod b/INSTALL/grub/i386-pc/usbserial_usbdebug.mod new file mode 100644 index 0000000..e8f3c41 Binary files /dev/null and b/INSTALL/grub/i386-pc/usbserial_usbdebug.mod differ diff --git a/INSTALL/grub/i386-pc/usbtest.mod b/INSTALL/grub/i386-pc/usbtest.mod new file mode 100644 index 0000000..5c3a7fc Binary files /dev/null and b/INSTALL/grub/i386-pc/usbtest.mod differ diff --git a/INSTALL/grub/i386-pc/verifiers.mod b/INSTALL/grub/i386-pc/verifiers.mod new file mode 100644 index 0000000..c2dd207 Binary files /dev/null and b/INSTALL/grub/i386-pc/verifiers.mod differ diff --git a/INSTALL/grub/i386-pc/video.lst b/INSTALL/grub/i386-pc/video.lst new file mode 100644 index 0000000..6ca853e --- /dev/null +++ b/INSTALL/grub/i386-pc/video.lst @@ -0,0 +1,4 @@ +vbe +vga +video_bochs +video_cirrus diff --git a/INSTALL/grub/i386-pc/video_fb.mod b/INSTALL/grub/i386-pc/video_fb.mod new file mode 100644 index 0000000..4137d02 Binary files /dev/null and b/INSTALL/grub/i386-pc/video_fb.mod differ diff --git a/INSTALL/grub/i386-pc/wrmsr.mod b/INSTALL/grub/i386-pc/wrmsr.mod new file mode 100644 index 0000000..1d7d257 Binary files /dev/null and b/INSTALL/grub/i386-pc/wrmsr.mod differ diff --git a/INSTALL/grub/i386-pc/xnu.mod b/INSTALL/grub/i386-pc/xnu.mod new file mode 100644 index 0000000..6aa0590 Binary files /dev/null and b/INSTALL/grub/i386-pc/xnu.mod differ diff --git a/INSTALL/grub/i386-pc/xnu_uuid.mod b/INSTALL/grub/i386-pc/xnu_uuid.mod new file mode 100644 index 0000000..499f0b5 Binary files /dev/null and b/INSTALL/grub/i386-pc/xnu_uuid.mod differ diff --git a/INSTALL/grub/i386-pc/xnu_uuid_test.mod b/INSTALL/grub/i386-pc/xnu_uuid_test.mod new file mode 100644 index 0000000..a853235 Binary files /dev/null and b/INSTALL/grub/i386-pc/xnu_uuid_test.mod differ diff --git a/INSTALL/grub/i386-pc/zfs.mod b/INSTALL/grub/i386-pc/zfs.mod new file mode 100644 index 0000000..9f13caf Binary files /dev/null and b/INSTALL/grub/i386-pc/zfs.mod differ diff --git a/INSTALL/grub/i386-pc/zfscrypt.mod b/INSTALL/grub/i386-pc/zfscrypt.mod new file mode 100644 index 0000000..e684ccd Binary files /dev/null and b/INSTALL/grub/i386-pc/zfscrypt.mod differ diff --git a/INSTALL/grub/i386-pc/zfsinfo.mod b/INSTALL/grub/i386-pc/zfsinfo.mod new file mode 100644 index 0000000..68844f4 Binary files /dev/null and b/INSTALL/grub/i386-pc/zfsinfo.mod differ diff --git a/INSTALL/grub/i386-pc/zstd.mod b/INSTALL/grub/i386-pc/zstd.mod new file mode 100644 index 0000000..721fe20 Binary files /dev/null and b/INSTALL/grub/i386-pc/zstd.mod differ diff --git a/INSTALL/grub/keyboard.cfg b/INSTALL/grub/keyboard.cfg new file mode 100644 index 0000000..41caba9 --- /dev/null +++ b/INSTALL/grub/keyboard.cfg @@ -0,0 +1,62 @@ +submenu "$VTLANG_KEYBRD_LAYOUT" --class=debug_krdlayout --class=F5tool { + menuentry QWERTY_USA --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout QWERTY_USA + } + menuentry AZERTY --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout AZERTY + } + menuentry CZECH_QWERTY --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout CZECH_QWERTY + } + menuentry CZECH_QWERTZ --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout CZECH_QWERTZ + } + menuentry DANISH --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout DANISH + } + menuentry DVORAK_USA --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout DVORAK_USA + } + menuentry FRENCH --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout FRENCH + } + menuentry GERMAN --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout GERMAN + } + menuentry ITALIANO --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout ITALIANO + } + menuentry JAPAN_106 --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout JAPAN_106 + } + menuentry LATIN_USA --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout LATIN_USA + } + menuentry PORTU_BRAZIL --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout PORTU_BRAZIL + } + menuentry QWERTY_UK --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout QWERTY_UK + } + menuentry QWERTZ --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout QWERTZ + } + menuentry QWERTZ_HUN --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout QWERTZ_HUN + } + menuentry QWERTZ_SLOV_CROAT --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout QWERTZ_SLOV_CROAT + } + menuentry SPANISH --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout SPANISH + } + menuentry SWEDISH --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout SWEDISH + } + menuentry TURKISH_Q --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout TURKISH_Q + } + menuentry VIETNAMESE --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout VIETNAMESE + } +} diff --git a/INSTALL/grub/localboot.cfg b/INSTALL/grub/localboot.cfg new file mode 100644 index 0000000..e746f1a --- /dev/null +++ b/INSTALL/grub/localboot.cfg @@ -0,0 +1,222 @@ + +if [ "$grub_platform" = "pc" ]; then + menuentry "$VTLANG_LB_SBOOT_WINDOWS" --class=boot_windows --class=F4boot { + + set partid=3 + while [ $partid -le 128 ]; do + if vt_check_part_exist $partid; then + for bt in bootmgr BOOTMGR Bootmgr BootMGR; do + if [ -f ($vtoydev,$partid)/$bt ]; then + set root=($vtoydev,$partid) + ntldr /$bt + boot + fi + done + else + break + fi + vt_incr partid 1 + done + + if search -n -s -f /Boot/BCD; then + for bt in bootmgr BOOTMGR Bootmgr BootMGR; do + if [ -f /$bt ]; then + if regexp '^hd0' $root; then + ntldr /$bt + else + drivemap -s hd0 $root + ntldr /$bt + fi + break + fi + done + elif search -n -s -f /NTDETECT.COM; then + drivemap -s hd0 $root + ntldr /ntldr + else + echo "Windows NOT found ..." + fi + } + + menuentry "$VTLANG_LB_SBOOT_G4D" --class=boot_g4d --class=F4boot { + if search -n -s -f /grldr; then + ntldr /grldr + else + echo "Grub4dos NOT found ..." + fi + } + + menuentry "$VTLANG_LB_SBOOT_HDD1" --class=boot_disk --class=F4boot { + set root=(hd0,1) + chainloader +1 + boot + } + + menuentry "$VTLANG_LB_SBOOT_HDD2" --class=boot_disk --class=F4boot { + set root=(hd1,1) + chainloader +1 + boot + } + + menuentry "$VTLANG_LB_SBOOT_HDD3" --class=boot_disk --class=F4boot { + set root=(hd2,1) + chainloader +1 + boot + } + +else + + menuentry "$VTLANG_LB_SBOOT_WINDOWS" --class=boot_windows --class=F4boot { + + set partid=3 + while [ $partid -le 128 ]; do + if vt_check_part_exist $partid; then + if [ -f ($vtoydev,$partid)/EFI/Microsoft/Boot/bootmgfw.efi ]; then + set root=($vtoydev,$partid) + terminal_output console + chainloader /EFI/Microsoft/Boot/bootmgfw.efi + boot + elif [ -f ($vtoydev,$partid)/efi/Microsoft/Boot/bootmgfw.efi ]; then + set root=($vtoydev,$partid) + terminal_output console + chainloader /efi/Microsoft/Boot/bootmgfw.efi + boot + elif [ -f ($vtoydev,$partid)/VTEFI/Microsoft/Boot/bootmgfw.efi ]; then + set root=($vtoydev,$partid) + terminal_output console + chainloader /VTEFI/Microsoft/Boot/bootmgfw.efi + boot + fi + else + break + fi + vt_incr partid 1 + done + + if search -n -s -f /EFI/Microsoft/Boot/bootmgfw.efi; then + terminal_output console + chainloader /EFI/Microsoft/Boot/bootmgfw.efi + boot + elif search -n -s -f /efi/Microsoft/Boot/bootmgfw.efi; then + terminal_output console + chainloader /efi/Microsoft/Boot/bootmgfw.efi + boot + else + echo "Windows NOT found ..." + fi + } + + if [ "$grub_cpu" = "i386" ]; then + menuentry "$VTLANG_LB_SBOOT_IA32EFI" --class=boot_uefi --class=F4boot { + set VTOY_SEARCH_NO_VTOYEFI=1 + if search -n -s -f /efi/boot/bootia32.efi; then + unset VTOY_SEARCH_NO_VTOYEFI + terminal_output console + chainloader /efi/boot/bootia32.efi + boot + elif search -n -s -f /vtefi/boot/bootia32.efi; then + unset VTOY_SEARCH_NO_VTOYEFI + terminal_output console + chainloader /vtefi/boot/bootia32.efi + boot + else + unset VTOY_SEARCH_NO_VTOYEFI + echo "BOOTIA32.EFI NOT found ..." + fi + } + + menuentry "$VTLANG_LB_SBOOT_XORBOOT" --class=boot_xorboot --class=F4boot { + set VTOY_SEARCH_NO_VTOYEFI=1 + if search -n -s -f /efi/xorboot/xorboot32.xor; then + unset VTOY_SEARCH_NO_VTOYEFI + terminal_output console + if [ -f /efi/xorboot/bootia32.efi ]; then + chainloader /efi/xorboot/bootia32.efi + elif [ -f /efi/xorboot/xorboot.efi ]; then + chainloader /efi/xorboot/xorboot.efi + fi + boot + elif search -n -s -f /vtefi/xorboot/xorboot32.xor; then + unset VTOY_SEARCH_NO_VTOYEFI + terminal_output console + if [ -f /vtefi/xorboot/bootia32.efi ]; then + chainloader /vtefi/xorboot/bootia32.efi + elif [ -f /vtefi/xorboot/xorboot.efi ]; then + chainloader /vtefi/xorboot/xorboot.efi + fi + boot + else + unset VTOY_SEARCH_NO_VTOYEFI + echo "xorboot NOT found ..." + fi + } + elif [ "$grub_cpu" = "arm64" ]; then + menuentry "$VTLANG_LB_SBOOT_AA64EFI" --class=boot_uefi --class=F4boot { + set VTOY_SEARCH_NO_VTOYEFI=1 + if search -n -s -f /efi/boot/bootaa64.efi; then + unset VTOY_SEARCH_NO_VTOYEFI + terminal_output console + chainloader /efi/boot/bootaa64.efi + boot + elif search -n -s -f /vtefi/boot/bootaa64.efi; then + unset VTOY_SEARCH_NO_VTOYEFI + terminal_output console + chainloader /vtefi/boot/bootaa64.efi + boot + else + unset VTOY_SEARCH_NO_VTOYEFI + echo "BOOTAA64.EFI NOT found ..." + fi + } + else + menuentry "$VTLANG_LB_SBOOT_X64EFI" --class=boot_uefi --class=F4boot { + set VTOY_SEARCH_NO_VTOYEFI=1 + if search -n -s -f /efi/boot/bootx64.efi; then + unset VTOY_SEARCH_NO_VTOYEFI + terminal_output console + chainloader /efi/boot/bootx64.efi + boot + elif search -n -s -f /vtefi/boot/bootx64.efi; then + unset VTOY_SEARCH_NO_VTOYEFI + terminal_output console + chainloader /vtefi/boot/bootx64.efi + boot + else + unset VTOY_SEARCH_NO_VTOYEFI + echo "BOOTX64.EFI NOT found ..." + fi + } + + menuentry "$VTLANG_LB_SBOOT_XORBOOT" --class=boot_xorboot --class=F4boot { + set VTOY_SEARCH_NO_VTOYEFI=1 + if search -n -s -f /efi/xorboot/xorboot.xor; then + unset VTOY_SEARCH_NO_VTOYEFI + terminal_output console + if [ -f /efi/xorboot/bootx64.efi ]; then + chainloader /efi/xorboot/bootx64.efi + elif [ -f /efi/xorboot/xorboot.efi ]; then + chainloader /efi/xorboot/xorboot.efi + fi + boot + elif search -n -s -f /vtefi/xorboot/xorboot.xor; then + unset VTOY_SEARCH_NO_VTOYEFI + terminal_output console + if [ -f /vtefi/xorboot/bootx64.efi ]; then + chainloader /vtefi/xorboot/bootx64.efi + elif [ -f /vtefi/xorboot/xorboot.efi ]; then + chainloader /vtefi/xorboot/xorboot.efi + fi + boot + else + unset VTOY_SEARCH_NO_VTOYEFI + echo "xorboot NOT found ..." + fi + } + fi + + +fi + +menuentry "$VTLANG_RETURN_PREVIOUS" --class=vtoyret VTOY_RET { + echo "Return ..." +} diff --git a/INSTALL/grub/menu/ar_AR.json b/INSTALL/grub/menu/ar_AR.json new file mode 100644 index 0000000..a1831cf --- /dev/null +++ b/INSTALL/grub/menu/ar_AR.json @@ -0,0 +1,98 @@ +{ + "VTLANG_LANGUAGE_NAME": "Arabic (العربية)", + + "VTLANG_STR_HOTKEY_LIST": "L: لغة F1: مساعدة F2: تصفح F3: عرض لائحي F4: إقلاع محلي F5: أدوات F6: عوده", + "VTLANG_STR_HOTKEY_TREE": "L: لغة F1: مساعدة F2: تصفح F3: عرض شجري F4: إقلاع محلي F5: أدوات F6: عوده", + "VTLANG_RETURN_PREVIOUS": "عودة إلى القائمة السابقة [Esc]", + "VTLANG_RETURN_PRV_NOESC": "عودة إلى القائمة السابقة", + + "VTLANG_MENU_LANG": "اختيار اللغة في القائمة", + + "VTLANG_LB_SBOOT_WINDOWS": "البحث والإقلاع على Windows", + "VTLANG_LB_SBOOT_G4D": "البحث والإقلاع على Grub4dos", + "VTLANG_LB_SBOOT_HDD1": "الإقلاع على القرص المحلي الأول", + "VTLANG_LB_SBOOT_HDD2": "الإقلاع على القرص المحلي الثاني", + "VTLANG_LB_SBOOT_HDD3": "الإقلاع على القرص المحلي الثالث", + "VTLANG_LB_SBOOT_X64EFI": "البحث والإقلاع على BOOTX64.EFI", + "VTLANG_LB_SBOOT_IA32EFI": "البحث والإقلاع على BOOTIA32.EFI", + "VTLANG_LB_SBOOT_AA64EFI": "البحث والإقلاع على BOOTAA64.EFI", + "VTLANG_LB_SBOOT_XORBOOT": "البحث والإقلاع على xorboot", + + "VTLANG_FILE_CHKSUM": "تدقيق المجموع للملف", + "VTLANG_CHKSUM_MD5_CALC": "احسب md5sum", + "VTLANG_CHKSUM_SHA1_CALC": "احسب sha1sum", + "VTLANG_CHKSUM_SHA256_CALC": "احسب sha256sum", + "VTLANG_CHKSUM_SHA512_CALC": "احسب sha512sum", + "VTLANG_CHKSUM_MD5_CALC_CHK": "احسب وتحقق md5sum", + "VTLANG_CHKSUM_SHA1_CALC_CHK": "احسب وتحقق sha1sum", + "VTLANG_CHKSUM_SHA256_CALC_CHK": "احسب وتحقق sha256sum", + "VTLANG_CHKSUM_SHA512_CALC_CHK": "احسب وتحقق sha512sum", + + "VTLANG_POWER": "الطاقة", + "VTLANG_POWER_REBOOT": "إعادة التشغيل", + "VTLANG_POWER_HALT": "إيقاف", + "VTLANG_POWER_BOOT_EFIFW": "إعادة التشغيل إلى إعداد EFI", + + "VTLANG_KEYBRD_LAYOUT": "تخطيطات لوحة المفاتيح", + "VTLANG_HWINFO": "معلومات حول العتاد", + + "VTLANG_RESOLUTION_CFG": "تكوين الدقة", + "VTLANG_SCREEN_MODE": "وضع عرض الشاشة", + "VTLANG_SCREEN_TEXT_MODE": "فرض تحديد وضع النص", + "VTLANG_SCREEN_GUI_MODE": "فرض تحديد وضع الرسومات", + + "VTLANG_THEME_SELECT": "اختر السمة", + + "VTLANG_UEFI_UTIL": "أدوات Ventoy UEFI المساعدة", + "VTLANG_UTIL_SHOW_EFI_DRV": "عرض برامج تشغيل EFI", + "VTLANG_UTIL_FIX_BLINIT_FAIL": "إصلاح فشل تهيئة Windows BlinitializeLibrary", + + "VTLANG_JSON_CHK_JSON": "التحقق من تكوين json للبرنامج الإضافي (ventoy.json)", + "VTLANG_JSON_CHK_CONTROL": "التحقق من تكوين برنامج الإضافي العام للتحكم", + "VTLANG_JSON_CHK_THEME": "التحقق من تكوين برنامج الإضافي الخاص بالسمة", + "VTLANG_JSON_CHK_AUTOINS": "التحقق من تكوين برنامج الإضافي للتثبيت التلقائي", + "VTLANG_JSON_CHK_PERSIST": "التحقق من تكوين برنامج الإضافي المستمر", + "VTLANG_JSON_CHK_MENU_ALIAS": "التحقق من تكوين برنامج الإضافي الخاص بالقائمة المستعارة", + "VTLANG_JSON_CHK_MENU_TIP": "التحقق من تكوين برنامج الإضافي الخاص بتلميح القائمة", + "VTLANG_JSON_CHK_MENU_CLASS": "التحقق من تكوين برنامج الإضافي الخاص بفئة القائمة", + "VTLANG_JSON_CHK_INJECTION": "التحقق من تكوين برنامج الإضافي الخاص بالتدخل", + "VTLANG_JSON_CHK_AUTO_MEMDISK": "التحقق من تكوين برنامج الإضافي الخاص بالتثبيت التلقائي لـ memdisk", + "VTLANG_JSON_CHK_IMG_LIST": "التحقق من تكوين برنامج الإضافي الخاص بقائمة الصور", + "VTLANG_JSON_CHK_IMG_BLIST": "التحقق من تكوين برنامج الإضافي الخاص بقائمة سوداء للصور", + "VTLANG_JSON_CHK_CONF_REPLACE": "التحقق من تكوين برنامج الإضافي الخاص باستبدال ملف التكوين للإقلاع", + "VTLANG_JSON_CHK_DUD": "التحقق من تكوين برنامج الإضافي الخاص بـ dud", + "VTLANG_JSON_CHK_PASSWORD": "التحقق من تكوين برنامج الإضافي الخاص بكلمة المرور", + + "VTLANG_NORMAL_MODE": "الإقلاع في الوضع العادي", + "VTLANG_WIMBOOT_MODE": "الإقلاع في وضع wimboot", + "VTLANG_GRUB2_MODE": "الإقلاع في وضع grub2", + "VTLANG_MEMDISK_MODE": "الإقلاع في وضع memdisk", + + "VTLANG_RET_TO_LISTVIEW": "العودة إلى ListView", + "VTLANG_RET_TO_TREEVIEW": "العودة إلى TreeView", + + "VTLANG_NO_AUTOINS_SCRIPT": "الإقلاع بدون قالب التثبيت التلقائي", + "VTLANG_AUTOINS_USE": "الإقلاع مع", + + "VTLANG_NO_PERSIST": "الإقلاع بدون الاستمرارية", + "VTLANG_PERSIST_USE": "الإقلاع مع", + + "VTLANG_BROWER_RETURN": "العودة", + + "VTLANG_ENTER_EXIT": "اضغط على مفتاح Enter للخروج", + "VTLANG_ENTER_REBOOT": "اضغط على مفتاح Enter لإعادة التشغيل", + "VTLANG_ENTER_CONTINUE": "اضغط على مفتاح Enter للمتابعة", + + "VTLANG_CTRL_TEMP_SET": "إعدادات التحكم المؤقتة", + "VTLANG_WIN11_BYPASS_CHECK": "تجاوز فحص CPU/TPM/SecureBoot عند تثبيت Windows 11", + "VTLANG_WIN11_BYPASS_NRO": "تجاوز متطلبات الحساب عبر الإنترنت عند تثبيت Windows 11", + "VTLANG_LINUX_REMOUNT": "ضم قسم Ventoy بعد إقلاع Linux", + "VTLANG_SECONDARY_BOOT_MENU": "اظهر قائمة الإقلاع الثانوية", + "VTLANG_WIN_UEFI_RES_LOCK": "Lock the resolution when UEFI boot Windows/WinPE", + "VTLANG_UEFI_RES_LOCK_NONE": "None", + "VTLANG_UEFI_RES_LOCK_MAX": "Highest", + "VTLANG_UEFI_RES_LOCK_1024_768": "Fixed 1024 x 768", + "VTLANG_UEFI_RES_LOCK_BE1024_768": "At least 1024 x 768", + + "MENU_STR_XXX": "" +} diff --git a/INSTALL/grub/menu/bn_BN.json b/INSTALL/grub/menu/bn_BN.json new file mode 100644 index 0000000..54d342a --- /dev/null +++ b/INSTALL/grub/menu/bn_BN.json @@ -0,0 +1,99 @@ +{ + "VTLANG_LANGUAGE_NAME": "Bengali (বাংলা)", + + "VTLANG_STR_HOTKEY_LIST": "L:ভাষা F1:সাহায্য F2:Browser F3:ListView F4:Localboot F5:Tools F6:ExMenu", + "VTLANG_STR_HOTKEY_TREE": "L:ভাষা F1:সাহায্য F2:Browser F3:TreeView F4:Localboot F5:Tools F6:ExMenu", + "VTLANG_RETURN_PREVIOUS": "পূর্ববর্তী মেনুতে ফিরে যান [Esc]", + "VTLANG_RETURN_PRV_NOESC": "পূর্ববর্তী মেনুতে ফিরে যান", + + "VTLANG_MENU_LANG": "মেনু ভাষা নির্বাচন করুন", + + "VTLANG_LB_SBOOT_WINDOWS": "Windows অনুসন্ধান করুন এবং বুট করুন", + "VTLANG_LB_SBOOT_G4D": "Grub4dos অনুসন্ধান করুন এবং বুট করুন", + "VTLANG_LB_SBOOT_HDD1": "১ম(1st) স্থানীয় ডিস্ক বুট করুন", + "VTLANG_LB_SBOOT_HDD2": "২য়(2nd) স্থানীয় ডিস্ক বুট করুন", + "VTLANG_LB_SBOOT_HDD3": "3য়(3rd) স্থানীয় ডিস্ক বুট করুন", + "VTLANG_LB_SBOOT_X64EFI": "BOOTX64.EFI অনুসন্ধান করুন এবং বুট করুন", + "VTLANG_LB_SBOOT_IA32EFI": "BOOTIA32.EFI অনুসন্ধান করুন এবং বুট করুন", + "VTLANG_LB_SBOOT_AA64EFI": "BOOTAA64.EFI অনুসন্ধান করুন এবং বুট করুন", + "VTLANG_LB_SBOOT_XORBOOT": "xorboot অনুসন্ধান করুন এবং বুট করুন", + + "VTLANG_FILE_CHKSUM": "ফাইল চেকসাম", + "VTLANG_CHKSUM_MD5_CALC": "md5sum গণনা করুন", + "VTLANG_CHKSUM_SHA1_CALC": "sha1sum গণনা করুন", + "VTLANG_CHKSUM_SHA256_CALC": "sha256sum গণনা করুন", + "VTLANG_CHKSUM_SHA512_CALC": "sha512sum গণনা করুন", + "VTLANG_CHKSUM_MD5_CALC_CHK": "গণনা করুন এবং md5sum চেক করুন", + "VTLANG_CHKSUM_SHA1_CALC_CHK": "গণনা করুন এবং sha1sum চেক করুন", + "VTLANG_CHKSUM_SHA256_CALC_CHK": "গণনা করুন এবং sha256sum চেক করুন", + "VTLANG_CHKSUM_SHA512_CALC_CHK": "গণনা করুন এবং sha512sum চেক করুন", + + "VTLANG_POWER": "পাওয়ার", + "VTLANG_POWER_REBOOT": "রিবুট", + "VTLANG_POWER_HALT": "হল্ট", + "VTLANG_POWER_BOOT_EFIFW": "EFI সেটআপে রিবুট করুন", + + "VTLANG_KEYBRD_LAYOUT": "কীবোর্ড লেআউট", + "VTLANG_HWINFO": "হার্ডওয়্যার তথ্য", + + "VTLANG_RESOLUTION_CFG": "রেজোলিউশন কনফিগারেশন", + "VTLANG_SCREEN_MODE": "Screen Display মোড", + "VTLANG_SCREEN_TEXT_MODE": "Force Text মোড", + "VTLANG_SCREEN_GUI_MODE": "Force Graphics মোড", + + "VTLANG_THEME_SELECT": "থিম নির্বাচন করুন", + + "VTLANG_UEFI_UTIL": "Ventoy UEFI ইউটিলিটিস", + "VTLANG_UTIL_SHOW_EFI_DRV": "EFI ড্রাইভার দেখান", + "VTLANG_UTIL_FIX_BLINIT_FAIL": "Windows BlinitializeLibrary ব্যর্থতার সমাধান করুন", + + "VTLANG_JSON_CHK_JSON": "প্লাগইন json কনফিগারেশন পরীক্ষা করুন (ventoy.json)", + "VTLANG_JSON_CHK_CONTROL": "গ্লোবাল কন্ট্রোল প্লাগইন কনফিগারেশন চেক করুন", + "VTLANG_JSON_CHK_THEME": "থিম প্লাগইন কনফিগারেশন পরীক্ষা করুন", + "VTLANG_JSON_CHK_AUTOINS": "অটো ইন্সটল প্লাগইন কনফিগারেশন চেক করুন", + "VTLANG_JSON_CHK_PERSIST": "persistence প্লাগইন কনফিগারেশন পরীক্ষা করুন", + "VTLANG_JSON_CHK_MENU_ALIAS": "menu alias প্লাগইন কনফিগারেশন পরীক্ষা করুন", + "VTLANG_JSON_CHK_MENU_TIP": "menu tip প্লাগইন কনফিগারেশন পরীক্ষা করুন", + "VTLANG_JSON_CHK_MENU_CLASS": "menu class প্লাগইন কনফিগারেশন পরীক্ষা করুন", + "VTLANG_JSON_CHK_INJECTION": "injection প্লাগইন কনফিগারেশন পরীক্ষা করুন", + "VTLANG_JSON_CHK_AUTO_MEMDISK": "auto memdisk প্লাগইন কনফিগারেশন পরীক্ষা করুন", + "VTLANG_JSON_CHK_IMG_LIST": "image list প্লাগইন কনফিগারেশন পরীক্ষা করুন", + "VTLANG_JSON_CHK_IMG_BLIST": "image blacklist প্লাগইন কনফিগারেশন পরীক্ষা করুন", + "VTLANG_JSON_CHK_CONF_REPLACE": "boot conf replace প্লাগইন কনফিগারেশন পরীক্ষা করুন", + "VTLANG_JSON_CHK_DUD": "dud প্লাগইন কনফিগারেশন পরীক্ষা করুন", + "VTLANG_JSON_CHK_PASSWORD": "password প্লাগইন কনফিগারেশন পরীক্ষা করুন", + + "VTLANG_NORMAL_MODE": "সাধারণ মোডে বুট করুন", + "VTLANG_WIMBOOT_MODE": "wimboot মোডে বুট করুন", + "VTLANG_GRUB2_MODE": "grub2 মোডে বুট করুন", + "VTLANG_MEMDISK_MODE": "memdisk মোডে বুট করুন", + + "VTLANG_RET_TO_LISTVIEW": "ListView-এ ফিরে যান", + "VTLANG_RET_TO_TREEVIEW": "TreeView-এ ফিরে যান", + + "VTLANG_NO_AUTOINS_SCRIPT": "auto install মোড বিনা বুট করুন", + "VTLANG_AUTOINS_USE": "দিয়ে বুট করুন", + + "VTLANG_NO_PERSIST": "persistence বিনা বুট করুন", + "VTLANG_PERSIST_USE": "দিয়ে বুট করুন", + + "VTLANG_BROWER_RETURN": "ফিরে", + + "VTLANG_ENTER_EXIT": "প্রস্থান করার জন্য এন্টার কী টিপুন", + "VTLANG_ENTER_REBOOT": "রিবুট করতে এন্টার কী টিপুন", + "VTLANG_ENTER_CONTINUE": "চালিয়ে যেতে এন্টার কী টিপুন", + + "VTLANG_CTRL_TEMP_SET": "অস্থায়ী নিয়ন্ত্রণ সেটিংস", + "VTLANG_WIN11_BYPASS_CHECK": "Windows 11 ইনস্টল করার সময় CPU/TPM/SecureBoot চেক বাইপাস করুন", + "VTLANG_WIN11_BYPASS_NRO": "Windows 11 ইনস্টল করার সময় অনলাইন অ্যাকাউন্টের প্রয়োজন বাইপাস করুন", + "VTLANG_LINUX_REMOUNT": "লিনাক্স বুটের পরে ভেন্টয় পার্টিশনটি মাউন্ট করুন", + "VTLANG_SECONDARY_BOOT_MENU": "গৌণ বুট মেনু দেখান", + "VTLANG_WIN_UEFI_RES_LOCK": "Lock the resolution when UEFI boot Windows/WinPE", + "VTLANG_UEFI_RES_LOCK_NONE": "None", + "VTLANG_UEFI_RES_LOCK_MAX": "Highest", + "VTLANG_UEFI_RES_LOCK_1024_768": "Fixed 1024 x 768", + "VTLANG_UEFI_RES_LOCK_BE1024_768": "At least 1024 x 768", + + + "MENU_STR_XXX": "" +} diff --git a/INSTALL/grub/menu/cs_CZ.json b/INSTALL/grub/menu/cs_CZ.json new file mode 100644 index 0000000..ab31ae0 --- /dev/null +++ b/INSTALL/grub/menu/cs_CZ.json @@ -0,0 +1,99 @@ +{ + "VTLANG_LANGUAGE_NAME": "Czech (Čeština)", + + "VTLANG_STR_HOTKEY_LIST": "L:Jazyk F1:Nápověda F2:Procházet F3:Seznam F4:Místní boot F5:Nástroje F6:Rozšířená nabídka", + "VTLANG_STR_HOTKEY_TREE": "L:Jazyk F1:Nápověda F2:Procházet F3:Strom F4:Místní boot F5:Nástroje F6:Rozšířená nabídka", + "VTLANG_RETURN_PREVIOUS": "Vrátit do předchozí nabídky [Esc]", + "VTLANG_RETURN_PRV_NOESC": "Vrátit do předchozí nabídky", + + "VTLANG_MENU_LANG": "Výběrt jazyka nabídel", + + "VTLANG_LB_SBOOT_WINDOWS": "Najít a spustit Windows", + "VTLANG_LB_SBOOT_G4D": "Najít a spustit Grub4dos", + "VTLANG_LB_SBOOT_HDD1": "Spustit 1. místní disk", + "VTLANG_LB_SBOOT_HDD2": "Spustit 2. místní disk", + "VTLANG_LB_SBOOT_HDD3": "Spustit 3. místní disk", + "VTLANG_LB_SBOOT_X64EFI": "Najít a spustit BOOTX64.EFI", + "VTLANG_LB_SBOOT_IA32EFI": "Najít a spustit BOOTIA32.EFI", + "VTLANG_LB_SBOOT_AA64EFI": "Najít a spustit BOOTAA64.EFI", + "VTLANG_LB_SBOOT_XORBOOT": "Najít a spustit xorboot", + + "VTLANG_FILE_CHKSUM": "Kontrolní součet souboru", + "VTLANG_CHKSUM_MD5_CALC": "Spočítat md5sum", + "VTLANG_CHKSUM_SHA1_CALC": "Spočítat sha1sum", + "VTLANG_CHKSUM_SHA256_CALC": "Spočítat sha256sum", + "VTLANG_CHKSUM_SHA512_CALC": "Spočítat sha512sum", + "VTLANG_CHKSUM_MD5_CALC_CHK": "Spočítat a ověřit md5sum", + "VTLANG_CHKSUM_SHA1_CALC_CHK": "Spočítat a ověřit sha1sum", + "VTLANG_CHKSUM_SHA256_CALC_CHK": "Spočítat a ověřit sha256sum", + "VTLANG_CHKSUM_SHA512_CALC_CHK": "Spočítat a ověřit sha512sum", + + "VTLANG_POWER": "Napájení", + "VTLANG_POWER_REBOOT": "Restartovat", + "VTLANG_POWER_HALT": "Vypnout", + "VTLANG_POWER_BOOT_EFIFW": "Restartovat do EFI nastavení", + + "VTLANG_KEYBRD_LAYOUT": "Rozložení klávesnice", + "VTLANG_HWINFO": "Informace o hardwaru", + + "VTLANG_RESOLUTION_CFG": "Nastavení rolišení", + "VTLANG_SCREEN_MODE": "Nastavení režimu zobrazení", + "VTLANG_SCREEN_TEXT_MODE": "Vynutit textový režim", + "VTLANG_SCREEN_GUI_MODE": "Vynutit grafický režim", + + "VTLANG_THEME_SELECT": "Výběr motivu", + + "VTLANG_UEFI_UTIL": "Ventoy UEFI nástroje", + "VTLANG_UTIL_SHOW_EFI_DRV": "Zobrazit EFI ovladače", + "VTLANG_UTIL_FIX_BLINIT_FAIL": "Opravit chybu Windows BlinitializeLibrary", + + "VTLANG_JSON_CHK_JSON": "Zkontrolovat json konfiguraci zásuvných modulů (ventoy.json)", + "VTLANG_JSON_CHK_CONTROL": "Zkontrolovat konfiguraci hlavního zásuvného modulu", + "VTLANG_JSON_CHK_THEME": "Zkontrolovat konfiguraci zásuvného modulu motivů", + "VTLANG_JSON_CHK_AUTOINS": "Zkontrolovat konfiguraci zásuvného modulu automatické instalace", + "VTLANG_JSON_CHK_PERSIST": "Zkontrolovat konfiguraci zásuvného modulu perzistence", + "VTLANG_JSON_CHK_MENU_ALIAS": "Zkontrolovat konfiguraci zásuvného modulu aliasů", + "VTLANG_JSON_CHK_MENU_TIP": "Zkontrolovat konfiguraci zásuvného modulu tip", + "VTLANG_JSON_CHK_MENU_CLASS": "Zkontrolovat konfiguraci zásuvného modulu tříd", + "VTLANG_JSON_CHK_INJECTION": "Zkontrolovat konfiguraci zásuvného modulu injekcí", + "VTLANG_JSON_CHK_AUTO_MEMDISK": "Zkontrolovat konfiguraci zásuvného modulu automatického memdisku", + "VTLANG_JSON_CHK_IMG_LIST": "Zkontrolovat konfiguraci zásuvného modulu seznamu obrazů", + "VTLANG_JSON_CHK_IMG_BLIST": "Zkontrolovat konfiguraci zásuvného modulu černé listiny obrazů", + "VTLANG_JSON_CHK_CONF_REPLACE": "Zkontrolovat konfiguraci zásuvného modulu nahrazení konfigurace spouštění", + "VTLANG_JSON_CHK_DUD": "Zkontrolovat konfiguraci zásuvného modulu dud", + "VTLANG_JSON_CHK_PASSWORD": "Zkontrolovat konfiguraci zásuvného modulu hesla", + + "VTLANG_NORMAL_MODE": "Spustit normálně", + "VTLANG_WIMBOOT_MODE": "Spustit v režimu wimboot", + "VTLANG_GRUB2_MODE": "Spustit v režimu grub2", + "VTLANG_MEMDISK_MODE": "Spustit v režimu memdisk", + + "VTLANG_RET_TO_LISTVIEW": "Vrátis do zobrazení seznamu", + "VTLANG_RET_TO_TREEVIEW": "Vrátit do zobrazení stromu", + + "VTLANG_NO_AUTOINS_SCRIPT": "Spustit bez šablony automatické instalace", + "VTLANG_AUTOINS_USE": "Spustit s", + + "VTLANG_NO_PERSIST": "Spustit bez perzistence", + "VTLANG_PERSIST_USE": "Spustit s", + + "VTLANG_BROWER_RETURN": "Vrátit", + + "VTLANG_ENTER_EXIT": "zmáčkněte Enter pro ukončení", + "VTLANG_ENTER_REBOOT": "zmáčkněte Enter pro restart", + "VTLANG_ENTER_CONTINUE": "zmáčkněte enter pro pokračování", + + "VTLANG_CTRL_TEMP_SET": "Dočasné řídící nastavení", + "VTLANG_WIN11_BYPASS_CHECK": "Obejít CPU/TPM/SecureBoot kontrolu při instalaci Windows 11", + "VTLANG_WIN11_BYPASS_NRO": "Obejít požadování online účtu při instalaci Windows 11", + "VTLANG_LINUX_REMOUNT": "Připojit Ventoy oddíl po spuštění Linuxu", + "VTLANG_SECONDARY_BOOT_MENU": "Zobrazit druhou spouštěcí nabídku", + "VTLANG_WIN_UEFI_RES_LOCK": "Lock the resolution when UEFI boot Windows/WinPE", + "VTLANG_UEFI_RES_LOCK_NONE": "None", + "VTLANG_UEFI_RES_LOCK_MAX": "Highest", + "VTLANG_UEFI_RES_LOCK_1024_768": "Fixed 1024 x 768", + "VTLANG_UEFI_RES_LOCK_BE1024_768": "At least 1024 x 768", + + + "MENU_STR_XXX": "" +} diff --git a/INSTALL/grub/menu/de_DE.json b/INSTALL/grub/menu/de_DE.json new file mode 100644 index 0000000..fb59768 --- /dev/null +++ b/INSTALL/grub/menu/de_DE.json @@ -0,0 +1,99 @@ +{ + "VTLANG_LANGUAGE_NAME": "German (Deutsch)", + + "VTLANG_STR_HOTKEY_LIST": "L:Sprache F1:Hilfe F2:Browser F3:Listenansicht F4:Lokaler Start F5:Werkzeuge F6:Erweitert", + "VTLANG_STR_HOTKEY_TREE": "L:Sprache F1:Hilfe F2:Browser F3:Listenansicht F4:Lokaler Start F5:Werkzeuge F6:Erweitert", + "VTLANG_RETURN_PREVIOUS": "Zu vorherigem Menü [Esc]", + "VTLANG_RETURN_PRV_NOESC": "Zu vorherigem Menü", + + "VTLANG_MENU_LANG": "Menüsprache auswählen", + + "VTLANG_LB_SBOOT_WINDOWS": "Windows suchen und starten", + "VTLANG_LB_SBOOT_G4D": "Grub4dos suchen und starten", + "VTLANG_LB_SBOOT_HDD1": "Vom ersten lokalen Datenträger starten", + "VTLANG_LB_SBOOT_HDD2": "Vom zweiten lokalen Datenträger starten", + "VTLANG_LB_SBOOT_HDD3": "Vom dritten lokalen Datenträger starten", + "VTLANG_LB_SBOOT_X64EFI": "BOOTX64.EFI suchen und starten", + "VTLANG_LB_SBOOT_IA32EFI": "BOOTIA32.EFI suchen und starten", + "VTLANG_LB_SBOOT_AA64EFI": "BOOTAA64.EFI suchen und starten", + "VTLANG_LB_SBOOT_XORBOOT": "xorboot suchen und starten", + + "VTLANG_FILE_CHKSUM": "Dateiprüfsumme", + "VTLANG_CHKSUM_MD5_CALC": "md5sum berechnen", + "VTLANG_CHKSUM_SHA1_CALC": "sha1sum berechnen", + "VTLANG_CHKSUM_SHA256_CALC": "sha256sum berechnen", + "VTLANG_CHKSUM_SHA512_CALC": "sha512sum berechnen", + "VTLANG_CHKSUM_MD5_CALC_CHK": "md5sum berechnen und prüfen", + "VTLANG_CHKSUM_SHA1_CALC_CHK": "sha1sum berechnen und prüfen", + "VTLANG_CHKSUM_SHA256_CALC_CHK": "sha256sum berechnen und prüfen", + "VTLANG_CHKSUM_SHA512_CALC_CHK": "sha512sum berechnen und prüfen", + + "VTLANG_POWER": "Power", + "VTLANG_POWER_REBOOT": "Neustart", + "VTLANG_POWER_HALT": "Herunterfahren", + "VTLANG_POWER_BOOT_EFIFW": "Neustart in EFI-Konfiguration", + + "VTLANG_KEYBRD_LAYOUT": "Tastaturlayout", + "VTLANG_HWINFO": "Hardwareinformationen", + + "VTLANG_RESOLUTION_CFG": "Auflösungseinstellungen", + "VTLANG_SCREEN_MODE": "Bildschirmanzeigemodus", + "VTLANG_SCREEN_TEXT_MODE": "Textmodus erzwingen", + "VTLANG_SCREEN_GUI_MODE": "Grafikmodus erzwingen", + + "VTLANG_THEME_SELECT": "Design auswählen", + + "VTLANG_UEFI_UTIL": "Ventoy UEFI-Dienstprogramme", + "VTLANG_UTIL_SHOW_EFI_DRV": "EFI-Treiber anzeigen", + "VTLANG_UTIL_FIX_BLINIT_FAIL": "Windows BlinitializeLibrary Fehler beheben", + + "VTLANG_JSON_CHK_JSON": "Konfiguration des JSON-Plugins prüfen (ventoy.json)", + "VTLANG_JSON_CHK_CONTROL": "Konfiguration des Plugins für die allgemeine Kontrolle prüfen", + "VTLANG_JSON_CHK_THEME": "Konfiguration des Design-Plugins prüfen", + "VTLANG_JSON_CHK_AUTOINS": "Konfiguration des Plugins für die automatische Installation prüfen", + "VTLANG_JSON_CHK_PERSIST": "Konfiguration des Persistenz-Plugins prüfen", + "VTLANG_JSON_CHK_MENU_ALIAS": "Konfiguration des Menü-Alias-Plugin prüfen", + "VTLANG_JSON_CHK_MENU_TIP": "Konfiguration des Menütipp-Plugins prüfen", + "VTLANG_JSON_CHK_MENU_CLASS": "Konfiguration des Menüklassen-Plugins prüfen", + "VTLANG_JSON_CHK_INJECTION": "Konfiguration des Injektions-Plugins prüfen", + "VTLANG_JSON_CHK_AUTO_MEMDISK": "Konfiguration des auto-memdisk-Plugins prüfen", + "VTLANG_JSON_CHK_IMG_LIST": "Konfiguration des Abbild-Listen-Plugins prüfen", + "VTLANG_JSON_CHK_IMG_BLIST": "Konfiguration des Abbild-Sperrlisten-Plugins prüfen", + "VTLANG_JSON_CHK_CONF_REPLACE": "Konfiguration des Boot-Conf-Replace-Plugins prüfen", + "VTLANG_JSON_CHK_DUD": "Konfiguration des dud-Plugins prüfen", + "VTLANG_JSON_CHK_PASSWORD": "Konfiguration des Passwort-Plugins prüfen", + + "VTLANG_NORMAL_MODE": "In Normal-Modus starten", + "VTLANG_WIMBOOT_MODE": "In wimboot-Modus starten", + "VTLANG_GRUB2_MODE": "In grub2-Modus starten", + "VTLANG_MEMDISK_MODE": "In memdisk-Modus starten", + + "VTLANG_RET_TO_LISTVIEW": "Zurück zur Listenansicht", + "VTLANG_RET_TO_TREEVIEW": "Zurück zur Baumansicht", + + "VTLANG_NO_AUTOINS_SCRIPT": "Ohne Vorlage für die automatische Installation starten", + "VTLANG_AUTOINS_USE": "Start mit", + + "VTLANG_NO_PERSIST": "Ohne Persistenz starten", + "VTLANG_PERSIST_USE": "Start mit", + + "VTLANG_BROWER_RETURN": "Zurück", + + "VTLANG_ENTER_EXIT": "Drücken Sie zum Beenden die Eingabetaste", + "VTLANG_ENTER_REBOOT": "Drücken Sie die Eingabetaste, um neu zu starten", + "VTLANG_ENTER_CONTINUE": "Drücken Sie die Eingabetaste, um fortzufahren", + + "VTLANG_CTRL_TEMP_SET": "Temporäre Steuerungseinstellungen", + "VTLANG_WIN11_BYPASS_CHECK": "Umgehen Sie die CPU/TPM/SecureBoot-Prüfung bei der Installation von Windows 11", + "VTLANG_WIN11_BYPASS_NRO": "Umgehen Sie die Online-Kontoanforderung bei der Installation von Windows 11", + "VTLANG_LINUX_REMOUNT": "Mounten Sie die Ventoy-Partition nach dem Booten von Linux", + "VTLANG_SECONDARY_BOOT_MENU": "Sekundäres Bootmenü anzeigen", + "VTLANG_WIN_UEFI_RES_LOCK": "Lock the resolution when UEFI boot Windows/WinPE", + "VTLANG_UEFI_RES_LOCK_NONE": "None", + "VTLANG_UEFI_RES_LOCK_MAX": "Highest", + "VTLANG_UEFI_RES_LOCK_1024_768": "Fixed 1024 x 768", + "VTLANG_UEFI_RES_LOCK_BE1024_768": "At least 1024 x 768", + + + "MENU_STR_XXX": "" +} diff --git a/INSTALL/grub/menu/el_GR.json b/INSTALL/grub/menu/el_GR.json new file mode 100644 index 0000000..46f956f --- /dev/null +++ b/INSTALL/grub/menu/el_GR.json @@ -0,0 +1,99 @@ +{ + "VTLANG_LANGUAGE_NAME": "Greek (Ελληνικά)", + + "VTLANG_STR_HOTKEY_LIST": "L:Γλώσσα F1:Βοήθεια F2:Περιήγηση F3:Προβολή Λίστας F4:Εκκίνηση από τοπικό δίσκο F5:Εργαλεία F6:Προσ. Μενού", + "VTLANG_STR_HOTKEY_TREE": "L:Γλώσσα F1:Βοήθεια F2:Περιήγηση F3:Προβολή Δένδρου F4:Εκκίνηση από τοπικό δίσκο F5:Εργαλεία F6:Προσ. Μενού", + "VTLANG_RETURN_PREVIOUS": "Επιστροφή στο προηγούμενο μενού [Esc]", + "VTLANG_RETURN_PRV_NOESC": "Επιστροφή στο προηγούμενο μενού", + + "VTLANG_MENU_LANG": "Επιλογή Γλώσσας Μενού", + + "VTLANG_LB_SBOOT_WINDOWS": "Αναζήτηση και εκκίνηση των Windows", + "VTLANG_LB_SBOOT_G4D": "Αναζήτηση και εκκίνηση του Grub4dos", + "VTLANG_LB_SBOOT_HDD1": "Εκκίνηση του 1ου τοπικού δίσκου", + "VTLANG_LB_SBOOT_HDD2": "Εκκίνηση του 2ου τοπικού δίσκου", + "VTLANG_LB_SBOOT_HDD3": "Εκκίνηση του 3ου τοπικού δίσκου", + "VTLANG_LB_SBOOT_X64EFI": "Αναζήτηση και εκκίνηση του BOOTX64.EFI", + "VTLANG_LB_SBOOT_IA32EFI": "Αναζήτηση και εκκίνηση του BOOTIA32.EFI", + "VTLANG_LB_SBOOT_AA64EFI": "Αναζήτηση και εκκίνηση του BOOTAA64.EFI", + "VTLANG_LB_SBOOT_XORBOOT": "Αναζήτηση και εκκίνηση του xorboot", + + "VTLANG_FILE_CHKSUM": "Αρχείο checksum", + "VTLANG_CHKSUM_MD5_CALC": "Υπολογισμός md5sum", + "VTLANG_CHKSUM_SHA1_CALC": "Υπολογισμός sha1sum", + "VTLANG_CHKSUM_SHA256_CALC": "Υπολογισμός sha256sum", + "VTLANG_CHKSUM_SHA512_CALC": "Υπολογισμός sha512sum", + "VTLANG_CHKSUM_MD5_CALC_CHK": "Υπολογισμός και έλεγχος md5sum", + "VTLANG_CHKSUM_SHA1_CALC_CHK": "Υπολογισμός και έλεγχος sha1sum", + "VTLANG_CHKSUM_SHA256_CALC_CHK": "Υπολογισμός και έλεγχος sha256sum", + "VTLANG_CHKSUM_SHA512_CALC_CHK": "Υπολογισμός και έλεγχος sha512sum", + + "VTLANG_POWER": "Λειτουργία", + "VTLANG_POWER_REBOOT": "Επανεκκίνηση", + "VTLANG_POWER_HALT": "Απενεργοποίηση", + "VTLANG_POWER_BOOT_EFIFW": "Επανεκκίνηση σε EFI setup", + + "VTLANG_KEYBRD_LAYOUT": "Διατάξεις Πληκτρολογίου", + "VTLANG_HWINFO": "Πληροφορίες υλικού", + + "VTLANG_RESOLUTION_CFG": "Διαμόρφωση ανάλυσης", + "VTLANG_SCREEN_MODE": "Λειτουργία Προβολής Οθόνης", + "VTLANG_SCREEN_TEXT_MODE": "Επιβολή λειτουργίας κειμένου", + "VTLANG_SCREEN_GUI_MODE": "Επιβολή λειτουργίας Γραφικών (GUI)", + + "VTLANG_THEME_SELECT": "Επιλογή Θέματος", + + "VTLANG_UEFI_UTIL": "Εργαλεία Ventoy UEFI", + "VTLANG_UTIL_SHOW_EFI_DRV": "Προβολή EFI Drivers", + "VTLANG_UTIL_FIX_BLINIT_FAIL": "Διόρθωση αποτυχίας Windows BlinitializeLibrary", + + "VTLANG_JSON_CHK_JSON": "Ελεγχος διαμόρφωσης json πρόσθετων (ventoy.json)", + "VTLANG_JSON_CHK_CONTROL": "Ελεγχος διαμόρφωσης του πρόσθετου καθολικού ελέγχου", + "VTLANG_JSON_CHK_THEME": "Ελεγχος διαμόρφωσης του πρόσθετου θέματος", + "VTLANG_JSON_CHK_AUTOINS": "Ελεγχος διαμόρφωσης του πρόσθετου αυτόματης εγκατάστασης", + "VTLANG_JSON_CHK_PERSIST": "Ελεγχος διαμόρφωσης του πρόσθετου επιμονής", + "VTLANG_JSON_CHK_MENU_ALIAS": "Ελεγχος διαμόρφωσης του πρόσθετου ψευδώνυμου μενού", + "VTLANG_JSON_CHK_MENU_TIP": "Ελεγχος διαμόρφωσης του πρόσθετου συμβουλών μενού", + "VTLANG_JSON_CHK_MENU_CLASS": "Ελεγχος διαμόρφωσης του πρόσθετου κατηγορίας μενού", + "VTLANG_JSON_CHK_INJECTION": "Ελεγχος διαμόρφωσης του πρόσθετου injection", + "VTLANG_JSON_CHK_AUTO_MEMDISK": "Ελεγχος διαμόρφωσης του πρόσθετου auto memdisk", + "VTLANG_JSON_CHK_IMG_LIST": "Ελεγχος διαμόρφωσης του πρόσθετου Λίστα images", + "VTLANG_JSON_CHK_IMG_BLIST": "Ελεγχος διαμόρφωσης του πρόσθετου Μαύρη λίστα images", + "VTLANG_JSON_CHK_CONF_REPLACE": "Ελεγχος διαμόρφωσης του πρόσθετου Αντικατάσταση διαμόρφ. εκκίνησης", + "VTLANG_JSON_CHK_DUD": "Ελεγχος διαμόρφωσης του πρόσθετου dud", + "VTLANG_JSON_CHK_PASSWORD": "Ελεγχος διαμόρφωσης του πρόσθετου Κωδικός πρόσβασης", + + "VTLANG_NORMAL_MODE": "Κανονική εκκίνηση", + "VTLANG_WIMBOOT_MODE": "Εκκίνηση σε λειτουργία wimboot", + "VTLANG_GRUB2_MODE": "Εκκίνηση σε λειτουργία grub2", + "VTLANG_MEMDISK_MODE": "Εκκίνηση σε λειτουργία memdisk", + + "VTLANG_RET_TO_LISTVIEW": "Επιστροφή σε Προβολή Λίστας", + "VTLANG_RET_TO_TREEVIEW": "Επιστροφή σε Προβολή Δένδρου", + + "VTLANG_NO_AUTOINS_SCRIPT": "Εκκίνηση χωρίς πρότυπο αυτόματης εγκατάστασης", + "VTLANG_AUTOINS_USE": "Εκκίνηση", + + "VTLANG_NO_PERSIST": "Εκκίνηση χωρίς επιμονή", + "VTLANG_PERSIST_USE": "Εκκίνηση", + + "VTLANG_BROWER_RETURN": "Επιστροφή", + + "VTLANG_ENTER_EXIT": "πατήστε το πλήκτρο Enter για έξοδο", + "VTLANG_ENTER_REBOOT": "πατήστε το πλήκτρο Enter για επανεκκίνηση", + "VTLANG_ENTER_CONTINUE": "πατήστε το πλήκτρο Enter για να συνεχίσετε", + + "VTLANG_CTRL_TEMP_SET": "Προσωρινές ρυθμίσεις ελέγχου", + "VTLANG_WIN11_BYPASS_CHECK": "Παράκαμψη ελέγχου CPU/TPM/SecureBoot κατά την εγκατάσταση των Windows 11", + "VTLANG_WIN11_BYPASS_NRO": "Παράκαμψη της απαίτησης online λογαριασμού κατά την εγκατάσταση των Windows 11", + "VTLANG_LINUX_REMOUNT": "Προσάρτηση διαμερίσματος Ventoy μετά την εκκίνηση του Linux", + "VTLANG_SECONDARY_BOOT_MENU": "Εμφάνιση δευτερεύοντος μενού εκκίνησης", + "VTLANG_WIN_UEFI_RES_LOCK": "Lock the resolution when UEFI boot Windows/WinPE", + "VTLANG_UEFI_RES_LOCK_NONE": "None", + "VTLANG_UEFI_RES_LOCK_MAX": "Highest", + "VTLANG_UEFI_RES_LOCK_1024_768": "Fixed 1024 x 768", + "VTLANG_UEFI_RES_LOCK_BE1024_768": "At least 1024 x 768", + + + "MENU_STR_XXX": "" +} \ No newline at end of file diff --git a/INSTALL/grub/menu/en_US.json b/INSTALL/grub/menu/en_US.json new file mode 100644 index 0000000..56abff0 --- /dev/null +++ b/INSTALL/grub/menu/en_US.json @@ -0,0 +1,98 @@ +{ + "VTLANG_LANGUAGE_NAME": "English (English)", + + "VTLANG_STR_HOTKEY_LIST": "L:Language F1:Help F2:Browse F3:ListView F4:Localboot F5:Tools F6:ExMenu", + "VTLANG_STR_HOTKEY_TREE": "L:Language F1:Help F2:Browse F3:TreeView F4:Localboot F5:Tools F6:ExMenu", + "VTLANG_RETURN_PREVIOUS": "Return to previous menu [Esc]", + "VTLANG_RETURN_PRV_NOESC": "Return to previous menu", + + "VTLANG_MENU_LANG": "Menu Language Select", + + "VTLANG_LB_SBOOT_WINDOWS": "Search and boot Windows", + "VTLANG_LB_SBOOT_G4D": "Search and boot Grub4dos", + "VTLANG_LB_SBOOT_HDD1": "Boot the 1st local disk", + "VTLANG_LB_SBOOT_HDD2": "Boot the 2nd local disk", + "VTLANG_LB_SBOOT_HDD3": "Boot the 3rd local disk", + "VTLANG_LB_SBOOT_X64EFI": "Search and boot BOOTX64.EFI", + "VTLANG_LB_SBOOT_IA32EFI": "Search and boot BOOTIA32.EFI", + "VTLANG_LB_SBOOT_AA64EFI": "Search and boot BOOTAA64.EFI", + "VTLANG_LB_SBOOT_XORBOOT": "Search and boot xorboot", + + "VTLANG_FILE_CHKSUM": "File checksum", + "VTLANG_CHKSUM_MD5_CALC": "Calculate md5sum", + "VTLANG_CHKSUM_SHA1_CALC": "Calculate sha1sum", + "VTLANG_CHKSUM_SHA256_CALC": "Calculate sha256sum", + "VTLANG_CHKSUM_SHA512_CALC": "Calculate sha512sum", + "VTLANG_CHKSUM_MD5_CALC_CHK": "Calculate and check md5sum", + "VTLANG_CHKSUM_SHA1_CALC_CHK": "Calculate and check sha1sum", + "VTLANG_CHKSUM_SHA256_CALC_CHK": "Calculate and check sha256sum", + "VTLANG_CHKSUM_SHA512_CALC_CHK": "Calculate and check sha512sum", + + "VTLANG_POWER": "Power", + "VTLANG_POWER_REBOOT": "Reboot", + "VTLANG_POWER_HALT": "Halt", + "VTLANG_POWER_BOOT_EFIFW": "Reboot to EFI setup", + + "VTLANG_KEYBRD_LAYOUT": "Keyboard Layouts", + "VTLANG_HWINFO": "Hardware Information", + + "VTLANG_RESOLUTION_CFG": "Resolution Configuration", + "VTLANG_SCREEN_MODE": "Screen Display Mode", + "VTLANG_SCREEN_TEXT_MODE": "Force Text Mode", + "VTLANG_SCREEN_GUI_MODE": "Force Graphics Mode", + + "VTLANG_THEME_SELECT": "Theme Select", + + "VTLANG_UEFI_UTIL": "Ventoy UEFI Utilities", + "VTLANG_UTIL_SHOW_EFI_DRV": "Show EFI Drivers", + "VTLANG_UTIL_FIX_BLINIT_FAIL": "Fixup Windows BlinitializeLibrary Failure", + + "VTLANG_JSON_CHK_JSON": "Check plugin json configuration (ventoy.json)", + "VTLANG_JSON_CHK_CONTROL": "Check global control plugin configuration", + "VTLANG_JSON_CHK_THEME": "Check theme plugin configuration", + "VTLANG_JSON_CHK_AUTOINS": "Check auto install plugin configuration", + "VTLANG_JSON_CHK_PERSIST": "Check persistence plugin configuration", + "VTLANG_JSON_CHK_MENU_ALIAS": "Check menu alias plugin configuration", + "VTLANG_JSON_CHK_MENU_TIP": "Check menu tip plugin configuration", + "VTLANG_JSON_CHK_MENU_CLASS": "Check menu class plugin configuration", + "VTLANG_JSON_CHK_INJECTION": "Check injection plugin configuration", + "VTLANG_JSON_CHK_AUTO_MEMDISK": "Check auto memdisk plugin configuration", + "VTLANG_JSON_CHK_IMG_LIST": "Check image list plugin configuration", + "VTLANG_JSON_CHK_IMG_BLIST": "Check image blacklist plugin configuration", + "VTLANG_JSON_CHK_CONF_REPLACE": "Check boot conf replace plugin configuration", + "VTLANG_JSON_CHK_DUD": "Check dud plugin configuration", + "VTLANG_JSON_CHK_PASSWORD": "Check password plugin configuration", + + "VTLANG_NORMAL_MODE": "Boot in normal mode", + "VTLANG_WIMBOOT_MODE": "Boot in wimboot mode", + "VTLANG_GRUB2_MODE": "Boot in grub2 mode", + "VTLANG_MEMDISK_MODE": "Boot in memdisk mode", + + "VTLANG_RET_TO_LISTVIEW": "Return to ListView", + "VTLANG_RET_TO_TREEVIEW": "Return to TreeView", + + "VTLANG_NO_AUTOINS_SCRIPT": "Boot without auto installation template", + "VTLANG_AUTOINS_USE": "Boot with", + + "VTLANG_NO_PERSIST": "Boot without persistence", + "VTLANG_PERSIST_USE": "Boot with", + + "VTLANG_BROWER_RETURN": "Return", + + "VTLANG_ENTER_EXIT": "press Enter key to exit", + "VTLANG_ENTER_REBOOT": "press Enter key to reboot", + "VTLANG_ENTER_CONTINUE": "press Enter key to continue", + + "VTLANG_CTRL_TEMP_SET": "Temporary Control Settings", + "VTLANG_WIN11_BYPASS_CHECK": "Bypass CPU/TPM/SecureBoot check when install Windows 11", + "VTLANG_WIN11_BYPASS_NRO": "Bypass online account requirement when install Windows 11", + "VTLANG_LINUX_REMOUNT": "Mount Ventoy partition after boot Linux", + "VTLANG_SECONDARY_BOOT_MENU": "Show secondary boot menu", + "VTLANG_WIN_UEFI_RES_LOCK": "Lock the resolution when UEFI boot Windows/WinPE", + "VTLANG_UEFI_RES_LOCK_NONE": "None", + "VTLANG_UEFI_RES_LOCK_MAX": "Highest", + "VTLANG_UEFI_RES_LOCK_1024_768": "Fixed 1024 x 768", + "VTLANG_UEFI_RES_LOCK_BE1024_768": "At least 1024 x 768", + + "MENU_STR_XXX": "" +} diff --git a/INSTALL/grub/menu/es_ES.json b/INSTALL/grub/menu/es_ES.json new file mode 100644 index 0000000..ace5b35 --- /dev/null +++ b/INSTALL/grub/menu/es_ES.json @@ -0,0 +1,99 @@ +{ + "VTLANG_LANGUAGE_NAME": "Spanish (Español)", + + "VTLANG_STR_HOTKEY_LIST": "L:Idioma F1:Ayuda F2:Navegar F3:Vista de lista F4:Arranque local F5:Herramientas F6:Menú ext.", + "VTLANG_STR_HOTKEY_TREE": "L:Idioma F1:Ayuda F2:Navegar F3:Vista de árbol F4:Arranque local F5:Herramientas F6:Menú ext.", + "VTLANG_RETURN_PREVIOUS": "Regresar al menú anterior [Esc]", + "VTLANG_RETURN_PRV_NOESC": "Regresar al menú anterior", + + "VTLANG_MENU_LANG": "Selección de idioma del menú", + + "VTLANG_LB_SBOOT_WINDOWS": "Buscar y arrancar Windows", + "VTLANG_LB_SBOOT_G4D": "Buscar y arrancar Grub4dos", + "VTLANG_LB_SBOOT_HDD1": "Arrancar el 1er disco local", + "VTLANG_LB_SBOOT_HDD2": "Arrancar el 2do disco local", + "VTLANG_LB_SBOOT_HDD3": "Arrancar el 3er disco local", + "VTLANG_LB_SBOOT_X64EFI": "Buscar y arrancar BOOTX64.EFI", + "VTLANG_LB_SBOOT_IA32EFI": "Buscar y arrancar BOOTIA32.EFI", + "VTLANG_LB_SBOOT_AA64EFI": "Buscar y arrancar BOOTAA64.EFI", + "VTLANG_LB_SBOOT_XORBOOT": "Buscar y arrancar xorboot", + + "VTLANG_FILE_CHKSUM": "Suma de comprobación del archivo", + "VTLANG_CHKSUM_MD5_CALC": "Calcular md5sum", + "VTLANG_CHKSUM_SHA1_CALC": "Calcular sha1sum", + "VTLANG_CHKSUM_SHA256_CALC": "Calcular sha256sum", + "VTLANG_CHKSUM_SHA512_CALC": "Calcular sha512sum", + "VTLANG_CHKSUM_MD5_CALC_CHK": "Calcular y comprobar md5sum", + "VTLANG_CHKSUM_SHA1_CALC_CHK": "Calcular y comprobar sha1sum", + "VTLANG_CHKSUM_SHA256_CALC_CHK": "Calcular y comprobar sha256sum", + "VTLANG_CHKSUM_SHA512_CALC_CHK": "Calcular y comprobar sha512sum", + + "VTLANG_POWER": "Energía", + "VTLANG_POWER_REBOOT": "Reiniciar", + "VTLANG_POWER_HALT": "Apagar", + "VTLANG_POWER_BOOT_EFIFW": "Reiniciar a la configuración EFI", + + "VTLANG_KEYBRD_LAYOUT": "Distribuciones de teclado", + "VTLANG_HWINFO": "Información de hardware", + + "VTLANG_RESOLUTION_CFG": "Configuración de resolución", + "VTLANG_SCREEN_MODE": "Modo de visualización de pantalla", + "VTLANG_SCREEN_TEXT_MODE": "Forzar modo texto", + "VTLANG_SCREEN_GUI_MODE": "Forzar modo gráfico", + + "VTLANG_THEME_SELECT": "Selección de tema", + + "VTLANG_UEFI_UTIL": "Utilidades UEFI de Ventoy", + "VTLANG_UTIL_SHOW_EFI_DRV": "Mostrar controladores EFI", + "VTLANG_UTIL_FIX_BLINIT_FAIL": "Reparar error BlinitializeLibrary de Windows", + + "VTLANG_JSON_CHK_JSON": "Comprobar configuración del complemento de json (ventoy.json)", + "VTLANG_JSON_CHK_CONTROL": "Comprobar configuración del complemento de control global", + "VTLANG_JSON_CHK_THEME": "Comprobar configuración del complemento de tema", + "VTLANG_JSON_CHK_AUTOINS": "Comprobar configuración del complemento de autoinstalación", + "VTLANG_JSON_CHK_PERSIST": "Comprobar configuración del complemento de persistencia", + "VTLANG_JSON_CHK_MENU_ALIAS": "Comprobar configuración del complemento de alias de menú", + "VTLANG_JSON_CHK_MENU_TIP": "Comprobar configuración del complemento de consejo de menú", + "VTLANG_JSON_CHK_MENU_CLASS": "Comprobar configuración del complemento de clases de menú", + "VTLANG_JSON_CHK_INJECTION": "Comprobar configuración del complemento de inyección", + "VTLANG_JSON_CHK_AUTO_MEMDISK": "Comprobar configuración del complemento auto memdisk", + "VTLANG_JSON_CHK_IMG_LIST": "Comprobar configuración del complemento de lista de imágenes", + "VTLANG_JSON_CHK_IMG_BLIST": "Comprobar configuración del complemento de lista negra de imágenes", + "VTLANG_JSON_CHK_CONF_REPLACE": "Comprobar configuración del complemento de reemplazo de configuración de arranque", + "VTLANG_JSON_CHK_DUD": "Comprobar configuración del complemento dud", + "VTLANG_JSON_CHK_PASSWORD": "Comprobar configuración del complemento de contraseñas", + + "VTLANG_NORMAL_MODE": "Arrancar en modo normal", + "VTLANG_WIMBOOT_MODE": "Arrancar en modo wimboot", + "VTLANG_GRUB2_MODE": "Arrancar en modo grub2", + "VTLANG_MEMDISK_MODE": "Arrancar en modo memdisk", + + "VTLANG_RET_TO_LISTVIEW": "Regresar a vista de lista", + "VTLANG_RET_TO_TREEVIEW": "regresar a vista de árbol", + + "VTLANG_NO_AUTOINS_SCRIPT": "Arrancar sin plantilla de autoinstalación", + "VTLANG_AUTOINS_USE": "Arrancar con", + + "VTLANG_NO_PERSIST": "Arrancar sin persistencia", + "VTLANG_PERSIST_USE": "Arrancar con", + + "VTLANG_BROWER_RETURN": "Regresar", + + "VTLANG_ENTER_EXIT": "Presiona la tecla Entrar para salir", + "VTLANG_ENTER_REBOOT": "Presiona la tecla Entrar para reiniciar", + "VTLANG_ENTER_CONTINUE": "Presiona la tecla Entrar para continuar", + + "VTLANG_CTRL_TEMP_SET": "Ajustes de control temporales", + "VTLANG_WIN11_BYPASS_CHECK": "Omitir comprobación de CPU/TPM/SecureBoot al instalar Windows 11", + "VTLANG_WIN11_BYPASS_NRO": "Omitir requisito de cuenta en línea al instalar Windows 11", + "VTLANG_LINUX_REMOUNT": "Montar partición de Ventoy después de arrancar Linux", + "VTLANG_SECONDARY_BOOT_MENU": "Mostrar menú de arranque secundario", + "VTLANG_WIN_UEFI_RES_LOCK": "Bloquear la resolución al arrancar Windows/WinPE en modo UEFI", + "VTLANG_UEFI_RES_LOCK_NONE": "Ninguno", + "VTLANG_UEFI_RES_LOCK_MAX": "La más alta", + "VTLANG_UEFI_RES_LOCK_1024_768": "Fija 1024 x 768", + "VTLANG_UEFI_RES_LOCK_BE1024_768": "Al menos 1024 x 768", + + + "MENU_STR_XXX": "" +} diff --git a/INSTALL/grub/menu/fa_IR.json b/INSTALL/grub/menu/fa_IR.json new file mode 100644 index 0000000..98dfce4 --- /dev/null +++ b/INSTALL/grub/menu/fa_IR.json @@ -0,0 +1,99 @@ +{ + "VTLANG_LANGUAGE_NAME": "Persian (فارسی)", + + "VTLANG_STR_HOTKEY_LIST": "L:زبان F1:راهنما F2:مرور F3:نمای لیستی F4:بوت محلی F5:ابزار F6:بازگشت", + "VTLANG_STR_HOTKEY_TREE": "L:زبان F1:راهنما F2:مرور F3:نمای درختی F4:بوت محلی F5:ابزار F6:بازگشت", + "VTLANG_RETURN_PREVIOUS": "بازگشت به منوی قبلی [Esc]", + "VTLANG_RETURN_PRV_NOESC": "بازگشت به منوی قبلی", + + "VTLANG_MENU_LANG": "منوی انتخاب زبان", + + "VTLANG_LB_SBOOT_WINDOWS": "جستجو و بوت ویندوز", + "VTLANG_LB_SBOOT_G4D": "جستجو و بوت Grub4dos", + "VTLANG_LB_SBOOT_HDD1": "بوت اولین دیسک محلی", + "VTLANG_LB_SBOOT_HDD2": "بوت دومین دیسک محلی", + "VTLANG_LB_SBOOT_HDD3": "بوت سومین دیسک محلی", + "VTLANG_LB_SBOOT_X64EFI": "جستجو و بوت BOOTX64.EFI", + "VTLANG_LB_SBOOT_IA32EFI": "جستجو و بوت BOOTIA32.EFI", + "VTLANG_LB_SBOOT_AA64EFI": "جستجو و بوت BOOTAA64.EFI", + "VTLANG_LB_SBOOT_XORBOOT": "جستجو و بوت xorboot", + + "VTLANG_FILE_CHKSUM": "اعتبارسنجی فایل", + "VTLANG_CHKSUM_MD5_CALC": "محاسبه md5sum", + "VTLANG_CHKSUM_SHA1_CALC": "محاسبه sha1sum", + "VTLANG_CHKSUM_SHA256_CALC": "محاسبه sha256sum", + "VTLANG_CHKSUM_SHA512_CALC": "محاسبه sha512sum", + "VTLANG_CHKSUM_MD5_CALC_CHK": "محاسبه و بررسی md5sum", + "VTLANG_CHKSUM_SHA1_CALC_CHK": "محاسبه و بررسی sha1sum", + "VTLANG_CHKSUM_SHA256_CALC_CHK": "محاسبه و بررسی sha256sum", + "VTLANG_CHKSUM_SHA512_CALC_CHK": "محاسبه و بررسی sha512sum", + + "VTLANG_POWER": "انرژی", + "VTLANG_POWER_REBOOT": "ریبوت", + "VTLANG_POWER_HALT": "توقف", + "VTLANG_POWER_BOOT_EFIFW": "ریبوت به تنظیمات EFI", + + "VTLANG_KEYBRD_LAYOUT": "نمایه صفحه کلید", + "VTLANG_HWINFO": "اطلاعات سخت افزار", + + "VTLANG_RESOLUTION_CFG": "پیکربندی رزولوشن", + "VTLANG_SCREEN_MODE": "حالت نمایش صفحه", + "VTLANG_SCREEN_TEXT_MODE": "حالت متنی اجباری", + "VTLANG_SCREEN_GUI_MODE": "حالت گرافیکی اجباری", + + "VTLANG_THEME_SELECT": "انتخاب تم", + + "VTLANG_UEFI_UTIL": "ابزار های کمکی Ventoy UEFI", + "VTLANG_UTIL_SHOW_EFI_DRV": "نمایش درایور های EFI", + "VTLANG_UTIL_FIX_BLINIT_FAIL": "رفع خطای Windows BlinitializeLibrary", + + "VTLANG_JSON_CHK_JSON": "بررسی پیکربندی json افزونه (ventoy.json)", + "VTLANG_JSON_CHK_CONTROL": "بررسی پیکربندی افزونه کنترل سراسری", + "VTLANG_JSON_CHK_THEME": "بررسی پیکربندی افزونه قالب", + "VTLANG_JSON_CHK_AUTOINS": "بررسی پیکربندی افزونه نصب خودکار", + "VTLANG_JSON_CHK_PERSIST": "بررسی پیکربندی افزونه‌ی تداوم", + "VTLANG_JSON_CHK_MENU_ALIAS": "بررسی پیکربندی افزونه نام مستعار منو", + "VTLANG_JSON_CHK_MENU_TIP": "بررسی پیکربندی افزونه نکته منو", + "VTLANG_JSON_CHK_MENU_CLASS": "بررسی پیکربندی افزونه کلاس منو", + "VTLANG_JSON_CHK_INJECTION": "بررسی پیکربندی افزونه تزریق", + "VTLANG_JSON_CHK_AUTO_MEMDISK": "بررسی پیکربندی افزونه memdisk خودکار", + "VTLANG_JSON_CHK_IMG_LIST": "بررسی پیکربندی افزونه لیست ایمیج ها", + "VTLANG_JSON_CHK_IMG_BLIST": "بررسی پیکربندی افزونه لیست سیاه ایمیج", + "VTLANG_JSON_CHK_CONF_REPLACE": "بررسی پیکربندی افزونه جایگزینی فایل پیکربندی بوت", + "VTLANG_JSON_CHK_DUD": "بررسی پیکربندی افزونه dud", + "VTLANG_JSON_CHK_PASSWORD": "بررسی پیکربندی افزونه کلمه عبور", + + "VTLANG_NORMAL_MODE": "بوت در حالت عادی", + "VTLANG_WIMBOOT_MODE": "بوت در حالت wimboot", + "VTLANG_GRUB2_MODE": "بوت در حالت grub2", + "VTLANG_MEMDISK_MODE": "بوت در حالت memdisk", + + "VTLANG_RET_TO_LISTVIEW": "بازگشت به نمای لیستی", + "VTLANG_RET_TO_TREEVIEW": "بازگشت به نمای درختی", + + "VTLANG_NO_AUTOINS_SCRIPT": "بوت بدون قالب نصب خودکار", + "VTLANG_AUTOINS_USE": "بوت با", + + "VTLANG_NO_PERSIST": "بوت بدون تداوم", + "VTLANG_PERSIST_USE": "بوت با", + + "VTLANG_BROWER_RETURN": "بازگشت", + + "VTLANG_ENTER_EXIT": "جهت خروج دکمه Enter را فشار دهید", + "VTLANG_ENTER_REBOOT": "جهت ریبوت دکمه Enter را فشار دهید", + "VTLANG_ENTER_CONTINUE": "جهت ادامه دکمه Enter را فشار دهید", + + "VTLANG_CTRL_TEMP_SET": "تنظیمات کنترل موقت", + "VTLANG_WIN11_BYPASS_CHECK": "دور زدن بررسی CPU/TPM/SecureBoot در هنگام نصب ویندوز 11", + "VTLANG_WIN11_BYPASS_NRO": "دور زدن نیاز به حساب کاربری آنلاین هنگام نصب ویندوز 11", + "VTLANG_LINUX_REMOUNT": "اتصال پارتیشن Ventoy بعد از بوت لینوکس", + "VTLANG_SECONDARY_BOOT_MENU": "نمایش منوی بوت ثانویه", + "VTLANG_WIN_UEFI_RES_LOCK": "Lock the resolution when UEFI boot Windows/WinPE", + "VTLANG_UEFI_RES_LOCK_NONE": "None", + "VTLANG_UEFI_RES_LOCK_MAX": "Highest", + "VTLANG_UEFI_RES_LOCK_1024_768": "Fixed 1024 x 768", + "VTLANG_UEFI_RES_LOCK_BE1024_768": "At least 1024 x 768", + + + "MENU_STR_XXX": "" +} diff --git a/INSTALL/grub/menu/fr_FR.json b/INSTALL/grub/menu/fr_FR.json new file mode 100644 index 0000000..f2df056 --- /dev/null +++ b/INSTALL/grub/menu/fr_FR.json @@ -0,0 +1,99 @@ +{ + "VTLANG_LANGUAGE_NAME": "French (Français)", + + "VTLANG_STR_HOTKEY_LIST": "L:Langue F1:Aide F2:Parcourir F3:Affichage liste F4:Démarrage local F5:Outils F6:Menu étendu", + "VTLANG_STR_HOTKEY_TREE": "L:Langue F1:Aide F2:Parcourir F3:Affichage arborescence F4:Démarrage local F5:Outils F6:Menu étendu", + "VTLANG_RETURN_PREVIOUS": "Retour au menu précédent [Echap]", + "VTLANG_RETURN_PRV_NOESC": "Retour au menu précédent", + + "VTLANG_MENU_LANG": "Sélection de la langue des menus", + + "VTLANG_LB_SBOOT_WINDOWS": "Rechercher et démarrer Windows", + "VTLANG_LB_SBOOT_G4D": "Rechercher et démarrer GRUB4DOS", + "VTLANG_LB_SBOOT_HDD1": "Démarrer depuis le 1er disque local", + "VTLANG_LB_SBOOT_HDD2": "Démarrer depuis le 2e disque local", + "VTLANG_LB_SBOOT_HDD3": "Démarrer depuis le 3e disque local", + "VTLANG_LB_SBOOT_X64EFI": "Rechercher et démarrer BOOTX64.EFI", + "VTLANG_LB_SBOOT_IA32EFI": "Rechercher et démarrer BOOTIA32.EFI", + "VTLANG_LB_SBOOT_AA64EFI": "Rechercher et démarrer BOOTAA64.EFI", + "VTLANG_LB_SBOOT_XORBOOT": "Rechercher et démarrer xorboot", + + "VTLANG_FILE_CHKSUM": "Somme de contrôle du fichier", + "VTLANG_CHKSUM_MD5_CALC": "Calculer MD5", + "VTLANG_CHKSUM_SHA1_CALC": "Calculer SHA1", + "VTLANG_CHKSUM_SHA256_CALC": "Calculer SHA256", + "VTLANG_CHKSUM_SHA512_CALC": "Calculer SHA512", + "VTLANG_CHKSUM_MD5_CALC_CHK": "Calculer et vérifier MD5", + "VTLANG_CHKSUM_SHA1_CALC_CHK": "Calculer et vérifier SHA1", + "VTLANG_CHKSUM_SHA256_CALC_CHK": "Calculer et vérifier SHA256", + "VTLANG_CHKSUM_SHA512_CALC_CHK": "Calculer et vérifier SHA512", + + "VTLANG_POWER": "Extinction", + "VTLANG_POWER_REBOOT": "Redémarrer", + "VTLANG_POWER_HALT": "Éteindre", + "VTLANG_POWER_BOOT_EFIFW": "Redémarrer et accéder au menu EFI", + + "VTLANG_KEYBRD_LAYOUT": "Dispositions de clavier", + "VTLANG_HWINFO": "Informations sur le matériel", + + "VTLANG_RESOLUTION_CFG": "Configuration de la résolution", + "VTLANG_SCREEN_MODE": "Mode d’affichage", + "VTLANG_SCREEN_TEXT_MODE": "Mode texte", + "VTLANG_SCREEN_GUI_MODE": "Mode graphique", + + "VTLANG_THEME_SELECT": "Sélection du thème", + + "VTLANG_UEFI_UTIL": "Utilitaires UEFI de Ventoy", + "VTLANG_UTIL_SHOW_EFI_DRV": "Afficher les pilotes EFI", + "VTLANG_UTIL_FIX_BLINIT_FAIL": "Contourner l’échec de Windows BlinitializeLibrary", + + "VTLANG_JSON_CHK_JSON": "Afficher le fichier de configuration (ventoy.json)", + "VTLANG_JSON_CHK_CONTROL": "Afficher la configuration du plugin de contrôle global", + "VTLANG_JSON_CHK_THEME": "Afficher la configuration du plugin de thème", + "VTLANG_JSON_CHK_AUTOINS": "Afficher la configuration du plugin d’installation automatique", + "VTLANG_JSON_CHK_PERSIST": "Afficher la configuration du plugin de persistance", + "VTLANG_JSON_CHK_MENU_ALIAS": "Afficher la configuration du plugin des alias du menu", + "VTLANG_JSON_CHK_MENU_TIP": "Afficher la configuration du plugin des astuces du menu", + "VTLANG_JSON_CHK_MENU_CLASS": "Afficher la configuration du plugin des classes du menu", + "VTLANG_JSON_CHK_INJECTION": "Afficher la configuration du plugin d’injection", + "VTLANG_JSON_CHK_AUTO_MEMDISK": "Afficher la configuration du plugin memdisk automatique", + "VTLANG_JSON_CHK_IMG_LIST": "Afficher la configuration du plugin de liste des images", + "VTLANG_JSON_CHK_IMG_BLIST": "Afficher la configuration du plugin de liste noire des images", + "VTLANG_JSON_CHK_CONF_REPLACE": "Afficher la configuration du plugin de substitution des fichiers de démarrage", + "VTLANG_JSON_CHK_DUD": "Afficher la configuration du plugin de disques de mise à jour des pilotes", + "VTLANG_JSON_CHK_PASSWORD": "Afficher la configuration du plugin de mots de passe", + + "VTLANG_NORMAL_MODE": "Démarrer en mode normal", + "VTLANG_WIMBOOT_MODE": "Démarrer en mode WimBoot", + "VTLANG_GRUB2_MODE": "Démarrer en mode GRUB 2", + "VTLANG_MEMDISK_MODE": "Démarrer en mode Memdisk", + + "VTLANG_RET_TO_LISTVIEW": "Revenir à l’affichage en liste", + "VTLANG_RET_TO_TREEVIEW": "Revenir à l’affichage en arborescence", + + "VTLANG_NO_AUTOINS_SCRIPT": "Démarrer en ignorant le modèle d’auto-installation", + "VTLANG_AUTOINS_USE": "Démarrer en chargeant le modèle d’auto-installation", + + "VTLANG_NO_PERSIST": "Démarrer sans persistance", + "VTLANG_PERSIST_USE": "Démarrer avec la persistance", + + "VTLANG_BROWER_RETURN": "Retour", + + "VTLANG_ENTER_EXIT": "appuyez sur la touche Entrée pour quitter", + "VTLANG_ENTER_REBOOT": "appuyez sur la touche Entrée pour redémarrer", + "VTLANG_ENTER_CONTINUE": "appuyez sur la touche Entrée pour continuer", + + "VTLANG_CTRL_TEMP_SET": "Paramètres de contrôle temporaires", + "VTLANG_WIN11_BYPASS_CHECK": "Ignorer la vérification CPU/TPM/SecureBoot lors de l'installation de Windows 11", + "VTLANG_WIN11_BYPASS_NRO": "Contourner l'exigence de compte en ligne lors de l'installation de Windows 11", + "VTLANG_LINUX_REMOUNT": "Monter la partition Ventoy après le démarrage de Linux", + "VTLANG_SECONDARY_BOOT_MENU": "Afficher le menu de démarrage secondaire", + "VTLANG_WIN_UEFI_RES_LOCK": "Lock the resolution when UEFI boot Windows/WinPE", + "VTLANG_UEFI_RES_LOCK_NONE": "None", + "VTLANG_UEFI_RES_LOCK_MAX": "Highest", + "VTLANG_UEFI_RES_LOCK_1024_768": "Fixed 1024 x 768", + "VTLANG_UEFI_RES_LOCK_BE1024_768": "At least 1024 x 768", + + + "MENU_STR_XXX": "" +} diff --git a/INSTALL/grub/menu/hi_HI.json b/INSTALL/grub/menu/hi_HI.json new file mode 100644 index 0000000..a9295d9 --- /dev/null +++ b/INSTALL/grub/menu/hi_HI.json @@ -0,0 +1,99 @@ +{ + "VTLANG_LANGUAGE_NAME": "Hindi (हिन्दी)", + + "VTLANG_STR_HOTKEY_LIST": "L:भाषा F1:मदद F2:ब्राउज़र F3:ListView F4:स्थानीयबूट F5:उपकरण F6:ExMenu", + "VTLANG_STR_HOTKEY_TREE": "L:भाषा F1:मदद F2:ब्राउज़र F3:TreeView F4:स्थानीयबूट F5:उपकरण F6:ExMenu", + "VTLANG_RETURN_PREVIOUS": "पिछले मेनू पर लौटें [Esc]", + "VTLANG_RETURN_PRV_NOESC": "पिछले मेनू पर लौटें", + + "VTLANG_MENU_LANG": "मेनू भाषा का चयन करें", + + "VTLANG_LB_SBOOT_WINDOWS": "Windows खोजें और बूट करें", + "VTLANG_LB_SBOOT_G4D": "Grub4dos खोजें और बूट करें", + "VTLANG_LB_SBOOT_HDD1": "पहली(1st) स्थानीय डिस्क को बूट करें", + "VTLANG_LB_SBOOT_HDD2": "दूसरी(2nd) स्थानीय डिस्क बूट करें", + "VTLANG_LB_SBOOT_HDD3": "तीसरी(3rd) स्थानीय डिस्क बूट करें", + "VTLANG_LB_SBOOT_X64EFI": "BOOTX64.EFI खोजें और बूट करें", + "VTLANG_LB_SBOOT_IA32EFI": "BOOTIA32.EFI खोजें और बूट करें", + "VTLANG_LB_SBOOT_AA64EFI": "BOOTAA64.EFI खोजें और बूट करें", + "VTLANG_LB_SBOOT_XORBOOT": "xorboot खोजें और बूट करें", + + "VTLANG_FILE_CHKSUM": "फ़ाइल चेकसम", + "VTLANG_CHKSUM_MD5_CALC": "Md5sum की गणना करें", + "VTLANG_CHKSUM_SHA1_CALC": "sha1sum की गणना करें", + "VTLANG_CHKSUM_SHA256_CALC": "sha256sum की गणना करें", + "VTLANG_CHKSUM_SHA512_CALC": "sha512sum की गणना करें", + "VTLANG_CHKSUM_MD5_CALC_CHK": "md5sum की गणना और जाँच करें", + "VTLANG_CHKSUM_SHA1_CALC_CHK": "sha1sum की गणना और जाँच करें", + "VTLANG_CHKSUM_SHA256_CALC_CHK": "sha256sum की गणना और जाँच करें", + "VTLANG_CHKSUM_SHA512_CALC_CHK": "sha512sum की गणना और जाँच करें", + + "VTLANG_POWER": "पावर", + "VTLANG_POWER_REBOOT": "रीबूट", + "VTLANG_POWER_HALT": "हाल्ट", + "VTLANG_POWER_BOOT_EFIFW": "EFI सेटअप के लिए रीबूट करें", + + "VTLANG_KEYBRD_LAYOUT": "कीबोर्ड लेआउट", + "VTLANG_HWINFO": "हार्डवेयर की जानकारी", + + "VTLANG_RESOLUTION_CFG": "रिज़ॉल्यूशन कॉन्फ़िगरेशन", + "VTLANG_SCREEN_MODE": "Screen Display मोड", + "VTLANG_SCREEN_TEXT_MODE": "फोर्स Text मोड", + "VTLANG_SCREEN_GUI_MODE": "फोर्स Graphics मोड", + + "VTLANG_THEME_SELECT": "थीम का चयन", + + "VTLANG_UEFI_UTIL": "वेंटोय UEFI यूटिलिटीज", + "VTLANG_UTIL_SHOW_EFI_DRV": "EFI ड्राइवर्स दिखाएं", + "VTLANG_UTIL_FIX_BLINIT_FAIL": "Windows BlinitializeLibrary विफलता को ठीक करें", + + "VTLANG_JSON_CHK_JSON": "प्लगइन json विन्यास की जाँच करें (ventoy.json)", + "VTLANG_JSON_CHK_CONTROL": "global control प्लगइन विन्यास की जाँच करें", + "VTLANG_JSON_CHK_THEME": "theme प्लगइन विन्यास की जाँच करें", + "VTLANG_JSON_CHK_AUTOINS": "auto install प्लगइन विन्यास की जाँच करें", + "VTLANG_JSON_CHK_PERSIST": "persistence प्लगइन विन्यास की जाँच करें", + "VTLANG_JSON_CHK_MENU_ALIAS": "menu alias प्लगइन विन्यास की जाँच करें", + "VTLANG_JSON_CHK_MENU_TIP": "menu tip प्लगइन विन्यास की जाँच करें", + "VTLANG_JSON_CHK_MENU_CLASS": "menu class प्लगइन विन्यास की जाँच करें", + "VTLANG_JSON_CHK_INJECTION": "injection प्लगइन विन्यास की जाँच करें", + "VTLANG_JSON_CHK_AUTO_MEMDISK": "auto memdisk प्लगइन विन्यास की जाँच करें", + "VTLANG_JSON_CHK_IMG_LIST": "image list प्लगइन विन्यास की जाँच करें", + "VTLANG_JSON_CHK_IMG_BLIST": "image blacklist प्लगइन विन्यास की जाँच करें", + "VTLANG_JSON_CHK_CONF_REPLACE": "boot conf replace प्लगइन विन्यास की जाँच करें", + "VTLANG_JSON_CHK_DUD": "dud प्लगइन विन्यास की जाँच करें", + "VTLANG_JSON_CHK_PASSWORD": "password प्लगइन विन्यास की जाँच करें", + + "VTLANG_NORMAL_MODE": "सामान्य मोड में बूट करें", + "VTLANG_WIMBOOT_MODE": "wimboot मोड में बूट करें", + "VTLANG_GRUB2_MODE": "grub2 मोड में बूट करें", + "VTLANG_MEMDISK_MODE": "memdisk मोड में बूट करें", + + "VTLANG_RET_TO_LISTVIEW": "ListView पर वापस जाएँ", + "VTLANG_RET_TO_TREEVIEW": "TreeView पर वापस जाएँ", + + "VTLANG_NO_AUTOINS_SCRIPT": "ऑटो इंस्टॉलेशन टेम्पलेट के बिना बूट करें", + "VTLANG_AUTOINS_USE": "के साथ बूट करें", + + "VTLANG_NO_PERSIST": "बिना persistence के बूट करें", + "VTLANG_PERSIST_USE": "के साथ बूट करें", + + "VTLANG_BROWER_RETURN": "लौटें", + + "VTLANG_ENTER_EXIT": "बाहर निकलने के लिए एंटर कुंजी दबाएं", + "VTLANG_ENTER_REBOOT": "रिबूट करने के लिए एंटर कुंजी दबाएं", + "VTLANG_ENTER_CONTINUE": "जारी रखने के लिए एंटर कुंजी दबाएं", + + "VTLANG_CTRL_TEMP_SET": "अस्थायी नियंत्रण सेटिंग्स", + "VTLANG_WIN11_BYPASS_CHECK": "जब विंडोज 11 स्थापित करें, CPU/TPM/SECUREBOOT CHECK को बायपास करें", + "VTLANG_WIN11_BYPASS_NRO": "विंडोज 11 स्थापित करते समय ऑनलाइन खाते की आवश्यकता बाईपास", + "VTLANG_LINUX_REMOUNT": "लिनक्स बूट के बाद वेंटॉय विभाजन को माउंट करें", + "VTLANG_SECONDARY_BOOT_MENU": "द्वितीयक बूट मेनू दिखाएं", + "VTLANG_WIN_UEFI_RES_LOCK": "Lock the resolution when UEFI boot Windows/WinPE", + "VTLANG_UEFI_RES_LOCK_NONE": "None", + "VTLANG_UEFI_RES_LOCK_MAX": "Highest", + "VTLANG_UEFI_RES_LOCK_1024_768": "Fixed 1024 x 768", + "VTLANG_UEFI_RES_LOCK_BE1024_768": "At least 1024 x 768", + + + "MENU_STR_XXX": "" +} diff --git a/INSTALL/grub/menu/hr_HR.json b/INSTALL/grub/menu/hr_HR.json new file mode 100644 index 0000000..07e6eb4 --- /dev/null +++ b/INSTALL/grub/menu/hr_HR.json @@ -0,0 +1,99 @@ +{ + "VTLANG_LANGUAGE_NAME": "Croatian (Hrvatski)", + + "VTLANG_STR_HOTKEY_LIST": "L:Jezik F1:Help F2:Browse F3:ListView F4:Localboot F5:Tools F6:ExMenu", + "VTLANG_STR_HOTKEY_TREE": "L:Jezik F1:Help F2:Browse F3:TreeView F4:Localboot F5:Tools F6:ExMenu", + "VTLANG_RETURN_PREVIOUS": "Return to previous menu [Esc]", + "VTLANG_RETURN_PRV_NOESC": "Return to previous menu", + + "VTLANG_MENU_LANG": "Menu Language Select", + + "VTLANG_LB_SBOOT_WINDOWS": "Search and boot Windows", + "VTLANG_LB_SBOOT_G4D": "Search and boot Grub4dos", + "VTLANG_LB_SBOOT_HDD1": "Boot the 1st local disk", + "VTLANG_LB_SBOOT_HDD2": "Boot the 2nd local disk", + "VTLANG_LB_SBOOT_HDD3": "Boot the 3rd local disk", + "VTLANG_LB_SBOOT_X64EFI": "Search and boot BOOTX64.EFI", + "VTLANG_LB_SBOOT_IA32EFI": "Search and boot BOOTIA32.EFI", + "VTLANG_LB_SBOOT_AA64EFI": "Search and boot BOOTAA64.EFI", + "VTLANG_LB_SBOOT_XORBOOT": "Search and boot xorboot", + + "VTLANG_FILE_CHKSUM": "File checksum", + "VTLANG_CHKSUM_MD5_CALC": "Calculate md5sum", + "VTLANG_CHKSUM_SHA1_CALC": "Calculate sha1sum", + "VTLANG_CHKSUM_SHA256_CALC": "Calculate sha256sum", + "VTLANG_CHKSUM_SHA512_CALC": "Calculate sha512sum", + "VTLANG_CHKSUM_MD5_CALC_CHK": "Calculate and check md5sum", + "VTLANG_CHKSUM_SHA1_CALC_CHK": "Calculate and check sha1sum", + "VTLANG_CHKSUM_SHA256_CALC_CHK": "Calculate and check sha256sum", + "VTLANG_CHKSUM_SHA512_CALC_CHK": "Calculate and check sha512sum", + + "VTLANG_POWER": "Power", + "VTLANG_POWER_REBOOT": "Reboot", + "VTLANG_POWER_HALT": "Halt", + "VTLANG_POWER_BOOT_EFIFW": "Reboot to EFI setup", + + "VTLANG_KEYBRD_LAYOUT": "Keyboard Layouts", + "VTLANG_HWINFO": "Hardware Information", + + "VTLANG_RESOLUTION_CFG": "Resolution Configuration", + "VTLANG_SCREEN_MODE": "Screen Display Mode", + "VTLANG_SCREEN_TEXT_MODE": "Force Text Mode", + "VTLANG_SCREEN_GUI_MODE": "Force Graphics Mode", + + "VTLANG_THEME_SELECT": "Theme Select", + + "VTLANG_UEFI_UTIL": "Ventoy UEFI Utilities", + "VTLANG_UTIL_SHOW_EFI_DRV": "Show EFI Drivers", + "VTLANG_UTIL_FIX_BLINIT_FAIL": "Fixup Windows BlinitializeLibrary Failure", + + "VTLANG_JSON_CHK_JSON": "Check plugin json configuration (ventoy.json)", + "VTLANG_JSON_CHK_CONTROL": "Check global control plugin configuration", + "VTLANG_JSON_CHK_THEME": "Check theme plugin configuration", + "VTLANG_JSON_CHK_AUTOINS": "Check auto install plugin configuration", + "VTLANG_JSON_CHK_PERSIST": "Check persistence plugin configuration", + "VTLANG_JSON_CHK_MENU_ALIAS": "Check menu alias plugin configuration", + "VTLANG_JSON_CHK_MENU_TIP": "Check menu tip plugin configuration", + "VTLANG_JSON_CHK_MENU_CLASS": "Check menu class plugin configuration", + "VTLANG_JSON_CHK_INJECTION": "Check injection plugin configuration", + "VTLANG_JSON_CHK_AUTO_MEMDISK": "Check auto memdisk plugin configuration", + "VTLANG_JSON_CHK_IMG_LIST": "Check image list plugin configuration", + "VTLANG_JSON_CHK_IMG_BLIST": "Check image blacklist plugin configuration", + "VTLANG_JSON_CHK_CONF_REPLACE": "Check boot conf replace plugin configuration", + "VTLANG_JSON_CHK_DUD": "Check dud plugin configuration", + "VTLANG_JSON_CHK_PASSWORD": "Check password plugin configuration", + + "VTLANG_NORMAL_MODE": "Boot in normal mode", + "VTLANG_WIMBOOT_MODE": "Boot in wimboot mode", + "VTLANG_GRUB2_MODE": "Boot in grub2 mode", + "VTLANG_MEMDISK_MODE": "Boot in memdisk mode", + + "VTLANG_RET_TO_LISTVIEW": "Return to ListView", + "VTLANG_RET_TO_TREEVIEW": "Return to TreeView", + + "VTLANG_NO_AUTOINS_SCRIPT": "Boot without auto installation template", + "VTLANG_AUTOINS_USE": "Boot with", + + "VTLANG_NO_PERSIST": "Boot without persistence", + "VTLANG_PERSIST_USE": "Boot with", + + "VTLANG_BROWER_RETURN": "Return", + + "VTLANG_ENTER_EXIT": "pritisnite tipku Enter za izlaz", + "VTLANG_ENTER_REBOOT": "pritisnite tipku Enter za ponovno pokretanje", + "VTLANG_ENTER_CONTINUE": "pritisnite tipku Enter za nastavak", + + "VTLANG_CTRL_TEMP_SET": "Temporary Control Settings", + "VTLANG_WIN11_BYPASS_CHECK": "Bypass CPU/TPM/SecureBoot check when install Windows 11", + "VTLANG_WIN11_BYPASS_NRO": "Bypass online account requirement when install Windows 11", + "VTLANG_LINUX_REMOUNT": "Mount Ventoy partition after boot Linux", + "VTLANG_SECONDARY_BOOT_MENU": "Show secondary boot menu", + "VTLANG_WIN_UEFI_RES_LOCK": "Lock the resolution when UEFI boot Windows/WinPE", + "VTLANG_UEFI_RES_LOCK_NONE": "None", + "VTLANG_UEFI_RES_LOCK_MAX": "Highest", + "VTLANG_UEFI_RES_LOCK_1024_768": "Fixed 1024 x 768", + "VTLANG_UEFI_RES_LOCK_BE1024_768": "At least 1024 x 768", + + + "MENU_STR_XXX": "" +} diff --git a/INSTALL/grub/menu/hu_HU.json b/INSTALL/grub/menu/hu_HU.json new file mode 100644 index 0000000..5cc83b7 --- /dev/null +++ b/INSTALL/grub/menu/hu_HU.json @@ -0,0 +1,99 @@ +{ + "VTLANG_LANGUAGE_NAME": "Magyar (Hungarian)", + + "VTLANG_STR_HOTKEY_LIST": "L:Nyelv F1:Súgó F2:Tallózás F3:Listanézet F4:Helyi indítás F5:Eszközök F6:Bővített menü", + "VTLANG_STR_HOTKEY_TREE": "L:Nyelv F1:Súgó F2:Tallózás F3:Fanézet F4:Helyi indítás F5:Eszközök F6:Bővített menü", + "VTLANG_RETURN_PREVIOUS": "Vissza az előző menübe [Esc]", + "VTLANG_RETURN_PRV_NOESC": "Vissza az előző menübe", + + "VTLANG_MENU_LANG": "Menü nyelvének kiválasztása", + + "VTLANG_LB_SBOOT_WINDOWS": "Windows keresése és indítása", + "VTLANG_LB_SBOOT_G4D": "Grub4dos keresése és indítása", + "VTLANG_LB_SBOOT_HDD1": "Indítás az 1. helyi lemezről", + "VTLANG_LB_SBOOT_HDD2": "Indítás a 2. helyi lemezről", + "VTLANG_LB_SBOOT_HDD3": "Indítás a 3. helyi lemezről", + "VTLANG_LB_SBOOT_X64EFI": "BOOTX64.EFI keresése és indítása", + "VTLANG_LB_SBOOT_IA32EFI": "BOOTIA32.EFI keresése és indítása", + "VTLANG_LB_SBOOT_AA64EFI": "BOOTAA64.EFI keresése és indítása", + "VTLANG_LB_SBOOT_XORBOOT": "xorboot keresése és indítása", + + "VTLANG_FILE_CHKSUM": "Fájl ellenőrzőösszege", + "VTLANG_CHKSUM_MD5_CALC": "md5sum kiszámítása", + "VTLANG_CHKSUM_SHA1_CALC": "sha1sum kiszámítása", + "VTLANG_CHKSUM_SHA256_CALC": "sha256sum kiszámítása", + "VTLANG_CHKSUM_SHA512_CALC": "sha512sum kiszámítása", + "VTLANG_CHKSUM_MD5_CALC_CHK": "md5sum kiszámítása és ellenőrzése", + "VTLANG_CHKSUM_SHA1_CALC_CHK": "sha1sum kiszámítása és ellenőrzése", + "VTLANG_CHKSUM_SHA256_CALC_CHK": "sha256sum kiszámítása és ellenőrzése", + "VTLANG_CHKSUM_SHA512_CALC_CHK": "sha512sum kiszámítása és ellenőrzése", + + "VTLANG_POWER": "Főkapcsoló", + "VTLANG_POWER_REBOOT": "Újraindítás", + "VTLANG_POWER_HALT": "Leállítás", + "VTLANG_POWER_BOOT_EFIFW": "Újraindítás EFI beállításba", + + "VTLANG_KEYBRD_LAYOUT": "Billentyűzetkiosztások", + "VTLANG_HWINFO": "Hardverinformációk", + + "VTLANG_RESOLUTION_CFG": "Felbontás beállítása", + "VTLANG_SCREEN_MODE": "Képernyő megjelenítési módja", + "VTLANG_SCREEN_TEXT_MODE": "Szöveges mód kényszerítése", + "VTLANG_SCREEN_GUI_MODE": "Grafikus mód kényszerítése", + + "VTLANG_THEME_SELECT": "Téma kiválasztása", + + "VTLANG_UEFI_UTIL": "Ventoy UEFI-segédprogramok", + "VTLANG_UTIL_SHOW_EFI_DRV": "EFI-illesztőprogramok megjelenítése", + "VTLANG_UTIL_FIX_BLINIT_FAIL": "A Windows BlinitializeLibrary hibájának javítása", + + "VTLANG_JSON_CHK_JSON": "A bővítmény JSON-beállításának (ventoy.json) ellenőrzése", + "VTLANG_JSON_CHK_CONTROL": "A globális vezérlőbővítmény beállításának ellenőrzése", + "VTLANG_JSON_CHK_THEME": "A téma bővítmény beállításnak ellenőrzése", + "VTLANG_JSON_CHK_AUTOINS": "Az automatikus telepítés bővítmény beállításának ellenőrzése", + "VTLANG_JSON_CHK_PERSIST": "Az állandóság bővítmény beállításának ellenőrzése", + "VTLANG_JSON_CHK_MENU_ALIAS": "A menüálnév bővítmény beállításának ellenőrzése", + "VTLANG_JSON_CHK_MENU_TIP": "A menütipp bővítmény beállításának ellenőrzése", + "VTLANG_JSON_CHK_MENU_CLASS": "A menüosztály bővítmény beállításának ellenőrzése", + "VTLANG_JSON_CHK_INJECTION": "A befecskendezés bővítmény beállításnak ellenőrzése", + "VTLANG_JSON_CHK_AUTO_MEMDISK": "Az automatikus memórialemez bővítmény beállításának ellenőrzése", + "VTLANG_JSON_CHK_IMG_LIST": "A lemezképlista bővítmény beállításnak ellenőrzése", + "VTLANG_JSON_CHK_IMG_BLIST": "A lemezkép-tiltólista bővítmény beállításnak ellenőrzése", + "VTLANG_JSON_CHK_CONF_REPLACE": "Az indítási beállítás csere bővítmény beállításnak ellenőrzése", + "VTLANG_JSON_CHK_DUD": "A dud bővítmény beállításnak ellenőrzése", + "VTLANG_JSON_CHK_PASSWORD": "A jelszó bővítmény beállításnak ellenőrzése", + + "VTLANG_NORMAL_MODE": "Indítás normál módban", + "VTLANG_WIMBOOT_MODE": "Indítás wimboot módban", + "VTLANG_GRUB2_MODE": "Indítás grub2 módban", + "VTLANG_MEMDISK_MODE": "Indítás memórialemez módban", + + "VTLANG_RET_TO_LISTVIEW": "Vissza a listanézethez", + "VTLANG_RET_TO_TREEVIEW": "Vissza a fanézethez", + + "VTLANG_NO_AUTOINS_SCRIPT": "Indítás automatikus telepítési sablon nélkül", + "VTLANG_AUTOINS_USE": "Indítás ezzel:", + + "VTLANG_NO_PERSIST": "Indítás állandóság nélkül", + "VTLANG_PERSIST_USE": "Indítás ezzel:", + + "VTLANG_BROWER_RETURN": "Vissza", + + "VTLANG_ENTER_EXIT": "nyomja meg az Enter billentyűt a kilépéshez", + "VTLANG_ENTER_REBOOT": "nyomja meg az Enter billentyűt az újraindításhoz", + "VTLANG_ENTER_CONTINUE": "nyomja meg az Enter billentyűt a folytatáshoz", + + "VTLANG_CTRL_TEMP_SET": "Ideiglenes vezérlési beállítások", + "VTLANG_WIN11_BYPASS_CHECK": "CPU/TPM/SecureBoot ellenőrzés megkerülése Windows 11 telepítésekor", + "VTLANG_WIN11_BYPASS_NRO": "Internetes fiók követelményének megkerülése Windows 11 telepítésekor", + "VTLANG_LINUX_REMOUNT": "Ventoy partíció csatolása a Linux indítása után", + "VTLANG_SECONDARY_BOOT_MENU": "Másodlagos indítási menü megjelenítése", + "VTLANG_WIN_UEFI_RES_LOCK": "Lock the resolution when UEFI boot Windows/WinPE", + "VTLANG_UEFI_RES_LOCK_NONE": "None", + "VTLANG_UEFI_RES_LOCK_MAX": "Highest", + "VTLANG_UEFI_RES_LOCK_1024_768": "Fixed 1024 x 768", + "VTLANG_UEFI_RES_LOCK_BE1024_768": "At least 1024 x 768", + + + "MENU_STR_XXX": "" +} \ No newline at end of file diff --git a/INSTALL/grub/menu/id_ID.json b/INSTALL/grub/menu/id_ID.json new file mode 100644 index 0000000..bd7e850 --- /dev/null +++ b/INSTALL/grub/menu/id_ID.json @@ -0,0 +1,99 @@ +{ + "VTLANG_LANGUAGE_NAME": "Indonesian (Bahasa Indonesia)", + + "VTLANG_STR_HOTKEY_LIST": "L:Bahasa F1:Bantuan F2:Jelajah F3:ListView F4:boot lokal F5:Alat Utilitas F6:Menu Eksternal", + "VTLANG_STR_HOTKEY_TREE": "L:Bahasa F1:Bantuan F2:Jelajah F3:ListView F4:boot lokal F5:Alat Utilitas F6:Menu Eksternal", + "VTLANG_RETURN_PREVIOUS": "Kembali ke menu sebelumnya [Esc]", + "VTLANG_RETURN_PRV_NOESC": "Kembali ke menu sebelumnya", + + "VTLANG_MENU_LANG": "Menu Pilihan Bahasa", + + "VTLANG_LB_SBOOT_WINDOWS": "Mencari dan jalankan boot ke Windows", + "VTLANG_LB_SBOOT_G4D": "Mencari dan jalankan boot ke Grub4dos", + "VTLANG_LB_SBOOT_HDD1": "Jalankan boot ke disk lokal 1", + "VTLANG_LB_SBOOT_HDD2": "Jalankan boot ke disk lokal 2", + "VTLANG_LB_SBOOT_HDD3": "Jalankan boot ke disk lokal 3", + "VTLANG_LB_SBOOT_X64EFI": "Jalankan boot ke disk lokal nomor 1 BOOTX64.EFI", + "VTLANG_LB_SBOOT_IA32EFI": "Mencari dan jalankan boot ke BOOTIA32.EFI", + "VTLANG_LB_SBOOT_AA64EFI": "Mencari dan jalankan boot ke BOOTAA64.EFI", + "VTLANG_LB_SBOOT_XORBOOT": "Mencari dan jalankan boot ke xorboot", + + "VTLANG_FILE_CHKSUM": "Berkas checksum", + "VTLANG_CHKSUM_MD5_CALC": "Menghitung md5sum", + "VTLANG_CHKSUM_SHA1_CALC": "Menghitung sha1sum", + "VTLANG_CHKSUM_SHA256_CALC": "Menghitung sha256sum", + "VTLANG_CHKSUM_SHA512_CALC": "Menghitung sha512sum", + "VTLANG_CHKSUM_MD5_CALC_CHK": "Menghitung dan memeriksa md5sum", + "VTLANG_CHKSUM_SHA1_CALC_CHK": "Menghitung dan memeriksa sha1sum", + "VTLANG_CHKSUM_SHA256_CALC_CHK": "Menghitung dan memeriksa sha256sum", + "VTLANG_CHKSUM_SHA512_CALC_CHK": "Menghitung dan memeriksa sha512sum", + + "VTLANG_POWER": "Daya", + "VTLANG_POWER_REBOOT": "Memulai ulang", + "VTLANG_POWER_HALT": "Mematikan", + "VTLANG_POWER_BOOT_EFIFW": "Memulai ulang menuju EFI setup", + + "VTLANG_KEYBRD_LAYOUT": "Tata letak Keyboard", + "VTLANG_HWINFO": "Informasi Perangkat Keras", + + "VTLANG_RESOLUTION_CFG": "Setelan Resolusi", + "VTLANG_SCREEN_MODE": "Mode Tampilan Layar", + "VTLANG_SCREEN_TEXT_MODE": "Paksa ke Mode Teks", + "VTLANG_SCREEN_GUI_MODE": "Paksa ke Mode Grafis", + + "VTLANG_THEME_SELECT": "Pilih Tema", + + "VTLANG_UEFI_UTIL": "Utilitas UEFI Ventoy", + "VTLANG_UTIL_SHOW_EFI_DRV": "Tampilkan Driver EFI", + "VTLANG_UTIL_FIX_BLINIT_FAIL": "Memperbaiki Kegagalan Windows BlinitializeLibrary", + + "VTLANG_JSON_CHK_JSON": "Periksa setelan plugin (ventoy.json)", + "VTLANG_JSON_CHK_CONTROL": "Periksa setelan plugin global control", + "VTLANG_JSON_CHK_THEME": "Periksa setelan plugin theme", + "VTLANG_JSON_CHK_AUTOINS": "Periksa setelan plugin auto install", + "VTLANG_JSON_CHK_PERSIST": "Periksa setelan plugin persistence", + "VTLANG_JSON_CHK_MENU_ALIAS": "Periksa setelan plugin menu alias", + "VTLANG_JSON_CHK_MENU_TIP": "Periksa setelan plugin tip", + "VTLANG_JSON_CHK_MENU_CLASS": "Periksa setelan class plugin menu", + "VTLANG_JSON_CHK_INJECTION": "Periksa setelan plugin injection", + "VTLANG_JSON_CHK_AUTO_MEMDISK": "Periksa setelan plugin auto memdisk", + "VTLANG_JSON_CHK_IMG_LIST": "Periksa setelan plugin image list", + "VTLANG_JSON_CHK_IMG_BLIST": "Periksa setelant plugin image blacklis", + "VTLANG_JSON_CHK_CONF_REPLACE": "Periksa setelan plugin boot conf replace", + "VTLANG_JSON_CHK_DUD": "Periksa setelan plugin dud", + "VTLANG_JSON_CHK_PASSWORD": "Periksa setelan plugin password", + + "VTLANG_NORMAL_MODE": "Jalankan boot di mode normal", + "VTLANG_WIMBOOT_MODE": "Jalankan boot di mode wimboot", + "VTLANG_GRUB2_MODE": "Jalankan boot di mode grub2", + "VTLANG_MEMDISK_MODE": "Jalankan boot di mode memdisk", + + "VTLANG_RET_TO_LISTVIEW": "Kembali ke ListView", + "VTLANG_RET_TO_TREEVIEW": "Kembali ke TreeView", + + "VTLANG_NO_AUTOINS_SCRIPT": "Jalankan boot tanpa templat instalasi otomatis", + "VTLANG_AUTOINS_USE": "Jalankan boot dengan", + + "VTLANG_NO_PERSIST": "Jalankan boot tanpa persistence", + "VTLANG_PERSIST_USE": "Jalankan boot", + + "VTLANG_BROWER_RETURN": "Kembali", + + "VTLANG_ENTER_EXIT": "tekan tombol Enter untuk keluar", + "VTLANG_ENTER_REBOOT": "tekan tombol Enter untuk memulai ulang", + "VTLANG_ENTER_CONTINUE": "tekan tombol Enter untuk melanjutkan", + + "VTLANG_CTRL_TEMP_SET": "Pengaturan Kontrol Sementara", + "VTLANG_WIN11_BYPASS_CHECK": "Melewati pemeriksaaan CPU/TPM/SecureBoot ketika memasang Windows 11", + "VTLANG_WIN11_BYPASS_NRO": "Melewati persyaratan akun online ketika memasang Windows 11", + "VTLANG_LINUX_REMOUNT": "Memuat partisi Ventoy setelah boot ke Linux", + "VTLANG_SECONDARY_BOOT_MENU": "Tampilkan menu boot sekunder", + "VTLANG_WIN_UEFI_RES_LOCK": "Lock the resolution when UEFI boot Windows/WinPE", + "VTLANG_UEFI_RES_LOCK_NONE": "None", + "VTLANG_UEFI_RES_LOCK_MAX": "Highest", + "VTLANG_UEFI_RES_LOCK_1024_768": "Fixed 1024 x 768", + "VTLANG_UEFI_RES_LOCK_BE1024_768": "At least 1024 x 768", + + + "MENU_STR_XXX": "" +} diff --git a/INSTALL/grub/menu/it_IT.json b/INSTALL/grub/menu/it_IT.json new file mode 100644 index 0000000..0dff3e8 --- /dev/null +++ b/INSTALL/grub/menu/it_IT.json @@ -0,0 +1,99 @@ +{ + "VTLANG_LANGUAGE_NAME": "Italiano (Italian)", + + "VTLANG_STR_HOTKEY_LIST": "L:Lingua F1:Aiuto F2:Sfoglia F3:VistaElenco F4:BootLocale F5:Strumenti F6:MenuEx", + "VTLANG_STR_HOTKEY_TREE": "L:Lingua F1:Aiuto F2:Sfoglia F3:VistaStruttura F4:BootLocale F5:Strumenti F6:MenuEx", + "VTLANG_RETURN_PREVIOUS": "Torna al menu precedente [Esc]", + "VTLANG_RETURN_PRV_NOESC": "Torna al menu precedente", + + "VTLANG_MENU_LANG": "Selezione lingua interfaccia", + + "VTLANG_LB_SBOOT_WINDOWS": "Cerca e avvia Windows", + "VTLANG_LB_SBOOT_G4D": "Cerca e avvia Grub4dos", + "VTLANG_LB_SBOOT_HDD1": "Avvia il 1° disco locale", + "VTLANG_LB_SBOOT_HDD2": "Avvia il 2° disco locale", + "VTLANG_LB_SBOOT_HDD3": "Avvia il 3° disco locale", + "VTLANG_LB_SBOOT_X64EFI": "Cerca e avvia BOOTX64.EFI", + "VTLANG_LB_SBOOT_IA32EFI": "Cerca e avvia BOOTIA32.EFI", + "VTLANG_LB_SBOOT_AA64EFI": "Cerca e avvia BOOTAA64.EFI", + "VTLANG_LB_SBOOT_XORBOOT": "Cerca e avvia xorboot", + + "VTLANG_FILE_CHKSUM": "File checksum", + "VTLANG_CHKSUM_MD5_CALC": "Calcola md5sum", + "VTLANG_CHKSUM_SHA1_CALC": "Calcola sha1sum", + "VTLANG_CHKSUM_SHA256_CALC": "Calcola sha256sum", + "VTLANG_CHKSUM_SHA512_CALC": "Calcola sha512sum", + "VTLANG_CHKSUM_MD5_CALC_CHK": "Calcola e controlla md5sum", + "VTLANG_CHKSUM_SHA1_CALC_CHK": "Calcola e controlla sha1sum", + "VTLANG_CHKSUM_SHA256_CALC_CHK": "Calcola e controlla sha256sum", + "VTLANG_CHKSUM_SHA512_CALC_CHK": "Calcola e controlla sha512sum", + + "VTLANG_POWER": "Spegni il computer", + "VTLANG_POWER_REBOOT": "Riavvia il computer", + "VTLANG_POWER_HALT": "Arresta il computer", + "VTLANG_POWER_BOOT_EFIFW": "Riavvia il computer nell'impostazione EFI", + + "VTLANG_KEYBRD_LAYOUT": "Layout tastiera", + "VTLANG_HWINFO": "Informazioni hardware computer", + + "VTLANG_RESOLUTION_CFG": "Imposta risoluzione schermo", + "VTLANG_SCREEN_MODE": "Modalità schermo (testo/grafica)", + "VTLANG_SCREEN_TEXT_MODE": "Forza modalità testo schermo", + "VTLANG_SCREEN_GUI_MODE": "Forza modalità grafica schermo", + + "VTLANG_THEME_SELECT": "Seleziona tema interfaccia", + + "VTLANG_UEFI_UTIL": "Utilità UEFI Ventoy", + "VTLANG_UTIL_SHOW_EFI_DRV": "Visualizza driver EFI", + "VTLANG_UTIL_FIX_BLINIT_FAIL": "Correzione fallimento BlinitializeLibrary di Windows", + + "VTLANG_JSON_CHK_JSON": "Modifica file .json plugin (ventoy.json)", + "VTLANG_JSON_CHK_CONTROL": "Modifica controllo globale della configurazione dei plugin", + "VTLANG_JSON_CHK_THEME": "Modifica tema configurazione dei plugin", + "VTLANG_JSON_CHK_AUTOINS": "Modifica installazione automatica della configurazione dei plugin", + "VTLANG_JSON_CHK_PERSIST": "Modifica persistenza della configurazione dei plugin", + "VTLANG_JSON_CHK_MENU_ALIAS": "Modifica l'alias del menu della configurazione dei plugin", + "VTLANG_JSON_CHK_MENU_TIP": "Modifica suggerimento del menu della configurazione dei plugin", + "VTLANG_JSON_CHK_MENU_CLASS": "Modifica classe menu configurazione plugin", + "VTLANG_JSON_CHK_INJECTION": "Modifica injection della configurazione plugin", + "VTLANG_JSON_CHK_AUTO_MEMDISK": "Modifica memdisk automatico della configurazione dei plugin", + "VTLANG_JSON_CHK_IMG_LIST": "Modifica elenco immagini configurazione plugin", + "VTLANG_JSON_CHK_IMG_BLIST": "Modifica elenco immagini vietate configurazione plugin", + "VTLANG_JSON_CHK_CONF_REPLACE": "Modifica sostituzione configurazione di avvio configurazione dei plugin", + "VTLANG_JSON_CHK_DUD": "Modifica dud configurazione plugin", + "VTLANG_JSON_CHK_PASSWORD": "Modifica password configurazione plugin", + + "VTLANG_NORMAL_MODE": "Avvia in modalità normale", + "VTLANG_WIMBOOT_MODE": "Avvia in modalità wimboot", + "VTLANG_GRUB2_MODE": "Avvia in modalità grub2", + "VTLANG_MEMDISK_MODE": "Avvia in modalità memdisk", + + "VTLANG_RET_TO_LISTVIEW": "Torna alla VistaElenco", + "VTLANG_RET_TO_TREEVIEW": "Torna alla VistaStruttura", + + "VTLANG_NO_AUTOINS_SCRIPT": "Avvia senza il modello installazione automatica", + "VTLANG_AUTOINS_USE": "Avvia con", + + "VTLANG_NO_PERSIST": "Avvia senza persistenza", + "VTLANG_PERSIST_USE": "Avvia con", + + "VTLANG_BROWER_RETURN": "Indietro", + + "VTLANG_ENTER_EXIT": "Premi il tasto 'Invio' per uscire", + "VTLANG_ENTER_REBOOT": "Premi il tasto 'Invio' per riavviare", + "VTLANG_ENTER_CONTINUE": "Premi il tasto 'Invio' per continuare", + + "VTLANG_CTRL_TEMP_SET": "Impostazioni controllo temporaneo", + "VTLANG_WIN11_BYPASS_CHECK": "Durante l'installazione di Windows 11 bypassa il controllo CPU/TPM/SecureBoot ", + "VTLANG_WIN11_BYPASS_NRO": "Durante l'installazione di Windows 11 bypassa il requisito di un account online ", + "VTLANG_LINUX_REMOUNT": "Dopo l'avvio di Linux monta la partizione Ventoy ", + "VTLANG_SECONDARY_BOOT_MENU": "Visualizza menu di avvio secondario", + "VTLANG_WIN_UEFI_RES_LOCK": "Lock the resolution when UEFI boot Windows/WinPE", + "VTLANG_UEFI_RES_LOCK_NONE": "None", + "VTLANG_UEFI_RES_LOCK_MAX": "Highest", + "VTLANG_UEFI_RES_LOCK_1024_768": "Fixed 1024 x 768", + "VTLANG_UEFI_RES_LOCK_BE1024_768": "At least 1024 x 768", + + + "MENU_STR_XXX": "" +} diff --git a/INSTALL/grub/menu/ja_JP.json b/INSTALL/grub/menu/ja_JP.json new file mode 100644 index 0000000..5378f5c --- /dev/null +++ b/INSTALL/grub/menu/ja_JP.json @@ -0,0 +1,99 @@ +{ + "VTLANG_LANGUAGE_NAME": "Japanese (日本語)", + + "VTLANG_STR_HOTKEY_LIST": "L:言語 F1:説明 F2:閲覧 F3:表示切替(階層) F4:手許から起動 F5:道具 F6:拡張", + "VTLANG_STR_HOTKEY_TREE": "L:言語 F1:説明 F2:閲覧 F3:表示切替(一覧) F4:手許から起動 F5:道具 F6:拡張", + "VTLANG_RETURN_PREVIOUS": "前に戻る [Esc]", + "VTLANG_RETURN_PRV_NOESC": "前に戻る", + + "VTLANG_MENU_LANG": "表示言語", + + "VTLANG_LB_SBOOT_WINDOWS": "Windowsを検索して起動する", + "VTLANG_LB_SBOOT_G4D": "GRUB4DOSを検索して起動する", + "VTLANG_LB_SBOOT_HDD1": "最初の機器を起動します", + "VTLANG_LB_SBOOT_HDD2": "2番目の機器を起動する", + "VTLANG_LB_SBOOT_HDD3": "3番目の機器を起動する", + "VTLANG_LB_SBOOT_X64EFI": "BOOTX64.EFIを検索して起動する", + "VTLANG_LB_SBOOT_IA32EFI": "BOOTIA32.EFIを検索して起動する", + "VTLANG_LB_SBOOT_AA64EFI": "BOOTAA64.EFIを検索して起動する", + "VTLANG_LB_SBOOT_XORBOOT": "xorbootを検索して起動する", + + "VTLANG_FILE_CHKSUM": "検査合計", + "VTLANG_CHKSUM_MD5_CALC": "MD5を算出する", + "VTLANG_CHKSUM_SHA1_CALC": "SHA1を算出する", + "VTLANG_CHKSUM_SHA256_CALC": "SHA256を算出する", + "VTLANG_CHKSUM_SHA512_CALC": "SHA512を算出する", + "VTLANG_CHKSUM_MD5_CALC_CHK": "MD5を算出して検証する", + "VTLANG_CHKSUM_SHA1_CALC_CHK": "SHA1を算出して検証する", + "VTLANG_CHKSUM_SHA256_CALC_CHK": "SHA256を算出して検証する", + "VTLANG_CHKSUM_SHA512_CALC_CHK": "SHA512を算出して検証する", + + "VTLANG_POWER": "電源", + "VTLANG_POWER_REBOOT": "再起動", + "VTLANG_POWER_HALT": "電源断", + "VTLANG_POWER_BOOT_EFIFW": "再起動してEFIを構成する", + + "VTLANG_KEYBRD_LAYOUT": "鍵盤配列", + "VTLANG_HWINFO": "機器情報", + + "VTLANG_RESOLUTION_CFG": "画面解像度", + "VTLANG_SCREEN_MODE": "表示の種類", + "VTLANG_SCREEN_TEXT_MODE": "CLI表示を強制する", + "VTLANG_SCREEN_GUI_MODE": "GUI表示を強制する", + + "VTLANG_THEME_SELECT": "外観", + + "VTLANG_UEFI_UTIL": "Ventoy UEFI Utilities", + "VTLANG_UTIL_SHOW_EFI_DRV": "EFIドライバを表示する", + "VTLANG_UTIL_FIX_BLINIT_FAIL": "Windowsが「BlinitializeLibrary Failure」で起動しないのを修正する", + + "VTLANG_JSON_CHK_JSON": "拡張機能のJSON構成ファイル (ventoy.json) を検査する", + "VTLANG_JSON_CHK_CONTROL": "拡張機能「global control」の構成を検査する", + "VTLANG_JSON_CHK_THEME": "拡張機能「theme」の構成を検査する", + "VTLANG_JSON_CHK_AUTOINS": "拡張機能「auto install」の構成を検査する", + "VTLANG_JSON_CHK_PERSIST": "拡張機能「persistence」の構成を検査する", + "VTLANG_JSON_CHK_MENU_ALIAS": "拡張機能「menu alias」の構成を検査する", + "VTLANG_JSON_CHK_MENU_TIP": "拡張機能「menu tip」の構成を検査する", + "VTLANG_JSON_CHK_MENU_CLASS": "拡張機能「menu class」の構成を検査する", + "VTLANG_JSON_CHK_INJECTION": "拡張機能「injection」の構成を検査する", + "VTLANG_JSON_CHK_AUTO_MEMDISK": "拡張機能「auto memdisk」の構成を検査する", + "VTLANG_JSON_CHK_IMG_LIST": "拡張機能「image list」の構成を検査する", + "VTLANG_JSON_CHK_IMG_BLIST": "拡張機能「image blacklist」の構成を検査する", + "VTLANG_JSON_CHK_CONF_REPLACE": "拡張機能「boot conf replace」の構成を検査する", + "VTLANG_JSON_CHK_DUD": "拡張機能「dud」の構成を検査する", + "VTLANG_JSON_CHK_PASSWORD": "拡張機能「password」の構成を検査する", + + "VTLANG_NORMAL_MODE": "通常どおり起動", + "VTLANG_WIMBOOT_MODE": "WimBootを介して起動", + "VTLANG_GRUB2_MODE": "GRUB2を介して起動", + "VTLANG_MEMDISK_MODE": "MEMDISKを介して起動", + + "VTLANG_RET_TO_LISTVIEW": "一覧表示に切り替える", + "VTLANG_RET_TO_TREEVIEW": "階層表示に切り替える", + + "VTLANG_NO_AUTOINS_SCRIPT": "起動後に自動でインストールを行わない", + "VTLANG_AUTOINS_USE": "自動インストールを行う", + + "VTLANG_NO_PERSIST": "Live環境の永続保管領域を無効にする", + "VTLANG_PERSIST_USE": "有効にする", + + "VTLANG_BROWER_RETURN": "戻る", + + "VTLANG_ENTER_EXIT": "[Enter]を押して終了します", + "VTLANG_ENTER_REBOOT": "[Enter]を押して再起動します", + "VTLANG_ENTER_CONTINUE": "[Enter]を押して続行します", + + "VTLANG_CTRL_TEMP_SET": "Temporary Control Settings", + "VTLANG_WIN11_BYPASS_CHECK": "Bypass CPU/TPM/SecureBoot check when install Windows 11", + "VTLANG_WIN11_BYPASS_NRO": "Bypass online account requirement when install Windows 11", + "VTLANG_LINUX_REMOUNT": "Mount Ventoy partition after boot Linux", + "VTLANG_SECONDARY_BOOT_MENU": "Show secondary boot menu", + "VTLANG_WIN_UEFI_RES_LOCK": "Lock the resolution when UEFI boot Windows/WinPE", + "VTLANG_UEFI_RES_LOCK_NONE": "None", + "VTLANG_UEFI_RES_LOCK_MAX": "Highest", + "VTLANG_UEFI_RES_LOCK_1024_768": "Fixed 1024 x 768", + "VTLANG_UEFI_RES_LOCK_BE1024_768": "At least 1024 x 768", + + + "MENU_STR_XXX": "" +} diff --git a/INSTALL/grub/menu/ka_GE.json b/INSTALL/grub/menu/ka_GE.json new file mode 100644 index 0000000..af86d82 --- /dev/null +++ b/INSTALL/grub/menu/ka_GE.json @@ -0,0 +1,99 @@ +{ + "VTLANG_LANGUAGE_NAME": "Georgian (ქართული)", + + "VTLANG_STR_HOTKEY_LIST": "L:ენა F1:დახმარება F2:დათვალიერება F3:სიის ხედი F4:ლოკალური ჩატვირთვა F5:ხელსაწყოები F6:გასვლა", + "VTLANG_STR_HOTKEY_TREE": "L:ენა F1:დახმარება F2:დათვალიერება F3:ხის ხედი F4:ლოკალური ჩატვირთვა F5:ხელსაწყოები F6:გასვლა", + "VTLANG_RETURN_PREVIOUS": "წინა მენიუში დაბრუნება [Esc]", + "VTLANG_RETURN_PRV_NOESC": "წინა მენიუში დაბრუნება", + + "VTLANG_MENU_LANG": "მენიუს ენის არჩევა", + + "VTLANG_LB_SBOOT_WINDOWS": "Windows-ის მოძებნა და ჩატვირთვა", + "VTLANG_LB_SBOOT_G4D": "Grub4dos-ის მოძებნა და ჩატვირთვა", + "VTLANG_LB_SBOOT_HDD1": "1-ლი ლოკალური მყარი დისკიდან ჩატვირთვა", + "VTLANG_LB_SBOOT_HDD2": "მე-2 ლოკალური მყარი დისკიდან ჩატვირთვა", + "VTLANG_LB_SBOOT_HDD3": "მე-3 ლოკალური მყარი დისკიდან ჩატვირთვა", + "VTLANG_LB_SBOOT_X64EFI": "BOOTX64.EFI-ის მოძებნა და ჩატვირთვა", + "VTLANG_LB_SBOOT_IA32EFI": "BOOTIA32.EFI-ის მოძებნა და ჩატვირთვა", + "VTLANG_LB_SBOOT_AA64EFI": "BOOTAA64.EFI-ის მოძებნა და ჩატვირთვა", + "VTLANG_LB_SBOOT_XORBOOT": "xorboot-ის მოძებნა და ჩატვირთვა", + + "VTLANG_FILE_CHKSUM": "ფაილის საკონტროლო ჯამი", + "VTLANG_CHKSUM_MD5_CALC": "md5sum გამოთვლა", + "VTLANG_CHKSUM_SHA1_CALC": "sha1sum გამოთვლა", + "VTLANG_CHKSUM_SHA256_CALC": "sha256sum გამოთვლა", + "VTLANG_CHKSUM_SHA512_CALC": "sha512sum გამოთვლა", + "VTLANG_CHKSUM_MD5_CALC_CHK": "md5sum გამოთვლა და შემოწმება", + "VTLANG_CHKSUM_SHA1_CALC_CHK": "sha1sum გამოთვლა და შემოწმება", + "VTLANG_CHKSUM_SHA256_CALC_CHK": "sha256sum გამოთვლა და შემოწმება", + "VTLANG_CHKSUM_SHA512_CALC_CHK": "sha512sum გამოთვლა და შემოწმება", + + "VTLANG_POWER": "კომპიუტერის გამორთვა", + "VTLANG_POWER_REBOOT": "კომპიუტერის გადატვირთვა", + "VTLANG_POWER_HALT": "კომპიუტერის გაჩერება", + "VTLANG_POWER_BOOT_EFIFW": "გადატვირთვა EFI კონფიგურაციის რეჟიმში", + + "VTLANG_KEYBRD_LAYOUT": "კლავიატურის განლაგებები", + "VTLANG_HWINFO": "ინფორმაცია მოწყობილობების შესახებ", + + "VTLANG_RESOLUTION_CFG": "გარჩევადობის კონფიგურაცია", + "VTLANG_SCREEN_MODE": "ჩვენების რეჟიმი", + "VTLANG_SCREEN_TEXT_MODE": "ჩვენების ტექსტური რეჟიმი", + "VTLANG_SCREEN_GUI_MODE": "ჩვენების გრაფიკული რეჟიმი", + + "VTLANG_THEME_SELECT": "თემის არჩევა", + + "VTLANG_UEFI_UTIL": "Ventoy UEFI Utilities", + "VTLANG_UTIL_SHOW_EFI_DRV": "EFI დრაივერების ჩვენება", + "VTLANG_UTIL_FIX_BLINIT_FAIL": "Windows BlinitializeLibrary ხარვეზის გასწორება", + + "VTLANG_JSON_CHK_JSON": "მოდულების json კონფიგურაციის შემოწმება (ventoy.json)", + "VTLANG_JSON_CHK_CONTROL": "global control მოდულის კონფიგურაციის შემოწმება", + "VTLANG_JSON_CHK_THEME": "theme მოდულის კონფიგურაციის შემოწმება", + "VTLANG_JSON_CHK_AUTOINS": "auto install მოდულის კონფიგურაციის შემოწმება", + "VTLANG_JSON_CHK_PERSIST": "persistence მოდულის კონფიგურაციის შემოწმება", + "VTLANG_JSON_CHK_MENU_ALIAS": "menu alias მოდულის კონფიგურაციის შემოწმება", + "VTLANG_JSON_CHK_MENU_TIP": "menu tip მოდულის კონფიგურაციის შემოწმება", + "VTLANG_JSON_CHK_MENU_CLASS": "menu class მოდულის კონფიგურაციის შემოწმება", + "VTLANG_JSON_CHK_INJECTION": "injection მოდულის კონფიგურაციის შემოწმება", + "VTLANG_JSON_CHK_AUTO_MEMDISK": "auto memdisk მოდულის კონფიგურაციის შემოწმება", + "VTLANG_JSON_CHK_IMG_LIST": "image list მოდულის კონფიგურაციის შემოწმება", + "VTLANG_JSON_CHK_IMG_BLIST": "image blacklist მოდულის კონფიგურაციის შემოწმება", + "VTLANG_JSON_CHK_CONF_REPLACE": "boot conf replace მოდულის კონფიგურაციის შემოწმება", + "VTLANG_JSON_CHK_DUD": "dud მოდულის კონფიგურაციის შემოწმება", + "VTLANG_JSON_CHK_PASSWORD": "password მოდულის კონფიგურაციის შემოწმება", + + "VTLANG_NORMAL_MODE": "ჩატვირთვა normal რეჟიმში", + "VTLANG_WIMBOOT_MODE": "ჩატვირთვა wimboot რეჟიმში", + "VTLANG_GRUB2_MODE": "ჩატვირთვა grub2 რეჟიმში", + "VTLANG_MEMDISK_MODE": "ჩატვირთვა memdisk რეჟიმში", + + "VTLANG_RET_TO_LISTVIEW": "სიის ხედის დაბრუნება", + "VTLANG_RET_TO_TREEVIEW": "ხის ხედის დაბრუნება", + + "VTLANG_NO_AUTOINS_SCRIPT": "ჩატვირთვა ავტომატური ინსტალაციის სკრიპტის გარეშე", + "VTLANG_AUTOINS_USE": "ჩატვირთვა ავტომატური ინსტალაციის რეჟიმში", + + "VTLANG_NO_PERSIST": "ჩატვირთვა ცვლილებების შენახვის რეჟიმის გარეშე", + "VTLANG_PERSIST_USE": "ჩატვირთვა ცვლილებების შენახვის რეჟიმში", + + "VTLANG_BROWER_RETURN": "დაბრუნება", + + "VTLANG_ENTER_EXIT": "გასასვლელად დააჭირეთ Enter ღილაკს", + "VTLANG_ENTER_REBOOT": "დააჭირეთ Enter ღილაკს გადატვირთვისთვის", + "VTLANG_ENTER_CONTINUE": "გასაგრძელებლად დააჭირეთ Enter ღილაკს", + + "VTLANG_CTRL_TEMP_SET": "Temporary Control Settings", + "VTLANG_WIN11_BYPASS_CHECK": "Bypass CPU/TPM/SecureBoot check when install Windows 11", + "VTLANG_WIN11_BYPASS_NRO": "Bypass online account requirement when install Windows 11", + "VTLANG_LINUX_REMOUNT": "Mount Ventoy partition after boot Linux", + "VTLANG_SECONDARY_BOOT_MENU": "Show secondary boot menu", + "VTLANG_WIN_UEFI_RES_LOCK": "Lock the resolution when UEFI boot Windows/WinPE", + "VTLANG_UEFI_RES_LOCK_NONE": "None", + "VTLANG_UEFI_RES_LOCK_MAX": "Highest", + "VTLANG_UEFI_RES_LOCK_1024_768": "Fixed 1024 x 768", + "VTLANG_UEFI_RES_LOCK_BE1024_768": "At least 1024 x 768", + + + "MENU_STR_XXX": "" +} diff --git a/INSTALL/grub/menu/ko_KR.json b/INSTALL/grub/menu/ko_KR.json new file mode 100644 index 0000000..bd3c168 --- /dev/null +++ b/INSTALL/grub/menu/ko_KR.json @@ -0,0 +1,99 @@ +{ + "VTLANG_LANGUAGE_NAME": "Korean (한국어)", + + "VTLANG_STR_HOTKEY_LIST": " L:언어 F1:도움말 F2:찾아보기 F3:목록 보기 F4:로컬 부팅 F5:도구 F6:확장 메뉴", + "VTLANG_STR_HOTKEY_TREE": " L:언어 F1:도움말 F2:찾아보기 F3:트리 보기 F4:로컬 부팅 F5:도구 F6:확장 메뉴", + "VTLANG_RETURN_PREVIOUS": "이전 메뉴로 돌아가기 [Esc]", + "VTLANG_RETURN_PRV_NOESC": "이전 메뉴로 돌아가기", + + "VTLANG_MENU_LANG": "메뉴 언어 선택", + + "VTLANG_LB_SBOOT_WINDOWS": "Windows 검색 및 부팅", + "VTLANG_LB_SBOOT_G4D": "Grub4dos 검색 및 부팅", + "VTLANG_LB_SBOOT_HDD1": "첫 번째 로컬 디스크 부팅", + "VTLANG_LB_SBOOT_HDD2": "두 번째 로컬 디스크 부팅", + "VTLANG_LB_SBOOT_HDD3": "세 번째 로컬 디스크 부팅", + "VTLANG_LB_SBOOT_X64EFI": "BOOTX64.EFI 검색 및 부팅", + "VTLANG_LB_SBOOT_IA32EFI": "BOOTIA32.EFI 검색 및 부팅", + "VTLANG_LB_SBOOT_AA64EFI": "BOOTAA64.EFI 검색 및 부팅", + "VTLANG_LB_SBOOT_XORBOOT": "xorboot 검색 및 부팅", + + "VTLANG_FILE_CHKSUM": "파일 체크섬", + "VTLANG_CHKSUM_MD5_CALC": "md5 검사값 계산", + "VTLANG_CHKSUM_SHA1_CALC": "sha1 검사값 계산", + "VTLANG_CHKSUM_SHA256_CALC": "sha256 검사값 계산", + "VTLANG_CHKSUM_SHA512_CALC": "sha512 검사값 계산", + "VTLANG_CHKSUM_MD5_CALC_CHK": "md5 검사값 계산 및 확인", + "VTLANG_CHKSUM_SHA1_CALC_CHK": "sha1 검사값 계산 및 확인", + "VTLANG_CHKSUM_SHA256_CALC_CHK": "sha256 검사값 계산 및 확인", + "VTLANG_CHKSUM_SHA512_CALC_CHK": "sha512 검사값 계산 및 확인", + + "VTLANG_POWER": "전원", + "VTLANG_POWER_REBOOT": "다시 시작", + "VTLANG_POWER_HALT": "전원 끄기", + "VTLANG_POWER_BOOT_EFIFW": "UEFI 설정으로 다시 시작", + + "VTLANG_KEYBRD_LAYOUT": "키보드 레이아웃", + "VTLANG_HWINFO": "하드웨어 정보", + + "VTLANG_RESOLUTION_CFG": "해상도 구성", + "VTLANG_SCREEN_MODE": "화면 표시 모드", + "VTLANG_SCREEN_TEXT_MODE": "강제 텍스트 모드", + "VTLANG_SCREEN_GUI_MODE": "강제 그래픽 모드", + + "VTLANG_THEME_SELECT": "테마 선택", + + "VTLANG_UEFI_UTIL": "Ventoy UEFI 유틸리티", + "VTLANG_UTIL_SHOW_EFI_DRV": "UEFI 드라이버 표시", + "VTLANG_UTIL_FIX_BLINIT_FAIL": "Windows 초기화 라이브러리 오류 복구", + + "VTLANG_JSON_CHK_JSON": "플러그인 파일 구성 확인 (ventoy.json)", + "VTLANG_JSON_CHK_CONTROL": "전역 제어 플러그인 구성 확인", + "VTLANG_JSON_CHK_THEME": "테마 플러그인 구성 확인", + "VTLANG_JSON_CHK_AUTOINS": "자동 설치 플러그인 구성 확인", + "VTLANG_JSON_CHK_PERSIST": "영구화 플러그인 구성 확인", + "VTLANG_JSON_CHK_MENU_ALIAS": "메뉴 별칭 플러그인 구성 확인", + "VTLANG_JSON_CHK_MENU_TIP": "메뉴 팁 플러그인 구성 확인", + "VTLANG_JSON_CHK_MENU_CLASS": "메뉴 클래스 플러그인 구성 확인", + "VTLANG_JSON_CHK_INJECTION": "주입 플러그인 구성 확인", + "VTLANG_JSON_CHK_AUTO_MEMDISK": "자동 메모리 디스크 플러그인 구성 확인", + "VTLANG_JSON_CHK_IMG_LIST": "이미지 목록 플러그인 구성 확인", + "VTLANG_JSON_CHK_IMG_BLIST": "이미지 블랙리스트 플러그인 구성 확인", + "VTLANG_JSON_CHK_CONF_REPLACE": "부팅 구성 대체 플러그인 구성 확인", + "VTLANG_JSON_CHK_DUD": "드라이버 업데이트 디스크 플러그인 구성 확인", + "VTLANG_JSON_CHK_PASSWORD": "암호 플러그인 구성 확인", + + "VTLANG_NORMAL_MODE": "일반 모드로 부팅", + "VTLANG_WIMBOOT_MODE": "wimboot 모드로 부팅", + "VTLANG_GRUB2_MODE": "grub2 모드로 부팅", + "VTLANG_MEMDISK_MODE": "메모리 디스크 모드로 부팅", + + "VTLANG_RET_TO_LISTVIEW": "목록보기로 돌아가기", + "VTLANG_RET_TO_TREEVIEW": "트리보기로 돌아가기", + + "VTLANG_NO_AUTOINS_SCRIPT": "자동 설치 스크립트 사용 안 함", + "VTLANG_AUTOINS_USE": "부팅 대상", + + "VTLANG_NO_PERSIST": "영구화된 데이터 파일 사용 안 함", + "VTLANG_PERSIST_USE": "부팅 대상", + + "VTLANG_BROWER_RETURN": "돌아가기", + + "VTLANG_ENTER_EXIT": "종료하려면 Enter 키를 누르십시오", + "VTLANG_ENTER_REBOOT": "다시 시작하려면 Enter 키를 누르십시오", + "VTLANG_ENTER_CONTINUE": "계속하려면 Enter 키를 누르십시오", + + "VTLANG_CTRL_TEMP_SET": "임시 제어 설정", + "VTLANG_WIN11_BYPASS_CHECK": "Windows 11 설치 시 CPU/TPM/SecureBoot 검사 회피", + "VTLANG_WIN11_BYPASS_NRO": "Windows 11 설치 시 온라인 계정 요구 사항 무시", + "VTLANG_LINUX_REMOUNT": "Linux 부팅 후 Ventoy 파티션 마운트", + "VTLANG_SECONDARY_BOOT_MENU": "보조 부팅 메뉴 표시", + "VTLANG_WIN_UEFI_RES_LOCK": "UEFI 부팅 시 Windows/WinPE 해상도 고정", + "VTLANG_UEFI_RES_LOCK_NONE": "고정 안 함", + "VTLANG_UEFI_RES_LOCK_MAX": "최고 해상도로 고정", + "VTLANG_UEFI_RES_LOCK_1024_768": "1024 x 768로 고정", + "VTLANG_UEFI_RES_LOCK_BE1024_768": "1024 x 768 이상으로 고정", + + + "MENU_STR_XXX": "" +} diff --git a/INSTALL/grub/menu/lg_UG.json b/INSTALL/grub/menu/lg_UG.json new file mode 100644 index 0000000..397423a --- /dev/null +++ b/INSTALL/grub/menu/lg_UG.json @@ -0,0 +1,99 @@ +{ + "VTLANG_LANGUAGE_NAME": "English (English)", + + "VTLANG_STR_HOTKEY_LIST": "L:Language F1:Help F2:Browse F3:ListView F4:Localboot F5:Tools F6:ExMenu", + "VTLANG_STR_HOTKEY_TREE": "L:Language F1:Help F2:Browse F3:TreeView F4:Localboot F5:Tools F6:ExMenu", + "VTLANG_RETURN_PREVIOUS": "Return to previous menu [Esc]", + "VTLANG_RETURN_PRV_NOESC": "Return to previous menu", + + "VTLANG_MENU_LANG": "Menu Language Select", + + "VTLANG_LB_SBOOT_WINDOWS": "Search and boot Windows", + "VTLANG_LB_SBOOT_G4D": "Search and boot Grub4dos", + "VTLANG_LB_SBOOT_HDD1": "Boot the 1st local disk", + "VTLANG_LB_SBOOT_HDD2": "Boot the 2nd local disk", + "VTLANG_LB_SBOOT_HDD3": "Boot the 3rd local disk", + "VTLANG_LB_SBOOT_X64EFI": "Search and boot BOOTX64.EFI", + "VTLANG_LB_SBOOT_IA32EFI": "Search and boot BOOTIA32.EFI", + "VTLANG_LB_SBOOT_AA64EFI": "Search and boot BOOTAA64.EFI", + "VTLANG_LB_SBOOT_XORBOOT": "Search and boot xorboot", + + "VTLANG_FILE_CHKSUM": "File checksum", + "VTLANG_CHKSUM_MD5_CALC": "Calculate md5sum", + "VTLANG_CHKSUM_SHA1_CALC": "Calculate sha1sum", + "VTLANG_CHKSUM_SHA256_CALC": "Calculate sha256sum", + "VTLANG_CHKSUM_SHA512_CALC": "Calculate sha512sum", + "VTLANG_CHKSUM_MD5_CALC_CHK": "Calculate and check md5sum", + "VTLANG_CHKSUM_SHA1_CALC_CHK": "Calculate and check sha1sum", + "VTLANG_CHKSUM_SHA256_CALC_CHK": "Calculate and check sha256sum", + "VTLANG_CHKSUM_SHA512_CALC_CHK": "Calculate and check sha512sum", + + "VTLANG_POWER": "Power", + "VTLANG_POWER_REBOOT": "Reboot", + "VTLANG_POWER_HALT": "Halt", + "VTLANG_POWER_BOOT_EFIFW": "Reboot to EFI setup", + + "VTLANG_KEYBRD_LAYOUT": "Keyboard Layouts", + "VTLANG_HWINFO": "Hardware Information", + + "VTLANG_RESOLUTION_CFG": "Resolution Configuration", + "VTLANG_SCREEN_MODE": "Screen Display Mode", + "VTLANG_SCREEN_TEXT_MODE": "Force Text Mode", + "VTLANG_SCREEN_GUI_MODE": "Force Graphics Mode", + + "VTLANG_THEME_SELECT": "Theme Select", + + "VTLANG_UEFI_UTIL": "Ventoy UEFI Utilities", + "VTLANG_UTIL_SHOW_EFI_DRV": "Show EFI Drivers", + "VTLANG_UTIL_FIX_BLINIT_FAIL": "Fixup Windows BlinitializeLibrary Failure", + + "VTLANG_JSON_CHK_JSON": "Check plugin json configuration (ventoy.json)", + "VTLANG_JSON_CHK_CONTROL": "Check global control plugin configuration", + "VTLANG_JSON_CHK_THEME": "Check theme plugin configuration", + "VTLANG_JSON_CHK_AUTOINS": "Check auto install plugin configuration", + "VTLANG_JSON_CHK_PERSIST": "Check persistence plugin configuration", + "VTLANG_JSON_CHK_MENU_ALIAS": "Check menu alias plugin configuration", + "VTLANG_JSON_CHK_MENU_TIP": "Check menu tip plugin configuration", + "VTLANG_JSON_CHK_MENU_CLASS": "Check menu class plugin configuration", + "VTLANG_JSON_CHK_INJECTION": "Check injection plugin configuration", + "VTLANG_JSON_CHK_AUTO_MEMDISK": "Check auto memdisk plugin configuration", + "VTLANG_JSON_CHK_IMG_LIST": "Check image list plugin configuration", + "VTLANG_JSON_CHK_IMG_BLIST": "Check image blacklist plugin configuration", + "VTLANG_JSON_CHK_CONF_REPLACE": "Check boot conf replace plugin configuration", + "VTLANG_JSON_CHK_DUD": "Check dud plugin configuration", + "VTLANG_JSON_CHK_PASSWORD": "Check password plugin configuration", + + "VTLANG_NORMAL_MODE": "Boot in normal mode", + "VTLANG_WIMBOOT_MODE": "Boot in wimboot mode", + "VTLANG_GRUB2_MODE": "Boot in grub2 mode", + "VTLANG_MEMDISK_MODE": "Boot in memdisk mode", + + "VTLANG_RET_TO_LISTVIEW": "Return to ListView", + "VTLANG_RET_TO_TREEVIEW": "Return to TreeView", + + "VTLANG_NO_AUTOINS_SCRIPT": "Boot without auto installation template", + "VTLANG_AUTOINS_USE": "Boot with", + + "VTLANG_NO_PERSIST": "Boot without persistence", + "VTLANG_PERSIST_USE": "Boot with", + + "VTLANG_BROWER_RETURN": "Return", + + "VTLANG_ENTER_EXIT": "press Enter key to exit", + "VTLANG_ENTER_REBOOT": "press Enter key to reboot", + "VTLANG_ENTER_CONTINUE": "press Enter key to continue", + + "VTLANG_CTRL_TEMP_SET": "Temporary Control Settings", + "VTLANG_WIN11_BYPASS_CHECK": "Bypass CPU/TPM/SecureBoot check when install Windows 11", + "VTLANG_WIN11_BYPASS_NRO": "Bypass online account requirement when install Windows 11", + "VTLANG_LINUX_REMOUNT": "Mount Ventoy partition after boot Linux", + "VTLANG_SECONDARY_BOOT_MENU": "Show secondary boot menu", + "VTLANG_WIN_UEFI_RES_LOCK": "Lock the resolution when UEFI boot Windows/WinPE", + "VTLANG_UEFI_RES_LOCK_NONE": "None", + "VTLANG_UEFI_RES_LOCK_MAX": "Highest", + "VTLANG_UEFI_RES_LOCK_1024_768": "Fixed 1024 x 768", + "VTLANG_UEFI_RES_LOCK_BE1024_768": "At least 1024 x 768", + + + "MENU_STR_XXX": "" +} diff --git a/INSTALL/grub/menu/pl_PL.json b/INSTALL/grub/menu/pl_PL.json new file mode 100644 index 0000000..d78c4f6 --- /dev/null +++ b/INSTALL/grub/menu/pl_PL.json @@ -0,0 +1,99 @@ +{ + "VTLANG_LANGUAGE_NAME": "Polish (Poland)", + + "VTLANG_STR_HOTKEY_LIST": "L:Język F1:Pomoc F2:Przeglądaj F3:Widok listy F4:Localboot F5:Narzędzia F6:ExMenu", + "VTLANG_STR_HOTKEY_TREE": "L:Język F1:Pomoc F2:Przeglądaj F3:Widok drzewa F4:Localboot F5:Narzędzia F6:ExMenu", + "VTLANG_RETURN_PREVIOUS": "Powrót do poprzedniego menu [Esc]", + "VTLANG_RETURN_PRV_NOESC": "Powrót do poprzedniego menu", + + "VTLANG_MENU_LANG": "Wybierz język menu", + + "VTLANG_LB_SBOOT_WINDOWS": "Wyszukaj i uruchom Windows", + "VTLANG_LB_SBOOT_G4D": "Wyszukaj i uruchom Grub4dos", + "VTLANG_LB_SBOOT_HDD1": "Uruchom pierwszy dysk lokalny", + "VTLANG_LB_SBOOT_HDD2": "Uruchom drugi dysk lokalny", + "VTLANG_LB_SBOOT_HDD3": "Uruchom trzeci dysk lokalny", + "VTLANG_LB_SBOOT_X64EFI": "Wyszukaj i uruchom BOOTX64.EFI", + "VTLANG_LB_SBOOT_IA32EFI": "Wyszukaj i uruchom BOOTIA32.EFI", + "VTLANG_LB_SBOOT_AA64EFI": "Wyszukaj i uruchom BOOTAA64.EFI", + "VTLANG_LB_SBOOT_XORBOOT": "Wyszukaj i uruchom xorboot", + + "VTLANG_FILE_CHKSUM": "Suma kontrolna pliku", + "VTLANG_CHKSUM_MD5_CALC": "Oblicz sumę md5", + "VTLANG_CHKSUM_SHA1_CALC": "Oblicz sumę sha1", + "VTLANG_CHKSUM_SHA256_CALC": "Oblicz sumę sha256", + "VTLANG_CHKSUM_SHA512_CALC": "Oblicz sumę sha512", + "VTLANG_CHKSUM_MD5_CALC_CHK": "Oblicz i sprawdź sumę md5", + "VTLANG_CHKSUM_SHA1_CALC_CHK": "Oblicz i sprawdź sumę sha1", + "VTLANG_CHKSUM_SHA256_CALC_CHK": "Oblicz i sprawdź sumę sha256", + "VTLANG_CHKSUM_SHA512_CALC_CHK": "Oblicz i sprawdź sumę sha512", + + "VTLANG_POWER": "Opcje zasilania", + "VTLANG_POWER_REBOOT": "Uruchom ponownie", + "VTLANG_POWER_HALT": "Zakończ", + "VTLANG_POWER_BOOT_EFIFW": "Uruchom ponownie i przejdź do konfiguracji EFI", + + "VTLANG_KEYBRD_LAYOUT": "Układy klawiatury", + "VTLANG_HWINFO": "Informacje o konfiguracji sprzętowej", + + "VTLANG_RESOLUTION_CFG": "Konfiguracja rozdzielczości", + "VTLANG_SCREEN_MODE": "Tryb wyświetlania ekranu", + "VTLANG_SCREEN_TEXT_MODE": "Wymuś tryb tekstowy", + "VTLANG_SCREEN_GUI_MODE": "Wymuś tryb graficzny", + + "VTLANG_THEME_SELECT": "Wybierz motyw", + + "VTLANG_UEFI_UTIL": "Narzędzia Ventoy UEFI", + "VTLANG_UTIL_SHOW_EFI_DRV": "Pokaż sterowniki EFI", + "VTLANG_UTIL_FIX_BLINIT_FAIL": "Napraw błąd BlinitializeLibrary systemu Windows", + + "VTLANG_JSON_CHK_JSON": "Sprawdź konfigurację pluginu json (ventoy.json)", + "VTLANG_JSON_CHK_CONTROL": "Sprawdź konfigurację pluginu Global Control", + "VTLANG_JSON_CHK_THEME": "Sprawdź konfigurację pluginu Theme", + "VTLANG_JSON_CHK_AUTOINS": "Sprawdź konfigurację pluginu Auto Installation", + "VTLANG_JSON_CHK_PERSIST": "Sprawdź konfigurację pluginu Persistence", + "VTLANG_JSON_CHK_MENU_ALIAS": "Sprawdź konfigurację pluginu Menu Alias", + "VTLANG_JSON_CHK_MENU_TIP": "Sprawdź konfigurację pluginu Menu Tip", + "VTLANG_JSON_CHK_MENU_CLASS": "Sprawdź konfigurację pluginu Menu Class", + "VTLANG_JSON_CHK_INJECTION": "Sprawdź konfigurację pluginu Injection", + "VTLANG_JSON_CHK_AUTO_MEMDISK": "Sprawdź konfigurację pluginu Auto Memdisk", + "VTLANG_JSON_CHK_IMG_LIST": "Sprawdź konfigurację pluginu Image List", + "VTLANG_JSON_CHK_IMG_BLIST": "Sprawdź konfigurację pluginu Blacklist dla obrazów", + "VTLANG_JSON_CHK_CONF_REPLACE": "Sprawdź konfigurację pluginu Boot Conf Replace", + "VTLANG_JSON_CHK_DUD": "Sprawdź konfigurację pluginu DUD (Driver Update Disk)", + "VTLANG_JSON_CHK_PASSWORD": "Sprawdź konfigurację pluginu Password", + + "VTLANG_NORMAL_MODE": "Uruchom w trybie normalnym", + "VTLANG_WIMBOOT_MODE": "Uruchom w trybie Wimboot", + "VTLANG_GRUB2_MODE": "Uruchom w trybie grub2", + "VTLANG_MEMDISK_MODE": "Uruchom w trybie memdisk", + + "VTLANG_RET_TO_LISTVIEW": "Powrót do widoku listy", + "VTLANG_RET_TO_TREEVIEW": "Powrót do widoku drzewa", + + "VTLANG_NO_AUTOINS_SCRIPT": "Uruchom bez szablonu automatycznej instalacji", + "VTLANG_AUTOINS_USE": "Uruchom z", + + "VTLANG_NO_PERSIST": "Uruchom bez persistence (zapisywania ustawień)", + "VTLANG_PERSIST_USE": "Uruchom z", + + "VTLANG_BROWER_RETURN": "Powrót", + + "VTLANG_ENTER_EXIT": "naciśnij klawisz Enter, aby wyjść", + "VTLANG_ENTER_REBOOT": "naciśnij klawisz Enter, aby ponownie uruchomić", + "VTLANG_ENTER_CONTINUE": "naciśnij klawisz Enter, aby kontynuować", + + "VTLANG_CTRL_TEMP_SET": "Tymczasowe ustawienia kontroli", + "VTLANG_WIN11_BYPASS_CHECK": "Pominięcie sprawdzania CPU/TPM/SecureBoot podczas instalacji Windows 11", + "VTLANG_WIN11_BYPASS_NRO": "Pominięcie wymogu posiadania konta Microsoft podczas instalacji Windows 11", + "VTLANG_LINUX_REMOUNT": "Zamontuj partycję Ventoy po uruchomieniu Linuksa", + "VTLANG_SECONDARY_BOOT_MENU": "Pokaż dodatkowe menu rozruchowe (boot menu)", + "VTLANG_WIN_UEFI_RES_LOCK": "Zablokuj rozdzielczość podczas bootowania UEFI Windows/WinPE", + "VTLANG_UEFI_RES_LOCK_NONE": "Brak", + "VTLANG_UEFI_RES_LOCK_MAX": "Najwyższa", + "VTLANG_UEFI_RES_LOCK_1024_768": "Stała 1024 x 768", + "VTLANG_UEFI_RES_LOCK_BE1024_768": "Co najmniej 1024 x 768", + + + "MENU_STR_XXX": "" +} diff --git a/INSTALL/grub/menu/pt_BR.json b/INSTALL/grub/menu/pt_BR.json new file mode 100644 index 0000000..a6a249b --- /dev/null +++ b/INSTALL/grub/menu/pt_BR.json @@ -0,0 +1,99 @@ +{ + "VTLANG_LANGUAGE_NAME": "Brazilian Portuguese (Português Brasileiro)", + + "VTLANG_STR_HOTKEY_LIST": "L:Idioma F1:Ajuda F2:Explorar F3:Visualização em Lista F4:Inicialização Local F5:Ferramentas F6:Sair", + "VTLANG_STR_HOTKEY_TREE": "L:Idioma F1:Ajuda F2:Explorar F3:Visualização em Árvore F4:Inicialização Local F5:Ferramentas F6:Sair", + "VTLANG_RETURN_PREVIOUS": "Retornar ao menu anterior [Esc]", + "VTLANG_RETURN_PRV_NOESC": "Retornar ao menu anterior", + + "VTLANG_MENU_LANG": "Menu de Seleção dos Idiomas", + + "VTLANG_LB_SBOOT_WINDOWS": "Procurar e iniciar o Windows", + "VTLANG_LB_SBOOT_G4D": "Procurar e iniciar o Grub4dos", + "VTLANG_LB_SBOOT_HDD1": "Iniciar o 1º disco local", + "VTLANG_LB_SBOOT_HDD2": "Iniciar o 2º disco local", + "VTLANG_LB_SBOOT_HDD3": "Iniciar o 3º disco local", + "VTLANG_LB_SBOOT_X64EFI": "Procurar e iniciar o BOOTX64.EFI", + "VTLANG_LB_SBOOT_IA32EFI": "Procurar e iniciar o BOOTIA32.EFI", + "VTLANG_LB_SBOOT_AA64EFI": "Procurar e iniciar o BOOTAA64.EFI", + "VTLANG_LB_SBOOT_XORBOOT": "Procurar e iniciar o xorboot", + + "VTLANG_FILE_CHKSUM": "Checksum do arquivo", + "VTLANG_CHKSUM_MD5_CALC": "Calcular o md5sum", + "VTLANG_CHKSUM_SHA1_CALC": "Calcular o sha1sum", + "VTLANG_CHKSUM_SHA256_CALC": "Calcular o sha256sum", + "VTLANG_CHKSUM_SHA512_CALC": "Calcular o sha512sum", + "VTLANG_CHKSUM_MD5_CALC_CHK": "Calcular e verificar o md5sum", + "VTLANG_CHKSUM_SHA1_CALC_CHK": "Calcular e verificar o sha1sum", + "VTLANG_CHKSUM_SHA256_CALC_CHK": "Calcular e verificar o sha256sum", + "VTLANG_CHKSUM_SHA512_CALC_CHK": "Calcular e verificar o sha512sum", + + "VTLANG_POWER": "Energia", + "VTLANG_POWER_REBOOT": "Reiniciar", + "VTLANG_POWER_HALT": "Desligar", + "VTLANG_POWER_BOOT_EFIFW": "Reiniciar com a configuração do EFI", + + "VTLANG_KEYBRD_LAYOUT": "Esquemas do Teclado", + "VTLANG_HWINFO": "Informações do Hardware", + + "VTLANG_RESOLUTION_CFG": "Configuração da Resolução", + "VTLANG_SCREEN_MODE": "Modo de Exibição da Tela", + "VTLANG_SCREEN_TEXT_MODE": "Forçar o Modo Texto", + "VTLANG_SCREEN_GUI_MODE": "Forçar o Modo Gráfico", + + "VTLANG_THEME_SELECT": "Seleção de Tema", + + "VTLANG_UEFI_UTIL": "Utilitários UEFI do Ventoy", + "VTLANG_UTIL_SHOW_EFI_DRV": "Mostrar os Drivers EFI", + "VTLANG_UTIL_FIX_BLINIT_FAIL": "Consertar a Falha BlinitializeLibrary do Windows", + + "VTLANG_JSON_CHK_JSON": "Verificar a configuração do plugin json (ventoy.json)", + "VTLANG_JSON_CHK_CONTROL": "Verificar a configuração do plugin de controle global", + "VTLANG_JSON_CHK_THEME": "Verificar a configuração do plugin dos temas", + "VTLANG_JSON_CHK_AUTOINS": "Verificar a configuração do plugin de instalação automática", + "VTLANG_JSON_CHK_PERSIST": "Verificar a configuração do plugin de persistência", + "VTLANG_JSON_CHK_MENU_ALIAS": "Verificar a configuração do plugin do menu alias", + "VTLANG_JSON_CHK_MENU_TIP": "Verificar a configuração do plugin do menu das dicas", + "VTLANG_JSON_CHK_MENU_CLASS": "Verificar a configuração do plugin do menu classe", + "VTLANG_JSON_CHK_INJECTION": "Verificar a configuração do plugin de injeção", + "VTLANG_JSON_CHK_AUTO_MEMDISK": "Verificar a configuração do plugin automático do memdisk", + "VTLANG_JSON_CHK_IMG_LIST": "Verificar a configuração do plugin da lista de imagens", + "VTLANG_JSON_CHK_IMG_BLIST": "Verificar a configuração do plugin da lista negra de imagens", + "VTLANG_JSON_CHK_CONF_REPLACE": "Verificar a configuração do plugin de substituição da configuração de inicialização", + "VTLANG_JSON_CHK_DUD": "Verificar a configuração do plugin dud", + "VTLANG_JSON_CHK_PASSWORD": "Verificar a configuração do plugin das senhas", + + "VTLANG_NORMAL_MODE": "Iniciar no modo normal", + "VTLANG_WIMBOOT_MODE": "Iniciar no modo wimboot", + "VTLANG_GRUB2_MODE": "Iniciar no modo grub2", + "VTLANG_MEMDISK_MODE": "Iniciar no modo memdisk", + + "VTLANG_RET_TO_LISTVIEW": "Retornar pra Visualização em Lista", + "VTLANG_RET_TO_TREEVIEW": "Retornar para Visualização em Árvore", + + "VTLANG_NO_AUTOINS_SCRIPT": "Iniciar sem modelo de instalação automática", + "VTLANG_AUTOINS_USE": "Iniciar com", + + "VTLANG_NO_PERSIST": "Iniciar sem persistência", + "VTLANG_PERSIST_USE": "Iniciar com", + + "VTLANG_BROWER_RETURN": "Retornar", + + "VTLANG_ENTER_EXIT": "Pressione a tecla Enter pra sair", + "VTLANG_ENTER_REBOOT": "Pressione a tecla Enter pra reiniciar", + "VTLANG_ENTER_CONTINUE": "Pressione a tecla Enter pra continuar", + + "VTLANG_CTRL_TEMP_SET": "Configurações do Controle Temporário", + "VTLANG_WIN11_BYPASS_CHECK": "Ignorar a verificação da CPU/TPM/SecureBoot quando instalar o Windows 11", + "VTLANG_WIN11_BYPASS_NRO": "Ignorar o requerimento de conta online quanto instalar o Windows 11", + "VTLANG_LINUX_REMOUNT": "Montar a partição do Ventoy após iniciar o Linux", + "VTLANG_SECONDARY_BOOT_MENU": "Mostrar o menu secundário da inicialização", + "VTLANG_WIN_UEFI_RES_LOCK": "Lock the resolution when UEFI boot Windows/WinPE", + "VTLANG_UEFI_RES_LOCK_NONE": "None", + "VTLANG_UEFI_RES_LOCK_MAX": "Highest", + "VTLANG_UEFI_RES_LOCK_1024_768": "Fixed 1024 x 768", + "VTLANG_UEFI_RES_LOCK_BE1024_768": "At least 1024 x 768", + + + "MENU_STR_XXX": "" +} diff --git a/INSTALL/grub/menu/pt_PT.json b/INSTALL/grub/menu/pt_PT.json new file mode 100644 index 0000000..446fe1b --- /dev/null +++ b/INSTALL/grub/menu/pt_PT.json @@ -0,0 +1,99 @@ +{ + "VTLANG_LANGUAGE_NAME": "Portuguese (Português de Portugal)", + + "VTLANG_STR_HOTKEY_LIST": "L:Idioma F1:Ajuda F2:Navegar F3:Estrutura F4:Arranque local F5:Ferramentas F6:Sair", + "VTLANG_STR_HOTKEY_TREE": "L:Idioma F1:Ajuda F2:Navegar F3:Estrutura F4:Arranque local F5:Ferramentas F6:Sair", + "VTLANG_RETURN_PREVIOUS": "Voltar ao menu anterior [Esc]", + "VTLANG_RETURN_PRV_NOESC": "Voltar ao menu anterior", + + "VTLANG_MENU_LANG": "Seleção de idioma do menu", + + "VTLANG_LB_SBOOT_WINDOWS": "Pesquisar e iniciar o Windows", + "VTLANG_LB_SBOOT_G4D": "Pesquisar e iniciar o Grub4dos", + "VTLANG_LB_SBOOT_HDD1": "Arrancar o 1º disco local", + "VTLANG_LB_SBOOT_HDD2": "Arrancar o 2º disco local", + "VTLANG_LB_SBOOT_HDD3": "Arrancar o 3º disco local", + "VTLANG_LB_SBOOT_X64EFI": "Pesquisar e iniciar o BOOTX64.EFI", + "VTLANG_LB_SBOOT_IA32EFI": "Pesquisar e iniciar o BOOTIA32.EFI", + "VTLANG_LB_SBOOT_AA64EFI": "Pesquisar e iniciar o BOOTAA64.EFI", + "VTLANG_LB_SBOOT_XORBOOT": "Pesquisar e iniciar o xorboot", + + "VTLANG_FILE_CHKSUM": "Checksum do ficheiro", + "VTLANG_CHKSUM_MD5_CALC": "Calcular MD5", + "VTLANG_CHKSUM_SHA1_CALC": "Calcular SHA1", + "VTLANG_CHKSUM_SHA256_CALC": "Calcular SHA256", + "VTLANG_CHKSUM_SHA512_CALC": "Calcular SHA512", + "VTLANG_CHKSUM_MD5_CALC_CHK": "Calcular e verificar MD5", + "VTLANG_CHKSUM_SHA1_CALC_CHK": "Calcular e verificar SHA1", + "VTLANG_CHKSUM_SHA256_CALC_CHK": "Calcular e verificar SHA256", + "VTLANG_CHKSUM_SHA512_CALC_CHK": "Calcular e verificar SHA512", + + "VTLANG_POWER": "Energia", + "VTLANG_POWER_REBOOT": "Reiniciar", + "VTLANG_POWER_HALT": "Desligar", + "VTLANG_POWER_BOOT_EFIFW": "Reiniciar com a configuração EFI", + + "VTLANG_KEYBRD_LAYOUT": "Esquemas de teclado", + "VTLANG_HWINFO": "Informação do hardware", + + "VTLANG_RESOLUTION_CFG": "Configuração da resolução", + "VTLANG_SCREEN_MODE": "Modo de exibição", + "VTLANG_SCREEN_TEXT_MODE": "Modo texto", + "VTLANG_SCREEN_GUI_MODE": "Modo gráfico", + + "VTLANG_THEME_SELECT": "Seleção de tema", + + "VTLANG_UEFI_UTIL": "Ventoy UEFI Utilities", + "VTLANG_UTIL_SHOW_EFI_DRV": "Mostrar controladores EFI", + "VTLANG_UTIL_FIX_BLINIT_FAIL": "Corrigir falha BlinitializeLibrary do Windows", + + "VTLANG_JSON_CHK_JSON": "Verificar configuração do plugin json (ventoy.json)", + "VTLANG_JSON_CHK_CONTROL": "Verificar a configuração do plugin de controlo global", + "VTLANG_JSON_CHK_THEME": "Verificar configuração do plugin do tema", + "VTLANG_JSON_CHK_AUTOINS": "Verificar a configuração do plugin de instalação automática", + "VTLANG_JSON_CHK_PERSIST": "Verificar a configuração do plugin de persistência", + "VTLANG_JSON_CHK_MENU_ALIAS": "Verificar a configuração do plugin do menu alias", + "VTLANG_JSON_CHK_MENU_TIP": "Verificar a configuração do plugin do menu de dica", + "VTLANG_JSON_CHK_MENU_CLASS": "Verificar a configuração do plugin do menu classe", + "VTLANG_JSON_CHK_INJECTION": "Verificar a configuração do plugin de injeção", + "VTLANG_JSON_CHK_AUTO_MEMDISK": "Verificar a configuração do plugin automático do memdisk", + "VTLANG_JSON_CHK_IMG_LIST": "Verificar configuração do plugin da lista de imagens", + "VTLANG_JSON_CHK_IMG_BLIST": "Verificar configuração do plugin da lista negra de imagens", + "VTLANG_JSON_CHK_CONF_REPLACE": "Verificar a configuração do plugin de substituição de conf. de arranque", + "VTLANG_JSON_CHK_DUD": "Verificar configuração do plugin dud", + "VTLANG_JSON_CHK_PASSWORD": "Verificar configuração do plugin palavra-passe", + + "VTLANG_NORMAL_MODE": "Arrancar no modo normal", + "VTLANG_WIMBOOT_MODE": "Arrancar no modo wimboot", + "VTLANG_GRUB2_MODE": "Arrancar no modo grub2", + "VTLANG_MEMDISK_MODE": "Arrancar no modo memdisk", + + "VTLANG_RET_TO_LISTVIEW": "Voltar para Lista", + "VTLANG_RET_TO_TREEVIEW": "Voltar para Estrutura", + + "VTLANG_NO_AUTOINS_SCRIPT": "Arrancar sem modelo de instalação automática", + "VTLANG_AUTOINS_USE": "Arrancar com", + + "VTLANG_NO_PERSIST": "Arrancar sem persistência", + "VTLANG_PERSIST_USE": "Arrancar com", + + "VTLANG_BROWER_RETURN": "Voltar", + + "VTLANG_ENTER_EXIT": "pressione a tecla Enter para sair", + "VTLANG_ENTER_REBOOT": "pressione a tecla Enter para reiniciar", + "VTLANG_ENTER_CONTINUE": "pressione a tecla Enter para continuar", + + "VTLANG_CTRL_TEMP_SET": "Configurações de Controle Temporário", + "VTLANG_WIN11_BYPASS_CHECK": "Ignorar checagem de CPU/TPM/SecureBoot quando instalando Windows 11", + "VTLANG_WIN11_BYPASS_NRO": "Ignorar requerimento de conta online quanto instalando Windows 11", + "VTLANG_LINUX_REMOUNT": "Montar partição Ventoy após boot do Linux", + "VTLANG_SECONDARY_BOOT_MENU": "Mostar menu seundário de boot", + "VTLANG_WIN_UEFI_RES_LOCK": "Lock the resolution when UEFI boot Windows/WinPE", + "VTLANG_UEFI_RES_LOCK_NONE": "None", + "VTLANG_UEFI_RES_LOCK_MAX": "Highest", + "VTLANG_UEFI_RES_LOCK_1024_768": "Fixed 1024 x 768", + "VTLANG_UEFI_RES_LOCK_BE1024_768": "At least 1024 x 768", + + + "MENU_STR_XXX": "" +} diff --git a/INSTALL/grub/menu/ru_RU.json b/INSTALL/grub/menu/ru_RU.json new file mode 100644 index 0000000..274151b --- /dev/null +++ b/INSTALL/grub/menu/ru_RU.json @@ -0,0 +1,99 @@ +{ + "VTLANG_LANGUAGE_NAME": "Russian (Русский)", + + "VTLANG_STR_HOTKEY_LIST": "L:Язык F1:Помощь F2:Обзор F3:ВидСписок F4:ЛокалЗагрузка F5:Сервис F6:РасширМеню", + "VTLANG_STR_HOTKEY_TREE": "L:Язык F1:Помощь F2:Обзор F3:ВидДерево F4:ЛокалЗагрузка F5:Сервис F6:РасширМеню", + "VTLANG_RETURN_PREVIOUS": "Вернуться в предыдущее меню [Esc]", + "VTLANG_RETURN_PRV_NOESC": "Вернуться в предыдущее меню", + + "VTLANG_MENU_LANG": "Выбор языка меню", + + "VTLANG_LB_SBOOT_WINDOWS": "Найти и загрузить Windows", + "VTLANG_LB_SBOOT_G4D": "Найти и загрузить Grub4dos", + "VTLANG_LB_SBOOT_HDD1": "Загрузить 1-й локальный диск", + "VTLANG_LB_SBOOT_HDD2": "Загрузить 2-й локальный диск", + "VTLANG_LB_SBOOT_HDD3": "Загрузить 3-й локальный диск", + "VTLANG_LB_SBOOT_X64EFI": "Найти и загрузить OOTX64.EFI", + "VTLANG_LB_SBOOT_IA32EFI": "Найти и загрузить BOOTIA32.EFI", + "VTLANG_LB_SBOOT_AA64EFI": "Найти и загрузить BOOTAA64.EFI", + "VTLANG_LB_SBOOT_XORBOOT": "Найти и загрузить xorboot", + + "VTLANG_FILE_CHKSUM": "Контрольная сумма файла", + "VTLANG_CHKSUM_MD5_CALC": "Вычислить md5sum", + "VTLANG_CHKSUM_SHA1_CALC": "Вычислить sha1sum", + "VTLANG_CHKSUM_SHA256_CALC": "Вычислить sha256sum", + "VTLANG_CHKSUM_SHA512_CALC": "Вычислить sha512sum", + "VTLANG_CHKSUM_MD5_CALC_CHK": "Вычислить и проверить md5sum", + "VTLANG_CHKSUM_SHA1_CALC_CHK": "Вычислить и проверить sha1sum", + "VTLANG_CHKSUM_SHA256_CALC_CHK": "Вычислить и проверить sha256sum", + "VTLANG_CHKSUM_SHA512_CALC_CHK": "Вычислить и проверить sha512sum", + + "VTLANG_POWER": "Питание", + "VTLANG_POWER_REBOOT": "Перезагрузить", + "VTLANG_POWER_HALT": "Завершить работу", + "VTLANG_POWER_BOOT_EFIFW": "Перезагрузиться в настройку EFI", + + "VTLANG_KEYBRD_LAYOUT": "Раскладки клавиатуры", + "VTLANG_HWINFO": "Сведения об оборудовании", + + "VTLANG_RESOLUTION_CFG": "Конфигурация разрешения", + "VTLANG_SCREEN_MODE": "Режим отображения экрана", + "VTLANG_SCREEN_TEXT_MODE": "Выбрать текстовый режим", + "VTLANG_SCREEN_GUI_MODE": "Выбрать графический режим", + + "VTLANG_THEME_SELECT": "Выбор темы", + + "VTLANG_UEFI_UTIL": "Утилиты UEFI Ventoy", + "VTLANG_UTIL_SHOW_EFI_DRV": "Показать драйверы EFI", + "VTLANG_UTIL_FIX_BLINIT_FAIL": "Исправить ошибку Windows «BlinitializeLibrary»", + + "VTLANG_JSON_CHK_JSON": "Проверить настройки расширения «json» (ventoy.json)", + "VTLANG_JSON_CHK_CONTROL": "Проверить настройки расширения «global control»", + "VTLANG_JSON_CHK_THEME": "Проверить настройки расширения «theme»", + "VTLANG_JSON_CHK_AUTOINS": "Проверить настройки расширения «auto install»", + "VTLANG_JSON_CHK_PERSIST": "Проверить настройки расширения «persistence»", + "VTLANG_JSON_CHK_MENU_ALIAS": "Проверить настройки расширения «menu alias»", + "VTLANG_JSON_CHK_MENU_TIP": "Проверить настройки расширения «menu tip»", + "VTLANG_JSON_CHK_MENU_CLASS": "Проверить настройки расширения «menu class»", + "VTLANG_JSON_CHK_INJECTION": "Проверить настройки расширения «injection»", + "VTLANG_JSON_CHK_AUTO_MEMDISK": "Проверить настройки расширения «auto memdisk»", + "VTLANG_JSON_CHK_IMG_LIST": "Проверить настройки расширения «image list»", + "VTLANG_JSON_CHK_IMG_BLIST": "Проверить настройки расширения «image blacklist»", + "VTLANG_JSON_CHK_CONF_REPLACE": "Проверить настройки расширения «boot conf replace»", + "VTLANG_JSON_CHK_DUD": "Проверить настройки расширения «dud»", + "VTLANG_JSON_CHK_PASSWORD": "Проверить настройки расширения «password»", + + "VTLANG_NORMAL_MODE": "Загрузиться в обычном режиме", + "VTLANG_WIMBOOT_MODE": "Загрузиться в режиме wimboot", + "VTLANG_GRUB2_MODE": "Загрузиться в режиме grub2", + "VTLANG_MEMDISK_MODE": "Загрузиться в режиме memdisk", + + "VTLANG_RET_TO_LISTVIEW": "Вернуться к Виду списком", + "VTLANG_RET_TO_TREEVIEW": "Вернуться к Виду древом", + + "VTLANG_NO_AUTOINS_SCRIPT": "Загрузка без шаблона автоматической установки", + "VTLANG_AUTOINS_USE": "Загрузиться с", + + "VTLANG_NO_PERSIST": "Загрузка без сохраняемости", + "VTLANG_PERSIST_USE": "Загрузиться с", + + "VTLANG_BROWER_RETURN": "Вернуться", + + "VTLANG_ENTER_EXIT": "нажмите клавишу ввода, чтобы выйти", + "VTLANG_ENTER_REBOOT": "нажмите клавишу ввода для перезагрузки", + "VTLANG_ENTER_CONTINUE": "нажмите клавишу ввода, чтобы продолжить", + + "VTLANG_CTRL_TEMP_SET": "Настройки временного управления", + "VTLANG_WIN11_BYPASS_CHECK": "Обойти проверку CPU/TPM/SecureBoot при установке Windows 11", + "VTLANG_WIN11_BYPASS_NRO": "Обойти требование сетевой учётной записи при установке Windows 11", + "VTLANG_LINUX_REMOUNT": "Смонтировать раздел Ventoy после загрузки Linux", + "VTLANG_SECONDARY_BOOT_MENU": "Показать вторичное загрузочное меню", + "VTLANG_WIN_UEFI_RES_LOCK": "Lock the resolution when UEFI boot Windows/WinPE", + "VTLANG_UEFI_RES_LOCK_NONE": "None", + "VTLANG_UEFI_RES_LOCK_MAX": "Highest", + "VTLANG_UEFI_RES_LOCK_1024_768": "Fixed 1024 x 768", + "VTLANG_UEFI_RES_LOCK_BE1024_768": "At least 1024 x 768", + + + "MENU_STR_XXX": "" +} diff --git a/INSTALL/grub/menu/sl_si.json b/INSTALL/grub/menu/sl_si.json new file mode 100644 index 0000000..9fca5a4 --- /dev/null +++ b/INSTALL/grub/menu/sl_si.json @@ -0,0 +1,99 @@ +{ + "VTLANG_LANGUAGE_NAME": "Slovenija (Slovenski)", + + "VTLANG_STR_HOTKEY_LIST": "L:Jezik F1:Pomoč F2:Prebrskaj F3:ListView F4:Localboot F5:Orodja F6:ExMenu", + "VTLANG_STR_HOTKEY_TREE": "L:Jezik F1:Pomoč F2:Prebrskaj F3:TreeView F4:Localboot F5:Orodja F6:ExMenu", + "VTLANG_RETURN_PREVIOUS": "Vrnitev v prejšnji meni [Esc]", + "VTLANG_RETURN_PRV_NOESC": "Vrnitev v prejšnji meni", + + "VTLANG_MENU_LANG": "Izbira jezika menija", + + "VTLANG_LB_SBOOT_WINDOWS": "Iskanje in zagon sistema Windows", + "VTLANG_LB_SBOOT_G4D": "Iskanje in zagon Grub4dos", + "VTLANG_LB_SBOOT_HDD1": "Zagon 1. lokalnega diska", + "VTLANG_LB_SBOOT_HDD2": "Zagon 2. lokalnega diska", + "VTLANG_LB_SBOOT_HDD3": "Zagon 3. lokalnega diska", + "VTLANG_LB_SBOOT_X64EFI": "Iskanje in zagon BOOTX64.EFI", + "VTLANG_LB_SBOOT_IA32EFI": "Iskanje in zagon BOOTIA32.EFI", + "VTLANG_LB_SBOOT_AA64EFI": "Iskanje in zagon BOOTAA64.EFI", + "VTLANG_LB_SBOOT_XORBOOT": "Iskanje in zagon xorboot", + + "VTLANG_FILE_CHKSUM": "File checksum", + "VTLANG_CHKSUM_MD5_CALC": "Izračunaj md5sum", + "VTLANG_CHKSUM_SHA1_CALC": "Izračunaj sha1sum", + "VTLANG_CHKSUM_SHA256_CALC": "Izračunaj sha256sum", + "VTLANG_CHKSUM_SHA512_CALC": "Izračunaj sha512sum", + "VTLANG_CHKSUM_MD5_CALC_CHK": "Izračunaj in preveri md5sum", + "VTLANG_CHKSUM_SHA1_CALC_CHK": "Izračunaj in preveri sha1sum", + "VTLANG_CHKSUM_SHA256_CALC_CHK": "Izračunaj in preveri sha256sum", + "VTLANG_CHKSUM_SHA512_CALC_CHK": "Izračunaj in preveri sha512sum", + + "VTLANG_POWER": "Napajanje", + "VTLANG_POWER_REBOOT": "Ponovni zagon", + "VTLANG_POWER_HALT": "Halt", + "VTLANG_POWER_BOOT_EFIFW": "Ponovni zagon v nastavitev EFI", + + "VTLANG_KEYBRD_LAYOUT": "Postavitev tipkovnice", + "VTLANG_HWINFO": "Informacije o strojni opremi", + + "VTLANG_RESOLUTION_CFG": "Nastavitev ločljivosti", + "VTLANG_SCREEN_MODE": "Način prikaza na zaslonu", + "VTLANG_SCREEN_TEXT_MODE": "Vsili besedilni način", + "VTLANG_SCREEN_GUI_MODE": "Vsili grafični način", + + "VTLANG_THEME_SELECT": "Izbira teme", + + "VTLANG_UEFI_UTIL": "Pripomočki Ventoy UEFI", + "VTLANG_UTIL_SHOW_EFI_DRV": "Prikaži gonilnike EFI", + "VTLANG_UTIL_FIX_BLINIT_FAIL": "Popravek napake Windows BlinitializeLibrary", + + "VTLANG_JSON_CHK_JSON": "Preverite konfiguracijo vtičnika json (ventoy.json)", + "VTLANG_JSON_CHK_CONTROL": "Preverite konfiguracijo globalnega nadzornega vtičnika", + "VTLANG_JSON_CHK_THEME": "Preverite konfiguracijo vtičnika teme", + "VTLANG_JSON_CHK_AUTOINS": "Preverite konfiguracijo vtičnika za samodejno namestitev", + "VTLANG_JSON_CHK_PERSIST": "Preverite konfiguracijo vtičnika persistence", + "VTLANG_JSON_CHK_MENU_ALIAS": "Preverite konfiguracijo vtičnika menija", + "VTLANG_JSON_CHK_MENU_TIP": "Preverite konfiguracijo vtičnika za nasvete menija", + "VTLANG_JSON_CHK_MENU_CLASS": "Preverite konfiguracijo vtičnika razreda menija", + "VTLANG_JSON_CHK_INJECTION": "Check injection plugin configuration", + "VTLANG_JSON_CHK_AUTO_MEMDISK": "Preverite konfiguracijo vtičnika Auto Memdisk.", + "VTLANG_JSON_CHK_IMG_LIST": "Preverite konfiguracijo vtičnika za seznam slik", + "VTLANG_JSON_CHK_IMG_BLIST": "Preverite konfiguracijo vtičnika za črno listo slik", + "VTLANG_JSON_CHK_CONF_REPLACE": "Preverite boot conf zamenjajte plugin konfiguracijo", + "VTLANG_JSON_CHK_DUD": "Preverite konfiguracijo vtičnika dud", + "VTLANG_JSON_CHK_PASSWORD": "Preverite konfiguracijo vtičnika za geslo", + + "VTLANG_NORMAL_MODE": "Zagon v običajnem načinu", + "VTLANG_WIMBOOT_MODE": "Zagon v načinu wimboot", + "VTLANG_GRUB2_MODE": "Zagon v načinu grub2", + "VTLANG_MEMDISK_MODE": "Zagon v načinu memdisk", + + "VTLANG_RET_TO_LISTVIEW": "Vrnitev na ListView", + "VTLANG_RET_TO_TREEVIEW": "Vrnitev v TreeView", + + "VTLANG_NO_AUTOINS_SCRIPT": "Zagon brez predloge za samodejno namestitev", + "VTLANG_AUTOINS_USE": "Zagon z", + + "VTLANG_NO_PERSIST": "Boot without persistence", + "VTLANG_PERSIST_USE": "Zagon z", + + "VTLANG_BROWER_RETURN": "Nazaj", + + "VTLANG_ENTER_EXIT": "za izhod pritisnite tipko Enter", + "VTLANG_ENTER_REBOOT": "pritisnite tipko Enter za ponovni zagon", + "VTLANG_ENTER_CONTINUE": "za nadaljevanje pritisnite tipko Enter", + + "VTLANG_CTRL_TEMP_SET": "Začasne nadzorne nastavitve", + "VTLANG_WIN11_BYPASS_CHECK": "Obid preverjanja CPU/TPM/SecureBoot pri namestitvi sistema Windows 11", + "VTLANG_WIN11_BYPASS_NRO": "Obid zahteve po spletnem računu pri namestitvi sistema Windows 11", + "VTLANG_LINUX_REMOUNT": "Priklopi Ventoy particijo po zagonu Linuxa", + "VTLANG_SECONDARY_BOOT_MENU": "Prikaz sekundarnega zagonskega menija", + "VTLANG_WIN_UEFI_RES_LOCK": "Lock the resolution when UEFI boot Windows/WinPE", + "VTLANG_UEFI_RES_LOCK_NONE": "None", + "VTLANG_UEFI_RES_LOCK_MAX": "Highest", + "VTLANG_UEFI_RES_LOCK_1024_768": "Fixed 1024 x 768", + "VTLANG_UEFI_RES_LOCK_BE1024_768": "At least 1024 x 768", + + + "MENU_STR_XXX": "" +} diff --git a/INSTALL/grub/menu/sr_RS.json b/INSTALL/grub/menu/sr_RS.json new file mode 100644 index 0000000..9be2549 --- /dev/null +++ b/INSTALL/grub/menu/sr_RS.json @@ -0,0 +1,99 @@ + + "VTLANG_LANGUAGE_NAME": "Serbian Latin (Srpski)", + + "VTLANG_STR_HOTKEY_LIST": "L:Језик F1:Help F2:Browse F3:ListView F4:Localboot F5:Tools F6:ExMenu", + "VTLANG_STR_HOTKEY_TREE": "L:Језик F1:Help F2:Browse F3:TreeView F4:Localboot F5:Tools F6:ExMenu", + "VTLANG_RETURN_PREVIOUS": "Return to previous menu [Esc]", + "VTLANG_RETURN_PRV_NOESC": "Return to previous menu", + + "VTLANG_MENU_LANG": "Menu Language Select", + + "VTLANG_LB_SBOOT_WINDOWS": "Search and boot Windows", + "VTLANG_LB_SBOOT_G4D": "Search and boot Grub4dos", + "VTLANG_LB_SBOOT_HDD1": "Boot the 1st local disk", + "VTLANG_LB_SBOOT_HDD2": "Boot the 2nd local disk", + "VTLANG_LB_SBOOT_HDD3": "Boot the 3rd local disk", + "VTLANG_LB_SBOOT_X64EFI": "Search and boot BOOTX64.EFI", + "VTLANG_LB_SBOOT_IA32EFI": "Search and boot BOOTIA32.EFI", + "VTLANG_LB_SBOOT_AA64EFI": "Search and boot BOOTAA64.EFI", + "VTLANG_LB_SBOOT_XORBOOT": "Search and boot xorboot", + + "VTLANG_FILE_CHKSUM": "File checksum", + "VTLANG_CHKSUM_MD5_CALC": "Calculate md5sum", + "VTLANG_CHKSUM_SHA1_CALC": "Calculate sha1sum", + "VTLANG_CHKSUM_SHA256_CALC": "Calculate sha256sum", + "VTLANG_CHKSUM_SHA512_CALC": "Calculate sha512sum", + "VTLANG_CHKSUM_MD5_CALC_CHK": "Calculate and check md5sum", + "VTLANG_CHKSUM_SHA1_CALC_CHK": "Calculate and check sha1sum", + "VTLANG_CHKSUM_SHA256_CALC_CHK": "Calculate and check sha256sum", + "VTLANG_CHKSUM_SHA512_CALC_CHK": "Calculate and check sha512sum", + + "VTLANG_POWER": "Power", + "VTLANG_POWER_REBOOT": "Reboot", + "VTLANG_POWER_HALT": "Halt", + "VTLANG_POWER_BOOT_EFIFW": "Reboot to EFI setup", + + "VTLANG_KEYBRD_LAYOUT": "Keyboard Layouts", + "VTLANG_HWINFO": "Hardware Information", + + "VTLANG_RESOLUTION_CFG": "Resolution Configuration", + "VTLANG_SCREEN_MODE": "Screen Display Mode", + "VTLANG_SCREEN_TEXT_MODE": "Force Text Mode", + "VTLANG_SCREEN_GUI_MODE": "Force Graphics Mode", + + "VTLANG_THEME_SELECT": "Theme Select", + + "VTLANG_UEFI_UTIL": "Ventoy UEFI Utilities", + "VTLANG_UTIL_SHOW_EFI_DRV": "Show EFI Drivers", + "VTLANG_UTIL_FIX_BLINIT_FAIL": "Fixup Windows BlinitializeLibrary Failure", + + "VTLANG_JSON_CHK_JSON": "Check plugin json configuration (ventoy.json)", + "VTLANG_JSON_CHK_CONTROL": "Check global control plugin configuration", + "VTLANG_JSON_CHK_THEME": "Check theme plugin configuration", + "VTLANG_JSON_CHK_AUTOINS": "Check auto install plugin configuration", + "VTLANG_JSON_CHK_PERSIST": "Check persistence plugin configuration", + "VTLANG_JSON_CHK_MENU_ALIAS": "Check menu alias plugin configuration", + "VTLANG_JSON_CHK_MENU_TIP": "Check menu tip plugin configuration", + "VTLANG_JSON_CHK_MENU_CLASS": "Check menu class plugin configuration", + "VTLANG_JSON_CHK_INJECTION": "Check injection plugin configuration", + "VTLANG_JSON_CHK_AUTO_MEMDISK": "Check auto memdisk plugin configuration", + "VTLANG_JSON_CHK_IMG_LIST": "Check image list plugin configuration", + "VTLANG_JSON_CHK_IMG_BLIST": "Check image blacklist plugin configuration", + "VTLANG_JSON_CHK_CONF_REPLACE": "Check boot conf replace plugin configuration", + "VTLANG_JSON_CHK_DUD": "Check dud plugin configuration", + "VTLANG_JSON_CHK_PASSWORD": "Check password plugin configuration", + + "VTLANG_NORMAL_MODE": "Boot in normal mode", + "VTLANG_WIMBOOT_MODE": "Boot in wimboot mode", + "VTLANG_GRUB2_MODE": "Boot in grub2 mode", + "VTLANG_MEMDISK_MODE": "Boot in memdisk mode", + + "VTLANG_RET_TO_LISTVIEW": "Return to ListView", + "VTLANG_RET_TO_TREEVIEW": "Return to TreeView", + + "VTLANG_NO_AUTOINS_SCRIPT": "Boot without auto installation template", + "VTLANG_AUTOINS_USE": "Boot with", + + "VTLANG_NO_PERSIST": "Boot without persistence", + "VTLANG_PERSIST_USE": "Boot with", + + "VTLANG_BROWER_RETURN": "Return", + + "VTLANG_ENTER_EXIT": "press Enter key to exit", + "VTLANG_ENTER_REBOOT": "press Enter key to reboot", + "VTLANG_ENTER_CONTINUE": "press Enter key to continue", + + "VTLANG_CTRL_TEMP_SET": "Temporary Control Settings", + "VTLANG_WIN11_BYPASS_CHECK": "Bypass CPU/TPM/SecureBoot check when install Windows 11", + "VTLANG_WIN11_BYPASS_NRO": "Bypass online account requirement when install Windows 11", + "VTLANG_LINUX_REMOUNT": "Mount Ventoy partition after boot Linux", + "VTLANG_SECONDARY_BOOT_MENU": "Show secondary boot menu", + "VTLANG_WIN_UEFI_RES_LOCK": "Lock the resolution when UEFI boot Windows/WinPE", + "VTLANG_UEFI_RES_LOCK_NONE": "None", + "VTLANG_UEFI_RES_LOCK_MAX": "Highest", + "VTLANG_UEFI_RES_LOCK_1024_768": "Fixed 1024 x 768", + "VTLANG_UEFI_RES_LOCK_BE1024_768": "At least 1024 x 768", + + + "MENU_STR_XXX": "" +} diff --git a/INSTALL/grub/menu/ta_IN.json b/INSTALL/grub/menu/ta_IN.json new file mode 100644 index 0000000..826202a --- /dev/null +++ b/INSTALL/grub/menu/ta_IN.json @@ -0,0 +1,99 @@ +{ + "VTLANG_LANGUAGE_NAME": "Tamil (தமிழ்)", + + "VTLANG_STR_HOTKEY_LIST": "L:மொழி F1:உதவி F2:உலாவுக F3:பட்டியல்பார்வை F4:லோக்கல்பூட் F5:கருவிகள் F6:ExMenu", + "VTLANG_STR_HOTKEY_TREE": "L:மொழி F1:உதவி F2:உலாவுக F3:மரப்பார்வை F4:லோக்கல்பூட் F5:கருவிகள் F6:ExMenu", + "VTLANG_RETURN_PREVIOUS": "முந்தைய பட்டியலுக்குத் திரும்பு [Esc]", + "VTLANG_RETURN_PRV_NOESC": "முந்தைய பட்டியலுக்குத் திரும்பு", + + "VTLANG_MENU_LANG": "மொழி தேர்வு பட்டியல்", + + "VTLANG_LB_SBOOT_WINDOWS": "விண்டோஸைத் தேடி துவக்கவும்", + "VTLANG_LB_SBOOT_G4D": "Grub4dos ஐத் தேடி துவக்கவும்", + "VTLANG_LB_SBOOT_HDD1": "1வது உள்ளூர் வட்டை துவக்கவும்", + "VTLANG_LB_SBOOT_HDD2": "2வது உள்ளூர் வட்டை துவக்கவும்", + "VTLANG_LB_SBOOT_HDD3": "3வது உள்ளூர் வட்டை துவக்கவும்", + "VTLANG_LB_SBOOT_X64EFI": "BOOTX64.EFI ஐத் தேடி துவக்கவும்", + "VTLANG_LB_SBOOT_IA32EFI": "BOOTIA32.EFI ஐத் தேடி துவக்கவும்", + "VTLANG_LB_SBOOT_AA64EFI": "BOOTAA64.EFI ஐத் தேடி துவக்கவும்", + "VTLANG_LB_SBOOT_XORBOOT": "xorboot ஐத் தேடி துவக்கவும்", + + "VTLANG_FILE_CHKSUM": "கோப்பு செக்சம்", + "VTLANG_CHKSUM_MD5_CALC": "md5sum ஐக் கணக்கிடவும்", + "VTLANG_CHKSUM_SHA1_CALC": "sha1sum ஐக் கணக்கிடவும்", + "VTLANG_CHKSUM_SHA256_CALC": "sha256sum ஐக் கணக்கிடவும்", + "VTLANG_CHKSUM_SHA512_CALC": "sha512sum ஐக் கணக்கிடவும்", + "VTLANG_CHKSUM_MD5_CALC_CHK": "md5sum ஐக் கணக்கிட்டு சரிபார்க்கவும்", + "VTLANG_CHKSUM_SHA1_CALC_CHK": "sha1sum ஐக் கணக்கிட்டு சரிபார்க்கவும்", + "VTLANG_CHKSUM_SHA256_CALC_CHK": "sha256sum ஐக் கணக்கிட்டு சரிபார்க்கவும்", + "VTLANG_CHKSUM_SHA512_CALC_CHK": "sha512sum ஐக் கணக்கிட்டு சரிபார்க்கவும்", + + "VTLANG_POWER": "பவர்", + "VTLANG_POWER_REBOOT": "மறுதொடக்கம்", + "VTLANG_POWER_HALT": "நிறுத்து", + "VTLANG_POWER_BOOT_EFIFW": "EFI அமைப்பிற்கு மீண்டும் துவக்கவும்", + + "VTLANG_KEYBRD_LAYOUT": "விசைப்பலகை தளவமைப்புகள்", + "VTLANG_HWINFO": "வன்பொருள் தகவல்", + + "VTLANG_RESOLUTION_CFG": "தீர்மானம் கட்டமைப்பு", + "VTLANG_SCREEN_MODE": "திரை காட்சி பயன்முறை", + "VTLANG_SCREEN_TEXT_MODE": "கட்டாய உரை பயன்முறை", + "VTLANG_SCREEN_GUI_MODE": "கட்டாய கிராபிக்ஸ் பயன்முறை", + + "VTLANG_THEME_SELECT": "தீம் தேர்வு", + + "VTLANG_UEFI_UTIL": "Ventoy UEFI பயன்பாடுகள்", + "VTLANG_UTIL_SHOW_EFI_DRV": "EFI இயக்கிகளைக் காட்டு", + "VTLANG_UTIL_FIX_BLINIT_FAIL": "Windows BlinitializeLibrary தோல்வியைச் சரிசெய்தல்", + + "VTLANG_JSON_CHK_JSON": "செருகுநிரல் json உள்ளமைவைச் சரிபார்க்கவும் (ventoy.json)", + "VTLANG_JSON_CHK_CONTROL": "உலகளாவிய கட்டுப்பாட்டு செருகுநிரல் உள்ளமைவைச் சரிபார்க்கவும்", + "VTLANG_JSON_CHK_THEME": "தீம் செருகுநிரல் உள்ளமைவைச் சரிபார்க்கவும்", + "VTLANG_JSON_CHK_AUTOINS": "தானாக நிறுவும் செருகுநிரல் உள்ளமைவைச் சரிபார்க்கவும்", + "VTLANG_JSON_CHK_PERSIST": "நிலைத்தன்மை செருகுநிரல் உள்ளமைவைச் சரிபார்க்கவும்", + "VTLANG_JSON_CHK_MENU_ALIAS": "பட்டியலில் மாற்று செருகுநிரல் உள்ளமைவைச் சரிபார்க்கவும்", + "VTLANG_JSON_CHK_MENU_TIP": "பட்டியலில் முனை செருகுநிரல் உள்ளமைவைச் சரிபார்க்கவும்", + "VTLANG_JSON_CHK_MENU_CLASS": "பட்டியலில் வகுப்பு செருகுநிரல் உள்ளமைவைச் சரிபார்க்கவும்", + "VTLANG_JSON_CHK_INJECTION": "ஊசி செருகுநிரல் உள்ளமைவைச் சரிபார்க்கவும்", + "VTLANG_JSON_CHK_AUTO_MEMDISK": "ஆட்டோ மெம்டிஸ்க் செருகுநிரல் உள்ளமைவைச் சரிபார்க்கவும்", + "VTLANG_JSON_CHK_IMG_LIST": "பட பட்டியல் செருகுநிரல் உள்ளமைவை சரிபார்க்கவும்", + "VTLANG_JSON_CHK_IMG_BLIST": "படத்தின் தடுப்புப்பட்டியல் செருகுநிரல் உள்ளமைவைச் சரிபார்க்கவும்", + "VTLANG_JSON_CHK_CONF_REPLACE": "பூட் conf சொருகி உள்ளமைவை மாற்றுவதை சரிபார்க்கவும்", + "VTLANG_JSON_CHK_DUD": "dud செருகுநிரல் உள்ளமைவை சரிபார்க்கவும்", + "VTLANG_JSON_CHK_PASSWORD": "கடவுச்சொல் செருகுநிரல் உள்ளமைவைச் சரிபார்க்கவும்", + + "VTLANG_NORMAL_MODE": "சாதாரண பயன்முறையில் துவக்கவும்", + "VTLANG_WIMBOOT_MODE": "wimboot பயன்முறையில் துவக்கவும்", + "VTLANG_GRUB2_MODE": "grub2 பயன்முறையில் துவக்கவும்", + "VTLANG_MEMDISK_MODE": "memdisk பயன்முறையில் துவக்கவும்", + + "VTLANG_RET_TO_LISTVIEW": "பட்டியல்பார்வை பக்கத்துக்குத் திரும்பு", + "VTLANG_RET_TO_TREEVIEW": "மரப்பார்வை பக்கத்துக்குத் திரும்பு", + + "VTLANG_NO_AUTOINS_SCRIPT": "தானியங்கி நிறுவல் டெம்ப்ளேட் இல்லாமல் துவக்கவும்", + "VTLANG_AUTOINS_USE": "துவக்கவும் இத்துடன்", + + "VTLANG_NO_PERSIST": "விடாமுயற்சி இல்லாமல் துவக்கவும்", + "VTLANG_PERSIST_USE": "துவக்கவும் இத்துடன்", + + "VTLANG_BROWER_RETURN": "திரும்பு", + + "VTLANG_ENTER_EXIT": "வெளியேற Enter விசையை அழுத்தவும்", + "VTLANG_ENTER_REBOOT": "மறுதொடக்கம் செய்ய Enter விசையை அழுத்தவும்", + "VTLANG_ENTER_CONTINUE": "தொடர Enter விசையை அழுத்தவும்", + + "VTLANG_CTRL_TEMP_SET": "தற்காலிக கட்டுப்பாட்டு அமைப்புகள்", + "VTLANG_WIN11_BYPASS_CHECK": "விண்டோஸ் 11 ஐ நிறுவும் போது CPU/TPM/SecureBoot சரிபார்பை புறக்கணிக்கவும்", + "VTLANG_WIN11_BYPASS_NRO": "விண்டோஸ் 11 ஐ நிறுவும் போது ஆன்லைன் கணக்கின் தேவையை புறக்கணிக்கவும்", + "VTLANG_LINUX_REMOUNT": "லினக்ஸை துவக்கிய பிறகு Ventoy பகிர்வை ஏற்றவும்", + "VTLANG_SECONDARY_BOOT_MENU": "இரண்டாம் நிலை துவக்க பட்டியலைக் காட்டு", + "VTLANG_WIN_UEFI_RES_LOCK": "Lock the resolution when UEFI boot Windows/WinPE", + "VTLANG_UEFI_RES_LOCK_NONE": "None", + "VTLANG_UEFI_RES_LOCK_MAX": "Highest", + "VTLANG_UEFI_RES_LOCK_1024_768": "Fixed 1024 x 768", + "VTLANG_UEFI_RES_LOCK_BE1024_768": "At least 1024 x 768", + + + "MENU_STR_XXX": "" +} diff --git a/INSTALL/grub/menu/tr_TR.json b/INSTALL/grub/menu/tr_TR.json new file mode 100644 index 0000000..21ed036 --- /dev/null +++ b/INSTALL/grub/menu/tr_TR.json @@ -0,0 +1,99 @@ +{ + "VTLANG_LANGUAGE_NAME": "Turkish (Türkçe)", + + "VTLANG_STR_HOTKEY_LIST": "L:Dil F1:Yardım F2:Gözat F3:Liste Görünümü F4:Önyükleme Seçenekleri F5:Araçlar F6:Grub2 Menü", + "VTLANG_STR_HOTKEY_TREE": "L:Dil F1:Yardım F2:Gözat F3:Ağaç Görünümü F4:Önyükleme Seçenekleri F5:Araçlar F6:Grub2 Menü", + "VTLANG_RETURN_PREVIOUS": "Önceki menüye geri dön [Esc]", + "VTLANG_RETURN_PRV_NOESC": "Önceki menüye geri dön", + + "VTLANG_MENU_LANG": "Menü Dili Seçimi", + + "VTLANG_LB_SBOOT_WINDOWS": "Windows'u bul ve Önyükle", + "VTLANG_LB_SBOOT_G4D": "Grub4dos'u bul ve Önyükle", + "VTLANG_LB_SBOOT_HDD1": "1. Yerel diskten Önyükleme yap", + "VTLANG_LB_SBOOT_HDD2": "2. Yerel diskten Önyükleme yap", + "VTLANG_LB_SBOOT_HDD3": "3. Yerel diskten Önyükleme yap", + "VTLANG_LB_SBOOT_X64EFI": "BOOTX64.EFI'yi bul ve Önyükleme yap", + "VTLANG_LB_SBOOT_IA32EFI": "BOOTIA32.EFI'yi bul ve Önyükleme yap", + "VTLANG_LB_SBOOT_AA64EFI": "BOOTAA64.EFI'yi bul ve Önyükleme yap", + "VTLANG_LB_SBOOT_XORBOOT": "XORBOOT'u bul ve Önyükleme yap", + + "VTLANG_FILE_CHKSUM": "Dosya Doğrulama", + "VTLANG_CHKSUM_MD5_CALC": "md5sum değerini hesapla", + "VTLANG_CHKSUM_SHA1_CALC": "sha1sum değerini hesapla", + "VTLANG_CHKSUM_SHA256_CALC": "sha256sum değerini hesapla", + "VTLANG_CHKSUM_SHA512_CALC": "sha512sum değerini hesapla", + "VTLANG_CHKSUM_MD5_CALC_CHK": "md5sum hesapla ve kontrol et", + "VTLANG_CHKSUM_SHA1_CALC_CHK": "sha1sum hesapla ve kontrol et", + "VTLANG_CHKSUM_SHA256_CALC_CHK": "sha256sum hesapla ve kontrol et", + "VTLANG_CHKSUM_SHA512_CALC_CHK": "sha512sum hesapla ve kontrol et", + + "VTLANG_POWER": "Güç Seçenekleri", + "VTLANG_POWER_REBOOT": "Yeniden Başlat", + "VTLANG_POWER_HALT": "Bilgisayarı Kapat", + "VTLANG_POWER_BOOT_EFIFW": "EFI BIOS Ayarları ile Yeniden Başlat", + + "VTLANG_KEYBRD_LAYOUT": "Klavye düzenleri", + "VTLANG_HWINFO": "Donanım Bilgisi", + + "VTLANG_RESOLUTION_CFG": "Çözünürlük Yapılandırması", + "VTLANG_SCREEN_MODE": "Ekran Görüntüleme Modu", + "VTLANG_SCREEN_TEXT_MODE": "Metin Modu'nu Dene", + "VTLANG_SCREEN_GUI_MODE": "Grafik Modu'nu Dene", + + "VTLANG_THEME_SELECT": "Tema Seçimi", + + "VTLANG_UEFI_UTIL": "Ventoy UEFI Utilities", + "VTLANG_UTIL_SHOW_EFI_DRV": "EFI Sürücülerini Göster", + "VTLANG_UTIL_FIX_BLINIT_FAIL": "Windows BlinitializeLibrary Hatasını Düzelt", + + "VTLANG_JSON_CHK_JSON": "json (ventoy.json) Yapılandırma Dosyası Ayarlarını kontrol et", + "VTLANG_JSON_CHK_CONTROL": "(Global Control Plugin) yapılandırma ayarları", + "VTLANG_JSON_CHK_THEME": "(Theme Plugin) yapılandırma ayarları", + "VTLANG_JSON_CHK_AUTOINS": "(Auto Install Plugin) yapılandırma ayarları", + "VTLANG_JSON_CHK_PERSIST": "(Persistence Plugin) yapılandırma ayarları", + "VTLANG_JSON_CHK_MENU_ALIAS": "(Menu Alias Plugin) yapılandırma ayarları", + "VTLANG_JSON_CHK_MENU_TIP": "(Menu Tip Plugin) yapılandırma ayarları", + "VTLANG_JSON_CHK_MENU_CLASS": "(Menu Class Plugin) yapılandırma ayarları", + "VTLANG_JSON_CHK_INJECTION": "(Injection Plugin) yapılandırma ayarları", + "VTLANG_JSON_CHK_AUTO_MEMDISK": "(Auto Memdisk Plugin) yapılandırma ayarları", + "VTLANG_JSON_CHK_IMG_LIST": "(Image List Plugin) yapılandırma ayarları", + "VTLANG_JSON_CHK_IMG_BLIST": "(Image Blacklist Plugin) yapılandırma ayarları", + "VTLANG_JSON_CHK_CONF_REPLACE": "(Check Boot Conf Replace Plugin) yapılandırma ayarları", + "VTLANG_JSON_CHK_DUD": "(Dud Plugin) yapılandırma ayarları", + "VTLANG_JSON_CHK_PASSWORD": "(Password Plugin) yapılandırma ayarları", + + "VTLANG_NORMAL_MODE": "NORMAL(ISO) Mod'da ÖnYükleme Yap", + "VTLANG_WIMBOOT_MODE": "WIMBOOT(WIM) Mod'da Önyükleme Yap", + "VTLANG_GRUB2_MODE": "GRUB2 Mod'da Önyükleme Yap", + "VTLANG_MEMDISK_MODE": "MEMDISK Modunda ÖnYükleme Yap", + + "VTLANG_RET_TO_LISTVIEW": "Liste Görünümü Moduna Geri Dön", + "VTLANG_RET_TO_TREEVIEW": "Ağaç Görünümü Moduna Geri Dön", + + "VTLANG_NO_AUTOINS_SCRIPT": "Otomatik yükleme şablonu(autoinstalltemplate.xml) olmadan Önyükleme yap", + "VTLANG_AUTOINS_USE": "ile Önyükleme Yap", + + "VTLANG_NO_PERSIST": "Kalıcı ayar dosyası(persistence.dat) olmadan Önyükleme Yap", + "VTLANG_PERSIST_USE": "ile Önyükleme Yap", + + "VTLANG_BROWER_RETURN": "Geri Dön", + + "VTLANG_ENTER_EXIT": "çıkmak için ENTER tuşuna basın", + "VTLANG_ENTER_REBOOT": "yeniden başlatmak için ENTER'a basın", + "VTLANG_ENTER_CONTINUE": "devam etmek için ENTER'a basın", + + "VTLANG_CTRL_TEMP_SET": "Geçici Kontrol Ayarları", + "VTLANG_WIN11_BYPASS_CHECK": "Windows11'i yüklerken, TPM/CPU/RAM kontrollerini atla", + "VTLANG_WIN11_BYPASS_NRO": "Windows11'i yüklerken, çevrimiçi hesap gereksinimini(OOBE) atla", + "VTLANG_LINUX_REMOUNT": "Linux sistemi önyükledikten sonra, Ventoy bölümünü bağla", + "VTLANG_SECONDARY_BOOT_MENU": "İkincil önyükleme menüsünü göster", + "VTLANG_WIN_UEFI_RES_LOCK": "Lock the resolution when UEFI boot Windows/WinPE", + "VTLANG_UEFI_RES_LOCK_NONE": "None", + "VTLANG_UEFI_RES_LOCK_MAX": "Highest", + "VTLANG_UEFI_RES_LOCK_1024_768": "Fixed 1024 x 768", + "VTLANG_UEFI_RES_LOCK_BE1024_768": "At least 1024 x 768", + + + "MENU_STR_XXX": "" +} diff --git a/INSTALL/grub/menu/uk_UA.json b/INSTALL/grub/menu/uk_UA.json new file mode 100644 index 0000000..c767590 --- /dev/null +++ b/INSTALL/grub/menu/uk_UA.json @@ -0,0 +1,99 @@ +{ + "VTLANG_LANGUAGE_NAME": "Ukrainian (Українська)", + + "VTLANG_STR_HOTKEY_LIST": "L:Мова F1:Довідка F2:Перегляд F3:Вид списком F4:Локальне завантаження F5:Інструменти F6:Вийти з меню", + "VTLANG_STR_HOTKEY_TREE": "L:Мова F1:Довідка F2:Перегляд F3:Вид деревом F4:Локальне завантаження F5:Інструменти F6:Вийти з меню", + "VTLANG_RETURN_PREVIOUS": "Повернутись до попереднього меню [Esc]", + "VTLANG_RETURN_PRV_NOESC": "Повернутись до попереднього меню", + + "VTLANG_MENU_LANG": "Мова меню", + + "VTLANG_LB_SBOOT_WINDOWS": "Знайти та завантажити Windows", + "VTLANG_LB_SBOOT_G4D": "Знайти та завантажити Grub4dos", + "VTLANG_LB_SBOOT_HDD1": "Завантажити 1-й локальний диск", + "VTLANG_LB_SBOOT_HDD2": "Завантажити 2-й локальний диск", + "VTLANG_LB_SBOOT_HDD3": "Завантажити 3-й локальний диск", + "VTLANG_LB_SBOOT_X64EFI": "Знайти та завантажити BOOTX64.EFI", + "VTLANG_LB_SBOOT_IA32EFI": "Знайти та завантажити BOOTIA32.EFI", + "VTLANG_LB_SBOOT_AA64EFI": "Знайти та завантажити BOOTAA64.EFI", + "VTLANG_LB_SBOOT_XORBOOT": "Знайти та завантажити xorboot", + + "VTLANG_FILE_CHKSUM": "Контрольна сума файлу", + "VTLANG_CHKSUM_MD5_CALC": "Розрахувати md5", + "VTLANG_CHKSUM_SHA1_CALC": "Розрахувати sha1", + "VTLANG_CHKSUM_SHA256_CALC": "Розрахувати sha256", + "VTLANG_CHKSUM_SHA512_CALC": "Розрахувати sha512", + "VTLANG_CHKSUM_MD5_CALC_CHK": "Розрахувати та перевірити md5", + "VTLANG_CHKSUM_SHA1_CALC_CHK": "Розрахувати та перевірити sha1", + "VTLANG_CHKSUM_SHA256_CALC_CHK": "Розрахувати та перевірити sha256", + "VTLANG_CHKSUM_SHA512_CALC_CHK": "Розрахувати та перевірити sha512", + + "VTLANG_POWER": "Живлення", + "VTLANG_POWER_REBOOT": "Перезавантажити", + "VTLANG_POWER_HALT": "Завершити роботу", + "VTLANG_POWER_BOOT_EFIFW": "Перезавантажитись до налаштувань UEFI/BIOS", + + "VTLANG_KEYBRD_LAYOUT": "Розкладка клавіатури", + "VTLANG_HWINFO": "Відомості про пристрій", + + "VTLANG_RESOLUTION_CFG": "Налаштування роздільної здатності", + "VTLANG_SCREEN_MODE": "Інтерфейс користувача", + "VTLANG_SCREEN_TEXT_MODE": "Перейти до текстового інтерфейсу", + "VTLANG_SCREEN_GUI_MODE": "Перейти до графічного інтерфейсу", + + "VTLANG_THEME_SELECT": "Теми", + + "VTLANG_UEFI_UTIL": "Утиліти Ventoy UEFI", + "VTLANG_UTIL_SHOW_EFI_DRV": "Показати драйвери EFI", + "VTLANG_UTIL_FIX_BLINIT_FAIL": "Виправити помилку Windows 'BlinitializeLibrary Failure'", + + "VTLANG_JSON_CHK_JSON": "Перевірити налаштування плагіну 'json' (ventoy.json)", + "VTLANG_JSON_CHK_CONTROL": "Перевірити налаштування плагіну 'global control'", + "VTLANG_JSON_CHK_THEME": "Перевірити налаштування плагіну 'theme'", + "VTLANG_JSON_CHK_AUTOINS": "Перевірити налаштування плагіну 'auto install'", + "VTLANG_JSON_CHK_PERSIST": "Перевірити налаштування плагіну 'persistence'", + "VTLANG_JSON_CHK_MENU_ALIAS": "Перевірити налаштування плагіну 'menu alias'", + "VTLANG_JSON_CHK_MENU_TIP": "Перевірити налаштування плагіну 'menu tip'", + "VTLANG_JSON_CHK_MENU_CLASS": "Перевірити налаштування плагіну 'menu class'", + "VTLANG_JSON_CHK_INJECTION": "Перевірити налаштування плагіну 'injection'", + "VTLANG_JSON_CHK_AUTO_MEMDISK": "Перевірити налаштування плагіну 'auto memdisk'", + "VTLANG_JSON_CHK_IMG_LIST": "Перевірити налаштування плагіну 'image list'", + "VTLANG_JSON_CHK_IMG_BLIST": "Перевірити налаштування плагіну 'image blacklist plugin'", + "VTLANG_JSON_CHK_CONF_REPLACE": "Перевірити налаштування плагіну 'boot conf replace'", + "VTLANG_JSON_CHK_DUD": "Перевірити налаштування плагіну 'dud'", + "VTLANG_JSON_CHK_PASSWORD": "Перевірити налаштування плагіну 'password'", + + "VTLANG_NORMAL_MODE": "Завантажити в нормальному режимі", + "VTLANG_WIMBOOT_MODE": "Завантажити в режимі wimboot", + "VTLANG_GRUB2_MODE": "Завантажити в режимі GRUB2", + "VTLANG_MEMDISK_MODE": "Завантажити в режимі MEMDISK", + + "VTLANG_RET_TO_LISTVIEW": "Повернутись до перегляду списком", + "VTLANG_RET_TO_TREEVIEW": "Повернутись до деревовидного перегляду", + + "VTLANG_NO_AUTOINS_SCRIPT": "Завантажити без шаблону авто-інсталяції", + "VTLANG_AUTOINS_USE": "Завантажити з", + + "VTLANG_NO_PERSIST": "Завантажити без збереження", + "VTLANG_PERSIST_USE": "Завантажити з ", + + "VTLANG_BROWER_RETURN": "Повернутись", + + "VTLANG_ENTER_EXIT": "натисніть Enter для виходу", + "VTLANG_ENTER_REBOOT": "натисніть Enter для перезавантаження", + "VTLANG_ENTER_CONTINUE": "натисніть Enter для продовження", + + "VTLANG_CTRL_TEMP_SET": "Різні налаштування", + "VTLANG_WIN11_BYPASS_CHECK": "Обійти перевірку CPU/TPM/SecureBoot під час інсталяції Windows 11", + "VTLANG_WIN11_BYPASS_NRO": "Обійти вимогу онлайн-аккаунту під час інсталяції Windows 11", + "VTLANG_LINUX_REMOUNT": "Монтувати розділ Ventoy після завантаження Linux", + "VTLANG_SECONDARY_BOOT_MENU": "Показувати вторинне меню завантаження", + "VTLANG_WIN_UEFI_RES_LOCK": "Lock the resolution when UEFI boot Windows/WinPE", + "VTLANG_UEFI_RES_LOCK_NONE": "None", + "VTLANG_UEFI_RES_LOCK_MAX": "Highest", + "VTLANG_UEFI_RES_LOCK_1024_768": "Fixed 1024 x 768", + "VTLANG_UEFI_RES_LOCK_BE1024_768": "At least 1024 x 768", + + + "MENU_STR_XXX": "" +} diff --git a/INSTALL/grub/menu/vi_VN.json b/INSTALL/grub/menu/vi_VN.json new file mode 100644 index 0000000..9539a6c --- /dev/null +++ b/INSTALL/grub/menu/vi_VN.json @@ -0,0 +1,99 @@ +{ + "VTLANG_LANGUAGE_NAME": "Vietnamese (Tiếng Việt)", + + "VTLANG_STR_HOTKEY_LIST": "L:Ngôn ngữ F1:Trợ giúp F2:Duyệt F3:ListView F4:Khởi động cục bộ F5:Công cụ F6:ExMenu", + "VTLANG_STR_HOTKEY_TREE": "L:Ngôn ngữ F1:Trợ giúp F2:Duyệt F3:TreeView F4:Khởi động cục bộ F5:Công cụ F6:ExMenu", + "VTLANG_RETURN_PREVIOUS": "Trở về menu trước [Esc]", + "VTLANG_RETURN_PRV_NOESC": "Trở về menu trước", + + "VTLANG_MENU_LANG": "Chọn ngôn ngữ menu", + + "VTLANG_LB_SBOOT_WINDOWS": "Tìm kiếm và khởi động Windows", + "VTLANG_LB_SBOOT_G4D": "Tìm kiếm và khởi động Grub4dos", + "VTLANG_LB_SBOOT_HDD1": "Khởi động từ ổ đĩa thứ 1 ở trên máy", + "VTLANG_LB_SBOOT_HDD2": "Khởi động từ ổ đĩa thứ 2 ở trên máy", + "VTLANG_LB_SBOOT_HDD3": "Khởi động từ ổ đĩa thứ 3 ở trên máy", + "VTLANG_LB_SBOOT_X64EFI": "Tìm kiếm và khởi động BOOTX64.EFI", + "VTLANG_LB_SBOOT_IA32EFI": "Tìm kiếm và khởi động BOOTIA32.EFI", + "VTLANG_LB_SBOOT_AA64EFI": "Tìm kiếm và khởi động BOOTAA64.EFI", + "VTLANG_LB_SBOOT_XORBOOT": "Tìm kiếm và khởi động xorboot", + + "VTLANG_FILE_CHKSUM": "Checksum tệp", + "VTLANG_CHKSUM_MD5_CALC": "Tính md5sum", + "VTLANG_CHKSUM_SHA1_CALC": "Tính sha1sum", + "VTLANG_CHKSUM_SHA256_CALC": "Tính sha256sum", + "VTLANG_CHKSUM_SHA512_CALC": "Tính sha512sum", + "VTLANG_CHKSUM_MD5_CALC_CHK": "Tính và kiểm tra md5sum", + "VTLANG_CHKSUM_SHA1_CALC_CHK": "Tính và kiểm tra sha1sum", + "VTLANG_CHKSUM_SHA256_CALC_CHK": "Tính và kiểm tra sha256sum", + "VTLANG_CHKSUM_SHA512_CALC_CHK": "Tính và kiểm tra sha512sum", + + "VTLANG_POWER": "Nguồn điện", + "VTLANG_POWER_REBOOT": "Khởi động lại", + "VTLANG_POWER_HALT": "Tắt máy", + "VTLANG_POWER_BOOT_EFIFW": "Khởi động lại vào cài đặt UEFI", + + "VTLANG_KEYBRD_LAYOUT": "Bố cục bàn phím", + "VTLANG_HWINFO": "Thông tin phần cứng", + + "VTLANG_RESOLUTION_CFG": "Cấu hình độ phân giải", + "VTLANG_SCREEN_MODE": "Chế độ hiển thị", + "VTLANG_SCREEN_TEXT_MODE": "Bắt buộc giao diện văn bản", + "VTLANG_SCREEN_GUI_MODE": "Bắt buộc giao diện đồ hoạ", + + "VTLANG_THEME_SELECT": "Chọn chủ đề", + + "VTLANG_UEFI_UTIL": "Các tiện ích UEFI Ventoy", + "VTLANG_UTIL_SHOW_EFI_DRV": "Hiển thị các driver EFI", + "VTLANG_UTIL_FIX_BLINIT_FAIL": "Sửa lỗi BlinitializeLibrary của Windows", + + "VTLANG_JSON_CHK_JSON": "Kiểm tra cấu hình plugin json (ventoy.json)", + "VTLANG_JSON_CHK_CONTROL": "Kiểm tra cấu hình plugin điều khiển toàn cục", + "VTLANG_JSON_CHK_THEME": "Kiểm tra cấu hình plugin chủ đề", + "VTLANG_JSON_CHK_AUTOINS": "Kiểm tra cấu hình plugin tự động cài đặt", + "VTLANG_JSON_CHK_PERSIST": "Kiểm tra cấu hình plugin persistence", + "VTLANG_JSON_CHK_MENU_ALIAS": "Kiểm tra cấu hình plugin alias menu", + "VTLANG_JSON_CHK_MENU_TIP": "Kiểm tra cấu hình plugin tip menu", + "VTLANG_JSON_CHK_MENU_CLASS": "Kiểm tra cấu hình plugin lớp menu", + "VTLANG_JSON_CHK_INJECTION": "Kiểm tra cấu hình plugin injection", + "VTLANG_JSON_CHK_AUTO_MEMDISK": "Kiểm tra cấu hình plugin auto memdisk", + "VTLANG_JSON_CHK_IMG_LIST": "Kiểm tra cấu hình plugin danh sách ảnh đĩa", + "VTLANG_JSON_CHK_IMG_BLIST": "Kiểm tra cấu hình plugin danh sách đen ảnh đĩa", + "VTLANG_JSON_CHK_CONF_REPLACE": "Kiểm tra cấu hình plugin boot replace conf", + "VTLANG_JSON_CHK_DUD": "Kiểm tra cấu hình plugin dud", + "VTLANG_JSON_CHK_PASSWORD": "Kiểm tra cấu hình plugin mật khẩu", + + "VTLANG_NORMAL_MODE": "Khởi động ở chế độ bình thường", + "VTLANG_WIMBOOT_MODE": "Khởi động ở chế độ wimboot", + "VTLANG_GRUB2_MODE": "Khởi động ở chế độ GRUB2", + "VTLANG_MEMDISK_MODE": "Khởi động ở chế độ memdisk", + + "VTLANG_RET_TO_LISTVIEW": "Trở về ListView", + "VTLANG_RET_TO_TREEVIEW": "Trở về TreeView", + + "VTLANG_NO_AUTOINS_SCRIPT": "Khởi động không dùng mẫu cài đặt", + "VTLANG_AUTOINS_USE": "Khởi động với", + + "VTLANG_NO_PERSIST": "Khởi động không có persistence", + "VTLANG_PERSIST_USE": "Khởi động với", + + "VTLANG_BROWER_RETURN": "Trở về", + + "VTLANG_ENTER_EXIT": "nhấn Enter để thoát", + "VTLANG_ENTER_REBOOT": "nhấn Enter để khởi động lại", + "VTLANG_ENTER_CONTINUE": "nhấn enter để tiếp tục", + + "VTLANG_CTRL_TEMP_SET": "Cài đặt điều khiển tạm", + "VTLANG_WIN11_BYPASS_CHECK": "Bỏ qua kiểm tra CPU/TPM/SecureBoot khi cài đặt Windows 11", + "VTLANG_WIN11_BYPASS_NRO": "Bỏ qua yêu cầu tài khoản trực tuyến khi cài đặt Windows 11", + "VTLANG_LINUX_REMOUNT": "Gắn phân vùng Ventoy sau khi khởi động GNU/Linux", + "VTLANG_SECONDARY_BOOT_MENU": "Hiện menu khởi động thứ cấp`", + "VTLANG_WIN_UEFI_RES_LOCK": "Lock the resolution when UEFI boot Windows/WinPE", + "VTLANG_UEFI_RES_LOCK_NONE": "None", + "VTLANG_UEFI_RES_LOCK_MAX": "Highest", + "VTLANG_UEFI_RES_LOCK_1024_768": "Fixed 1024 x 768", + "VTLANG_UEFI_RES_LOCK_BE1024_768": "At least 1024 x 768", + + + "MENU_STR_XXX": "" +} diff --git a/INSTALL/grub/menu/zh_CN.json b/INSTALL/grub/menu/zh_CN.json new file mode 100644 index 0000000..9870cea --- /dev/null +++ b/INSTALL/grub/menu/zh_CN.json @@ -0,0 +1,98 @@ +{ + "VTLANG_LANGUAGE_NAME": "Chinese Simplified (简体中文)", + + "VTLANG_STR_HOTKEY_LIST": "L:语言 F1:帮助 F2:本地浏览 F3:列表模式 F4:本地启动 F5:工具 F6:扩展菜单", + "VTLANG_STR_HOTKEY_TREE": "L:语言 F1:帮助 F2:本地浏览 F3:树形模式 F4:本地启动 F5:工具 F6:扩展菜单", + "VTLANG_RETURN_PREVIOUS": "返回上一级菜单 [Esc]", + "VTLANG_RETURN_PRV_NOESC": "返回上一级菜单", + + "VTLANG_MENU_LANG": "菜单语言", + + "VTLANG_LB_SBOOT_WINDOWS": "搜索并启动 Windows", + "VTLANG_LB_SBOOT_G4D": "搜索并启动 Grub4dos", + "VTLANG_LB_SBOOT_HDD1": "启动本地硬盘1中的系统", + "VTLANG_LB_SBOOT_HDD2": "启动本地硬盘2中的系统", + "VTLANG_LB_SBOOT_HDD3": "启动本地硬盘3中的系统", + "VTLANG_LB_SBOOT_X64EFI": "搜索并启动 BOOTX64.EFI", + "VTLANG_LB_SBOOT_IA32EFI": "搜索并启动 BOOTIA32.EFI", + "VTLANG_LB_SBOOT_AA64EFI": "搜索并启动 BOOTAA64.EFI", + "VTLANG_LB_SBOOT_XORBOOT": "搜索并启动 xorboot", + + "VTLANG_FILE_CHKSUM": "文件校验", + "VTLANG_CHKSUM_MD5_CALC": "计算 MD5 校验值", + "VTLANG_CHKSUM_SHA1_CALC": "计算 SHA1 校验值", + "VTLANG_CHKSUM_SHA256_CALC": "计算 SHA256 校验值", + "VTLANG_CHKSUM_SHA512_CALC": "计算 SHA512 校验值", + "VTLANG_CHKSUM_MD5_CALC_CHK": "计算并检查 MD5 校验值", + "VTLANG_CHKSUM_SHA1_CALC_CHK": "计算并检查 SHA1 校验值", + "VTLANG_CHKSUM_SHA256_CALC_CHK": "计算并检查 SHA256 校验值", + "VTLANG_CHKSUM_SHA512_CALC_CHK": "计算并检查 SHA512 校验值", + + "VTLANG_POWER": "电源", + "VTLANG_POWER_REBOOT": "重启", + "VTLANG_POWER_HALT": "关机", + "VTLANG_POWER_BOOT_EFIFW": "重启进入 UEFI 设置菜单", + + "VTLANG_KEYBRD_LAYOUT": "键盘布局", + "VTLANG_HWINFO": "硬件信息", + + "VTLANG_RESOLUTION_CFG": "屏幕分辨率", + "VTLANG_SCREEN_MODE": "显示模式", + "VTLANG_SCREEN_TEXT_MODE": "文本模式", + "VTLANG_SCREEN_GUI_MODE": "图形模式", + + "VTLANG_THEME_SELECT": "主题选择", + + "VTLANG_UEFI_UTIL": "Ventoy UEFI 工具", + "VTLANG_UTIL_SHOW_EFI_DRV": "显示 UEFI 驱动", + "VTLANG_UTIL_FIX_BLINIT_FAIL": "修复 Windows BlinitializeLibrary 错误", + + "VTLANG_JSON_CHK_JSON": "检查插件配置文件 (ventoy.json)", + "VTLANG_JSON_CHK_CONTROL": "配置检查 —— 全局控制插件", + "VTLANG_JSON_CHK_THEME": "配置检查 —— 主题插件", + "VTLANG_JSON_CHK_AUTOINS": "配置检查 —— 自动安装插件", + "VTLANG_JSON_CHK_PERSIST": "配置检查 —— 持久化插件", + "VTLANG_JSON_CHK_MENU_ALIAS": "配置检查 —— 菜单别名插件", + "VTLANG_JSON_CHK_MENU_TIP": "配置检查 —— 菜单提示插件", + "VTLANG_JSON_CHK_MENU_CLASS": "配置检查 —— 菜单类型插件", + "VTLANG_JSON_CHK_INJECTION": "配置检查 —— 文件注入插件", + "VTLANG_JSON_CHK_AUTO_MEMDISK": "配置检查 —— 自动内存盘模式插件", + "VTLANG_JSON_CHK_IMG_LIST": "配置检查 —— 文件列表插件(白名单)", + "VTLANG_JSON_CHK_IMG_BLIST": "配置检查 —— 文件列表插件(黑名单)", + "VTLANG_JSON_CHK_CONF_REPLACE": "配置检查 —— 启动配置替换插件", + "VTLANG_JSON_CHK_DUD": "配置检查 —— Driver Update Disk插件", + "VTLANG_JSON_CHK_PASSWORD": "配置检查 —— 密码插件", + + "VTLANG_NORMAL_MODE": "以正常模式启动", + "VTLANG_WIMBOOT_MODE": "以 wimboot 模式启动", + "VTLANG_GRUB2_MODE": "以 grub2 模式启动", + "VTLANG_MEMDISK_MODE": "以内存盘模式启动", + + "VTLANG_RET_TO_LISTVIEW": "返回到列表模式", + "VTLANG_RET_TO_TREEVIEW": "返回到树形模式", + + "VTLANG_NO_AUTOINS_SCRIPT": "不使用自动安装脚本", + "VTLANG_AUTOINS_USE": "使用", + + "VTLANG_NO_PERSIST": "不使用持久化数据文件", + "VTLANG_PERSIST_USE": "使用", + + "VTLANG_BROWER_RETURN": "返回", + + "VTLANG_ENTER_EXIT": "按回车键退出", + "VTLANG_ENTER_REBOOT": "按回车键重启", + "VTLANG_ENTER_CONTINUE": "按回车键继续", + + "VTLANG_CTRL_TEMP_SET": "控制变量设置", + "VTLANG_WIN11_BYPASS_CHECK": "安装 Windows 11 时绕过 TPM/安全启动 等硬件检查", + "VTLANG_WIN11_BYPASS_NRO": "安装 Windows 11 时绕过在线账户的要求", + "VTLANG_LINUX_REMOUNT": "启动 Linux 系统后挂载 Ventoy 分区", + "VTLANG_SECONDARY_BOOT_MENU": "显示二级启动菜单", + "VTLANG_WIN_UEFI_RES_LOCK": "UEFI启动 Windows/WinPE 时锁定分辨率", + "VTLANG_UEFI_RES_LOCK_NONE": "不锁定", + "VTLANG_UEFI_RES_LOCK_MAX": "锁定最高分辨率", + "VTLANG_UEFI_RES_LOCK_1024_768": "锁定 1024 x 768", + "VTLANG_UEFI_RES_LOCK_BE1024_768": "锁定 1024 x 768 及以上", + + "MENU_STR_XXX": "" +} diff --git a/INSTALL/grub/menu/zh_TW.json b/INSTALL/grub/menu/zh_TW.json new file mode 100644 index 0000000..9f165bd --- /dev/null +++ b/INSTALL/grub/menu/zh_TW.json @@ -0,0 +1,98 @@ +{ + "VTLANG_LANGUAGE_NAME": "Chinese Traditional (正體中文)", + + "VTLANG_STR_HOTKEY_LIST": "L:語言 F1:說明 F2:瀏覽 F3:清單檢視 F4:本機啟動 F5:工具 F6:附加選單", + "VTLANG_STR_HOTKEY_TREE": "L:語言 F1:說明 F2:瀏覽 F3:樹狀檢視 F4:本機啟動 F5:工具 F6:附加選單", + "VTLANG_RETURN_PREVIOUS": "返回上一層選單 [Esc]", + "VTLANG_RETURN_PRV_NOESC": "返回上一層選單", + + "VTLANG_MENU_LANG": "選單語言", + + "VTLANG_LB_SBOOT_WINDOWS": "搜尋並啟動 Windows", + "VTLANG_LB_SBOOT_G4D": "搜尋並啟動 Grub4dos", + "VTLANG_LB_SBOOT_HDD1": "啟動本機硬碟1中的系統", + "VTLANG_LB_SBOOT_HDD2": "啟動本機硬碟2中的系統", + "VTLANG_LB_SBOOT_HDD3": "啟動本機硬碟3中的系統", + "VTLANG_LB_SBOOT_X64EFI": "搜尋並啟動 BOOTX64.EFI", + "VTLANG_LB_SBOOT_IA32EFI": "搜尋並啟動 BOOTIA32.EFI", + "VTLANG_LB_SBOOT_AA64EFI": "搜尋並啟動 BOOTAA64.EFI", + "VTLANG_LB_SBOOT_XORBOOT": "搜尋並啟動 xorboot", + + "VTLANG_FILE_CHKSUM": "校驗檔案", + "VTLANG_CHKSUM_MD5_CALC": "計算 MD5 檢查碼", + "VTLANG_CHKSUM_SHA1_CALC": "計算 SHA1 檢查碼", + "VTLANG_CHKSUM_SHA256_CALC": "計算 SHA256 檢查碼", + "VTLANG_CHKSUM_SHA512_CALC": "計算 SHA512 檢查碼", + "VTLANG_CHKSUM_MD5_CALC_CHK": "計算並檢查 MD5 檢查碼", + "VTLANG_CHKSUM_SHA1_CALC_CHK": "計算並檢查 SHA1 檢查碼", + "VTLANG_CHKSUM_SHA256_CALC_CHK": "計算並檢查 SHA256 檢查碼", + "VTLANG_CHKSUM_SHA512_CALC_CHK": "計算並檢查 SHA512 檢查碼", + + "VTLANG_POWER": "電源", + "VTLANG_POWER_REBOOT": "重新開機", + "VTLANG_POWER_HALT": "關機", + "VTLANG_POWER_BOOT_EFIFW": "重新開機進入 UEFI 設定選單", + + "VTLANG_KEYBRD_LAYOUT": "鍵盤設定", + "VTLANG_HWINFO": "硬體資訊", + + "VTLANG_RESOLUTION_CFG": "螢幕解析度", + "VTLANG_SCREEN_MODE": "顯示模式", + "VTLANG_SCREEN_TEXT_MODE": "強制文字模式", + "VTLANG_SCREEN_GUI_MODE": "強制圖形模式", + + "VTLANG_THEME_SELECT": "主題風格選擇", + + "VTLANG_UEFI_UTIL": "Ventoy UEFI 實用程式", + "VTLANG_UTIL_SHOW_EFI_DRV": "顯示 UEFI 驅動", + "VTLANG_UTIL_FIX_BLINIT_FAIL": "修復 Windows BlinitializeLibrary 錯誤", + + "VTLANG_JSON_CHK_JSON": "檢查外掛程式設定檔 (ventoy.json)", + "VTLANG_JSON_CHK_CONTROL": "設定檢查 —— 全域控制外掛程式", + "VTLANG_JSON_CHK_THEME": "設定檢查 —— 主題風格外掛程式", + "VTLANG_JSON_CHK_AUTOINS": "設定檢查 —— 自動安裝外掛程式", + "VTLANG_JSON_CHK_PERSIST": "設定檢查 —— 永久性外掛程式", + "VTLANG_JSON_CHK_MENU_ALIAS": "設定檢查 —— 功能表別名外掛程式", + "VTLANG_JSON_CHK_MENU_TIP": "設定檢查 —— 功能表提示外掛程式", + "VTLANG_JSON_CHK_MENU_CLASS": "設定檢查 —— 功能表分類外掛程式", + "VTLANG_JSON_CHK_INJECTION": "設定檢查 —— 檔注入外掛程式", + "VTLANG_JSON_CHK_AUTO_MEMDISK": "設定檢查 —— 自動 memdisk 模式外掛程式", + "VTLANG_JSON_CHK_IMG_LIST": "設定檢查 —— 映像檔清單外掛程式(白名單)", + "VTLANG_JSON_CHK_IMG_BLIST": "設定檢查 —— 映像檔清單外掛程式(黑名單)", + "VTLANG_JSON_CHK_CONF_REPLACE": "設定檢查 —— 啟動設定替換外掛程式", + "VTLANG_JSON_CHK_DUD": "設定檢查 —— Driver Update Disk外掛程式", + "VTLANG_JSON_CHK_PASSWORD": "設定檢查 —— 密碼外掛程式", + + "VTLANG_NORMAL_MODE": "以正常模式啟動", + "VTLANG_WIMBOOT_MODE": "以 wimboot 模式啟動", + "VTLANG_GRUB2_MODE": "以 grub2 模式啟動", + "VTLANG_MEMDISK_MODE": "以 memdisk 模式啟動", + + "VTLANG_RET_TO_LISTVIEW": "返回到清單檢視", + "VTLANG_RET_TO_TREEVIEW": "返回到樹狀檢視", + + "VTLANG_NO_AUTOINS_SCRIPT": "不使用自動安裝腳本", + "VTLANG_AUTOINS_USE": "使用", + + "VTLANG_NO_PERSIST": "不使用永久性資料檔案", + "VTLANG_PERSIST_USE": "使用", + + "VTLANG_BROWER_RETURN": "返回", + + "VTLANG_ENTER_EXIT": "按 Enter 鍵退出", + "VTLANG_ENTER_REBOOT": "按 Enter 鍵重新開機", + "VTLANG_ENTER_CONTINUE": "按 Enter 鍵繼續", + + "VTLANG_CTRL_TEMP_SET": "控制變數設定", + "VTLANG_WIN11_BYPASS_CHECK": "安裝 Windows 11 時繞過TPM/安全啟動等硬體檢查", + "VTLANG_WIN11_BYPASS_NRO": "安裝 Windows 11 時繞過登入帳戶的需求", + "VTLANG_LINUX_REMOUNT": "啟動 Linux 系統後掛載 Ventoy 分區", + "VTLANG_SECONDARY_BOOT_MENU": "顯示次要啟動選單", + "VTLANG_WIN_UEFI_RES_LOCK": "Lock the resolution when UEFI boot Windows/WinPE", + "VTLANG_UEFI_RES_LOCK_NONE": "None", + "VTLANG_UEFI_RES_LOCK_MAX": "Highest", + "VTLANG_UEFI_RES_LOCK_1024_768": "Fixed 1024 x 768", + "VTLANG_UEFI_RES_LOCK_BE1024_768": "At least 1024 x 768", + + "MENU_STR_XXX": "" +} diff --git a/INSTALL/grub/menulang.cfg b/INSTALL/grub/menulang.cfg new file mode 100644 index 0000000..e50f12f --- /dev/null +++ b/INSTALL/grub/menulang.cfg @@ -0,0 +1 @@ +#ventoy_pack.sh will generate menuentry here diff --git a/INSTALL/grub/mips64el-efi/adler32.mod b/INSTALL/grub/mips64el-efi/adler32.mod new file mode 100644 index 0000000..5c11d9a Binary files /dev/null and b/INSTALL/grub/mips64el-efi/adler32.mod differ diff --git a/INSTALL/grub/mips64el-efi/affs.mod b/INSTALL/grub/mips64el-efi/affs.mod new file mode 100644 index 0000000..79f7d3b Binary files /dev/null and b/INSTALL/grub/mips64el-efi/affs.mod differ diff --git a/INSTALL/grub/mips64el-efi/afs.mod b/INSTALL/grub/mips64el-efi/afs.mod new file mode 100644 index 0000000..e09eb7b Binary files /dev/null and b/INSTALL/grub/mips64el-efi/afs.mod differ diff --git a/INSTALL/grub/mips64el-efi/archelp.mod b/INSTALL/grub/mips64el-efi/archelp.mod new file mode 100644 index 0000000..75c8444 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/archelp.mod differ diff --git a/INSTALL/grub/mips64el-efi/bfs.mod b/INSTALL/grub/mips64el-efi/bfs.mod new file mode 100644 index 0000000..cb28a88 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/bfs.mod differ diff --git a/INSTALL/grub/mips64el-efi/blscfg.mod b/INSTALL/grub/mips64el-efi/blscfg.mod new file mode 100644 index 0000000..cdd0cd0 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/blscfg.mod differ diff --git a/INSTALL/grub/mips64el-efi/bswap_test.mod b/INSTALL/grub/mips64el-efi/bswap_test.mod new file mode 100644 index 0000000..e13d333 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/bswap_test.mod differ diff --git a/INSTALL/grub/mips64el-efi/btrfs.mod b/INSTALL/grub/mips64el-efi/btrfs.mod new file mode 100644 index 0000000..e3b549b Binary files /dev/null and b/INSTALL/grub/mips64el-efi/btrfs.mod differ diff --git a/INSTALL/grub/mips64el-efi/cbfs.mod b/INSTALL/grub/mips64el-efi/cbfs.mod new file mode 100644 index 0000000..c95efc9 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/cbfs.mod differ diff --git a/INSTALL/grub/mips64el-efi/cmdline_cat_test.mod b/INSTALL/grub/mips64el-efi/cmdline_cat_test.mod new file mode 100644 index 0000000..94df7a7 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/cmdline_cat_test.mod differ diff --git a/INSTALL/grub/mips64el-efi/cmp.mod b/INSTALL/grub/mips64el-efi/cmp.mod new file mode 100644 index 0000000..09e90e5 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/cmp.mod differ diff --git a/INSTALL/grub/mips64el-efi/cmp_test.mod b/INSTALL/grub/mips64el-efi/cmp_test.mod new file mode 100644 index 0000000..ecc41ff Binary files /dev/null and b/INSTALL/grub/mips64el-efi/cmp_test.mod differ diff --git a/INSTALL/grub/mips64el-efi/command.lst b/INSTALL/grub/mips64el-efi/command.lst new file mode 100644 index 0000000..1a5b7f8 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/command.lst differ diff --git a/INSTALL/grub/mips64el-efi/cpio.mod b/INSTALL/grub/mips64el-efi/cpio.mod new file mode 100644 index 0000000..0af3d1e Binary files /dev/null and b/INSTALL/grub/mips64el-efi/cpio.mod differ diff --git a/INSTALL/grub/mips64el-efi/cpio_be.mod b/INSTALL/grub/mips64el-efi/cpio_be.mod new file mode 100644 index 0000000..126fac3 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/cpio_be.mod differ diff --git a/INSTALL/grub/mips64el-efi/crc64.mod b/INSTALL/grub/mips64el-efi/crc64.mod new file mode 100644 index 0000000..175d347 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/crc64.mod differ diff --git a/INSTALL/grub/mips64el-efi/crypto.lst b/INSTALL/grub/mips64el-efi/crypto.lst new file mode 100644 index 0000000..bd0a97c Binary files /dev/null and b/INSTALL/grub/mips64el-efi/crypto.lst differ diff --git a/INSTALL/grub/mips64el-efi/cryptodisk.mod b/INSTALL/grub/mips64el-efi/cryptodisk.mod new file mode 100644 index 0000000..d887d4b Binary files /dev/null and b/INSTALL/grub/mips64el-efi/cryptodisk.mod differ diff --git a/INSTALL/grub/mips64el-efi/ctz_test.mod b/INSTALL/grub/mips64el-efi/ctz_test.mod new file mode 100644 index 0000000..e8ffc84 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/ctz_test.mod differ diff --git a/INSTALL/grub/mips64el-efi/date.mod b/INSTALL/grub/mips64el-efi/date.mod new file mode 100644 index 0000000..9c9dd99 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/date.mod differ diff --git a/INSTALL/grub/mips64el-efi/datehook.mod b/INSTALL/grub/mips64el-efi/datehook.mod new file mode 100644 index 0000000..4dace4a Binary files /dev/null and b/INSTALL/grub/mips64el-efi/datehook.mod differ diff --git a/INSTALL/grub/mips64el-efi/disk.mod b/INSTALL/grub/mips64el-efi/disk.mod new file mode 100644 index 0000000..7c67ffc Binary files /dev/null and b/INSTALL/grub/mips64el-efi/disk.mod differ diff --git a/INSTALL/grub/mips64el-efi/div.mod b/INSTALL/grub/mips64el-efi/div.mod new file mode 100644 index 0000000..f847722 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/div.mod differ diff --git a/INSTALL/grub/mips64el-efi/div_test.mod b/INSTALL/grub/mips64el-efi/div_test.mod new file mode 100644 index 0000000..d16bb6a Binary files /dev/null and b/INSTALL/grub/mips64el-efi/div_test.mod differ diff --git a/INSTALL/grub/mips64el-efi/dm_nv.mod b/INSTALL/grub/mips64el-efi/dm_nv.mod new file mode 100644 index 0000000..74749a3 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/dm_nv.mod differ diff --git a/INSTALL/grub/mips64el-efi/efinet.mod b/INSTALL/grub/mips64el-efi/efinet.mod new file mode 100644 index 0000000..c81d8bc Binary files /dev/null and b/INSTALL/grub/mips64el-efi/efinet.mod differ diff --git a/INSTALL/grub/mips64el-efi/elf.mod b/INSTALL/grub/mips64el-efi/elf.mod new file mode 100644 index 0000000..2a69995 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/elf.mod differ diff --git a/INSTALL/grub/mips64el-efi/eval.mod b/INSTALL/grub/mips64el-efi/eval.mod new file mode 100644 index 0000000..37eefdb Binary files /dev/null and b/INSTALL/grub/mips64el-efi/eval.mod differ diff --git a/INSTALL/grub/mips64el-efi/exfctest.mod b/INSTALL/grub/mips64el-efi/exfctest.mod new file mode 100644 index 0000000..3db7c61 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/exfctest.mod differ diff --git a/INSTALL/grub/mips64el-efi/f2fs.mod b/INSTALL/grub/mips64el-efi/f2fs.mod new file mode 100644 index 0000000..3516fe3 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/f2fs.mod differ diff --git a/INSTALL/grub/mips64el-efi/fdt.lst b/INSTALL/grub/mips64el-efi/fdt.lst new file mode 100644 index 0000000..ea28d9e Binary files /dev/null and b/INSTALL/grub/mips64el-efi/fdt.lst differ diff --git a/INSTALL/grub/mips64el-efi/fs.lst b/INSTALL/grub/mips64el-efi/fs.lst new file mode 100644 index 0000000..12c6c9d Binary files /dev/null and b/INSTALL/grub/mips64el-efi/fs.lst differ diff --git a/INSTALL/grub/mips64el-efi/functional_test.mod b/INSTALL/grub/mips64el-efi/functional_test.mod new file mode 100644 index 0000000..164797a Binary files /dev/null and b/INSTALL/grub/mips64el-efi/functional_test.mod differ diff --git a/INSTALL/grub/mips64el-efi/fwload.mod b/INSTALL/grub/mips64el-efi/fwload.mod new file mode 100644 index 0000000..14a0d32 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/fwload.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_arcfour.mod b/INSTALL/grub/mips64el-efi/gcry_arcfour.mod new file mode 100644 index 0000000..69f507a Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_arcfour.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_blowfish.mod b/INSTALL/grub/mips64el-efi/gcry_blowfish.mod new file mode 100644 index 0000000..ec968a3 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_blowfish.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_camellia.mod b/INSTALL/grub/mips64el-efi/gcry_camellia.mod new file mode 100644 index 0000000..61d964a Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_camellia.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_cast5.mod b/INSTALL/grub/mips64el-efi/gcry_cast5.mod new file mode 100644 index 0000000..bebfb7a Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_cast5.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_crc.mod b/INSTALL/grub/mips64el-efi/gcry_crc.mod new file mode 100644 index 0000000..2206b68 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_crc.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_des.mod b/INSTALL/grub/mips64el-efi/gcry_des.mod new file mode 100644 index 0000000..8c1f69d Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_des.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_dsa.mod b/INSTALL/grub/mips64el-efi/gcry_dsa.mod new file mode 100644 index 0000000..9ab092d Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_dsa.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_idea.mod b/INSTALL/grub/mips64el-efi/gcry_idea.mod new file mode 100644 index 0000000..8e52677 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_idea.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_md4.mod b/INSTALL/grub/mips64el-efi/gcry_md4.mod new file mode 100644 index 0000000..6e01627 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_md4.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_rfc2268.mod b/INSTALL/grub/mips64el-efi/gcry_rfc2268.mod new file mode 100644 index 0000000..57760d9 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_rfc2268.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_rijndael.mod b/INSTALL/grub/mips64el-efi/gcry_rijndael.mod new file mode 100644 index 0000000..d3a6068 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_rijndael.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_rmd160.mod b/INSTALL/grub/mips64el-efi/gcry_rmd160.mod new file mode 100644 index 0000000..6f8be83 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_rmd160.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_rsa.mod b/INSTALL/grub/mips64el-efi/gcry_rsa.mod new file mode 100644 index 0000000..d19584c Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_rsa.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_seed.mod b/INSTALL/grub/mips64el-efi/gcry_seed.mod new file mode 100644 index 0000000..ba695b3 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_seed.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_serpent.mod b/INSTALL/grub/mips64el-efi/gcry_serpent.mod new file mode 100644 index 0000000..9507246 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_serpent.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_sha1.mod b/INSTALL/grub/mips64el-efi/gcry_sha1.mod new file mode 100644 index 0000000..e71483f Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_sha1.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_sha256.mod b/INSTALL/grub/mips64el-efi/gcry_sha256.mod new file mode 100644 index 0000000..6ce2ad4 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_sha256.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_tiger.mod b/INSTALL/grub/mips64el-efi/gcry_tiger.mod new file mode 100644 index 0000000..b771dc8 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_tiger.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_twofish.mod b/INSTALL/grub/mips64el-efi/gcry_twofish.mod new file mode 100644 index 0000000..5c13e90 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_twofish.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_whirlpool.mod b/INSTALL/grub/mips64el-efi/gcry_whirlpool.mod new file mode 100644 index 0000000..b48b76d Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_whirlpool.mod differ diff --git a/INSTALL/grub/mips64el-efi/geli.mod b/INSTALL/grub/mips64el-efi/geli.mod new file mode 100644 index 0000000..ca127ca Binary files /dev/null and b/INSTALL/grub/mips64el-efi/geli.mod differ diff --git a/INSTALL/grub/mips64el-efi/gptsync.mod b/INSTALL/grub/mips64el-efi/gptsync.mod new file mode 100644 index 0000000..2efaf74 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gptsync.mod differ diff --git a/INSTALL/grub/mips64el-efi/hello.mod b/INSTALL/grub/mips64el-efi/hello.mod new file mode 100644 index 0000000..b43acca Binary files /dev/null and b/INSTALL/grub/mips64el-efi/hello.mod differ diff --git a/INSTALL/grub/mips64el-efi/help.mod b/INSTALL/grub/mips64el-efi/help.mod new file mode 100644 index 0000000..b5333a2 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/help.mod differ diff --git a/INSTALL/grub/mips64el-efi/hexdump.mod b/INSTALL/grub/mips64el-efi/hexdump.mod new file mode 100644 index 0000000..e9240e8 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/hexdump.mod differ diff --git a/INSTALL/grub/mips64el-efi/hfs.mod b/INSTALL/grub/mips64el-efi/hfs.mod new file mode 100644 index 0000000..a13022b Binary files /dev/null and b/INSTALL/grub/mips64el-efi/hfs.mod differ diff --git a/INSTALL/grub/mips64el-efi/hfspluscomp.mod b/INSTALL/grub/mips64el-efi/hfspluscomp.mod new file mode 100644 index 0000000..72a9938 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/hfspluscomp.mod differ diff --git a/INSTALL/grub/mips64el-efi/jfs.mod b/INSTALL/grub/mips64el-efi/jfs.mod new file mode 100644 index 0000000..3104fb7 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/jfs.mod differ diff --git a/INSTALL/grub/mips64el-efi/keystatus.mod b/INSTALL/grub/mips64el-efi/keystatus.mod new file mode 100644 index 0000000..aafda35 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/keystatus.mod differ diff --git a/INSTALL/grub/mips64el-efi/ldm.mod b/INSTALL/grub/mips64el-efi/ldm.mod new file mode 100644 index 0000000..7a4240c Binary files /dev/null and b/INSTALL/grub/mips64el-efi/ldm.mod differ diff --git a/INSTALL/grub/mips64el-efi/loadenv.mod b/INSTALL/grub/mips64el-efi/loadenv.mod new file mode 100644 index 0000000..7584c9b Binary files /dev/null and b/INSTALL/grub/mips64el-efi/loadenv.mod differ diff --git a/INSTALL/grub/mips64el-efi/lsacpi.mod b/INSTALL/grub/mips64el-efi/lsacpi.mod new file mode 100644 index 0000000..f1dafe2 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/lsacpi.mod differ diff --git a/INSTALL/grub/mips64el-efi/lsefi.mod b/INSTALL/grub/mips64el-efi/lsefi.mod new file mode 100644 index 0000000..e7428a2 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/lsefi.mod differ diff --git a/INSTALL/grub/mips64el-efi/lsefimmap.mod b/INSTALL/grub/mips64el-efi/lsefimmap.mod new file mode 100644 index 0000000..d2bd312 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/lsefimmap.mod differ diff --git a/INSTALL/grub/mips64el-efi/lsefisystab.mod b/INSTALL/grub/mips64el-efi/lsefisystab.mod new file mode 100644 index 0000000..f199439 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/lsefisystab.mod differ diff --git a/INSTALL/grub/mips64el-efi/lsmmap.mod b/INSTALL/grub/mips64el-efi/lsmmap.mod new file mode 100644 index 0000000..2835774 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/lsmmap.mod differ diff --git a/INSTALL/grub/mips64el-efi/lssal.mod b/INSTALL/grub/mips64el-efi/lssal.mod new file mode 100644 index 0000000..57f9eb3 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/lssal.mod differ diff --git a/INSTALL/grub/mips64el-efi/luks.mod b/INSTALL/grub/mips64el-efi/luks.mod new file mode 100644 index 0000000..eade785 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/luks.mod differ diff --git a/INSTALL/grub/mips64el-efi/lvm.mod b/INSTALL/grub/mips64el-efi/lvm.mod new file mode 100644 index 0000000..88d2fb1 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/lvm.mod differ diff --git a/INSTALL/grub/mips64el-efi/macbless.mod b/INSTALL/grub/mips64el-efi/macbless.mod new file mode 100644 index 0000000..e063217 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/macbless.mod differ diff --git a/INSTALL/grub/mips64el-efi/macho.mod b/INSTALL/grub/mips64el-efi/macho.mod new file mode 100644 index 0000000..043b2e7 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/macho.mod differ diff --git a/INSTALL/grub/mips64el-efi/mdraid09.mod b/INSTALL/grub/mips64el-efi/mdraid09.mod new file mode 100644 index 0000000..351ae1b Binary files /dev/null and b/INSTALL/grub/mips64el-efi/mdraid09.mod differ diff --git a/INSTALL/grub/mips64el-efi/mdraid09_be.mod b/INSTALL/grub/mips64el-efi/mdraid09_be.mod new file mode 100644 index 0000000..24394f4 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/mdraid09_be.mod differ diff --git a/INSTALL/grub/mips64el-efi/mdraid1x.mod b/INSTALL/grub/mips64el-efi/mdraid1x.mod new file mode 100644 index 0000000..f9e374c Binary files /dev/null and b/INSTALL/grub/mips64el-efi/mdraid1x.mod differ diff --git a/INSTALL/grub/mips64el-efi/memdisk.mod b/INSTALL/grub/mips64el-efi/memdisk.mod new file mode 100644 index 0000000..86932db Binary files /dev/null and b/INSTALL/grub/mips64el-efi/memdisk.mod differ diff --git a/INSTALL/grub/mips64el-efi/memrw.mod b/INSTALL/grub/mips64el-efi/memrw.mod new file mode 100644 index 0000000..a0a6dde Binary files /dev/null and b/INSTALL/grub/mips64el-efi/memrw.mod differ diff --git a/INSTALL/grub/mips64el-efi/minix.mod b/INSTALL/grub/mips64el-efi/minix.mod new file mode 100644 index 0000000..ef34533 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/minix.mod differ diff --git a/INSTALL/grub/mips64el-efi/minix2.mod b/INSTALL/grub/mips64el-efi/minix2.mod new file mode 100644 index 0000000..cd505fa Binary files /dev/null and b/INSTALL/grub/mips64el-efi/minix2.mod differ diff --git a/INSTALL/grub/mips64el-efi/minix2_be.mod b/INSTALL/grub/mips64el-efi/minix2_be.mod new file mode 100644 index 0000000..7f4fec2 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/minix2_be.mod differ diff --git a/INSTALL/grub/mips64el-efi/minix3.mod b/INSTALL/grub/mips64el-efi/minix3.mod new file mode 100644 index 0000000..d2b94ca Binary files /dev/null and b/INSTALL/grub/mips64el-efi/minix3.mod differ diff --git a/INSTALL/grub/mips64el-efi/minix3_be.mod b/INSTALL/grub/mips64el-efi/minix3_be.mod new file mode 100644 index 0000000..13bf1ba Binary files /dev/null and b/INSTALL/grub/mips64el-efi/minix3_be.mod differ diff --git a/INSTALL/grub/mips64el-efi/minix_be.mod b/INSTALL/grub/mips64el-efi/minix_be.mod new file mode 100644 index 0000000..2b58151 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/minix_be.mod differ diff --git a/INSTALL/grub/mips64el-efi/moddep.lst b/INSTALL/grub/mips64el-efi/moddep.lst new file mode 100644 index 0000000..427a4b0 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/moddep.lst differ diff --git a/INSTALL/grub/mips64el-efi/mouse.mod b/INSTALL/grub/mips64el-efi/mouse.mod new file mode 100644 index 0000000..bc2dda8 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/mouse.mod differ diff --git a/INSTALL/grub/mips64el-efi/mpi.mod b/INSTALL/grub/mips64el-efi/mpi.mod new file mode 100644 index 0000000..a847b2e Binary files /dev/null and b/INSTALL/grub/mips64el-efi/mpi.mod differ diff --git a/INSTALL/grub/mips64el-efi/msdospart.mod b/INSTALL/grub/mips64el-efi/msdospart.mod new file mode 100644 index 0000000..1c485a3 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/msdospart.mod differ diff --git a/INSTALL/grub/mips64el-efi/mul_test.mod b/INSTALL/grub/mips64el-efi/mul_test.mod new file mode 100644 index 0000000..4d539b3 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/mul_test.mod differ diff --git a/INSTALL/grub/mips64el-efi/nilfs2.mod b/INSTALL/grub/mips64el-efi/nilfs2.mod new file mode 100644 index 0000000..6189366 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/nilfs2.mod differ diff --git a/INSTALL/grub/mips64el-efi/normal.mod b/INSTALL/grub/mips64el-efi/normal.mod new file mode 100644 index 0000000..8c4f138 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/normal.mod differ diff --git a/INSTALL/grub/mips64el-efi/ntfscomp.mod b/INSTALL/grub/mips64el-efi/ntfscomp.mod new file mode 100644 index 0000000..b24d9ae Binary files /dev/null and b/INSTALL/grub/mips64el-efi/ntfscomp.mod differ diff --git a/INSTALL/grub/mips64el-efi/odc.mod b/INSTALL/grub/mips64el-efi/odc.mod new file mode 100644 index 0000000..20afc1e Binary files /dev/null and b/INSTALL/grub/mips64el-efi/odc.mod differ diff --git a/INSTALL/grub/mips64el-efi/offsetio.mod b/INSTALL/grub/mips64el-efi/offsetio.mod new file mode 100644 index 0000000..c314738 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/offsetio.mod differ diff --git a/INSTALL/grub/mips64el-efi/part_acorn.mod b/INSTALL/grub/mips64el-efi/part_acorn.mod new file mode 100644 index 0000000..6ecce91 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/part_acorn.mod differ diff --git a/INSTALL/grub/mips64el-efi/part_amiga.mod b/INSTALL/grub/mips64el-efi/part_amiga.mod new file mode 100644 index 0000000..a705f8d Binary files /dev/null and b/INSTALL/grub/mips64el-efi/part_amiga.mod differ diff --git a/INSTALL/grub/mips64el-efi/part_bsd.mod b/INSTALL/grub/mips64el-efi/part_bsd.mod new file mode 100644 index 0000000..e4523e7 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/part_bsd.mod differ diff --git a/INSTALL/grub/mips64el-efi/part_dfly.mod b/INSTALL/grub/mips64el-efi/part_dfly.mod new file mode 100644 index 0000000..6b6dde0 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/part_dfly.mod differ diff --git a/INSTALL/grub/mips64el-efi/part_dvh.mod b/INSTALL/grub/mips64el-efi/part_dvh.mod new file mode 100644 index 0000000..a3582cc Binary files /dev/null and b/INSTALL/grub/mips64el-efi/part_dvh.mod differ diff --git a/INSTALL/grub/mips64el-efi/part_plan.mod b/INSTALL/grub/mips64el-efi/part_plan.mod new file mode 100644 index 0000000..e7b9cc2 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/part_plan.mod differ diff --git a/INSTALL/grub/mips64el-efi/part_sun.mod b/INSTALL/grub/mips64el-efi/part_sun.mod new file mode 100644 index 0000000..4dcb3af Binary files /dev/null and b/INSTALL/grub/mips64el-efi/part_sun.mod differ diff --git a/INSTALL/grub/mips64el-efi/part_sunpc.mod b/INSTALL/grub/mips64el-efi/part_sunpc.mod new file mode 100644 index 0000000..7aea649 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/part_sunpc.mod differ diff --git a/INSTALL/grub/mips64el-efi/partmap.lst b/INSTALL/grub/mips64el-efi/partmap.lst new file mode 100644 index 0000000..720c55e Binary files /dev/null and b/INSTALL/grub/mips64el-efi/partmap.lst differ diff --git a/INSTALL/grub/mips64el-efi/parttool.lst b/INSTALL/grub/mips64el-efi/parttool.lst new file mode 100644 index 0000000..bfa2d4a Binary files /dev/null and b/INSTALL/grub/mips64el-efi/parttool.lst differ diff --git a/INSTALL/grub/mips64el-efi/parttool.mod b/INSTALL/grub/mips64el-efi/parttool.mod new file mode 100644 index 0000000..d93f08c Binary files /dev/null and b/INSTALL/grub/mips64el-efi/parttool.mod differ diff --git a/INSTALL/grub/mips64el-efi/password.mod b/INSTALL/grub/mips64el-efi/password.mod new file mode 100644 index 0000000..f7e9043 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/password.mod differ diff --git a/INSTALL/grub/mips64el-efi/pbkdf2_test.mod b/INSTALL/grub/mips64el-efi/pbkdf2_test.mod new file mode 100644 index 0000000..6dd1452 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/pbkdf2_test.mod differ diff --git a/INSTALL/grub/mips64el-efi/pgp.mod b/INSTALL/grub/mips64el-efi/pgp.mod new file mode 100644 index 0000000..24f438f Binary files /dev/null and b/INSTALL/grub/mips64el-efi/pgp.mod differ diff --git a/INSTALL/grub/mips64el-efi/probe.mod b/INSTALL/grub/mips64el-efi/probe.mod new file mode 100644 index 0000000..30ae5a8 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/probe.mod differ diff --git a/INSTALL/grub/mips64el-efi/procfs.mod b/INSTALL/grub/mips64el-efi/procfs.mod new file mode 100644 index 0000000..f831889 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/procfs.mod differ diff --git a/INSTALL/grub/mips64el-efi/progress.mod b/INSTALL/grub/mips64el-efi/progress.mod new file mode 100644 index 0000000..b23fc39 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/progress.mod differ diff --git a/INSTALL/grub/mips64el-efi/raid5rec.mod b/INSTALL/grub/mips64el-efi/raid5rec.mod new file mode 100644 index 0000000..2724de9 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/raid5rec.mod differ diff --git a/INSTALL/grub/mips64el-efi/raid6rec.mod b/INSTALL/grub/mips64el-efi/raid6rec.mod new file mode 100644 index 0000000..5dbcaf9 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/raid6rec.mod differ diff --git a/INSTALL/grub/mips64el-efi/reiserfs.mod b/INSTALL/grub/mips64el-efi/reiserfs.mod new file mode 100644 index 0000000..6eee7c9 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/reiserfs.mod differ diff --git a/INSTALL/grub/mips64el-efi/relocator.mod b/INSTALL/grub/mips64el-efi/relocator.mod new file mode 100644 index 0000000..1d7be9d Binary files /dev/null and b/INSTALL/grub/mips64el-efi/relocator.mod differ diff --git a/INSTALL/grub/mips64el-efi/romfs.mod b/INSTALL/grub/mips64el-efi/romfs.mod new file mode 100644 index 0000000..7e90eb2 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/romfs.mod differ diff --git a/INSTALL/grub/mips64el-efi/scsi.mod b/INSTALL/grub/mips64el-efi/scsi.mod new file mode 100644 index 0000000..4699e75 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/scsi.mod differ diff --git a/INSTALL/grub/mips64el-efi/search_fs_file.mod b/INSTALL/grub/mips64el-efi/search_fs_file.mod new file mode 100644 index 0000000..0aa8d45 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/search_fs_file.mod differ diff --git a/INSTALL/grub/mips64el-efi/search_fs_uuid.mod b/INSTALL/grub/mips64el-efi/search_fs_uuid.mod new file mode 100644 index 0000000..be770e0 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/search_fs_uuid.mod differ diff --git a/INSTALL/grub/mips64el-efi/search_label.mod b/INSTALL/grub/mips64el-efi/search_label.mod new file mode 100644 index 0000000..0c50342 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/search_label.mod differ diff --git a/INSTALL/grub/mips64el-efi/setjmp.mod b/INSTALL/grub/mips64el-efi/setjmp.mod new file mode 100644 index 0000000..456d469 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/setjmp.mod differ diff --git a/INSTALL/grub/mips64el-efi/setjmp_test.mod b/INSTALL/grub/mips64el-efi/setjmp_test.mod new file mode 100644 index 0000000..42dbc0e Binary files /dev/null and b/INSTALL/grub/mips64el-efi/setjmp_test.mod differ diff --git a/INSTALL/grub/mips64el-efi/sfs.mod b/INSTALL/grub/mips64el-efi/sfs.mod new file mode 100644 index 0000000..4ea53fe Binary files /dev/null and b/INSTALL/grub/mips64el-efi/sfs.mod differ diff --git a/INSTALL/grub/mips64el-efi/shift_test.mod b/INSTALL/grub/mips64el-efi/shift_test.mod new file mode 100644 index 0000000..09e8693 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/shift_test.mod differ diff --git a/INSTALL/grub/mips64el-efi/signature_test.mod b/INSTALL/grub/mips64el-efi/signature_test.mod new file mode 100644 index 0000000..10354fc Binary files /dev/null and b/INSTALL/grub/mips64el-efi/signature_test.mod differ diff --git a/INSTALL/grub/mips64el-efi/sleep_test.mod b/INSTALL/grub/mips64el-efi/sleep_test.mod new file mode 100644 index 0000000..8100c64 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/sleep_test.mod differ diff --git a/INSTALL/grub/mips64el-efi/smbios.mod b/INSTALL/grub/mips64el-efi/smbios.mod new file mode 100644 index 0000000..21fd7d4 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/smbios.mod differ diff --git a/INSTALL/grub/mips64el-efi/strtoull_test.mod b/INSTALL/grub/mips64el-efi/strtoull_test.mod new file mode 100644 index 0000000..248498a Binary files /dev/null and b/INSTALL/grub/mips64el-efi/strtoull_test.mod differ diff --git a/INSTALL/grub/mips64el-efi/syslinuxcfg.mod b/INSTALL/grub/mips64el-efi/syslinuxcfg.mod new file mode 100644 index 0000000..2271802 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/syslinuxcfg.mod differ diff --git a/INSTALL/grub/mips64el-efi/terminal.lst b/INSTALL/grub/mips64el-efi/terminal.lst new file mode 100644 index 0000000..0f853df Binary files /dev/null and b/INSTALL/grub/mips64el-efi/terminal.lst differ diff --git a/INSTALL/grub/mips64el-efi/test_blockarg.mod b/INSTALL/grub/mips64el-efi/test_blockarg.mod new file mode 100644 index 0000000..d84f601 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/test_blockarg.mod differ diff --git a/INSTALL/grub/mips64el-efi/testload.mod b/INSTALL/grub/mips64el-efi/testload.mod new file mode 100644 index 0000000..3a241b0 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/testload.mod differ diff --git a/INSTALL/grub/mips64el-efi/testspeed.mod b/INSTALL/grub/mips64el-efi/testspeed.mod new file mode 100644 index 0000000..145c704 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/testspeed.mod differ diff --git a/INSTALL/grub/mips64el-efi/tga.mod b/INSTALL/grub/mips64el-efi/tga.mod new file mode 100644 index 0000000..c6ab4b4 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/tga.mod differ diff --git a/INSTALL/grub/mips64el-efi/time.mod b/INSTALL/grub/mips64el-efi/time.mod new file mode 100644 index 0000000..ddb2b09 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/time.mod differ diff --git a/INSTALL/grub/mips64el-efi/tr.mod b/INSTALL/grub/mips64el-efi/tr.mod new file mode 100644 index 0000000..736b18b Binary files /dev/null and b/INSTALL/grub/mips64el-efi/tr.mod differ diff --git a/INSTALL/grub/mips64el-efi/ufs1.mod b/INSTALL/grub/mips64el-efi/ufs1.mod new file mode 100644 index 0000000..a8a1936 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/ufs1.mod differ diff --git a/INSTALL/grub/mips64el-efi/ufs1_be.mod b/INSTALL/grub/mips64el-efi/ufs1_be.mod new file mode 100644 index 0000000..521caf3 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/ufs1_be.mod differ diff --git a/INSTALL/grub/mips64el-efi/ufs2.mod b/INSTALL/grub/mips64el-efi/ufs2.mod new file mode 100644 index 0000000..f2a6318 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/ufs2.mod differ diff --git a/INSTALL/grub/mips64el-efi/verifiers.mod b/INSTALL/grub/mips64el-efi/verifiers.mod new file mode 100644 index 0000000..e058a90 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/verifiers.mod differ diff --git a/INSTALL/grub/mips64el-efi/video.lst b/INSTALL/grub/mips64el-efi/video.lst new file mode 100644 index 0000000..ad1dbd0 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/video.lst differ diff --git a/INSTALL/grub/mips64el-efi/videoinfo.mod b/INSTALL/grub/mips64el-efi/videoinfo.mod new file mode 100644 index 0000000..09973fe Binary files /dev/null and b/INSTALL/grub/mips64el-efi/videoinfo.mod differ diff --git a/INSTALL/grub/mips64el-efi/videotest.mod b/INSTALL/grub/mips64el-efi/videotest.mod new file mode 100644 index 0000000..a5884a2 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/videotest.mod differ diff --git a/INSTALL/grub/mips64el-efi/videotest_checksum.mod b/INSTALL/grub/mips64el-efi/videotest_checksum.mod new file mode 100644 index 0000000..c35ef24 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/videotest_checksum.mod differ diff --git a/INSTALL/grub/mips64el-efi/xnu_uuid.mod b/INSTALL/grub/mips64el-efi/xnu_uuid.mod new file mode 100644 index 0000000..9d9b25b Binary files /dev/null and b/INSTALL/grub/mips64el-efi/xnu_uuid.mod differ diff --git a/INSTALL/grub/mips64el-efi/xnu_uuid_test.mod b/INSTALL/grub/mips64el-efi/xnu_uuid_test.mod new file mode 100644 index 0000000..1eaf08d Binary files /dev/null and b/INSTALL/grub/mips64el-efi/xnu_uuid_test.mod differ diff --git a/INSTALL/grub/mips64el-efi/zfs.mod b/INSTALL/grub/mips64el-efi/zfs.mod new file mode 100644 index 0000000..46fe086 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/zfs.mod differ diff --git a/INSTALL/grub/mips64el-efi/zfscrypt.mod b/INSTALL/grub/mips64el-efi/zfscrypt.mod new file mode 100644 index 0000000..df770b3 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/zfscrypt.mod differ diff --git a/INSTALL/grub/mips64el-efi/zfsinfo.mod b/INSTALL/grub/mips64el-efi/zfsinfo.mod new file mode 100644 index 0000000..ff09333 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/zfsinfo.mod differ diff --git a/INSTALL/grub/mips64el-efi/zstd.mod b/INSTALL/grub/mips64el-efi/zstd.mod new file mode 100644 index 0000000..ee57185 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/zstd.mod differ diff --git a/INSTALL/grub/power.cfg b/INSTALL/grub/power.cfg new file mode 100644 index 0000000..293151c --- /dev/null +++ b/INSTALL/grub/power.cfg @@ -0,0 +1,25 @@ +submenu "$VTLANG_POWER" --class=debug_power --class=F5tool { + menuentry "$VTLANG_POWER_REBOOT" --class=debug_reboot --class=debug_power --class=F5tool { + echo -e '\n\nSystem is rebooting ... \n' + sleep 1 + reboot + } + + menuentry "$VTLANG_POWER_HALT" --class=debug_halt --class=debug_power --class=F5tool { + echo -e '\n\nSystem is halting ... \n' + sleep 1 + halt + } + + if [ "$grub_platform" != "pc" ]; then + menuentry "$VTLANG_POWER_BOOT_EFIFW" --class=debug_efisetup --class=debug_power --class=F5tool { + echo -e '\n\nRebooting to enter UEFI firmware setup ... \n' + sleep 1 + fwsetup + } + fi + + menuentry "$VTLANG_RETURN_PREVIOUS" --class=vtoyret VTOY_RET { + echo "Return ..." + } +} diff --git a/INSTALL/grub/themes/ventoy/background.png b/INSTALL/grub/themes/ventoy/background.png new file mode 100644 index 0000000..8a4ac94 Binary files /dev/null and b/INSTALL/grub/themes/ventoy/background.png differ diff --git a/INSTALL/grub/themes/ventoy/menu_c.png b/INSTALL/grub/themes/ventoy/menu_c.png new file mode 100644 index 0000000..75c165b Binary files /dev/null and b/INSTALL/grub/themes/ventoy/menu_c.png differ diff --git a/INSTALL/grub/themes/ventoy/menu_e.png b/INSTALL/grub/themes/ventoy/menu_e.png new file mode 100644 index 0000000..d4c7421 Binary files /dev/null and b/INSTALL/grub/themes/ventoy/menu_e.png differ diff --git a/INSTALL/grub/themes/ventoy/menu_n.png b/INSTALL/grub/themes/ventoy/menu_n.png new file mode 100644 index 0000000..5af3469 Binary files /dev/null and b/INSTALL/grub/themes/ventoy/menu_n.png differ diff --git a/INSTALL/grub/themes/ventoy/menu_ne.png b/INSTALL/grub/themes/ventoy/menu_ne.png new file mode 100644 index 0000000..8757868 Binary files /dev/null and b/INSTALL/grub/themes/ventoy/menu_ne.png differ diff --git a/INSTALL/grub/themes/ventoy/menu_nw.png b/INSTALL/grub/themes/ventoy/menu_nw.png new file mode 100644 index 0000000..8757868 Binary files /dev/null and b/INSTALL/grub/themes/ventoy/menu_nw.png differ diff --git a/INSTALL/grub/themes/ventoy/menu_s.png b/INSTALL/grub/themes/ventoy/menu_s.png new file mode 100644 index 0000000..6ba2734 Binary files /dev/null and b/INSTALL/grub/themes/ventoy/menu_s.png differ diff --git a/INSTALL/grub/themes/ventoy/menu_se.png b/INSTALL/grub/themes/ventoy/menu_se.png new file mode 100644 index 0000000..959b609 Binary files /dev/null and b/INSTALL/grub/themes/ventoy/menu_se.png differ diff --git a/INSTALL/grub/themes/ventoy/menu_sw.png b/INSTALL/grub/themes/ventoy/menu_sw.png new file mode 100644 index 0000000..959b609 Binary files /dev/null and b/INSTALL/grub/themes/ventoy/menu_sw.png differ diff --git a/INSTALL/grub/themes/ventoy/menu_w.png b/INSTALL/grub/themes/ventoy/menu_w.png new file mode 100644 index 0000000..d4c7421 Binary files /dev/null and b/INSTALL/grub/themes/ventoy/menu_w.png differ diff --git a/INSTALL/grub/themes/ventoy/select_c.png b/INSTALL/grub/themes/ventoy/select_c.png new file mode 100644 index 0000000..245259a Binary files /dev/null and b/INSTALL/grub/themes/ventoy/select_c.png differ diff --git a/INSTALL/grub/themes/ventoy/slider_c.png b/INSTALL/grub/themes/ventoy/slider_c.png new file mode 100644 index 0000000..7d630fd Binary files /dev/null and b/INSTALL/grub/themes/ventoy/slider_c.png differ diff --git a/INSTALL/grub/themes/ventoy/slider_n.png b/INSTALL/grub/themes/ventoy/slider_n.png new file mode 100644 index 0000000..41482c9 Binary files /dev/null and b/INSTALL/grub/themes/ventoy/slider_n.png differ diff --git a/INSTALL/grub/themes/ventoy/slider_s.png b/INSTALL/grub/themes/ventoy/slider_s.png new file mode 100644 index 0000000..17adc2a Binary files /dev/null and b/INSTALL/grub/themes/ventoy/slider_s.png differ diff --git a/INSTALL/grub/themes/ventoy/terminal_box_c.png b/INSTALL/grub/themes/ventoy/terminal_box_c.png new file mode 100644 index 0000000..d0dd52a Binary files /dev/null and b/INSTALL/grub/themes/ventoy/terminal_box_c.png differ diff --git a/INSTALL/grub/themes/ventoy/terminal_box_e.png b/INSTALL/grub/themes/ventoy/terminal_box_e.png new file mode 100644 index 0000000..394cbe4 Binary files /dev/null and b/INSTALL/grub/themes/ventoy/terminal_box_e.png differ diff --git a/INSTALL/grub/themes/ventoy/terminal_box_n.png b/INSTALL/grub/themes/ventoy/terminal_box_n.png new file mode 100644 index 0000000..476f8bc Binary files /dev/null and b/INSTALL/grub/themes/ventoy/terminal_box_n.png differ diff --git a/INSTALL/grub/themes/ventoy/terminal_box_ne.png b/INSTALL/grub/themes/ventoy/terminal_box_ne.png new file mode 100644 index 0000000..9e26959 Binary files /dev/null and b/INSTALL/grub/themes/ventoy/terminal_box_ne.png differ diff --git a/INSTALL/grub/themes/ventoy/terminal_box_nw.png b/INSTALL/grub/themes/ventoy/terminal_box_nw.png new file mode 100644 index 0000000..5c3cba8 Binary files /dev/null and b/INSTALL/grub/themes/ventoy/terminal_box_nw.png differ diff --git a/INSTALL/grub/themes/ventoy/terminal_box_s.png b/INSTALL/grub/themes/ventoy/terminal_box_s.png new file mode 100644 index 0000000..85a8901 Binary files /dev/null and b/INSTALL/grub/themes/ventoy/terminal_box_s.png differ diff --git a/INSTALL/grub/themes/ventoy/terminal_box_se.png b/INSTALL/grub/themes/ventoy/terminal_box_se.png new file mode 100644 index 0000000..d8627ee Binary files /dev/null and b/INSTALL/grub/themes/ventoy/terminal_box_se.png differ diff --git a/INSTALL/grub/themes/ventoy/terminal_box_sw.png b/INSTALL/grub/themes/ventoy/terminal_box_sw.png new file mode 100644 index 0000000..67c600c Binary files /dev/null and b/INSTALL/grub/themes/ventoy/terminal_box_sw.png differ diff --git a/INSTALL/grub/themes/ventoy/terminal_box_w.png b/INSTALL/grub/themes/ventoy/terminal_box_w.png new file mode 100644 index 0000000..d066e2d Binary files /dev/null and b/INSTALL/grub/themes/ventoy/terminal_box_w.png differ diff --git a/INSTALL/grub/themes/ventoy/theme.txt b/INSTALL/grub/themes/ventoy/theme.txt new file mode 100644 index 0000000..88e8a21 --- /dev/null +++ b/INSTALL/grub/themes/ventoy/theme.txt @@ -0,0 +1,97 @@ + +desktop-image: "background.png" +title-text: " " +title-color: "#ffffff" +message-color: "#f2f2f2" + +terminal-box: "terminal_box_*.png" + ++ boot_menu { + left = 10% + width = 80% + top = 30% + height = 50% + + menu_pixmap_style = "menu_*.png" + + item_color = "#ffffff" + item_height = 30 + + item_spacing = 1 + item_padding = 1 + + selected_item_color= "#f2f2f2" + selected_item_pixmap_style = "select_*.png" + + item_icon_space = 0 + + scrollbar = true + scrollbar_width = 10 + scrollbar_thumb = "slider_*.png" +} + + + ++ progress_bar { + id = "__timeout__" + text = "@TIMEOUT_NOTIFICATION_SHORT@" + + left = 90% + width = 10% + top = 90% + + text_color = "red" + bar_style = "*" + highlight_style = "*" +} + ++ hbox{ + left = 28% + top = 95% + width = 10% + height = 25 + + label {text = "@VTOY_HOTKEY_TIP@" color = "blue" align = "left"} +} + + ++ hbox{ + left = 30% + top = 95%-25 + width = 10% + height = 25 + + label {text = "@VTOY_MEM_DISK@" color = "red" align = "left"} +} + + ++ hbox{ + left = 30% + top = 95%-50 + width = 10% + height = 25 + + label {text = "@VTOY_ISO_RAW@" color = "red" align = "left"} +} + + ++ hbox{ + left = 30%+200 + top = 95%-50 + width = 10% + height = 25 + + label {text = "@VTOY_GRUB2_MODE@" color = "red" align = "left"} +} + ++ hbox{ + left = 30%+200 + top = 95%-25 + width = 10% + height = 25 + + label {text = "@VTOY_WIMBOOT_MODE@" color = "red" align = "left"} +} + ++ hbox{ + left = 90% + top = 55 + width = 10% + height = 25 + + label {text = "@VTOY_ISO_UEFI_DRV@" color = "red" align = "left"} +} diff --git a/INSTALL/grub/x86_64-efi/adler32.mod b/INSTALL/grub/x86_64-efi/adler32.mod new file mode 100644 index 0000000..8df78d1 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/adler32.mod differ diff --git a/INSTALL/grub/x86_64-efi/affs.mod b/INSTALL/grub/x86_64-efi/affs.mod new file mode 100644 index 0000000..5dca7c6 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/affs.mod differ diff --git a/INSTALL/grub/x86_64-efi/afs.mod b/INSTALL/grub/x86_64-efi/afs.mod new file mode 100644 index 0000000..5be6473 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/afs.mod differ diff --git a/INSTALL/grub/x86_64-efi/ahci.mod b/INSTALL/grub/x86_64-efi/ahci.mod new file mode 100644 index 0000000..86b274d Binary files /dev/null and b/INSTALL/grub/x86_64-efi/ahci.mod differ diff --git a/INSTALL/grub/x86_64-efi/aout.mod b/INSTALL/grub/x86_64-efi/aout.mod new file mode 100644 index 0000000..aec5b82 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/aout.mod differ diff --git a/INSTALL/grub/x86_64-efi/appleldr.mod b/INSTALL/grub/x86_64-efi/appleldr.mod new file mode 100644 index 0000000..a4505c3 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/appleldr.mod differ diff --git a/INSTALL/grub/x86_64-efi/archelp.mod b/INSTALL/grub/x86_64-efi/archelp.mod new file mode 100644 index 0000000..62463ee Binary files /dev/null and b/INSTALL/grub/x86_64-efi/archelp.mod differ diff --git a/INSTALL/grub/x86_64-efi/ata.mod b/INSTALL/grub/x86_64-efi/ata.mod new file mode 100644 index 0000000..825e494 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/ata.mod differ diff --git a/INSTALL/grub/x86_64-efi/backtrace.mod b/INSTALL/grub/x86_64-efi/backtrace.mod new file mode 100644 index 0000000..29f9fef Binary files /dev/null and b/INSTALL/grub/x86_64-efi/backtrace.mod differ diff --git a/INSTALL/grub/x86_64-efi/bfs.mod b/INSTALL/grub/x86_64-efi/bfs.mod new file mode 100644 index 0000000..c74d6e1 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/bfs.mod differ diff --git a/INSTALL/grub/x86_64-efi/blscfg.mod b/INSTALL/grub/x86_64-efi/blscfg.mod new file mode 100644 index 0000000..01c5479 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/blscfg.mod differ diff --git a/INSTALL/grub/x86_64-efi/bsd.mod b/INSTALL/grub/x86_64-efi/bsd.mod new file mode 100644 index 0000000..c7f3fe0 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/bsd.mod differ diff --git a/INSTALL/grub/x86_64-efi/bswap_test.mod b/INSTALL/grub/x86_64-efi/bswap_test.mod new file mode 100644 index 0000000..b80415a Binary files /dev/null and b/INSTALL/grub/x86_64-efi/bswap_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/btrfs.mod b/INSTALL/grub/x86_64-efi/btrfs.mod new file mode 100644 index 0000000..afcd8c4 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/btrfs.mod differ diff --git a/INSTALL/grub/x86_64-efi/cbfs.mod b/INSTALL/grub/x86_64-efi/cbfs.mod new file mode 100644 index 0000000..6bfcfa0 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cbfs.mod differ diff --git a/INSTALL/grub/x86_64-efi/cbls.mod b/INSTALL/grub/x86_64-efi/cbls.mod new file mode 100644 index 0000000..325251e Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cbls.mod differ diff --git a/INSTALL/grub/x86_64-efi/cbmemc.mod b/INSTALL/grub/x86_64-efi/cbmemc.mod new file mode 100644 index 0000000..1245aac Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cbmemc.mod differ diff --git a/INSTALL/grub/x86_64-efi/cbtable.mod b/INSTALL/grub/x86_64-efi/cbtable.mod new file mode 100644 index 0000000..f46fe4f Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cbtable.mod differ diff --git a/INSTALL/grub/x86_64-efi/cbtime.mod b/INSTALL/grub/x86_64-efi/cbtime.mod new file mode 100644 index 0000000..f685e5e Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cbtime.mod differ diff --git a/INSTALL/grub/x86_64-efi/cmdline_cat_test.mod b/INSTALL/grub/x86_64-efi/cmdline_cat_test.mod new file mode 100644 index 0000000..57c7bbe Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cmdline_cat_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/cmp.mod b/INSTALL/grub/x86_64-efi/cmp.mod new file mode 100644 index 0000000..f739795 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cmp.mod differ diff --git a/INSTALL/grub/x86_64-efi/cmp_test.mod b/INSTALL/grub/x86_64-efi/cmp_test.mod new file mode 100644 index 0000000..e750bdb Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cmp_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/command.lst b/INSTALL/grub/x86_64-efi/command.lst new file mode 100644 index 0000000..96cba29 --- /dev/null +++ b/INSTALL/grub/x86_64-efi/command.lst @@ -0,0 +1,203 @@ +*acpi: acpi +*all_functional_test: functional_test +*background_image: gfxterm_background +*bls_import: blscfg +*blscfg: blscfg +*cat: cat +*cpuid: cpuid +*crc: hashsum +*cryptomount: cryptodisk +*echo: echo +*extract_syslinux_entries_configfile: syslinuxcfg +*extract_syslinux_entries_source: syslinuxcfg +*file: file +*functional_test: functional_test +*fwconnect: fwload +*fwload: fwload +*gettext: gettext +*hashsum: hashsum +*hdparm: hdparm +*hello: hello +*help: help +*hexdump: hexdump +*inb: iorw +*inl: iorw +*inw: iorw +*keystatus: keystatus +*kfreebsd: bsd +*knetbsd: bsd +*kopenbsd: bsd +*list_env: loadenv +*load_env: loadenv +*loopback: loopback +*ls: ls +*lsacpi: lsacpi +*lspci: lspci +*md5sum: hashsum +*menuentry: normal +*pcidump: pcidump +*probe: probe +*rdmsr: rdmsr +*read_byte: memrw +*read_dword: memrw +*read_word: memrw +*regexp: regexp +*save_env: loadenv +*search: search +*serial: serial +*set_keyboard_layout: setkey +*setkey: setkey +*setpci: setpci +*sha1sum: hashsum +*sha256sum: hashsum +*sha512sum: hashsum +*sleep: sleep +*smbios: smbios +*submenu: normal +*syslinux_configfile: syslinuxcfg +*syslinux_source: syslinuxcfg +*terminfo: terminfo +*test_blockarg: test_blockarg +*testspeed: testspeed +*tr: tr +*trust: pgp +*verify_detached: pgp +*xnu_splash: xnu +*zfskey: zfscrypt +.: configfile +[: test +appleloader: appleldr +authenticate: normal +background_color: gfxterm_background +backtrace: backtrace +badram: mmap +blocklist: blocklist +boot: boot +break: normal +cat: minicmd +cbmemc: cbmemc +chainloader: chain +clear: normal +cmp: cmp +configfile: configfile +continue: normal +coreboot_boottime: cbtime +cutmem: mmap +date: date +distrust: pgp +dump: minicmd +eval: eval +exit: minicmd +export: normal +extract_entries_configfile: configfile +extract_entries_source: configfile +extract_legacy_entries_configfile: legacycfg +extract_legacy_entries_source: legacycfg +fakebios: loadbios +false: true +fix_video: fixvideo +fwsetup: efifwsetup +gptsync: gptsync +halt: halt +help: minicmd +hexdump_random: random +initrd16: linux16 +initrd: linux +initrdefi: linux +keymap: keylayouts +kfreebsd_loadenv: bsd +kfreebsd_module: bsd +kfreebsd_module_elf: bsd +knetbsd_module: bsd +knetbsd_module_elf: bsd +kopenbsd_ramdisk: bsd +legacy_check_password: legacycfg +legacy_configfile: legacycfg +legacy_initrd: legacycfg +legacy_initrd_nounzip: legacycfg +legacy_kernel: legacycfg +legacy_password: legacycfg +legacy_source: legacycfg +linux16: linux16 +linux: linux +linuxefi: linux +list_trusted: pgp +loadbios: loadbios +loadfont: font +lscoreboot: cbls +lsefi: lsefi +lsefimmap: lsefimmap +lsefisystab: lsefisystab +lsfonts: font +lsmmap: lsmmap +lsmod: minicmd +lssal: lssal +macppcbless: macbless +mactelbless: macbless +module2: multiboot2 +module: multiboot +multiboot2: multiboot2 +multiboot: multiboot +nativedisk: nativedisk +net_add_addr: net +net_add_dns: net +net_add_route: net +net_bootp: net +net_del_addr: net +net_del_dns: net +net_del_route: net +net_dhcp: net +net_get_dhcp_option: net +net_ipv6_autoconf: net +net_ls_addr: net +net_ls_cards: net +net_ls_dns: net +net_ls_routes: net +net_nslookup: net +normal: normal +normal_exit: normal +outb: iorw +outl: iorw +outw: iorw +parttool: parttool +password: password +password_pbkdf2: password_pbkdf2 +play: play +read: read +reboot: reboot +return: normal +rmmod: minicmd +search.file: search_fs_file +search.fs_label: search_label +search.fs_uuid: search_fs_uuid +setparams: normal +shift: normal +source: configfile +terminal_input: terminal +terminal_output: terminal +test: test +testload: testload +time: time +true: true +usb: usbtest +videoinfo: videoinfo +videotest: videotest +vt_img_extra_initrd_append: linux +vt_img_extra_initrd_reset: linux +vt_set_boot_opt: linux +vt_unset_boot_opt: linux +write_byte: memrw +write_dword: memrw +write_word: memrw +wrmsr: wrmsr +xnu_devprop_load: xnu +xnu_kernel64: xnu +xnu_kernel: xnu +xnu_kext: xnu +xnu_kextdir: xnu +xnu_mkext: xnu +xnu_ramdisk: xnu +xnu_resume: xnu +xnu_uuid: xnu_uuid +zfs-bootfs: zfsinfo +zfsinfo: zfsinfo diff --git a/INSTALL/grub/x86_64-efi/cpio.mod b/INSTALL/grub/x86_64-efi/cpio.mod new file mode 100644 index 0000000..c5d64b1 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cpio.mod differ diff --git a/INSTALL/grub/x86_64-efi/cpio_be.mod b/INSTALL/grub/x86_64-efi/cpio_be.mod new file mode 100644 index 0000000..e81b625 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cpio_be.mod differ diff --git a/INSTALL/grub/x86_64-efi/cpuid.mod b/INSTALL/grub/x86_64-efi/cpuid.mod new file mode 100644 index 0000000..03e9389 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cpuid.mod differ diff --git a/INSTALL/grub/x86_64-efi/crc64.mod b/INSTALL/grub/x86_64-efi/crc64.mod new file mode 100644 index 0000000..ec5e9c0 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/crc64.mod differ diff --git a/INSTALL/grub/x86_64-efi/crypto.lst b/INSTALL/grub/x86_64-efi/crypto.lst new file mode 100644 index 0000000..77d9efc --- /dev/null +++ b/INSTALL/grub/x86_64-efi/crypto.lst @@ -0,0 +1,45 @@ +RIJNDAEL: gcry_rijndael +RIJNDAEL192: gcry_rijndael +RIJNDAEL256: gcry_rijndael +AES128: gcry_rijndael +AES-128: gcry_rijndael +AES-192: gcry_rijndael +AES-256: gcry_rijndael +ADLER32: adler32 +CRC64: crc64 +ARCFOUR: gcry_arcfour +BLOWFISH: gcry_blowfish +CAMELLIA128: gcry_camellia +CAMELLIA192: gcry_camellia +CAMELLIA256: gcry_camellia +CAST5: gcry_cast5 +CRC32: gcry_crc +CRC32RFC1510: gcry_crc +CRC24RFC2440: gcry_crc +DES: gcry_des +3DES: gcry_des +DSA: gcry_dsa +IDEA: gcry_idea +MD4: gcry_md4 +MD5: gcry_md5 +RFC2268_40: gcry_rfc2268 +AES: gcry_rijndael +AES192: gcry_rijndael +AES256: gcry_rijndael +RIPEMD160: gcry_rmd160 +RSA: gcry_rsa +SEED: gcry_seed +SERPENT128: gcry_serpent +SERPENT192: gcry_serpent +SERPENT256: gcry_serpent +SHA1: gcry_sha1 +SHA224: gcry_sha256 +SHA256: gcry_sha256 +SHA512: gcry_sha512 +SHA384: gcry_sha512 +TIGER192: gcry_tiger +TIGER: gcry_tiger +TIGER2: gcry_tiger +TWOFISH: gcry_twofish +TWOFISH128: gcry_twofish +WHIRLPOOL: gcry_whirlpool diff --git a/INSTALL/grub/x86_64-efi/cryptodisk.mod b/INSTALL/grub/x86_64-efi/cryptodisk.mod new file mode 100644 index 0000000..c56ebf5 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cryptodisk.mod differ diff --git a/INSTALL/grub/x86_64-efi/cs5536.mod b/INSTALL/grub/x86_64-efi/cs5536.mod new file mode 100644 index 0000000..b52ab08 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cs5536.mod differ diff --git a/INSTALL/grub/x86_64-efi/ctz_test.mod b/INSTALL/grub/x86_64-efi/ctz_test.mod new file mode 100644 index 0000000..e602fd1 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/ctz_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/date.mod b/INSTALL/grub/x86_64-efi/date.mod new file mode 100644 index 0000000..5fec5bb Binary files /dev/null and b/INSTALL/grub/x86_64-efi/date.mod differ diff --git a/INSTALL/grub/x86_64-efi/datehook.mod b/INSTALL/grub/x86_64-efi/datehook.mod new file mode 100644 index 0000000..f398c92 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/datehook.mod differ diff --git a/INSTALL/grub/x86_64-efi/disk.mod b/INSTALL/grub/x86_64-efi/disk.mod new file mode 100644 index 0000000..aab241b Binary files /dev/null and b/INSTALL/grub/x86_64-efi/disk.mod differ diff --git a/INSTALL/grub/x86_64-efi/div.mod b/INSTALL/grub/x86_64-efi/div.mod new file mode 100644 index 0000000..374129f Binary files /dev/null and b/INSTALL/grub/x86_64-efi/div.mod differ diff --git a/INSTALL/grub/x86_64-efi/div_test.mod b/INSTALL/grub/x86_64-efi/div_test.mod new file mode 100644 index 0000000..ede46a0 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/div_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/dm_nv.mod b/INSTALL/grub/x86_64-efi/dm_nv.mod new file mode 100644 index 0000000..19a4608 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/dm_nv.mod differ diff --git a/INSTALL/grub/x86_64-efi/efinet.mod b/INSTALL/grub/x86_64-efi/efinet.mod new file mode 100644 index 0000000..6cef7b1 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/efinet.mod differ diff --git a/INSTALL/grub/x86_64-efi/ehci.mod b/INSTALL/grub/x86_64-efi/ehci.mod new file mode 100644 index 0000000..841296f Binary files /dev/null and b/INSTALL/grub/x86_64-efi/ehci.mod differ diff --git a/INSTALL/grub/x86_64-efi/elf.mod b/INSTALL/grub/x86_64-efi/elf.mod new file mode 100644 index 0000000..d4811f8 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/elf.mod differ diff --git a/INSTALL/grub/x86_64-efi/eval.mod b/INSTALL/grub/x86_64-efi/eval.mod new file mode 100644 index 0000000..4c401f8 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/eval.mod differ diff --git a/INSTALL/grub/x86_64-efi/exfctest.mod b/INSTALL/grub/x86_64-efi/exfctest.mod new file mode 100644 index 0000000..fc8d158 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/exfctest.mod differ diff --git a/INSTALL/grub/x86_64-efi/f2fs.mod b/INSTALL/grub/x86_64-efi/f2fs.mod new file mode 100644 index 0000000..aec0954 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/f2fs.mod differ diff --git a/INSTALL/grub/x86_64-efi/fdt.lst b/INSTALL/grub/x86_64-efi/fdt.lst new file mode 100644 index 0000000..e69de29 diff --git a/INSTALL/grub/x86_64-efi/fixvideo.mod b/INSTALL/grub/x86_64-efi/fixvideo.mod new file mode 100644 index 0000000..625c52e Binary files /dev/null and b/INSTALL/grub/x86_64-efi/fixvideo.mod differ diff --git a/INSTALL/grub/x86_64-efi/fs.lst b/INSTALL/grub/x86_64-efi/fs.lst new file mode 100644 index 0000000..0acd240 --- /dev/null +++ b/INSTALL/grub/x86_64-efi/fs.lst @@ -0,0 +1,37 @@ +affs +afs +bfs +btrfs +cbfs +cpio +cpio_be +exfat +ext2 +f2fs +fat +hfs +hfsplus +iso9660 +jfs +minix +minix2 +minix2_be +minix3 +minix3_be +minix_be +newc +nilfs2 +ntfs +odc +procfs +reiserfs +romfs +sfs +squash4 +tar +udf +ufs1 +ufs1_be +ufs2 +xfs +zfs diff --git a/INSTALL/grub/x86_64-efi/functional_test.mod b/INSTALL/grub/x86_64-efi/functional_test.mod new file mode 100644 index 0000000..0b2d146 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/functional_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_arcfour.mod b/INSTALL/grub/x86_64-efi/gcry_arcfour.mod new file mode 100644 index 0000000..97568f7 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_arcfour.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_blowfish.mod b/INSTALL/grub/x86_64-efi/gcry_blowfish.mod new file mode 100644 index 0000000..5d962f4 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_blowfish.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_camellia.mod b/INSTALL/grub/x86_64-efi/gcry_camellia.mod new file mode 100644 index 0000000..b44663b Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_camellia.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_cast5.mod b/INSTALL/grub/x86_64-efi/gcry_cast5.mod new file mode 100644 index 0000000..8a264bf Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_cast5.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_crc.mod b/INSTALL/grub/x86_64-efi/gcry_crc.mod new file mode 100644 index 0000000..7f71a65 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_crc.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_des.mod b/INSTALL/grub/x86_64-efi/gcry_des.mod new file mode 100644 index 0000000..919d2c3 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_des.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_dsa.mod b/INSTALL/grub/x86_64-efi/gcry_dsa.mod new file mode 100644 index 0000000..1413441 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_dsa.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_idea.mod b/INSTALL/grub/x86_64-efi/gcry_idea.mod new file mode 100644 index 0000000..b304320 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_idea.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_md4.mod b/INSTALL/grub/x86_64-efi/gcry_md4.mod new file mode 100644 index 0000000..b4e2e60 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_md4.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_rfc2268.mod b/INSTALL/grub/x86_64-efi/gcry_rfc2268.mod new file mode 100644 index 0000000..fed34c0 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_rfc2268.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_rijndael.mod b/INSTALL/grub/x86_64-efi/gcry_rijndael.mod new file mode 100644 index 0000000..29ac30e Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_rijndael.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_rmd160.mod b/INSTALL/grub/x86_64-efi/gcry_rmd160.mod new file mode 100644 index 0000000..b8c35dc Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_rmd160.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_rsa.mod b/INSTALL/grub/x86_64-efi/gcry_rsa.mod new file mode 100644 index 0000000..e3a5899 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_rsa.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_seed.mod b/INSTALL/grub/x86_64-efi/gcry_seed.mod new file mode 100644 index 0000000..1fa8178 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_seed.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_serpent.mod b/INSTALL/grub/x86_64-efi/gcry_serpent.mod new file mode 100644 index 0000000..fd12f88 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_serpent.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_sha1.mod b/INSTALL/grub/x86_64-efi/gcry_sha1.mod new file mode 100644 index 0000000..9c6a843 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_sha1.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_sha256.mod b/INSTALL/grub/x86_64-efi/gcry_sha256.mod new file mode 100644 index 0000000..973d765 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_sha256.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_tiger.mod b/INSTALL/grub/x86_64-efi/gcry_tiger.mod new file mode 100644 index 0000000..686e70b Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_tiger.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_twofish.mod b/INSTALL/grub/x86_64-efi/gcry_twofish.mod new file mode 100644 index 0000000..013c91f Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_twofish.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_whirlpool.mod b/INSTALL/grub/x86_64-efi/gcry_whirlpool.mod new file mode 100644 index 0000000..e10c785 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_whirlpool.mod differ diff --git a/INSTALL/grub/x86_64-efi/geli.mod b/INSTALL/grub/x86_64-efi/geli.mod new file mode 100644 index 0000000..c5db646 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/geli.mod differ diff --git a/INSTALL/grub/x86_64-efi/gptsync.mod b/INSTALL/grub/x86_64-efi/gptsync.mod new file mode 100644 index 0000000..86ecbbf Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gptsync.mod differ diff --git a/INSTALL/grub/x86_64-efi/hdparm.mod b/INSTALL/grub/x86_64-efi/hdparm.mod new file mode 100644 index 0000000..bd19f3f Binary files /dev/null and b/INSTALL/grub/x86_64-efi/hdparm.mod differ diff --git a/INSTALL/grub/x86_64-efi/hello.mod b/INSTALL/grub/x86_64-efi/hello.mod new file mode 100644 index 0000000..5692186 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/hello.mod differ diff --git a/INSTALL/grub/x86_64-efi/help.mod b/INSTALL/grub/x86_64-efi/help.mod new file mode 100644 index 0000000..9c27d63 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/help.mod differ diff --git a/INSTALL/grub/x86_64-efi/hexdump.mod b/INSTALL/grub/x86_64-efi/hexdump.mod new file mode 100644 index 0000000..75a176d Binary files /dev/null and b/INSTALL/grub/x86_64-efi/hexdump.mod differ diff --git a/INSTALL/grub/x86_64-efi/hfs.mod b/INSTALL/grub/x86_64-efi/hfs.mod new file mode 100644 index 0000000..efab966 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/hfs.mod differ diff --git a/INSTALL/grub/x86_64-efi/hfspluscomp.mod b/INSTALL/grub/x86_64-efi/hfspluscomp.mod new file mode 100644 index 0000000..e206005 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/hfspluscomp.mod differ diff --git a/INSTALL/grub/x86_64-efi/iorw.mod b/INSTALL/grub/x86_64-efi/iorw.mod new file mode 100644 index 0000000..707b405 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/iorw.mod differ diff --git a/INSTALL/grub/x86_64-efi/jfs.mod b/INSTALL/grub/x86_64-efi/jfs.mod new file mode 100644 index 0000000..4f99b2c Binary files /dev/null and b/INSTALL/grub/x86_64-efi/jfs.mod differ diff --git a/INSTALL/grub/x86_64-efi/keylayouts.mod b/INSTALL/grub/x86_64-efi/keylayouts.mod new file mode 100644 index 0000000..2c2f9e7 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/keylayouts.mod differ diff --git a/INSTALL/grub/x86_64-efi/keystatus.mod b/INSTALL/grub/x86_64-efi/keystatus.mod new file mode 100644 index 0000000..3cd5d7c Binary files /dev/null and b/INSTALL/grub/x86_64-efi/keystatus.mod differ diff --git a/INSTALL/grub/x86_64-efi/ldm.mod b/INSTALL/grub/x86_64-efi/ldm.mod new file mode 100644 index 0000000..baa88e7 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/ldm.mod differ diff --git a/INSTALL/grub/x86_64-efi/legacy_password_test.mod b/INSTALL/grub/x86_64-efi/legacy_password_test.mod new file mode 100644 index 0000000..225082a Binary files /dev/null and b/INSTALL/grub/x86_64-efi/legacy_password_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/legacycfg.mod b/INSTALL/grub/x86_64-efi/legacycfg.mod new file mode 100644 index 0000000..91afa23 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/legacycfg.mod differ diff --git a/INSTALL/grub/x86_64-efi/linux16.mod b/INSTALL/grub/x86_64-efi/linux16.mod new file mode 100644 index 0000000..d36f75f Binary files /dev/null and b/INSTALL/grub/x86_64-efi/linux16.mod differ diff --git a/INSTALL/grub/x86_64-efi/loadbios.mod b/INSTALL/grub/x86_64-efi/loadbios.mod new file mode 100644 index 0000000..b4e1d1f Binary files /dev/null and b/INSTALL/grub/x86_64-efi/loadbios.mod differ diff --git a/INSTALL/grub/x86_64-efi/loadenv.mod b/INSTALL/grub/x86_64-efi/loadenv.mod new file mode 100644 index 0000000..8ab183a Binary files /dev/null and b/INSTALL/grub/x86_64-efi/loadenv.mod differ diff --git a/INSTALL/grub/x86_64-efi/lsacpi.mod b/INSTALL/grub/x86_64-efi/lsacpi.mod new file mode 100644 index 0000000..5bda6c1 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/lsacpi.mod differ diff --git a/INSTALL/grub/x86_64-efi/lsefi.mod b/INSTALL/grub/x86_64-efi/lsefi.mod new file mode 100644 index 0000000..23e7674 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/lsefi.mod differ diff --git a/INSTALL/grub/x86_64-efi/lsefimmap.mod b/INSTALL/grub/x86_64-efi/lsefimmap.mod new file mode 100644 index 0000000..3cef1a2 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/lsefimmap.mod differ diff --git a/INSTALL/grub/x86_64-efi/lsefisystab.mod b/INSTALL/grub/x86_64-efi/lsefisystab.mod new file mode 100644 index 0000000..ebc59df Binary files /dev/null and b/INSTALL/grub/x86_64-efi/lsefisystab.mod differ diff --git a/INSTALL/grub/x86_64-efi/lsmmap.mod b/INSTALL/grub/x86_64-efi/lsmmap.mod new file mode 100644 index 0000000..b02fe98 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/lsmmap.mod differ diff --git a/INSTALL/grub/x86_64-efi/lspci.mod b/INSTALL/grub/x86_64-efi/lspci.mod new file mode 100644 index 0000000..39ef1be Binary files /dev/null and b/INSTALL/grub/x86_64-efi/lspci.mod differ diff --git a/INSTALL/grub/x86_64-efi/lssal.mod b/INSTALL/grub/x86_64-efi/lssal.mod new file mode 100644 index 0000000..7cfb71c Binary files /dev/null and b/INSTALL/grub/x86_64-efi/lssal.mod differ diff --git a/INSTALL/grub/x86_64-efi/luks.mod b/INSTALL/grub/x86_64-efi/luks.mod new file mode 100644 index 0000000..e0d290f Binary files /dev/null and b/INSTALL/grub/x86_64-efi/luks.mod differ diff --git a/INSTALL/grub/x86_64-efi/lvm.mod b/INSTALL/grub/x86_64-efi/lvm.mod new file mode 100644 index 0000000..68a8152 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/lvm.mod differ diff --git a/INSTALL/grub/x86_64-efi/macbless.mod b/INSTALL/grub/x86_64-efi/macbless.mod new file mode 100644 index 0000000..4631c36 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/macbless.mod differ diff --git a/INSTALL/grub/x86_64-efi/macho.mod b/INSTALL/grub/x86_64-efi/macho.mod new file mode 100644 index 0000000..b174dcf Binary files /dev/null and b/INSTALL/grub/x86_64-efi/macho.mod differ diff --git a/INSTALL/grub/x86_64-efi/mdraid09.mod b/INSTALL/grub/x86_64-efi/mdraid09.mod new file mode 100644 index 0000000..b676846 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/mdraid09.mod differ diff --git a/INSTALL/grub/x86_64-efi/mdraid09_be.mod b/INSTALL/grub/x86_64-efi/mdraid09_be.mod new file mode 100644 index 0000000..c47e089 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/mdraid09_be.mod differ diff --git a/INSTALL/grub/x86_64-efi/mdraid1x.mod b/INSTALL/grub/x86_64-efi/mdraid1x.mod new file mode 100644 index 0000000..8cc6418 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/mdraid1x.mod differ diff --git a/INSTALL/grub/x86_64-efi/memdisk.mod b/INSTALL/grub/x86_64-efi/memdisk.mod new file mode 100644 index 0000000..41c1270 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/memdisk.mod differ diff --git a/INSTALL/grub/x86_64-efi/memrw.mod b/INSTALL/grub/x86_64-efi/memrw.mod new file mode 100644 index 0000000..8d9893e Binary files /dev/null and b/INSTALL/grub/x86_64-efi/memrw.mod differ diff --git a/INSTALL/grub/x86_64-efi/minix.mod b/INSTALL/grub/x86_64-efi/minix.mod new file mode 100644 index 0000000..bf5442d Binary files /dev/null and b/INSTALL/grub/x86_64-efi/minix.mod differ diff --git a/INSTALL/grub/x86_64-efi/minix2.mod b/INSTALL/grub/x86_64-efi/minix2.mod new file mode 100644 index 0000000..6a7c81d Binary files /dev/null and b/INSTALL/grub/x86_64-efi/minix2.mod differ diff --git a/INSTALL/grub/x86_64-efi/minix2_be.mod b/INSTALL/grub/x86_64-efi/minix2_be.mod new file mode 100644 index 0000000..baf2187 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/minix2_be.mod differ diff --git a/INSTALL/grub/x86_64-efi/minix3.mod b/INSTALL/grub/x86_64-efi/minix3.mod new file mode 100644 index 0000000..2e601d7 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/minix3.mod differ diff --git a/INSTALL/grub/x86_64-efi/minix3_be.mod b/INSTALL/grub/x86_64-efi/minix3_be.mod new file mode 100644 index 0000000..5d052b6 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/minix3_be.mod differ diff --git a/INSTALL/grub/x86_64-efi/minix_be.mod b/INSTALL/grub/x86_64-efi/minix_be.mod new file mode 100644 index 0000000..0bf16a3 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/minix_be.mod differ diff --git a/INSTALL/grub/x86_64-efi/moddep.lst b/INSTALL/grub/x86_64-efi/moddep.lst new file mode 100644 index 0000000..afdc0e0 --- /dev/null +++ b/INSTALL/grub/x86_64-efi/moddep.lst @@ -0,0 +1,270 @@ +videotest: font video gfxmenu +odc: archelp +loopback: extcmd +setkey: extcmd +macho: +gcry_des: crypto +memrw: extcmd +terminfo: extcmd +f2fs: fshelp +part_gpt: +romfs: fshelp +read: +lsefimmap: +aout: +gcry_arcfour: crypto +tftp: net priority_queue +newc: archelp +minix2_be: +elf: +videotest_checksum: font functional_test video_fb +password_pbkdf2: crypto gcry_sha512 pbkdf2 normal +gcry_seed: crypto +pcidump: extcmd +bsd: elf serial crypto gcry_md5 verifiers extcmd aout video boot cpuid relocator mmap +sfs: fshelp +reiserfs: fshelp +part_sunpc: +zstd: +gfxmenu: video_colors trig bitmap_scale gfxterm font normal video bitmap +backtrace: +jfs: +help: extcmd normal +configfile: normal +cbls: cbtable +gfxterm_menu: font functional_test procfs normal video_fb +gcry_idea: crypto +tr: extcmd +shift_test: functional_test +ohci: cs5536 usb boot +afs: fshelp +spkmodem: terminfo +usb_keyboard: keylayouts usb +xzio: crypto +syslinuxcfg: extcmd normal +search_fs_file: +wrmsr: +usbms: scsi usb +test_blockarg: extcmd normal +true: +affs: fshelp +iso9660: fshelp +smbios: extcmd +exfat: fshelp +setjmp_test: setjmp functional_test +gfxterm: font video +efinet: net +disk: +appleldr: boot +xfs: fshelp +testspeed: extcmd normal +cpio_be: archelp +functional_test: btrfs extcmd video video_fb +bswap_test: functional_test +sleep: extcmd normal +memdisk: +gcry_rijndael: crypto +mdraid09_be: diskfilter +gettext: +gcry_sha1: crypto +hfspluscomp: gzio hfsplus +cmp: +random: hexdump +offsetio: +file: elf macho extcmd offsetio +usbserial_usbdebug: serial usb usbserial_common +video_colors: +morse: +hashsum: crypto extcmd normal +usb: +halt: acpi +gfxterm_background: video_colors bitmap_scale gfxterm extcmd video bitmap +search_fs_uuid: +gcry_dsa: pgp mpi +keystatus: extcmd +linux: ventoy verifiers video boot relocator mmap +geli: cryptodisk crypto gcry_sha512 pbkdf2 gcry_sha256 +cmdline_cat_test: font functional_test normal procfs video_fb +rdmsr: extcmd +part_sun: +cbtable: +pbkdf2_test: functional_test pbkdf2 gcry_sha1 +video_bochs: video video_fb +verifiers: +bufio: +usbserial_ftdi: serial usb usbserial_common +legacy_password_test: functional_test legacycfg +cpuid: extcmd +blscfg: extcmd normal +hdparm: extcmd hexdump +bfs: fshelp +gcry_blowfish: crypto +test: +nilfs2: fshelp +gcry_rsa: pgp mpi +cryptodisk: crypto extcmd procfs +nativedisk: +minicmd: +signature_test: functional_test procfs +ata: scsi +udf: fshelp +gzio: gcry_crc +xnu_uuid: gcry_md5 +uhci: usb +pata: ata +mul_test: functional_test +adler32: crypto +terminal: +shim_lock: verifiers +div: +ehci: cs5536 usb boot +crypto: +part_bsd: part_msdos +cs5536: +ventoy: ext2 fshelp elf btrfs crypto font gcry_md5 exfat udf datetime div extcmd normal video gcry_sha1 mmap iso9660 +gcry_sha512: crypto +password: crypto normal +fshelp: +sleep_test: functional_test datetime +iorw: extcmd +xnu: macho bitmap_scale random verifiers extcmd boot video bitmap relocator mmap +mmap: +exfctest: functional_test +zfsinfo: zfs +ldm: part_gpt diskfilter part_msdos +eval: normal +part_dvh: +lssal: +blocklist: +ext2: fshelp +net: priority_queue bufio datetime boot +part_acorn: +videoinfo: video +btrfs: zstd lzopio raid6rec gzio +lsmmap: mmap +strtoull_test: functional_test +bitmap: +ntfs: fshelp +multiboot: net linux video boot relocator mmap +tpm: verifiers +gcry_crc: crypto +png: bufio bitmap +jpeg: bufio bitmap +macbless: disk +div_test: functional_test div +regexp: extcmd normal +parttool: normal +usbserial_pl2303: serial usb usbserial_common +cpio: archelp +gcry_rmd160: crypto +fat: fshelp +ufs1_be: +archelp: +http: net +zfs: gzio +raid6rec: diskfilter +lsefisystab: +minix2: +lsacpi: extcmd acpi +datehook: datetime normal +loadenv: disk extcmd +bitmap_scale: bitmap +probe: extcmd +minix3: +tar: archelp +loadbios: +hfs: fshelp +procfs: archelp +boot: +keylayouts: +progress: normal +kernel: +usbtest: usb +relocator: mmap +acpi: extcmd mmap +tga: bufio bitmap +reboot: +fwload: extcmd +serial: extcmd terminfo +zfscrypt: crypto pbkdf2 extcmd zfs gcry_sha1 gcry_rijndael +efi_uga: video video_fb +dm_nv: diskfilter +cmp_test: functional_test +luks: cryptodisk crypto pbkdf2 +font: bufio video +raid5rec: diskfilter +crc64: crypto +datetime: +efifwsetup: +ctz_test: functional_test +video: +cbmemc: cbtable normal terminfo +hfsplus: fshelp +gcry_cast5: crypto +extcmd: +squash4: fshelp zstd lzopio zfs xzio gzio +part_plan: +minix_be: +gcry_whirlpool: crypto +gcry_tiger: crypto +fixvideo: +search: search_fs_uuid search_fs_file extcmd search_label +lspci: extcmd +cbtime: cbtable +video_fb: +minix3_be: +trig: +msdospart: disk parttool +priority_queue: +gcry_twofish: crypto +part_dfly: +xnu_uuid_test: functional_test +diskfilter: +testload: +part_apple: +hexdump: extcmd +date: datetime normal +pbkdf2: crypto +gcry_sha256: crypto +ls: extcmd normal +usbserial_common: serial usb +ntfscomp: ntfs +mouse: +lzopio: crypto +video_cirrus: video video_fb +hello: extcmd +scsi: +linux16: linux boot video relocator mmap +cat: extcmd +ahci: ata boot +pgp: crypto verifiers extcmd mpi gcry_sha1 +normal: terminal crypto verifiers bufio extcmd boot gettext +ufs1: +mdraid09: diskfilter +lvm: diskfilter +chain: net efinet boot +cbfs: archelp +ufs2: +time: +setpci: extcmd +gptsync: disk +search_label: +setjmp: +multiboot2: linux net video boot relocator acpi mmap +gcry_rfc2268: crypto +mdraid1x: diskfilter +mpi: crypto +legacycfg: crypto password gcry_md5 normal +play: +part_amiga: +efi_gop: video video_fb +minix: +echo: extcmd +lsefi: +gcry_serpent: crypto +gcry_md4: crypto +gcry_md5: crypto +part_msdos: +gcry_camellia: crypto +at_keyboard: keylayouts boot +all_video: efi_gop efi_uga video_bochs video_cirrus diff --git a/INSTALL/grub/x86_64-efi/morse.mod b/INSTALL/grub/x86_64-efi/morse.mod new file mode 100644 index 0000000..123c9f4 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/morse.mod differ diff --git a/INSTALL/grub/x86_64-efi/mpi.mod b/INSTALL/grub/x86_64-efi/mpi.mod new file mode 100644 index 0000000..5468955 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/mpi.mod differ diff --git a/INSTALL/grub/x86_64-efi/msdospart.mod b/INSTALL/grub/x86_64-efi/msdospart.mod new file mode 100644 index 0000000..96e3e8e Binary files /dev/null and b/INSTALL/grub/x86_64-efi/msdospart.mod differ diff --git a/INSTALL/grub/x86_64-efi/mul_test.mod b/INSTALL/grub/x86_64-efi/mul_test.mod new file mode 100644 index 0000000..4a37424 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/mul_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/multiboot.mod b/INSTALL/grub/x86_64-efi/multiboot.mod new file mode 100644 index 0000000..4fc337b Binary files /dev/null and b/INSTALL/grub/x86_64-efi/multiboot.mod differ diff --git a/INSTALL/grub/x86_64-efi/multiboot2.mod b/INSTALL/grub/x86_64-efi/multiboot2.mod new file mode 100644 index 0000000..eec62fd Binary files /dev/null and b/INSTALL/grub/x86_64-efi/multiboot2.mod differ diff --git a/INSTALL/grub/x86_64-efi/nativedisk.mod b/INSTALL/grub/x86_64-efi/nativedisk.mod new file mode 100644 index 0000000..41e87c2 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/nativedisk.mod differ diff --git a/INSTALL/grub/x86_64-efi/nilfs2.mod b/INSTALL/grub/x86_64-efi/nilfs2.mod new file mode 100644 index 0000000..ce329fc Binary files /dev/null and b/INSTALL/grub/x86_64-efi/nilfs2.mod differ diff --git a/INSTALL/grub/x86_64-efi/normal.mod b/INSTALL/grub/x86_64-efi/normal.mod new file mode 100644 index 0000000..3c91f88 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/normal.mod differ diff --git a/INSTALL/grub/x86_64-efi/ntfscomp.mod b/INSTALL/grub/x86_64-efi/ntfscomp.mod new file mode 100644 index 0000000..9f35f83 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/ntfscomp.mod differ diff --git a/INSTALL/grub/x86_64-efi/odc.mod b/INSTALL/grub/x86_64-efi/odc.mod new file mode 100644 index 0000000..1ae0790 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/odc.mod differ diff --git a/INSTALL/grub/x86_64-efi/offsetio.mod b/INSTALL/grub/x86_64-efi/offsetio.mod new file mode 100644 index 0000000..15c8c22 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/offsetio.mod differ diff --git a/INSTALL/grub/x86_64-efi/ohci.mod b/INSTALL/grub/x86_64-efi/ohci.mod new file mode 100644 index 0000000..de29f2b Binary files /dev/null and b/INSTALL/grub/x86_64-efi/ohci.mod differ diff --git a/INSTALL/grub/x86_64-efi/part_acorn.mod b/INSTALL/grub/x86_64-efi/part_acorn.mod new file mode 100644 index 0000000..323854a Binary files /dev/null and b/INSTALL/grub/x86_64-efi/part_acorn.mod differ diff --git a/INSTALL/grub/x86_64-efi/part_amiga.mod b/INSTALL/grub/x86_64-efi/part_amiga.mod new file mode 100644 index 0000000..5bf5667 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/part_amiga.mod differ diff --git a/INSTALL/grub/x86_64-efi/part_bsd.mod b/INSTALL/grub/x86_64-efi/part_bsd.mod new file mode 100644 index 0000000..9123c90 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/part_bsd.mod differ diff --git a/INSTALL/grub/x86_64-efi/part_dfly.mod b/INSTALL/grub/x86_64-efi/part_dfly.mod new file mode 100644 index 0000000..cf7c46e Binary files /dev/null and b/INSTALL/grub/x86_64-efi/part_dfly.mod differ diff --git a/INSTALL/grub/x86_64-efi/part_dvh.mod b/INSTALL/grub/x86_64-efi/part_dvh.mod new file mode 100644 index 0000000..37acae5 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/part_dvh.mod differ diff --git a/INSTALL/grub/x86_64-efi/part_plan.mod b/INSTALL/grub/x86_64-efi/part_plan.mod new file mode 100644 index 0000000..8825a81 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/part_plan.mod differ diff --git a/INSTALL/grub/x86_64-efi/part_sun.mod b/INSTALL/grub/x86_64-efi/part_sun.mod new file mode 100644 index 0000000..3fd865f Binary files /dev/null and b/INSTALL/grub/x86_64-efi/part_sun.mod differ diff --git a/INSTALL/grub/x86_64-efi/part_sunpc.mod b/INSTALL/grub/x86_64-efi/part_sunpc.mod new file mode 100644 index 0000000..576a0fe Binary files /dev/null and b/INSTALL/grub/x86_64-efi/part_sunpc.mod differ diff --git a/INSTALL/grub/x86_64-efi/partmap.lst b/INSTALL/grub/x86_64-efi/partmap.lst new file mode 100644 index 0000000..761233a --- /dev/null +++ b/INSTALL/grub/x86_64-efi/partmap.lst @@ -0,0 +1,11 @@ +part_acorn +part_amiga +part_apple +part_bsd +part_dfly +part_dvh +part_gpt +part_msdos +part_plan +part_sun +part_sunpc diff --git a/INSTALL/grub/x86_64-efi/parttool.lst b/INSTALL/grub/x86_64-efi/parttool.lst new file mode 100644 index 0000000..68b4b5c --- /dev/null +++ b/INSTALL/grub/x86_64-efi/parttool.lst @@ -0,0 +1 @@ +msdos: msdospart diff --git a/INSTALL/grub/x86_64-efi/parttool.mod b/INSTALL/grub/x86_64-efi/parttool.mod new file mode 100644 index 0000000..fd631c0 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/parttool.mod differ diff --git a/INSTALL/grub/x86_64-efi/password.mod b/INSTALL/grub/x86_64-efi/password.mod new file mode 100644 index 0000000..a2dd92d Binary files /dev/null and b/INSTALL/grub/x86_64-efi/password.mod differ diff --git a/INSTALL/grub/x86_64-efi/pata.mod b/INSTALL/grub/x86_64-efi/pata.mod new file mode 100644 index 0000000..d61ef8d Binary files /dev/null and b/INSTALL/grub/x86_64-efi/pata.mod differ diff --git a/INSTALL/grub/x86_64-efi/pbkdf2_test.mod b/INSTALL/grub/x86_64-efi/pbkdf2_test.mod new file mode 100644 index 0000000..80c9e52 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/pbkdf2_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/pcidump.mod b/INSTALL/grub/x86_64-efi/pcidump.mod new file mode 100644 index 0000000..1cecc62 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/pcidump.mod differ diff --git a/INSTALL/grub/x86_64-efi/pgp.mod b/INSTALL/grub/x86_64-efi/pgp.mod new file mode 100644 index 0000000..994a868 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/pgp.mod differ diff --git a/INSTALL/grub/x86_64-efi/play.mod b/INSTALL/grub/x86_64-efi/play.mod new file mode 100644 index 0000000..e101c82 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/play.mod differ diff --git a/INSTALL/grub/x86_64-efi/probe.mod b/INSTALL/grub/x86_64-efi/probe.mod new file mode 100644 index 0000000..af84602 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/probe.mod differ diff --git a/INSTALL/grub/x86_64-efi/procfs.mod b/INSTALL/grub/x86_64-efi/procfs.mod new file mode 100644 index 0000000..aad83d3 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/procfs.mod differ diff --git a/INSTALL/grub/x86_64-efi/progress.mod b/INSTALL/grub/x86_64-efi/progress.mod new file mode 100644 index 0000000..de09125 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/progress.mod differ diff --git a/INSTALL/grub/x86_64-efi/raid5rec.mod b/INSTALL/grub/x86_64-efi/raid5rec.mod new file mode 100644 index 0000000..b4786b2 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/raid5rec.mod differ diff --git a/INSTALL/grub/x86_64-efi/raid6rec.mod b/INSTALL/grub/x86_64-efi/raid6rec.mod new file mode 100644 index 0000000..bfd0d1b Binary files /dev/null and b/INSTALL/grub/x86_64-efi/raid6rec.mod differ diff --git a/INSTALL/grub/x86_64-efi/random.mod b/INSTALL/grub/x86_64-efi/random.mod new file mode 100644 index 0000000..83a6c80 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/random.mod differ diff --git a/INSTALL/grub/x86_64-efi/rdmsr.mod b/INSTALL/grub/x86_64-efi/rdmsr.mod new file mode 100644 index 0000000..9bf3269 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/rdmsr.mod differ diff --git a/INSTALL/grub/x86_64-efi/reiserfs.mod b/INSTALL/grub/x86_64-efi/reiserfs.mod new file mode 100644 index 0000000..1b98ff6 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/reiserfs.mod differ diff --git a/INSTALL/grub/x86_64-efi/romfs.mod b/INSTALL/grub/x86_64-efi/romfs.mod new file mode 100644 index 0000000..b295143 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/romfs.mod differ diff --git a/INSTALL/grub/x86_64-efi/scsi.mod b/INSTALL/grub/x86_64-efi/scsi.mod new file mode 100644 index 0000000..a5e5e85 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/scsi.mod differ diff --git a/INSTALL/grub/x86_64-efi/search_fs_file.mod b/INSTALL/grub/x86_64-efi/search_fs_file.mod new file mode 100644 index 0000000..082d676 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/search_fs_file.mod differ diff --git a/INSTALL/grub/x86_64-efi/search_fs_uuid.mod b/INSTALL/grub/x86_64-efi/search_fs_uuid.mod new file mode 100644 index 0000000..4f49d86 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/search_fs_uuid.mod differ diff --git a/INSTALL/grub/x86_64-efi/search_label.mod b/INSTALL/grub/x86_64-efi/search_label.mod new file mode 100644 index 0000000..2f93d11 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/search_label.mod differ diff --git a/INSTALL/grub/x86_64-efi/setjmp.mod b/INSTALL/grub/x86_64-efi/setjmp.mod new file mode 100644 index 0000000..a0b4e57 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/setjmp.mod differ diff --git a/INSTALL/grub/x86_64-efi/setjmp_test.mod b/INSTALL/grub/x86_64-efi/setjmp_test.mod new file mode 100644 index 0000000..291d987 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/setjmp_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/setpci.mod b/INSTALL/grub/x86_64-efi/setpci.mod new file mode 100644 index 0000000..908a3ad Binary files /dev/null and b/INSTALL/grub/x86_64-efi/setpci.mod differ diff --git a/INSTALL/grub/x86_64-efi/sfs.mod b/INSTALL/grub/x86_64-efi/sfs.mod new file mode 100644 index 0000000..a532b1f Binary files /dev/null and b/INSTALL/grub/x86_64-efi/sfs.mod differ diff --git a/INSTALL/grub/x86_64-efi/shift_test.mod b/INSTALL/grub/x86_64-efi/shift_test.mod new file mode 100644 index 0000000..5a1321a Binary files /dev/null and b/INSTALL/grub/x86_64-efi/shift_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/shim_lock.mod b/INSTALL/grub/x86_64-efi/shim_lock.mod new file mode 100644 index 0000000..3e4123a Binary files /dev/null and b/INSTALL/grub/x86_64-efi/shim_lock.mod differ diff --git a/INSTALL/grub/x86_64-efi/signature_test.mod b/INSTALL/grub/x86_64-efi/signature_test.mod new file mode 100644 index 0000000..54a3545 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/signature_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/sleep_test.mod b/INSTALL/grub/x86_64-efi/sleep_test.mod new file mode 100644 index 0000000..2722f35 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/sleep_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/spkmodem.mod b/INSTALL/grub/x86_64-efi/spkmodem.mod new file mode 100644 index 0000000..eac5b90 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/spkmodem.mod differ diff --git a/INSTALL/grub/x86_64-efi/strtoull_test.mod b/INSTALL/grub/x86_64-efi/strtoull_test.mod new file mode 100644 index 0000000..24b4245 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/strtoull_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/syslinuxcfg.mod b/INSTALL/grub/x86_64-efi/syslinuxcfg.mod new file mode 100644 index 0000000..020f9cf Binary files /dev/null and b/INSTALL/grub/x86_64-efi/syslinuxcfg.mod differ diff --git a/INSTALL/grub/x86_64-efi/terminal.lst b/INSTALL/grub/x86_64-efi/terminal.lst new file mode 100644 index 0000000..9afb9bd --- /dev/null +++ b/INSTALL/grub/x86_64-efi/terminal.lst @@ -0,0 +1,10 @@ +iat_keyboard: at_keyboard +imouse: mouse +iserial: serial +iserial_*: serial +oaudio: morse +ocbmemc: cbmemc +ogfxterm: gfxterm +oserial: serial +oserial_*: serial +ospkmodem: spkmodem diff --git a/INSTALL/grub/x86_64-efi/test_blockarg.mod b/INSTALL/grub/x86_64-efi/test_blockarg.mod new file mode 100644 index 0000000..742a480 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/test_blockarg.mod differ diff --git a/INSTALL/grub/x86_64-efi/testload.mod b/INSTALL/grub/x86_64-efi/testload.mod new file mode 100644 index 0000000..a7185ac Binary files /dev/null and b/INSTALL/grub/x86_64-efi/testload.mod differ diff --git a/INSTALL/grub/x86_64-efi/testspeed.mod b/INSTALL/grub/x86_64-efi/testspeed.mod new file mode 100644 index 0000000..609b3a5 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/testspeed.mod differ diff --git a/INSTALL/grub/x86_64-efi/tga.mod b/INSTALL/grub/x86_64-efi/tga.mod new file mode 100644 index 0000000..ecbf32d Binary files /dev/null and b/INSTALL/grub/x86_64-efi/tga.mod differ diff --git a/INSTALL/grub/x86_64-efi/time.mod b/INSTALL/grub/x86_64-efi/time.mod new file mode 100644 index 0000000..7112f0c Binary files /dev/null and b/INSTALL/grub/x86_64-efi/time.mod differ diff --git a/INSTALL/grub/x86_64-efi/tpm.mod b/INSTALL/grub/x86_64-efi/tpm.mod new file mode 100644 index 0000000..811b7ce Binary files /dev/null and b/INSTALL/grub/x86_64-efi/tpm.mod differ diff --git a/INSTALL/grub/x86_64-efi/tr.mod b/INSTALL/grub/x86_64-efi/tr.mod new file mode 100644 index 0000000..cc01528 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/tr.mod differ diff --git a/INSTALL/grub/x86_64-efi/ufs1.mod b/INSTALL/grub/x86_64-efi/ufs1.mod new file mode 100644 index 0000000..de62764 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/ufs1.mod differ diff --git a/INSTALL/grub/x86_64-efi/ufs1_be.mod b/INSTALL/grub/x86_64-efi/ufs1_be.mod new file mode 100644 index 0000000..bab7012 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/ufs1_be.mod differ diff --git a/INSTALL/grub/x86_64-efi/ufs2.mod b/INSTALL/grub/x86_64-efi/ufs2.mod new file mode 100644 index 0000000..d1cc24c Binary files /dev/null and b/INSTALL/grub/x86_64-efi/ufs2.mod differ diff --git a/INSTALL/grub/x86_64-efi/uhci.mod b/INSTALL/grub/x86_64-efi/uhci.mod new file mode 100644 index 0000000..a9a490c Binary files /dev/null and b/INSTALL/grub/x86_64-efi/uhci.mod differ diff --git a/INSTALL/grub/x86_64-efi/usb.mod b/INSTALL/grub/x86_64-efi/usb.mod new file mode 100644 index 0000000..423a463 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/usb.mod differ diff --git a/INSTALL/grub/x86_64-efi/usbms.mod b/INSTALL/grub/x86_64-efi/usbms.mod new file mode 100644 index 0000000..ab5848d Binary files /dev/null and b/INSTALL/grub/x86_64-efi/usbms.mod differ diff --git a/INSTALL/grub/x86_64-efi/usbserial_common.mod b/INSTALL/grub/x86_64-efi/usbserial_common.mod new file mode 100644 index 0000000..5a33d89 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/usbserial_common.mod differ diff --git a/INSTALL/grub/x86_64-efi/usbserial_ftdi.mod b/INSTALL/grub/x86_64-efi/usbserial_ftdi.mod new file mode 100644 index 0000000..35cc7af Binary files /dev/null and b/INSTALL/grub/x86_64-efi/usbserial_ftdi.mod differ diff --git a/INSTALL/grub/x86_64-efi/usbserial_pl2303.mod b/INSTALL/grub/x86_64-efi/usbserial_pl2303.mod new file mode 100644 index 0000000..1b93dec Binary files /dev/null and b/INSTALL/grub/x86_64-efi/usbserial_pl2303.mod differ diff --git a/INSTALL/grub/x86_64-efi/usbserial_usbdebug.mod b/INSTALL/grub/x86_64-efi/usbserial_usbdebug.mod new file mode 100644 index 0000000..6fd988a Binary files /dev/null and b/INSTALL/grub/x86_64-efi/usbserial_usbdebug.mod differ diff --git a/INSTALL/grub/x86_64-efi/usbtest.mod b/INSTALL/grub/x86_64-efi/usbtest.mod new file mode 100644 index 0000000..b2cc766 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/usbtest.mod differ diff --git a/INSTALL/grub/x86_64-efi/verifiers.mod b/INSTALL/grub/x86_64-efi/verifiers.mod new file mode 100644 index 0000000..c44200f Binary files /dev/null and b/INSTALL/grub/x86_64-efi/verifiers.mod differ diff --git a/INSTALL/grub/x86_64-efi/video.lst b/INSTALL/grub/x86_64-efi/video.lst new file mode 100644 index 0000000..ae9ba23 --- /dev/null +++ b/INSTALL/grub/x86_64-efi/video.lst @@ -0,0 +1,4 @@ +efi_gop +efi_uga +video_bochs +video_cirrus diff --git a/INSTALL/grub/x86_64-efi/videoinfo.mod b/INSTALL/grub/x86_64-efi/videoinfo.mod new file mode 100644 index 0000000..d30ab12 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/videoinfo.mod differ diff --git a/INSTALL/grub/x86_64-efi/videotest.mod b/INSTALL/grub/x86_64-efi/videotest.mod new file mode 100644 index 0000000..9cd7cc5 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/videotest.mod differ diff --git a/INSTALL/grub/x86_64-efi/videotest_checksum.mod b/INSTALL/grub/x86_64-efi/videotest_checksum.mod new file mode 100644 index 0000000..afba542 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/videotest_checksum.mod differ diff --git a/INSTALL/grub/x86_64-efi/wrmsr.mod b/INSTALL/grub/x86_64-efi/wrmsr.mod new file mode 100644 index 0000000..6624182 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/wrmsr.mod differ diff --git a/INSTALL/grub/x86_64-efi/xnu.mod b/INSTALL/grub/x86_64-efi/xnu.mod new file mode 100644 index 0000000..3ba80d2 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/xnu.mod differ diff --git a/INSTALL/grub/x86_64-efi/xnu_uuid.mod b/INSTALL/grub/x86_64-efi/xnu_uuid.mod new file mode 100644 index 0000000..f5cc67f Binary files /dev/null and b/INSTALL/grub/x86_64-efi/xnu_uuid.mod differ diff --git a/INSTALL/grub/x86_64-efi/xnu_uuid_test.mod b/INSTALL/grub/x86_64-efi/xnu_uuid_test.mod new file mode 100644 index 0000000..d39261e Binary files /dev/null and b/INSTALL/grub/x86_64-efi/xnu_uuid_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/zfs.mod b/INSTALL/grub/x86_64-efi/zfs.mod new file mode 100644 index 0000000..86bd3a4 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/zfs.mod differ diff --git a/INSTALL/grub/x86_64-efi/zfscrypt.mod b/INSTALL/grub/x86_64-efi/zfscrypt.mod new file mode 100644 index 0000000..cb2e7f8 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/zfscrypt.mod differ diff --git a/INSTALL/grub/x86_64-efi/zfsinfo.mod b/INSTALL/grub/x86_64-efi/zfsinfo.mod new file mode 100644 index 0000000..7a3af4c Binary files /dev/null and b/INSTALL/grub/x86_64-efi/zfsinfo.mod differ diff --git a/INSTALL/grub/x86_64-efi/zstd.mod b/INSTALL/grub/x86_64-efi/zstd.mod new file mode 100644 index 0000000..9ba950f Binary files /dev/null and b/INSTALL/grub/x86_64-efi/zstd.mod differ diff --git a/INSTALL/plugin/ventoy/theme/background.png b/INSTALL/plugin/ventoy/theme/background.png new file mode 100644 index 0000000..5a5c771 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/background.png differ diff --git a/INSTALL/plugin/ventoy/theme/icons/deepin.png b/INSTALL/plugin/ventoy/theme/icons/deepin.png new file mode 100644 index 0000000..a071b75 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/icons/deepin.png differ diff --git a/INSTALL/plugin/ventoy/theme/icons/red-hat.png b/INSTALL/plugin/ventoy/theme/icons/red-hat.png new file mode 100644 index 0000000..df19452 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/icons/red-hat.png differ diff --git a/INSTALL/plugin/ventoy/theme/icons/ubuntu.png b/INSTALL/plugin/ventoy/theme/icons/ubuntu.png new file mode 100644 index 0000000..a8ad283 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/icons/ubuntu.png differ diff --git a/INSTALL/plugin/ventoy/theme/icons/vtoyiso.png b/INSTALL/plugin/ventoy/theme/icons/vtoyiso.png new file mode 100644 index 0000000..b4e8077 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/icons/vtoyiso.png differ diff --git a/INSTALL/plugin/ventoy/theme/menu_c.png b/INSTALL/plugin/ventoy/theme/menu_c.png new file mode 100644 index 0000000..75c165b Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/menu_c.png differ diff --git a/INSTALL/plugin/ventoy/theme/menu_e.png b/INSTALL/plugin/ventoy/theme/menu_e.png new file mode 100644 index 0000000..d4c7421 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/menu_e.png differ diff --git a/INSTALL/plugin/ventoy/theme/menu_n.png b/INSTALL/plugin/ventoy/theme/menu_n.png new file mode 100644 index 0000000..5af3469 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/menu_n.png differ diff --git a/INSTALL/plugin/ventoy/theme/menu_ne.png b/INSTALL/plugin/ventoy/theme/menu_ne.png new file mode 100644 index 0000000..8757868 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/menu_ne.png differ diff --git a/INSTALL/plugin/ventoy/theme/menu_nw.png b/INSTALL/plugin/ventoy/theme/menu_nw.png new file mode 100644 index 0000000..8757868 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/menu_nw.png differ diff --git a/INSTALL/plugin/ventoy/theme/menu_s.png b/INSTALL/plugin/ventoy/theme/menu_s.png new file mode 100644 index 0000000..6ba2734 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/menu_s.png differ diff --git a/INSTALL/plugin/ventoy/theme/menu_se.png b/INSTALL/plugin/ventoy/theme/menu_se.png new file mode 100644 index 0000000..959b609 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/menu_se.png differ diff --git a/INSTALL/plugin/ventoy/theme/menu_sw.png b/INSTALL/plugin/ventoy/theme/menu_sw.png new file mode 100644 index 0000000..959b609 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/menu_sw.png differ diff --git a/INSTALL/plugin/ventoy/theme/menu_w.png b/INSTALL/plugin/ventoy/theme/menu_w.png new file mode 100644 index 0000000..d4c7421 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/menu_w.png differ diff --git a/INSTALL/plugin/ventoy/theme/select_c.png b/INSTALL/plugin/ventoy/theme/select_c.png new file mode 100644 index 0000000..245259a Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/select_c.png differ diff --git a/INSTALL/plugin/ventoy/theme/slider_c.png b/INSTALL/plugin/ventoy/theme/slider_c.png new file mode 100644 index 0000000..7d630fd Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/slider_c.png differ diff --git a/INSTALL/plugin/ventoy/theme/slider_n.png b/INSTALL/plugin/ventoy/theme/slider_n.png new file mode 100644 index 0000000..41482c9 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/slider_n.png differ diff --git a/INSTALL/plugin/ventoy/theme/slider_s.png b/INSTALL/plugin/ventoy/theme/slider_s.png new file mode 100644 index 0000000..17adc2a Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/slider_s.png differ diff --git a/INSTALL/plugin/ventoy/theme/terminal_box_c.png b/INSTALL/plugin/ventoy/theme/terminal_box_c.png new file mode 100644 index 0000000..d0dd52a Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/terminal_box_c.png differ diff --git a/INSTALL/plugin/ventoy/theme/terminal_box_e.png b/INSTALL/plugin/ventoy/theme/terminal_box_e.png new file mode 100644 index 0000000..394cbe4 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/terminal_box_e.png differ diff --git a/INSTALL/plugin/ventoy/theme/terminal_box_n.png b/INSTALL/plugin/ventoy/theme/terminal_box_n.png new file mode 100644 index 0000000..476f8bc Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/terminal_box_n.png differ diff --git a/INSTALL/plugin/ventoy/theme/terminal_box_ne.png b/INSTALL/plugin/ventoy/theme/terminal_box_ne.png new file mode 100644 index 0000000..9e26959 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/terminal_box_ne.png differ diff --git a/INSTALL/plugin/ventoy/theme/terminal_box_nw.png b/INSTALL/plugin/ventoy/theme/terminal_box_nw.png new file mode 100644 index 0000000..5c3cba8 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/terminal_box_nw.png differ diff --git a/INSTALL/plugin/ventoy/theme/terminal_box_s.png b/INSTALL/plugin/ventoy/theme/terminal_box_s.png new file mode 100644 index 0000000..85a8901 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/terminal_box_s.png differ diff --git a/INSTALL/plugin/ventoy/theme/terminal_box_se.png b/INSTALL/plugin/ventoy/theme/terminal_box_se.png new file mode 100644 index 0000000..d8627ee Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/terminal_box_se.png differ diff --git a/INSTALL/plugin/ventoy/theme/terminal_box_sw.png b/INSTALL/plugin/ventoy/theme/terminal_box_sw.png new file mode 100644 index 0000000..67c600c Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/terminal_box_sw.png differ diff --git a/INSTALL/plugin/ventoy/theme/terminal_box_w.png b/INSTALL/plugin/ventoy/theme/terminal_box_w.png new file mode 100644 index 0000000..d066e2d Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/terminal_box_w.png differ diff --git a/INSTALL/plugin/ventoy/theme/theme.txt b/INSTALL/plugin/ventoy/theme/theme.txt new file mode 100644 index 0000000..f881506 --- /dev/null +++ b/INSTALL/plugin/ventoy/theme/theme.txt @@ -0,0 +1,96 @@ + +desktop-image: "background.png" +title-text: " " +title-color: "#ffffff" +message-color: "#f2f2f2" + +terminal-box: "terminal_box_*.png" + ++ boot_menu { + left = 10% + width = 80% + top = 30% + height = 50% + + menu_pixmap_style = "menu_*.png" + + item_color = "#ffffff" + item_height = 30 + + item_spacing = 1 + item_padding = 1 + + selected_item_color= "#f2f2f2" + selected_item_pixmap_style = "select_*.png" + + item_icon_space = 0 + + scrollbar = true + scrollbar_width = 10 + scrollbar_thumb = "slider_*.png" +} + ++ progress_bar { + id = "__timeout__" + text = "@TIMEOUT_NOTIFICATION_SHORT@" + + left = 20% + width = 60% + top = 85% + + text_color = "red" + bar_style = "*" + highlight_style = "*" +} + ++ hbox{ + left = 30% + top = 95% + width = 10% + height = 25 + + label {text = "@VTOY_HOTKEY_TIP@" color = "blue" align = "left"} +} + + ++ hbox{ + left = 30% + top = 95%-25 + width = 10% + height = 25 + + label {text = "@VTOY_MEM_DISK@" color = "red" align = "left"} +} + + ++ hbox{ + left = 30% + top = 95%-50 + width = 10% + height = 25 + + label {text = "@VTOY_ISO_RAW@" color = "red" align = "left"} +} + + ++ hbox{ + left = 30%+200 + top = 95%-50 + width = 10% + height = 25 + + label {text = "@VTOY_GRUB2_MODE@" color = "red" align = "left"} +} + ++ hbox{ + left = 30%+200 + top = 95%-25 + width = 10% + height = 25 + + label {text = "@VTOY_WIMBOOT_MODE@" color = "red" align = "left"} +} + ++ hbox{ + left = 90% + top = 55 + width = 10% + height = 25 + + label {text = "@VTOY_ISO_UEFI_DRV@" color = "red" align = "left"} +} + diff --git a/INSTALL/plugin/ventoy/ventoy.json b/INSTALL/plugin/ventoy/ventoy.json new file mode 100644 index 0000000..0452aab --- /dev/null +++ b/INSTALL/plugin/ventoy/ventoy.json @@ -0,0 +1,60 @@ +{ + "control": [ + { "VTOY_DEFAULT_MENU_MODE": "1" }, + { "VTOY_FILT_DOT_UNDERSCORE_FILE": "1" } + ], + + "theme": { + "file": "/ventoy/theme/theme.txt", + "display_mode": "GUI", + "ventoy_left": "5%", + "ventoy_top": "95%", + "ventoy_color": "#0000ff" + }, + + + "menu_class": [ + { + "key": "ubuntu", + "class": "ubuntu" + }, + { + "key": "deepin", + "class": "deepin" + }, + { + "dir": "rhel", + "class": "red-hat" + } + ], + + "menu_alias": [ + { + "image": "/ISO/MX-19.1_x64.iso", + "alias": "MX 19.1 ISO file For me" + }, + { + "image": "/cn_windows_10_enterprise_ltsc_2019_x64_dvd_9c09ff24.iso", + "alias": "我的 Windows 10 系统" + } + ], + + "auto_install": [ + { + "image": "/ISO/cn_windows_10.iso", + "template": "/ventoy/script/windows_unattended.cfg" + }, + { + "image": "/ISO/cn_windows_server_2012_r2_vl_x64_dvd_2979220.iso", + "template": [ + "/ventoy/script/windows_unattended1.xml", + "/ventoy/script/windows_unattended2.xml", + "/ventoy/script/windows_unattended3.xml", + "/ventoy/script/windows_unattended4.xml", + "/ventoy/script/windows_unattended5.xml", + "/ventoy/script/windows_unattended6.xml" + ] + } + ] + +} diff --git a/INSTALL/plugin/ventoy/ventoy_grub.cfg b/INSTALL/plugin/ventoy/ventoy_grub.cfg new file mode 100644 index 0000000..f736fb9 --- /dev/null +++ b/INSTALL/plugin/ventoy/ventoy_grub.cfg @@ -0,0 +1,19 @@ +menuentry "My Custom Menu" --class=custom { + echo 'This is custom menu ... ' + sleep 1 +} + +submenu 'My Custom SubMenu -->' --class=customsub { + menuentry "My Custom Menu2" --class=custom2 { + echo 'This is custom menu2 ... ' + sleep 1 + } + + menuentry '<-- Return to previous menu [Esc]' --class=vtoyret VTOY_RET { + echo 'Return ...' + } +} + +menuentry '<-- Return to previous menu [Esc]' --class=vtoyret VTOY_RET { + echo 'Return ...' +} diff --git a/INSTALL/sign_with_pass.exp b/INSTALL/sign_with_pass.exp new file mode 100644 index 0000000..d3e27ec --- /dev/null +++ b/INSTALL/sign_with_pass.exp @@ -0,0 +1,19 @@ +#!/usr/bin/expect -f + +set password [lindex $argv 0] +set key_file [lindex $argv 1] +set cert_file [lindex $argv 2] +set input_file [lindex $argv 3] +set output_file [lindex $argv 4] + + +spawn bash -c "sbsign --key '$key_file' --cert '$cert_file' --output '$output_file' '$input_file' 2>&1" +expect -nocase -re "Enter PEM pass phrase:" +send "$password\r" + + +expect eof + + +set ret [wait] +exit [lindex $ret 3] diff --git a/INSTALL/tool/ENROLL_THIS_KEY_IN_MOKMANAGER.cer b/INSTALL/tool/ENROLL_THIS_KEY_IN_MOKMANAGER.cer new file mode 100644 index 0000000..3d7feea Binary files /dev/null and b/INSTALL/tool/ENROLL_THIS_KEY_IN_MOKMANAGER.cer differ diff --git a/INSTALL/tool/VentoyGTK.glade b/INSTALL/tool/VentoyGTK.glade new file mode 100644 index 0000000..d362a81 --- /dev/null +++ b/INSTALL/tool/VentoyGTK.glade @@ -0,0 +1,585 @@ + + + + + True + False + + + + False + False + Partition Configuration + True + center + 460 + 270 + + + True + False + + + 440 + 50 + True + False + 0 + + + True + False + + + 380 + True + True + + + 10 + 10 + + + + + + + 10 + 10 + + + + + + 220 + 60 + True + False + 0 + + + True + False + + + 200 + True + True + * + False + False + True + True + 10 + + + 10 + 10 + + + + + + + 10 + 60 + + + + + + 220 + 60 + True + False + 0 + + + True + False + + + 200 + True + False + 1 + + MB + GB + + + + 10 + 10 + + + + + + + 230 + 60 + + + + + + 440 + 50 + True + False + 0 + + + True + False + + + 380 + True + True + True + + + 10 + 10 + + + + + + + 10 + 140 + + + + + + OK + 100 + 40 + True + True + True + + + 90 + 210 + + + + + Cancel + 100 + 40 + True + True + True + True + + + 270 + 210 + + + + + + 460 + 25 + True + False + 0 + + + 10 + 250 + + + + + + + + + False + False + Ventoy2Disk + False + center + 480 + 365 + + + True + False + + + 480 + 22 + True + False + + + True + False + Options + True + + + True + False + + + Secure Boot Support + True + False + True + False + + + + + True + False + Partition Style + True + + + True + False + + + MBR + True + False + True + True + + + + + GPT + True + False + True + False + + + + + + + + + Partition Configuration + True + False + True + + + + + Clear Ventoy + True + False + True + + + + + Show All Devices + True + False + True + False + + + + + + + + + + True + False + Language + True + + + True + False + + + + + + + + + 460 + 75 + True + False + 0 + + + True + False + + + 380 + True + False + + + 10 + 5 + + + + + 50 + True + True + True + True + image_refresh + + + 398 + 0 + + + + + + + True + False + Device + + + + + 10 + 40 + + + + + 228 + 70 + True + False + 0.5 + + + True + False + + + 10 + 40 + False + False + + + 20 + 2 + + + + + 120 + 40 + True + False + + True + + + 45 + + + + + 45 + 20 + True + False + MBR + + + 180 + 30 + + + + + + + True + False + Ventoy In Package + True + + + + + 10 + 132 + + + + + 228 + 70 + True + False + 0.5 + + + True + False + + + 10 + 40 + True + False + + + 20 + 2 + + + + + 120 + 40 + True + False + + True + + + 45 + + + + + 45 + 20 + True + False + + + + 180 + 30 + + + + + + + True + False + Ventoy In Device + True + + + + + 243 + 132 + + + + + 460 + 50 + True + False + 0 + + + True + False + + + 440 + True + False + 0.0 + + + 8 + 10 + + + + + + + True + False + Status - READY + + + + + 10 + 215 + + + + + Install + 100 + 40 + True + True + True + + + 100 + 300 + + + + + Update + 100 + 40 + True + True + True + + + 280 + 300 + + + + + + 460 + 25 + True + False + 0 + + + 10 + 345 + + + + + + + \ No newline at end of file diff --git a/INSTALL/tool/VentoyWorker.sh b/INSTALL/tool/VentoyWorker.sh new file mode 100644 index 0000000..4e86b8e --- /dev/null +++ b/INSTALL/tool/VentoyWorker.sh @@ -0,0 +1,643 @@ +#!/bin/sh + +. ./tool/ventoy_lib.sh + +print_usage() { + + echo 'Usage: Ventoy2Disk.sh CMD [ OPTION ] /dev/sdX' + echo ' CMD:' + echo ' -i install Ventoy to sdX (fails if disk already installed with Ventoy)' + echo ' -I force install Ventoy to sdX (no matter if installed or not)' + echo ' -u update Ventoy in sdX' + echo ' -l list Ventoy information in sdX' + echo '' + echo ' OPTION: (optional)' + echo ' -r SIZE_MiB preserve some space (MiB) at the bottom of the disk (only for install)' + echo ' -s/-S enable/disable secure boot support (default is enabled)' + echo ' -g use GPT partition style, default is MBR (only for install)' + echo ' -L Label of the 1st exfat partition (default is Ventoy)' + echo ' -n try non-destructive installation (only for install)' + echo '' +} + + +SECUREBOOT="YES" +VTNEW_LABEL='Ventoy' +RESERVE_SIZE_MB=0 +while [ -n "$1" ]; do + if [ "$1" = "-i" ]; then + MODE="install" + elif [ "$1" = "-I" ]; then + MODE="install" + FORCE="Y" + elif [ "$1" = "-n" ]; then + NONDESTRUCTIVE="Y" + elif [ "$1" = "-u" ]; then + MODE="update" + elif [ "$1" = "-l" ]; then + MODE="list" + elif [ "$1" = "-s" ]; then + SECUREBOOT="YES" + elif [ "$1" = "-S" ]; then + SECUREBOOT="NO" + elif [ "$1" = "-g" ]; then + VTGPT="YES" + elif [ "$1" = "-L" ]; then + shift + VTNEW_LABEL=$1 + elif [ "$1" = "-r" ]; then + RESERVE_SPACE="YES" + shift + RESERVE_SIZE_MB=$1 + elif [ "$1" = "-V" ] || [ "$1" = "--version" ]; then + exit 0 + elif [ "$1" = "-h" ] || [ "$1" = "--help" ]; then + print_usage + exit 0 + else + if ! [ -b "$1" ]; then + vterr "$1 is NOT a valid device" + print_usage + exit 1 + fi + DISK=$1 + # Resolve symlinks now, will be needed to look up information about the device in + # the /sys/ filesystem, for example /sys/class/block/${DISK#/dev/}/start + # The main use case is supporting /dev/disk/by-id/ symlinks instead of raw devices + if [ -L "$DISK" ]; then + DISK=$(readlink -e -n "$DISK") + fi + fi + + shift +done + +if [ -z "$MODE" ]; then + print_usage + exit 1 +fi + +if ! [ -b "$DISK" ]; then + vterr "Disk $DISK does not exist" + exit 1 +fi + +if [ -e /sys/class/block/${DISK#/dev/}/start ]; then + vterr "$DISK is a partition, please use the whole disk." + echo "For example:" + vterr " sudo sh Ventoy2Disk.sh -i /dev/sdb1 <=== This is wrong" + vtinfo " sudo sh Ventoy2Disk.sh -i /dev/sdb <=== This is right" + echo "" + exit 1 +fi + +if [ -n "$RESERVE_SPACE" -a "$MODE" = "install" ]; then + if echo $RESERVE_SIZE_MB | grep -q '^[0-9][0-9]*$'; then + vtdebug "User will reserve $RESERVE_SIZE_MB MiB disk space" + else + vterr "$RESERVE_SIZE_MB is invalid for reserved space" + exit 1 + fi +fi + +vtdebug "MODE=$MODE FORCE=$FORCE RESERVE_SPACE=$RESERVE_SPACE RESERVE_SIZE_MB=$RESERVE_SIZE_MB" + +#check tools +if check_tool_work_ok; then + vtdebug "check tool work ok" +else + vterr "Some tools can not run on current system. Please check log.txt for details." + exit 1 +fi + +if [ "$MODE" = "list" ]; then + version=$(get_disk_ventoy_version $DISK) + if [ $? -eq 0 ]; then + echo "Ventoy Version in Disk: $version" + + vtPart1Type=$(dd if=$DISK bs=1 count=1 skip=450 status=none | hexdump -n1 -e '1/1 "%02X"') + if [ "$vtPart1Type" = "EE" ]; then + echo "Disk Partition Style : GPT" + else + echo "Disk Partition Style : MBR" + fi + + if check_disk_secure_boot $DISK; then + echo "Secure Boot Support : YES" + else + echo "Secure Boot Support : NO" + fi + else + echo "Ventoy Version: NA" + fi + echo "" + exit 0 +fi + +#check mountpoint +check_umount_disk "$DISK" + +if grep "$DISK" /proc/mounts; then + vterr "$DISK is already mounted, please umount it first!" + exit 1 +fi + +#check swap partition +if swapon --help 2>&1 | grep -q '^ -s,'; then + if swapon -s | grep -q "^${DISK}[0-9]"; then + vterr "$DISK is used as swap, please swapoff it first!" + exit 1 + fi +fi + +#check access +if dd if="$DISK" of=/dev/null bs=1 count=1 >/dev/null 2>&1; then + vtdebug "root permission check ok ..." +else + vterr "Failed to access $DISK, maybe root privilege is needed!" + echo '' + exit 1 +fi + + +#check tmp_mnt directory +if [ -d ./tmp_mnt ]; then + vtdebug "There is a tmp_mnt directory, now delete it." + umount ./tmp_mnt >/dev/null 2>&1 + rm -rf ./tmp_mnt + if [ -d ./tmp_mnt ]; then + vterr "tmp_mnt directory exists, please delete it first." + exit 1 + fi +fi + + +if [ "$MODE" = "install" -a -z "$NONDESTRUCTIVE" ]; then + vtdebug "install Ventoy ..." + + if [ -n "$VTGPT" ]; then + if parted -v > /dev/null 2>&1; then + PARTTOOL='parted' + else + vterr "parted is not found in the system, Ventoy can't create new partitions without it." + vterr "You should install \"GNU parted\" first." + exit 1 + fi + else + if parted -v > /dev/null 2>&1; then + PARTTOOL='parted' + elif command -v fdisk > /dev/null 2>&1; then + PARTTOOL='fdisk' + else + vterr "Both parted and fdisk are not found in the system, Ventoy can't create new partitions." + exit 1 + fi + fi + + if [ "$PARTTOOL" = "parted" ]; then + if parted -s $DISK p 2>&1 | grep -i -q 'sector size.*4096.*4096'; then + vterr "Currently Ventoy does not support 4K native device." + exit 1 + fi + else + if fdisk -l $DISK | grep -i -q 'sector size.*4096.*4096'; then + vterr "Currently Ventoy does not support 4K native device." + exit 1 + fi + fi + + + version=$(get_disk_ventoy_version $DISK) + if [ $? -eq 0 ]; then + if [ -z "$FORCE" ]; then + vtwarn "$DISK already contains a Ventoy with version $version" + vtwarn "Use -u option to do a safe upgrade operation." + vtwarn "OR if you really want to reinstall Ventoy to $DISK, please use -I option." + vtwarn "" + exit 1 + fi + fi + + disk_sector_num=$(cat /sys/block/${DISK#/dev/}/size) + disk_size_gb=$(expr $disk_sector_num / 2097152) + + if [ $disk_sector_num -gt 4294967296 ] && [ -z "$VTGPT" ]; then + vterr "$DISK is over 2TB size, MBR will not work on it." + exit 1 + fi + + if [ -n "$RESERVE_SPACE" ]; then + sum_size_mb=$(expr $RESERVE_SIZE_MB + $VENTOY_PART_SIZE_MB) + reserve_sector_num=$(expr $sum_size_mb \* 2048) + + if [ $disk_sector_num -le $reserve_sector_num ]; then + vterr "Can't reserve $RESERVE_SIZE_MB MiB space from $DISK" + exit 1 + fi + fi + + #Print disk info + echo "Disk : $DISK" + parted -s $DISK p 2>&1 | grep Model + echo "Size : $disk_size_gb GiB" + if [ -n "$VTGPT" ]; then + echo "Style: GPT" + else + echo "Style: MBR" + fi + echo '' + + if [ -n "$RESERVE_SPACE" ]; then + echo "You will reserve $RESERVE_SIZE_MB MiB disk space " + fi + echo '' + + vtwarn "Attention:" + vtwarn "You will install Ventoy to $DISK." + vtwarn "All the data on the disk $DISK will be lost!!!" + echo "" + + read -p 'Continue? (y/n) ' Answer + if [ "$Answer" != "y" ]; then + if [ "$Answer" != "Y" ]; then + exit 0 + fi + fi + + echo "" + vtwarn "All the data on the disk $DISK will be lost!!!" + read -p 'Double-check. Continue? (y/n) ' Answer + if [ "$Answer" != "y" ]; then + if [ "$Answer" != "Y" ]; then + exit 0 + fi + fi + + if [ $disk_sector_num -le $VENTOY_SECTOR_NUM ]; then + vterr "No enough space in disk $DISK" + exit 1 + fi + + # check and umount + check_umount_disk "$DISK" + + if ! dd if=/dev/zero of=$DISK bs=64 count=512 status=none conv=fsync; then + vterr "Write data to $DISK failed, please check whether it's in use." + exit 1 + fi + + if [ -n "$VTGPT" ]; then + vtdebug "format_ventoy_disk_gpt $RESERVE_SIZE_MB $DISK $PARTTOOL ..." + format_ventoy_disk_gpt $RESERVE_SIZE_MB $DISK $PARTTOOL + else + vtdebug "format_ventoy_disk_mbr $RESERVE_SIZE_MB $DISK $PARTTOOL ..." + format_ventoy_disk_mbr $RESERVE_SIZE_MB $DISK $PARTTOOL + fi + + # format part1 + + # DiskSize > 32GB Cluster Size use 128KB + # DiskSize < 32GB Cluster Size use 32KB + if [ $disk_size_gb -gt 32 ]; then + cluster_sectors=256 + else + cluster_sectors=64 + fi + + PART1=$(get_disk_part_name $DISK 1) + PART2=$(get_disk_part_name $DISK 2) + + #clean part2 + dd status=none conv=fsync if=/dev/zero of=$DISK bs=512 count=32 seek=$part2_start_sector + + #format part1 + wait_and_create_part ${PART1} ${PART2} + if [ -b ${PART1} ]; then + vtinfo "Format partition 1 ${PART1} ..." + mkexfatfs -n "$VTNEW_LABEL" -s $cluster_sectors ${PART1} + if [ $? -ne 0 ]; then + echo "mkexfatfs failed, now retry..." + mkexfatfs -n "$VTNEW_LABEL" -s $cluster_sectors ${PART1} + if [ $? -ne 0 ]; then + echo "######### mkexfatfs failed, exit ########" + exit 1 + fi + else + echo "mkexfatfs success" + fi + else + vterr "${PART1} NOT exist" + fi + + vtinfo "writing data to disk ..." + dd status=none conv=fsync if=./boot/boot.img of=$DISK bs=1 count=446 + + if [ -n "$VTGPT" ]; then + echo -en '\x22' | dd status=none of=$DISK conv=fsync bs=1 count=1 seek=92 + xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2014 seek=34 + echo -en '\x23' | dd of=$DISK conv=fsync bs=1 count=1 seek=17908 status=none + else + xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1 + fi + + # check and umount + check_umount_disk "$DISK" + + xzcat ./ventoy/ventoy.disk.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=$VENTOY_SECTOR_NUM seek=$part2_start_sector + + #test UUID + testUUIDStr=$(vtoy_gen_uuid | hexdump -C) + vtdebug "test uuid: $testUUIDStr" + + #disk uuid + vtoy_gen_uuid | dd status=none conv=fsync of=${DISK} seek=384 bs=1 count=16 + + #disk signature + vtoy_gen_uuid | dd status=none conv=fsync of=${DISK} skip=12 seek=440 bs=1 count=4 + + vtinfo "sync data ..." + sync + + vtinfo "esp partition processing ..." + + if [ "$SECUREBOOT" != "YES" ]; then + sleep 2 + check_umount_disk "$DISK" + vtoycli partresize -s $DISK $part2_start_sector + fi + + echo "" + vtinfo "Install Ventoy to $DISK successfully finished." + echo "" + +elif [ "$MODE" = "install" -a -n "$NONDESTRUCTIVE" ]; then + vtdebug "non-destructive install Ventoy ..." + + version=$(get_disk_ventoy_version $DISK) + if [ $? -eq 0 ]; then + if [ -z "$FORCE" ]; then + vtwarn "$DISK already contains a Ventoy with version $version." + vtwarn "You can not do and don not need non-destructive installation." + vtwarn "" + exit 1 + fi + fi + + disk_sector_num=$(cat /sys/block/${DISK#/dev/}/size) + disk_size_gb=$(expr $disk_sector_num / 2097152) + + if vtoycli partresize -t $DISK; then + OldStyle="GPT" + else + OldStyle="MBR" + fi + + #Print disk info + echo "Disk : $DISK" + parted -s $DISK p 2>&1 | grep Model + echo "Size : $disk_size_gb GiB" + echo "Style: $OldStyle" + echo '' + + vtwarn "Attention:" + vtwarn "Ventoy will try non-destructive installation on $DISK if possible." + echo "" + + read -p 'Continue? (y/n) ' Answer + if [ "$Answer" != "y" ]; then + if [ "$Answer" != "Y" ]; then + exit 0 + fi + fi + + if [ $disk_sector_num -le $VENTOY_SECTOR_NUM ]; then + vterr "No enough space in disk $DISK" + exit 1 + fi + + PART1=$(get_disk_part_name $DISK 1) + PART2=$(get_disk_part_name $DISK 2) + + #Part1 size in MB aligned with 4KB + PART1_SECTORS=$(cat /sys/class/block/${PART1#/dev/}/size) + PART1_4K=$(expr $PART1_SECTORS / 8) + PART1_MB=$(expr $PART1_4K / 256) + PART1_NEW_MB=$(expr $PART1_MB - 32) + + echo "$PART1 is ${PART1_MB}MiB" + + #check partition layout + echo "check partition layout ..." + vtoycli partresize -c $DISK + vtRet=$? + if [ $vtRet -eq 0 ]; then + exit 1 + else + # check and umount + check_umount_disk "$DISK" + sleep 1 + check_umount_disk "$DISK" + + if [ $vtRet -eq 1 ]; then + echo "Free space enough, start install..." + part2_start_sector=$(expr $PART1_SECTORS + 2048) + elif [ $vtRet -eq 2 ]; then + echo "We need to shrink partition 1 firstly ..." + + PART1_BLKID=$(blkid $PART1) + blkid $PART1 + + if echo $PART1_BLKID | grep -E -q -i 'TYPE=ntfs|TYPE=.ntfs'; then + echo "Partition 1 contains NTFS filesystem" + + which ntfsresize + if [ $? -ne 0 ]; then + echo "###[FAIL] ntfsresize not found. Please install ntfs-3g package." + exit 1 + fi + + echo "ntfsfix -b -d $PART1 ..." + ntfsfix -b -d $PART1 + + echo "ntfsresize --size ${PART1_NEW_MB}Mi $PART1 ..." + ntfsresize -f --size ${PART1_NEW_MB}Mi $PART1 + if [ $? -ne 0 ]; then + echo "###[FAIL] ntfsresize failed." + exit 1 + fi + elif echo $PART1_BLKID | grep -E -q -i 'TYPE=ext[2-4]|TYPE=.ext[2-4]'; then + echo "Partition 1 contains EXT filesystem" + + which resize2fs + if [ $? -ne 0 ]; then + echo "###[FAIL] resize2fs not found. Please install e2fsprogs package." + exit 1 + fi + + echo "e2fsck -f $PART1 ..." + e2fsck -f $PART1 + + echo "resize2fs $PART1 ${PART1_NEW_MB}M ..." + resize2fs $PART1 ${PART1_NEW_MB}M + if [ $? -ne 0 ]; then + echo "###[FAIL] resize2fs failed." + exit 1 + fi + else + echo "###[FAIL] Unsupported filesystem in partition 1." + exit 1 + fi + + sync + PART1_NEW_END_MB=$(expr $PART1_NEW_MB + 1) + part2_start_sector=$(expr $PART1_NEW_END_MB \* 2048) + fi + fi + + vtinfo "writing data to disk part2_start=$part2_start_sector ..." + + dd status=none conv=fsync if=./boot/boot.img of=$DISK bs=1 count=440 + + if [ "$OldStyle" = "GPT" ]; then + echo -en '\x22' | dd status=none of=$DISK conv=fsync bs=1 count=1 seek=92 + xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2014 seek=34 + echo -en '\x23' | dd of=$DISK conv=fsync bs=1 count=1 seek=17908 status=none + else + xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1 + fi + + xzcat ./ventoy/ventoy.disk.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=$VENTOY_SECTOR_NUM seek=$part2_start_sector + + #test UUID + testUUIDStr=$(vtoy_gen_uuid | hexdump -C) + vtdebug "test uuid: $testUUIDStr" + + #disk uuid + vtoy_gen_uuid | dd status=none conv=fsync of=${DISK} seek=384 bs=1 count=16 + + vtinfo "sync data ..." + sync + + vtinfo "esp partition processing ..." + if [ "$SECUREBOOT" != "YES" ]; then + vtoycli partresize -s $DISK $part2_start_sector + fi + + vtinfo "update partition table $DISK $part2_start_sector ..." + vtoycli partresize -p $DISK $part2_start_sector + if [ $? -eq 0 ]; then + sync + echo "" + vtinfo "Ventoy non-destructive installation on $DISK successfully finished." + echo "" + else + echo "" + vterr "Ventoy non-destructive installation on $DISK failed." + echo "" + fi + +else + vtdebug "update Ventoy ..." + + oldver=$(get_disk_ventoy_version $DISK) + if [ $? -ne 0 ]; then + if is_disk_contains_ventoy $DISK; then + oldver="Unknown" + else + vtwarn "$DISK does not contain Ventoy or data corrupted" + echo "" + vtwarn "Please use -i option if you want to install ventoy to $DISK" + echo "" + exit 1 + fi + fi + + #reserve secure boot option + if [ -z "$SECUREBOOT" ]; then + if check_disk_secure_boot $DISK; then + SECUREBOOT="YES" + else + SECUREBOOT="NO" + fi + fi + + curver=$(cat ./ventoy/version) + + vtinfo "Upgrade operation is safe, all the data in the 1st partition (iso files and other) will be unchanged!" + echo "" + + read -p "Update Ventoy $oldver ===> $curver Continue? (y/n) " Answer + if [ "$Answer" != "y" ]; then + if [ "$Answer" != "Y" ]; then + exit 0 + fi + fi + + PART2=$(get_disk_part_name $DISK 2) + SHORT_PART2=${PART2#/dev/} + part2_start=$(cat /sys/class/block/$SHORT_PART2/start) + + PART1_TYPE=$(dd if=$DISK bs=1 count=1 skip=450 status=none | hexdump -n1 -e '1/1 "%02X"') + + #reserve disk uuid + rm -f ./diskuuid.bin + dd status=none conv=fsync if=${DISK} skip=384 bs=1 count=16 of=./diskuuid.bin + + dd status=none conv=fsync if=./boot/boot.img of=$DISK bs=1 count=440 + dd status=none conv=fsync if=./diskuuid.bin of=$DISK bs=1 count=16 seek=384 + rm -f ./diskuuid.bin + + #reserve data + rm -f ./rsvdata.bin + dd status=none conv=fsync if=${DISK} skip=2040 bs=512 count=8 of=./rsvdata.bin + + if [ "$PART1_TYPE" = "EE" ]; then + vtdebug "This is GPT partition style ..." + echo -en '\x22' | dd status=none of=$DISK conv=fsync bs=1 count=1 seek=92 + xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2014 seek=34 + echo -en '\x23' | dd of=$DISK conv=fsync bs=1 count=1 seek=17908 status=none + else + vtdebug "This is MBR partition style ..." + + PART1_ACTIVE=$(dd if=$DISK bs=1 count=1 skip=446 status=none | hexdump -n1 -e '1/1 "%02X"') + PART2_ACTIVE=$(dd if=$DISK bs=1 count=1 skip=462 status=none | hexdump -n1 -e '1/1 "%02X"') + + vtdebug "PART1_ACTIVE=$PART1_ACTIVE PART2_ACTIVE=$PART2_ACTIVE" + if [ "$PART1_ACTIVE" = "00" ] && [ "$PART2_ACTIVE" = "80" ]; then + vtdebug "change 1st partition active, 2nd partition inactive ..." + echo -en '\x80' | dd of=$DISK conv=fsync bs=1 count=1 seek=446 status=none + echo -en '\x00' | dd of=$DISK conv=fsync bs=1 count=1 seek=462 status=none + fi + xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1 + fi + + dd status=none conv=fsync if=./rsvdata.bin seek=2040 bs=512 count=8 of=${DISK} + rm -f ./rsvdata.bin + + check_umount_disk "$DISK" + + xzcat ./ventoy/ventoy.disk.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=$VENTOY_SECTOR_NUM seek=$part2_start + sync + + vtinfo "esp partition processing ..." + if [ "$SECUREBOOT" != "YES" ]; then + sleep 2 + check_umount_disk "$DISK" + vtoycli partresize -s $DISK $part2_start + fi + + + if [ "$PART1_TYPE" = "EE" ]; then + vtinfo "update esp partition attribute" + vtoycli gpt -f $DISK + sync + fi + + + echo "" + vtinfo "Update Ventoy on $DISK successfully finished." + echo "" + +fi + + diff --git a/INSTALL/tool/aarch64/Plugson b/INSTALL/tool/aarch64/Plugson new file mode 100644 index 0000000..6916416 Binary files /dev/null and b/INSTALL/tool/aarch64/Plugson differ diff --git a/INSTALL/tool/aarch64/V2DServer b/INSTALL/tool/aarch64/V2DServer new file mode 100644 index 0000000..a35bd7d Binary files /dev/null and b/INSTALL/tool/aarch64/V2DServer differ diff --git a/INSTALL/tool/aarch64/Ventoy2Disk.gtk3 b/INSTALL/tool/aarch64/Ventoy2Disk.gtk3 new file mode 100644 index 0000000..e0203a8 Binary files /dev/null and b/INSTALL/tool/aarch64/Ventoy2Disk.gtk3 differ diff --git a/INSTALL/tool/aarch64/Ventoy2Disk.qt5 b/INSTALL/tool/aarch64/Ventoy2Disk.qt5 new file mode 100644 index 0000000..4a3f5fb Binary files /dev/null and b/INSTALL/tool/aarch64/Ventoy2Disk.qt5 differ diff --git a/INSTALL/tool/aarch64/ash b/INSTALL/tool/aarch64/ash new file mode 100644 index 0000000..55eb145 Binary files /dev/null and b/INSTALL/tool/aarch64/ash differ diff --git a/INSTALL/tool/aarch64/hexdump b/INSTALL/tool/aarch64/hexdump new file mode 100644 index 0000000..0f4e6c2 Binary files /dev/null and b/INSTALL/tool/aarch64/hexdump differ diff --git a/INSTALL/tool/aarch64/mkexfatfs b/INSTALL/tool/aarch64/mkexfatfs new file mode 100644 index 0000000..e22e9f1 Binary files /dev/null and b/INSTALL/tool/aarch64/mkexfatfs differ diff --git a/INSTALL/tool/aarch64/mount.exfat-fuse b/INSTALL/tool/aarch64/mount.exfat-fuse new file mode 100644 index 0000000..0cf851b Binary files /dev/null and b/INSTALL/tool/aarch64/mount.exfat-fuse differ diff --git a/INSTALL/tool/aarch64/vlnk b/INSTALL/tool/aarch64/vlnk new file mode 100644 index 0000000..0bf4fe0 Binary files /dev/null and b/INSTALL/tool/aarch64/vlnk differ diff --git a/INSTALL/tool/aarch64/vtoycli b/INSTALL/tool/aarch64/vtoycli new file mode 100644 index 0000000..7186ceb Binary files /dev/null and b/INSTALL/tool/aarch64/vtoycli differ diff --git a/INSTALL/tool/aarch64/xzcat b/INSTALL/tool/aarch64/xzcat new file mode 100644 index 0000000..4064856 Binary files /dev/null and b/INSTALL/tool/aarch64/xzcat differ diff --git a/INSTALL/tool/create_ventoy_iso_part_dm.sh b/INSTALL/tool/create_ventoy_iso_part_dm.sh new file mode 100644 index 0000000..a7ad6ed --- /dev/null +++ b/INSTALL/tool/create_ventoy_iso_part_dm.sh @@ -0,0 +1,38 @@ +#!/bin/sh + +if [ "$(id -u)" -ne 0 ]; then + echo "Please run with sudo ..." + exit 1 +fi + +oldpwd=$(pwd) +VPART="" + +if dmsetup -h > /dev/null 2>&1; then + VPART_MAJOR_MINOR=$(dmsetup table ventoy | head -n 1 | awk '{print $4}') + cd /sys/class/block/ + for t in *; do + if grep -q "^${VPART_MAJOR_MINOR}$" $t/dev; then + VPART=$t + echo 0 $(cat /sys/class/block/$VPART/size) linear /dev/$VPART 0 | dmsetup create $VPART + dmsetup mknodes "$VPART" > /dev/null 2>&1 + break + fi + done + cd $oldpwd + + if [ -z "$VPART" ]; then + echo "$VPART_MAJOR_MINOR not found" + dmsetup ls; dmsetup info ventoy; dmsetup table ventoy + exit 1 + else + if [ ! -b "/dev/mapper/$VPART" ]; then + udevadm trigger --type=devices --action=add > /dev/null 2>&1 + udevadm settle > /dev/null 2>&1 + fi + echo "Create /dev/mapper/$VPART success" + fi +else + echo "dmsetup program not avaliable" + exit 1 +fi diff --git a/INSTALL/tool/distro_gui_type.json b/INSTALL/tool/distro_gui_type.json new file mode 100644 index 0000000..f400fa9 --- /dev/null +++ b/INSTALL/tool/distro_gui_type.json @@ -0,0 +1,52 @@ +[ + { + "type": "env", + "name": "DESKTOP_SESSION", + "condition": "equal", + "expression": "deepin", + "gui": "qt5" + }, + { + "type": "env", + "name": "DESKTOP_SESSION", + "condition": "equal", + "expression": "uos", + "gui": "qt5" + }, + { + "type": "env", + "name": "DESKTOP_SESSION", + "condition": "equal", + "expression": "ukui", + "gui": "gtk3" + }, + { + "type": "env", + "name": "DESKTOP_SESSION", + "condition": "equal", + "expression": "cinnamon", + "gui": "gtk3" + }, + { + "type": "env", + "name": "DESKTOP_SESSION", + "condition": "equal", + "expression": "gnome", + "gui": "gtk3" + }, + { + "type": "env", + "name": "DESKTOP_SESSION", + "condition": "equal", + "expression": "plasma", + "gui": "qt5" + }, + { + "type": "env", + "name": "DESKTOP_SESSION", + "condition": "equal", + "expression": "xfce", + "gui": "gtk3" + } + +] diff --git a/INSTALL/tool/i386/Plugson b/INSTALL/tool/i386/Plugson new file mode 100644 index 0000000..715b9f7 Binary files /dev/null and b/INSTALL/tool/i386/Plugson differ diff --git a/INSTALL/tool/i386/V2DServer b/INSTALL/tool/i386/V2DServer new file mode 100644 index 0000000..f394355 Binary files /dev/null and b/INSTALL/tool/i386/V2DServer differ diff --git a/INSTALL/tool/i386/Ventoy2Disk.gtk2 b/INSTALL/tool/i386/Ventoy2Disk.gtk2 new file mode 100644 index 0000000..32fb510 Binary files /dev/null and b/INSTALL/tool/i386/Ventoy2Disk.gtk2 differ diff --git a/INSTALL/tool/i386/Ventoy2Disk.gtk3 b/INSTALL/tool/i386/Ventoy2Disk.gtk3 new file mode 100644 index 0000000..a2ed830 Binary files /dev/null and b/INSTALL/tool/i386/Ventoy2Disk.gtk3 differ diff --git a/INSTALL/tool/i386/Ventoy2Disk.qt5 b/INSTALL/tool/i386/Ventoy2Disk.qt5 new file mode 100644 index 0000000..2f5efb3 Binary files /dev/null and b/INSTALL/tool/i386/Ventoy2Disk.qt5 differ diff --git a/INSTALL/tool/i386/ash b/INSTALL/tool/i386/ash new file mode 100644 index 0000000..04f5d22 Binary files /dev/null and b/INSTALL/tool/i386/ash differ diff --git a/INSTALL/tool/i386/hexdump b/INSTALL/tool/i386/hexdump new file mode 100644 index 0000000..0fd90c2 Binary files /dev/null and b/INSTALL/tool/i386/hexdump differ diff --git a/INSTALL/tool/i386/mkexfatfs b/INSTALL/tool/i386/mkexfatfs new file mode 100644 index 0000000..a067639 Binary files /dev/null and b/INSTALL/tool/i386/mkexfatfs differ diff --git a/INSTALL/tool/i386/mount.exfat-fuse b/INSTALL/tool/i386/mount.exfat-fuse new file mode 100644 index 0000000..0b3a5f1 Binary files /dev/null and b/INSTALL/tool/i386/mount.exfat-fuse differ diff --git a/INSTALL/tool/i386/vlnk b/INSTALL/tool/i386/vlnk new file mode 100644 index 0000000..81fcf3d Binary files /dev/null and b/INSTALL/tool/i386/vlnk differ diff --git a/INSTALL/tool/i386/vtoycli b/INSTALL/tool/i386/vtoycli new file mode 100644 index 0000000..02eae99 Binary files /dev/null and b/INSTALL/tool/i386/vtoycli differ diff --git a/INSTALL/tool/i386/xzcat b/INSTALL/tool/i386/xzcat new file mode 100644 index 0000000..012a984 Binary files /dev/null and b/INSTALL/tool/i386/xzcat differ diff --git a/INSTALL/tool/mips64el/Plugson b/INSTALL/tool/mips64el/Plugson new file mode 100644 index 0000000..78c7484 Binary files /dev/null and b/INSTALL/tool/mips64el/Plugson differ diff --git a/INSTALL/tool/mips64el/V2DServer b/INSTALL/tool/mips64el/V2DServer new file mode 100644 index 0000000..8ea50cb Binary files /dev/null and b/INSTALL/tool/mips64el/V2DServer differ diff --git a/INSTALL/tool/mips64el/Ventoy2Disk.gtk3 b/INSTALL/tool/mips64el/Ventoy2Disk.gtk3 new file mode 100644 index 0000000..60d7cb9 Binary files /dev/null and b/INSTALL/tool/mips64el/Ventoy2Disk.gtk3 differ diff --git a/INSTALL/tool/mips64el/Ventoy2Disk.qt5 b/INSTALL/tool/mips64el/Ventoy2Disk.qt5 new file mode 100644 index 0000000..903c3e0 Binary files /dev/null and b/INSTALL/tool/mips64el/Ventoy2Disk.qt5 differ diff --git a/INSTALL/tool/mips64el/ash b/INSTALL/tool/mips64el/ash new file mode 100644 index 0000000..039e82a Binary files /dev/null and b/INSTALL/tool/mips64el/ash differ diff --git a/INSTALL/tool/mips64el/hexdump b/INSTALL/tool/mips64el/hexdump new file mode 100644 index 0000000..dc0d52f Binary files /dev/null and b/INSTALL/tool/mips64el/hexdump differ diff --git a/INSTALL/tool/mips64el/mkexfatfs b/INSTALL/tool/mips64el/mkexfatfs new file mode 100644 index 0000000..281ab2a Binary files /dev/null and b/INSTALL/tool/mips64el/mkexfatfs differ diff --git a/INSTALL/tool/mips64el/mount.exfat-fuse b/INSTALL/tool/mips64el/mount.exfat-fuse new file mode 100644 index 0000000..2702c58 Binary files /dev/null and b/INSTALL/tool/mips64el/mount.exfat-fuse differ diff --git a/INSTALL/tool/mips64el/vlnk b/INSTALL/tool/mips64el/vlnk new file mode 100644 index 0000000..571a81a Binary files /dev/null and b/INSTALL/tool/mips64el/vlnk differ diff --git a/INSTALL/tool/mips64el/vtoycli b/INSTALL/tool/mips64el/vtoycli new file mode 100644 index 0000000..18ecd6a Binary files /dev/null and b/INSTALL/tool/mips64el/vtoycli differ diff --git a/INSTALL/tool/mips64el/xzcat b/INSTALL/tool/mips64el/xzcat new file mode 100644 index 0000000..910c74c Binary files /dev/null and b/INSTALL/tool/mips64el/xzcat differ diff --git a/INSTALL/tool/ventoy_lib.sh b/INSTALL/tool/ventoy_lib.sh new file mode 100644 index 0000000..c90d13c --- /dev/null +++ b/INSTALL/tool/ventoy_lib.sh @@ -0,0 +1,513 @@ +#!/bin/sh + +#Ventoy partition 32MB +VENTOY_PART_SIZE=33554432 +VENTOY_PART_SIZE_MB=32 +VENTOY_SECTOR_SIZE=512 +VENTOY_SECTOR_NUM=65536 + +ventoy_false() { + [ "1" = "2" ] +} + +ventoy_true() { + [ "1" = "1" ] +} + + +vtinfo() { + echo -e "\033[32m$*\033[0m" +} + +vtwarn() { + echo -e "\033[33m$*\033[0m" +} + + +vterr() { + echo -e "\033[31m$*\033[0m" +} + +vtdebug() { + echo "$*" >> ./log.txt +} + +vtoy_gen_uuid() { + if uuid -F BIN > /dev/null 2>&1; then + uuid -F BIN + elif uuidgen -V > /dev/null 2>&1; then + a=$(uuidgen | sed 's/-//g') + echo -en "\x${a:0:2}\x${a:2:2}\x${a:4:2}\x${a:6:2}\x${a:8:2}\x${a:10:2}\x${a:12:2}\x${a:14:2}\x${a:16:2}\x${a:18:2}\x${a:20:2}\x${a:22:2}\x${a:24:2}\x${a:26:2}\x${a:28:2}\x${a:30:2}" + elif python -V > /dev/null 2>&1; then + a=$(python -c 'import sys,uuid; sys.stdout.write(uuid.uuid4().hex)') + echo -en "\x${a:0:2}\x${a:2:2}\x${a:4:2}\x${a:6:2}\x${a:8:2}\x${a:10:2}\x${a:12:2}\x${a:14:2}\x${a:16:2}\x${a:18:2}\x${a:20:2}\x${a:22:2}\x${a:24:2}\x${a:26:2}\x${a:28:2}\x${a:30:2}" + elif [ -e /dev/urandom ]; then + dd if=/dev/urandom bs=1 count=16 status=none + else + datestr=$(date +%N%N%N%N%N) + a=${datestr:0:32} + echo -en "\x${a:0:2}\x${a:2:2}\x${a:4:2}\x${a:6:2}\x${a:8:2}\x${a:10:2}\x${a:12:2}\x${a:14:2}\x${a:16:2}\x${a:18:2}\x${a:20:2}\x${a:22:2}\x${a:24:2}\x${a:26:2}\x${a:28:2}\x${a:30:2}" + fi +} + +check_tool_work_ok() { + + if echo 1 | hexdump > /dev/null; then + vtdebug "hexdump test ok ..." + else + vtdebug "hexdump test fail ..." + ventoy_false + return + fi + + if mkexfatfs -V > /dev/null; then + vtdebug "mkexfatfs test ok ..." + else + vtdebug "mkexfatfs test fail ..." + ventoy_false + return + fi + + if vtoycli fat -T; then + vtdebug "vtoycli fat test ok ..." + else + vtdebug "vtoycli fat test fail ..." + ventoy_false + return + fi + + vtdebug "tool check success ..." + ventoy_true +} + + +get_disk_part_name() { + DISK=$1 + + if echo $DISK | grep -q "/dev/loop"; then + echo ${DISK}p${2} + elif echo $DISK | grep -q "/dev/nvme[0-9][0-9]*n[0-9]"; then + echo ${DISK}p${2} + elif echo $DISK | grep -q "/dev/mmcblk[0-9]"; then + echo ${DISK}p${2} + elif echo $DISK | grep -q "/dev/nbd[0-9]"; then + echo ${DISK}p${2} + elif echo $DISK | grep -q "/dev/zd[0-9]"; then + echo ${DISK}p${2} + elif echo $DISK | grep -q "/dev/md[0-9]"; then + echo ${DISK}p${2} + else + echo ${DISK}${2} + fi +} + +check_umount_disk() { + DiskOrPart="$1" + grep "^${DiskOrPart}" /proc/mounts | while read mtline; do + mtpnt=$(echo $mtline | awk '{print $2}') + vtdebug "Trying to umount $mtpnt ..." + umount $mtpnt >/dev/null 2>&1 + done +} + +get_ventoy_version_from_cfg() { + if grep -q 'set.*VENTOY_VERSION=' $1; then + grep 'set.*VENTOY_VERSION=' $1 | awk -F'"' '{print $2}' + else + echo 'none' + fi +} + +is_disk_contains_ventoy() { + DISK=$1 + + PART1=$(get_disk_part_name $1 1) + PART2=$(get_disk_part_name $1 2) + + if [ -e /sys/class/block/${PART2#/dev/}/size ]; then + SIZE=$(cat /sys/class/block/${PART2#/dev/}/size) + else + SIZE=0 + fi + + if ! [ -b $PART1 ]; then + vtdebug "$PART1 not exist" + ventoy_false + return + fi + + if ! [ -b $PART2 ]; then + vtdebug "$PART2 not exist" + ventoy_false + return + fi + + PART1_TYPE=$(dd if=$DISK bs=1 count=1 skip=450 status=none | hexdump -n1 -e '1/1 "%02X"') + PART2_TYPE=$(dd if=$DISK bs=1 count=1 skip=466 status=none | hexdump -n1 -e '1/1 "%02X"') + + # if [ "$PART1_TYPE" != "EE" ]; then + # if [ "$PART2_TYPE" != "EF" ]; then + # vtdebug "part2 type is $PART2_TYPE not EF" + # ventoy_false + # return + # fi + # fi + + # PART1_TYPE=$(dd if=$DISK bs=1 count=1 skip=450 status=none | hexdump -n1 -e '1/1 "%02X"') + # if [ "$PART1_TYPE" != "07" ]; then + # vtdebug "part1 type is $PART2_TYPE not 07" + # ventoy_false + # return + # fi + + if [ -e /sys/class/block/${PART1#/dev/}/start ]; then + PART1_START=$(cat /sys/class/block/${PART1#/dev/}/start) + fi + + if [ "$PART1_START" != "2048" ]; then + vtdebug "part1 start is $PART1_START not 2048" + ventoy_false + return + fi + + if [ "$VENTOY_SECTOR_NUM" != "$SIZE" ]; then + vtdebug "part2 size is $SIZE not $VENTOY_SECTOR_NUM" + ventoy_false + return + fi + + ventoy_true +} + +check_disk_secure_boot() { + if ! is_disk_contains_ventoy $1; then + ventoy_false + return + fi + + PART2=$(get_disk_part_name $1 2) + + vtoycli fat -s $PART2 +} + +get_disk_ventoy_version() { + + if ! is_disk_contains_ventoy $1; then + ventoy_false + return + fi + + PART2=$(get_disk_part_name $1 2) + + ParseVer=$(vtoycli fat $PART2) + if [ $? -eq 0 ]; then + vtdebug "Ventoy version in $PART2 is $ParseVer" + echo $ParseVer + ventoy_true + return + fi + + ventoy_false +} + +wait_and_create_part() { + vPART1=$1 + vPART2=$2 + echo 'Wait for partitions $vPART1 and $vPART2 ...' + for i in 0 1 2 3 4 5 6 7 8 9; do + if ls -l $vPART1 2>/dev/null | grep -q '^b'; then + if ls -l $vPART2 2>/dev/null | grep -q '^b'; then + break + fi + else + echo "Wait for $vPART1 and $vPART2 ..." + sleep 1 + fi + done + + if ls -l $vPART1 2>/dev/null | grep -q '^b'; then + echo "$vPART1 exist OK" + else + MajorMinor=$(sed "s/:/ /" /sys/class/block/${vPART1#/dev/}/dev) + echo "mknod -m 0660 $vPART1 b $MajorMinor ..." + mknod -m 0660 $vPART1 b $MajorMinor + fi + + if ls -l $vPART2 2>/dev/null | grep -q '^b'; then + echo "$vPART2 exist OK" + else + MajorMinor=$(sed "s/:/ /" /sys/class/block/${vPART2#/dev/}/dev) + echo "mknod -m 0660 $vPART2 b $MajorMinor ..." + mknod -m 0660 $vPART2 b $MajorMinor + fi + + if ls -l $vPART1 2>/dev/null | grep -q '^b'; then + if ls -l $vPART2 2>/dev/null | grep -q '^b'; then + echo "partition exist OK" + fi + else + echo "[FAIL] $vPART1/$vPART2 does not exist" + exit 1 + fi +} + + +format_ventoy_disk_mbr() { + reserve_mb=$1 + DISK=$2 + PARTTOOL=$3 + + PART1=$(get_disk_part_name $DISK 1) + PART2=$(get_disk_part_name $DISK 2) + + sector_num=$(cat /sys/block/${DISK#/dev/}/size) + + part1_start_sector=2048 + + if [ $reserve_mb -gt 0 ]; then + reserve_sector_num=$(expr $reserve_mb \* 2048) + part1_end_sector=$(expr $sector_num - $reserve_sector_num - $VENTOY_SECTOR_NUM - 1) + else + part1_end_sector=$(expr $sector_num - $VENTOY_SECTOR_NUM - 1) + fi + + part2_start_sector=$(expr $part1_end_sector + 1) + + modsector=$(expr $part2_start_sector % 8) + if [ $modsector -gt 0 ]; then + vtdebug "modsector:$modsector need to be aligned with 4KB" + part1_end_sector=$(expr $part1_end_sector - $modsector) + part2_start_sector=$(expr $part1_end_sector + 1) + fi + + part2_end_sector=$(expr $part2_start_sector + $VENTOY_SECTOR_NUM - 1) + + export part2_start_sector + + vtdebug "part1_start_sector=$part1_start_sector part1_end_sector=$part1_end_sector" + vtdebug "part2_start_sector=$part2_start_sector part2_end_sector=$part2_end_sector" + + if [ -e $PART1 ]; then + echo "delete $PART1" + rm -f $PART1 + fi + + if [ -e $PART2 ]; then + echo "delete $PART2" + rm -f $PART2 + fi + + echo "" + echo "Create partitions on $DISK by $PARTTOOL in MBR style ..." + + if [ "$PARTTOOL" = "parted" ]; then + vtdebug "format disk by parted ..." + parted -a none --script $DISK \ + mklabel msdos \ + unit s \ + mkpart primary ntfs $part1_start_sector $part1_end_sector \ + mkpart primary fat16 $part2_start_sector $part2_end_sector \ + set 1 boot on \ + quit + + sync + echo -en '\xEF' | dd of=$DISK conv=fsync bs=1 count=1 seek=466 > /dev/null 2>&1 + else + vtdebug "format disk by fdisk ..." + +fdisk $DISK >>./log.txt 2>&1 </dev/null 2>&1 + partprobe >/dev/null 2>&1 + partx -u $DISK >/dev/null 2>&1 + sleep 3 + echo "Done" + + + echo 'Wait for partitions ...' + for i in 0 1 2 3 4 5 6 7 8 9; do + if [ -b $PART1 -a -b $PART2 ]; then + break + else + echo "Wait for $PART1/$PART2 ..." + sleep 1 + fi + done + + if ! [ -b $PART1 ]; then + MajorMinor=$(sed "s/:/ /" /sys/class/block/${PART1#/dev/}/dev) + echo "mknod -m 0660 $PART1 b $MajorMinor ..." + mknod -m 0660 $PART1 b $MajorMinor + fi + + if ! [ -b $PART2 ]; then + MajorMinor=$(sed "s/:/ /" /sys/class/block/${PART2#/dev/}/dev) + echo "mknod -m 0660 $PART2 b $MajorMinor ..." + mknod -m 0660 $PART2 b $MajorMinor + fi + + if [ -b $PART1 -a -b $PART2 ]; then + echo "partition exist OK" + else + echo "[FAIL] $PART1/$PART2 does not exist" + exit 1 + fi + + echo "create efi fat fs $PART2 ..." + for i in 0 1 2 3 4 5 6 7 8 9; do + check_umount_disk "$PART2" + + if mkfs.vfat -F 16 -n VTOYEFI -s 1 $PART2; then + echo 'success' + break + else + echo "$? retry ..." + sleep 2 + fi + done +} + + +format_ventoy_disk_gpt() { + reserve_mb=$1 + DISK=$2 + PARTTOOL=$3 + + PART1=$(get_disk_part_name $DISK 1) + PART2=$(get_disk_part_name $DISK 2) + + sector_num=$(cat /sys/block/${DISK#/dev/}/size) + + part1_start_sector=2048 + + if [ $reserve_mb -gt 0 ]; then + reserve_sector_num=$(expr $reserve_mb \* 2048 + 33) + part1_end_sector=$(expr $sector_num - $reserve_sector_num - $VENTOY_SECTOR_NUM - 1) + else + part1_end_sector=$(expr $sector_num - $VENTOY_SECTOR_NUM - 34) + fi + + part2_start_sector=$(expr $part1_end_sector + 1) + + modsector=$(expr $part2_start_sector % 8) + if [ $modsector -gt 0 ]; then + vtdebug "modsector:$modsector need to be aligned with 4KB" + part1_end_sector=$(expr $part1_end_sector - $modsector) + part2_start_sector=$(expr $part1_end_sector + 1) + fi + + part2_end_sector=$(expr $part2_start_sector + $VENTOY_SECTOR_NUM - 1) + + export part2_start_sector + + vtdebug "part1_start_sector=$part1_start_sector part1_end_sector=$part1_end_sector" + vtdebug "part2_start_sector=$part2_start_sector part2_end_sector=$part2_end_sector" + + if [ -e $PART1 ]; then + echo "delete $PART1" + rm -f $PART1 + fi + + if [ -e $PART2 ]; then + echo "delete $PART2" + rm -f $PART2 + fi + + echo "" + echo "Create partitions on $DISK by $PARTTOOL in GPT style ..." + + vtdebug "format disk by parted ..." + + if [ "$TOOLDIR" != "aarch64" ]; then + vt_set_efi_type="set 2 msftdata on" + fi + + parted -a none --script $DISK \ + mklabel gpt \ + unit s \ + mkpart Ventoy ntfs $part1_start_sector $part1_end_sector \ + mkpart VTOYEFI fat16 $part2_start_sector $part2_end_sector \ + $vt_set_efi_type \ + quit + + sync + + vtoycli gpt -f $DISK + sync + + udevadm trigger --name-match=$DISK >/dev/null 2>&1 + partprobe >/dev/null 2>&1 + partx -u $DISK >/dev/null 2>&1 + sleep 3 + echo "Done" + + echo 'Wait for partitions ...' + for i in 0 1 2 3 4 5 6 7 8 9; do + if [ -b $PART1 -a -b $PART2 ]; then + break + else + echo "Wait for $PART1/$PART2 ..." + sleep 1 + fi + done + + if ! [ -b $PART1 ]; then + MajorMinor=$(sed "s/:/ /" /sys/class/block/${PART1#/dev/}/dev) + echo "mknod -m 0660 $PART1 b $MajorMinor ..." + mknod -m 0660 $PART1 b $MajorMinor + fi + + if ! [ -b $PART2 ]; then + MajorMinor=$(sed "s/:/ /" /sys/class/block/${PART2#/dev/}/dev) + echo "mknod -m 0660 $PART2 b $MajorMinor ..." + mknod -m 0660 $PART2 b $MajorMinor + fi + + if [ -b $PART1 -a -b $PART2 ]; then + echo "partition exist OK" + else + echo "[FAIL] $PART1/$PART2 does not exist" + exit 1 + fi + + echo "create efi fat fs $PART2 ..." + + for i in 0 1 2 3 4 5 6 7 8 9; do + check_umount_disk "$PART2" + + if mkfs.vfat -F 16 -n VTOYEFI -s 1 $PART2; then + echo 'success' + break + else + echo "$? retry ..." + sleep 2 + fi + done +} + + + + + diff --git a/INSTALL/tool/x86_64/Plugson b/INSTALL/tool/x86_64/Plugson new file mode 100644 index 0000000..0cec4c7 Binary files /dev/null and b/INSTALL/tool/x86_64/Plugson differ diff --git a/INSTALL/tool/x86_64/V2DServer b/INSTALL/tool/x86_64/V2DServer new file mode 100644 index 0000000..aff2c38 Binary files /dev/null and b/INSTALL/tool/x86_64/V2DServer differ diff --git a/INSTALL/tool/x86_64/Ventoy2Disk.gtk2 b/INSTALL/tool/x86_64/Ventoy2Disk.gtk2 new file mode 100644 index 0000000..b9aa513 Binary files /dev/null and b/INSTALL/tool/x86_64/Ventoy2Disk.gtk2 differ diff --git a/INSTALL/tool/x86_64/Ventoy2Disk.gtk3 b/INSTALL/tool/x86_64/Ventoy2Disk.gtk3 new file mode 100644 index 0000000..27c2260 Binary files /dev/null and b/INSTALL/tool/x86_64/Ventoy2Disk.gtk3 differ diff --git a/INSTALL/tool/x86_64/Ventoy2Disk.qt5 b/INSTALL/tool/x86_64/Ventoy2Disk.qt5 new file mode 100644 index 0000000..82dd6e0 Binary files /dev/null and b/INSTALL/tool/x86_64/Ventoy2Disk.qt5 differ diff --git a/INSTALL/tool/x86_64/ash b/INSTALL/tool/x86_64/ash new file mode 100644 index 0000000..a137ff3 Binary files /dev/null and b/INSTALL/tool/x86_64/ash differ diff --git a/INSTALL/tool/x86_64/hexdump b/INSTALL/tool/x86_64/hexdump new file mode 100644 index 0000000..c6ce582 Binary files /dev/null and b/INSTALL/tool/x86_64/hexdump differ diff --git a/INSTALL/tool/x86_64/mkexfatfs b/INSTALL/tool/x86_64/mkexfatfs new file mode 100644 index 0000000..5d8720c Binary files /dev/null and b/INSTALL/tool/x86_64/mkexfatfs differ diff --git a/INSTALL/tool/x86_64/mount.exfat-fuse b/INSTALL/tool/x86_64/mount.exfat-fuse new file mode 100644 index 0000000..8f94524 Binary files /dev/null and b/INSTALL/tool/x86_64/mount.exfat-fuse differ diff --git a/INSTALL/tool/x86_64/vlnk b/INSTALL/tool/x86_64/vlnk new file mode 100644 index 0000000..c25e6b8 Binary files /dev/null and b/INSTALL/tool/x86_64/vlnk differ diff --git a/INSTALL/tool/x86_64/vtoycli b/INSTALL/tool/x86_64/vtoycli new file mode 100644 index 0000000..1e5c1b3 Binary files /dev/null and b/INSTALL/tool/x86_64/vtoycli differ diff --git a/INSTALL/tool/x86_64/xzcat b/INSTALL/tool/x86_64/xzcat new file mode 100644 index 0000000..210f960 Binary files /dev/null and b/INSTALL/tool/x86_64/xzcat differ diff --git a/INSTALL/ventoy/7z/32/7za.xz b/INSTALL/ventoy/7z/32/7za.xz new file mode 100644 index 0000000..927e25a Binary files /dev/null and b/INSTALL/ventoy/7z/32/7za.xz differ diff --git a/INSTALL/ventoy/7z/64/7za.xz b/INSTALL/ventoy/7z/64/7za.xz new file mode 100644 index 0000000..bf52734 Binary files /dev/null and b/INSTALL/ventoy/7z/64/7za.xz differ diff --git a/INSTALL/ventoy/common_bcd.xz b/INSTALL/ventoy/common_bcd.xz new file mode 100644 index 0000000..b81f6c2 Binary files /dev/null and b/INSTALL/ventoy/common_bcd.xz differ diff --git a/INSTALL/ventoy/common_bootmgr.xz b/INSTALL/ventoy/common_bootmgr.xz new file mode 100644 index 0000000..bdaa0ef Binary files /dev/null and b/INSTALL/ventoy/common_bootmgr.xz differ diff --git a/INSTALL/ventoy/dragonfly.mfs.xz b/INSTALL/ventoy/dragonfly.mfs.xz new file mode 100644 index 0000000..c15a006 Binary files /dev/null and b/INSTALL/ventoy/dragonfly.mfs.xz differ diff --git a/INSTALL/ventoy/imdisk/32/imdisk.cpl b/INSTALL/ventoy/imdisk/32/imdisk.cpl new file mode 100644 index 0000000..e59193c Binary files /dev/null and b/INSTALL/ventoy/imdisk/32/imdisk.cpl differ diff --git a/INSTALL/ventoy/imdisk/32/imdisk.exe b/INSTALL/ventoy/imdisk/32/imdisk.exe new file mode 100644 index 0000000..c082730 Binary files /dev/null and b/INSTALL/ventoy/imdisk/32/imdisk.exe differ diff --git a/INSTALL/ventoy/imdisk/32/imdisk.sys b/INSTALL/ventoy/imdisk/32/imdisk.sys new file mode 100644 index 0000000..17b2ac2 Binary files /dev/null and b/INSTALL/ventoy/imdisk/32/imdisk.sys differ diff --git a/INSTALL/ventoy/imdisk/64/imdisk.cpl b/INSTALL/ventoy/imdisk/64/imdisk.cpl new file mode 100644 index 0000000..13f94b2 Binary files /dev/null and b/INSTALL/ventoy/imdisk/64/imdisk.cpl differ diff --git a/INSTALL/ventoy/imdisk/64/imdisk.exe b/INSTALL/ventoy/imdisk/64/imdisk.exe new file mode 100644 index 0000000..19cb383 Binary files /dev/null and b/INSTALL/ventoy/imdisk/64/imdisk.exe differ diff --git a/INSTALL/ventoy/imdisk/64/imdisk.sys b/INSTALL/ventoy/imdisk/64/imdisk.sys new file mode 100644 index 0000000..430229f Binary files /dev/null and b/INSTALL/ventoy/imdisk/64/imdisk.sys differ diff --git a/INSTALL/ventoy/ipxe.krn b/INSTALL/ventoy/ipxe.krn new file mode 100644 index 0000000..7d43c5f Binary files /dev/null and b/INSTALL/ventoy/ipxe.krn differ diff --git a/INSTALL/ventoy/iso9660_aa64.efi b/INSTALL/ventoy/iso9660_aa64.efi new file mode 100644 index 0000000..6d9b803 Binary files /dev/null and b/INSTALL/ventoy/iso9660_aa64.efi differ diff --git a/INSTALL/ventoy/iso9660_ia32.efi b/INSTALL/ventoy/iso9660_ia32.efi new file mode 100644 index 0000000..8123899 Binary files /dev/null and b/INSTALL/ventoy/iso9660_ia32.efi differ diff --git a/INSTALL/ventoy/iso9660_x64.efi b/INSTALL/ventoy/iso9660_x64.efi new file mode 100644 index 0000000..240c33f Binary files /dev/null and b/INSTALL/ventoy/iso9660_x64.efi differ diff --git a/INSTALL/ventoy/memdisk b/INSTALL/ventoy/memdisk new file mode 100644 index 0000000..3ada56c Binary files /dev/null and b/INSTALL/ventoy/memdisk differ diff --git a/INSTALL/ventoy/udf_aa64.efi b/INSTALL/ventoy/udf_aa64.efi new file mode 100644 index 0000000..bed2b01 Binary files /dev/null and b/INSTALL/ventoy/udf_aa64.efi differ diff --git a/INSTALL/ventoy/udf_ia32.efi b/INSTALL/ventoy/udf_ia32.efi new file mode 100644 index 0000000..ba4ed35 Binary files /dev/null and b/INSTALL/ventoy/udf_ia32.efi differ diff --git a/INSTALL/ventoy/udf_x64.efi b/INSTALL/ventoy/udf_x64.efi new file mode 100644 index 0000000..0f327fb Binary files /dev/null and b/INSTALL/ventoy/udf_x64.efi differ diff --git a/INSTALL/ventoy/ventoy.cpio b/INSTALL/ventoy/ventoy.cpio new file mode 100644 index 0000000..5b98223 Binary files /dev/null and b/INSTALL/ventoy/ventoy.cpio differ diff --git a/INSTALL/ventoy/ventoy_aa64.efi b/INSTALL/ventoy/ventoy_aa64.efi new file mode 100644 index 0000000..d359a0a Binary files /dev/null and b/INSTALL/ventoy/ventoy_aa64.efi differ diff --git a/INSTALL/ventoy/ventoy_arm64.cpio b/INSTALL/ventoy/ventoy_arm64.cpio new file mode 100644 index 0000000..b8c6809 Binary files /dev/null and b/INSTALL/ventoy/ventoy_arm64.cpio differ diff --git a/INSTALL/ventoy/ventoy_efiboot.img.xz b/INSTALL/ventoy/ventoy_efiboot.img.xz new file mode 100644 index 0000000..121ef3d Binary files /dev/null and b/INSTALL/ventoy/ventoy_efiboot.img.xz differ diff --git a/INSTALL/ventoy/ventoy_ia32.efi b/INSTALL/ventoy/ventoy_ia32.efi new file mode 100644 index 0000000..b28a9d4 Binary files /dev/null and b/INSTALL/ventoy/ventoy_ia32.efi differ diff --git a/INSTALL/ventoy/ventoy_mips64.cpio b/INSTALL/ventoy/ventoy_mips64.cpio new file mode 100644 index 0000000..4cbeda6 Binary files /dev/null and b/INSTALL/ventoy/ventoy_mips64.cpio differ diff --git a/INSTALL/ventoy/ventoy_unix.cpio b/INSTALL/ventoy/ventoy_unix.cpio new file mode 100644 index 0000000..5432c16 Binary files /dev/null and b/INSTALL/ventoy/ventoy_unix.cpio differ diff --git a/INSTALL/ventoy/ventoy_x64.efi b/INSTALL/ventoy/ventoy_x64.efi new file mode 100644 index 0000000..9126e4a Binary files /dev/null and b/INSTALL/ventoy/ventoy_x64.efi differ diff --git a/INSTALL/ventoy/ventoy_x86.cpio b/INSTALL/ventoy/ventoy_x86.cpio new file mode 100644 index 0000000..61a106b Binary files /dev/null and b/INSTALL/ventoy/ventoy_x86.cpio differ diff --git a/INSTALL/ventoy/vtloopex.cpio b/INSTALL/ventoy/vtloopex.cpio new file mode 100644 index 0000000..ccf0bf8 Binary files /dev/null and b/INSTALL/ventoy/vtloopex.cpio differ diff --git a/INSTALL/ventoy/vtoyjump32.exe b/INSTALL/ventoy/vtoyjump32.exe new file mode 100644 index 0000000..ff94de4 Binary files /dev/null and b/INSTALL/ventoy/vtoyjump32.exe differ diff --git a/INSTALL/ventoy/vtoyjump64.exe b/INSTALL/ventoy/vtoyjump64.exe new file mode 100644 index 0000000..fb6ea27 Binary files /dev/null and b/INSTALL/ventoy/vtoyjump64.exe differ diff --git a/INSTALL/ventoy/vtoyutil_aa64.efi b/INSTALL/ventoy/vtoyutil_aa64.efi new file mode 100644 index 0000000..57387a0 Binary files /dev/null and b/INSTALL/ventoy/vtoyutil_aa64.efi differ diff --git a/INSTALL/ventoy/vtoyutil_ia32.efi b/INSTALL/ventoy/vtoyutil_ia32.efi new file mode 100644 index 0000000..9c76ce1 Binary files /dev/null and b/INSTALL/ventoy/vtoyutil_ia32.efi differ diff --git a/INSTALL/ventoy/vtoyutil_x64.efi b/INSTALL/ventoy/vtoyutil_x64.efi new file mode 100644 index 0000000..eb430dd Binary files /dev/null and b/INSTALL/ventoy/vtoyutil_x64.efi differ diff --git a/INSTALL/ventoy/wimboot.i386.efi.xz b/INSTALL/ventoy/wimboot.i386.efi.xz new file mode 100644 index 0000000..ca8ca6b Binary files /dev/null and b/INSTALL/ventoy/wimboot.i386.efi.xz differ diff --git a/INSTALL/ventoy/wimboot.x86_64.xz b/INSTALL/ventoy/wimboot.x86_64.xz new file mode 100644 index 0000000..66fc556 Binary files /dev/null and b/INSTALL/ventoy/wimboot.x86_64.xz differ diff --git a/INSTALL/ventoy_pack.sh b/INSTALL/ventoy_pack.sh new file mode 100644 index 0000000..850d8f4 --- /dev/null +++ b/INSTALL/ventoy_pack.sh @@ -0,0 +1,381 @@ +#!/bin/sh + +if [ "$VENTOY_CERT_PASS" = "YES" ]; then + read -s -p "Enter cert key passphrase: " KEY_PASS + echo + + if openssl pkey -in "$VENTOY_CERT_KEY" -passin pass:"$KEY_PASS" -out /dev/null > /dev/null 2>&1; then + echo "Password check OK" + else + echo "Incorrect password" + exit 1 + fi +fi + +sign_efi() { + efi=$1 + + if [ ! -f "$efi" ]; then + printf "### %-64s non-exist\n" "$efi" + return + fi + + #Don't sign if VENTOY_CERT_KEY is not defined. + if [ -z "$VENTOY_CERT_KEY" -o -z "$VENTOY_CERT_PEM" ]; then + printf "### %-64s NO-CA\n" "$efi" + return + fi + + if echo $efi | grep -q '\.xz$'; then + xzcat $efi > ${efi}.unxz + mv ${efi}.unxz ${efi} + fi + + rm -f "${efi}.signed" + if [ "$VENTOY_CERT_PASS" = "YES" ]; then + expect -f ./sign_with_pass.exp "$KEY_PASS" "$VENTOY_CERT_KEY" "$VENTOY_CERT_PEM" "${efi}" "${efi}.signed" >/dev/null 2>&1 + else + sbsign --key "$VENTOY_CERT_KEY" --cert "$VENTOY_CERT_PEM" --output "${efi}.signed" "${efi}" >/dev/null 2>&1 + fi + + if [ -f "${efi}.signed" ]; then + if echo $efi | grep -q '\.xz$'; then + xz --check=crc32 "${efi}.signed" + mv "${efi}.signed.xz" "$efi" + rm -f "${efi}.signed" + else + mv "${efi}.signed" "$efi" + fi + else + printf "### %-64s failed\n" "$efi" + exit 1 + fi + + printf "### %-64s success\n" "$efi" +} + +if [ "$1" = "CI" ]; then + OPT='-dR' +else + OPT='-a' +fi + +dos2unix -q ./tool/ventoy_lib.sh +dos2unix -q ./tool/VentoyWorker.sh +dos2unix -q ./tool/VentoyGTK.glade +dos2unix -q ./tool/distro_gui_type.json + +. ./tool/ventoy_lib.sh + +GRUB_DIR=../GRUB2/INSTALL +LANG_DIR=../LANGUAGES + +if ! [ -d $GRUB_DIR ]; then + echo "$GRUB_DIR not exist" + exit 1 +fi + + +cd ../IMG +sh mkcpio.sh +sh mkloopex.sh +cd - + +cd ../Unix +sh pack_unix.sh +cd - + +cd ../LinuxGUI +sh language.sh || exit 1 +sh build.sh +cd - + +cd ../Plugson +sh build.sh +sh pack.sh +cd - + +cd ../Vlnk +sh build.sh +sh pack.sh +cd - + + +LOOP=$(losetup -f) + +rm -f img.bin +dd if=/dev/zero of=img.bin bs=1M count=256 status=none + +losetup -P $LOOP img.bin + +while ! grep -q 524288 /sys/block/${LOOP#/dev/}/size 2>/dev/null; do + echo "wait $LOOP ..." + sleep 1 +done + +format_ventoy_disk_mbr 0 $LOOP fdisk + +$GRUB_DIR/sbin/grub-bios-setup --skip-fs-probe --directory="./grub/i386-pc" $LOOP + +curver=$(get_ventoy_version_from_cfg ./grub/grub.cfg) + +tmpmnt=./ventoy-${curver}-mnt +tmpdir=./ventoy-${curver} + +rm -rf $tmpmnt +mkdir -p $tmpmnt + +mount ${LOOP}p2 $tmpmnt + +mkdir -p $tmpmnt/grub + +# First copy grub.cfg file, to make it locate at front of the part2 +cp $OPT ./grub/grub.cfg $tmpmnt/grub/ + +ls -1 ./grub/ | grep -v 'grub\.cfg' | while read line; do + cp $OPT ./grub/$line $tmpmnt/grub/ +done + +#tar help txt +cd $tmpmnt/grub/ +tar czf help.tar.gz ./help/ +rm -rf ./help +cd ../../ + +#tar menu txt & update menulang.cfg +cd $tmpmnt/grub/ + +vtlangtitle=$(grep VTLANG_LANGUAGE_NAME menu/zh_CN.json | awk -F\" '{print $4}') +echo "menuentry \"zh_CN - $vtlangtitle\" --class=menu_lang_item --class=debug_menu_lang --class=F5tool {" >> menulang.cfg +echo " vt_load_menu_lang zh_CN" >> menulang.cfg +echo "}" >> menulang.cfg + +ls -1 menu/ | grep -v 'zh_CN' | sort | while read vtlang; do + vtlangname=${vtlang%.*} + vtlangtitle=$(grep VTLANG_LANGUAGE_NAME menu/$vtlang | awk -F\" '{print $4}') + echo "menuentry \"$vtlangname - $vtlangtitle\" --class=menu_lang_item --class=debug_menu_lang --class=F5tool {" >> menulang.cfg + echo " vt_load_menu_lang $vtlangname" >> menulang.cfg + echo "}" >> menulang.cfg +done +echo "menuentry \"\$VTLANG_RETURN_PREVIOUS\" --class=vtoyret VTOY_RET {" >> menulang.cfg +echo " echo \"Return ...\"" >> menulang.cfg +echo "}" >> menulang.cfg + +tar czf menu.tar.gz ./menu/ +rm -rf ./menu +cd ../../ + + + +cp $OPT ./ventoy $tmpmnt/ +cp $OPT ./EFI $tmpmnt/ +cp $OPT ./tool/ENROLL_THIS_KEY_IN_MOKMANAGER.cer $tmpmnt/ + + +mkdir -p $tmpmnt/tool +# cp $OPT ./tool/i386/mount.exfat-fuse $tmpmnt/tool/mount.exfat-fuse_i386 +# cp $OPT ./tool/x86_64/mount.exfat-fuse $tmpmnt/tool/mount.exfat-fuse_x86_64 +# cp $OPT ./tool/aarch64/mount.exfat-fuse $tmpmnt/tool/mount.exfat-fuse_aarch64 +# to save space +dd status=none bs=1024 count=16 if=./tool/i386/vtoycli of=$tmpmnt/tool/mount.exfat-fuse_i386 +dd status=none bs=1024 count=16 if=./tool/x86_64/vtoycli of=$tmpmnt/tool/mount.exfat-fuse_x86_64 +dd status=none bs=1024 count=16 if=./tool/aarch64/vtoycli of=$tmpmnt/tool/mount.exfat-fuse_aarch64 +cp -a ./tool/create_ventoy_iso_part_dm.sh $tmpmnt/tool/ + + +rm -f $tmpmnt/grub/i386-pc/*.img + + +sign_efi $tmpmnt/EFI/BOOT/fbia32.efi +sign_efi $tmpmnt/EFI/BOOT/fbaa64.efi +sign_efi $tmpmnt/EFI/BOOT/grubx64_real.efi +sign_efi $tmpmnt/EFI/BOOT/grubia32_real.efi +sign_efi $tmpmnt/ventoy/iso9660_x64.efi +sign_efi $tmpmnt/ventoy/iso9660_ia32.efi +sign_efi $tmpmnt/ventoy/iso9660_aa64.efi +sign_efi $tmpmnt/ventoy/udf_x64.efi +sign_efi $tmpmnt/ventoy/udf_ia32.efi +sign_efi $tmpmnt/ventoy/udf_aa64.efi +sign_efi $tmpmnt/ventoy/ventoy_x64.efi +sign_efi $tmpmnt/ventoy/ventoy_ia32.efi +sign_efi $tmpmnt/ventoy/ventoy_aa64.efi +sign_efi $tmpmnt/ventoy/vtoyutil_x64.efi +sign_efi $tmpmnt/ventoy/vtoyutil_ia32.efi +sign_efi $tmpmnt/ventoy/vtoyutil_aa64.efi +sign_efi $tmpmnt/ventoy/wimboot.i386.efi.xz +sign_efi $tmpmnt/ventoy/wimboot.x86_64.xz + +#inject Ventoy Grub sign sha256 value into VtoyShim +grub_sha256=$(sha256sum $tmpmnt/EFI/BOOT/grubx64_real.efi | awk '{print $1}') +magic_cnt=$(hexdump -C $tmpmnt/EFI/BOOT/fbx64.efi | grep '26 26 26 26 26 26 26 26' | wc -l) +if [ $magic_cnt -ne 1 ]; then + echo "hash magic duplicate" + exit 1 +fi +magic_off_hex=$(hexdump -C $tmpmnt/EFI/BOOT/fbx64.efi | grep '26 26 26 26 26 26 26 26' | awk '{print $1}') +magic_off=$(printf '%u' "0x${magic_off_hex}") + +echo_cmd=$(echo $grub_sha256 | sed 's/\(..\)/\\x\1/g') + +echo Ventoy Grub hash $grub_sha256 +echo -en "$echo_cmd" | dd bs=1 count=32 of=$tmpmnt/EFI/BOOT/fbx64.efi seek=$magic_off conv=notrunc status=none + +sign_efi $tmpmnt/EFI/BOOT/fbx64.efi + + +umount $tmpmnt && rm -rf $tmpmnt + + +rm -rf $tmpdir +mkdir -p $tmpdir/boot +mkdir -p $tmpdir/ventoy +echo $curver > $tmpdir/ventoy/version +dd if=$LOOP of=$tmpdir/boot/boot.img bs=1 count=512 status=none +dd if=$LOOP of=$tmpdir/boot/core.img bs=512 count=2047 skip=1 status=none +xz --check=crc32 $tmpdir/boot/core.img + +cp $OPT ./tool $tmpdir/ +rm -f $tmpdir/ENROLL_THIS_KEY_IN_MOKMANAGER.cer +cp $OPT Ventoy2Disk.sh $tmpdir/ +cp $OPT VentoyWeb.sh $tmpdir/ +cp $OPT VentoyPlugson.sh $tmpdir/ +cp $OPT VentoyVlnk.sh $tmpdir/ +cp $OPT VentoyGUI* $tmpdir/ + + +cp $OPT README $tmpdir/ +cp $OPT plugin $tmpdir/ +cp $OPT CreatePersistentImg.sh $tmpdir/ +cp $OPT ExtendPersistentImg.sh $tmpdir/ +dos2unix -q $tmpdir/Ventoy2Disk.sh +dos2unix -q $tmpdir/VentoyWeb.sh +dos2unix -q $tmpdir/VentoyPlugson.sh +dos2unix -q $tmpdir/VentoyVlnk.sh + + +dos2unix -q $tmpdir/CreatePersistentImg.sh +dos2unix -q $tmpdir/ExtendPersistentImg.sh + +cp $OPT ../LinuxGUI/WebUI $tmpdir/ +sed 's/.*SCRIPT_DEL_THIS \(.*\)/\1/g' -i $tmpdir/WebUI/index.html + +#32MB disk img +dd status=none if=$LOOP of=$tmpdir/ventoy/ventoy.disk.img bs=512 count=$VENTOY_SECTOR_NUM skip=$part2_start_sector + + +#4k image +# echo "make 4K img ..." +# dd status=none if=/dev/zero of=$tmpdir/ventoy/ventoy_4k.disk.img bs=1M count=32 +# mkfs.vfat -F 16 -n VTOYEFI -s 1 -S 4096 $tmpdir/ventoy/ventoy_4k.disk.img +# vDIR1=$(mktemp -d) +# vDIR2=$(mktemp -d) +# mount $tmpdir/ventoy/ventoy.disk.img $vDIR1 +# mount $tmpdir/ventoy/ventoy_4k.disk.img $vDIR2 +# cp -a $vDIR1/* $vDIR2/ +# umount $vDIR1 +# umount $vDIR2 +# rm -rf $vDIR1 $vDIR2 + +# xz --check=crc32 $tmpdir/ventoy/ventoy_4k.disk.img + +xz --check=crc32 $tmpdir/ventoy/ventoy.disk.img + + + +losetup -d $LOOP && rm -f img.bin + +rm -f ventoy-${curver}-linux.tar.gz + + +CurDir=$PWD + +for d in i386 x86_64 aarch64 mips64el; do + cd $tmpdir/tool/$d + for file in $(ls); do + if [ "$file" != "xzcat" ]; then + if echo "$file" | grep -q '^Ventoy2Disk'; then + chmod +x $file + else + xz --check=crc32 $file + fi + fi + done + cd $CurDir +done + +#chmod +find $tmpdir/ -type d -exec chmod 755 "{}" + +find $tmpdir/ -type f -exec chmod 644 "{}" + +chmod +x $tmpdir/Ventoy2Disk.sh +chmod +x $tmpdir/VentoyWeb.sh +chmod +x $tmpdir/VentoyPlugson.sh +chmod +x $tmpdir/VentoyVlnk.sh +chmod +x $tmpdir/VentoyGUI* +chmod +x $tmpdir/tool/*.sh + +for d in i386 x86_64 aarch64 mips64el; do + chmod +x $tmpdir/tool/$d/xzcat + chmod +x $tmpdir/tool/$d/Ventoy2Disk.* +done + + +cp $OPT $LANG_DIR/languages.json $tmpdir/tool/ + + +chmod +x $tmpdir/CreatePersistentImg.sh +chmod +x $tmpdir/ExtendPersistentImg.sh + +tar -czvf ventoy-${curver}-linux.tar.gz $tmpdir + + + +rm -f ventoy-${curver}-windows.zip + +cp $OPT Ventoy2Disk.exe $tmpdir/ +cp $OPT VentoyPlugson.exe $tmpdir/ +cp $OPT VentoyVlnk.exe $tmpdir/ +cp $OPT FOR_X64_ARM.txt $tmpdir/ +mkdir -p $tmpdir/altexe +cp $OPT Ventoy2Disk_*.exe $tmpdir/altexe/ +cp $OPT VentoyPlugson_*.exe $tmpdir/altexe/ + + + +cp $OPT $tmpdir/tool/plugson.tar.xz $tmpdir/ventoy/ +cp $OPT $LANG_DIR/languages.json $tmpdir/ventoy/ +rm -rf $tmpdir/tool +rm -f $tmpdir/*.sh +rm -f $tmpdir/VentoyGUI.* +rm -rf $tmpdir/WebUI +rm -f $tmpdir/README + + +zip -r ventoy-${curver}-windows.zip $tmpdir/ + +rm -rf $tmpdir + +echo "=============== run livecd.sh ===============" +cd ../LiveCDGUI +sh livecd.sh $1 +cd $CurDir + +mv ../LiveCDGUI/ventoy*.iso ./ + +if [ -e ventoy-${curver}-windows.zip ] && [ -e ventoy-${curver}-linux.tar.gz ]; then + + if [ -z "$VENTOY_CERT_KEY" -o -z "$VENTOY_CERT_PEM" ]; then + echo "[warning]: EFI files are not signed and can only boot when Secure Boot is disabled." + echo "[warning]: EFI files are not signed and can only boot when Secure Boot is disabled." + echo "[warning]: EFI files are not signed and can only boot when Secure Boot is disabled." + fi + + echo -e "\n ============= SUCCESS =================\n" +else + echo -e "\n ============= FAILED =================\n" + exit 1 +fi + +rm -f log.txt +rm -f sha256.txt +sha256sum ventoy-${curver}-* > sha256.txt + diff --git a/IPXE/buildipxe.sh b/IPXE/buildipxe.sh new file mode 100644 index 0000000..ce8e789 --- /dev/null +++ b/IPXE/buildipxe.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +rm -rf ipxe-3fe683e + +tar -xf ipxe_org_code/ipxe-3fe683e.tar.bz2 -C ./ + +rm -rf ./ipxe-3fe683e/src/bin +rm -rf ./ipxe-3fe683e/src/drivers + +/bin/cp -a ipxe_mod_code/ipxe-3fe683e ./ + +cd ipxe-3fe683e/src + +echo '========= build IPXE ==========' +sh build.sh + +cd ../../ + diff --git a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/core/runtime.c b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/core/runtime.c new file mode 100644 index 0000000..049f14b --- /dev/null +++ b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/core/runtime.c @@ -0,0 +1,295 @@ +/* + * Copyright (C) 2011 Michael Brown . + * + * 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 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. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +/** @file + * + * Command line and initrd passed to iPXE at runtime + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** Command line physical address + * + * This can be set by the prefix. + */ +uint32_t __bss16 ( cmdline_phys ); +#define cmdline_phys __use_data16 ( cmdline_phys ) + +/** initrd physical address + * + * This can be set by the prefix. + */ +uint32_t __bss16 ( initrd_phys ); +#define initrd_phys __use_data16 ( initrd_phys ) + +/** initrd length + * + * This can be set by the prefix. + */ +uint32_t __bss16 ( initrd_len ); +#define initrd_len __use_data16 ( initrd_len ) + +/** Internal copy of the command line */ +static char *cmdline_copy; + +/** Free command line image */ +static void cmdline_image_free ( struct refcnt *refcnt ) { + struct image *image = container_of ( refcnt, struct image, refcnt ); + + DBGC ( image, "RUNTIME freeing command line\n" ); + free ( cmdline_copy ); +} + +/** Embedded script representing the command line */ +static struct image cmdline_image = { + .refcnt = REF_INIT ( cmdline_image_free ), + .name = "", + .type = &script_image_type, +}; + +/** Colour for debug messages */ +#define colour &cmdline_image + +/** + * Strip unwanted cruft from command line + * + * @v cmdline Command line + * @v cruft Initial substring of cruft to strip + */ +static void cmdline_strip ( char *cmdline, const char *cruft ) { + char *strip; + char *strip_end; + + /* Find unwanted cruft, if present */ + if ( ! ( strip = strstr ( cmdline, cruft ) ) ) + return; + + /* Strip unwanted cruft */ + strip_end = strchr ( strip, ' ' ); + if ( strip_end ) { + *strip_end = '\0'; + DBGC ( colour, "RUNTIME stripping \"%s\"\n", strip ); + strcpy ( strip, ( strip_end + 1 ) ); + } else { + DBGC ( colour, "RUNTIME stripping \"%s\"\n", strip ); + *strip = '\0'; + } +} + +/** + * Initialise command line + * + * @ret rc Return status code + */ +static int cmdline_init ( void ) { + userptr_t cmdline_user; + userptr_t chainaddr; + char *pos1; + char *pos2; + int chainlen; + char *cmdline; + size_t len; + int rc; + + /* Do nothing if no command line was specified */ + if ( ! cmdline_phys ) { + DBGC ( colour, "RUNTIME found no command line\n" ); + return 0; + } + cmdline_user = phys_to_user ( cmdline_phys ); + len = ( strlen_user ( cmdline_user, 0 ) + 1 /* NUL */ ); + + pos1 = strstr((char *)cmdline_user, "mem:"); + if (pos1) + { + pos2 = strstr(pos1, ":size:"); + if (pos2) + { + *pos2 = 0; + chainaddr = phys_to_user(strtoul(pos1 + 4 + 2, NULL, 16)); // skip 0x prefix in hex number + chainlen = (int)strtoul(pos2 + 6, NULL, 10); + *pos2 = ':'; + + g_initrd_addr = (void *)umalloc(chainlen); + g_initrd_len = chainlen; + memcpy_user((userptr_t)g_initrd_addr, 0, chainaddr, 0, chainlen); + } + } + + /* Allocate and copy command line */ + cmdline_copy = malloc ( len ); + if ( ! cmdline_copy ) { + DBGC ( colour, "RUNTIME could not allocate %zd bytes for " + "command line\n", len ); + rc = -ENOMEM; + goto err_alloc_cmdline_copy; + } + + g_cmdline_copy = cmdline_copy; + + cmdline = cmdline_copy; + copy_from_user ( cmdline, cmdline_user, 0, len ); + DBGC ( colour, "RUNTIME found command line \"%s\" at %08x\n", + cmdline, cmdline_phys ); + + /* Mark command line as consumed */ + cmdline_phys = 0; + + /* Strip unwanted cruft from the command line */ + cmdline_strip ( cmdline, "BOOT_IMAGE=" ); + cmdline_strip ( cmdline, "initrd=" ); + while ( isspace ( *cmdline ) ) + cmdline++; + DBGC ( colour, "RUNTIME using command line \"%s\"\n", cmdline ); + + /* Prepare and register image */ + cmdline_image.data = virt_to_user ( cmdline ); + cmdline_image.len = strlen ( cmdline ); + if ( cmdline_image.len ) { + if ( ( rc = register_image ( &cmdline_image ) ) != 0 ) { + DBGC ( colour, "RUNTIME could not register command " + "line: %s\n", strerror ( rc ) ); + goto err_register_image; + } + } + + /* Drop our reference to the image */ + image_put ( &cmdline_image ); + + return 0; + + err_register_image: + image_put ( &cmdline_image ); + err_alloc_cmdline_copy: + return rc; +} + +/** + * Initialise initrd + * + * @ret rc Return status code + */ +static int initrd_init ( void ) { + struct image *image; + int rc; + + /* Do nothing if no initrd was specified */ + if ( ! initrd_phys ) { + DBGC ( colour, "RUNTIME found no initrd\n" ); + return 0; + } + if ( ! initrd_len ) { + DBGC ( colour, "RUNTIME found empty initrd\n" ); + return 0; + } + DBGC ( colour, "RUNTIME found initrd at [%x,%x)\n", + initrd_phys, ( initrd_phys + initrd_len ) ); + + /* Allocate image */ + image = alloc_image ( NULL ); + if ( ! image ) { + DBGC ( colour, "RUNTIME could not allocate image for " + "initrd\n" ); + rc = -ENOMEM; + goto err_alloc_image; + } + if ( ( rc = image_set_name ( image, "" ) ) != 0 ) { + DBGC ( colour, "RUNTIME could not set image name: %s\n", + strerror ( rc ) ); + goto err_set_name; + } + + /* Allocate and copy initrd content */ + image->data = umalloc ( initrd_len ); + if ( ! image->data ) { + DBGC ( colour, "RUNTIME could not allocate %d bytes for " + "initrd\n", initrd_len ); + rc = -ENOMEM; + goto err_umalloc; + } + image->len = initrd_len; + memcpy_user ( image->data, 0, phys_to_user ( initrd_phys ), 0, + initrd_len ); + + /* Mark initrd as consumed */ + initrd_phys = 0; + + /* Register image */ + if ( ( rc = register_image ( image ) ) != 0 ) { + DBGC ( colour, "RUNTIME could not register initrd: %s\n", + strerror ( rc ) ); + goto err_register_image; + } + + /* Drop our reference to the image */ + image_put ( image ); + + return 0; + + err_register_image: + err_umalloc: + err_set_name: + image_put ( image ); + err_alloc_image: + return rc; +} + +/** + * Initialise command line and initrd + * + */ +static void runtime_init ( void ) { + int rc; + + /* Initialise command line */ + if ( ( rc = cmdline_init() ) != 0 ) { + /* No way to report failure */ + return; + } + + /* Initialise initrd */ + if ( ( rc = initrd_init() ) != 0 ) { + /* No way to report failure */ + return; + } +} + +/** Command line and initrd initialisation function */ +struct startup_fn runtime_startup_fn __startup_fn ( STARTUP_NORMAL ) = { + .name = "runtime", + .startup = runtime_init, +}; diff --git a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/core/ventoy_vdisk.c b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/core/ventoy_vdisk.c new file mode 100644 index 0000000..0150ad7 --- /dev/null +++ b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/core/ventoy_vdisk.c @@ -0,0 +1,811 @@ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int g_debug = 0; +int g_hddmode = 0; +int g_bios_disk80 = 0; +char *g_cmdline_copy; +void *g_initrd_addr; +size_t g_initrd_len; +ventoy_chain_head *g_chain; +ventoy_img_chunk *g_chunk; +uint32_t g_img_chunk_num; +ventoy_img_chunk *g_cur_chunk; +uint32_t g_disk_sector_size; +uint8_t *g_os_param_reserved; + + +ventoy_override_chunk *g_override_chunk; +uint32_t g_override_chunk_num; + +ventoy_virt_chunk *g_virt_chunk; +uint32_t g_virt_chunk_num; + +ventoy_sector_flag g_sector_flag[128]; + +#define VENTOY_ISO9660_SECTOR_OVERFLOW 2097152 + +int g_fixup_iso9660_secover_enable = 0; +int g_fixup_iso9660_secover_start = 0; +uint64 g_fixup_iso9660_secover_1st_secs = 0; +uint64 g_fixup_iso9660_secover_cur_secs = 0; +uint64 g_fixup_iso9660_secover_tot_secs = 0; + +static struct int13_disk_address __bss16 ( ventoy_address ); +#define ventoy_address __use_data16 ( ventoy_address ) + +static uint64_t ventoy_remap_lba_hdd(uint64_t lba, uint32_t *count) +{ + uint32_t i; + uint32_t max_sectors; + ventoy_img_chunk *cur; + + if ((NULL == g_cur_chunk) || (lba < g_cur_chunk->img_start_sector) || + (lba > g_cur_chunk->img_end_sector)) + { + g_cur_chunk = NULL; + for (i = 0; i < g_img_chunk_num; i++) + { + cur = g_chunk + i; + if (lba >= cur->img_start_sector && lba <= cur->img_end_sector) + { + g_cur_chunk = cur; + break; + } + } + } + + if (g_cur_chunk) + { + max_sectors = g_cur_chunk->img_end_sector - lba + 1; + if (*count > max_sectors) + { + *count = max_sectors; + } + + return g_cur_chunk->disk_start_sector + (lba - g_cur_chunk->img_start_sector); + } + return lba; +} + +static uint64_t ventoy_remap_lba(uint64_t lba, uint32_t *count) +{ + uint32_t i; + uint32_t max_sectors; + ventoy_img_chunk *cur; + + if ((NULL == g_cur_chunk) || ((lba) < g_cur_chunk->img_start_sector) || ((lba) > g_cur_chunk->img_end_sector)) + { + g_cur_chunk = NULL; + for (i = 0; i < g_img_chunk_num; i++) + { + cur = g_chunk + i; + if (lba >= cur->img_start_sector && lba <= cur->img_end_sector) + { + g_cur_chunk = cur; + break; + } + } + } + + if (g_cur_chunk) + { + max_sectors = g_cur_chunk->img_end_sector - lba + 1; + if (*count > max_sectors) + { + *count = max_sectors; + } + + if (512 == g_disk_sector_size) + { + return g_cur_chunk->disk_start_sector + ((lba - g_cur_chunk->img_start_sector) << 2); + } + return g_cur_chunk->disk_start_sector + (lba - g_cur_chunk->img_start_sector) * 2048 / g_disk_sector_size; + } + return lba; +} + +static int ventoy_vdisk_read_real_hdd(uint64_t lba, unsigned int count, unsigned long buffer) +{ + uint32_t left = 0; + uint32_t readcount = 0; + uint32_t tmpcount = 0; + uint16_t status = 0; + uint64_t curlba = 0; + uint64_t maplba = 0; + unsigned long phyaddr; + + curlba = lba; + left = count; + +#if VTOY_DEBUG + printf("ventoy_vdisk_read_real_hdd: %llu %u\n", lba, count); +#endif + + while (left > 0) + { + readcount = left; + maplba = ventoy_remap_lba_hdd(curlba, &readcount); + + tmpcount = readcount; + + phyaddr = user_to_phys(buffer, 0); + + while (tmpcount > 0) + { + /* Use INT 13, 42 to read the data from real disk */ + ventoy_address.lba = maplba; + ventoy_address.buffer.segment = (uint16_t)(phyaddr >> 4); + ventoy_address.buffer.offset = (uint16_t)(phyaddr & 0x0F); + + if (tmpcount >= 64) /* max sectors per transmit */ + { + ventoy_address.count = 64; + tmpcount -= 64; + maplba += 64; + phyaddr += 32768; + } + else + { + ventoy_address.count = tmpcount; + tmpcount = 0; + } + + __asm__ __volatile__ ( REAL_CODE ( "stc\n\t" + "sti\n\t" + "int $0x13\n\t" + "sti\n\t" /* BIOS bugs */ + "jc 1f\n\t" + "xorw %%ax, %%ax\n\t" + "\n1:\n\t" ) + : "=a" ( status ) + : "a" ( 0x4200 ), "d" ( VENTOY_BIOS_FAKE_DRIVE ), + "S" ( __from_data16 ( &ventoy_address ) ) ); + } + + curlba += readcount; + left -= readcount; + buffer += (readcount * 512); + } + + return 0; +} + +static int ventoy_vdisk_read_real(uint64_t lba, unsigned int count, unsigned long buffer) +{ + uint32_t i = 0; + uint32_t left = 0; + uint32_t readcount = 0; + uint32_t tmpcount = 0; + uint16_t status = 0; + uint64_t curlba = 0; + uint64_t maplba = 0; + uint64_t start = 0; + uint64_t end = 0; + uint64_t override_start = 0; + uint64_t override_end = 0; + unsigned long phyaddr; + unsigned long databuffer = buffer; + uint8_t *override_data; + + curlba = lba; + left = count; + + while (left > 0) + { + readcount = left; + maplba = ventoy_remap_lba(curlba, &readcount); + + if (g_disk_sector_size == 512) + { + tmpcount = (readcount << 2); + } + else + { + tmpcount = (readcount * 2048) / g_disk_sector_size; + } + + phyaddr = user_to_phys(buffer, 0); + + while (tmpcount > 0) + { + /* Use INT 13, 42 to read the data from real disk */ + ventoy_address.lba = maplba; + ventoy_address.buffer.segment = (uint16_t)(phyaddr >> 4); + ventoy_address.buffer.offset = (uint16_t)(phyaddr & 0x0F); + + if (tmpcount >= 64) /* max sectors per transmit */ + { + ventoy_address.count = 64; + tmpcount -= 64; + maplba += 64; + phyaddr += 32768; + } + else + { + ventoy_address.count = tmpcount; + tmpcount = 0; + } + + __asm__ __volatile__ ( REAL_CODE ( "stc\n\t" + "sti\n\t" + "int $0x13\n\t" + "sti\n\t" /* BIOS bugs */ + "jc 1f\n\t" + "xorw %%ax, %%ax\n\t" + "\n1:\n\t" ) + : "=a" ( status ) + : "a" ( 0x4200 ), "d" ( VENTOY_BIOS_FAKE_DRIVE ), + "S" ( __from_data16 ( &ventoy_address ) ) ); + } + + curlba += readcount; + left -= readcount; + buffer += (readcount * 2048); + } + + start = lba * 2048; + if (start > g_chain->real_img_size_in_bytes) + { + goto end; + } + + end = start + count * 2048; + for (i = 0; i < g_override_chunk_num; i++) + { + override_data = g_override_chunk[i].override_data; + override_start = g_override_chunk[i].img_offset; + override_end = override_start + g_override_chunk[i].override_size; + + if (end <= override_start || start >= override_end) + { + continue; + } + + if (start <= override_start) + { + if (end <= override_end) + { + memcpy((char *)databuffer + override_start - start, override_data, end - override_start); + } + else + { + memcpy((char *)databuffer + override_start - start, override_data, override_end - override_start); + } + } + else + { + if (end <= override_end) + { + memcpy((char *)databuffer, override_data + start - override_start, end - start); + } + else + { + memcpy((char *)databuffer, override_data + start - override_start, override_end - start); + } + } + + if (g_fixup_iso9660_secover_enable && (!g_fixup_iso9660_secover_start) && + g_override_chunk[i].override_size == sizeof(ventoy_iso9660_override)) + { + ventoy_iso9660_override *dirent = (ventoy_iso9660_override *)override_data; + if (dirent->first_sector >= VENTOY_ISO9660_SECTOR_OVERFLOW) + { + g_fixup_iso9660_secover_start = 1; + g_fixup_iso9660_secover_cur_secs = 0; + } + } + } + +end: + + return 0; +} + +uint64_t ventoy_fixup_iso9660_sector(uint64_t Lba, uint32_t secNum) +{ + uint32_t i = 0; + + if (g_fixup_iso9660_secover_cur_secs > 0) + { + Lba += VENTOY_ISO9660_SECTOR_OVERFLOW; + g_fixup_iso9660_secover_cur_secs += secNum; + if (g_fixup_iso9660_secover_cur_secs >= g_fixup_iso9660_secover_tot_secs) + { + g_fixup_iso9660_secover_start = 0; + goto end; + } + } + else + { + ventoy_iso9660_override *dirent; + ventoy_override_chunk *pOverride; + + for (i = 0, pOverride = g_override_chunk; i < g_override_chunk_num; i++, pOverride++) + { + dirent = (ventoy_iso9660_override *)pOverride->override_data; + if (Lba == dirent->first_sector) + { + g_fixup_iso9660_secover_start = 0; + goto end; + } + } + + if (g_fixup_iso9660_secover_start) + { + for (i = 0, pOverride = g_override_chunk; i < g_override_chunk_num; i++, pOverride++) + { + dirent = (ventoy_iso9660_override *)pOverride->override_data; + if (Lba + VENTOY_ISO9660_SECTOR_OVERFLOW == dirent->first_sector) + { + g_fixup_iso9660_secover_tot_secs = (dirent->size + 2047) / 2048; + g_fixup_iso9660_secover_cur_secs = secNum; + if (g_fixup_iso9660_secover_cur_secs >= g_fixup_iso9660_secover_tot_secs) + { + g_fixup_iso9660_secover_start = 0; + } + Lba += VENTOY_ISO9660_SECTOR_OVERFLOW; + goto end; + } + } + } + } + +end: + return Lba; +} + +int ventoy_vdisk_read(struct san_device *sandev, uint64_t lba, unsigned int count, unsigned long buffer) +{ + uint32_t i, j; + uint64_t curlba; + uint64_t lastlba = 0; + uint32_t lbacount = 0; + unsigned long lastbuffer; + uint64_t readend; + uint64_t VirtSec; + ventoy_virt_chunk *node; + ventoy_sector_flag *cur_flag; + ventoy_sector_flag *sector_flag = g_sector_flag; + struct i386_all_regs *ix86; + + if (INT13_EXTENDED_READ != sandev->int13_command) + { + DBGC(sandev, "invalid cmd %u\n", sandev->int13_command); + return 0; + } + + ix86 = (struct i386_all_regs *)sandev->x86_regptr; + + if (g_hddmode) + { + #if 0 + /* need to check ?? */ + lastlba = g_chain->virt_img_size_in_bytes / 512; + if (lba < lastlba) + { + if (lba + count > lastlba) + { + count = lastlba - lba; + } + ventoy_vdisk_read_real_hdd(lba, count, buffer); + } + #endif + + ventoy_vdisk_read_real_hdd(lba, count, buffer); + ix86->regs.dl = sandev->drive; + return 0; + } + + /* Workaround for SSTR PE loader error */ + if (g_fixup_iso9660_secover_start) + { + lba = ventoy_fixup_iso9660_sector(lba, count); + } + + readend = (lba + count) * 2048; + if (readend <= g_chain->real_img_size_in_bytes) + { + ventoy_vdisk_read_real(lba, count, buffer); + ix86->regs.dl = sandev->drive; + return 0; + } + else if ((lba * 2048) < g_chain->real_img_size_in_bytes) + { + /* fix for grub4dos Inconsistent data read from error */ + memset((void *)(buffer + (count - 1) * 2048), 0, 2048); + + count = (g_chain->real_img_size_in_bytes / 2048) - lba; + ventoy_vdisk_read_real(lba, count, buffer); + ix86->regs.dl = sandev->drive; + + lba += count; + buffer += count * 2048; + count = (readend - g_chain->real_img_size_in_bytes) / 2048; + } + + VirtSec = g_chain->virt_img_size_in_bytes / 2048; + if (lba >= VirtSec) + { + /* fix for grub4dos Inconsistent data read from error */ + memset((void *)(buffer + (count - 1) * 2048), 0, 2048); + + ix86->regs.dl = sandev->drive; + return 0; + } + else if (lba + count > VirtSec) + { + count = VirtSec - lba; + } + + if (count > sizeof(g_sector_flag)) + { + sector_flag = (ventoy_sector_flag *)malloc(count * sizeof(ventoy_sector_flag)); + } + + for (curlba = lba, cur_flag = sector_flag, j = 0; j < count; j++, curlba++, cur_flag++) + { + cur_flag->flag = 0; + for (node = g_virt_chunk, i = 0; i < g_virt_chunk_num; i++, node++) + { + if (curlba >= node->mem_sector_start && curlba < node->mem_sector_end) + { + memcpy((void *)(buffer + j * 2048), + (char *)g_virt_chunk + node->mem_sector_offset + (curlba - node->mem_sector_start) * 2048, + 2048); + cur_flag->flag = 1; + break; + } + else if (curlba >= node->remap_sector_start && curlba < node->remap_sector_end) + { + cur_flag->remap_lba = node->org_sector_start + curlba - node->remap_sector_start; + cur_flag->flag = 2; + break; + } + } + } + + for (curlba = lba, cur_flag = sector_flag, j = 0; j < count; j++, curlba++, cur_flag++) + { + if (cur_flag->flag == 2) + { + if (lastlba == 0) + { + lastbuffer = buffer + j * 2048; + lastlba = cur_flag->remap_lba; + lbacount = 1; + } + else if (lastlba + lbacount == cur_flag->remap_lba) + { + lbacount++; + } + else + { + ventoy_vdisk_read_real(lastlba, lbacount, lastbuffer); + lastbuffer = buffer + j * 2048; + lastlba = cur_flag->remap_lba; + lbacount = 1; + } + } + } + + if (lbacount > 0) + { + ventoy_vdisk_read_real(lastlba, lbacount, lastbuffer); + } + + if (sector_flag != g_sector_flag) + { + free(sector_flag); + } + + ix86->regs.dl = sandev->drive; + return 0; +} + +static void ventoy_dump_img_chunk(ventoy_chain_head *chain) +{ + uint32_t i; + ventoy_img_chunk *chunk; + + chunk = (ventoy_img_chunk *)((char *)chain + chain->img_chunk_offset); + + printf("##################### ventoy_dump_img_chunk #######################\n"); + + for (i = 0; i < chain->img_chunk_num; i++) + { + printf("%2u: [ %u - %u ] <==> [ %llu - %llu ]\n", + i, chunk[i].img_start_sector, chunk[i].img_end_sector, + chunk[i].disk_start_sector, chunk[i].disk_end_sector); + } + + ventoy_debug_pause(); +} + +static void ventoy_dump_override_chunk(ventoy_chain_head *chain) +{ + uint32_t i; + ventoy_override_chunk *chunk; + + chunk = (ventoy_override_chunk *)((char *)chain + chain->override_chunk_offset); + + printf("##################### ventoy_dump_override_chunk #######################\n"); + + for (i = 0; i < g_override_chunk_num; i++) + { + printf("%2u: [ %llu, %u ]\n", i, chunk[i].img_offset, chunk[i].override_size); + } + + ventoy_debug_pause(); +} + +static void ventoy_dump_virt_chunk(ventoy_chain_head *chain) +{ + uint32_t i; + ventoy_virt_chunk *node; + + printf("##################### ventoy_dump_virt_chunk #######################\n"); + printf("virt_chunk_offset=%u\n", chain->virt_chunk_offset); + printf("virt_chunk_num=%u\n", chain->virt_chunk_num); + + node = (ventoy_virt_chunk *)((char *)chain + chain->virt_chunk_offset); + for (i = 0; i < chain->virt_chunk_num; i++, node++) + { + printf("%2u: mem:[ %u, %u, %u ] remap:[ %u, %u, %u ]\n", i, + node->mem_sector_start, + node->mem_sector_end, + node->mem_sector_offset, + node->remap_sector_start, + node->remap_sector_end, + node->org_sector_start); + } + + ventoy_debug_pause(); +} + +static void ventoy_dump_chain(ventoy_chain_head *chain) +{ + uint32_t i = 0; + uint8_t chksum = 0; + uint8_t *guid; + uint8_t *sig; + uint8_t *vtoy_reserve; + + guid = chain->os_param.vtoy_disk_guid; + sig = chain->os_param.vtoy_disk_signature; + + for (i = 0; i < sizeof(ventoy_os_param); i++) + { + chksum += *((uint8_t *)(&(chain->os_param)) + i); + } + + vtoy_reserve = (uint8_t *)(chain->os_param.vtoy_reserved); + + printf("##################### ventoy_dump_chain #######################\n"); + + printf("os_param will be save at %p\n", ventoy_get_runtime_addr()); + + printf("os_param->chksum=0x%x (%s)\n", chain->os_param.chksum, chksum ? "FAILED" : "SUCCESS"); + printf("os_param->vtoy_disk_guid=%02x%02x%02x%02x\n", guid[0], guid[1], guid[2], guid[3]); + printf("os_param->vtoy_disk_signature=%02x%02x%02x%02x\n", sig[0], sig[1], sig[2], sig[3]); + printf("os_param->vtoy_disk_size=%llu\n", chain->os_param.vtoy_disk_size); + printf("os_param->vtoy_disk_part_id=%u\n", chain->os_param.vtoy_disk_part_id); + printf("os_param->vtoy_disk_part_type=%u\n", chain->os_param.vtoy_disk_part_type); + printf("os_param->vtoy_img_path=<%s>\n", chain->os_param.vtoy_img_path); + printf("os_param->vtoy_img_size=<%llu>\n", chain->os_param.vtoy_img_size); + printf("os_param->vtoy_reserve[ ]=<%u %u %u %u %u %u %u>\n", + vtoy_reserve[0], vtoy_reserve[1], vtoy_reserve[2], vtoy_reserve[3], + vtoy_reserve[4], vtoy_reserve[5], vtoy_reserve[6]); + printf("os_param->vtoy_img_location_addr=<0x%llx>\n", chain->os_param.vtoy_img_location_addr); + printf("os_param->vtoy_img_location_len=<%u>\n", chain->os_param.vtoy_img_location_len); + ventoy_debug_pause(); + + printf("chain->disk_drive=0x%x\n", chain->disk_drive); + printf("chain->drive_map=0x%x\n", chain->drive_map); + printf("chain->disk_sector_size=%u\n", chain->disk_sector_size); + printf("chain->real_img_size_in_bytes=%llu\n", chain->real_img_size_in_bytes); + printf("chain->virt_img_size_in_bytes=%llu\n", chain->virt_img_size_in_bytes); + printf("chain->boot_catalog=%u\n", chain->boot_catalog); + printf("chain->img_chunk_offset=%u\n", chain->img_chunk_offset); + printf("chain->img_chunk_num=%u\n", chain->img_chunk_num); + printf("chain->override_chunk_offset=%u\n", chain->override_chunk_offset); + printf("chain->override_chunk_num=%u\n", chain->override_chunk_num); + printf("chain->virt_chunk_offset=%u\n", chain->virt_chunk_offset); + printf("chain->virt_chunk_num=%u\n", chain->virt_chunk_num); + ventoy_debug_pause(); + + ventoy_dump_img_chunk(chain); + ventoy_dump_override_chunk(chain); + ventoy_dump_virt_chunk(chain); +} + +static int ventoy_update_image_location(ventoy_os_param *param) +{ + uint8_t chksum = 0; + unsigned int i; + unsigned int length; + userptr_t address = 0; + ventoy_image_location *location = NULL; + ventoy_image_disk_region *region = NULL; + ventoy_img_chunk *chunk = g_chunk; + + length = sizeof(ventoy_image_location) + (g_img_chunk_num - 1) * sizeof(ventoy_image_disk_region); + + address = umalloc(length + 4096 * 2); + if (!address) + { + return 0; + } + + if (address % 4096) + { + address += 4096 - (address % 4096); + } + + param->chksum = 0; + param->vtoy_img_location_addr = user_to_phys(address, 0); + param->vtoy_img_location_len = length; + + /* update check sum */ + for (i = 0; i < sizeof(ventoy_os_param); i++) + { + chksum += *((uint8_t *)param + i); + } + param->chksum = (chksum == 0) ? 0 : (uint8_t)(0x100 - chksum); + + location = (ventoy_image_location *)(unsigned long)(address); + if (NULL == location) + { + return 0; + } + + memcpy(&location->guid, ¶m->guid, sizeof(ventoy_guid)); + location->image_sector_size = g_hddmode ? 512 : 2048; + location->disk_sector_size = g_chain->disk_sector_size; + location->region_count = g_img_chunk_num; + + region = location->regions; + + if (g_hddmode) + { + for (i = 0; i < g_img_chunk_num; i++) + { + region->image_sector_count = chunk->disk_end_sector - chunk->disk_start_sector + 1; + region->image_start_sector = chunk->img_start_sector * 4; + region->disk_start_sector = chunk->disk_start_sector; + region++; + chunk++; + } + } + else + { + for (i = 0; i < g_img_chunk_num; i++) + { + region->image_sector_count = chunk->img_end_sector - chunk->img_start_sector + 1; + region->image_start_sector = chunk->img_start_sector; + region->disk_start_sector = chunk->disk_start_sector; + region++; + chunk++; + } + } + + return 0; +} + +int ventoy_boot_vdisk(void *data) +{ + uint8_t chksum = 0; + unsigned int i; + unsigned int drive; + ventoy_img_chunk *cur; + + (void)data; + + ventoy_address.bufsize = offsetof ( typeof ( ventoy_address ), buffer_phys ); + + if (strstr(g_cmdline_copy, "debug")) + { + g_debug = 1; + printf("### ventoy chain boot begin... ###\n"); + printf("cmdline: <%s>\n", g_cmdline_copy); + ventoy_debug_pause(); + } + + if (strstr(g_cmdline_copy, "sector512")) + { + g_hddmode = 1; + } + + if (strstr(g_cmdline_copy, "bios80")) + { + g_bios_disk80 = 1; + } + + g_chain = (ventoy_chain_head *)g_initrd_addr; + g_chunk = (ventoy_img_chunk *)((char *)g_chain + g_chain->img_chunk_offset); + g_img_chunk_num = g_chain->img_chunk_num; + g_disk_sector_size = g_chain->disk_sector_size; + g_cur_chunk = g_chunk; + + g_os_param_reserved = (uint8_t *)(g_chain->os_param.vtoy_reserved); + + /* Workaround for Windows & ISO9660 */ + if (g_os_param_reserved[2] == ventoy_chain_windows && g_os_param_reserved[3] == 0) + { + g_fixup_iso9660_secover_enable = 1; + } + + g_override_chunk = (ventoy_override_chunk *)((char *)g_chain + g_chain->override_chunk_offset); + g_override_chunk_num = g_chain->override_chunk_num; + + g_virt_chunk = (ventoy_virt_chunk *)((char *)g_chain + g_chain->virt_chunk_offset); + g_virt_chunk_num = g_chain->virt_chunk_num; + + if (g_debug) + { + for (i = 0; i < sizeof(ventoy_os_param); i++) + { + chksum += *((uint8_t *)(&(g_chain->os_param)) + i); + } + printf("os param checksum: 0x%x %s\n", g_chain->os_param.chksum, chksum ? "FAILED" : "SUCCESS"); + } + + ventoy_update_image_location(&(g_chain->os_param)); + + if (g_debug) + { + ventoy_dump_chain(g_chain); + } + + if (g_hddmode) + { + for (i = 0; i < g_img_chunk_num; i++) + { + cur = g_chunk + i; + cur->img_start_sector *= 4; + cur->img_end_sector = cur->img_end_sector * 4 + 3; + } + } + + drive = ventoy_int13_hook(g_chain); + + if (g_debug) + { + printf("### ventoy chain boot before boot image ... ###\n"); + ventoy_debug_pause(); + } + + ventoy_int13_boot(drive, &(g_chain->os_param), g_cmdline_copy); + + if (g_debug) + { + printf("!!!!!!!!!! ventoy boot failed !!!!!!!!!!\n"); + ventoy_debug_pause(); + } + + return 0; +} + diff --git a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/drivers/hyperv/hyperv.c b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/drivers/hyperv/hyperv.c new file mode 100644 index 0000000..01e13c3 --- /dev/null +++ b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/drivers/hyperv/hyperv.c @@ -0,0 +1,820 @@ +/* + * Copyright (C) 2014 Michael Brown . + * + * 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. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +/** @file + * + * Hyper-V driver + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hyperv.h" + +/** Maximum time to wait for a message response + * + * This is a policy decision. + */ +#define HV_MESSAGE_MAX_WAIT_MS 1000 + +/** Hyper-V timer frequency (fixed 10Mhz) */ +#define HV_TIMER_HZ 10000000 + +/** Hyper-V timer scale factor (used to avoid 64-bit division) */ +#define HV_TIMER_SHIFT 18 + +/** + * Convert a Hyper-V status code to an iPXE status code + * + * @v status Hyper-V status code + * @ret rc iPXE status code (before negation) + */ +#define EHV( status ) EPLATFORM ( EINFO_EPLATFORM, (status) ) + +/** + * Allocate zeroed pages + * + * @v hv Hyper-V hypervisor + * @v ... Page addresses to fill in, terminated by NULL + * @ret rc Return status code + */ +__attribute__ (( sentinel )) int +hv_alloc_pages ( struct hv_hypervisor *hv, ... ) { + va_list args; + void **page; + int i; + + /* Allocate and zero pages */ + va_start ( args, hv ); + for ( i = 0 ; ( ( page = va_arg ( args, void ** ) ) != NULL ); i++ ) { + *page = malloc_dma ( PAGE_SIZE, PAGE_SIZE ); + if ( ! *page ) + goto err_alloc; + memset ( *page, 0, PAGE_SIZE ); + } + va_end ( args ); + + return 0; + + err_alloc: + va_end ( args ); + va_start ( args, hv ); + for ( ; i >= 0 ; i-- ) { + page = va_arg ( args, void ** ); + free_dma ( *page, PAGE_SIZE ); + } + va_end ( args ); + return -ENOMEM; +} + +/** + * Free pages + * + * @v hv Hyper-V hypervisor + * @v ... Page addresses, terminated by NULL + */ +__attribute__ (( sentinel )) void +hv_free_pages ( struct hv_hypervisor *hv, ... ) { + va_list args; + void *page; + + va_start ( args, hv ); + while ( ( page = va_arg ( args, void * ) ) != NULL ) + free_dma ( page, PAGE_SIZE ); + va_end ( args ); +} + +/** + * Allocate message buffer + * + * @v hv Hyper-V hypervisor + * @ret rc Return status code + */ +static int hv_alloc_message ( struct hv_hypervisor *hv ) { + + /* Allocate buffer. Must be aligned to at least 8 bytes and + * must not cross a page boundary, so align on its own size. + */ + hv->message = malloc_dma ( sizeof ( *hv->message ), + sizeof ( *hv->message ) ); + if ( ! hv->message ) + return -ENOMEM; + + return 0; +} + +/** + * Free message buffer + * + * @v hv Hyper-V hypervisor + */ +static void hv_free_message ( struct hv_hypervisor *hv ) { + + /* Free buffer */ + free_dma ( hv->message, sizeof ( *hv->message ) ); +} + +/** + * Check whether or not we are running in Hyper-V + * + * @ret rc Return status code + */ +static int hv_check_hv ( void ) { + struct x86_features features; + uint32_t interface_id; + uint32_t discard_ebx; + uint32_t discard_ecx; + uint32_t discard_edx; + + /* Check for presence of a hypervisor (not necessarily Hyper-V) */ + x86_features ( &features ); + if ( ! ( features.intel.ecx & CPUID_FEATURES_INTEL_ECX_HYPERVISOR ) ) { + DBGC ( HV_INTERFACE_ID, "HV not running in a hypervisor\n" ); + return -ENODEV; + } + + /* Check that hypervisor is Hyper-V */ + cpuid ( HV_CPUID_INTERFACE_ID, 0, &interface_id, &discard_ebx, + &discard_ecx, &discard_edx ); + if ( interface_id != HV_INTERFACE_ID ) { + DBGC ( HV_INTERFACE_ID, "HV not running in Hyper-V (interface " + "ID %#08x)\n", interface_id ); + return -ENODEV; + } + + return 0; +} + +/** + * Check required features + * + * @v hv Hyper-V hypervisor + * @ret rc Return status code + */ +static int hv_check_features ( struct hv_hypervisor *hv ) { + uint32_t available; + uint32_t permissions; + uint32_t discard_ecx; + uint32_t discard_edx; + + /* Check that required features and privileges are available */ + cpuid ( HV_CPUID_FEATURES, 0, &available, &permissions, &discard_ecx, + &discard_edx ); + if ( ! ( available & HV_FEATURES_AVAIL_HYPERCALL_MSR ) ) { + DBGC ( hv, "HV %p has no hypercall MSRs (features %08x:%08x)\n", + hv, available, permissions ); + return -ENODEV; + } + if ( ! ( available & HV_FEATURES_AVAIL_SYNIC_MSR ) ) { + DBGC ( hv, "HV %p has no SynIC MSRs (features %08x:%08x)\n", + hv, available, permissions ); + return -ENODEV; + } + if ( ! ( permissions & HV_FEATURES_PERM_POST_MESSAGES ) ) { + DBGC ( hv, "HV %p cannot post messages (features %08x:%08x)\n", + hv, available, permissions ); + return -EACCES; + } + if ( ! ( permissions & HV_FEATURES_PERM_SIGNAL_EVENTS ) ) { + DBGC ( hv, "HV %p cannot signal events (features %08x:%08x)", + hv, available, permissions ); + return -EACCES; + } + + return 0; +} + +/** + * Check that Gen 2 UEFI firmware is not running + * + * @v hv Hyper-V hypervisor + * @ret rc Return status code + * + * We must not steal ownership from the Gen 2 UEFI firmware, since + * doing so will cause an immediate crash. Avoid this by checking for + * the guest OS identity known to be used by the Gen 2 UEFI firmware. + */ +static int hv_check_uefi ( struct hv_hypervisor *hv ) { + uint64_t guest_os_id; + + /* Check for UEFI firmware's guest OS identity */ + guest_os_id = rdmsr ( HV_X64_MSR_GUEST_OS_ID ); + if ( guest_os_id == HV_GUEST_OS_ID_UEFI ) { + DBGC ( hv, "HV %p is owned by UEFI firmware\n", hv ); + return -ENOTSUP; + } + + return 0; +} + +/** + * Map hypercall page + * + * @v hv Hyper-V hypervisor + */ +static void hv_map_hypercall ( struct hv_hypervisor *hv ) { + union { + struct { + uint32_t ebx; + uint32_t ecx; + uint32_t edx; + } __attribute__ (( packed )); + char text[ 13 /* "bbbbccccdddd" + NUL */ ]; + } vendor_id; + uint32_t build; + uint32_t version; + uint32_t discard_eax; + uint32_t discard_ecx; + uint32_t discard_edx; + uint64_t guest_os_id; + uint64_t hypercall; + + /* Report guest OS identity */ + guest_os_id = rdmsr ( HV_X64_MSR_GUEST_OS_ID ); + if ( guest_os_id != 0 ) { + DBGC ( hv, "HV %p guest OS ID MSR was %#08llx\n", + hv, guest_os_id ); + } + guest_os_id = HV_GUEST_OS_ID_IPXE; + DBGC2 ( hv, "HV %p guest OS ID MSR is %#08llx\n", hv, guest_os_id ); + wrmsr ( HV_X64_MSR_GUEST_OS_ID, guest_os_id ); + + /* Get hypervisor system identity (for debugging) */ + cpuid ( HV_CPUID_VENDOR_ID, 0, &discard_eax, &vendor_id.ebx, + &vendor_id.ecx, &vendor_id.edx ); + vendor_id.text[ sizeof ( vendor_id.text ) - 1 ] = '\0'; + cpuid ( HV_CPUID_HYPERVISOR_ID, 0, &build, &version, &discard_ecx, + &discard_edx ); + DBGC ( hv, "HV %p detected \"%s\" version %d.%d build %d\n", hv, + vendor_id.text, ( version >> 16 ), ( version & 0xffff ), build ); + + /* Map hypercall page */ + hypercall = rdmsr ( HV_X64_MSR_HYPERCALL ); + hypercall &= ( PAGE_SIZE - 1 ); + hypercall |= ( virt_to_phys ( hv->hypercall ) | HV_HYPERCALL_ENABLE ); + DBGC2 ( hv, "HV %p hypercall MSR is %#08llx\n", hv, hypercall ); + wrmsr ( HV_X64_MSR_HYPERCALL, hypercall ); +} + +/** + * Unmap hypercall page + * + * @v hv Hyper-V hypervisor + */ +static void hv_unmap_hypercall ( struct hv_hypervisor *hv ) { + uint64_t hypercall; + uint64_t guest_os_id; + + /* Unmap the hypercall page */ + hypercall = rdmsr ( HV_X64_MSR_HYPERCALL ); + hypercall &= ( ( PAGE_SIZE - 1 ) & ~HV_HYPERCALL_ENABLE ); + DBGC2 ( hv, "HV %p hypercall MSR is %#08llx\n", hv, hypercall ); + wrmsr ( HV_X64_MSR_HYPERCALL, hypercall ); + + /* Reset the guest OS identity */ + guest_os_id = 0; + DBGC2 ( hv, "HV %p guest OS ID MSR is %#08llx\n", hv, guest_os_id ); + wrmsr ( HV_X64_MSR_GUEST_OS_ID, guest_os_id ); +} + +/** + * Map synthetic interrupt controller + * + * @v hv Hyper-V hypervisor + */ +static void hv_map_synic ( struct hv_hypervisor *hv ) { + uint64_t simp; + uint64_t siefp; + uint64_t scontrol; + + /* Zero SynIC message and event pages */ + memset ( hv->synic.message, 0, PAGE_SIZE ); + memset ( hv->synic.event, 0, PAGE_SIZE ); + + /* Map SynIC message page */ + simp = rdmsr ( HV_X64_MSR_SIMP ); + simp &= ( PAGE_SIZE - 1 ); + simp |= ( virt_to_phys ( hv->synic.message ) | HV_SIMP_ENABLE ); + DBGC2 ( hv, "HV %p SIMP MSR is %#08llx\n", hv, simp ); + wrmsr ( HV_X64_MSR_SIMP, simp ); + + /* Map SynIC event page */ + siefp = rdmsr ( HV_X64_MSR_SIEFP ); + siefp &= ( PAGE_SIZE - 1 ); + siefp |= ( virt_to_phys ( hv->synic.event ) | HV_SIEFP_ENABLE ); + DBGC2 ( hv, "HV %p SIEFP MSR is %#08llx\n", hv, siefp ); + wrmsr ( HV_X64_MSR_SIEFP, siefp ); + + /* Enable SynIC */ + scontrol = rdmsr ( HV_X64_MSR_SCONTROL ); + scontrol |= HV_SCONTROL_ENABLE; + DBGC2 ( hv, "HV %p SCONTROL MSR is %#08llx\n", hv, scontrol ); + wrmsr ( HV_X64_MSR_SCONTROL, scontrol ); +} + +/** + * Unmap synthetic interrupt controller, leaving SCONTROL untouched + * + * @v hv Hyper-V hypervisor + */ +static void hv_unmap_synic_no_scontrol ( struct hv_hypervisor *hv ) { + uint64_t siefp; + uint64_t simp; + + /* Unmap SynIC event page */ + siefp = rdmsr ( HV_X64_MSR_SIEFP ); + siefp &= ( ( PAGE_SIZE - 1 ) & ~HV_SIEFP_ENABLE ); + DBGC2 ( hv, "HV %p SIEFP MSR is %#08llx\n", hv, siefp ); + wrmsr ( HV_X64_MSR_SIEFP, siefp ); + + /* Unmap SynIC message page */ + simp = rdmsr ( HV_X64_MSR_SIMP ); + simp &= ( ( PAGE_SIZE - 1 ) & ~HV_SIMP_ENABLE ); + DBGC2 ( hv, "HV %p SIMP MSR is %#08llx\n", hv, simp ); + wrmsr ( HV_X64_MSR_SIMP, simp ); +} + +/** + * Unmap synthetic interrupt controller + * + * @v hv Hyper-V hypervisor + */ +static void hv_unmap_synic ( struct hv_hypervisor *hv ) { + uint64_t scontrol; + + /* Disable SynIC */ + scontrol = rdmsr ( HV_X64_MSR_SCONTROL ); + scontrol &= ~HV_SCONTROL_ENABLE; + DBGC2 ( hv, "HV %p SCONTROL MSR is %#08llx\n", hv, scontrol ); + wrmsr ( HV_X64_MSR_SCONTROL, scontrol ); + + /* Unmap SynIC event and message pages */ + hv_unmap_synic_no_scontrol ( hv ); +} + +/** + * Enable synthetic interrupt + * + * @v hv Hyper-V hypervisor + * @v sintx Synthetic interrupt number + */ +void hv_enable_sint ( struct hv_hypervisor *hv, unsigned int sintx ) { + unsigned long msr = HV_X64_MSR_SINT ( sintx ); + uint64_t sint; + + /* Enable synthetic interrupt + * + * We have to enable the interrupt, otherwise messages will + * not be delivered (even though the documentation implies + * that polling for messages is possible). We enable AutoEOI + * and hook the interrupt to the obsolete IRQ13 (FPU + * exception) vector, which will be implemented as a no-op. + */ + sint = rdmsr ( msr ); + sint &= ~( HV_SINT_MASKED | HV_SINT_VECTOR_MASK ); + sint |= ( HV_SINT_AUTO_EOI | + HV_SINT_VECTOR ( IRQ_INT ( 13 /* See comment above */ ) ) ); + DBGC2 ( hv, "HV %p SINT%d MSR is %#08llx\n", hv, sintx, sint ); + wrmsr ( msr, sint ); +} + +/** + * Disable synthetic interrupt + * + * @v hv Hyper-V hypervisor + * @v sintx Synthetic interrupt number + */ +void hv_disable_sint ( struct hv_hypervisor *hv, unsigned int sintx ) { + unsigned long msr = HV_X64_MSR_SINT ( sintx ); + uint64_t sint; + + /* Do nothing if interrupt is already disabled */ + sint = rdmsr ( msr ); + if ( sint & HV_SINT_MASKED ) + return; + + /* Disable synthetic interrupt */ + sint &= ~HV_SINT_AUTO_EOI; + sint |= HV_SINT_MASKED; + DBGC2 ( hv, "HV %p SINT%d MSR is %#08llx\n", hv, sintx, sint ); + wrmsr ( msr, sint ); +} + +/** + * Post message + * + * @v hv Hyper-V hypervisor + * @v id Connection ID + * @v type Message type + * @v data Message + * @v len Length of message + * @ret rc Return status code + */ +int hv_post_message ( struct hv_hypervisor *hv, unsigned int id, + unsigned int type, const void *data, size_t len ) { + struct hv_post_message *msg = &hv->message->posted; + int status; + int rc; + + /* Sanity check */ + assert ( len <= sizeof ( msg->data ) ); + + /* Construct message */ + memset ( msg, 0, sizeof ( *msg ) ); + msg->id = cpu_to_le32 ( id ); + msg->type = cpu_to_le32 ( type ); + msg->len = cpu_to_le32 ( len ); + memcpy ( msg->data, data, len ); + DBGC2 ( hv, "HV %p connection %d posting message type %#08x:\n", + hv, id, type ); + DBGC2_HDA ( hv, 0, msg->data, len ); + + /* Post message */ + if ( ( status = hv_call ( hv, HV_POST_MESSAGE, msg, NULL ) ) != 0 ) { + rc = -EHV ( status ); + DBGC ( hv, "HV %p could not post message to %#08x: %s\n", + hv, id, strerror ( rc ) ); + return rc; + } + + return 0; +} + +/** + * Wait for received message + * + * @v hv Hyper-V hypervisor + * @v sintx Synthetic interrupt number + * @ret rc Return status code + */ +int hv_wait_for_message ( struct hv_hypervisor *hv, unsigned int sintx ) { + struct hv_message *msg = &hv->message->received; + struct hv_message *src = &hv->synic.message[sintx]; + unsigned int retries; + size_t len; + + /* Wait for message to arrive */ + for ( retries = 0 ; retries < HV_MESSAGE_MAX_WAIT_MS ; retries++ ) { + + /* Check for message */ + if ( src->type ) { + + /* Copy message */ + memset ( msg, 0, sizeof ( *msg ) ); + len = src->len; + assert ( len <= sizeof ( *msg ) ); + memcpy ( msg, src, + ( offsetof ( typeof ( *msg ), data ) + len ) ); + DBGC2 ( hv, "HV %p SINT%d received message type " + "%#08x:\n", hv, sintx, + le32_to_cpu ( msg->type ) ); + DBGC2_HDA ( hv, 0, msg->data, len ); + + /* Consume message */ + src->type = 0; + + return 0; + } + + /* Trigger message delivery */ + wrmsr ( HV_X64_MSR_EOM, 0 ); + + /* Delay */ + mdelay ( 1 ); + } + + DBGC ( hv, "HV %p SINT%d timed out waiting for message\n", + hv, sintx ); + return -ETIMEDOUT; +} + +/** + * Signal event + * + * @v hv Hyper-V hypervisor + * @v id Connection ID + * @v flag Flag number + * @ret rc Return status code + */ +int hv_signal_event ( struct hv_hypervisor *hv, unsigned int id, + unsigned int flag ) { + struct hv_signal_event *event = &hv->message->signalled; + int status; + int rc; + + /* Construct event */ + memset ( event, 0, sizeof ( *event ) ); + event->id = cpu_to_le32 ( id ); + event->flag = cpu_to_le16 ( flag ); + + /* Signal event */ + if ( ( status = hv_call ( hv, HV_SIGNAL_EVENT, event, NULL ) ) != 0 ) { + rc = -EHV ( status ); + DBGC ( hv, "HV %p could not signal event to %#08x: %s\n", + hv, id, strerror ( rc ) ); + return rc; + } + + return 0; +} + +/** + * Probe root device + * + * @v rootdev Root device + * @ret rc Return status code + */ +static int hv_probe ( struct root_device *rootdev ) { + struct hv_hypervisor *hv; + int rc; + + /* Check we are running in Hyper-V */ + if ( ( rc = hv_check_hv() ) != 0 ) + goto err_check_hv; + + /* Allocate and initialise structure */ + hv = zalloc ( sizeof ( *hv ) ); + if ( ! hv ) { + rc = -ENOMEM; + goto err_alloc; + } + + /* Check features */ + if ( ( rc = hv_check_features ( hv ) ) != 0 ) + goto err_check_features; + + /* Check that Gen 2 UEFI firmware is not running */ + if ( ( rc = hv_check_uefi ( hv ) ) != 0 ) + goto err_check_uefi; + + /* Allocate pages */ + if ( ( rc = hv_alloc_pages ( hv, &hv->hypercall, &hv->synic.message, + &hv->synic.event, NULL ) ) != 0 ) + goto err_alloc_pages; + + /* Allocate message buffer */ + if ( ( rc = hv_alloc_message ( hv ) ) != 0 ) + goto err_alloc_message; + + /* Map hypercall page */ + hv_map_hypercall ( hv ); + + /* Map synthetic interrupt controller */ + hv_map_synic ( hv ); + + /* Probe Hyper-V devices */ + if ( ( rc = vmbus_probe ( hv, &rootdev->dev ) ) != 0 ) + goto err_vmbus_probe; + + rootdev_set_drvdata ( rootdev, hv ); + return 0; + + vmbus_remove ( hv, &rootdev->dev ); + err_vmbus_probe: + hv_unmap_synic ( hv ); + hv_unmap_hypercall ( hv ); + hv_free_message ( hv ); + err_alloc_message: + hv_free_pages ( hv, hv->hypercall, hv->synic.message, hv->synic.event, + NULL ); + err_alloc_pages: + err_check_uefi: + err_check_features: + free ( hv ); + err_alloc: + err_check_hv: + return rc; +} + +/** + * Remove root device + * + * @v rootdev Root device + */ +static void hv_remove ( struct root_device *rootdev ) { + struct hv_hypervisor *hv = rootdev_get_drvdata ( rootdev ); + + vmbus_remove ( hv, &rootdev->dev ); + hv_unmap_synic ( hv ); + hv_unmap_hypercall ( hv ); + hv_free_message ( hv ); + hv_free_pages ( hv, hv->hypercall, hv->synic.message, hv->synic.event, + NULL ); + free ( hv ); + rootdev_set_drvdata ( rootdev, NULL ); +} + +/** Hyper-V root device driver */ +static struct root_driver hv_root_driver = { + .probe = hv_probe, + .remove = hv_remove, +}; + +/** Hyper-V root device */ +struct root_device hv_root_device __root_device = { + .dev = { .name = "Hyper-V" }, + .driver = &hv_root_driver, +}; + +/** + * Quiesce system + * + */ +static void hv_quiesce ( void ) { + struct hv_hypervisor *hv = rootdev_get_drvdata ( &hv_root_device ); + unsigned int i; + + /* Do nothing if we are not running in Hyper-V */ + if ( ! hv ) + return; + + /* The "enlightened" portions of the Windows Server 2016 boot + * process will not cleanly take ownership of an active + * Hyper-V connection. Experimentation shows that the minimum + * requirement is that we disable the SynIC message page + * (i.e. zero the SIMP MSR). + * + * We cannot perform a full shutdown of the Hyper-V + * connection. Experimentation shows that if we disable the + * SynIC (i.e. zero the SCONTROL MSR) then Windows Server 2016 + * will enter an indefinite wait loop. + * + * Attempt to create a safe handover environment by resetting + * all MSRs except for SCONTROL. + * + * Note that we do not shut down our VMBus devices, since we + * may need to unquiesce the system and continue operation. + */ + + /* Disable all synthetic interrupts */ + for ( i = 0 ; i <= HV_SINT_MAX ; i++ ) + hv_disable_sint ( hv, i ); + + /* Unmap synthetic interrupt controller, leaving SCONTROL + * enabled (see above). + */ + hv_unmap_synic_no_scontrol ( hv ); + + /* Unmap hypercall page */ + hv_unmap_hypercall ( hv ); + + DBGC ( hv, "HV %p quiesced\n", hv ); +} + +/** + * Unquiesce system + * + */ +static void hv_unquiesce ( void ) { + struct hv_hypervisor *hv = rootdev_get_drvdata ( &hv_root_device ); + uint64_t simp; + int rc; + + /* Do nothing if we are not running in Hyper-V */ + if ( ! hv ) + return; + + /* Experimentation shows that the "enlightened" portions of + * Windows Server 2016 will break our Hyper-V connection at + * some point during a SAN boot. Surprisingly it does not + * change the guest OS ID MSR, but it does leave the SynIC + * message page disabled. + * + * Our own explicit quiescing procedure will also disable the + * SynIC message page. We can therefore use the SynIC message + * page enable bit as a heuristic to determine when we need to + * reestablish our Hyper-V connection. + */ + simp = rdmsr ( HV_X64_MSR_SIMP ); + if ( simp & HV_SIMP_ENABLE ) + return; + + /* Remap hypercall page */ + hv_map_hypercall ( hv ); + + /* Remap synthetic interrupt controller */ + hv_map_synic ( hv ); + + /* Reset Hyper-V devices */ + if ( ( rc = vmbus_reset ( hv, &hv_root_device.dev ) ) != 0 ) { + DBGC ( hv, "HV %p could not unquiesce: %s\n", + hv, strerror ( rc ) ); + /* Nothing we can do */ + return; + } +} + +/** Hyper-V quiescer */ +struct quiescer hv_quiescer __quiescer = { + .quiesce = hv_quiesce, + .unquiesce = hv_unquiesce, +}; + +/** + * Probe timer + * + * @ret rc Return status code + */ +static int hv_timer_probe ( void ) { + uint32_t available; + uint32_t discard_ebx; + uint32_t discard_ecx; + uint32_t discard_edx; + int rc; + + /* Check we are running in Hyper-V */ + if ( ( rc = hv_check_hv() ) != 0 ) + return rc; + + /* Check for available reference counter */ + cpuid ( HV_CPUID_FEATURES, 0, &available, &discard_ebx, &discard_ecx, + &discard_edx ); + if ( ! ( available & HV_FEATURES_AVAIL_TIME_REF_COUNT_MSR ) ) { + DBGC ( HV_INTERFACE_ID, "HV has no time reference counter\n" ); + return -ENODEV; + } + + return 0; +} + +/** + * Get current system time in ticks + * + * @ret ticks Current time, in ticks + */ +static unsigned long hv_currticks ( void ) { + + /* Calculate time using a combination of bit shifts and + * multiplication (to avoid a 64-bit division). + */ + return ( ( rdmsr ( HV_X64_MSR_TIME_REF_COUNT ) >> HV_TIMER_SHIFT ) * + ( TICKS_PER_SEC / ( HV_TIMER_HZ >> HV_TIMER_SHIFT ) ) ); +} + +/** + * Delay for a fixed number of microseconds + * + * @v usecs Number of microseconds for which to delay + */ +static void hv_udelay ( unsigned long usecs ) { + uint32_t start; + uint32_t elapsed; + uint32_t threshold; + + /* Spin until specified number of 10MHz ticks have elapsed */ + start = rdmsr ( HV_X64_MSR_TIME_REF_COUNT ); + threshold = ( usecs * ( HV_TIMER_HZ / 1000000 ) ); + do { + elapsed = ( rdmsr ( HV_X64_MSR_TIME_REF_COUNT ) - start ); + } while ( elapsed < threshold ); +} + +/** Hyper-V timer */ +struct timer hv_timer __timer ( TIMER_PREFERRED ) = { + .name = "Hyper-V", + .probe = hv_timer_probe, + .currticks = hv_currticks, + .udelay = hv_udelay, +}; + +/* Drag in objects via hv_root_device */ +REQUIRING_SYMBOL ( hv_root_device ); + +/* Drag in netvsc driver */ +//REQUIRE_OBJECT ( netvsc ); diff --git a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/drivers/xen/hvm.c b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/drivers/xen/hvm.c new file mode 100644 index 0000000..1d9188e --- /dev/null +++ b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/drivers/xen/hvm.c @@ -0,0 +1,503 @@ +/* + * Copyright (C) 2014 Michael Brown . + * + * 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. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hvm.h" + +/** @file + * + * Xen HVM driver + * + */ + +/** + * Get CPUID base + * + * @v hvm HVM device + * @ret rc Return status code + */ +static int hvm_cpuid_base ( struct hvm_device *hvm ) { + struct { + uint32_t ebx; + uint32_t ecx; + uint32_t edx; + } __attribute__ (( packed )) signature; + uint32_t base; + uint32_t version; + uint32_t discard_eax; + uint32_t discard_ebx; + uint32_t discard_ecx; + uint32_t discard_edx; + + /* Scan for magic signature */ + for ( base = HVM_CPUID_MIN ; base <= HVM_CPUID_MAX ; + base += HVM_CPUID_STEP ) { + cpuid ( base, 0, &discard_eax, &signature.ebx, &signature.ecx, + &signature.edx ); + if ( memcmp ( &signature, HVM_CPUID_MAGIC, + sizeof ( signature ) ) == 0 ) { + hvm->cpuid_base = base; + cpuid ( ( base + HVM_CPUID_VERSION ), 0, &version, + &discard_ebx, &discard_ecx, &discard_edx ); + DBGC2 ( hvm, "HVM using CPUID base %#08x (v%d.%d)\n", + base, ( version >> 16 ), ( version & 0xffff ) ); + return 0; + } + } + + DBGC ( hvm, "HVM could not find hypervisor\n" ); + return -ENODEV; +} + +/** + * Map hypercall page(s) + * + * @v hvm HVM device + * @ret rc Return status code + */ +static int hvm_map_hypercall ( struct hvm_device *hvm ) { + uint32_t pages; + uint32_t msr; + uint32_t discard_ecx; + uint32_t discard_edx; + physaddr_t hypercall_phys; + uint32_t version; + static xen_extraversion_t extraversion; + int xenrc; + int rc; + + /* Get number of hypercall pages and MSR to use */ + cpuid ( ( hvm->cpuid_base + HVM_CPUID_PAGES ), 0, &pages, &msr, + &discard_ecx, &discard_edx ); + + /* Allocate pages */ + hvm->hypercall_len = ( pages * PAGE_SIZE ); + hvm->xen.hypercall = malloc_dma ( hvm->hypercall_len, PAGE_SIZE ); + if ( ! hvm->xen.hypercall ) { + DBGC ( hvm, "HVM could not allocate %d hypercall page(s)\n", + pages ); + return -ENOMEM; + } + hypercall_phys = virt_to_phys ( hvm->xen.hypercall ); + DBGC2 ( hvm, "HVM hypercall page(s) at [%#08lx,%#08lx) via MSR %#08x\n", + hypercall_phys, ( hypercall_phys + hvm->hypercall_len ), msr ); + + /* Write to MSR */ + wrmsr ( msr, hypercall_phys ); + + /* Check that hypercall mechanism is working */ + version = xenver_version ( &hvm->xen ); + if ( ( xenrc = xenver_extraversion ( &hvm->xen, &extraversion ) ) != 0){ + rc = -EXEN ( xenrc ); + DBGC ( hvm, "HVM could not get extraversion: %s\n", + strerror ( rc ) ); + return rc; + } + DBGC2 ( hvm, "HVM found Xen version %d.%d%s\n", + ( version >> 16 ), ( version & 0xffff ) , extraversion ); + + return 0; +} + +/** + * Unmap hypercall page(s) + * + * @v hvm HVM device + */ +static void hvm_unmap_hypercall ( struct hvm_device *hvm ) { + + /* Free pages */ + free_dma ( hvm->xen.hypercall, hvm->hypercall_len ); +} + +/** + * Allocate and map MMIO space + * + * @v hvm HVM device + * @v space Source mapping space + * @v len Length (must be a multiple of PAGE_SIZE) + * @ret mmio MMIO space address, or NULL on error + */ +static void * hvm_ioremap ( struct hvm_device *hvm, unsigned int space, + size_t len ) { + struct xen_add_to_physmap add; + struct xen_remove_from_physmap remove; + unsigned int pages = ( len / PAGE_SIZE ); + physaddr_t mmio_phys; + unsigned int i; + void *mmio; + int xenrc; + int rc; + + /* Sanity check */ + assert ( ( len % PAGE_SIZE ) == 0 ); + + /* Check for available space */ + if ( ( hvm->mmio_offset + len ) > hvm->mmio_len ) { + DBGC ( hvm, "HVM could not allocate %zd bytes of MMIO space " + "(%zd of %zd remaining)\n", len, + ( hvm->mmio_len - hvm->mmio_offset ), hvm->mmio_len ); + goto err_no_space; + } + + /* Map this space */ + mmio = ioremap ( ( hvm->mmio + hvm->mmio_offset ), len ); + if ( ! mmio ) { + DBGC ( hvm, "HVM could not map MMIO space [%08lx,%08lx)\n", + ( hvm->mmio + hvm->mmio_offset ), + ( hvm->mmio + hvm->mmio_offset + len ) ); + goto err_ioremap; + } + mmio_phys = virt_to_phys ( mmio ); + + /* Add to physical address space */ + for ( i = 0 ; i < pages ; i++ ) { + add.domid = DOMID_SELF; + add.idx = i; + add.space = space; + add.gpfn = ( ( mmio_phys / PAGE_SIZE ) + i ); + if ( ( xenrc = xenmem_add_to_physmap ( &hvm->xen, &add ) ) !=0){ + rc = -EXEN ( xenrc ); + DBGC ( hvm, "HVM could not add space %d idx %d at " + "[%08lx,%08lx): %s\n", space, i, + ( mmio_phys + ( i * PAGE_SIZE ) ), + ( mmio_phys + ( ( i + 1 ) * PAGE_SIZE ) ), + strerror ( rc ) ); + goto err_add_to_physmap; + } + } + + /* Update offset */ + hvm->mmio_offset += len; + + return mmio; + + i = pages; + err_add_to_physmap: + for ( i-- ; ( signed int ) i >= 0 ; i-- ) { + remove.domid = DOMID_SELF; + add.gpfn = ( ( mmio_phys / PAGE_SIZE ) + i ); + xenmem_remove_from_physmap ( &hvm->xen, &remove ); + } + iounmap ( mmio ); + err_ioremap: + err_no_space: + return NULL; +} + +/** + * Unmap MMIO space + * + * @v hvm HVM device + * @v mmio MMIO space address + * @v len Length (must be a multiple of PAGE_SIZE) + */ +static void hvm_iounmap ( struct hvm_device *hvm, void *mmio, size_t len ) { + struct xen_remove_from_physmap remove; + physaddr_t mmio_phys = virt_to_phys ( mmio ); + unsigned int pages = ( len / PAGE_SIZE ); + unsigned int i; + int xenrc; + int rc; + + /* Unmap this space */ + iounmap ( mmio ); + + /* Remove from physical address space */ + for ( i = 0 ; i < pages ; i++ ) { + remove.domid = DOMID_SELF; + remove.gpfn = ( ( mmio_phys / PAGE_SIZE ) + i ); + if ( ( xenrc = xenmem_remove_from_physmap ( &hvm->xen, + &remove ) ) != 0 ) { + rc = -EXEN ( xenrc ); + DBGC ( hvm, "HVM could not remove space [%08lx,%08lx): " + "%s\n", ( mmio_phys + ( i * PAGE_SIZE ) ), + ( mmio_phys + ( ( i + 1 ) * PAGE_SIZE ) ), + strerror ( rc ) ); + /* Nothing we can do about this */ + } + } +} + +/** + * Map shared info page + * + * @v hvm HVM device + * @ret rc Return status code + */ +static int hvm_map_shared_info ( struct hvm_device *hvm ) { + physaddr_t shared_info_phys; + int rc; + + /* Map shared info page */ + hvm->xen.shared = hvm_ioremap ( hvm, XENMAPSPACE_shared_info, + PAGE_SIZE ); + if ( ! hvm->xen.shared ) { + rc = -ENOMEM; + goto err_alloc; + } + shared_info_phys = virt_to_phys ( hvm->xen.shared ); + DBGC2 ( hvm, "HVM shared info page at [%#08lx,%#08lx)\n", + shared_info_phys, ( shared_info_phys + PAGE_SIZE ) ); + + /* Sanity check */ + DBGC2 ( hvm, "HVM wallclock time is %d\n", + readl ( &hvm->xen.shared->wc_sec ) ); + + return 0; + + hvm_iounmap ( hvm, hvm->xen.shared, PAGE_SIZE ); + err_alloc: + return rc; +} + +/** + * Unmap shared info page + * + * @v hvm HVM device + */ +static void hvm_unmap_shared_info ( struct hvm_device *hvm ) { + + /* Unmap shared info page */ + hvm_iounmap ( hvm, hvm->xen.shared, PAGE_SIZE ); +} + +/** + * Map grant table + * + * @v hvm HVM device + * @ret rc Return status code + */ +static int hvm_map_grant ( struct hvm_device *hvm ) { + physaddr_t grant_phys; + int rc; + + /* Initialise grant table */ + if ( ( rc = xengrant_init ( &hvm->xen ) ) != 0 ) { + DBGC ( hvm, "HVM could not initialise grant table: %s\n", + strerror ( rc ) ); + return rc; + } + + /* Map grant table */ + hvm->xen.grant.table = hvm_ioremap ( hvm, XENMAPSPACE_grant_table, + hvm->xen.grant.len ); + if ( ! hvm->xen.grant.table ) + return -ENODEV; + + grant_phys = virt_to_phys ( hvm->xen.grant.table ); + DBGC2 ( hvm, "HVM mapped grant table at [%08lx,%08lx)\n", + grant_phys, ( grant_phys + hvm->xen.grant.len ) ); + return 0; +} + +/** + * Unmap grant table + * + * @v hvm HVM device + */ +static void hvm_unmap_grant ( struct hvm_device *hvm ) { + + /* Unmap grant table */ + hvm_iounmap ( hvm, hvm->xen.grant.table, hvm->xen.grant.len ); +} + +/** + * Map XenStore + * + * @v hvm HVM device + * @ret rc Return status code + */ +static int hvm_map_xenstore ( struct hvm_device *hvm ) { + uint64_t xenstore_evtchn; + uint64_t xenstore_pfn; + physaddr_t xenstore_phys; + char *name; + int xenrc; + int rc; + + /* Get XenStore event channel */ + if ( ( xenrc = xen_hvm_get_param ( &hvm->xen, HVM_PARAM_STORE_EVTCHN, + &xenstore_evtchn ) ) != 0 ) { + rc = -EXEN ( xenrc ); + DBGC ( hvm, "HVM could not get XenStore event channel: %s\n", + strerror ( rc ) ); + return rc; + } + hvm->xen.store.port = xenstore_evtchn; + + /* Get XenStore PFN */ + if ( ( xenrc = xen_hvm_get_param ( &hvm->xen, HVM_PARAM_STORE_PFN, + &xenstore_pfn ) ) != 0 ) { + rc = -EXEN ( xenrc ); + DBGC ( hvm, "HVM could not get XenStore PFN: %s\n", + strerror ( rc ) ); + return rc; + } + xenstore_phys = ( xenstore_pfn * PAGE_SIZE ); + + /* Map XenStore */ + hvm->xen.store.intf = ioremap ( xenstore_phys, PAGE_SIZE ); + if ( ! hvm->xen.store.intf ) { + DBGC ( hvm, "HVM could not map XenStore at [%08lx,%08lx)\n", + xenstore_phys, ( xenstore_phys + PAGE_SIZE ) ); + return -ENODEV; + } + DBGC2 ( hvm, "HVM mapped XenStore at [%08lx,%08lx) with event port " + "%d\n", xenstore_phys, ( xenstore_phys + PAGE_SIZE ), + hvm->xen.store.port ); + + /* Check that XenStore is working */ + if ( ( rc = xenstore_read ( &hvm->xen, &name, "name", NULL ) ) != 0 ) { + DBGC ( hvm, "HVM could not read domain name: %s\n", + strerror ( rc ) ); + return rc; + } + DBGC2 ( hvm, "HVM running in domain \"%s\"\n", name ); + free ( name ); + + return 0; +} + +/** + * Unmap XenStore + * + * @v hvm HVM device + */ +static void hvm_unmap_xenstore ( struct hvm_device *hvm ) { + + /* Unmap XenStore */ + iounmap ( hvm->xen.store.intf ); +} + +/** + * Probe PCI device + * + * @v pci PCI device + * @ret rc Return status code + */ +static int hvm_probe ( struct pci_device *pci ) { + struct hvm_device *hvm; + int rc; + + /* Allocate and initialise structure */ + hvm = zalloc ( sizeof ( *hvm ) ); + if ( ! hvm ) { + rc = -ENOMEM; + goto err_alloc; + } + hvm->mmio = pci_bar_start ( pci, HVM_MMIO_BAR ); + hvm->mmio_len = pci_bar_size ( pci, HVM_MMIO_BAR ); + DBGC2 ( hvm, "HVM has MMIO space [%08lx,%08lx)\n", + hvm->mmio, ( hvm->mmio + hvm->mmio_len ) ); + + /* Fix up PCI device */ + adjust_pci_device ( pci ); + + /* Attach to hypervisor */ + if ( ( rc = hvm_cpuid_base ( hvm ) ) != 0 ) + goto err_cpuid_base; + if ( ( rc = hvm_map_hypercall ( hvm ) ) != 0 ) + goto err_map_hypercall; + if ( ( rc = hvm_map_shared_info ( hvm ) ) != 0 ) + goto err_map_shared_info; + if ( ( rc = hvm_map_grant ( hvm ) ) != 0 ) + goto err_map_grant; + if ( ( rc = hvm_map_xenstore ( hvm ) ) != 0 ) + goto err_map_xenstore; + + /* Probe Xen devices */ + if ( ( rc = xenbus_probe ( &hvm->xen, &pci->dev ) ) != 0 ) { + DBGC ( hvm, "HVM could not probe Xen bus: %s\n", + strerror ( rc ) ); + goto err_xenbus_probe; + } + + pci_set_drvdata ( pci, hvm ); + return 0; + + xenbus_remove ( &hvm->xen, &pci->dev ); + err_xenbus_probe: + hvm_unmap_xenstore ( hvm ); + err_map_xenstore: + hvm_unmap_grant ( hvm ); + err_map_grant: + hvm_unmap_shared_info ( hvm ); + err_map_shared_info: + hvm_unmap_hypercall ( hvm ); + err_map_hypercall: + err_cpuid_base: + free ( hvm ); + err_alloc: + return rc; +} + +/** + * Remove PCI device + * + * @v pci PCI device + */ +static void hvm_remove ( struct pci_device *pci ) { + struct hvm_device *hvm = pci_get_drvdata ( pci ); + + xenbus_remove ( &hvm->xen, &pci->dev ); + hvm_unmap_xenstore ( hvm ); + hvm_unmap_grant ( hvm ); + hvm_unmap_shared_info ( hvm ); + hvm_unmap_hypercall ( hvm ); + free ( hvm ); +} + +/** PCI device IDs */ +static struct pci_device_id hvm_ids[] = { + PCI_ROM ( 0x5853, 0x0001, "hvm", "hvm", 0 ), + PCI_ROM ( 0x5853, 0x0002, "hvm2", "hvm2", 0 ), +}; + +/** PCI driver */ +struct pci_driver hvm_driver __pci_driver = { + .ids = hvm_ids, + .id_count = ( sizeof ( hvm_ids ) / sizeof ( hvm_ids[0] ) ), + .probe = hvm_probe, + .remove = hvm_remove, +}; + +/* Drag in objects via hvm_driver */ +REQUIRING_SYMBOL ( hvm_driver ); + +/* Drag in netfront driver */ +//REQUIRE_OBJECT ( netfront ); diff --git a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/interface/pcbios/hidemem.c b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/interface/pcbios/hidemem.c new file mode 100644 index 0000000..1a3022c --- /dev/null +++ b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/interface/pcbios/hidemem.c @@ -0,0 +1,235 @@ +/* Copyright (C) 2006 Michael Brown . + * + * 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 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. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#include +#include +#include +#include +#include +#include +#include +#include + +/** Set to true if you want to test a fake E820 map */ +#define FAKE_E820 0 + +/** Alignment for hidden memory regions */ +#define ALIGN_HIDDEN 4096 /* 4kB page alignment should be enough */ + +/** + * A hidden region of iPXE + * + * This represents a region that will be edited out of the system's + * memory map. + * + * This structure is accessed by assembly code, so must not be + * changed. + */ +struct hidden_region { + /** Physical start address */ + uint64_t start; + /** Physical end address */ + uint64_t end; +}; + +/** Hidden base memory */ +extern struct hidden_region __data16 ( hidemem_base ); +#define hidemem_base __use_data16 ( hidemem_base ) + +/** Hidden umalloc memory */ +extern struct hidden_region __data16 ( hidemem_umalloc ); +#define hidemem_umalloc __use_data16 ( hidemem_umalloc ) + +/** Hidden text memory */ +extern struct hidden_region __data16 ( hidemem_textdata ); +#define hidemem_textdata __use_data16 ( hidemem_textdata ) + +/** Assembly routine in e820mangler.S */ +extern void int15(); + +/** Vector for storing original INT 15 handler */ +extern struct segoff __text16 ( int15_vector ); +#define int15_vector __use_text16 ( int15_vector ) + +/* The linker defines these symbols for us */ +extern char _textdata[]; +extern char _etextdata[]; +extern char _text16_memsz[]; +#define _text16_memsz ( ( size_t ) _text16_memsz ) +extern char _data16_memsz[]; +#define _data16_memsz ( ( size_t ) _data16_memsz ) + +/** + * Hide region of memory from system memory map + * + * @v region Hidden memory region + * @v start Start of region + * @v end End of region + */ +static void hide_region ( struct hidden_region *region, + physaddr_t start, physaddr_t end ) { + + /* Some operating systems get a nasty shock if a region of the + * E820 map seems to start on a non-page boundary. Make life + * safer by rounding out our edited region. + */ + region->start = ( start & ~( ALIGN_HIDDEN - 1 ) ); + region->end = ( ( end + ALIGN_HIDDEN - 1 ) & ~( ALIGN_HIDDEN - 1 ) ); + + DBG ( "Hiding region [%llx,%llx)\n", region->start, region->end ); +} + +/** + * Hide used base memory + * + */ +void hide_basemem ( void ) { + /* Hide from the top of free base memory to 640kB. Don't use + * hide_region(), because we don't want this rounded to the + * nearest page boundary. + */ + hidemem_base.start = ( get_fbms() * 1024 ); +} + +/** + * Hide umalloc() region + * + */ +void hide_umalloc ( physaddr_t start, physaddr_t end ) { + assert ( end <= virt_to_phys ( _textdata ) ); + hide_region ( &hidemem_umalloc, start, end ); +} + +/** + * Hide .text and .data + * + */ +void hide_textdata ( void ) { + hide_region ( &hidemem_textdata, virt_to_phys ( _textdata ), + virt_to_phys ( _etextdata ) ); +} + +/** + * Hide Etherboot + * + * Installs an INT 15 handler to edit Etherboot out of the memory map + * returned by the BIOS. + */ +static void hide_etherboot ( void ) { + struct memory_map memmap; + unsigned int rm_ds_top; + unsigned int rm_cs_top; + unsigned int fbms; + + /* Dump memory map before mangling */ + DBG ( "Hiding iPXE from system memory map\n" ); + get_memmap ( &memmap ); + + /* Hook in fake E820 map, if we're testing one */ + if ( FAKE_E820 ) { + DBG ( "Hooking in fake E820 map\n" ); + fake_e820(); + get_memmap ( &memmap ); + } + + /* Initialise the hidden regions */ + hide_basemem(); + hide_umalloc ( virt_to_phys ( _textdata ), virt_to_phys ( _textdata ) ); + hide_textdata(); + + /* Some really moronic BIOSes bring up the PXE stack via the + * UNDI loader entry point and then don't bother to unload it + * before overwriting the code and data segments. If this + * happens, we really don't want to leave INT 15 hooked, + * because that will cause any loaded OS to die horribly as + * soon as it attempts to fetch the system memory map. + * + * We use a heuristic to guess whether or not we are being + * loaded sensibly. + */ + rm_cs_top = ( ( ( rm_cs << 4 ) + _text16_memsz + 1024 - 1 ) >> 10 ); + rm_ds_top = ( ( ( rm_ds << 4 ) + _data16_memsz + 1024 - 1 ) >> 10 ); + fbms = get_fbms(); + if ( ( rm_cs_top < fbms ) && ( rm_ds_top < fbms ) ) { + DBG ( "Detected potentially unsafe UNDI load at CS=%04x " + "DS=%04x FBMS=%dkB\n", rm_cs, rm_ds, fbms ); + DBG ( "Disabling INT 15 memory hiding\n" ); + return; + } + + /* Hook INT 15 */ + hook_bios_interrupt ( 0x15, ( intptr_t ) int15, &int15_vector ); + + /* Dump memory map after mangling */ + DBG ( "Hidden iPXE from system memory map\n" ); + get_memmap ( &memmap ); +} + +/** + * Unhide Etherboot + * + * Uninstalls the INT 15 handler installed by hide_etherboot(), if + * possible. + */ +static void unhide_etherboot ( int flags __unused ) { + struct memory_map memmap; + int rc; + + /* If we have more than one hooked interrupt at this point, it + * means that some other vector is still hooked, in which case + * we can't safely unhook INT 15 because we need to keep our + * memory protected. (We expect there to be at least one + * hooked interrupt, because INT 15 itself is still hooked). + */ + if ( hooked_bios_interrupts > 1 ) { + DBG ( "Cannot unhide: %d interrupt vectors still hooked\n", + hooked_bios_interrupts ); + return; + } + + /* Try to unhook INT 15 */ + if ( ( rc = unhook_bios_interrupt ( 0x15, ( intptr_t ) int15, + &int15_vector ) ) != 0 ) { + DBG ( "Cannot unhook INT15: %s\n", strerror ( rc ) ); + /* Leave it hooked; there's nothing else we can do, + * and it should be intrinsically safe (though + * wasteful of RAM). + */ + } + + /* Unhook fake E820 map, if used */ + if ( FAKE_E820 ) + unfake_e820(); + + /* Dump memory map after unhiding */ + DBG ( "Unhidden iPXE from system memory map\n" ); + get_memmap ( &memmap ); +} + +/** Hide Etherboot startup function */ +struct startup_fn hide_etherboot_startup_fn __startup_fn ( STARTUP_EARLY ) = { + .name = "hidemem", + .startup = hide_etherboot, + .shutdown = unhide_etherboot, +}; diff --git a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/interface/pcbios/int13.c b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/interface/pcbios/int13.c new file mode 100644 index 0000000..fe8c4b4 --- /dev/null +++ b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/interface/pcbios/int13.c @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2010 Michael Brown . + * + * 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 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. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#include +#include + +static int null_san_hook ( unsigned int drive __unused, + struct uri **uris __unused, + unsigned int count __unused, + unsigned int flags __unused ) { + return -EOPNOTSUPP; +} + +static void null_san_unhook ( unsigned int drive __unused ) { + /* Do nothing */ +} + +static int null_san_boot ( unsigned int drive __unused, + const char *filename __unused ) { + return -EOPNOTSUPP; +} + +static int null_san_describe ( void ) { + return -EOPNOTSUPP; +} + +PROVIDE_SANBOOT ( pcbios, san_hook, null_san_hook ); +PROVIDE_SANBOOT ( pcbios, san_unhook, null_san_unhook ); +PROVIDE_SANBOOT ( pcbios, san_boot, null_san_boot ); +PROVIDE_SANBOOT ( pcbios, san_describe, null_san_describe ); + diff --git a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/interface/pcbios/ventoy_int13.c b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/interface/pcbios/ventoy_int13.c new file mode 100644 index 0000000..d343b03 --- /dev/null +++ b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/interface/pcbios/ventoy_int13.c @@ -0,0 +1,1586 @@ +/* + * Copyright (C) 2006 Michael Brown . + * Copyright (C) 2020 longpanda . + * + * 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 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. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ventoy_int13.h" + +static unsigned int g_drive_map1 = 0; +static unsigned int g_drive_map2 = 0; + +/** @file + * + * INT 13 emulation + * + * This module provides a mechanism for exporting block devices via + * the BIOS INT 13 disk interrupt interface. + * + */ + +/** INT 13 SAN device private data */ +struct int13_data { + /** BIOS natural drive number (0x00-0xff) + * + * This is the drive number that would have been assigned by + * 'naturally' appending the drive to the end of the BIOS + * drive list. + * + * If the emulated drive replaces a preexisting drive, this is + * the drive number that the preexisting drive gets remapped + * to. + */ + unsigned int natural_drive; + + /** Number of cylinders + * + * The cylinder number field in an INT 13 call is ten bits + * wide, giving a maximum of 1024 cylinders. Conventionally, + * when the 7.8GB limit of a CHS address is exceeded, it is + * the number of cylinders that is increased beyond the + * addressable limit. + */ + unsigned int cylinders; + /** Number of heads + * + * The head number field in an INT 13 call is eight bits wide, + * giving a maximum of 256 heads. However, apparently all + * versions of MS-DOS up to and including Win95 fail with 256 + * heads, so the maximum encountered in practice is 255. + */ + unsigned int heads; + /** Number of sectors per track + * + * The sector number field in an INT 13 call is six bits wide, + * giving a maximum of 63 sectors, since sector numbering + * (unlike head and cylinder numbering) starts at 1, not 0. + */ + unsigned int sectors_per_track; + + /** Address of El Torito boot catalog (if any) */ + unsigned int boot_catalog; + /** Status of last operation */ + int last_status; +}; + +/** Vector for chaining to other INT 13 handlers */ +static struct segoff __text16 ( int13_vector ); +#define int13_vector __use_text16 ( int13_vector ) + +/** Assembly wrapper */ +extern void int13_wrapper ( void ); + +/** Dummy floppy disk parameter table */ +static struct int13_fdd_parameters __data16 ( int13_fdd_params ) = { + /* 512 bytes per sector */ + .bytes_per_sector = 0x02, + /* Highest sectors per track that we ever return */ + .sectors_per_track = 48, +}; +#define int13_fdd_params __use_data16 ( int13_fdd_params ) + +/** + * Equipment word + * + * This is a cached copy of the BIOS Data Area equipment word at + * 40:10. + */ +static uint16_t equipment_word; + +/** + * Number of BIOS floppy disk drives + * + * This is derived from the equipment word. It is held in .text16 to + * allow for easy access by the INT 13,08 wrapper. + */ +static uint8_t __text16 ( num_fdds ); +#define num_fdds __use_text16 ( num_fdds ) + +/** + * Number of BIOS hard disk drives + * + * This is a cached copy of the BIOS Data Area number of hard disk + * drives at 40:75. It is held in .text16 to allow for easy access by + * the INT 13,08 wrapper. + */ +static uint8_t __text16 ( num_drives ); +#define num_drives __use_text16 ( num_drives ) +static struct san_device *g_sandev; + +/** + * Calculate SAN device capacity (limited to 32 bits) + * + * @v sandev SAN device + * @ret blocks Number of blocks + */ +static inline uint32_t int13_capacity32 ( struct san_device *sandev ) { + uint64_t capacity = sandev_capacity ( sandev ); + return ( ( capacity <= 0xffffffffUL ) ? capacity : 0xffffffff ); +} + +/** + * Test if SAN device is a floppy disk drive + * + * @v sandev SAN device + * @ret is_fdd SAN device is a floppy disk drive + */ +static inline int int13_is_fdd ( struct san_device *sandev ) { + (void)sandev; + return 0; +} + +#if 0 +/** + * Guess INT 13 hard disk drive geometry + * + * @v sandev SAN device + * @v scratch Scratch area for single-sector reads + * @ret heads Guessed number of heads + * @ret sectors Guessed number of sectors per track + * @ret rc Return status code + * + * Guesses the drive geometry by inspecting the partition table. + */ +static int int13_guess_geometry_hdd ( struct san_device *sandev, void *scratch, + unsigned int *heads, + unsigned int *sectors ) { + struct master_boot_record *mbr = scratch; + struct partition_table_entry *partition; + unsigned int i; + unsigned int start_cylinder; + unsigned int start_head; + unsigned int start_sector; + unsigned int end_head; + unsigned int end_sector; + int rc; + + /* Read partition table */ + if ( ( rc = sandev_read ( sandev, 0, 1, virt_to_user ( mbr ) ) ) != 0 ) { + DBGC ( sandev, "INT13 drive %02x could not read " + "partition table to guess geometry: %s\n", + sandev->drive, strerror ( rc ) ); + return rc; + } + DBGC2 ( sandev, "INT13 drive %02x has MBR:\n", sandev->drive ); + DBGC2_HDA ( sandev, 0, mbr, sizeof ( *mbr ) ); + DBGC ( sandev, "INT13 drive %02x has signature %08x\n", + sandev->drive, mbr->signature ); + + /* Scan through partition table and modify guesses for + * heads and sectors_per_track if we find any used + * partitions. + */ + *heads = 0; + *sectors = 0; + for ( i = 0 ; i < 4 ; i++ ) { + + /* Skip empty partitions */ + partition = &mbr->partitions[i]; + if ( ! partition->type ) + continue; + + /* If partition starts on cylinder 0 then we can + * unambiguously determine the number of sectors. + */ + start_cylinder = PART_CYLINDER ( partition->chs_start ); + start_head = PART_HEAD ( partition->chs_start ); + start_sector = PART_SECTOR ( partition->chs_start ); + if ( ( start_cylinder == 0 ) && ( start_head != 0 ) ) { + *sectors = ( ( partition->start + 1 - start_sector ) / + start_head ); + DBGC ( sandev, "INT13 drive %02x guessing C/H/S " + "xx/xx/%d based on partition %d\n", + sandev->drive, *sectors, ( i + 1 ) ); + } + + /* If partition ends on a higher head or sector number + * than our current guess, then increase the guess. + */ + end_head = PART_HEAD ( partition->chs_end ); + end_sector = PART_SECTOR ( partition->chs_end ); + if ( ( end_head + 1 ) > *heads ) { + *heads = ( end_head + 1 ); + DBGC ( sandev, "INT13 drive %02x guessing C/H/S " + "xx/%d/xx based on partition %d\n", + sandev->drive, *heads, ( i + 1 ) ); + } + if ( end_sector > *sectors ) { + *sectors = end_sector; + DBGC ( sandev, "INT13 drive %02x guessing C/H/S " + "xx/xx/%d based on partition %d\n", + sandev->drive, *sectors, ( i + 1 ) ); + } + } + + /* Default guess is xx/255/63 */ + if ( ! *heads ) + *heads = 255; + if ( ! *sectors ) + *sectors = 63; + + return 0; +} + +/** Recognised floppy disk geometries */ +static const struct int13_fdd_geometry int13_fdd_geometries[] = { + INT13_FDD_GEOMETRY ( 40, 1, 8 ), + INT13_FDD_GEOMETRY ( 40, 1, 9 ), + INT13_FDD_GEOMETRY ( 40, 2, 8 ), + INT13_FDD_GEOMETRY ( 40, 1, 9 ), + INT13_FDD_GEOMETRY ( 80, 2, 8 ), + INT13_FDD_GEOMETRY ( 80, 2, 9 ), + INT13_FDD_GEOMETRY ( 80, 2, 15 ), + INT13_FDD_GEOMETRY ( 80, 2, 18 ), + INT13_FDD_GEOMETRY ( 80, 2, 20 ), + INT13_FDD_GEOMETRY ( 80, 2, 21 ), + INT13_FDD_GEOMETRY ( 82, 2, 21 ), + INT13_FDD_GEOMETRY ( 83, 2, 21 ), + INT13_FDD_GEOMETRY ( 80, 2, 22 ), + INT13_FDD_GEOMETRY ( 80, 2, 23 ), + INT13_FDD_GEOMETRY ( 80, 2, 24 ), + INT13_FDD_GEOMETRY ( 80, 2, 36 ), + INT13_FDD_GEOMETRY ( 80, 2, 39 ), + INT13_FDD_GEOMETRY ( 80, 2, 40 ), + INT13_FDD_GEOMETRY ( 80, 2, 44 ), + INT13_FDD_GEOMETRY ( 80, 2, 48 ), +}; + +/** + * Guess INT 13 floppy disk drive geometry + * + * @v sandev SAN device + * @ret heads Guessed number of heads + * @ret sectors Guessed number of sectors per track + * @ret rc Return status code + * + * Guesses the drive geometry by inspecting the disk size. + */ +static int int13_guess_geometry_fdd ( struct san_device *sandev, + unsigned int *heads, + unsigned int *sectors ) { + unsigned int blocks = sandev_capacity ( sandev ); + const struct int13_fdd_geometry *geometry; + unsigned int cylinders; + unsigned int i; + + /* Look for a match against a known geometry */ + for ( i = 0 ; i < ( sizeof ( int13_fdd_geometries ) / + sizeof ( int13_fdd_geometries[0] ) ) ; i++ ) { + geometry = &int13_fdd_geometries[i]; + cylinders = INT13_FDD_CYLINDERS ( geometry ); + *heads = INT13_FDD_HEADS ( geometry ); + *sectors = INT13_FDD_SECTORS ( geometry ); + if ( ( cylinders * (*heads) * (*sectors) ) == blocks ) { + DBGC ( sandev, "INT13 drive %02x guessing C/H/S " + "%d/%d/%d based on size %dK\n", sandev->drive, + cylinders, *heads, *sectors, ( blocks / 2 ) ); + return 0; + } + } + + /* Otherwise, assume a partial disk image in the most common + * format (1440K, 80/2/18). + */ + *heads = 2; + *sectors = 18; + DBGC ( sandev, "INT13 drive %02x guessing C/H/S xx/%d/%d based on size " + "%dK\n", sandev->drive, *heads, *sectors, ( blocks / 2 ) ); + return 0; +} + +/** + * Guess INT 13 drive geometry + * + * @v sandev SAN device + * @v scratch Scratch area for single-sector reads + * @ret rc Return status code + */ +static int int13_guess_geometry ( struct san_device *sandev, void *scratch ) { + struct int13_data *int13 = sandev->priv; + unsigned int guessed_heads; + unsigned int guessed_sectors; + unsigned int blocks; + unsigned int blocks_per_cyl; + int rc; + + /* Guess geometry according to drive type */ + if ( int13_is_fdd ( sandev ) ) { + if ( ( rc = int13_guess_geometry_fdd ( sandev, &guessed_heads, + &guessed_sectors )) != 0) + return rc; + } else { + if ( ( rc = int13_guess_geometry_hdd ( sandev, scratch, + &guessed_heads, + &guessed_sectors )) != 0) + return rc; + } + + /* Apply guesses if no geometry already specified */ + if ( ! int13->heads ) + int13->heads = guessed_heads; + if ( ! int13->sectors_per_track ) + int13->sectors_per_track = guessed_sectors; + if ( ! int13->cylinders ) { + /* Avoid attempting a 64-bit divide on a 32-bit system */ + blocks = int13_capacity32 ( sandev ); + blocks_per_cyl = ( int13->heads * int13->sectors_per_track ); + assert ( blocks_per_cyl != 0 ); + int13->cylinders = ( blocks / blocks_per_cyl ); + if ( int13->cylinders > 1024 ) + int13->cylinders = 1024; + } + + return 0; +} +#endif /* #if 0 */ + +/** + * Update BIOS drive count + */ +void int13_sync_num_drives ( void ) { + struct san_device *sandev; + struct int13_data *int13; + uint8_t *counter; + uint8_t max_drive; + uint8_t required; + + /* Get current drive counts */ + get_real ( equipment_word, BDA_SEG, BDA_EQUIPMENT_WORD ); + get_real ( num_drives, BDA_SEG, BDA_NUM_DRIVES ); + num_fdds = ( ( equipment_word & 0x0001 ) ? + ( ( ( equipment_word >> 6 ) & 0x3 ) + 1 ) : 0 ); + + /* Ensure count is large enough to cover all of our SAN devices */ + for_each_sandev ( sandev ) { + int13 = sandev->priv; + counter = ( int13_is_fdd ( sandev ) ? &num_fdds : &num_drives ); + max_drive = sandev->drive; + if ( max_drive < int13->natural_drive ) + max_drive = int13->natural_drive; + required = ( ( max_drive & 0x7f ) + 1 ); + if ( *counter < required ) { + *counter = required; + DBGC ( sandev, "INT13 drive %02x added to drive count: " + "%d HDDs, %d FDDs\n", + sandev->drive, num_drives, num_fdds ); + } + } + + /* Update current drive count */ + equipment_word &= ~( ( 0x3 << 6 ) | 0x0001 ); + if ( num_fdds ) { + equipment_word |= ( 0x0001 | + ( ( ( num_fdds - 1 ) & 0x3 ) << 6 ) ); + } + put_real ( equipment_word, BDA_SEG, BDA_EQUIPMENT_WORD ); + put_real ( num_drives, BDA_SEG, BDA_NUM_DRIVES ); +} + +/** + * Check number of drives + */ +void int13_check_num_drives ( void ) { + uint16_t check_equipment_word; + uint8_t check_num_drives; + + get_real ( check_equipment_word, BDA_SEG, BDA_EQUIPMENT_WORD ); + get_real ( check_num_drives, BDA_SEG, BDA_NUM_DRIVES ); + if ( ( check_equipment_word != equipment_word ) || + ( check_num_drives != num_drives ) ) { + int13_sync_num_drives(); + } +} + +/** + * INT 13, 00 - Reset disk system + * + * @v sandev SAN device + * @ret status Status code + */ +static int int13_reset ( struct san_device *sandev, + struct i386_all_regs *ix86 __unused ) { + int rc; + + DBGC2 ( sandev, "Reset drive\n" ); + + /* Reset SAN device */ + if ( ( rc = sandev_reset ( sandev ) ) != 0 ) + return -INT13_STATUS_RESET_FAILED; + + return 0; +} + +/** + * INT 13, 01 - Get status of last operation + * + * @v sandev SAN device + * @ret status Status code + */ +static int int13_get_last_status ( struct san_device *sandev, + struct i386_all_regs *ix86 __unused ) { + struct int13_data *int13 = sandev->priv; + + DBGC2 ( sandev, "Get status of last operation\n" ); + return int13->last_status; +} + +/** + * Read / write sectors + * + * @v sandev SAN device + * @v al Number of sectors to read or write (must be nonzero) + * @v ch Low bits of cylinder number + * @v cl (bits 7:6) High bits of cylinder number + * @v cl (bits 5:0) Sector number + * @v dh Head number + * @v es:bx Data buffer + * @v sandev_rw SAN device read/write method + * @ret status Status code + * @ret al Number of sectors read or written + */ +static int int13_rw_sectors ( struct san_device *sandev, + struct i386_all_regs *ix86, + int ( * sandev_rw ) ( struct san_device *sandev, + uint64_t lba, + unsigned int count, + userptr_t buffer ) ) { + struct int13_data *int13 = sandev->priv; + unsigned int cylinder, head, sector; + unsigned long lba; + unsigned int count; + userptr_t buffer; + int rc; + + /* Validate blocksize */ + if ( sandev_blksize ( sandev ) != INT13_BLKSIZE ) { + DBGC ( sandev, "\nINT 13 drive %02x invalid blocksize (%zd) " + "for non-extended read/write\n", + sandev->drive, sandev_blksize ( sandev ) ); + return -INT13_STATUS_INVALID; + } + + /* Calculate parameters */ + cylinder = ( ( ( ix86->regs.cl & 0xc0 ) << 2 ) | ix86->regs.ch ); + head = ix86->regs.dh; + sector = ( ix86->regs.cl & 0x3f ); + if ( ( cylinder >= int13->cylinders ) || + ( head >= int13->heads ) || + ( sector < 1 ) || ( sector > int13->sectors_per_track ) ) { + DBGC ( sandev, "C/H/S %d/%d/%d out of range for geometry " + "%d/%d/%d\n", cylinder, head, sector, int13->cylinders, + int13->heads, int13->sectors_per_track ); + return -INT13_STATUS_INVALID; + } + lba = ( ( ( ( cylinder * int13->heads ) + head ) + * int13->sectors_per_track ) + sector - 1 ); + count = ix86->regs.al; + buffer = real_to_user ( ix86->segs.es, ix86->regs.bx ); + + DBGC2 ( sandev, "C/H/S %d/%d/%d = LBA %08lx <-> %04x:%04x (count %d)\n", + cylinder, head, sector, lba, ix86->segs.es, ix86->regs.bx, + count ); + + /* Read from / write to block device */ + if ( ( rc = sandev_rw ( sandev, lba, count, buffer ) ) != 0 ){ + DBGC ( sandev, "INT13 drive %02x I/O failed: %s\n", + sandev->drive, strerror ( rc ) ); + return -INT13_STATUS_READ_ERROR; + } + + return 0; +} + +/** + * INT 13, 02 - Read sectors + * + * @v sandev SAN device + * @v al Number of sectors to read (must be nonzero) + * @v ch Low bits of cylinder number + * @v cl (bits 7:6) High bits of cylinder number + * @v cl (bits 5:0) Sector number + * @v dh Head number + * @v es:bx Data buffer + * @ret status Status code + * @ret al Number of sectors read + */ +static int int13_read_sectors ( struct san_device *sandev, + struct i386_all_regs *ix86 ) { + + DBGC2 ( sandev, "Read: " ); + return int13_rw_sectors ( sandev, ix86, sandev_read ); +} + +/** + * INT 13, 03 - Write sectors + * + * @v sandev SAN device + * @v al Number of sectors to write (must be nonzero) + * @v ch Low bits of cylinder number + * @v cl (bits 7:6) High bits of cylinder number + * @v cl (bits 5:0) Sector number + * @v dh Head number + * @v es:bx Data buffer + * @ret status Status code + * @ret al Number of sectors written + */ +static int int13_write_sectors ( struct san_device *sandev, + struct i386_all_regs *ix86 ) { + + DBGC2 ( sandev, "Write: " ); + return int13_rw_sectors ( sandev, ix86, sandev_write ); +} + +/** + * INT 13, 08 - Get drive parameters + * + * @v sandev SAN device + * @ret status Status code + * @ret ch Low bits of maximum cylinder number + * @ret cl (bits 7:6) High bits of maximum cylinder number + * @ret cl (bits 5:0) Maximum sector number + * @ret dh Maximum head number + * @ret dl Number of drives + */ +static int int13_get_parameters ( struct san_device *sandev, + struct i386_all_regs *ix86 ) { + struct int13_data *int13 = sandev->priv; + unsigned int max_cylinder = int13->cylinders - 1; + unsigned int max_head = int13->heads - 1; + unsigned int max_sector = int13->sectors_per_track; /* sic */ + + DBGC2 ( sandev, "Get drive parameters\n" ); + + /* Validate blocksize */ + if ( sandev_blksize ( sandev ) != INT13_BLKSIZE ) { + DBGC ( sandev, "\nINT 13 drive %02x invalid blocksize (%zd) " + "for non-extended parameters\n", + sandev->drive, sandev_blksize ( sandev ) ); + return -INT13_STATUS_INVALID; + } + + /* Common parameters */ + ix86->regs.ch = ( max_cylinder & 0xff ); + ix86->regs.cl = ( ( ( max_cylinder >> 8 ) << 6 ) | max_sector ); + ix86->regs.dh = max_head; + ix86->regs.dl = ( int13_is_fdd ( sandev ) ? num_fdds : num_drives ); + + /* Floppy-specific parameters */ + if ( int13_is_fdd ( sandev ) ) { + ix86->regs.bl = INT13_FDD_TYPE_1M44; + ix86->segs.es = rm_ds; + ix86->regs.di = __from_data16 ( &int13_fdd_params ); + } + + return 0; +} + +/** + * INT 13, 15 - Get disk type + * + * @v sandev SAN device + * @ret ah Type code + * @ret cx:dx Sector count + * @ret status Status code / disk type + */ +static int int13_get_disk_type ( struct san_device *sandev, + struct i386_all_regs *ix86 ) { + uint32_t blocks; + + DBGC2 ( sandev, "Get disk type\n" ); + + if ( int13_is_fdd ( sandev ) ) { + return INT13_DISK_TYPE_FDD; + } else { + blocks = int13_capacity32 ( sandev ); + ix86->regs.cx = ( blocks >> 16 ); + ix86->regs.dx = ( blocks & 0xffff ); + return INT13_DISK_TYPE_HDD; + } +} + +/** + * INT 13, 41 - Extensions installation check + * + * @v sandev SAN device + * @v bx 0x55aa + * @ret bx 0xaa55 + * @ret cx Extensions API support bitmap + * @ret status Status code / API version + */ +static int int13_extension_check ( struct san_device *sandev __unused, + struct i386_all_regs *ix86 ) { + + if ( ix86->regs.bx == 0x55aa ) { + DBGC2 ( sandev, "INT13 extensions installation check\n" ); + ix86->regs.bx = 0xaa55; + ix86->regs.cx = ( INT13_EXTENSION_LINEAR | + INT13_EXTENSION_EDD | + INT13_EXTENSION_64BIT ); + return INT13_EXTENSION_VER_3_0; + } else { + return -INT13_STATUS_INVALID; + } +} + +/** + * Extended read / write + * + * @v sandev SAN device + * @v ds:si Disk address packet + * @v sandev_rw SAN device read/write method + * @ret status Status code + */ +static int int13_extended_rw ( struct san_device *sandev, + struct i386_all_regs *ix86, + int ( * sandev_rw ) ( struct san_device *sandev, + uint64_t lba, + unsigned int count, + userptr_t buffer ) ) { + struct int13_disk_address addr; + uint8_t bufsize; + uint64_t lba; + unsigned long count; + userptr_t buffer; + int rc; + + /* Extended reads are not allowed on floppy drives. + * ELTORITO.SYS seems to assume that we are really a CD-ROM if + * we support extended reads for a floppy drive. + */ + if ( int13_is_fdd ( sandev ) ) + return -INT13_STATUS_INVALID; + + /* Get buffer size */ + get_real ( bufsize, ix86->segs.ds, + ( ix86->regs.si + offsetof ( typeof ( addr ), bufsize ) ) ); + if ( bufsize < offsetof ( typeof ( addr ), buffer_phys ) ) { + DBGC2 ( sandev, "\n", bufsize ); + return -INT13_STATUS_INVALID; + } + + /* Read parameters from disk address structure */ + memset ( &addr, 0, sizeof ( addr ) ); + copy_from_real ( &addr, ix86->segs.ds, ix86->regs.si, bufsize ); + lba = addr.lba; + DBGC2 ( sandev, "LBA %08llx <-> ", ( ( unsigned long long ) lba ) ); + if ( ( addr.count == 0xff ) || + ( ( addr.buffer.segment == 0xffff ) && + ( addr.buffer.offset == 0xffff ) ) ) { + buffer = phys_to_user ( addr.buffer_phys ); + DBGC2 ( sandev, "%08llx", + ( ( unsigned long long ) addr.buffer_phys ) ); + } else { + buffer = real_to_user ( addr.buffer.segment, + addr.buffer.offset ); + DBGC2 ( sandev, "%04x:%04x", addr.buffer.segment, + addr.buffer.offset ); + } + if ( addr.count <= 0x7f ) { + count = addr.count; + } else if ( addr.count == 0xff ) { + count = addr.long_count; + } else { + DBGC2 ( sandev, " \n", addr.count ); + return -INT13_STATUS_INVALID; + } + DBGC2 ( sandev, " (count %ld)\n", count ); + + /* Read from / write to block device */ + if ( ( rc = sandev_rw ( sandev, lba, count, buffer ) ) != 0 ) { + DBGC ( sandev, "INT13 drive %02x extended I/O failed: %s\n", + sandev->drive, strerror ( rc ) ); + /* Record that no blocks were transferred successfully */ + addr.count = 0; + put_real ( addr.count, ix86->segs.ds, + ( ix86->regs.si + + offsetof ( typeof ( addr ), count ) ) ); + return -INT13_STATUS_READ_ERROR; + } + + copy_to_real (ix86->segs.ds, ix86->regs.si, &addr, bufsize ); + + return 0; +} + +/** + * INT 13, 42 - Extended read + * + * @v sandev SAN device + * @v ds:si Disk address packet + * @ret status Status code + */ +static int int13_extended_read ( struct san_device *sandev, + struct i386_all_regs *ix86 ) { + + DBGC2 ( sandev, "Extended read: " ); + return int13_extended_rw ( sandev, ix86, sandev_read ); +} + +/** + * INT 13, 43 - Extended write + * + * @v sandev SAN device + * @v ds:si Disk address packet + * @ret status Status code + */ +static int int13_extended_write ( struct san_device *sandev, + struct i386_all_regs *ix86 ) { + + DBGC2 ( sandev, "Extended write: " ); + return int13_extended_rw ( sandev, ix86, sandev_write ); +} + +/** + * INT 13, 44 - Verify sectors + * + * @v sandev SAN device + * @v ds:si Disk address packet + * @ret status Status code + */ +static int int13_extended_verify ( struct san_device *sandev, + struct i386_all_regs *ix86 ) { + struct int13_disk_address addr; + uint64_t lba; + unsigned long count; + + /* Read parameters from disk address structure */ + if ( DBG_EXTRA ) { + copy_from_real ( &addr, ix86->segs.ds, ix86->regs.si, + sizeof ( addr )); + lba = addr.lba; + count = addr.count; + DBGC2 ( sandev, "Verify: LBA %08llx (count %ld)\n", + ( ( unsigned long long ) lba ), count ); + } + + /* We have no mechanism for verifying sectors */ + return -INT13_STATUS_INVALID; +} + +/** + * INT 13, 44 - Extended seek + * + * @v sandev SAN device + * @v ds:si Disk address packet + * @ret status Status code + */ +static int int13_extended_seek ( struct san_device *sandev, + struct i386_all_regs *ix86 ) { + struct int13_disk_address addr; + uint64_t lba; + unsigned long count; + + /* Read parameters from disk address structure */ + if ( DBG_EXTRA ) { + copy_from_real ( &addr, ix86->segs.ds, ix86->regs.si, + sizeof ( addr )); + lba = addr.lba; + count = addr.count; + DBGC2 ( sandev, "Seek: LBA %08llx (count %ld)\n", + ( ( unsigned long long ) lba ), count ); + } + + /* Ignore and return success */ + return 0; +} + +/** + * Build device path information + * + * @v sandev SAN device + * @v dpi Device path information + * @ret rc Return status code + */ +static int int13_device_path_info ( struct san_device *sandev, + struct edd_device_path_information *dpi ) { + struct san_path *sanpath; + struct device *device; + struct device_description *desc; + unsigned int i; + uint8_t sum = 0; + int rc; + return -ECANCELED; + /* Reopen block device if necessary */ + if ( sandev_needs_reopen ( sandev ) && + ( ( rc = sandev_reopen ( sandev ) ) != 0 ) ) + return rc; + sanpath = sandev->active; + assert ( sanpath != NULL ); + + /* Get underlying hardware device */ + device = identify_device ( &sanpath->block ); + if ( ! device ) { + DBGC ( sandev, "INT13 drive %02x cannot identify hardware " + "device\n", sandev->drive ); + return -ENODEV; + } + + /* Fill in bus type and interface path */ + desc = &device->desc; + switch ( desc->bus_type ) { + case BUS_TYPE_PCI: + dpi->host_bus_type.type = EDD_BUS_TYPE_PCI; + dpi->interface_path.pci.bus = PCI_BUS ( desc->location ); + dpi->interface_path.pci.slot = PCI_SLOT ( desc->location ); + dpi->interface_path.pci.function = PCI_FUNC ( desc->location ); + dpi->interface_path.pci.channel = 0xff; /* unused */ + break; + default: + DBGC ( sandev, "INT13 drive %02x unrecognised bus type %d\n", + sandev->drive, desc->bus_type ); + return -ENOTSUP; + } + + /* Get EDD block device description */ + if ( ( rc = edd_describe ( &sanpath->block, &dpi->interface_type, + &dpi->device_path ) ) != 0 ) { + DBGC ( sandev, "INT13 drive %02x cannot identify block device: " + "%s\n", sandev->drive, strerror ( rc ) ); + return rc; + } + + /* Fill in common fields and fix checksum */ + dpi->key = EDD_DEVICE_PATH_INFO_KEY; + dpi->len = sizeof ( *dpi ); + for ( i = 0 ; i < sizeof ( *dpi ) ; i++ ) + sum += *( ( ( uint8_t * ) dpi ) + i ); + dpi->checksum -= sum; + + return 0; +} + +/** + * INT 13, 48 - Get extended parameters + * + * @v sandev SAN device + * @v ds:si Drive parameter table + * @ret status Status code + */ +static int int13_get_extended_parameters ( struct san_device *sandev, + struct i386_all_regs *ix86 ) { + struct int13_data *int13 = sandev->priv; + struct int13_disk_parameters params; + struct segoff address; + size_t len = sizeof ( params ); + uint16_t bufsize; + int rc; + + /* Get buffer size */ + get_real ( bufsize, ix86->segs.ds, + ( ix86->regs.si + offsetof ( typeof ( params ), bufsize ))); + + DBGC2 ( sandev, "Get extended drive parameters to %04x:%04x+%02x\n", + ix86->segs.ds, ix86->regs.si, bufsize ); + + /* Build drive parameters */ + memset ( ¶ms, 0, sizeof ( params ) ); + params.flags = INT13_FL_DMA_TRANSPARENT; + if ( ( int13->cylinders < 1024 ) && + ( sandev_capacity ( sandev ) <= INT13_MAX_CHS_SECTORS ) ) { + params.flags |= INT13_FL_CHS_VALID; + } + params.cylinders = int13->cylinders; + params.heads = int13->heads; + params.sectors_per_track = int13->sectors_per_track; + params.sectors = sandev_capacity ( sandev ); + params.sector_size = sandev_blksize ( sandev ); + memset ( ¶ms.dpte, 0xff, sizeof ( params.dpte ) ); + if ( ( rc = int13_device_path_info ( sandev, ¶ms.dpi ) ) != 0 ) { + DBGC ( sandev, "INT13 drive %02x could not provide device " + "path information: %s\n", + sandev->drive, strerror ( rc ) ); + len = offsetof ( typeof ( params ), dpi ); + } + + /* Calculate returned "buffer size" (which will be less than + * the length actually copied if device path information is + * present). + */ + if ( bufsize < offsetof ( typeof ( params ), dpte ) ) + return -INT13_STATUS_INVALID; + if ( bufsize < offsetof ( typeof ( params ), dpi ) ) { + params.bufsize = offsetof ( typeof ( params ), dpte ); + } else { + params.bufsize = offsetof ( typeof ( params ), dpi ); + } + + DBGC ( sandev, "INT 13 drive %02x described using extended " + "parameters:\n", sandev->drive ); + address.segment = ix86->segs.ds; + address.offset = ix86->regs.si; + DBGC_HDA ( sandev, address, ¶ms, len ); + + /* Return drive parameters */ + if ( len > bufsize ) + len = bufsize; + copy_to_real ( ix86->segs.ds, ix86->regs.si, ¶ms, len ); + + return 0; +} + +/** + * INT 13, 4b - Get status or terminate CD-ROM emulation + * + * @v sandev SAN device + * @v ds:si Specification packet + * @ret status Status code + */ +static int int13_cdrom_status_terminate ( struct san_device *sandev, + struct i386_all_regs *ix86 ) { + struct int13_cdrom_specification specification; + + DBGC2 ( sandev, "Get CD-ROM emulation status to %04x:%04x%s\n", + ix86->segs.ds, ix86->regs.si, + ( ix86->regs.al ? "" : " and terminate" ) ); + + /* Fail if we are not a CD-ROM */ + if ( ! sandev->is_cdrom ) { + DBGC ( sandev, "INT13 drive %02x is not a CD-ROM\n", + sandev->drive ); + return -INT13_STATUS_INVALID; + } + + /* Build specification packet */ + memset ( &specification, 0, sizeof ( specification ) ); + specification.size = sizeof ( specification ); + specification.drive = sandev->drive; + + /* Return specification packet */ + copy_to_real ( ix86->segs.ds, ix86->regs.si, &specification, + sizeof ( specification ) ); + + return 0; +} + + +/** + * INT 13, 4d - Read CD-ROM boot catalog + * + * @v sandev SAN device + * @v ds:si Command packet + * @ret status Status code + */ +static int int13_cdrom_read_boot_catalog ( struct san_device *sandev, + struct i386_all_regs *ix86 ) { + struct int13_data *int13 = sandev->priv; + struct int13_cdrom_boot_catalog_command command; + unsigned int start; + int rc; + + /* Read parameters from command packet */ + copy_from_real ( &command, ix86->segs.ds, ix86->regs.si, + sizeof ( command ) ); + DBGC2 ( sandev, "Read CD-ROM boot catalog to %08x\n", command.buffer ); + + /* Fail if we have no boot catalog */ + if ( ! int13->boot_catalog ) { + DBGC ( sandev, "INT13 drive %02x has no boot catalog\n", + sandev->drive ); + return -INT13_STATUS_INVALID; + } + start = ( int13->boot_catalog + command.start ); + + /* Read from boot catalog */ + if ( ( rc = sandev_read ( sandev, start, command.count, + phys_to_user ( command.buffer ) ) ) != 0 ) { + DBGC ( sandev, "INT13 drive %02x could not read boot catalog: " + "%s\n", sandev->drive, strerror ( rc ) ); + return -INT13_STATUS_READ_ERROR; + } + + return 0; +} + + + +/** + * INT 13 handler + * + */ +static __asmcall void int13 ( struct i386_all_regs *ix86 ) { + int command = ix86->regs.ah; + unsigned int bios_drive = ix86->regs.dl; + struct san_device *sandev; + struct int13_data *int13; + int status; + + /* We simulate a cdrom, so no need to sync hd drive number */ + //int13_check_num_drives(); + + #if VTOY_DEBUG + printf("int13 0x%x 0x%x\n", bios_drive, command); sleep(1); + #endif + + if (bios_drive == VENTOY_BIOS_FAKE_DRIVE) + { + ix86->regs.dl = g_sandev->exdrive; + return; + } + + if (VENTOY_BOOT_FIXBIN_DRIVE == bios_drive && INT13_READ_SECTORS == command) + { + /* read sector 0 0x80 */ + if (ix86->regs.dh == 0 && (ix86->regs.cl & 0x3f) == 1 && ix86->regs.al == 1) + { + userptr_t buffer; + + buffer = real_to_user(ix86->segs.es, ix86->regs.bx); + if (buffer) + { + memset((void *)buffer, 0, 512); + } + + ix86->regs.dl = 0x80; + ix86->regs.ah = 0; + + /* Set OF to indicate to wrapper not to chain this call */ + ix86->flags |= OF; + return; + } + } + + // drive swap + if (g_drive_map1 >= 0x80 && g_drive_map2 >= 0x80) + { + if (bios_drive == g_drive_map1) + { + ix86->regs.dl = g_drive_map2; + return; + } + else if (bios_drive == g_drive_map2) + { + ix86->regs.dl = g_drive_map1; + return; + } + } + + for_each_sandev ( sandev ) { + + int13 = sandev->priv; + if ( bios_drive != sandev->drive ) { + /* Remap any accesses to this drive's natural number */ + if ( bios_drive == int13->natural_drive ) { + DBGC2 ( sandev, "INT13,%02x (%02x) remapped to " + "(%02x)\n", ix86->regs.ah, + bios_drive, sandev->drive ); + ix86->regs.dl = sandev->drive; + return; + } else if ( ( ( bios_drive & 0x7f ) == 0x7f ) && + ( command == INT13_CDROM_STATUS_TERMINATE ) + && sandev->is_cdrom ) { + + /* Catch non-drive-specific CD-ROM calls */ + } else { + return; + } + } + + sandev->int13_command = command; + sandev->x86_regptr = ix86; + + DBGC2 ( sandev, "INT13,%02x (%02x): ", + ix86->regs.ah, bios_drive ); + + switch ( command ) { + case INT13_RESET: + status = int13_reset ( sandev, ix86 ); + break; + case INT13_GET_LAST_STATUS: + status = int13_get_last_status ( sandev, ix86 ); + break; + case INT13_READ_SECTORS: + status = int13_read_sectors ( sandev, ix86 ); + break; + case INT13_WRITE_SECTORS: + status = int13_write_sectors ( sandev, ix86 ); + break; + case INT13_GET_PARAMETERS: + status = int13_get_parameters ( sandev, ix86 ); + break; + case INT13_GET_DISK_TYPE: + status = int13_get_disk_type ( sandev, ix86 ); + break; + case INT13_EXTENSION_CHECK: + status = int13_extension_check ( sandev, ix86 ); + break; + case INT13_EXTENDED_READ: + status = int13_extended_read ( sandev, ix86 ); + break; + case INT13_EXTENDED_WRITE: + status = int13_extended_write ( sandev, ix86 ); + break; + case INT13_EXTENDED_VERIFY: + status = int13_extended_verify ( sandev, ix86 ); + break; + case INT13_EXTENDED_SEEK: + status = int13_extended_seek ( sandev, ix86 ); + break; + case INT13_GET_EXTENDED_PARAMETERS: + status = int13_get_extended_parameters ( sandev, ix86 ); + break; + case INT13_CDROM_STATUS_TERMINATE: + status = int13_cdrom_status_terminate ( sandev, ix86 ); + break; + case INT13_CDROM_READ_BOOT_CATALOG: + status = int13_cdrom_read_boot_catalog ( sandev, ix86 ); + break; + default: + DBGC2 ( sandev, "*** Unrecognised INT13 ***\n" ); + status = -INT13_STATUS_INVALID; + break; + } + + /* Store status for INT 13,01 */ + int13->last_status = status; + + /* Negative status indicates an error */ + if ( status < 0 ) { + status = -status; + DBGC ( sandev, "INT13,%02x (%02x) failed with status " + "%02x\n", ix86->regs.ah, sandev->drive, status ); + } else { + ix86->flags &= ~CF; + } + ix86->regs.ah = status; + + /* Set OF to indicate to wrapper not to chain this call */ + ix86->flags |= OF; + + return; + } +} + +/** + * Hook INT 13 handler + * + */ +static void int13_hook_vector ( void ) { + /* Assembly wrapper to call int13(). int13() sets OF if we + * should not chain to the previous handler. (The wrapper + * clears CF and OF before calling int13()). + */ + __asm__ __volatile__ ( + TEXT16_CODE ( "\nint13_wrapper:\n\t" + /* Preserve %ax and %dx for future reference */ + "pushw %%bp\n\t" + "movw %%sp, %%bp\n\t" + "pushw %%ax\n\t" + "pushw %%dx\n\t" + /* Clear OF, set CF, call int13() */ + "orb $0, %%al\n\t" + "stc\n\t" + VIRT_CALL ( int13 ) + /* Chain if OF not set */ + "jo 1f\n\t" + "pushfw\n\t" + "lcall *%%cs:int13_vector\n\t" + "\n1:\n\t" + /* Overwrite flags for iret */ + "pushfw\n\t" + "popw 6(%%bp)\n\t" + /* Fix up %dl: + * + * INT 13,15 : do nothing if hard disk + * INT 13,08 : load with number of drives + * all others: restore original value + */ + "cmpb $0x15, -1(%%bp)\n\t" + "jne 2f\n\t" + "testb $0x80, -4(%%bp)\n\t" + "jnz 3f\n\t" + "\n2:\n\t" + "movb -4(%%bp), %%dl\n\t" + "cmpb $0x08, -1(%%bp)\n\t" + "jne 3f\n\t" + "testb $0x80, %%dl\n\t" + "movb %%cs:num_drives, %%dl\n\t" + "jnz 3f\n\t" + "movb %%cs:num_fdds, %%dl\n\t" + /* Return */ + "\n3:\n\t" + "movw %%bp, %%sp\n\t" + "popw %%bp\n\t" + "iret\n\t" ) : : ); + + hook_bios_interrupt ( 0x13, ( intptr_t ) int13_wrapper, &int13_vector ); +} + + + +/** + * Load and verify master boot record from INT 13 drive + * + * @v drive Drive number + * @v address Boot code address to fill in + * @ret rc Return status code + */ +static int int13_load_mbr ( unsigned int drive, struct segoff *address ) { + uint16_t magic; + + address->segment = 0; + address->offset = 0x7c00; + copy_to_real(address->segment, address->offset, g_sandev->boot_catalog_sector, 512); + + /* Check magic signature */ + get_real ( magic, address->segment, (address->offset + offsetof ( struct master_boot_record, magic ) ) ); + + if ( magic != INT13_MBR_MAGIC ) { + DBG ( "INT13 drive %02x does not contain a valid MBR\n", + drive ); + return -ENOEXEC; + } + + return 0; +} + +/** El Torito boot catalog command packet */ +static struct int13_cdrom_boot_catalog_command __data16 ( eltorito_cmd ) = { + .size = sizeof ( struct int13_cdrom_boot_catalog_command ), + .count = 1, + .buffer = 0x7c00, + .start = 0, +}; +#define eltorito_cmd __use_data16 ( eltorito_cmd ) + +/** El Torito disk address packet */ +static struct int13_disk_address __bss16 ( eltorito_address ); +#define eltorito_address __use_data16 ( eltorito_address ) + +/** + * Load and verify El Torito boot record from INT 13 drive + * + * @v drive Drive number + * @v address Boot code address to fill in + * @ret rc Return status code + */ +static int int13_load_eltorito ( unsigned int drive, struct segoff *address ) { + struct { + struct eltorito_validation_entry valid; + struct eltorito_boot_entry boot; + } __attribute__ (( packed )) catalog; + uint16_t status; + + if (g_sandev && g_sandev->drive == drive) + { + copy_to_user(phys_to_user ( eltorito_cmd.buffer ), 0, g_sandev->boot_catalog_sector, sizeof(g_sandev->boot_catalog_sector)); + } + else + { + /* Use INT 13, 4d to read the boot catalog */ + __asm__ __volatile__ ( REAL_CODE ( "stc\n\t" + "sti\n\t" + "int $0x13\n\t" + "sti\n\t" /* BIOS bugs */ + "jc 1f\n\t" + "xorw %%ax, %%ax\n\t" + "\n1:\n\t" ) + : "=a" ( status ) + : "a" ( 0x4d00 ), "d" ( drive ), + "S" ( __from_data16 ( &eltorito_cmd ) ) ); + if ( status ) { + DBG ( "INT13 drive %02x could not read El Torito boot catalog " + "(status %04x)\n", drive, status ); + return -EIO; + } + } + + copy_from_user ( &catalog, phys_to_user ( eltorito_cmd.buffer ), 0, + sizeof ( catalog ) ); + + /* Sanity checks */ + if ( catalog.valid.platform_id != ELTORITO_PLATFORM_X86 ) { + DBG ( "INT13 drive %02x El Torito specifies unknown platform " + "%02x\n", drive, catalog.valid.platform_id ); + return -ENOEXEC; + } + if ( catalog.boot.indicator != ELTORITO_BOOTABLE ) { + DBG ( "INT13 drive %02x El Torito is not bootable\n", drive ); + return -ENOEXEC; + } + if ( catalog.boot.media_type != ELTORITO_NO_EMULATION ) { + DBG ( "INT13 drive %02x El Torito requires emulation " + "type %02x\n", drive, catalog.boot.media_type ); + return -ENOTSUP; + } + DBG ( "INT13 drive %02x El Torito boot image at LBA %08x (count %d)\n", + drive, catalog.boot.start, catalog.boot.length ); + address->segment = ( catalog.boot.load_segment ? + catalog.boot.load_segment : 0x7c0 ); + address->offset = 0; + DBG ( "INT13 drive %02x El Torito boot image loads at %04x:%04x\n", + drive, address->segment, address->offset ); + + if (catalog.boot.length > 256) + { + if (g_debug) + { + printf("trim length from %d to 4\n", catalog.boot.length); + } + catalog.boot.length = 4; + } + + /* Use INT 13, 42 to read the boot image */ + eltorito_address.bufsize = + offsetof ( typeof ( eltorito_address ), buffer_phys ); + eltorito_address.count = catalog.boot.length; + eltorito_address.buffer = *address; + eltorito_address.lba = catalog.boot.start; + __asm__ __volatile__ ( REAL_CODE ( "stc\n\t" + "sti\n\t" + "int $0x13\n\t" + "sti\n\t" /* BIOS bugs */ + "jc 1f\n\t" + "xorw %%ax, %%ax\n\t" + "\n1:\n\t" ) + : "=a" ( status ) + : "a" ( 0x4200 ), "d" ( drive ), + "S" ( __from_data16 ( &eltorito_address ) ) ); + if ( status ) { + DBG ( "INT13 drive %02x could not read El Torito boot image " + "(status %04x)\n", drive, status ); + return -EIO; + } + + if (catalog.boot.length > 4) + { + isolinux_boot_info *bootinfo = NULL; + bootinfo = (isolinux_boot_info *)(real_to_user(address->segment, address->offset)); + if (0x7C6CEAFA == bootinfo->isolinux0 && 0x90900000 == bootinfo->isolinux1) + { + if (bootinfo->BootFileLocation == 0 && bootinfo->PvdLocation == 16 && + (bootinfo->BootFileLen / 2048) < catalog.boot.length && bootinfo->BootFileChecksum > 0) + { + if (g_debug) + { + printf("isolinux file location is 0, now fix it to %u ...\n", catalog.boot.start); + ventoy_debug_pause(); + } + bootinfo->BootFileLocation = catalog.boot.start; + } + } + } + + return 0; +} + +/** + * Hook INT 13 SAN device + * + * @v drive Drive number + * @v uris List of URIs + * @v count Number of URIs + * @v flags Flags + * @ret drive Drive number, or negative error + * + * Registers the drive with the INT 13 emulation subsystem, and hooks + * the INT 13 interrupt vector (if not already hooked). + */ +unsigned int ventoy_int13_hook (ventoy_chain_head *chain) +{ + unsigned int blocks; + unsigned int blocks_per_cyl; + unsigned int natural_drive; + struct int13_data *int13; + + /* We simulate a cdrom, so no need to sync hd drive number */ + //int13_sync_num_drives(); + + /* hook will copy num_drives to dl when int13 08 was called, so must initialize it's value */ + get_real(num_drives, BDA_SEG, BDA_NUM_DRIVES); + + if (g_hddmode) + { + natural_drive = g_bios_disk80 ? 0x80 : (num_drives | 0x80); + } + else + { + natural_drive = 0xE0; /* just set a cdrom drive number 224 */ + } + + if (chain->os_param.vtoy_reserved[6]) + { + if (g_hddmode) + { + /* drive map no need for linux vtoy/img boot */ + } + else + { + g_drive_map1 = 0x80; + g_drive_map2 = 0x81; + } + } + else if (chain->disk_drive >= 0x80 && chain->drive_map >= 0x80) + { + g_drive_map1 = chain->disk_drive; + g_drive_map2 = chain->drive_map; + } + + /* a fake sandev */ + g_sandev = zalloc(sizeof(struct san_device) + sizeof(struct int13_data)); + g_sandev->priv = int13 = (struct int13_data *)(g_sandev + 1); + g_sandev->drive = int13->natural_drive = natural_drive; + g_sandev->is_cdrom = g_hddmode ? 0 : 1; + g_sandev->blksize_shift = g_hddmode ? 0 : 2; + g_sandev->capacity.blksize = 512; + g_sandev->capacity.blocks = chain->virt_img_size_in_bytes / 512; + g_sandev->exdrive = chain->disk_drive; + int13->boot_catalog = chain->boot_catalog; + memcpy(g_sandev->boot_catalog_sector, chain->boot_catalog_sector, sizeof(chain->boot_catalog_sector)); + + + /* Apply guesses if no geometry already specified */ + if ( ! int13->heads ) + int13->heads = 255; + if ( ! int13->sectors_per_track ) + int13->sectors_per_track = 63; + if ( ! int13->cylinders ) { + /* Avoid attempting a 64-bit divide on a 32-bit system */ + blocks = int13_capacity32 ( g_sandev ); + blocks_per_cyl = ( int13->heads * int13->sectors_per_track ); + + int13->cylinders = ( blocks / blocks_per_cyl ); + if ( int13->cylinders > 1024 ) + int13->cylinders = 1024; + } + + /* Hook INT 13 vector if not already hooked */ + int13_hook_vector(); + + /* Update BIOS drive count */ + //int13_sync_num_drives(); + + return natural_drive; +} + +static uint8_t __bss16_array ( xbftab, [512 + 128]) + __attribute__ (( aligned ( 16 ) )); +#define xbftab __use_data16 ( xbftab ) + +void * ventoy_get_runtime_addr(void) +{ + return (void *)user_to_phys((userptr_t)(&xbftab), 0); +} + +/** + * Attempt to boot from an INT 13 drive + * + * @v drive Drive number + * @v filename Filename (or NULL to use default) + * @ret rc Return status code + * + * This boots from the specified INT 13 drive by loading the Master + * Boot Record to 0000:7c00 and jumping to it. INT 18 is hooked to + * capture an attempt by the MBR to boot the next device. (This is + * the closest thing to a return path from an MBR). + * + * Note that this function can never return success, by definition. + */ +int ventoy_int13_boot ( unsigned int drive, void *imginfo, const char *cmdline) { + //struct memory_map memmap; + int rc; + int headlen; + struct segoff address; + struct acpi_header *acpi = NULL; + struct ibft_table *ibft = NULL; + + /* Look for a usable boot sector */ + if (g_hddmode) + { + if ((rc = int13_load_mbr(drive, &address)) != 0) + { + printf("int13_load_mbr %d\n", rc); + return rc; + } + } + else + { + if ( ( ( rc = int13_load_eltorito ( drive, &address ) ) != 0 ) && + ( ( rc = int13_load_mbr ( drive, &address ) ) != 0 )) + return rc; + } + + if (imginfo) + { + if (strstr(cmdline, "ibft")) + { + headlen = 80; + ibft = (struct ibft_table *)(&xbftab); + acpi = &(ibft->acpi); + memset(ibft, 0, headlen); + + acpi->signature = IBFT_SIG; + acpi->length = headlen + sizeof(ventoy_os_param); + acpi->revision = 1; + strncpy(acpi->oem_id, "ventoy", sizeof(acpi->oem_id)); + strncpy(acpi->oem_table_id, "runtime", sizeof(acpi->oem_table_id)); + memcpy((uint8_t *)ibft + headlen, imginfo, sizeof(ventoy_os_param)); + acpi_fix_checksum(acpi); + } + else + { + memcpy((&xbftab), imginfo, sizeof(ventoy_os_param)); + } + } + + /* Dump out memory map prior to boot, if memmap debugging is + * enabled. Not required for program flow, but we have so + * many problems that turn out to be memory-map related that + * it's worth doing. + */ + //get_memmap ( &memmap ); + + DBGC(g_sandev, "start to boot ...\n"); + + /* Jump to boot sector */ + if ( ( rc = call_bootsector ( address.segment, address.offset, + drive ) ) != 0 ) { + return rc; + } + + return -ECANCELED; /* -EIMPOSSIBLE */ +} + diff --git a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/interface/pcbios/ventoy_int13.h b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/interface/pcbios/ventoy_int13.h new file mode 100644 index 0000000..e6fe545 --- /dev/null +++ b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/interface/pcbios/ventoy_int13.h @@ -0,0 +1,48 @@ + +#ifndef __VENTOY_INT13_H__ +#define __VENTOY_INT13_H__ + +#undef for_each_sandev +#define for_each_sandev( sandev ) sandev = g_sandev; if (sandev) + +int ventoy_vdisk_read(struct san_device*sandev, uint64_t lba, unsigned int count, unsigned long buffer); + +static inline int ventoy_sandev_write ( struct san_device *sandev, uint64_t lba, unsigned int count, unsigned long buffer ) +{ + (void)sandev; + (void)lba; + (void)count; + (void)buffer; + DBGC(sandev, "ventoy_sandev_write\n"); + return 0; +} + +static inline int ventoy_sandev_reset (void *sandev) +{ + (void)sandev; + DBGC(sandev, "ventoy_sandev_reset\n"); + return 0; +} + +#define sandev_reset ventoy_sandev_reset +#define sandev_read ventoy_vdisk_read +#define sandev_write ventoy_sandev_write + +#undef ECANCELED +#define ECANCELED 0x0b +#undef ENODEV +#define ENODEV 0x2c +#undef ENOTSUP +#define ENOTSUP 0x3c +#undef ENOMEM +#define ENOMEM 0x31 +#undef EIO +#define EIO 0x1d +#undef ENOEXEC +#define ENOEXEC 0x2e +#undef ENOSPC +#define ENOSPC 0x34 + + +#endif /* __VENTOY_INT13_H__ */ + diff --git a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/build.sh b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/build.sh new file mode 100644 index 0000000..e8417a2 --- /dev/null +++ b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/build.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +build_bios() { + rm -f bin/ipxe.iso + + make -e -k -j 8 bin/ipxe.iso BIOS_MODE=BIOS + + if ! [ -e bin/ipxe.iso ]; then + echo "Failed" + exit 1 + fi + + mkdir -p ./mnt + mount bin/ipxe.iso ./mnt + + rm -f ../../../INSTALL/ventoy/ipxe.krn + cp -a ./mnt/ipxe.krn ../../../INSTALL/ventoy/ipxe.krn + + umount ./mnt > /dev/null 2>&1 + umount ./mnt > /dev/null 2>&1 + umount ./mnt > /dev/null 2>&1 + + rm -rf ./mnt + + echo -e "\n===============SUCCESS===============\n" +} + + +build_bios + + diff --git a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/config/settings.h b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/config/settings.h new file mode 100644 index 0000000..8c22e1f --- /dev/null +++ b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/config/settings.h @@ -0,0 +1,24 @@ +#ifndef CONFIG_SETTINGS_H +#define CONFIG_SETTINGS_H + +/** @file + * + * Configuration settings sources + * + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +//#define PCI_SETTINGS /* PCI device settings */ +//#define CPUID_SETTINGS /* CPUID settings */ +//#define MEMMAP_SETTINGS /* Memory map settings */ +//#define VMWARE_SETTINGS /* VMware GuestInfo settings */ +//#define VRAM_SETTINGS /* Video RAM dump settings */ +//#define ACPI_SETTINGS /* ACPI settings */ + +#include +#include NAMED_CONFIG(settings.h) +#include +#include LOCAL_NAMED_CONFIG(settings.h) + +#endif /* CONFIG_SETTINGS_H */ diff --git a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/core/device.c b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/core/device.c new file mode 100644 index 0000000..d3909b4 --- /dev/null +++ b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/core/device.c @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2006 Michael Brown . + * + * 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 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. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#include +#include +#include +#include +#include +#include + +/** + * @file + * + * Device model + * + */ + +/** Registered root devices */ +static LIST_HEAD ( devices ); + +/** Device removal inhibition counter */ +int device_keep_count = 0; + +/** + * Probe a root device + * + * @v rootdev Root device + * @ret rc Return status code + */ +static int rootdev_probe ( struct root_device *rootdev ) { + int rc; + + DBG ( "Adding %s root bus\n", rootdev->dev.name ); + if ( ( rc = rootdev->driver->probe ( rootdev ) ) != 0 ) { + DBG ( "Failed to add %s root bus: %s\n", + rootdev->dev.name, strerror ( rc ) ); + return rc; + } + + return 0; +} + +/** + * Remove a root device + * + * @v rootdev Root device + */ +static void rootdev_remove ( struct root_device *rootdev ) { + rootdev->driver->remove ( rootdev ); + DBG ( "Removed %s root bus\n", rootdev->dev.name ); +} + +/** + * Probe all devices + * + * This initiates probing for all devices in the system. After this + * call, the device hierarchy will be populated, and all hardware + * should be ready to use. + */ +static void probe_devices ( void ) { + struct root_device *rootdev; + int rc; + + for_each_table_entry ( rootdev, ROOT_DEVICES ) { + list_add ( &rootdev->dev.siblings, &devices ); + INIT_LIST_HEAD ( &rootdev->dev.children ); + if ( ( rc = rootdev_probe ( rootdev ) ) != 0 ) + list_del ( &rootdev->dev.siblings ); + } +} + +/** + * Remove all devices + * + */ +static void remove_devices ( int booting __unused ) { + struct root_device *rootdev; + struct root_device *tmp; + + if ( device_keep_count != 0 ) { + DBG ( "Refusing to remove devices on shutdown\n" ); + return; + } + + list_for_each_entry_safe ( rootdev, tmp, &devices, dev.siblings ) { + rootdev_remove ( rootdev ); + list_del ( &rootdev->dev.siblings ); + } +} + +//struct startup_fn startup_devices __startup_fn ( STARTUP_NORMAL ) = { +struct startup_fn startup_devices = { + .name = "devices", + .startup = probe_devices, + .shutdown = remove_devices, +}; + +/** + * Identify a device behind an interface + * + * @v intf Interface + * @ret device Device, or NULL + */ +struct device * identify_device ( struct interface *intf ) { + struct interface *dest; + identify_device_TYPE ( void * ) *op = + intf_get_dest_op ( intf, identify_device, &dest ); + void *object = intf_object ( dest ); + void *device; + + if ( op ) { + device = op ( object ); + } else { + /* Default is to return NULL */ + device = NULL; + } + + intf_put ( dest ); + return device; +} diff --git a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/core/main.c b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/core/main.c new file mode 100644 index 0000000..6a60ad3 --- /dev/null +++ b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/core/main.c @@ -0,0 +1,47 @@ +/************************************************************************** +iPXE - Network Bootstrap Program + +Literature dealing with the network protocols: + ARP - RFC826 + RARP - RFC903 + UDP - RFC768 + BOOTP - RFC951, RFC2132 (vendor extensions) + DHCP - RFC2131, RFC2132 (options) + TFTP - RFC1350, RFC2347 (options), RFC2348 (blocksize), RFC2349 (tsize) + RPC - RFC1831, RFC1832 (XDR), RFC1833 (rpcbind/portmapper) + +**************************************************************************/ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#include +#include +#include +#include +#include +#include + +/** + * Main entry point + * + * @ret rc Return status code + */ +__asmcall int main ( void ) { + int rc; + + /* Perform one-time-only initialisation (e.g. heap) */ + initialise(); + + /* Some devices take an unreasonably long time to initialise */ + //printf ( "%s initialising devices...", product_short_name ); + startup(); + //printf ( "ok\n" ); + + /* Attempt to boot */ + if ( ( rc = ventoy_boot_vdisk ( NULL ) ) != 0 ) + goto err_ipxe; + + err_ipxe: + shutdown_exit(); + return rc; +} diff --git a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/core/ventoy_dummy.c b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/core/ventoy_dummy.c new file mode 100644 index 0000000..ee7d114 --- /dev/null +++ b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/core/ventoy_dummy.c @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2017 Michael Brown . + * + * 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 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. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +/** + * @file + * + * SAN booting + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +unsigned long pci_bar_size ( struct pci_device *pci, unsigned int reg ) +{ + (void)pci; + (void)reg; + + return 0; +} + +unsigned long pci_bar_start ( struct pci_device *pci, unsigned int reg ) +{ + (void)pci; + (void)reg; + return 0; +} + +void adjust_pci_device ( struct pci_device *pci ) +{ + (void)pci; +} + +/* + * obj_netfront + * obj_netvsc + * + * ibft_model + */ + +int scsi_parse_lun ( const char *lun_string, struct scsi_lun *lun ) +{ + (void)lun_string; + (void)lun; + return 0; +} + +void scsi_parse_sense ( const void *data, size_t len, + struct scsi_sns_descriptor *sense ) +{ + (void)data; + (void)len; + (void)sense; + + return; +} + +void scsi_response ( struct interface *intf, struct scsi_rsp *response ) +{ + (void)intf; + (void)response; +} +int scsi_open ( struct interface *block, struct interface *scsi, + struct scsi_lun *lun ) +{ + (void)block; + (void)scsi; + (void)lun; + + return 0; +} + +int scsi_command ( struct interface *control, struct interface *data, + struct scsi_cmd *command ) +{ + (void)control; + (void)data; + (void)command; + + return 0; +} + + +int ata_open ( struct interface *block, struct interface *ata, + unsigned int device, unsigned int max_count ) +{ + (void)block; + (void)ata; + (void)device; + (void)max_count; + + return 0; +} + +int ata_command ( struct interface *control, struct interface *data, + struct ata_cmd *command ) +{ + (void)control; + (void)data; + (void)command; + + return 0; +} + +#if 0 +static uint32_t mCrcTable[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 +}; + +uint32_t CalculateCrc32 +( + const void *Buffer, + uint32_t Length, + uint32_t InitValue +) +{ + uint32_t Crc = 0; + uint32_t Index = 0; + const uint8_t *Ptr = (const uint8_t *)Buffer; + + Crc = InitValue ^ 0xffffffff; + for (Index = 0; Index < Length; Index++, Ptr++) + { + Crc = (Crc >> 8) ^ mCrcTable[(uint8_t) Crc ^ *Ptr]; + } + + return (Crc ^ 0xffffffff); +} + +#endif + diff --git a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/core/vsprintf.c b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/core/vsprintf.c new file mode 100644 index 0000000..4a231b4 --- /dev/null +++ b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/core/vsprintf.c @@ -0,0 +1,501 @@ +/* + * Copyright (C) 2006 Michael Brown . + * + * 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 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. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#include +#include +#include +#include +#include +#include + +/** @file */ + +#define CHAR_LEN 0 /**< "hh" length modifier */ +#define SHORT_LEN 1 /**< "h" length modifier */ +#define INT_LEN 2 /**< no length modifier */ +#define LONG_LEN 3 /**< "l" length modifier */ +#define LONGLONG_LEN 4 /**< "ll" length modifier */ +#define SIZE_T_LEN 5 /**< "z" length modifier */ + +static uint8_t type_sizes[] = { + [CHAR_LEN] = sizeof ( char ), + [SHORT_LEN] = sizeof ( short ), + [INT_LEN] = sizeof ( int ), + [LONG_LEN] = sizeof ( long ), + [LONGLONG_LEN] = sizeof ( long long ), + [SIZE_T_LEN] = sizeof ( size_t ), +}; + +/** + * Use lower-case for hexadecimal digits + * + * Note that this value is set to 0x20 since that makes for very + * efficient calculations. (Bitwise-ORing with @c LCASE converts to a + * lower-case character, for example.) + */ +#define LCASE 0x20 + +/** + * Use "alternate form" + * + * For hexadecimal numbers, this means to add a "0x" or "0X" prefix to + * the number. + */ +#define ALT_FORM 0x02 + +/** + * Use zero padding + * + * Note that this value is set to 0x10 since that allows the pad + * character to be calculated as @c 0x20|(flags&ZPAD) + */ +#define ZPAD 0x10 + +/** + * Format a hexadecimal number + * + * @v end End of buffer to contain number + * @v num Number to format + * @v width Minimum field width + * @v flags Format flags + * @ret ptr End of buffer + * + * Fills a buffer in reverse order with a formatted hexadecimal + * number. The number will be zero-padded to the specified width. + * Lower-case and "alternate form" (i.e. "0x" prefix) flags may be + * set. + * + * There must be enough space in the buffer to contain the largest + * number that this function can format. + */ +static char * format_hex ( char *end, unsigned long long num, int width, + int flags ) { + char *ptr = end; + int case_mod = ( flags & LCASE ); + int pad = ( ( flags & ZPAD ) | ' ' ); + + /* Generate the number */ + do { + *(--ptr) = "0123456789ABCDEF"[ num & 0xf ] | case_mod; + num >>= 4; + } while ( num ); + + /* Pad to width */ + while ( ( end - ptr ) < width ) + *(--ptr) = pad; + + /* Add "0x" or "0X" if alternate form specified */ + if ( flags & ALT_FORM ) { + *(--ptr) = 'X' | case_mod; + *(--ptr) = '0'; + } + + return ptr; +} + +/** + * Format a decimal number + * + * @v end End of buffer to contain number + * @v num Number to format + * @v width Minimum field width + * @v flags Format flags + * @ret ptr End of buffer + * + * Fills a buffer in reverse order with a formatted decimal number. + * The number will be space-padded to the specified width. + * + * There must be enough space in the buffer to contain the largest + * number that this function can format. + */ +static char * format_decimal ( char *end, signed long num, int width, + int flags ) { + char *ptr = end; + int negative = 0; + int zpad = ( flags & ZPAD ); + int pad = ( zpad | ' ' ); + + /* Generate the number */ + if ( num < 0 ) { + negative = 1; + num = -num; + } + do { + *(--ptr) = '0' + ( num % 10 ); + num /= 10; + } while ( num ); + + /* Add "-" if necessary */ + if ( negative && ( ! zpad ) ) + *(--ptr) = '-'; + + /* Pad to width */ + while ( ( end - ptr ) < width ) + *(--ptr) = pad; + + /* Add "-" if necessary */ + if ( negative && zpad ) + *ptr = '-'; + + return ptr; +} + +#define ZPAD 0x10 +char *format_unsigned_decimal(char *end, unsigned long long num, int width, int flags) +{ + char *ptr = end; + int zpad = ( flags & ZPAD ); + int pad = ( zpad | ' ' ); + + do { + *(--ptr) = '0' + ( num % 10 ); + num /= 10; + } while ( num ); + + /* Pad to width */ + while ( ( end - ptr ) < width ) + *(--ptr) = pad; + + return ptr; +} + +/** + * Print character via a printf context + * + * @v ctx Context + * @v c Character + * + * Call's the printf_context::handler() method and increments + * printf_context::len. + */ +static inline void cputchar ( struct printf_context *ctx, unsigned char c ) { + ctx->handler ( ctx, c ); + ++ctx->len; +} + +/** + * Write a formatted string to a printf context + * + * @v ctx Context + * @v fmt Format string + * @v args Arguments corresponding to the format string + * @ret len Length of formatted string + */ +size_t vcprintf ( struct printf_context *ctx, const char *fmt, va_list args ) { + int flags; + int width; + uint8_t *length; + char *ptr; + char tmp_buf[32]; /* 32 is enough for all numerical formats. + * Insane width fields could overflow this buffer. */ + wchar_t *wptr; + + /* Initialise context */ + ctx->len = 0; + + for ( ; *fmt ; fmt++ ) { + /* Pass through ordinary characters */ + if ( *fmt != '%' ) { + cputchar ( ctx, *fmt ); + continue; + } + fmt++; + /* Process flag characters */ + flags = 0; + for ( ; ; fmt++ ) { + if ( *fmt == '#' ) { + flags |= ALT_FORM; + } else if ( *fmt == '0' ) { + flags |= ZPAD; + } else { + /* End of flag characters */ + break; + } + } + /* Process field width */ + width = 0; + for ( ; ; fmt++ ) { + if ( ( ( unsigned ) ( *fmt - '0' ) ) < 10 ) { + width = ( width * 10 ) + ( *fmt - '0' ); + } else { + break; + } + } + /* We don't do floating point */ + /* Process length modifier */ + length = &type_sizes[INT_LEN]; + for ( ; ; fmt++ ) { + if ( *fmt == 'h' ) { + length--; + } else if ( *fmt == 'l' ) { + length++; + } else if ( *fmt == 'z' ) { + length = &type_sizes[SIZE_T_LEN]; + } else { + break; + } + } + /* Process conversion specifier */ + ptr = tmp_buf + sizeof ( tmp_buf ) - 1; + *ptr = '\0'; + wptr = NULL; + if ( *fmt == 'c' ) { + if ( length < &type_sizes[LONG_LEN] ) { + cputchar ( ctx, va_arg ( args, unsigned int ) ); + } else { + wchar_t wc; + size_t len; + + wc = va_arg ( args, wint_t ); + len = wcrtomb ( tmp_buf, wc, NULL ); + tmp_buf[len] = '\0'; + ptr = tmp_buf; + } + } else if ( *fmt == 's' ) { + if ( length < &type_sizes[LONG_LEN] ) { + ptr = va_arg ( args, char * ); + if ( ! ptr ) + ptr = ""; + } else { + wptr = va_arg ( args, wchar_t * ); + if ( ! wptr ) + ptr = ""; + } + } else if ( *fmt == 'p' ) { + intptr_t ptrval; + + ptrval = ( intptr_t ) va_arg ( args, void * ); + ptr = format_hex ( ptr, ptrval, width, + ( ALT_FORM | LCASE ) ); + } else if ( ( *fmt & ~0x20 ) == 'X' ) { + unsigned long long hex; + + flags |= ( *fmt & 0x20 ); /* LCASE */ + if ( *length >= sizeof ( unsigned long long ) ) { + hex = va_arg ( args, unsigned long long ); + } else if ( *length >= sizeof ( unsigned long ) ) { + hex = va_arg ( args, unsigned long ); + } else { + hex = va_arg ( args, unsigned int ); + } + ptr = format_hex ( ptr, hex, width, flags ); + } else if ( ( *fmt == 'd' ) || ( *fmt == 'i' ) ){ + signed long decimal; + + if ( *length >= sizeof ( signed long ) ) { + decimal = va_arg ( args, signed long ); + } else { + decimal = va_arg ( args, signed int ); + } + ptr = format_decimal ( ptr, decimal, width, flags ); + } else if ( ( *fmt == 'u' ) || ( *fmt == 'U' )){ + unsigned long long decimal; + if ( *length >= sizeof ( unsigned long long ) ) { + decimal = va_arg ( args, unsigned long long ); + } else if ( *length >= sizeof ( unsigned long ) ) { + decimal = va_arg ( args, unsigned long ); + } else { + decimal = va_arg ( args, unsigned int ); + } + ptr = format_unsigned_decimal( ptr, decimal, width, flags ); + } else { + *(--ptr) = *fmt; + } + /* Write out conversion result */ + if ( wptr == NULL ) { + for ( ; *ptr ; ptr++ ) { + cputchar ( ctx, *ptr ); + } + } else { + for ( ; *wptr ; wptr++ ) { + size_t len = wcrtomb ( tmp_buf, *wptr, NULL ); + for ( ptr = tmp_buf ; len-- ; ptr++ ) { + cputchar ( ctx, *ptr ); + } + } + } + } + + return ctx->len; +} + +/** Context used by vsnprintf() and friends */ +struct sputc_context { + struct printf_context ctx; + /** Buffer for formatted string (used by printf_sputc()) */ + char *buf; + /** Buffer length (used by printf_sputc()) */ + size_t max_len; +}; + +/** + * Write character to buffer + * + * @v ctx Context + * @v c Character + */ +static void printf_sputc ( struct printf_context *ctx, unsigned int c ) { + struct sputc_context * sctx = + container_of ( ctx, struct sputc_context, ctx ); + + if ( ctx->len < sctx->max_len ) + sctx->buf[ctx->len] = c; +} + +/** + * Write a formatted string to a buffer + * + * @v buf Buffer into which to write the string + * @v size Size of buffer + * @v fmt Format string + * @v args Arguments corresponding to the format string + * @ret len Length of formatted string + * + * If the buffer is too small to contain the string, the returned + * length is the length that would have been written had enough space + * been available. + */ +int vsnprintf ( char *buf, size_t size, const char *fmt, va_list args ) { + struct sputc_context sctx; + size_t len; + size_t end; + + /* Hand off to vcprintf */ + sctx.ctx.handler = printf_sputc; + sctx.buf = buf; + sctx.max_len = size; + len = vcprintf ( &sctx.ctx, fmt, args ); + + /* Add trailing NUL */ + if ( size ) { + end = size - 1; + if ( len < end ) + end = len; + buf[end] = '\0'; + } + + return len; +} + +/** + * Write a formatted string to a buffer + * + * @v buf Buffer into which to write the string + * @v size Size of buffer + * @v fmt Format string + * @v ... Arguments corresponding to the format string + * @ret len Length of formatted string + */ +int snprintf ( char *buf, size_t size, const char *fmt, ... ) { + va_list args; + int i; + + va_start ( args, fmt ); + i = vsnprintf ( buf, size, fmt, args ); + va_end ( args ); + return i; +} + +/** + * Version of vsnprintf() that accepts a signed buffer size + * + * @v buf Buffer into which to write the string + * @v size Size of buffer + * @v fmt Format string + * @v args Arguments corresponding to the format string + * @ret len Length of formatted string + */ +int vssnprintf ( char *buf, ssize_t ssize, const char *fmt, va_list args ) { + + /* Treat negative buffer size as zero buffer size */ + if ( ssize < 0 ) + ssize = 0; + + /* Hand off to vsnprintf */ + return vsnprintf ( buf, ssize, fmt, args ); +} + +/** + * Version of vsnprintf() that accepts a signed buffer size + * + * @v buf Buffer into which to write the string + * @v size Size of buffer + * @v fmt Format string + * @v ... Arguments corresponding to the format string + * @ret len Length of formatted string + */ +int ssnprintf ( char *buf, ssize_t ssize, const char *fmt, ... ) { + va_list args; + int len; + + /* Hand off to vssnprintf */ + va_start ( args, fmt ); + len = vssnprintf ( buf, ssize, fmt, args ); + va_end ( args ); + return len; +} + +/** + * Write character to console + * + * @v ctx Context + * @v c Character + */ +static void printf_putchar ( struct printf_context *ctx __unused, + unsigned int c ) { + putchar ( c ); +} + +/** + * Write a formatted string to the console + * + * @v fmt Format string + * @v args Arguments corresponding to the format string + * @ret len Length of formatted string + */ +int vprintf ( const char *fmt, va_list args ) { + struct printf_context ctx; + + /* Hand off to vcprintf */ + ctx.handler = printf_putchar; + return vcprintf ( &ctx, fmt, args ); +} + +/** + * Write a formatted string to the console. + * + * @v fmt Format string + * @v ... Arguments corresponding to the format string + * @ret len Length of formatted string + */ +int printf ( const char *fmt, ... ) { + va_list args; + int i; + + va_start ( args, fmt ); + i = vprintf ( fmt, args ); + va_end ( args ); + return i; +} diff --git a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/drivers/net/efi/snp.c b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/drivers/net/efi/snp.c new file mode 100644 index 0000000..8d15b6f --- /dev/null +++ b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/drivers/net/efi/snp.c @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2014 Michael Brown . + * + * 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 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. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#if 0 + +#include +#include +#include +#include +#include "snpnet.h" +#include "nii.h" + +/** @file + * + * SNP driver + * + */ + +/** + * Check to see if driver supports a device + * + * @v device EFI device handle + * @ret rc Return status code + */ +static int snp_supported ( EFI_HANDLE device ) { + EFI_BOOT_SERVICES *bs = efi_systab->BootServices; + EFI_STATUS efirc; + + /* Check that this is not a device we are providing ourselves */ + if ( find_snpdev ( device ) != NULL ) { + DBGCP ( device, "SNP %s is provided by this binary\n", + efi_handle_name ( device ) ); + return -ENOTTY; + } + + /* Test for presence of simple network protocol */ + if ( ( efirc = bs->OpenProtocol ( device, + &efi_simple_network_protocol_guid, + NULL, efi_image_handle, device, + EFI_OPEN_PROTOCOL_TEST_PROTOCOL))!=0){ + DBGCP ( device, "SNP %s is not an SNP device\n", + efi_handle_name ( device ) ); + return -EEFI ( efirc ); + } + DBGC ( device, "SNP %s is an SNP device\n", + efi_handle_name ( device ) ); + + return 0; +} + +/** + * Check to see if driver supports a device + * + * @v device EFI device handle + * @ret rc Return status code + */ +static int nii_supported ( EFI_HANDLE device ) { + EFI_BOOT_SERVICES *bs = efi_systab->BootServices; + EFI_STATUS efirc; + + /* Check that this is not a device we are providing ourselves */ + if ( find_snpdev ( device ) != NULL ) { + DBGCP ( device, "NII %s is provided by this binary\n", + efi_handle_name ( device ) ); + return -ENOTTY; + } + + /* Test for presence of NII protocol */ + if ( ( efirc = bs->OpenProtocol ( device, + &efi_nii31_protocol_guid, + NULL, efi_image_handle, device, + EFI_OPEN_PROTOCOL_TEST_PROTOCOL))!=0){ + DBGCP ( device, "NII %s is not an NII device\n", + efi_handle_name ( device ) ); + return -EEFI ( efirc ); + } + DBGC ( device, "NII %s is an NII device\n", + efi_handle_name ( device ) ); + + return 0; +} + +/** EFI SNP driver */ +struct efi_driver snp_driver __efi_driver ( EFI_DRIVER_NORMAL ) = { + .name = "SNP", + .supported = snp_supported, + .start = snpnet_start, + .stop = snpnet_stop, +}; + +/** EFI NII driver */ +struct efi_driver nii_driver __efi_driver ( EFI_DRIVER_NORMAL ) = { + .name = "NII", + .supported = nii_supported, + .start = nii_start, + .stop = nii_stop, +}; + +#endif + diff --git a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/include/ipxe/sanboot.h b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/include/ipxe/sanboot.h new file mode 100644 index 0000000..2c2639a --- /dev/null +++ b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/include/ipxe/sanboot.h @@ -0,0 +1,256 @@ +#ifndef _IPXE_SANBOOT_H +#define _IPXE_SANBOOT_H + +/** @file + * + * iPXE sanboot API + * + * The sanboot API provides methods for hooking, unhooking, + * describing, and booting from SAN devices. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** A SAN path */ +struct san_path { + /** Containing SAN device */ + struct san_device *sandev; + /** Path index */ + unsigned int index; + /** SAN device URI */ + struct uri *uri; + /** List of open/closed paths */ + struct list_head list; + + /** Underlying block device interface */ + struct interface block; + /** Process */ + struct process process; + /** Path status */ + int path_rc; + + /** ACPI descriptor (if applicable) */ + struct acpi_descriptor *desc; +}; + +/** A SAN device */ +struct san_device { + /** Reference count */ + struct refcnt refcnt; + /** List of SAN devices */ + struct list_head list; + + /** Drive number */ + unsigned int drive; + /** Flags */ + unsigned int flags; + + /** Command interface */ + struct interface command; + /** Command timeout timer */ + struct retry_timer timer; + /** Command status */ + int command_rc; + + /** Raw block device capacity */ + struct block_device_capacity capacity; + /** Block size shift + * + * To allow for emulation of CD-ROM access, this represents + * the left-shift required to translate from exposed logical + * I/O blocks to underlying blocks. + */ + unsigned int blksize_shift; + /** Drive is a CD-ROM */ + int is_cdrom; + + /** Driver private data */ + void *priv; + + /** Number of paths */ + unsigned int paths; + /** Current active path */ + struct san_path *active; + /** List of opened SAN paths */ + struct list_head opened; + /** List of closed SAN paths */ + struct list_head closed; + + unsigned int exdrive; + int int13_command; + void *x86_regptr; + uint8_t boot_catalog_sector[2048]; + + /** SAN paths */ + struct san_path path[0]; +}; + +/** SAN device flags */ +enum san_device_flags { + /** Device should not be included in description tables */ + SAN_NO_DESCRIBE = 0x0001, +}; + +/** + * Calculate static inline sanboot API function name + * + * @v _prefix Subsystem prefix + * @v _api_func API function + * @ret _subsys_func Subsystem API function + */ +#define SANBOOT_INLINE( _subsys, _api_func ) \ + SINGLE_API_INLINE ( SANBOOT_PREFIX_ ## _subsys, _api_func ) + +/** + * Provide a sanboot API implementation + * + * @v _prefix Subsystem prefix + * @v _api_func API function + * @v _func Implementing function + */ +#define PROVIDE_SANBOOT( _subsys, _api_func, _func ) \ + PROVIDE_SINGLE_API ( SANBOOT_PREFIX_ ## _subsys, _api_func, _func ) + +/** + * Provide a static inline sanboot API implementation + * + * @v _prefix Subsystem prefix + * @v _api_func API function + */ +#define PROVIDE_SANBOOT_INLINE( _subsys, _api_func ) \ + PROVIDE_SINGLE_API_INLINE ( SANBOOT_PREFIX_ ## _subsys, _api_func ) + +/* Include all architecture-independent sanboot API headers */ +#include +#include +#include + +/* Include all architecture-dependent sanboot API headers */ +#include + +/** + * Hook SAN device + * + * @v drive Drive number + * @v uris List of URIs + * @v count Number of URIs + * @v flags Flags + * @ret drive Drive number, or negative error + */ +int san_hook ( unsigned int drive, struct uri **uris, unsigned int count, + unsigned int flags ); + +/** + * Unhook SAN device + * + * @v drive Drive number + */ +void san_unhook ( unsigned int drive ); + +/** + * Attempt to boot from a SAN device + * + * @v drive Drive number + * @v filename Filename (or NULL to use default) + * @ret rc Return status code + */ +int san_boot ( unsigned int drive, const char *filename ); + +/** + * Describe SAN devices for SAN-booted operating system + * + * @ret rc Return status code + */ +int san_describe ( void ); + +extern struct list_head san_devices; + +/** Iterate over all SAN devices */ +#define for_each_sandev( sandev ) \ + list_for_each_entry ( (sandev), &san_devices, list ) + +/** There exist some SAN devices + * + * @ret existence Existence of SAN devices + */ +static inline int have_sandevs ( void ) { + return ( ! list_empty ( &san_devices ) ); +} + +/** + * Get reference to SAN device + * + * @v sandev SAN device + * @ret sandev SAN device + */ +static inline __attribute__ (( always_inline )) struct san_device * +sandev_get ( struct san_device *sandev ) { + ref_get ( &sandev->refcnt ); + return sandev; +} + +/** + * Drop reference to SAN device + * + * @v sandev SAN device + */ +static inline __attribute__ (( always_inline )) void +sandev_put ( struct san_device *sandev ) { + ref_put ( &sandev->refcnt ); +} + +/** + * Calculate SAN device block size + * + * @v sandev SAN device + * @ret blksize Sector size + */ +static inline size_t sandev_blksize ( struct san_device *sandev ) { + return ( sandev->capacity.blksize << sandev->blksize_shift ); +} + +/** + * Calculate SAN device capacity + * + * @v sandev SAN device + * @ret blocks Number of blocks + */ +static inline uint64_t sandev_capacity ( struct san_device *sandev ) { + return ( sandev->capacity.blocks >> sandev->blksize_shift ); +} + +/** + * Check if SAN device needs to be reopened + * + * @v sandev SAN device + * @ret needs_reopen SAN device needs to be reopened + */ +static inline int sandev_needs_reopen ( struct san_device *sandev ) { + return ( sandev->active == NULL ); +} + +extern struct san_device * sandev_find ( unsigned int drive ); +extern int sandev_reopen ( struct san_device *sandev ); +extern int sandev_reset ( struct san_device *sandev ); +extern int sandev_read ( struct san_device *sandev, uint64_t lba, + unsigned int count, userptr_t buffer ); +extern int sandev_write ( struct san_device *sandev, uint64_t lba, + unsigned int count, userptr_t buffer ); +extern struct san_device * alloc_sandev ( struct uri **uris, unsigned int count, + size_t priv_size ); +extern int register_sandev ( struct san_device *sandev, unsigned int drive, + unsigned int flags ); +extern void unregister_sandev ( struct san_device *sandev ); +extern unsigned int san_default_drive ( void ); + +#endif /* _IPXE_SANBOOT_H */ diff --git a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/include/ventoy.h b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/include/ventoy.h new file mode 100644 index 0000000..b759e9f --- /dev/null +++ b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/include/ventoy.h @@ -0,0 +1,251 @@ + +#ifndef __VENTOY_VDISK_H__ +#define __VENTOY_VDISK_H__ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +//#define VTOY_DEBUG 1 + +#define grub_uint64_t uint64_t +#define grub_uint32_t uint32_t +#define grub_uint16_t uint16_t +#define grub_uint8_t uint8_t + +#define COMPILE_ASSERT(expr) extern char __compile_assert[(expr) ? 1 : -1] + +#define VENTOY_GUID { 0x77772020, 0x2e77, 0x6576, { 0x6e, 0x74, 0x6f, 0x79, 0x2e, 0x6e, 0x65, 0x74 }} + +typedef enum ventoy_chain_type +{ + ventoy_chain_linux = 0, /* 0: linux */ + ventoy_chain_windows, /* 1: windows */ + ventoy_chain_wim, /* 2: wim */ + + ventoy_chain_max +}ventoy_chain_type; + +#pragma pack(1) + +typedef struct ventoy_guid +{ + grub_uint32_t data1; + grub_uint16_t data2; + grub_uint16_t data3; + grub_uint8_t data4[8]; +}ventoy_guid; + +typedef struct ventoy_image_disk_region +{ + grub_uint32_t image_sector_count; /* image sectors contained in this region */ + grub_uint32_t image_start_sector; /* image sector start */ + grub_uint64_t disk_start_sector; /* disk sector start */ +}ventoy_image_disk_region; + +typedef struct ventoy_image_location +{ + ventoy_guid guid; + + /* image sector size, 2048/512 */ + grub_uint32_t image_sector_size; + + /* disk sector size, normally the value is 512 */ + grub_uint32_t disk_sector_size; + + grub_uint32_t region_count; + + /* + * disk region data + * If the image file has more than one fragments in disk, + * there will be more than one region data here. + * + */ + ventoy_image_disk_region regions[1]; + + /* ventoy_image_disk_region regions[2~region_count-1] */ +}ventoy_image_location; + +typedef struct ventoy_os_param +{ + ventoy_guid guid; // VENTOY_GUID + grub_uint8_t chksum; // checksum + + grub_uint8_t vtoy_disk_guid[16]; + grub_uint64_t vtoy_disk_size; // disk size in bytes + grub_uint16_t vtoy_disk_part_id; // begin with 1 + grub_uint16_t vtoy_disk_part_type; // 0:exfat 1:ntfs other: reserved + char vtoy_img_path[384]; // It seems to be enough, utf-8 format + grub_uint64_t vtoy_img_size; // image file size in bytes + + /* + * Ventoy will write a copy of ventoy_image_location data into runtime memory + * this is the physically address and length of that memory. + * Address 0 means no such data exist. + * Address will be aligned by 4KB. + * + */ + grub_uint64_t vtoy_img_location_addr; + grub_uint32_t vtoy_img_location_len; + + grub_uint8_t vtoy_reserved[32]; // Internal use by ventoy + + grub_uint8_t vtoy_disk_signature[4]; + + grub_uint8_t reserved[27]; +}ventoy_os_param; + +typedef struct ventoy_iso9660_override +{ + uint32_t first_sector; + uint32_t first_sector_be; + uint32_t size; + uint32_t size_be; +}ventoy_iso9660_override; + +#pragma pack() + +// compile assert to check that size of ventoy_os_param must be 512 +COMPILE_ASSERT(sizeof(ventoy_os_param) == 512); + + + + + + + +#pragma pack(4) + +typedef struct ventoy_chain_head +{ + ventoy_os_param os_param; + + grub_uint32_t disk_drive; + grub_uint32_t drive_map; + grub_uint32_t disk_sector_size; + + grub_uint64_t real_img_size_in_bytes; + grub_uint64_t virt_img_size_in_bytes; + grub_uint32_t boot_catalog; + grub_uint8_t boot_catalog_sector[2048]; + + grub_uint32_t img_chunk_offset; + grub_uint32_t img_chunk_num; + + grub_uint32_t override_chunk_offset; + grub_uint32_t override_chunk_num; + + grub_uint32_t virt_chunk_offset; + grub_uint32_t virt_chunk_num; +}ventoy_chain_head; + + +typedef struct ventoy_img_chunk +{ + grub_uint32_t img_start_sector; //2KB + grub_uint32_t img_end_sector; + + grub_uint64_t disk_start_sector; // in disk_sector_size + grub_uint64_t disk_end_sector; +}ventoy_img_chunk; + + +typedef struct ventoy_override_chunk +{ + grub_uint64_t img_offset; + grub_uint32_t override_size; + grub_uint8_t override_data[512]; +}ventoy_override_chunk; + +typedef struct ventoy_virt_chunk +{ + grub_uint32_t mem_sector_start; + grub_uint32_t mem_sector_end; + grub_uint32_t mem_sector_offset; + grub_uint32_t remap_sector_start; + grub_uint32_t remap_sector_end; + grub_uint32_t org_sector_start; +}ventoy_virt_chunk; + + +#pragma pack() + + +#define ventoy_debug_pause() \ +{\ + printf("\nPress Ctrl+C to continue......");\ + sleep(3600);\ + printf("\n");\ +} + +typedef struct ventoy_sector_flag +{ + uint8_t flag; // 0:init 1:mem 2:remap + uint64_t remap_lba; +}ventoy_sector_flag; + +#define VENTOY_BIOS_FAKE_DRIVE 0xFE +#define VENTOY_BOOT_FIXBIN_DRIVE 0xFD + +extern int g_debug; +extern int g_hddmode; +extern int g_bios_disk80; +extern char *g_cmdline_copy; +extern void *g_initrd_addr; +extern size_t g_initrd_len; +extern uint32_t g_disk_sector_size; +unsigned int ventoy_int13_hook (ventoy_chain_head *chain); +int ventoy_int13_boot ( unsigned int drive, void *imginfo, const char *cmdline); +void * ventoy_get_runtime_addr(void); +int ventoy_boot_vdisk(void *data); + + +uint32_t CalculateCrc32 +( + const void *Buffer, + uint32_t Length, + uint32_t InitValue +); + +struct smbios3_entry { + + uint8_t signature[5]; + + /** Checksum */ + uint8_t checksum; + + /** Length */ + uint8_t len; + + /** Major version */ + uint8_t major; + + /** Minor version */ + uint8_t minor; + + uint8_t docrev; + + uint8_t revision; + + uint8_t reserved; + + uint32_t maxsize; + + uint64_t address; +} __attribute__ (( packed )); + + +typedef struct isolinux_boot_info +{ + uint32_t isolinux0; + uint32_t isolinux1; + uint32_t PvdLocation; + uint32_t BootFileLocation; + uint32_t BootFileLen; + uint32_t BootFileChecksum; + uint8_t Reserved[40]; +}isolinux_boot_info; + +//#undef DBGLVL +//#define DBGLVL 7 + +#endif /* __VENTOY_VDISK_H__ */ + diff --git a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/interface/efi/efi_pci.c b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/interface/efi/efi_pci.c new file mode 100644 index 0000000..6726ef3 --- /dev/null +++ b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/interface/efi/efi_pci.c @@ -0,0 +1,467 @@ +/* + * Copyright (C) 2008 Michael Brown . + * + * 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 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. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#if 0 + +#include +#include +#include +#include +#include +#include +#include +#include + +/** @file + * + * iPXE PCI I/O API for EFI + * + */ + +/* Disambiguate the various error causes */ +#define EINFO_EEFI_PCI \ + __einfo_uniqify ( EINFO_EPLATFORM, 0x01, \ + "Could not open PCI I/O protocol" ) +#define EINFO_EEFI_PCI_NOT_PCI \ + __einfo_platformify ( EINFO_EEFI_PCI, EFI_UNSUPPORTED, \ + "Not a PCI device" ) +#define EEFI_PCI_NOT_PCI __einfo_error ( EINFO_EEFI_PCI_NOT_PCI ) +#define EINFO_EEFI_PCI_IN_USE \ + __einfo_platformify ( EINFO_EEFI_PCI, EFI_ACCESS_DENIED, \ + "PCI device already has a driver" ) +#define EEFI_PCI_IN_USE __einfo_error ( EINFO_EEFI_PCI_IN_USE ) +#define EEFI_PCI( efirc ) \ + EPLATFORM ( EINFO_EEFI_PCI, efirc, \ + EEFI_PCI_NOT_PCI, EEFI_PCI_IN_USE ) + +/****************************************************************************** + * + * iPXE PCI API + * + ****************************************************************************** + */ + +/** + * Locate EFI PCI root bridge I/O protocol + * + * @v pci PCI device + * @ret handle EFI PCI root bridge handle + * @ret root EFI PCI root bridge I/O protocol, or NULL if not found + * @ret rc Return status code + */ +static int efipci_root ( struct pci_device *pci, EFI_HANDLE *handle, + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL **root ) { + EFI_BOOT_SERVICES *bs = efi_systab->BootServices; + EFI_HANDLE *handles; + UINTN num_handles; + union { + void *interface; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *root; + } u; + EFI_STATUS efirc; + UINTN i; + int rc; + + /* Enumerate all handles */ + if ( ( efirc = bs->LocateHandleBuffer ( ByProtocol, + &efi_pci_root_bridge_io_protocol_guid, + NULL, &num_handles, &handles ) ) != 0 ) { + rc = -EEFI ( efirc ); + DBGC ( pci, "EFIPCI " PCI_FMT " cannot locate root bridges: " + "%s\n", PCI_ARGS ( pci ), strerror ( rc ) ); + goto err_locate; + } + + /* Look for matching root bridge I/O protocol */ + for ( i = 0 ; i < num_handles ; i++ ) { + *handle = handles[i]; + if ( ( efirc = bs->OpenProtocol ( *handle, + &efi_pci_root_bridge_io_protocol_guid, + &u.interface, efi_image_handle, *handle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL ) ) != 0 ) { + rc = -EEFI ( efirc ); + DBGC ( pci, "EFIPCI " PCI_FMT " cannot open %s: %s\n", + PCI_ARGS ( pci ), efi_handle_name ( *handle ), + strerror ( rc ) ); + continue; + } + if ( u.root->SegmentNumber == PCI_SEG ( pci->busdevfn ) ) { + *root = u.root; + bs->FreePool ( handles ); + return 0; + } + bs->CloseProtocol ( *handle, + &efi_pci_root_bridge_io_protocol_guid, + efi_image_handle, *handle ); + } + DBGC ( pci, "EFIPCI " PCI_FMT " found no root bridge\n", + PCI_ARGS ( pci ) ); + rc = -ENOENT; + + bs->FreePool ( handles ); + err_locate: + return rc; +} + +/** + * Calculate EFI PCI configuration space address + * + * @v pci PCI device + * @v location Encoded offset and width + * @ret address EFI PCI address + */ +static unsigned long efipci_address ( struct pci_device *pci, + unsigned long location ) { + + return EFI_PCI_ADDRESS ( PCI_BUS ( pci->busdevfn ), + PCI_SLOT ( pci->busdevfn ), + PCI_FUNC ( pci->busdevfn ), + EFIPCI_OFFSET ( location ) ); +} + +/** + * Read from PCI configuration space + * + * @v pci PCI device + * @v location Encoded offset and width + * @ret value Value + * @ret rc Return status code + */ +int efipci_read ( struct pci_device *pci, unsigned long location, + void *value ) { + EFI_BOOT_SERVICES *bs = efi_systab->BootServices; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *root; + EFI_HANDLE handle; + EFI_STATUS efirc; + int rc; + + /* Identify root bridge */ + if ( ( rc = efipci_root ( pci, &handle, &root ) ) != 0 ) + goto err_root; + + /* Read from configuration space */ + if ( ( efirc = root->Pci.Read ( root, EFIPCI_WIDTH ( location ), + efipci_address ( pci, location ), 1, + value ) ) != 0 ) { + rc = -EEFI ( efirc ); + DBGC ( pci, "EFIPCI " PCI_FMT " config read from offset %02lx " + "failed: %s\n", PCI_ARGS ( pci ), + EFIPCI_OFFSET ( location ), strerror ( rc ) ); + goto err_read; + } + + err_read: + bs->CloseProtocol ( handle, &efi_pci_root_bridge_io_protocol_guid, + efi_image_handle, handle ); + err_root: + return rc; +} + +/** + * Write to PCI configuration space + * + * @v pci PCI device + * @v location Encoded offset and width + * @v value Value + * @ret rc Return status code + */ +int efipci_write ( struct pci_device *pci, unsigned long location, + unsigned long value ) { + EFI_BOOT_SERVICES *bs = efi_systab->BootServices; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *root; + EFI_HANDLE handle; + EFI_STATUS efirc; + int rc; + + /* Identify root bridge */ + if ( ( rc = efipci_root ( pci, &handle, &root ) ) != 0 ) + goto err_root; + + /* Read from configuration space */ + if ( ( efirc = root->Pci.Write ( root, EFIPCI_WIDTH ( location ), + efipci_address ( pci, location ), 1, + &value ) ) != 0 ) { + rc = -EEFI ( efirc ); + DBGC ( pci, "EFIPCI " PCI_FMT " config write to offset %02lx " + "failed: %s\n", PCI_ARGS ( pci ), + EFIPCI_OFFSET ( location ), strerror ( rc ) ); + goto err_write; + } + + err_write: + bs->CloseProtocol ( handle, &efi_pci_root_bridge_io_protocol_guid, + efi_image_handle, handle ); + err_root: + return rc; +} + +PROVIDE_PCIAPI_INLINE ( efi, pci_num_bus ); +PROVIDE_PCIAPI_INLINE ( efi, pci_read_config_byte ); +PROVIDE_PCIAPI_INLINE ( efi, pci_read_config_word ); +PROVIDE_PCIAPI_INLINE ( efi, pci_read_config_dword ); +PROVIDE_PCIAPI_INLINE ( efi, pci_write_config_byte ); +PROVIDE_PCIAPI_INLINE ( efi, pci_write_config_word ); +PROVIDE_PCIAPI_INLINE ( efi, pci_write_config_dword ); + +/****************************************************************************** + * + * EFI PCI device instantiation + * + ****************************************************************************** + */ + +/** + * Open EFI PCI device + * + * @v device EFI device handle + * @v attributes Protocol opening attributes + * @v pci PCI device to fill in + * @ret rc Return status code + */ +int efipci_open ( EFI_HANDLE device, UINT32 attributes, + struct pci_device *pci ) { + EFI_BOOT_SERVICES *bs = efi_systab->BootServices; + union { + EFI_PCI_IO_PROTOCOL *pci_io; + void *interface; + } pci_io; + UINTN pci_segment, pci_bus, pci_dev, pci_fn; + unsigned int busdevfn; + EFI_STATUS efirc; + int rc; + + /* See if device is a PCI device */ + if ( ( efirc = bs->OpenProtocol ( device, &efi_pci_io_protocol_guid, + &pci_io.interface, efi_image_handle, + device, attributes ) ) != 0 ) { + rc = -EEFI_PCI ( efirc ); + DBGCP ( device, "EFIPCI %s cannot open PCI protocols: %s\n", + efi_handle_name ( device ), strerror ( rc ) ); + goto err_open_protocol; + } + + /* Get PCI bus:dev.fn address */ + if ( ( efirc = pci_io.pci_io->GetLocation ( pci_io.pci_io, &pci_segment, + &pci_bus, &pci_dev, + &pci_fn ) ) != 0 ) { + rc = -EEFI ( efirc ); + DBGC ( device, "EFIPCI %s could not get PCI location: %s\n", + efi_handle_name ( device ), strerror ( rc ) ); + goto err_get_location; + } + busdevfn = PCI_BUSDEVFN ( pci_segment, pci_bus, pci_dev, pci_fn ); + pci_init ( pci, busdevfn ); + DBGCP ( device, "EFIPCI " PCI_FMT " is %s\n", + PCI_ARGS ( pci ), efi_handle_name ( device ) ); + + /* Try to enable I/O cycles, memory cycles, and bus mastering. + * Some platforms will 'helpfully' report errors if these bits + * can't be enabled (for example, if the card doesn't actually + * support I/O cycles). Work around any such platforms by + * enabling bits individually and simply ignoring any errors. + */ + pci_io.pci_io->Attributes ( pci_io.pci_io, + EfiPciIoAttributeOperationEnable, + EFI_PCI_IO_ATTRIBUTE_IO, NULL ); + pci_io.pci_io->Attributes ( pci_io.pci_io, + EfiPciIoAttributeOperationEnable, + EFI_PCI_IO_ATTRIBUTE_MEMORY, NULL ); + pci_io.pci_io->Attributes ( pci_io.pci_io, + EfiPciIoAttributeOperationEnable, + EFI_PCI_IO_ATTRIBUTE_BUS_MASTER, NULL ); + + /* Populate PCI device */ + if ( ( rc = pci_read_config ( pci ) ) != 0 ) { + DBGC ( device, "EFIPCI " PCI_FMT " cannot read PCI " + "configuration: %s\n", + PCI_ARGS ( pci ), strerror ( rc ) ); + goto err_pci_read_config; + } + + return 0; + + err_pci_read_config: + err_get_location: + bs->CloseProtocol ( device, &efi_pci_io_protocol_guid, + efi_image_handle, device ); + err_open_protocol: + return rc; +} + +/** + * Close EFI PCI device + * + * @v device EFI device handle + */ +void efipci_close ( EFI_HANDLE device ) { + EFI_BOOT_SERVICES *bs = efi_systab->BootServices; + + bs->CloseProtocol ( device, &efi_pci_io_protocol_guid, + efi_image_handle, device ); +} + +/** + * Get EFI PCI device information + * + * @v device EFI device handle + * @v pci PCI device to fill in + * @ret rc Return status code + */ +int efipci_info ( EFI_HANDLE device, struct pci_device *pci ) { + int rc; + + /* Open PCI device, if possible */ + if ( ( rc = efipci_open ( device, EFI_OPEN_PROTOCOL_GET_PROTOCOL, + pci ) ) != 0 ) + return rc; + + /* Close PCI device */ + efipci_close ( device ); + + return 0; +} + +/****************************************************************************** + * + * EFI PCI driver + * + ****************************************************************************** + */ + +/** + * Check to see if driver supports a device + * + * @v device EFI device handle + * @ret rc Return status code + */ +static int efipci_supported ( EFI_HANDLE device ) { + struct pci_device pci; + int rc; + + /* Get PCI device information */ + if ( ( rc = efipci_info ( device, &pci ) ) != 0 ) + return rc; + + /* Look for a driver */ + if ( ( rc = pci_find_driver ( &pci ) ) != 0 ) { + DBGC ( device, "EFIPCI " PCI_FMT " (%04x:%04x class %06x) " + "has no driver\n", PCI_ARGS ( &pci ), pci.vendor, + pci.device, pci.class ); + return rc; + } + DBGC ( device, "EFIPCI " PCI_FMT " (%04x:%04x class %06x) has driver " + "\"%s\"\n", PCI_ARGS ( &pci ), pci.vendor, pci.device, + pci.class, pci.id->name ); + + return 0; +} + +/** + * Attach driver to device + * + * @v efidev EFI device + * @ret rc Return status code + */ +static int efipci_start ( struct efi_device *efidev ) { + EFI_HANDLE device = efidev->device; + struct pci_device *pci; + int rc; + + /* Allocate PCI device */ + pci = zalloc ( sizeof ( *pci ) ); + if ( ! pci ) { + rc = -ENOMEM; + goto err_alloc; + } + + /* Open PCI device */ + if ( ( rc = efipci_open ( device, ( EFI_OPEN_PROTOCOL_BY_DRIVER | + EFI_OPEN_PROTOCOL_EXCLUSIVE ), + pci ) ) != 0 ) { + DBGC ( device, "EFIPCI %s could not open PCI device: %s\n", + efi_handle_name ( device ), strerror ( rc ) ); + DBGC_EFI_OPENERS ( device, device, &efi_pci_io_protocol_guid ); + goto err_open; + } + + /* Find driver */ + if ( ( rc = pci_find_driver ( pci ) ) != 0 ) { + DBGC ( device, "EFIPCI " PCI_FMT " has no driver\n", + PCI_ARGS ( pci ) ); + goto err_find_driver; + } + + /* Mark PCI device as a child of the EFI device */ + pci->dev.parent = &efidev->dev; + list_add ( &pci->dev.siblings, &efidev->dev.children ); + + /* Probe driver */ + if ( ( rc = pci_probe ( pci ) ) != 0 ) { + DBGC ( device, "EFIPCI " PCI_FMT " could not probe driver " + "\"%s\": %s\n", PCI_ARGS ( pci ), pci->id->name, + strerror ( rc ) ); + goto err_probe; + } + DBGC ( device, "EFIPCI " PCI_FMT " using driver \"%s\"\n", + PCI_ARGS ( pci ), pci->id->name ); + + efidev_set_drvdata ( efidev, pci ); + return 0; + + pci_remove ( pci ); + err_probe: + list_del ( &pci->dev.siblings ); + err_find_driver: + efipci_close ( device ); + err_open: + free ( pci ); + err_alloc: + return rc; +} + +/** + * Detach driver from device + * + * @v efidev EFI device + */ +static void efipci_stop ( struct efi_device *efidev ) { + struct pci_device *pci = efidev_get_drvdata ( efidev ); + EFI_HANDLE device = efidev->device; + + pci_remove ( pci ); + list_del ( &pci->dev.siblings ); + efipci_close ( device ); + free ( pci ); +} + +/** EFI PCI driver */ +struct efi_driver efipci_driver __efi_driver ( EFI_DRIVER_NORMAL ) = { + .name = "PCI", + .supported = efipci_supported, + .start = efipci_start, + .stop = efipci_stop, +}; + +#endif diff --git a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/net/tcp/iscsi.c b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/net/tcp/iscsi.c new file mode 100644 index 0000000..babf286 --- /dev/null +++ b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/net/tcp/iscsi.c @@ -0,0 +1,2152 @@ +/* + * Copyright (C) 2006 Michael Brown . + * + * 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 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. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** @file + * + * iSCSI protocol + * + */ + +FEATURE ( FEATURE_PROTOCOL, "iSCSI", DHCP_EB_FEATURE_ISCSI, 1 ); + +/* Disambiguate the various error causes */ +#define EACCES_INCORRECT_TARGET_USERNAME \ + __einfo_error ( EINFO_EACCES_INCORRECT_TARGET_USERNAME ) +#define EINFO_EACCES_INCORRECT_TARGET_USERNAME \ + __einfo_uniqify ( EINFO_EACCES, 0x01, "Incorrect target username" ) +#define EACCES_INCORRECT_TARGET_PASSWORD \ + __einfo_error ( EINFO_EACCES_INCORRECT_TARGET_PASSWORD ) +#define EINFO_EACCES_INCORRECT_TARGET_PASSWORD \ + __einfo_uniqify ( EINFO_EACCES, 0x02, "Incorrect target password" ) +#define EINVAL_ROOT_PATH_TOO_SHORT \ + __einfo_error ( EINFO_EINVAL_ROOT_PATH_TOO_SHORT ) +#define EINFO_EINVAL_ROOT_PATH_TOO_SHORT \ + __einfo_uniqify ( EINFO_EINVAL, 0x01, "Root path too short" ) +#define EINVAL_BAD_CREDENTIAL_MIX \ + __einfo_error ( EINFO_EINVAL_BAD_CREDENTIAL_MIX ) +#define EINFO_EINVAL_BAD_CREDENTIAL_MIX \ + __einfo_uniqify ( EINFO_EINVAL, 0x02, "Bad credential mix" ) +#define EINVAL_NO_ROOT_PATH \ + __einfo_error ( EINFO_EINVAL_NO_ROOT_PATH ) +#define EINFO_EINVAL_NO_ROOT_PATH \ + __einfo_uniqify ( EINFO_EINVAL, 0x03, "No root path" ) +#define EINVAL_NO_TARGET_IQN \ + __einfo_error ( EINFO_EINVAL_NO_TARGET_IQN ) +#define EINFO_EINVAL_NO_TARGET_IQN \ + __einfo_uniqify ( EINFO_EINVAL, 0x04, "No target IQN" ) +#define EINVAL_NO_INITIATOR_IQN \ + __einfo_error ( EINFO_EINVAL_NO_INITIATOR_IQN ) +#define EINFO_EINVAL_NO_INITIATOR_IQN \ + __einfo_uniqify ( EINFO_EINVAL, 0x05, "No initiator IQN" ) +#define EIO_TARGET_UNAVAILABLE \ + __einfo_error ( EINFO_EIO_TARGET_UNAVAILABLE ) +#define EINFO_EIO_TARGET_UNAVAILABLE \ + __einfo_uniqify ( EINFO_EIO, 0x01, "Target not currently operational" ) +#define EIO_TARGET_NO_RESOURCES \ + __einfo_error ( EINFO_EIO_TARGET_NO_RESOURCES ) +#define EINFO_EIO_TARGET_NO_RESOURCES \ + __einfo_uniqify ( EINFO_EIO, 0x02, "Target out of resources" ) +#define ENOTSUP_INITIATOR_STATUS \ + __einfo_error ( EINFO_ENOTSUP_INITIATOR_STATUS ) +#define EINFO_ENOTSUP_INITIATOR_STATUS \ + __einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Unsupported initiator status" ) +#define ENOTSUP_OPCODE \ + __einfo_error ( EINFO_ENOTSUP_OPCODE ) +#define EINFO_ENOTSUP_OPCODE \ + __einfo_uniqify ( EINFO_ENOTSUP, 0x02, "Unsupported opcode" ) +#define ENOTSUP_DISCOVERY \ + __einfo_error ( EINFO_ENOTSUP_DISCOVERY ) +#define EINFO_ENOTSUP_DISCOVERY \ + __einfo_uniqify ( EINFO_ENOTSUP, 0x03, "Discovery not supported" ) +#define ENOTSUP_TARGET_STATUS \ + __einfo_error ( EINFO_ENOTSUP_TARGET_STATUS ) +#define EINFO_ENOTSUP_TARGET_STATUS \ + __einfo_uniqify ( EINFO_ENOTSUP, 0x04, "Unsupported target status" ) +#define EPERM_INITIATOR_AUTHENTICATION \ + __einfo_error ( EINFO_EPERM_INITIATOR_AUTHENTICATION ) +#define EINFO_EPERM_INITIATOR_AUTHENTICATION \ + __einfo_uniqify ( EINFO_EPERM, 0x01, "Initiator authentication failed" ) +#define EPERM_INITIATOR_AUTHORISATION \ + __einfo_error ( EINFO_EPERM_INITIATOR_AUTHORISATION ) +#define EINFO_EPERM_INITIATOR_AUTHORISATION \ + __einfo_uniqify ( EINFO_EPERM, 0x02, "Initiator not authorised" ) +#define EPROTO_INVALID_CHAP_ALGORITHM \ + __einfo_error ( EINFO_EPROTO_INVALID_CHAP_ALGORITHM ) +#define EINFO_EPROTO_INVALID_CHAP_ALGORITHM \ + __einfo_uniqify ( EINFO_EPROTO, 0x01, "Invalid CHAP algorithm" ) +#define EPROTO_INVALID_CHAP_IDENTIFIER \ + __einfo_error ( EINFO_EPROTO_INVALID_CHAP_IDENTIFIER ) +#define EINFO_EPROTO_INVALID_CHAP_IDENTIFIER \ + __einfo_uniqify ( EINFO_EPROTO, 0x02, "Invalid CHAP identifier" ) +#define EPROTO_INVALID_LARGE_BINARY \ + __einfo_error ( EINFO_EPROTO_INVALID_LARGE_BINARY ) +#define EINFO_EPROTO_INVALID_LARGE_BINARY \ + __einfo_uniqify ( EINFO_EPROTO, 0x03, "Invalid large binary value" ) +#define EPROTO_INVALID_CHAP_RESPONSE \ + __einfo_error ( EINFO_EPROTO_INVALID_CHAP_RESPONSE ) +#define EINFO_EPROTO_INVALID_CHAP_RESPONSE \ + __einfo_uniqify ( EINFO_EPROTO, 0x04, "Invalid CHAP response" ) +#define EPROTO_INVALID_KEY_VALUE_PAIR \ + __einfo_error ( EINFO_EPROTO_INVALID_KEY_VALUE_PAIR ) +#define EINFO_EPROTO_INVALID_KEY_VALUE_PAIR \ + __einfo_uniqify ( EINFO_EPROTO, 0x05, "Invalid key/value pair" ) +#define EPROTO_VALUE_REJECTED \ + __einfo_error ( EINFO_EPROTO_VALUE_REJECTED ) +#define EINFO_EPROTO_VALUE_REJECTED \ + __einfo_uniqify ( EINFO_EPROTO, 0x06, "Parameter rejected" ) + +static void iscsi_start_tx ( struct iscsi_session *iscsi ); +static void iscsi_start_login ( struct iscsi_session *iscsi ); +static void iscsi_start_data_out ( struct iscsi_session *iscsi, + unsigned int datasn ); + +/** + * Finish receiving PDU data into buffer + * + * @v iscsi iSCSI session + */ +static void iscsi_rx_buffered_data_done ( struct iscsi_session *iscsi ) { + free ( iscsi->rx_buffer ); + iscsi->rx_buffer = NULL; +} + +/** + * Receive PDU data into buffer + * + * @v iscsi iSCSI session + * @v data Data to receive + * @v len Length of data + * @ret rc Return status code + * + * This can be used when the RX PDU type handler wishes to buffer up + * all received data and process the PDU as a single unit. The caller + * is repsonsible for calling iscsi_rx_buffered_data_done() after + * processing the data. + */ +static int iscsi_rx_buffered_data ( struct iscsi_session *iscsi, + const void *data, size_t len ) { + + /* Allocate buffer on first call */ + if ( ! iscsi->rx_buffer ) { + iscsi->rx_buffer = malloc ( iscsi->rx_len ); + if ( ! iscsi->rx_buffer ) + return -ENOMEM; + } + + /* Copy data to buffer */ + assert ( ( iscsi->rx_offset + len ) <= iscsi->rx_len ); + memcpy ( ( iscsi->rx_buffer + iscsi->rx_offset ), data, len ); + + return 0; +} + +/** + * Free iSCSI session + * + * @v refcnt Reference counter + */ +static void iscsi_free ( struct refcnt *refcnt ) { + struct iscsi_session *iscsi = + container_of ( refcnt, struct iscsi_session, refcnt ); + + free ( iscsi->initiator_iqn ); + free ( iscsi->target_address ); + free ( iscsi->target_iqn ); + free ( iscsi->initiator_username ); + free ( iscsi->initiator_password ); + free ( iscsi->target_username ); + free ( iscsi->target_password ); + chap_finish ( &iscsi->chap ); + iscsi_rx_buffered_data_done ( iscsi ); + free ( iscsi->command ); + free ( iscsi ); +} + +/** + * Shut down iSCSI interface + * + * @v iscsi iSCSI session + * @v rc Reason for close + */ +static void iscsi_close ( struct iscsi_session *iscsi, int rc ) { + + /* A TCP graceful close is still an error from our point of view */ + if ( rc == 0 ) + rc = -ECONNRESET; + + DBGC ( iscsi, "iSCSI %p closed: %s\n", iscsi, strerror ( rc ) ); + + /* Stop transmission process */ + process_del ( &iscsi->process ); + + /* Shut down interfaces */ + intfs_shutdown ( rc, &iscsi->socket, &iscsi->control, &iscsi->data, + NULL ); +} + +/** + * Assign new iSCSI initiator task tag + * + * @v iscsi iSCSI session + */ +static void iscsi_new_itt ( struct iscsi_session *iscsi ) { + static uint16_t itt_idx; + + iscsi->itt = ( ISCSI_TAG_MAGIC | (++itt_idx) ); +} + +/** + * Open iSCSI transport-layer connection + * + * @v iscsi iSCSI session + * @ret rc Return status code + */ +static int iscsi_open_connection ( struct iscsi_session *iscsi ) { + struct sockaddr_tcpip target; + int rc; + + assert ( iscsi->tx_state == ISCSI_TX_IDLE ); + assert ( iscsi->rx_state == ISCSI_RX_BHS ); + assert ( iscsi->rx_offset == 0 ); + + /* Open socket */ + memset ( &target, 0, sizeof ( target ) ); + target.st_port = htons ( iscsi->target_port ); + if ( ( rc = xfer_open_named_socket ( &iscsi->socket, SOCK_STREAM, + ( struct sockaddr * ) &target, + iscsi->target_address, + NULL ) ) != 0 ) { + DBGC ( iscsi, "iSCSI %p could not open socket: %s\n", + iscsi, strerror ( rc ) ); + return rc; + } + + /* Enter security negotiation phase */ + iscsi->status = ( ISCSI_STATUS_SECURITY_NEGOTIATION_PHASE | + ISCSI_STATUS_STRINGS_SECURITY ); + if ( iscsi->target_username ) + iscsi->status |= ISCSI_STATUS_AUTH_REVERSE_REQUIRED; + + /* Assign new ISID */ + iscsi->isid_iana_qual = ( random() & 0xffff ); + + /* Assign fresh initiator task tag */ + iscsi_new_itt ( iscsi ); + + /* Initiate login */ + iscsi_start_login ( iscsi ); + + return 0; +} + +/** + * Close iSCSI transport-layer connection + * + * @v iscsi iSCSI session + * @v rc Reason for close + * + * Closes the transport-layer connection and resets the session state + * ready to attempt a fresh login. + */ +static void iscsi_close_connection ( struct iscsi_session *iscsi, int rc ) { + + /* Close all data transfer interfaces */ + intf_restart ( &iscsi->socket, rc ); + + /* Clear connection status */ + iscsi->status = 0; + + /* Reset TX and RX state machines */ + iscsi->tx_state = ISCSI_TX_IDLE; + iscsi->rx_state = ISCSI_RX_BHS; + iscsi->rx_offset = 0; + + /* Free any temporary dynamically allocated memory */ + chap_finish ( &iscsi->chap ); + iscsi_rx_buffered_data_done ( iscsi ); +} + +/** + * Mark iSCSI SCSI operation as complete + * + * @v iscsi iSCSI session + * @v rc Return status code + * @v rsp SCSI response, if any + * + * Note that iscsi_scsi_done() will not close the connection, and must + * therefore be called only when the internal state machines are in an + * appropriate state, otherwise bad things may happen on the next call + * to iscsi_scsi_command(). The general rule is to call + * iscsi_scsi_done() only at the end of receiving a PDU; at this point + * the TX and RX engines should both be idle. + */ +static void iscsi_scsi_done ( struct iscsi_session *iscsi, int rc, + struct scsi_rsp *rsp ) { + uint32_t itt = iscsi->itt; + + assert ( iscsi->tx_state == ISCSI_TX_IDLE ); + + /* Clear command */ + free ( iscsi->command ); + iscsi->command = NULL; + + /* Send SCSI response, if any */ + if ( rsp ) + scsi_response ( &iscsi->data, rsp ); + + /* Close SCSI command, if this is still the same command. (It + * is possible that the command interface has already been + * closed as a result of the SCSI response we sent.) + */ + if ( iscsi->itt == itt ) + intf_restart ( &iscsi->data, rc ); +} + +/**************************************************************************** + * + * iSCSI SCSI command issuing + * + */ + +/** + * Build iSCSI SCSI command BHS + * + * @v iscsi iSCSI session + * + * We don't currently support bidirectional commands (i.e. with both + * Data-In and Data-Out segments); these would require providing code + * to generate an AHS, and there doesn't seem to be any need for it at + * the moment. + */ +static void iscsi_start_command ( struct iscsi_session *iscsi ) { + struct iscsi_bhs_scsi_command *command = &iscsi->tx_bhs.scsi_command; + + assert ( ! ( iscsi->command->data_in && iscsi->command->data_out ) ); + + /* Construct BHS and initiate transmission */ + iscsi_start_tx ( iscsi ); + command->opcode = ISCSI_OPCODE_SCSI_COMMAND; + command->flags = ( ISCSI_FLAG_FINAL | + ISCSI_COMMAND_ATTR_SIMPLE ); + if ( iscsi->command->data_in ) + command->flags |= ISCSI_COMMAND_FLAG_READ; + if ( iscsi->command->data_out ) + command->flags |= ISCSI_COMMAND_FLAG_WRITE; + /* lengths left as zero */ + memcpy ( &command->lun, &iscsi->command->lun, + sizeof ( command->lun ) ); + command->itt = htonl ( iscsi->itt ); + command->exp_len = htonl ( iscsi->command->data_in_len | + iscsi->command->data_out_len ); + command->cmdsn = htonl ( iscsi->cmdsn ); + command->expstatsn = htonl ( iscsi->statsn + 1 ); + memcpy ( &command->cdb, &iscsi->command->cdb, sizeof ( command->cdb )); + DBGC2 ( iscsi, "iSCSI %p start " SCSI_CDB_FORMAT " %s %#zx\n", + iscsi, SCSI_CDB_DATA ( command->cdb ), + ( iscsi->command->data_in ? "in" : "out" ), + ( iscsi->command->data_in ? + iscsi->command->data_in_len : + iscsi->command->data_out_len ) ); +} + +/** + * Receive data segment of an iSCSI SCSI response PDU + * + * @v iscsi iSCSI session + * @v data Received data + * @v len Length of received data + * @v remaining Data remaining after this data + * @ret rc Return status code + */ +static int iscsi_rx_scsi_response ( struct iscsi_session *iscsi, + const void *data, size_t len, + size_t remaining ) { + struct iscsi_bhs_scsi_response *response + = &iscsi->rx_bhs.scsi_response; + struct scsi_rsp rsp; + uint32_t residual_count; + size_t data_len; + int rc; + + /* Buffer up the PDU data */ + if ( ( rc = iscsi_rx_buffered_data ( iscsi, data, len ) ) != 0 ) { + DBGC ( iscsi, "iSCSI %p could not buffer SCSI response: %s\n", + iscsi, strerror ( rc ) ); + return rc; + } + if ( remaining ) + return 0; + + /* Parse SCSI response and discard buffer */ + memset ( &rsp, 0, sizeof ( rsp ) ); + rsp.status = response->status; + residual_count = ntohl ( response->residual_count ); + if ( response->flags & ISCSI_DATA_FLAG_OVERFLOW ) { + rsp.overrun = residual_count; + } else if ( response->flags & ISCSI_DATA_FLAG_UNDERFLOW ) { + rsp.overrun = -(residual_count); + } + data_len = ISCSI_DATA_LEN ( response->lengths ); + if ( data_len ) { + scsi_parse_sense ( ( iscsi->rx_buffer + 2 ), ( data_len - 2 ), + &rsp.sense ); + } + iscsi_rx_buffered_data_done ( iscsi ); + + /* Check for errors */ + if ( response->response != ISCSI_RESPONSE_COMMAND_COMPLETE ) + return -EIO; + + /* Mark as completed */ + iscsi_scsi_done ( iscsi, 0, &rsp ); + return 0; +} + +/** + * Receive data segment of an iSCSI data-in PDU + * + * @v iscsi iSCSI session + * @v data Received data + * @v len Length of received data + * @v remaining Data remaining after this data + * @ret rc Return status code + */ +static int iscsi_rx_data_in ( struct iscsi_session *iscsi, + const void *data, size_t len, + size_t remaining ) { + struct iscsi_bhs_data_in *data_in = &iscsi->rx_bhs.data_in; + unsigned long offset; + + /* Copy data to data-in buffer */ + offset = ntohl ( data_in->offset ) + iscsi->rx_offset; + assert ( iscsi->command != NULL ); + assert ( iscsi->command->data_in ); + assert ( ( offset + len ) <= iscsi->command->data_in_len ); + copy_to_user ( iscsi->command->data_in, offset, data, len ); + + /* Wait for whole SCSI response to arrive */ + if ( remaining ) + return 0; + + /* Mark as completed if status is present */ + if ( data_in->flags & ISCSI_DATA_FLAG_STATUS ) { + assert ( ( offset + len ) == iscsi->command->data_in_len ); + assert ( data_in->flags & ISCSI_FLAG_FINAL ); + /* iSCSI cannot return an error status via a data-in */ + iscsi_scsi_done ( iscsi, 0, NULL ); + } + + return 0; +} + +/** + * Receive data segment of an iSCSI R2T PDU + * + * @v iscsi iSCSI session + * @v data Received data + * @v len Length of received data + * @v remaining Data remaining after this data + * @ret rc Return status code + */ +static int iscsi_rx_r2t ( struct iscsi_session *iscsi, + const void *data __unused, size_t len __unused, + size_t remaining __unused ) { + struct iscsi_bhs_r2t *r2t = &iscsi->rx_bhs.r2t; + + /* Record transfer parameters and trigger first data-out */ + iscsi->ttt = ntohl ( r2t->ttt ); + iscsi->transfer_offset = ntohl ( r2t->offset ); + iscsi->transfer_len = ntohl ( r2t->len ); + iscsi_start_data_out ( iscsi, 0 ); + + return 0; +} + +/** + * Build iSCSI data-out BHS + * + * @v iscsi iSCSI session + * @v datasn Data sequence number within the transfer + * + */ +static void iscsi_start_data_out ( struct iscsi_session *iscsi, + unsigned int datasn ) { + struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out; + unsigned long offset; + unsigned long remaining; + unsigned long len; + + /* We always send 512-byte Data-Out PDUs; this removes the + * need to worry about the target's MaxRecvDataSegmentLength. + */ + offset = datasn * 512; + remaining = iscsi->transfer_len - offset; + len = remaining; + if ( len > 512 ) + len = 512; + + /* Construct BHS and initiate transmission */ + iscsi_start_tx ( iscsi ); + data_out->opcode = ISCSI_OPCODE_DATA_OUT; + if ( len == remaining ) + data_out->flags = ( ISCSI_FLAG_FINAL ); + ISCSI_SET_LENGTHS ( data_out->lengths, 0, len ); + data_out->lun = iscsi->command->lun; + data_out->itt = htonl ( iscsi->itt ); + data_out->ttt = htonl ( iscsi->ttt ); + data_out->expstatsn = htonl ( iscsi->statsn + 1 ); + data_out->datasn = htonl ( datasn ); + data_out->offset = htonl ( iscsi->transfer_offset + offset ); + DBGC ( iscsi, "iSCSI %p start data out DataSN %#x len %#lx\n", + iscsi, datasn, len ); +} + +/** + * Complete iSCSI data-out PDU transmission + * + * @v iscsi iSCSI session + * + */ +static void iscsi_data_out_done ( struct iscsi_session *iscsi ) { + struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out; + + /* If we haven't reached the end of the sequence, start + * sending the next data-out PDU. + */ + if ( ! ( data_out->flags & ISCSI_FLAG_FINAL ) ) + iscsi_start_data_out ( iscsi, ntohl ( data_out->datasn ) + 1 ); +} + +/** + * Send iSCSI data-out data segment + * + * @v iscsi iSCSI session + * @ret rc Return status code + */ +static int iscsi_tx_data_out ( struct iscsi_session *iscsi ) { + struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out; + struct io_buffer *iobuf; + unsigned long offset; + size_t len; + size_t pad_len; + + offset = ntohl ( data_out->offset ); + len = ISCSI_DATA_LEN ( data_out->lengths ); + pad_len = ISCSI_DATA_PAD_LEN ( data_out->lengths ); + + assert ( iscsi->command != NULL ); + assert ( iscsi->command->data_out ); + assert ( ( offset + len ) <= iscsi->command->data_out_len ); + + iobuf = xfer_alloc_iob ( &iscsi->socket, ( len + pad_len ) ); + if ( ! iobuf ) + return -ENOMEM; + + copy_from_user ( iob_put ( iobuf, len ), + iscsi->command->data_out, offset, len ); + memset ( iob_put ( iobuf, pad_len ), 0, pad_len ); + + return xfer_deliver_iob ( &iscsi->socket, iobuf ); +} + +/** + * Receive data segment of an iSCSI NOP-In + * + * @v iscsi iSCSI session + * @v data Received data + * @v len Length of received data + * @v remaining Data remaining after this data + * @ret rc Return status code + */ +static int iscsi_rx_nop_in ( struct iscsi_session *iscsi, + const void *data __unused, size_t len __unused, + size_t remaining __unused ) { + struct iscsi_nop_in *nop_in = &iscsi->rx_bhs.nop_in; + + DBGC2 ( iscsi, "iSCSI %p received NOP-In\n", iscsi ); + + /* We don't currently have the ability to respond to NOP-Ins + * sent as ping requests, but we can happily accept NOP-Ins + * sent merely to update CmdSN. + */ + if ( nop_in->ttt == htonl ( ISCSI_TAG_RESERVED ) ) + return 0; + + /* Ignore any other NOP-Ins. The target may eventually + * disconnect us for failing to respond, but this minimises + * unnecessary connection closures. + */ + DBGC ( iscsi, "iSCSI %p received unsupported NOP-In with TTT %08x\n", + iscsi, ntohl ( nop_in->ttt ) ); + return 0; +} + +/**************************************************************************** + * + * iSCSI login + * + */ + +/** + * Build iSCSI login request strings + * + * @v iscsi iSCSI session + * + * These are the initial set of strings sent in the first login + * request PDU. We want the following settings: + * + * HeaderDigest=None + * DataDigest=None + * MaxConnections=1 (irrelevant; we make only one connection anyway) [4] + * InitialR2T=Yes [1] + * ImmediateData=No (irrelevant; we never send immediate data) [4] + * MaxRecvDataSegmentLength=8192 (default; we don't care) [3] + * MaxBurstLength=262144 (default; we don't care) [3] + * FirstBurstLength=65536 (irrelevant due to other settings) [5] + * DefaultTime2Wait=0 [2] + * DefaultTime2Retain=0 [2] + * MaxOutstandingR2T=1 + * DataPDUInOrder=Yes + * DataSequenceInOrder=Yes + * ErrorRecoveryLevel=0 + * + * [1] InitialR2T has an OR resolution function, so the target may + * force us to use it. We therefore simplify our logic by always + * using it. + * + * [2] These ensure that we can safely start a new task once we have + * reconnected after a failure, without having to manually tidy up + * after the old one. + * + * [3] We are quite happy to use the RFC-defined default values for + * these parameters, but some targets (notably OpenSolaris) + * incorrectly assume a default value of zero, so we explicitly + * specify the default values. + * + * [4] We are quite happy to use the RFC-defined default values for + * these parameters, but some targets (notably a QNAP TS-639Pro) fail + * unless they are supplied, so we explicitly specify the default + * values. + * + * [5] FirstBurstLength is defined to be irrelevant since we already + * force InitialR2T=Yes and ImmediateData=No, but some targets + * (notably LIO as of kernel 4.11) fail unless it is specified, so we + * explicitly specify the default value. + */ +static int iscsi_build_login_request_strings ( struct iscsi_session *iscsi, + void *data, size_t len ) { + unsigned int used = 0; + const char *auth_method; + + if ( iscsi->status & ISCSI_STATUS_STRINGS_SECURITY ) { + /* Default to allowing no authentication */ + auth_method = "None"; + /* If we have a credential to supply, permit CHAP */ + if ( iscsi->initiator_username ) + auth_method = "CHAP,None"; + /* If we have a credential to check, force CHAP */ + if ( iscsi->target_username ) + auth_method = "CHAP"; + used += ssnprintf ( data + used, len - used, + "InitiatorName=%s%c" + "TargetName=%s%c" + "SessionType=Normal%c" + "AuthMethod=%s%c", + iscsi->initiator_iqn, 0, + iscsi->target_iqn, 0, 0, + auth_method, 0 ); + } + + if ( iscsi->status & ISCSI_STATUS_STRINGS_CHAP_ALGORITHM ) { + used += ssnprintf ( data + used, len - used, "CHAP_A=5%c", 0 ); + } + + if ( ( iscsi->status & ISCSI_STATUS_STRINGS_CHAP_RESPONSE ) ) { + char buf[ base16_encoded_len ( iscsi->chap.response_len ) + 1 ]; + assert ( iscsi->initiator_username != NULL ); + base16_encode ( iscsi->chap.response, iscsi->chap.response_len, + buf, sizeof ( buf ) ); + used += ssnprintf ( data + used, len - used, + "CHAP_N=%s%cCHAP_R=0x%s%c", + iscsi->initiator_username, 0, buf, 0 ); + } + + if ( ( iscsi->status & ISCSI_STATUS_STRINGS_CHAP_CHALLENGE ) ) { + size_t challenge_len = ( sizeof ( iscsi->chap_challenge ) - 1 ); + char buf[ base16_encoded_len ( challenge_len ) + 1 ]; + base16_encode ( ( iscsi->chap_challenge + 1 ), challenge_len, + buf, sizeof ( buf ) ); + used += ssnprintf ( data + used, len - used, + "CHAP_I=%d%cCHAP_C=0x%s%c", + iscsi->chap_challenge[0], 0, buf, 0 ); + } + + if ( iscsi->status & ISCSI_STATUS_STRINGS_OPERATIONAL ) { + used += ssnprintf ( data + used, len - used, + "HeaderDigest=None%c" + "DataDigest=None%c" + "MaxConnections=1%c" + "InitialR2T=Yes%c" + "ImmediateData=No%c" + "MaxRecvDataSegmentLength=8192%c" + "MaxBurstLength=262144%c" + "FirstBurstLength=65536%c" + "DefaultTime2Wait=0%c" + "DefaultTime2Retain=0%c" + "MaxOutstandingR2T=1%c" + "DataPDUInOrder=Yes%c" + "DataSequenceInOrder=Yes%c" + "ErrorRecoveryLevel=0%c", + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); + } + + return used; +} + +/** + * Build iSCSI login request BHS + * + * @v iscsi iSCSI session + */ +static void iscsi_start_login ( struct iscsi_session *iscsi ) { + struct iscsi_bhs_login_request *request = &iscsi->tx_bhs.login_request; + int len; + + switch ( iscsi->status & ISCSI_LOGIN_CSG_MASK ) { + case ISCSI_LOGIN_CSG_SECURITY_NEGOTIATION: + DBGC ( iscsi, "iSCSI %p entering security negotiation\n", + iscsi ); + break; + case ISCSI_LOGIN_CSG_OPERATIONAL_NEGOTIATION: + DBGC ( iscsi, "iSCSI %p entering operational negotiation\n", + iscsi ); + break; + default: + assert ( 0 ); + } + + /* Construct BHS and initiate transmission */ + iscsi_start_tx ( iscsi ); + request->opcode = ( ISCSI_OPCODE_LOGIN_REQUEST | + ISCSI_FLAG_IMMEDIATE ); + request->flags = ( ( iscsi->status & ISCSI_STATUS_PHASE_MASK ) | + ISCSI_LOGIN_FLAG_TRANSITION ); + /* version_max and version_min left as zero */ + len = iscsi_build_login_request_strings ( iscsi, NULL, 0 ); + ISCSI_SET_LENGTHS ( request->lengths, 0, len ); + request->isid_iana_en = htonl ( ISCSI_ISID_IANA | + IANA_EN_FEN_SYSTEMS ); + request->isid_iana_qual = htons ( iscsi->isid_iana_qual ); + /* tsih left as zero */ + request->itt = htonl ( iscsi->itt ); + /* cid left as zero */ + request->cmdsn = htonl ( iscsi->cmdsn ); + request->expstatsn = htonl ( iscsi->statsn + 1 ); +} + +/** + * Complete iSCSI login request PDU transmission + * + * @v iscsi iSCSI session + * + */ +static void iscsi_login_request_done ( struct iscsi_session *iscsi ) { + + /* Clear any "strings to send" flags */ + iscsi->status &= ~ISCSI_STATUS_STRINGS_MASK; + + /* Free any dynamically allocated storage used for login */ + chap_finish ( &iscsi->chap ); +} + +/** + * Transmit data segment of an iSCSI login request PDU + * + * @v iscsi iSCSI session + * @ret rc Return status code + * + * For login requests, the data segment consists of the login strings. + */ +static int iscsi_tx_login_request ( struct iscsi_session *iscsi ) { + struct iscsi_bhs_login_request *request = &iscsi->tx_bhs.login_request; + struct io_buffer *iobuf; + size_t len; + size_t pad_len; + + len = ISCSI_DATA_LEN ( request->lengths ); + pad_len = ISCSI_DATA_PAD_LEN ( request->lengths ); + iobuf = xfer_alloc_iob ( &iscsi->socket, ( len + pad_len ) ); + if ( ! iobuf ) + return -ENOMEM; + iob_put ( iobuf, len ); + iscsi_build_login_request_strings ( iscsi, iobuf->data, len ); + memset ( iob_put ( iobuf, pad_len ), 0, pad_len ); + + return xfer_deliver_iob ( &iscsi->socket, iobuf ); +} + +/** + * Decode large binary value + * + * @v encoded Encoded large binary value + * @v raw Raw data + * @v len Length of data buffer + * @ret len Length of raw data, or negative error + */ +static int iscsi_large_binary_decode ( const char *encoded, uint8_t *raw, + size_t len ) { + + /* Check for initial '0x' or '0b' and decode as appropriate */ + if ( *(encoded++) == '0' ) { + switch ( tolower ( *(encoded++) ) ) { + case 'x' : + return base16_decode ( encoded, raw, len ); + case 'b' : + return base64_decode ( encoded, raw, len ); + } + } + + return -EPROTO_INVALID_LARGE_BINARY; +} + +/** + * Handle iSCSI TargetAddress text value + * + * @v iscsi iSCSI session + * @v value TargetAddress value + * @ret rc Return status code + */ +static int iscsi_handle_targetaddress_value ( struct iscsi_session *iscsi, + const char *value ) { + char *separator; + + DBGC ( iscsi, "iSCSI %p will redirect to %s\n", iscsi, value ); + + /* Replace target address */ + free ( iscsi->target_address ); + iscsi->target_address = strdup ( value ); + if ( ! iscsi->target_address ) + return -ENOMEM; + + /* Replace target port */ + iscsi->target_port = htons ( ISCSI_PORT ); + separator = strchr ( iscsi->target_address, ':' ); + if ( separator ) { + *separator = '\0'; + iscsi->target_port = strtoul ( ( separator + 1 ), NULL, 0 ); + } + + return 0; +} + +/** + * Handle iSCSI AuthMethod text value + * + * @v iscsi iSCSI session + * @v value AuthMethod value + * @ret rc Return status code + */ +static int iscsi_handle_authmethod_value ( struct iscsi_session *iscsi, + const char *value ) { + + /* If server requests CHAP, send the CHAP_A string */ + if ( strcmp ( value, "CHAP" ) == 0 ) { + DBGC ( iscsi, "iSCSI %p initiating CHAP authentication\n", + iscsi ); + iscsi->status |= ( ISCSI_STATUS_STRINGS_CHAP_ALGORITHM | + ISCSI_STATUS_AUTH_FORWARD_REQUIRED ); + } + + return 0; +} + +/** + * Handle iSCSI CHAP_A text value + * + * @v iscsi iSCSI session + * @v value CHAP_A value + * @ret rc Return status code + */ +static int iscsi_handle_chap_a_value ( struct iscsi_session *iscsi, + const char *value ) { + + /* We only ever offer "5" (i.e. MD5) as an algorithm, so if + * the server responds with anything else it is a protocol + * violation. + */ + if ( strcmp ( value, "5" ) != 0 ) { + DBGC ( iscsi, "iSCSI %p got invalid CHAP algorithm \"%s\"\n", + iscsi, value ); + return -EPROTO_INVALID_CHAP_ALGORITHM; + } + + return 0; +} + +/** + * Handle iSCSI CHAP_I text value + * + * @v iscsi iSCSI session + * @v value CHAP_I value + * @ret rc Return status code + */ +static int iscsi_handle_chap_i_value ( struct iscsi_session *iscsi, + const char *value ) { + unsigned int identifier; + char *endp; + int rc; + + /* The CHAP identifier is an integer value */ + identifier = strtoul ( value, &endp, 0 ); + if ( *endp != '\0' ) { + DBGC ( iscsi, "iSCSI %p saw invalid CHAP identifier \"%s\"\n", + iscsi, value ); + return -EPROTO_INVALID_CHAP_IDENTIFIER; + } + + /* Prepare for CHAP with MD5 */ + chap_finish ( &iscsi->chap ); + if ( ( rc = chap_init ( &iscsi->chap, &md5_algorithm ) ) != 0 ) { + DBGC ( iscsi, "iSCSI %p could not initialise CHAP: %s\n", + iscsi, strerror ( rc ) ); + return rc; + } + + /* Identifier and secret are the first two components of the + * challenge. + */ + chap_set_identifier ( &iscsi->chap, identifier ); + if ( iscsi->initiator_password ) { + chap_update ( &iscsi->chap, iscsi->initiator_password, + strlen ( iscsi->initiator_password ) ); + } + + return 0; +} + +/** + * Handle iSCSI CHAP_C text value + * + * @v iscsi iSCSI session + * @v value CHAP_C value + * @ret rc Return status code + */ +static int iscsi_handle_chap_c_value ( struct iscsi_session *iscsi, + const char *value ) { + uint8_t buf[ strlen ( value ) ]; /* Decoding never expands data */ + unsigned int i; + int len; + int rc; + + /* Process challenge */ + len = iscsi_large_binary_decode ( value, buf, sizeof ( buf ) ); + if ( len < 0 ) { + rc = len; + DBGC ( iscsi, "iSCSI %p invalid CHAP challenge \"%s\": %s\n", + iscsi, value, strerror ( rc ) ); + return rc; + } + chap_update ( &iscsi->chap, buf, len ); + + /* Build CHAP response */ + DBGC ( iscsi, "iSCSI %p sending CHAP response\n", iscsi ); + chap_respond ( &iscsi->chap ); + iscsi->status |= ISCSI_STATUS_STRINGS_CHAP_RESPONSE; + + /* Send CHAP challenge, if applicable */ + if ( iscsi->target_username ) { + iscsi->status |= ISCSI_STATUS_STRINGS_CHAP_CHALLENGE; + /* Generate CHAP challenge data */ + for ( i = 0 ; i < sizeof ( iscsi->chap_challenge ) ; i++ ) { + iscsi->chap_challenge[i] = random(); + } + } + + return 0; +} + +/** + * Handle iSCSI CHAP_N text value + * + * @v iscsi iSCSI session + * @v value CHAP_N value + * @ret rc Return status code + */ +static int iscsi_handle_chap_n_value ( struct iscsi_session *iscsi, + const char *value ) { + + /* The target username isn't actually involved at any point in + * the authentication process; it merely serves to identify + * which password the target is using to generate the CHAP + * response. We unnecessarily verify that the username is as + * expected, in order to provide mildly helpful diagnostics if + * the target is supplying the wrong username/password + * combination. + */ + if ( iscsi->target_username && + ( strcmp ( iscsi->target_username, value ) != 0 ) ) { + DBGC ( iscsi, "iSCSI %p target username \"%s\" incorrect " + "(wanted \"%s\")\n", + iscsi, value, iscsi->target_username ); + return -EACCES_INCORRECT_TARGET_USERNAME; + } + + return 0; +} + +/** + * Handle iSCSI CHAP_R text value + * + * @v iscsi iSCSI session + * @v value CHAP_R value + * @ret rc Return status code + */ +static int iscsi_handle_chap_r_value ( struct iscsi_session *iscsi, + const char *value ) { + uint8_t buf[ strlen ( value ) ]; /* Decoding never expands data */ + int len; + int rc; + + /* Generate CHAP response for verification */ + chap_finish ( &iscsi->chap ); + if ( ( rc = chap_init ( &iscsi->chap, &md5_algorithm ) ) != 0 ) { + DBGC ( iscsi, "iSCSI %p could not initialise CHAP: %s\n", + iscsi, strerror ( rc ) ); + return rc; + } + chap_set_identifier ( &iscsi->chap, iscsi->chap_challenge[0] ); + if ( iscsi->target_password ) { + chap_update ( &iscsi->chap, iscsi->target_password, + strlen ( iscsi->target_password ) ); + } + chap_update ( &iscsi->chap, &iscsi->chap_challenge[1], + ( sizeof ( iscsi->chap_challenge ) - 1 ) ); + chap_respond ( &iscsi->chap ); + + /* Process response */ + len = iscsi_large_binary_decode ( value, buf, sizeof ( buf ) ); + if ( len < 0 ) { + rc = len; + DBGC ( iscsi, "iSCSI %p invalid CHAP response \"%s\": %s\n", + iscsi, value, strerror ( rc ) ); + return rc; + } + + /* Check CHAP response */ + if ( len != ( int ) iscsi->chap.response_len ) { + DBGC ( iscsi, "iSCSI %p invalid CHAP response length\n", + iscsi ); + return -EPROTO_INVALID_CHAP_RESPONSE; + } + if ( memcmp ( buf, iscsi->chap.response, len ) != 0 ) { + DBGC ( iscsi, "iSCSI %p incorrect CHAP response \"%s\"\n", + iscsi, value ); + return -EACCES_INCORRECT_TARGET_PASSWORD; + } + + /* Mark session as authenticated */ + iscsi->status |= ISCSI_STATUS_AUTH_REVERSE_OK; + + return 0; +} + +/** An iSCSI text string that we want to handle */ +struct iscsi_string_type { + /** String key + * + * This is the portion preceding the "=" sign, + * e.g. "InitiatorName", "CHAP_A", etc. + */ + const char *key; + /** Handle iSCSI string value + * + * @v iscsi iSCSI session + * @v value iSCSI string value + * @ret rc Return status code + */ + int ( * handle ) ( struct iscsi_session *iscsi, const char *value ); +}; + +/** iSCSI text strings that we want to handle */ +static struct iscsi_string_type iscsi_string_types[] = { + { "TargetAddress", iscsi_handle_targetaddress_value }, + { "AuthMethod", iscsi_handle_authmethod_value }, + { "CHAP_A", iscsi_handle_chap_a_value }, + { "CHAP_I", iscsi_handle_chap_i_value }, + { "CHAP_C", iscsi_handle_chap_c_value }, + { "CHAP_N", iscsi_handle_chap_n_value }, + { "CHAP_R", iscsi_handle_chap_r_value }, + { NULL, NULL } +}; + +/** + * Handle iSCSI string + * + * @v iscsi iSCSI session + * @v string iSCSI string (in "key=value" format) + * @ret rc Return status code + */ +static int iscsi_handle_string ( struct iscsi_session *iscsi, + const char *string ) { + struct iscsi_string_type *type; + const char *separator; + const char *value; + size_t key_len; + int rc; + + /* Find separator */ + separator = strchr ( string, '=' ); + if ( ! separator ) { + DBGC ( iscsi, "iSCSI %p malformed string %s\n", + iscsi, string ); + return -EPROTO_INVALID_KEY_VALUE_PAIR; + } + key_len = ( separator - string ); + value = ( separator + 1 ); + + /* Check for rejections. Since we send only non-rejectable + * values, any rejection is a fatal protocol error. + */ + if ( strcmp ( value, "Reject" ) == 0 ) { + DBGC ( iscsi, "iSCSI %p rejection: %s\n", iscsi, string ); + return -EPROTO_VALUE_REJECTED; + } + + /* Handle key/value pair */ + for ( type = iscsi_string_types ; type->key ; type++ ) { + if ( strncmp ( string, type->key, key_len ) != 0 ) + continue; + DBGC ( iscsi, "iSCSI %p handling %s\n", iscsi, string ); + if ( ( rc = type->handle ( iscsi, value ) ) != 0 ) { + DBGC ( iscsi, "iSCSI %p could not handle %s: %s\n", + iscsi, string, strerror ( rc ) ); + return rc; + } + return 0; + } + DBGC ( iscsi, "iSCSI %p ignoring %s\n", iscsi, string ); + return 0; +} + +/** + * Handle iSCSI strings + * + * @v iscsi iSCSI session + * @v string iSCSI string buffer + * @v len Length of string buffer + * @ret rc Return status code + */ +static int iscsi_handle_strings ( struct iscsi_session *iscsi, + const char *strings, size_t len ) { + size_t string_len; + int rc; + + /* Handle each string in turn, taking care not to overrun the + * data buffer in case of badly-terminated data. + */ + while ( 1 ) { + string_len = ( strnlen ( strings, len ) + 1 ); + if ( string_len > len ) + break; + if ( ( rc = iscsi_handle_string ( iscsi, strings ) ) != 0 ) + return rc; + strings += string_len; + len -= string_len; + } + return 0; +} + +/** + * Convert iSCSI response status to return status code + * + * @v status_class iSCSI status class + * @v status_detail iSCSI status detail + * @ret rc Return status code + */ +static int iscsi_status_to_rc ( unsigned int status_class, + unsigned int status_detail ) { + switch ( status_class ) { + case ISCSI_STATUS_INITIATOR_ERROR : + switch ( status_detail ) { + case ISCSI_STATUS_INITIATOR_ERROR_AUTHENTICATION : + return -EPERM_INITIATOR_AUTHENTICATION; + case ISCSI_STATUS_INITIATOR_ERROR_AUTHORISATION : + return -EPERM_INITIATOR_AUTHORISATION; + case ISCSI_STATUS_INITIATOR_ERROR_NOT_FOUND : + case ISCSI_STATUS_INITIATOR_ERROR_REMOVED : + return -ENODEV; + default : + return -ENOTSUP_INITIATOR_STATUS; + } + case ISCSI_STATUS_TARGET_ERROR : + switch ( status_detail ) { + case ISCSI_STATUS_TARGET_ERROR_UNAVAILABLE: + return -EIO_TARGET_UNAVAILABLE; + case ISCSI_STATUS_TARGET_ERROR_NO_RESOURCES: + return -EIO_TARGET_NO_RESOURCES; + default: + return -ENOTSUP_TARGET_STATUS; + } + default : + return -EINVAL; + } +} + +/** + * Receive data segment of an iSCSI login response PDU + * + * @v iscsi iSCSI session + * @v data Received data + * @v len Length of received data + * @v remaining Data remaining after this data + * @ret rc Return status code + */ +static int iscsi_rx_login_response ( struct iscsi_session *iscsi, + const void *data, size_t len, + size_t remaining ) { + struct iscsi_bhs_login_response *response + = &iscsi->rx_bhs.login_response; + int rc; + + /* Buffer up the PDU data */ + if ( ( rc = iscsi_rx_buffered_data ( iscsi, data, len ) ) != 0 ) { + DBGC ( iscsi, "iSCSI %p could not buffer login response: %s\n", + iscsi, strerror ( rc ) ); + return rc; + } + if ( remaining ) + return 0; + + /* Process string data and discard string buffer */ + if ( ( rc = iscsi_handle_strings ( iscsi, iscsi->rx_buffer, + iscsi->rx_len ) ) != 0 ) + return rc; + iscsi_rx_buffered_data_done ( iscsi ); + + /* Check for login redirection */ + if ( response->status_class == ISCSI_STATUS_REDIRECT ) { + DBGC ( iscsi, "iSCSI %p redirecting to new server\n", iscsi ); + iscsi_close_connection ( iscsi, 0 ); + if ( ( rc = iscsi_open_connection ( iscsi ) ) != 0 ) { + DBGC ( iscsi, "iSCSI %p could not redirect: %s\n ", + iscsi, strerror ( rc ) ); + return rc; + } + return 0; + } + + /* Check for fatal errors */ + if ( response->status_class != 0 ) { + DBGC ( iscsi, "iSCSI login failure: class %02x detail %02x\n", + response->status_class, response->status_detail ); + rc = iscsi_status_to_rc ( response->status_class, + response->status_detail ); + return rc; + } + + /* Handle login transitions */ + if ( response->flags & ISCSI_LOGIN_FLAG_TRANSITION ) { + iscsi->status &= ~( ISCSI_STATUS_PHASE_MASK | + ISCSI_STATUS_STRINGS_MASK ); + switch ( response->flags & ISCSI_LOGIN_NSG_MASK ) { + case ISCSI_LOGIN_NSG_OPERATIONAL_NEGOTIATION: + iscsi->status |= + ( ISCSI_STATUS_OPERATIONAL_NEGOTIATION_PHASE | + ISCSI_STATUS_STRINGS_OPERATIONAL ); + break; + case ISCSI_LOGIN_NSG_FULL_FEATURE_PHASE: + iscsi->status |= ISCSI_STATUS_FULL_FEATURE_PHASE; + break; + default: + DBGC ( iscsi, "iSCSI %p got invalid response flags " + "%02x\n", iscsi, response->flags ); + return -EIO; + } + } + + /* Send next login request PDU if we haven't reached the full + * feature phase yet. + */ + if ( ( iscsi->status & ISCSI_STATUS_PHASE_MASK ) != + ISCSI_STATUS_FULL_FEATURE_PHASE ) { + iscsi_start_login ( iscsi ); + return 0; + } + + /* Check that target authentication was successful (if required) */ + if ( ( iscsi->status & ISCSI_STATUS_AUTH_REVERSE_REQUIRED ) && + ! ( iscsi->status & ISCSI_STATUS_AUTH_REVERSE_OK ) ) { + DBGC ( iscsi, "iSCSI %p nefarious target tried to bypass " + "authentication\n", iscsi ); + return -EPROTO; + } + + /* Notify SCSI layer of window change */ + DBGC ( iscsi, "iSCSI %p entering full feature phase\n", iscsi ); + xfer_window_changed ( &iscsi->control ); + + return 0; +} + +/**************************************************************************** + * + * iSCSI to socket interface + * + */ + +/** + * Pause TX engine + * + * @v iscsi iSCSI session + */ +static void iscsi_tx_pause ( struct iscsi_session *iscsi ) { + process_del ( &iscsi->process ); +} + +/** + * Resume TX engine + * + * @v iscsi iSCSI session + */ +static void iscsi_tx_resume ( struct iscsi_session *iscsi ) { + process_add ( &iscsi->process ); +} + +/** + * Start up a new TX PDU + * + * @v iscsi iSCSI session + * + * This initiates the process of sending a new PDU. Only one PDU may + * be in transit at any one time. + */ +static void iscsi_start_tx ( struct iscsi_session *iscsi ) { + + assert ( iscsi->tx_state == ISCSI_TX_IDLE ); + + /* Initialise TX BHS */ + memset ( &iscsi->tx_bhs, 0, sizeof ( iscsi->tx_bhs ) ); + + /* Flag TX engine to start transmitting */ + iscsi->tx_state = ISCSI_TX_BHS; + + /* Start transmission process */ + iscsi_tx_resume ( iscsi ); +} + +/** + * Transmit nothing + * + * @v iscsi iSCSI session + * @ret rc Return status code + */ +static int iscsi_tx_nothing ( struct iscsi_session *iscsi __unused ) { + return 0; +} + +/** + * Transmit basic header segment of an iSCSI PDU + * + * @v iscsi iSCSI session + * @ret rc Return status code + */ +static int iscsi_tx_bhs ( struct iscsi_session *iscsi ) { + return xfer_deliver_raw ( &iscsi->socket, &iscsi->tx_bhs, + sizeof ( iscsi->tx_bhs ) ); +} + +/** + * Transmit data segment of an iSCSI PDU + * + * @v iscsi iSCSI session + * @ret rc Return status code + * + * Handle transmission of part of a PDU data segment. iscsi::tx_bhs + * will be valid when this is called. + */ +static int iscsi_tx_data ( struct iscsi_session *iscsi ) { + struct iscsi_bhs_common *common = &iscsi->tx_bhs.common; + + switch ( common->opcode & ISCSI_OPCODE_MASK ) { + case ISCSI_OPCODE_DATA_OUT: + return iscsi_tx_data_out ( iscsi ); + case ISCSI_OPCODE_LOGIN_REQUEST: + return iscsi_tx_login_request ( iscsi ); + default: + /* Nothing to send in other states */ + return 0; + } +} + +/** + * Complete iSCSI PDU transmission + * + * @v iscsi iSCSI session + * + * Called when a PDU has been completely transmitted and the TX state + * machine is about to enter the idle state. iscsi::tx_bhs will be + * valid for the just-completed PDU when this is called. + */ +static void iscsi_tx_done ( struct iscsi_session *iscsi ) { + struct iscsi_bhs_common *common = &iscsi->tx_bhs.common; + + /* Stop transmission process */ + iscsi_tx_pause ( iscsi ); + + switch ( common->opcode & ISCSI_OPCODE_MASK ) { + case ISCSI_OPCODE_DATA_OUT: + iscsi_data_out_done ( iscsi ); + break; + case ISCSI_OPCODE_LOGIN_REQUEST: + iscsi_login_request_done ( iscsi ); + break; + default: + /* No action */ + break; + } +} + +/** + * Transmit iSCSI PDU + * + * @v iscsi iSCSI session + * @v buf Temporary data buffer + * @v len Length of temporary data buffer + * + * Constructs data to be sent for the current TX state + */ +static void iscsi_tx_step ( struct iscsi_session *iscsi ) { + struct iscsi_bhs_common *common = &iscsi->tx_bhs.common; + int ( * tx ) ( struct iscsi_session *iscsi ); + enum iscsi_tx_state next_state; + size_t tx_len; + int rc; + + /* Select fragment to transmit */ + while ( 1 ) { + switch ( iscsi->tx_state ) { + case ISCSI_TX_BHS: + tx = iscsi_tx_bhs; + tx_len = sizeof ( iscsi->tx_bhs ); + next_state = ISCSI_TX_AHS; + break; + case ISCSI_TX_AHS: + tx = iscsi_tx_nothing; + tx_len = 0; + next_state = ISCSI_TX_DATA; + break; + case ISCSI_TX_DATA: + tx = iscsi_tx_data; + tx_len = ISCSI_DATA_LEN ( common->lengths ); + next_state = ISCSI_TX_IDLE; + break; + case ISCSI_TX_IDLE: + /* Nothing to do; pause processing */ + iscsi_tx_pause ( iscsi ); + return; + default: + assert ( 0 ); + return; + } + + /* Check for window availability, if needed */ + if ( tx_len && ( xfer_window ( &iscsi->socket ) == 0 ) ) { + /* Cannot transmit at this point; pause + * processing and wait for window to reopen + */ + iscsi_tx_pause ( iscsi ); + return; + } + + /* Transmit data */ + if ( ( rc = tx ( iscsi ) ) != 0 ) { + DBGC ( iscsi, "iSCSI %p could not transmit: %s\n", + iscsi, strerror ( rc ) ); + /* Transmission errors are fatal */ + iscsi_close ( iscsi, rc ); + return; + } + + /* Move to next state */ + iscsi->tx_state = next_state; + + /* If we have moved to the idle state, mark + * transmission as complete + */ + if ( iscsi->tx_state == ISCSI_TX_IDLE ) + iscsi_tx_done ( iscsi ); + } +} + +/** iSCSI TX process descriptor */ +static struct process_descriptor iscsi_process_desc = + PROC_DESC ( struct iscsi_session, process, iscsi_tx_step ); + +/** + * Receive basic header segment of an iSCSI PDU + * + * @v iscsi iSCSI session + * @v data Received data + * @v len Length of received data + * @v remaining Data remaining after this data + * @ret rc Return status code + * + * This fills in iscsi::rx_bhs with the data from the BHS portion of + * the received PDU. + */ +static int iscsi_rx_bhs ( struct iscsi_session *iscsi, const void *data, + size_t len, size_t remaining __unused ) { + memcpy ( &iscsi->rx_bhs.bytes[iscsi->rx_offset], data, len ); + if ( ( iscsi->rx_offset + len ) >= sizeof ( iscsi->rx_bhs ) ) { + DBGC2 ( iscsi, "iSCSI %p received PDU opcode %#x len %#x\n", + iscsi, iscsi->rx_bhs.common.opcode, + ISCSI_DATA_LEN ( iscsi->rx_bhs.common.lengths ) ); + } + return 0; +} + +/** + * Discard portion of an iSCSI PDU. + * + * @v iscsi iSCSI session + * @v data Received data + * @v len Length of received data + * @v remaining Data remaining after this data + * @ret rc Return status code + * + * This discards data from a portion of a received PDU. + */ +static int iscsi_rx_discard ( struct iscsi_session *iscsi __unused, + const void *data __unused, size_t len __unused, + size_t remaining __unused ) { + /* Do nothing */ + return 0; +} + +/** + * Receive data segment of an iSCSI PDU + * + * @v iscsi iSCSI session + * @v data Received data + * @v len Length of received data + * @v remaining Data remaining after this data + * @ret rc Return status code + * + * Handle processing of part of a PDU data segment. iscsi::rx_bhs + * will be valid when this is called. + */ +static int iscsi_rx_data ( struct iscsi_session *iscsi, const void *data, + size_t len, size_t remaining ) { + struct iscsi_bhs_common_response *response + = &iscsi->rx_bhs.common_response; + + /* Update cmdsn and statsn */ + iscsi->cmdsn = ntohl ( response->expcmdsn ); + iscsi->statsn = ntohl ( response->statsn ); + + switch ( response->opcode & ISCSI_OPCODE_MASK ) { + case ISCSI_OPCODE_LOGIN_RESPONSE: + return iscsi_rx_login_response ( iscsi, data, len, remaining ); + case ISCSI_OPCODE_SCSI_RESPONSE: + return iscsi_rx_scsi_response ( iscsi, data, len, remaining ); + case ISCSI_OPCODE_DATA_IN: + return iscsi_rx_data_in ( iscsi, data, len, remaining ); + case ISCSI_OPCODE_R2T: + return iscsi_rx_r2t ( iscsi, data, len, remaining ); + case ISCSI_OPCODE_NOP_IN: + return iscsi_rx_nop_in ( iscsi, data, len, remaining ); + default: + if ( remaining ) + return 0; + DBGC ( iscsi, "iSCSI %p unknown opcode %02x\n", iscsi, + response->opcode ); + return -ENOTSUP_OPCODE; + } +} + +/** + * Receive new data + * + * @v iscsi iSCSI session + * @v iobuf I/O buffer + * @v meta Data transfer metadata + * @ret rc Return status code + * + * This handles received PDUs. The receive strategy is to fill in + * iscsi::rx_bhs with the contents of the BHS portion of the PDU, + * throw away any AHS portion, and then process each part of the data + * portion as it arrives. The data processing routine therefore + * always has a full copy of the BHS available, even for portions of + * the data in different packets to the BHS. + */ +static int iscsi_socket_deliver ( struct iscsi_session *iscsi, + struct io_buffer *iobuf, + struct xfer_metadata *meta __unused ) { + struct iscsi_bhs_common *common = &iscsi->rx_bhs.common; + int ( * rx ) ( struct iscsi_session *iscsi, const void *data, + size_t len, size_t remaining ); + enum iscsi_rx_state next_state; + size_t frag_len; + size_t remaining; + int rc; + + while ( 1 ) { + switch ( iscsi->rx_state ) { + case ISCSI_RX_BHS: + rx = iscsi_rx_bhs; + iscsi->rx_len = sizeof ( iscsi->rx_bhs ); + next_state = ISCSI_RX_AHS; + break; + case ISCSI_RX_AHS: + rx = iscsi_rx_discard; + iscsi->rx_len = 4 * ISCSI_AHS_LEN ( common->lengths ); + next_state = ISCSI_RX_DATA; + break; + case ISCSI_RX_DATA: + rx = iscsi_rx_data; + iscsi->rx_len = ISCSI_DATA_LEN ( common->lengths ); + next_state = ISCSI_RX_DATA_PADDING; + break; + case ISCSI_RX_DATA_PADDING: + rx = iscsi_rx_discard; + iscsi->rx_len = ISCSI_DATA_PAD_LEN ( common->lengths ); + next_state = ISCSI_RX_BHS; + break; + default: + assert ( 0 ); + rc = -EINVAL; + goto done; + } + + frag_len = iscsi->rx_len - iscsi->rx_offset; + if ( frag_len > iob_len ( iobuf ) ) + frag_len = iob_len ( iobuf ); + remaining = iscsi->rx_len - iscsi->rx_offset - frag_len; + if ( ( rc = rx ( iscsi, iobuf->data, frag_len, + remaining ) ) != 0 ) { + DBGC ( iscsi, "iSCSI %p could not process received " + "data: %s\n", iscsi, strerror ( rc ) ); + goto done; + } + + iscsi->rx_offset += frag_len; + iob_pull ( iobuf, frag_len ); + + /* If all the data for this state has not yet been + * received, stay in this state for now. + */ + if ( iscsi->rx_offset != iscsi->rx_len ) { + rc = 0; + goto done; + } + + iscsi->rx_state = next_state; + iscsi->rx_offset = 0; + } + + done: + /* Free I/O buffer */ + free_iob ( iobuf ); + + /* Destroy session on error */ + if ( rc != 0 ) + iscsi_close ( iscsi, rc ); + + return rc; +} + +/** + * Handle redirection event + * + * @v iscsi iSCSI session + * @v type Location type + * @v args Remaining arguments depend upon location type + * @ret rc Return status code + */ +static int iscsi_vredirect ( struct iscsi_session *iscsi, int type, + va_list args ) { + va_list tmp; + struct sockaddr *peer; + int rc; + + /* Intercept redirects to a LOCATION_SOCKET and record the IP + * address for the iBFT. This is a bit of a hack, but avoids + * inventing an ioctl()-style call to retrieve the socket + * address from a data-xfer interface. + */ + if ( type == LOCATION_SOCKET ) { + va_copy ( tmp, args ); + ( void ) va_arg ( tmp, int ); /* Discard "semantics" */ + peer = va_arg ( tmp, struct sockaddr * ); + memcpy ( &iscsi->target_sockaddr, peer, + sizeof ( iscsi->target_sockaddr ) ); + va_end ( tmp ); + } + + /* Redirect to new location */ + if ( ( rc = xfer_vreopen ( &iscsi->socket, type, args ) ) != 0 ) + goto err; + + return 0; + + err: + iscsi_close ( iscsi, rc ); + return rc; +} + +/** iSCSI socket interface operations */ +static struct interface_operation iscsi_socket_operations[] = { + INTF_OP ( xfer_deliver, struct iscsi_session *, iscsi_socket_deliver ), + INTF_OP ( xfer_window_changed, struct iscsi_session *, + iscsi_tx_resume ), + INTF_OP ( xfer_vredirect, struct iscsi_session *, iscsi_vredirect ), + INTF_OP ( intf_close, struct iscsi_session *, iscsi_close ), +}; + +/** iSCSI socket interface descriptor */ +static struct interface_descriptor iscsi_socket_desc = + INTF_DESC ( struct iscsi_session, socket, iscsi_socket_operations ); + +/**************************************************************************** + * + * iSCSI command issuing + * + */ + +/** + * Check iSCSI flow-control window + * + * @v iscsi iSCSI session + * @ret len Length of window + */ +static size_t iscsi_scsi_window ( struct iscsi_session *iscsi ) { + + if ( ( ( iscsi->status & ISCSI_STATUS_PHASE_MASK ) == + ISCSI_STATUS_FULL_FEATURE_PHASE ) && + ( iscsi->command == NULL ) ) { + /* We cannot handle concurrent commands */ + return 1; + } else { + return 0; + } +} + +/** + * Issue iSCSI SCSI command + * + * @v iscsi iSCSI session + * @v parent Parent interface + * @v command SCSI command + * @ret tag Command tag, or negative error + */ +static int iscsi_scsi_command ( struct iscsi_session *iscsi, + struct interface *parent, + struct scsi_cmd *command ) { + + /* This iSCSI implementation cannot handle multiple concurrent + * commands or commands arriving before login is complete. + */ + if ( iscsi_scsi_window ( iscsi ) == 0 ) { + DBGC ( iscsi, "iSCSI %p cannot handle concurrent commands\n", + iscsi ); + return -EOPNOTSUPP; + } + + /* Store command */ + iscsi->command = malloc ( sizeof ( *command ) ); + if ( ! iscsi->command ) + return -ENOMEM; + memcpy ( iscsi->command, command, sizeof ( *command ) ); + + /* Assign new ITT */ + iscsi_new_itt ( iscsi ); + + /* Start sending command */ + iscsi_start_command ( iscsi ); + + /* Attach to parent interface and return */ + intf_plug_plug ( &iscsi->data, parent ); + return iscsi->itt; +} + +/** + * Get iSCSI ACPI descriptor + * + * @v iscsi iSCSI session + * @ret desc ACPI descriptor + */ +static struct acpi_descriptor * iscsi_describe ( struct iscsi_session *iscsi ) { + + return &iscsi->desc; +} + +/** iSCSI SCSI command-issuing interface operations */ +static struct interface_operation iscsi_control_op[] = { + INTF_OP ( scsi_command, struct iscsi_session *, iscsi_scsi_command ), + INTF_OP ( xfer_window, struct iscsi_session *, iscsi_scsi_window ), + INTF_OP ( intf_close, struct iscsi_session *, iscsi_close ), + INTF_OP ( acpi_describe, struct iscsi_session *, iscsi_describe ), +}; + +/** iSCSI SCSI command-issuing interface descriptor */ +static struct interface_descriptor iscsi_control_desc = + INTF_DESC ( struct iscsi_session, control, iscsi_control_op ); + +/** + * Close iSCSI command + * + * @v iscsi iSCSI session + * @v rc Reason for close + */ +static void iscsi_command_close ( struct iscsi_session *iscsi, int rc ) { + + /* Restart interface */ + intf_restart ( &iscsi->data, rc ); + + /* Treat unsolicited command closures mid-command as fatal, + * because we have no code to handle partially-completed PDUs. + */ + if ( iscsi->command != NULL ) + iscsi_close ( iscsi, ( ( rc == 0 ) ? -ECANCELED : rc ) ); +} + +/** iSCSI SCSI command interface operations */ +static struct interface_operation iscsi_data_op[] = { + INTF_OP ( intf_close, struct iscsi_session *, iscsi_command_close ), +}; + +/** iSCSI SCSI command interface descriptor */ +static struct interface_descriptor iscsi_data_desc = + INTF_DESC ( struct iscsi_session, data, iscsi_data_op ); + +/**************************************************************************** + * + * Instantiator + * + */ + +/** iSCSI root path components (as per RFC4173) */ +enum iscsi_root_path_component { + RP_SERVERNAME = 0, + RP_PROTOCOL, + RP_PORT, + RP_LUN, + RP_TARGETNAME, + NUM_RP_COMPONENTS +}; + +/** iSCSI initiator IQN setting */ +const struct setting initiator_iqn_setting __setting ( SETTING_SANBOOT_EXTRA, + initiator-iqn ) = { + .name = "initiator-iqn", + .description = "iSCSI initiator name", + .tag = DHCP_ISCSI_INITIATOR_IQN, + .type = &setting_type_string, +}; + +/** iSCSI reverse username setting */ +const struct setting reverse_username_setting __setting ( SETTING_AUTH_EXTRA, + reverse-username ) = { + .name = "reverse-username", + .description = "Reverse user name", + .tag = DHCP_EB_REVERSE_USERNAME, + .type = &setting_type_string, +}; + +/** iSCSI reverse password setting */ +const struct setting reverse_password_setting __setting ( SETTING_AUTH_EXTRA, + reverse-password ) = { + .name = "reverse-password", + .description = "Reverse password", + .tag = DHCP_EB_REVERSE_PASSWORD, + .type = &setting_type_string, +}; + +/** + * Parse iSCSI root path + * + * @v iscsi iSCSI session + * @v root_path iSCSI root path (as per RFC4173) + * @ret rc Return status code + */ +static int iscsi_parse_root_path ( struct iscsi_session *iscsi, + const char *root_path ) { + char rp_copy[ strlen ( root_path ) + 1 ]; + char *rp_comp[NUM_RP_COMPONENTS]; + char *rp = rp_copy; + int skip = 0; + int i = 0; + int rc; + + /* Split root path into component parts */ + strcpy ( rp_copy, root_path ); + while ( 1 ) { + rp_comp[i++] = rp; + if ( i == NUM_RP_COMPONENTS ) + break; + for ( ; ( ( *rp != ':' ) || skip ) ; rp++ ) { + if ( ! *rp ) { + DBGC ( iscsi, "iSCSI %p root path \"%s\" " + "too short\n", iscsi, root_path ); + return -EINVAL_ROOT_PATH_TOO_SHORT; + } else if ( *rp == '[' ) { + skip = 1; + } else if ( *rp == ']' ) { + skip = 0; + } + } + *(rp++) = '\0'; + } + + /* Use root path components to configure iSCSI session */ + iscsi->target_address = strdup ( rp_comp[RP_SERVERNAME] ); + if ( ! iscsi->target_address ) + return -ENOMEM; + iscsi->target_port = strtoul ( rp_comp[RP_PORT], NULL, 10 ); + if ( ! iscsi->target_port ) + iscsi->target_port = ISCSI_PORT; + if ( ( rc = scsi_parse_lun ( rp_comp[RP_LUN], &iscsi->lun ) ) != 0 ) { + DBGC ( iscsi, "iSCSI %p invalid LUN \"%s\"\n", + iscsi, rp_comp[RP_LUN] ); + return rc; + } + iscsi->target_iqn = strdup ( rp_comp[RP_TARGETNAME] ); + if ( ! iscsi->target_iqn ) + return -ENOMEM; + + return 0; +} + +/** + * Fetch iSCSI settings + * + * @v iscsi iSCSI session + * @ret rc Return status code + */ +static int iscsi_fetch_settings ( struct iscsi_session *iscsi ) { + char *hostname; + union uuid uuid; + int len; + + /* Fetch relevant settings. Don't worry about freeing on + * error, since iscsi_free() will take care of that anyway. + */ + fetch_string_setting_copy ( NULL, &username_setting, + &iscsi->initiator_username ); + fetch_string_setting_copy ( NULL, &password_setting, + &iscsi->initiator_password ); + fetch_string_setting_copy ( NULL, &reverse_username_setting, + &iscsi->target_username ); + fetch_string_setting_copy ( NULL, &reverse_password_setting, + &iscsi->target_password ); + + /* Use explicit initiator IQN if provided */ + fetch_string_setting_copy ( NULL, &initiator_iqn_setting, + &iscsi->initiator_iqn ); + if ( iscsi->initiator_iqn ) + return 0; + + /* Otherwise, try to construct an initiator IQN from the hostname */ + fetch_string_setting_copy ( NULL, &hostname_setting, &hostname ); + if ( hostname ) { + len = asprintf ( &iscsi->initiator_iqn, + ISCSI_DEFAULT_IQN_PREFIX ":%s", hostname ); + free ( hostname ); + if ( len < 0 ) { + DBGC ( iscsi, "iSCSI %p could not allocate initiator " + "IQN\n", iscsi ); + return -ENOMEM; + } + assert ( iscsi->initiator_iqn ); + return 0; + } + + /* Otherwise, try to construct an initiator IQN from the UUID */ + if ( ( len = fetch_uuid_setting ( NULL, &uuid_setting, &uuid ) ) < 0 ) { + DBGC ( iscsi, "iSCSI %p has no suitable initiator IQN\n", + iscsi ); + return -EINVAL_NO_INITIATOR_IQN; + } + if ( ( len = asprintf ( &iscsi->initiator_iqn, + ISCSI_DEFAULT_IQN_PREFIX ":%s", + uuid_ntoa ( &uuid ) ) ) < 0 ) { + DBGC ( iscsi, "iSCSI %p could not allocate initiator IQN\n", + iscsi ); + return -ENOMEM; + } + assert ( iscsi->initiator_iqn ); + + return 0; +} + + +/** + * Check iSCSI authentication details + * + * @v iscsi iSCSI session + * @ret rc Return status code + */ +static int iscsi_check_auth ( struct iscsi_session *iscsi ) { + + /* Check for invalid authentication combinations */ + if ( ( /* Initiator username without password (or vice-versa) */ + ( !! iscsi->initiator_username ) ^ + ( !! iscsi->initiator_password ) ) || + ( /* Target username without password (or vice-versa) */ + ( !! iscsi->target_username ) ^ + ( !! iscsi->target_password ) ) || + ( /* Target (reverse) without initiator (forward) */ + ( iscsi->target_username && + ( ! iscsi->initiator_username ) ) ) ) { + DBGC ( iscsi, "iSCSI %p invalid credentials: initiator " + "%sname,%spw, target %sname,%spw\n", iscsi, + ( iscsi->initiator_username ? "" : "no " ), + ( iscsi->initiator_password ? "" : "no " ), + ( iscsi->target_username ? "" : "no " ), + ( iscsi->target_password ? "" : "no " ) ); + return -EINVAL_BAD_CREDENTIAL_MIX; + } + + return 0; +} + +/** + * Open iSCSI URI + * + * @v parent Parent interface + * @v uri URI + * @ret rc Return status code + */ +static int iscsi_open ( struct interface *parent, struct uri *uri ) { + struct iscsi_session *iscsi; + int rc; + + /* Sanity check */ + if ( ! uri->opaque ) { + rc = -EINVAL_NO_ROOT_PATH; + goto err_sanity_uri; + } + + /* Allocate and initialise structure */ + iscsi = zalloc ( sizeof ( *iscsi ) ); + if ( ! iscsi ) { + rc = -ENOMEM; + goto err_zalloc; + } + ref_init ( &iscsi->refcnt, iscsi_free ); + intf_init ( &iscsi->control, &iscsi_control_desc, &iscsi->refcnt ); + intf_init ( &iscsi->data, &iscsi_data_desc, &iscsi->refcnt ); + intf_init ( &iscsi->socket, &iscsi_socket_desc, &iscsi->refcnt ); + process_init_stopped ( &iscsi->process, &iscsi_process_desc, + &iscsi->refcnt ); +// acpi_init ( &iscsi->desc, &ibft_model, &iscsi->refcnt ); + + /* Parse root path */ + if ( ( rc = iscsi_parse_root_path ( iscsi, uri->opaque ) ) != 0 ) + goto err_parse_root_path; + /* Set fields not specified by root path */ + if ( ( rc = iscsi_fetch_settings ( iscsi ) ) != 0 ) + goto err_fetch_settings; + /* Validate authentication */ + if ( ( rc = iscsi_check_auth ( iscsi ) ) != 0 ) + goto err_check_auth; + + /* Sanity checks */ + if ( ! iscsi->target_address ) { + DBGC ( iscsi, "iSCSI %p does not yet support discovery\n", + iscsi ); + rc = -ENOTSUP_DISCOVERY; + goto err_sanity_address; + } + if ( ! iscsi->target_iqn ) { + DBGC ( iscsi, "iSCSI %p no target address supplied in %s\n", + iscsi, uri->opaque ); + rc = -EINVAL_NO_TARGET_IQN; + goto err_sanity_iqn; + } + DBGC ( iscsi, "iSCSI %p initiator %s\n",iscsi, iscsi->initiator_iqn ); + DBGC ( iscsi, "iSCSI %p target %s %s\n", + iscsi, iscsi->target_address, iscsi->target_iqn ); + + /* Open socket */ + if ( ( rc = iscsi_open_connection ( iscsi ) ) != 0 ) + goto err_open_connection; + + /* Attach SCSI device to parent interface */ + if ( ( rc = scsi_open ( parent, &iscsi->control, + &iscsi->lun ) ) != 0 ) { + DBGC ( iscsi, "iSCSI %p could not create SCSI device: %s\n", + iscsi, strerror ( rc ) ); + goto err_scsi_open; + } + + /* Mortalise self, and return */ + ref_put ( &iscsi->refcnt ); + return 0; + + err_scsi_open: + err_open_connection: + err_sanity_iqn: + err_sanity_address: + err_check_auth: + err_fetch_settings: + err_parse_root_path: + iscsi_close ( iscsi, rc ); + ref_put ( &iscsi->refcnt ); + err_zalloc: + err_sanity_uri: + return rc; +} + +/** iSCSI URI opener */ +struct uri_opener iscsi_uri_opener __uri_opener = { + .scheme = "iscsi", + .open = iscsi_open, +}; diff --git a/IPXE/ipxe_org_code/ipxe-3fe683e.tar.bz2 b/IPXE/ipxe_org_code/ipxe-3fe683e.tar.bz2 new file mode 100644 index 0000000..0f60c1e Binary files /dev/null and b/IPXE/ipxe_org_code/ipxe-3fe683e.tar.bz2 differ diff --git a/KBD/cfg/KBD_AZERTY.cfg b/KBD/cfg/KBD_AZERTY.cfg new file mode 100644 index 0000000..6c6c7fc --- /dev/null +++ b/KBD/cfg/KBD_AZERTY.cfg @@ -0,0 +1,65 @@ +# set AZERTY keyboard generic +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey a q +setkey A Q +setkey z w +setkey Z W +setkey q a +setkey Q A +setkey m semicolon +setkey M colon +setkey w z +setkey W Z +setkey comma m +setkey question M +setkey semicolon comma +setkey period less +setkey colon period +setkey slash greater +setkey exclam slash +setkey dollar bracketright +setkey asterisk backslash +setkey percent doublequote +setkey ampersand 1 +setkey 1 exclam +setkey tilde 2 +setkey 2 at +setkey doublequote 3 +setkey 3 numbersign +setkey quote 4 +setkey 4 dollar +setkey parenleft 5 +setkey 5 percent +setkey minus 6 +setkey 6 caret +setkey backquote 7 +setkey 7 ampersand +setkey underscore 8 +setkey 8 asterisk +setkey caret 9 +setkey 9 parenleft +setkey at 0 +setkey 0 parenright +setkey parenright minus +setkey less backquote +setkey greater tilde +setkey numbersign braceright +setkey backslash question +setkey bracketright braceleft +setkey braceleft quote +setkey braceright underscore + +setkey -e +if [ "${quiet}" = "" ]; then + echo AZERTY KBD +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_CZECH_QWERTY.cfg b/KBD/cfg/KBD_CZECH_QWERTY.cfg new file mode 100644 index 0000000..e5934f7 --- /dev/null +++ b/KBD/cfg/KBD_CZECH_QWERTY.cfg @@ -0,0 +1,75 @@ +#QWERTY CZECH +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey semicolon backquote +setkey plus 1 +setkey equal minus +setkey quote equal +setkey parenright bracketright +setkey doublequote backslash +setkey minus slash +#shift +setkey 1 exclam +setkey 2 at +setkey 3 numbersign +setkey 4 dollar +setkey 5 percent +setkey 6 caret +setkey 7 ampersand +setkey 8 asterisk +setkey 9 parenleft +setkey 0 parenright +setkey percent underscore +setkey slash braceleft +setkey parenleft braceright +setkey doublequote colon +setkey exclam doublequote +setkey quote bar +setkey question less +setkey colon greater +setkey underscore question +#Alt +setkey backquote Abackquote +setkey exclam A1 +setkey at A2 +setkey numbersign A3 +setkey dollar A4 +setkey percent A5 +setkey caret A6 +setkey ampersand A7 +setkey asterisk A8 +setkey parenleft A9 +setkey parenright A0 +setkey minus Aminus +setkey equal Aequal +setkey bracketleft Abracketleft +setkey bracketright Abracketright +setkey semicolon Asemicolon +setkey backslash Abackslash +setkey less Acomma +setkey greater Aperiod +setkey slash Aslash +setkey tilde Atilde +setkey underscore Aunderscore +setkey plus Aplus +setkey braceleft Abraceleft +setkey braceright Abraceright +setkey caret Adoublequote +setkey colon Acolon +setkey question Aquestion + +setkey bar Abar + +setkey -e +if [ "${quiet}" = "" ]; then + echo CZECH QWERTY KBD +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_CZECH_QWERTZ.cfg b/KBD/cfg/KBD_CZECH_QWERTZ.cfg new file mode 100644 index 0000000..be8938e --- /dev/null +++ b/KBD/cfg/KBD_CZECH_QWERTZ.cfg @@ -0,0 +1,64 @@ +#QWERTZ CZECH +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey y z +setkey z y +setkey Y Z +setkey Z Y +setkey semicolon backquote +setkey plus 1 +setkey equal minus +setkey quote equal +setkey parenright bracketright +setkey doublequote backslash +setkey minus slash +#shift +setkey 1 exclam +setkey 2 at +setkey 3 numbersign +setkey 4 dollar +setkey 5 percent +setkey 6 caret +setkey 7 ampersand +setkey 8 asterisk +setkey 9 parenleft +setkey 0 parenright +setkey percent underscore +setkey slash braceleft +setkey parenleft braceright +setkey doublequote colon +setkey exclam doublequote +setkey quote bar +setkey question less +setkey colon greater +setkey underscore question +#Alt +setkey tilde A1 +setkey caret A3 +setkey backslash Aq +setkey bar Aw +setkey bracketleft Af +setkey bracketright Ag +setkey dollar Asemicolon +setkey numbersign Ax +setkey ampersand Ac +setkey at Av +setkey braceleft Ab +setkey braceright An +setkey less Acomma +setkey greater Aperiod +setkey asterisk Aslash + +setkey -e +if [ "${quiet}" = "" ]; then + echo CZECH QWERTZ KBD +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_DANISH.cfg b/KBD/cfg/KBD_DANISH.cfg new file mode 100644 index 0000000..1e59902 --- /dev/null +++ b/KBD/cfg/KBD_DANISH.cfg @@ -0,0 +1,56 @@ +#DANISH +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey plus minus +setkey quote equal +setkey doublequote bracketright +setkey quote backslash +setkey minus slash + +#shifted +setkey doublequote at +setkey ampersand caret +setkey slash ampersand +setkey parenleft asterisk +setkey parenright parenleft +setkey equal parenright +setkey question underscore +setkey caret braceright +setkey asterisk bar +setkey backquote plus +setkey semicolon less +setkey colon greater +setkey underscore question + +#use top-left key for oem102 codes +setkey bar Atilde +setkey backslash Abackquote +setkey greater tilde + +#AltGr +setkey at A2 +setkey dollar A4 +setkey braceleft A7 +setkey bracketleft A8 +setkey bracketright A9 +setkey braceright A0 +setkey backslash Aminus + +setkey less quote +setkey greater doublequote +setkey tilde Abracketright + +setkey -e +if [ "${quiet}" = "" ]; then + echo "DANISH KBD a=< A=>" + sleep 2 +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_DVORAK_USA.cfg b/KBD/cfg/KBD_DVORAK_USA.cfg new file mode 100644 index 0000000..9e4b608 --- /dev/null +++ b/KBD/cfg/KBD_DVORAK_USA.cfg @@ -0,0 +1,104 @@ +# Author: Alex Roper +# set DVORAK keyboard +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey [ minus +setkey braceleft underscore +setkey quote q +setkey doublequote Q +setkey comma w +setkey less W +setkey s semicolon +setkey S colon +setkey semicolon z +setkey colon Z +setkey w comma +setkey W less +setkey v period +setkey z greater +setkey z slash +setkey equal bracketright +setkey backslash backslash +setkey underscore doublequote +setkey quote q +setkey doublequote Q +setkey comma w +setkey less W +setkey period e +setkey greater E +setkey p r +setkey P R +setkey y t +setkey Y T +setkey f y +setkey F Y +setkey g u +setkey G U +setkey c c +setkey C I +setkey r o +setkey R O +setkey l p +setkey L P +setkey bracketright equal +setkey braceright plus +setkey a a +setkey A A +setkey o s +setkey O S +setkey e d +setkey E D +setkey u f +setkey U F +setkey i g +setkey I G +setkey d h +setkey D H +setkey h j +setkey H J +setkey t k +setkey T K +setkey n l +setkey N L +setkey s semicolon +setkey S colon +setkey minus quote +setkey underscore doublequote +setkey semicolon z +setkey colon Z +setkey q x +setkey Q X +setkey j c +setkey J C +setkey k v +setkey K V +setkey x b +setkey X B +setkey b n +setkey B N +#setkey m m +#setkey M M +setkey w comma +setkey W less +setkey v period +setkey V greater +setkey z slash +setkey Z question +setkey slash bracketleft +setkey question braceleft +setkey equal bracketright +setkey plus braceright + +setkey -e +if [ "${quiet}" = "" ]; then + echo DVORAK KBD +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_FRENCH.cfg b/KBD/cfg/KBD_FRENCH.cfg new file mode 100644 index 0000000..edc0430 --- /dev/null +++ b/KBD/cfg/KBD_FRENCH.cfg @@ -0,0 +1,80 @@ +#FRENCH AZERTY +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey less backquote +setkey greater tilde +setkey ampersand 1 +setkey 1 exclam +setkey tilde 2 +setkey 2 at +setkey doublequote 3 +setkey 3 numbersign +setkey quote 4 +setkey 4 dollar +setkey parenleft 5 +setkey 5 percent +setkey minus 6 +setkey 6 caret +setkey backquote 7 +setkey 7 ampersand +setkey underscore 8 +setkey 8 asterisk +setkey backslash 9 +setkey 9 parenleft +setkey at 0 +setkey 0 parenright +setkey parenright minus +setkey numbersign underscore +# no change for equal +# no change for plus +setkey a q +setkey A Q +setkey z w +setkey Z W +setkey caret bracketleft +# no equivalent for diaresis => we keep the US braceleft +setkey dollar bracketright +# no equivalent for pound => we keep the US braceright +setkey q a +setkey Q A +setkey m semicolon +setkey M colon +setkey bracketleft quote +setkey percent doublequote +setkey asterisk backslash +setkey bracketright bar +setkey w z +setkey W Z +setkey comma m +setkey question M +setkey semicolon comma +setkey period less +setkey colon period +setkey slash greater +setkey exclam slash +setkey bar question + +setkey tilde A2 +setkey numbersign A3 +setkey braceleft A4 +setkey bracketleft A5 +setkey bar A6 +setkey quote A7 +setkey backslash A8 +setkey caret A9 +setkey at A0 +setkey bracketright Aminus +setkey braceright Aequal +setkey -e +if [ "${quiet}" = "" ]; then + echo FRENCH KBD +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_GERMAN.cfg b/KBD/cfg/KBD_GERMAN.cfg new file mode 100644 index 0000000..1265fcd --- /dev/null +++ b/KBD/cfg/KBD_GERMAN.cfg @@ -0,0 +1,56 @@ +#GERMAN +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey doublequote at +setkey ampersand caret +setkey slash ampersand +setkey parenleft asterisk +setkey parenright parenleft +setkey equal parenright +setkey question underscore +setkey backslash minus +setkey z y +setkey Z Y +setkey y z +setkey Y Z +setkey plus bracketright +setkey asterisk braceright +setkey semicolon less +setkey colon greater +setkey minus slash +setkey backslash Aminus +setkey underscore question +setkey caret backquote +setkey quote equal +setkey backquote plus +setkey braceright doublequote +setkey bar bracketleft +setkey at braceleft +setkey numbersign backslash +setkey at Aq +setkey less backquote +setkey greater tilde +setkey braceleft A7 +setkey bracketleft A8 +setkey bracketright A9 +setkey braceright A0 +setkey tilde Abracketright +setkey backslash Aminus +setkey quote bar +setkey greater semicolon +setkey less colon +setkey bar quote + +setkey -e +if [ "${quiet}" = "" ]; then + echo GERMAN KBD +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_ITALIANO.cfg b/KBD/cfg/KBD_ITALIANO.cfg new file mode 100644 index 0000000..21846ec --- /dev/null +++ b/KBD/cfg/KBD_ITALIANO.cfg @@ -0,0 +1,52 @@ +# Italian +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey backslash backquote +setkey bar tilde +setkey doublequote at +setkey tilde numbersign +setkey ampersand caret +setkey slash ampersand +setkey parenleft asterisk +setkey parenright parenleft +setkey equal parenright +setkey quote minus +setkey question underscore +setkey caret plus +setkey bracketleft bracketleft +setkey bracketright braceleft +setkey plus bracketright +setkey asterisk braceright +setkey at semicolon +setkey braceleft colon +setkey numbersign quote +setkey braceright doublequote +setkey less backslash +setkey greater bar +setkey minus slash +setkey underscore question +setkey semicolon less +setkey colon greater + +setkey bracketleft Abracketleft +setkey bracketright Abracketright +setkey at Asemicolon +setkey numbersign Aquote +setkey braceright Abraceright +setkey braceleft Abraceleft + +setkey -e + +if [ "${quiet}" = "" ]; then + echo ITALIAN KBD +fi + + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_JAPAN_106.cfg b/KBD/cfg/KBD_JAPAN_106.cfg new file mode 100644 index 0000000..42c7fd9 --- /dev/null +++ b/KBD/cfg/KBD_JAPAN_106.cfg @@ -0,0 +1,37 @@ +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +# Jp106 keypad +setkey at bracketleft +setkey doublequote at +setkey ampersand caret +setkey quote ampersand +setkey parenleft asterisk +setkey parenright parenleft +setkey underscore parenright +setkey equal underscore +setkey plus colon +setkey colon quote +setkey asterisk doublequote +setkey bracketleft bracketright +setkey braceleft braceright +setkey bracketright backslash +setkey braceright bar +setkey backslash backquote +setkey tilde plus +setkey caret equal +setkey backquote braceleft +setkey bar tilde + +setkey -e +if [ "${quiet}" = "" ]; then + echo JAPANESE 106 KBD +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_LATIN_USA.cfg b/KBD/cfg/KBD_LATIN_USA.cfg new file mode 100644 index 0000000..f50b418 --- /dev/null +++ b/KBD/cfg/KBD_LATIN_USA.cfg @@ -0,0 +1,53 @@ +#LATIN AMERCICAN KBD +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey bar backquote +setkey quote minus +setkey question underscore +setkey backquote bracketleft +setkey plus bracketright +setkey braceleft quote +setkey braceright backslash +setkey minus slash +setkey ampersand caret +setkey doublequote at +setkey slash ampersand +setkey parenleft asterisk +setkey parenright parenleft +setkey equal parenright +setkey asterisk braceright +setkey bracketleft doublequote +setkey bracketright bar +setkey semicolon less +setkey colon greater +setkey underscore question + +setkey caret Aquote +setkey doublequote braceleft +setkey at Aq +setkey backquote Abackslash + +setkey backslash Aminus + +setkey greater plus +setkey less equal + +setkey backslash Aminus +setkey backquote Abackslash +setkey tilde Abracketright +setkey caret Aquote + +setkey -e +if [ "${quiet}" = "" ]; then + echo "LATIN AMERICAN KBD shift+top-right '>' top-right '<'" + sleep 3 +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_PORTU_BRAZIL.cfg b/KBD/cfg/KBD_PORTU_BRAZIL.cfg new file mode 100644 index 0000000..c0878a8 --- /dev/null +++ b/KBD/cfg/KBD_PORTU_BRAZIL.cfg @@ -0,0 +1,41 @@ +#PORTUGUESE-BRAZIL +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey quote backquote +setkey quote bracketleft +setkey bracketleft bracketright +setkey tilde quote +setkey bracketright backslash +setkey semicolon slash +setkey bar colon + +#shifted +setkey doublequote tilde +setkey backquote braceleft +setkey braceleft braceright +setkey caret doublequote +setkey braceright bar +setkey colon question +setkey backslash semicolon + + +#AltGr +setkey bar Atilde +setkey backslash Abackquote +setkey slash Aq +setkey question Aw + +setkey -e +if [ "${quiet}" = "" ]; then + echo "PORTUGUESE-BRAZIL KBD c+' -> \"|\" C -> \"\\\"" + sleep 3 +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_QWERTY_UK.cfg b/KBD/cfg/KBD_QWERTY_UK.cfg new file mode 100644 index 0000000..01cc9d0 --- /dev/null +++ b/KBD/cfg/KBD_QWERTY_UK.cfg @@ -0,0 +1,27 @@ +#QWERTY UK +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +#change key map for UK keyboard +setkey at doublequote +setkey doublequote at +setkey tilde bar +setkey numbersign backslash +setkey backslash numbersign +setkey bar tilde +setkey backslash Atilde +setkey backslash Abackquote + +setkey -e +if [ "${quiet}" = "" ]; then + echo "UK KBD use [Shift+3] for \\ and [Shift+top-left] for |" + sleep 2 +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_QWERTZ.cfg b/KBD/cfg/KBD_QWERTZ.cfg new file mode 100644 index 0000000..0bacacc --- /dev/null +++ b/KBD/cfg/KBD_QWERTZ.cfg @@ -0,0 +1,44 @@ +#QWERTZ generic +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey doublequote at +setkey ampersand percent +setkey slash ampersand + +setkey equal parenright +setkey question underscore +setkey backslash minus +setkey z y +setkey Z Y +setkey y z +setkey Y Z +setkey plus bracketright +setkey asterisk braceright +setkey semicolon less +setkey colon greater +setkey minus slash + +setkey underscore question +setkey caret backquote + +setkey backquote equal +setkey numbersign backslash +setkey parenright parenleft +setkey parenleft asterisk +setkey percent caret +setkey less numbersign +setkey greater bar + +setkey -e +if [ "${quiet}" = "" ]; then + echo QWERTZ KBD +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_QWERTZ_HUN.cfg b/KBD/cfg/KBD_QWERTZ_HUN.cfg new file mode 100644 index 0000000..f7263b3 --- /dev/null +++ b/KBD/cfg/KBD_QWERTZ_HUN.cfg @@ -0,0 +1,69 @@ +#QWERTZ Hungarian +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey y z +setkey z y +setkey Y Z +setkey Z Y +setkey 0 backquote +setkey quote exclam +setkey doublequote at +setkey plus numbersign +setkey exclam dollar +setkey slash caret +setkey equal ampersand +setkey parenleft asterisk +setkey parenright parenleft +setkey backslash Aq +setkey bar Aw +setkey bracketleft Af +setkey bracketright Ag +#setkey greater Aoem102 - Aoem102 not supported +#this is a y key in hungarian keyboard +setkey greater Az +setkey numbersign Ax +setkey ampersand Ac +setkey at Av +setkey braceleft Ab +setkey braceright An +setkey less Am +#use É (USA=:) for $ +setkey dollar colon +setkey question less +setkey colon greater +setkey minus slash +setkey underscore question +setkey at doublequote +setkey tilde A1 +setkey caret A3 +setkey backquote A7 + +#use Ö for asterisk +setkey asterisk 0 + +setkey dollar Asemicolon +setkey semicolon Acomma +setkey greater Aperiod +setkey asterisk Aslash +#semicolon use é key +#Hun AltGR chars: less greater numbersign ampersand at braceleft braceright semicolon asterisk backslash bar tilde caret quote doublequote bracketleft bracketright + +setkey backquote A9 +setkey doublequote A0 + + + +setkey -e +if [ "${quiet}" = "" ]; then + echo "QWERTZ_HUN KBD e ';'" + sleep 2 +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_QWERTZ_SLOV_CROAT.cfg b/KBD/cfg/KBD_QWERTZ_SLOV_CROAT.cfg new file mode 100644 index 0000000..30b20ea --- /dev/null +++ b/KBD/cfg/KBD_QWERTZ_SLOV_CROAT.cfg @@ -0,0 +1,48 @@ +#QWERTZ Croatian\Slovenian +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey quote minus +setkey plus equal +setkey y z +setkey minus slash +#shifted +setkey doublequote tilde +setkey doublequote at +setkey ampersand caret +setkey slash ampersand +setkey parenleft asterisk +setkey parenright parenleft +setkey equal parenright +setkey question underscore +setkey asterisk plus +setkey Y Z +setkey semicolon less +setkey colon greater +setkey underscore question +#AltGr +setkey tilde A1 +setkey caret A3 +setkey backquote A7 +setkey backslash Aq +setkey bar Aw +setkey bracketleft Af +setkey bracketright Ag +setkey at Av +setkey braceleft Ab +setkey braceright An +setkey less Acomma +setkey greater Aperiod + +setkey -e +if [ "${quiet}" = "" ]; then + echo QWERTZ_SLOV_CROAT KBD +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_SPANISH.cfg b/KBD/cfg/KBD_SPANISH.cfg new file mode 100644 index 0000000..fb9cc3b --- /dev/null +++ b/KBD/cfg/KBD_SPANISH.cfg @@ -0,0 +1,54 @@ +#Espanol - SPANISH CHARACTER - USA KBD CHARACTER +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey slash ampersand +setkey ampersand caret +setkey caret braceleft +setkey asterisk braceright +setkey parenleft asterisk +setkey parenright parenleft +setkey minus slash +setkey equal parenright +setkey quote minus +setkey underscore question +setkey question underscore +#setkey braceleft quote +#setkey braceright backslash +setkey colon greater +setkey greater bar +setkey doublequote at +setkey backslash backquote +setkey less backslash +setkey semicolon less +setkey backquote bracketleft +setkey plus bracketright +setkey plus colon +setkey at semicolon + +setkey bar A1 +setkey at A2 +setkey numbersign A3 +setkey tilde A4 +setkey bracketleft Abracketleft +setkey bracketright Abracketright +setkey braceleft Aquote +setkey braceright Abackslash + +setkey greater bar +setkey less backslash +setkey backslash Abackquote + +setkey -e +if [ "${quiet}" = "" ]; then + echo "SPANISH KBD MAP SET c=< C=>" + sleep 2 +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_SWEDISH.cfg b/KBD/cfg/KBD_SWEDISH.cfg new file mode 100644 index 0000000..6d17d15 --- /dev/null +++ b/KBD/cfg/KBD_SWEDISH.cfg @@ -0,0 +1,56 @@ +#SWEDISH +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey plus minus +setkey quote equal +setkey doublequote bracketright +setkey quote backslash +setkey minus slash + +#shifted +setkey doublequote at +setkey ampersand caret +setkey slash ampersand +setkey parenleft asterisk +setkey parenright parenleft +setkey equal parenright +setkey question underscore +setkey caret braceright +setkey asterisk bar +setkey backquote plus +setkey semicolon less +setkey colon greater +setkey underscore question + +#use top-left key for oem102 codes +setkey bar Atilde +setkey backslash Abackquote +setkey greater tilde + +#AltGr +setkey at A2 +setkey dollar A4 +setkey braceleft A7 +setkey bracketleft A8 +setkey bracketright A9 +setkey braceright A0 +setkey backslash Aminus + +setkey less quote +setkey greater doublequote +setkey tilde Abracketright + +setkey -e +if [ "${quiet}" = "" ]; then + echo "SWEDISH KBD a=< A=>" + sleep 2 +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_TURKISH_Q.cfg b/KBD/cfg/KBD_TURKISH_Q.cfg new file mode 100644 index 0000000..4a02fe6 --- /dev/null +++ b/KBD/cfg/KBD_TURKISH_Q.cfg @@ -0,0 +1,49 @@ +#QWERTY TURKISH +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey doublequote backquote +setkey asterisk minus +setkey minus equal +setkey comma backslash +setkey period slash +#shift +setkey quote at +setkey caret numbersign +setkey plus dollar +setkey ampersand caret +setkey slash ampersand +setkey parenleft asterisk +setkey parenright parenleft +setkey equal parenright +setkey question underscore +setkey underscore plus +setkey semicolon bar +setkey colon question +#altgr +setkey less Abackquote +setkey greater A1 +setkey numbersign A3 +setkey dollar A4 +setkey braceleft A7 +setkey bracketleft A8 +setkey bracketright A9 +setkey braceright A0 +setkey backslash Aminus +setkey bar Aequal +setkey at Aq +setkey doublequote Abracketleft +setkey tilde Abracketright + +setkey -e +if [ "${quiet}" = "" ]; then + echo TURKISH QWERTY KBD +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_VIETNAMESE.cfg b/KBD/cfg/KBD_VIETNAMESE.cfg new file mode 100644 index 0000000..2d81867 --- /dev/null +++ b/KBD/cfg/KBD_VIETNAMESE.cfg @@ -0,0 +1,52 @@ +#VIETNAMESE +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey exclam A1 +setkey at A2 +setkey numbersign A3 +setkey dollar A4 +setkey percent A5 +setkey caret A6 +setkey ampersand A7 +setkey asterisk A8 +setkey parenleft A9 +setkey parenright A0 +setkey plus Aplus +setkey equal Aequal +setkey braceleft Abraceleft +setkey braceright Abraceright +setkey colon Acolon +setkey semicolon Asemicolon +setkey quote Aquote +setkey backslash Abackslash +setkey less Aless +setkey greater Agreater +setkey comma Acomma +setkey period Aperiod +setkey question Aquestion +setkey slash Aslash +setkey tilde Atilde +setkey backquote Abackquote +setkey bracketright Abracketright +setkey bracketleft Abracketleft +setkey bar Abar +setkey doublequote Adoublequote +setkey colon Acolon +setkey minus Aminus +setkey underscore Aunderscore + +#for top row, use unshifted and shifted keys +setkey -e + +if [ "${quiet}" = "" ]; then + echo VIETNAMESE KBD +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/keyboard_layout.c b/KBD/keyboard_layout.c new file mode 100644 index 0000000..8d139b5 --- /dev/null +++ b/KBD/keyboard_layout.c @@ -0,0 +1,795 @@ + +#define ventoy_keyboard_set_layout(name) if (grub_strcmp(layout, #name) == 0) return ventoy_keyboard_layout_##name() + +static void ventoy_keyboard_layout_QWERTY_USA(void) { + grub_keymap_reset(); + grub_keymap_disable(); +} +static void ventoy_keyboard_layout_AZERTY(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("a", "q"); +grub_keymap_add_by_string("A", "Q"); +grub_keymap_add_by_string("z", "w"); +grub_keymap_add_by_string("Z", "W"); +grub_keymap_add_by_string("q", "a"); +grub_keymap_add_by_string("Q", "A"); +grub_keymap_add_by_string("m", "semicolon"); +grub_keymap_add_by_string("M", "colon"); +grub_keymap_add_by_string("w", "z"); +grub_keymap_add_by_string("W", "Z"); +grub_keymap_add_by_string("comma", "m"); +grub_keymap_add_by_string("question", "M"); +grub_keymap_add_by_string("semicolon", "comma"); +grub_keymap_add_by_string("period", "less"); +grub_keymap_add_by_string("colon", "period"); +grub_keymap_add_by_string("slash", "greater"); +grub_keymap_add_by_string("exclam", "slash"); +grub_keymap_add_by_string("dollar", "bracketright"); +grub_keymap_add_by_string("asterisk", "backslash"); +grub_keymap_add_by_string("percent", "doublequote"); +grub_keymap_add_by_string("ampersand", "1"); +grub_keymap_add_by_string("1", "exclam"); +grub_keymap_add_by_string("tilde", "2"); +grub_keymap_add_by_string("2", "at"); +grub_keymap_add_by_string("doublequote", "3"); +grub_keymap_add_by_string("3", "numbersign"); +grub_keymap_add_by_string("quote", "4"); +grub_keymap_add_by_string("4", "dollar"); +grub_keymap_add_by_string("parenleft", "5"); +grub_keymap_add_by_string("5", "percent"); +grub_keymap_add_by_string("minus", "6"); +grub_keymap_add_by_string("6", "caret"); +grub_keymap_add_by_string("backquote", "7"); +grub_keymap_add_by_string("7", "ampersand"); +grub_keymap_add_by_string("underscore", "8"); +grub_keymap_add_by_string("8", "asterisk"); +grub_keymap_add_by_string("caret", "9"); +grub_keymap_add_by_string("9", "parenleft"); +grub_keymap_add_by_string("at", "0"); +grub_keymap_add_by_string("0", "parenright"); +grub_keymap_add_by_string("parenright", "minus"); +grub_keymap_add_by_string("less", "backquote"); +grub_keymap_add_by_string("greater", "tilde"); +grub_keymap_add_by_string("numbersign", "braceright"); +grub_keymap_add_by_string("backslash", "question"); +grub_keymap_add_by_string("bracketright", "braceleft"); +grub_keymap_add_by_string("braceleft", "quote"); +grub_keymap_add_by_string("braceright", "underscore"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_CZECH_QWERTY(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("semicolon", "backquote"); +grub_keymap_add_by_string("plus", "1"); +grub_keymap_add_by_string("equal", "minus"); +grub_keymap_add_by_string("quote", "equal"); +grub_keymap_add_by_string("parenright", "bracketright"); +grub_keymap_add_by_string("doublequote", "backslash"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("1", "exclam"); +grub_keymap_add_by_string("2", "at"); +grub_keymap_add_by_string("3", "numbersign"); +grub_keymap_add_by_string("4", "dollar"); +grub_keymap_add_by_string("5", "percent"); +grub_keymap_add_by_string("6", "caret"); +grub_keymap_add_by_string("7", "ampersand"); +grub_keymap_add_by_string("8", "asterisk"); +grub_keymap_add_by_string("9", "parenleft"); +grub_keymap_add_by_string("0", "parenright"); +grub_keymap_add_by_string("percent", "underscore"); +grub_keymap_add_by_string("slash", "braceleft"); +grub_keymap_add_by_string("parenleft", "braceright"); +grub_keymap_add_by_string("doublequote", "colon"); +grub_keymap_add_by_string("exclam", "doublequote"); +grub_keymap_add_by_string("quote", "bar"); +grub_keymap_add_by_string("question", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("backquote", "Abackquote"); +grub_keymap_add_by_string("exclam", "A1"); +grub_keymap_add_by_string("at", "A2"); +grub_keymap_add_by_string("numbersign", "A3"); +grub_keymap_add_by_string("dollar", "A4"); +grub_keymap_add_by_string("percent", "A5"); +grub_keymap_add_by_string("caret", "A6"); +grub_keymap_add_by_string("ampersand", "A7"); +grub_keymap_add_by_string("asterisk", "A8"); +grub_keymap_add_by_string("parenleft", "A9"); +grub_keymap_add_by_string("parenright", "A0"); +grub_keymap_add_by_string("minus", "Aminus"); +grub_keymap_add_by_string("equal", "Aequal"); +grub_keymap_add_by_string("bracketleft", "Abracketleft"); +grub_keymap_add_by_string("bracketright", "Abracketright"); +grub_keymap_add_by_string("semicolon", "Asemicolon"); +grub_keymap_add_by_string("backslash", "Abackslash"); +grub_keymap_add_by_string("less", "Acomma"); +grub_keymap_add_by_string("greater", "Aperiod"); +grub_keymap_add_by_string("slash", "Aslash"); +grub_keymap_add_by_string("tilde", "Atilde"); +grub_keymap_add_by_string("underscore", "Aunderscore"); +grub_keymap_add_by_string("plus", "Aplus"); +grub_keymap_add_by_string("braceleft", "Abraceleft"); +grub_keymap_add_by_string("braceright", "Abraceright"); +grub_keymap_add_by_string("caret", "Adoublequote"); +grub_keymap_add_by_string("colon", "Acolon"); +grub_keymap_add_by_string("question", "Aquestion"); +grub_keymap_add_by_string("bar", "Abar"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_CZECH_QWERTZ(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("y", "z"); +grub_keymap_add_by_string("z", "y"); +grub_keymap_add_by_string("Y", "Z"); +grub_keymap_add_by_string("Z", "Y"); +grub_keymap_add_by_string("semicolon", "backquote"); +grub_keymap_add_by_string("plus", "1"); +grub_keymap_add_by_string("equal", "minus"); +grub_keymap_add_by_string("quote", "equal"); +grub_keymap_add_by_string("parenright", "bracketright"); +grub_keymap_add_by_string("doublequote", "backslash"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("1", "exclam"); +grub_keymap_add_by_string("2", "at"); +grub_keymap_add_by_string("3", "numbersign"); +grub_keymap_add_by_string("4", "dollar"); +grub_keymap_add_by_string("5", "percent"); +grub_keymap_add_by_string("6", "caret"); +grub_keymap_add_by_string("7", "ampersand"); +grub_keymap_add_by_string("8", "asterisk"); +grub_keymap_add_by_string("9", "parenleft"); +grub_keymap_add_by_string("0", "parenright"); +grub_keymap_add_by_string("percent", "underscore"); +grub_keymap_add_by_string("slash", "braceleft"); +grub_keymap_add_by_string("parenleft", "braceright"); +grub_keymap_add_by_string("doublequote", "colon"); +grub_keymap_add_by_string("exclam", "doublequote"); +grub_keymap_add_by_string("quote", "bar"); +grub_keymap_add_by_string("question", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("tilde", "A1"); +grub_keymap_add_by_string("caret", "A3"); +grub_keymap_add_by_string("backslash", "Aq"); +grub_keymap_add_by_string("bar", "Aw"); +grub_keymap_add_by_string("bracketleft", "Af"); +grub_keymap_add_by_string("bracketright", "Ag"); +grub_keymap_add_by_string("dollar", "Asemicolon"); +grub_keymap_add_by_string("numbersign", "Ax"); +grub_keymap_add_by_string("ampersand", "Ac"); +grub_keymap_add_by_string("at", "Av"); +grub_keymap_add_by_string("braceleft", "Ab"); +grub_keymap_add_by_string("braceright", "An"); +grub_keymap_add_by_string("less", "Acomma"); +grub_keymap_add_by_string("greater", "Aperiod"); +grub_keymap_add_by_string("asterisk", "Aslash"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_DANISH(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("plus", "minus"); +grub_keymap_add_by_string("quote", "equal"); +grub_keymap_add_by_string("doublequote", "bracketright"); +grub_keymap_add_by_string("quote", "backslash"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("caret", "braceright"); +grub_keymap_add_by_string("asterisk", "bar"); +grub_keymap_add_by_string("backquote", "plus"); +grub_keymap_add_by_string("semicolon", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("bar", "Atilde"); +grub_keymap_add_by_string("backslash", "Abackquote"); +grub_keymap_add_by_string("greater", "tilde"); +grub_keymap_add_by_string("at", "A2"); +grub_keymap_add_by_string("dollar", "A4"); +grub_keymap_add_by_string("braceleft", "A7"); +grub_keymap_add_by_string("bracketleft", "A8"); +grub_keymap_add_by_string("bracketright", "A9"); +grub_keymap_add_by_string("braceright", "A0"); +grub_keymap_add_by_string("backslash", "Aminus"); +grub_keymap_add_by_string("less", "quote"); +grub_keymap_add_by_string("greater", "doublequote"); +grub_keymap_add_by_string("tilde", "Abracketright"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_DVORAK_USA(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("[", "minus"); +grub_keymap_add_by_string("braceleft", "underscore"); +grub_keymap_add_by_string("quote", "q"); +grub_keymap_add_by_string("doublequote", "Q"); +grub_keymap_add_by_string("comma", "w"); +grub_keymap_add_by_string("less", "W"); +grub_keymap_add_by_string("s", "semicolon"); +grub_keymap_add_by_string("S", "colon"); +grub_keymap_add_by_string("semicolon", "z"); +grub_keymap_add_by_string("colon", "Z"); +grub_keymap_add_by_string("w", "comma"); +grub_keymap_add_by_string("W", "less"); +grub_keymap_add_by_string("v", "period"); +grub_keymap_add_by_string("z", "greater"); +grub_keymap_add_by_string("z", "slash"); +grub_keymap_add_by_string("equal", "bracketright"); +grub_keymap_add_by_string("backslash", "backslash"); +grub_keymap_add_by_string("underscore", "doublequote"); +grub_keymap_add_by_string("quote", "q"); +grub_keymap_add_by_string("doublequote", "Q"); +grub_keymap_add_by_string("comma", "w"); +grub_keymap_add_by_string("less", "W"); +grub_keymap_add_by_string("period", "e"); +grub_keymap_add_by_string("greater", "E"); +grub_keymap_add_by_string("p", "r"); +grub_keymap_add_by_string("P", "R"); +grub_keymap_add_by_string("y", "t"); +grub_keymap_add_by_string("Y", "T"); +grub_keymap_add_by_string("f", "y"); +grub_keymap_add_by_string("F", "Y"); +grub_keymap_add_by_string("g", "u"); +grub_keymap_add_by_string("G", "U"); +grub_keymap_add_by_string("c", "c"); +grub_keymap_add_by_string("C", "I"); +grub_keymap_add_by_string("r", "o"); +grub_keymap_add_by_string("R", "O"); +grub_keymap_add_by_string("l", "p"); +grub_keymap_add_by_string("L", "P"); +grub_keymap_add_by_string("bracketright", "equal"); +grub_keymap_add_by_string("braceright", "plus"); +grub_keymap_add_by_string("a", "a"); +grub_keymap_add_by_string("A", "A"); +grub_keymap_add_by_string("o", "s"); +grub_keymap_add_by_string("O", "S"); +grub_keymap_add_by_string("e", "d"); +grub_keymap_add_by_string("E", "D"); +grub_keymap_add_by_string("u", "f"); +grub_keymap_add_by_string("U", "F"); +grub_keymap_add_by_string("i", "g"); +grub_keymap_add_by_string("I", "G"); +grub_keymap_add_by_string("d", "h"); +grub_keymap_add_by_string("D", "H"); +grub_keymap_add_by_string("h", "j"); +grub_keymap_add_by_string("H", "J"); +grub_keymap_add_by_string("t", "k"); +grub_keymap_add_by_string("T", "K"); +grub_keymap_add_by_string("n", "l"); +grub_keymap_add_by_string("N", "L"); +grub_keymap_add_by_string("s", "semicolon"); +grub_keymap_add_by_string("S", "colon"); +grub_keymap_add_by_string("minus", "quote"); +grub_keymap_add_by_string("underscore", "doublequote"); +grub_keymap_add_by_string("semicolon", "z"); +grub_keymap_add_by_string("colon", "Z"); +grub_keymap_add_by_string("q", "x"); +grub_keymap_add_by_string("Q", "X"); +grub_keymap_add_by_string("j", "c"); +grub_keymap_add_by_string("J", "C"); +grub_keymap_add_by_string("k", "v"); +grub_keymap_add_by_string("K", "V"); +grub_keymap_add_by_string("x", "b"); +grub_keymap_add_by_string("X", "B"); +grub_keymap_add_by_string("b", "n"); +grub_keymap_add_by_string("B", "N"); +grub_keymap_add_by_string("w", "comma"); +grub_keymap_add_by_string("W", "less"); +grub_keymap_add_by_string("v", "period"); +grub_keymap_add_by_string("V", "greater"); +grub_keymap_add_by_string("z", "slash"); +grub_keymap_add_by_string("Z", "question"); +grub_keymap_add_by_string("slash", "bracketleft"); +grub_keymap_add_by_string("question", "braceleft"); +grub_keymap_add_by_string("equal", "bracketright"); +grub_keymap_add_by_string("plus", "braceright"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_FRENCH(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("less", "backquote"); +grub_keymap_add_by_string("greater", "tilde"); +grub_keymap_add_by_string("ampersand", "1"); +grub_keymap_add_by_string("1", "exclam"); +grub_keymap_add_by_string("tilde", "2"); +grub_keymap_add_by_string("2", "at"); +grub_keymap_add_by_string("doublequote", "3"); +grub_keymap_add_by_string("3", "numbersign"); +grub_keymap_add_by_string("quote", "4"); +grub_keymap_add_by_string("4", "dollar"); +grub_keymap_add_by_string("parenleft", "5"); +grub_keymap_add_by_string("5", "percent"); +grub_keymap_add_by_string("minus", "6"); +grub_keymap_add_by_string("6", "caret"); +grub_keymap_add_by_string("backquote", "7"); +grub_keymap_add_by_string("7", "ampersand"); +grub_keymap_add_by_string("underscore", "8"); +grub_keymap_add_by_string("8", "asterisk"); +grub_keymap_add_by_string("backslash", "9"); +grub_keymap_add_by_string("9", "parenleft"); +grub_keymap_add_by_string("at", "0"); +grub_keymap_add_by_string("0", "parenright"); +grub_keymap_add_by_string("parenright", "minus"); +grub_keymap_add_by_string("numbersign", "underscore"); +grub_keymap_add_by_string("a", "q"); +grub_keymap_add_by_string("A", "Q"); +grub_keymap_add_by_string("z", "w"); +grub_keymap_add_by_string("Z", "W"); +grub_keymap_add_by_string("caret", "bracketleft"); +grub_keymap_add_by_string("dollar", "bracketright"); +grub_keymap_add_by_string("q", "a"); +grub_keymap_add_by_string("Q", "A"); +grub_keymap_add_by_string("m", "semicolon"); +grub_keymap_add_by_string("M", "colon"); +grub_keymap_add_by_string("bracketleft", "quote"); +grub_keymap_add_by_string("percent", "doublequote"); +grub_keymap_add_by_string("asterisk", "backslash"); +grub_keymap_add_by_string("bracketright", "bar"); +grub_keymap_add_by_string("w", "z"); +grub_keymap_add_by_string("W", "Z"); +grub_keymap_add_by_string("comma", "m"); +grub_keymap_add_by_string("question", "M"); +grub_keymap_add_by_string("semicolon", "comma"); +grub_keymap_add_by_string("period", "less"); +grub_keymap_add_by_string("colon", "period"); +grub_keymap_add_by_string("slash", "greater"); +grub_keymap_add_by_string("exclam", "slash"); +grub_keymap_add_by_string("bar", "question"); +grub_keymap_add_by_string("tilde", "A2"); +grub_keymap_add_by_string("numbersign", "A3"); +grub_keymap_add_by_string("braceleft", "A4"); +grub_keymap_add_by_string("bracketleft", "A5"); +grub_keymap_add_by_string("bar", "A6"); +grub_keymap_add_by_string("quote", "A7"); +grub_keymap_add_by_string("backslash", "A8"); +grub_keymap_add_by_string("caret", "A9"); +grub_keymap_add_by_string("at", "A0"); +grub_keymap_add_by_string("bracketright", "Aminus"); +grub_keymap_add_by_string("braceright", "Aequal"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_GERMAN(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("backslash", "minus"); +grub_keymap_add_by_string("z", "y"); +grub_keymap_add_by_string("Z", "Y"); +grub_keymap_add_by_string("y", "z"); +grub_keymap_add_by_string("Y", "Z"); +grub_keymap_add_by_string("plus", "bracketright"); +grub_keymap_add_by_string("asterisk", "braceright"); +grub_keymap_add_by_string("semicolon", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("backslash", "Aminus"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("caret", "backquote"); +grub_keymap_add_by_string("quote", "equal"); +grub_keymap_add_by_string("backquote", "plus"); +grub_keymap_add_by_string("braceright", "doublequote"); +grub_keymap_add_by_string("bar", "bracketleft"); +grub_keymap_add_by_string("at", "braceleft"); +grub_keymap_add_by_string("numbersign", "backslash"); +grub_keymap_add_by_string("at", "Aq"); +grub_keymap_add_by_string("less", "backquote"); +grub_keymap_add_by_string("greater", "tilde"); +grub_keymap_add_by_string("braceleft", "A7"); +grub_keymap_add_by_string("bracketleft", "A8"); +grub_keymap_add_by_string("bracketright", "A9"); +grub_keymap_add_by_string("braceright", "A0"); +grub_keymap_add_by_string("tilde", "Abracketright"); +grub_keymap_add_by_string("backslash", "Aminus"); +grub_keymap_add_by_string("quote", "bar"); +grub_keymap_add_by_string("greater", "semicolon"); +grub_keymap_add_by_string("less", "colon"); +grub_keymap_add_by_string("bar", "quote"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_ITALIANO(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("backslash", "backquote"); +grub_keymap_add_by_string("bar", "tilde"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("tilde", "numbersign"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("quote", "minus"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("caret", "plus"); +grub_keymap_add_by_string("bracketleft", "bracketleft"); +grub_keymap_add_by_string("bracketright", "braceleft"); +grub_keymap_add_by_string("plus", "bracketright"); +grub_keymap_add_by_string("asterisk", "braceright"); +grub_keymap_add_by_string("at", "semicolon"); +grub_keymap_add_by_string("braceleft", "colon"); +grub_keymap_add_by_string("numbersign", "quote"); +grub_keymap_add_by_string("braceright", "doublequote"); +grub_keymap_add_by_string("less", "backslash"); +grub_keymap_add_by_string("greater", "bar"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("semicolon", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("bracketleft", "Abracketleft"); +grub_keymap_add_by_string("bracketright", "Abracketright"); +grub_keymap_add_by_string("at", "Asemicolon"); +grub_keymap_add_by_string("numbersign", "Aquote"); +grub_keymap_add_by_string("braceright", "Abraceright"); +grub_keymap_add_by_string("braceleft", "Abraceleft"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_JAPAN_106(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("at", "bracketleft"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("quote", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("underscore", "parenright"); +grub_keymap_add_by_string("equal", "underscore"); +grub_keymap_add_by_string("plus", "colon"); +grub_keymap_add_by_string("colon", "quote"); +grub_keymap_add_by_string("asterisk", "doublequote"); +grub_keymap_add_by_string("bracketleft", "bracketright"); +grub_keymap_add_by_string("braceleft", "braceright"); +grub_keymap_add_by_string("bracketright", "backslash"); +grub_keymap_add_by_string("braceright", "bar"); +grub_keymap_add_by_string("backslash", "backquote"); +grub_keymap_add_by_string("tilde", "plus"); +grub_keymap_add_by_string("caret", "equal"); +grub_keymap_add_by_string("backquote", "braceleft"); +grub_keymap_add_by_string("bar", "tilde"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_LATIN_USA(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("bar", "backquote"); +grub_keymap_add_by_string("quote", "minus"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("backquote", "bracketleft"); +grub_keymap_add_by_string("plus", "bracketright"); +grub_keymap_add_by_string("braceleft", "quote"); +grub_keymap_add_by_string("braceright", "backslash"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("asterisk", "braceright"); +grub_keymap_add_by_string("bracketleft", "doublequote"); +grub_keymap_add_by_string("bracketright", "bar"); +grub_keymap_add_by_string("semicolon", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("caret", "Aquote"); +grub_keymap_add_by_string("doublequote", "braceleft"); +grub_keymap_add_by_string("at", "Aq"); +grub_keymap_add_by_string("backquote", "Abackslash"); +grub_keymap_add_by_string("backslash", "Aminus"); +grub_keymap_add_by_string("greater", "plus"); +grub_keymap_add_by_string("less", "equal"); +grub_keymap_add_by_string("backslash", "Aminus"); +grub_keymap_add_by_string("backquote", "Abackslash"); +grub_keymap_add_by_string("tilde", "Abracketright"); +grub_keymap_add_by_string("caret", "Aquote"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_PORTU_BRAZIL(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("quote", "backquote"); +grub_keymap_add_by_string("quote", "bracketleft"); +grub_keymap_add_by_string("bracketleft", "bracketright"); +grub_keymap_add_by_string("tilde", "quote"); +grub_keymap_add_by_string("bracketright", "backslash"); +grub_keymap_add_by_string("semicolon", "slash"); +grub_keymap_add_by_string("bar", "colon"); +grub_keymap_add_by_string("doublequote", "tilde"); +grub_keymap_add_by_string("backquote", "braceleft"); +grub_keymap_add_by_string("braceleft", "braceright"); +grub_keymap_add_by_string("caret", "doublequote"); +grub_keymap_add_by_string("braceright", "bar"); +grub_keymap_add_by_string("colon", "question"); +grub_keymap_add_by_string("backslash", "semicolon"); +grub_keymap_add_by_string("bar", "Atilde"); +grub_keymap_add_by_string("backslash", "Abackquote"); +grub_keymap_add_by_string("slash", "Aq"); +grub_keymap_add_by_string("question", "Aw"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_QWERTY_UK(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("at", "doublequote"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("tilde", "bar"); +grub_keymap_add_by_string("numbersign", "backslash"); +grub_keymap_add_by_string("backslash", "numbersign"); +grub_keymap_add_by_string("bar", "tilde"); +grub_keymap_add_by_string("backslash", "Atilde"); +grub_keymap_add_by_string("backslash", "Abackquote"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_QWERTZ(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("ampersand", "percent"); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("backslash", "minus"); +grub_keymap_add_by_string("z", "y"); +grub_keymap_add_by_string("Z", "Y"); +grub_keymap_add_by_string("y", "z"); +grub_keymap_add_by_string("Y", "Z"); +grub_keymap_add_by_string("plus", "bracketright"); +grub_keymap_add_by_string("asterisk", "braceright"); +grub_keymap_add_by_string("semicolon", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("caret", "backquote"); +grub_keymap_add_by_string("backquote", "equal"); +grub_keymap_add_by_string("numbersign", "backslash"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("percent", "caret"); +grub_keymap_add_by_string("less", "numbersign"); +grub_keymap_add_by_string("greater", "bar"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_QWERTZ_HUN(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("y", "z"); +grub_keymap_add_by_string("z", "y"); +grub_keymap_add_by_string("Y", "Z"); +grub_keymap_add_by_string("Z", "Y"); +grub_keymap_add_by_string("0", "backquote"); +grub_keymap_add_by_string("quote", "exclam"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("plus", "numbersign"); +grub_keymap_add_by_string("exclam", "dollar"); +grub_keymap_add_by_string("slash", "caret"); +grub_keymap_add_by_string("equal", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("backslash", "Aq"); +grub_keymap_add_by_string("bar", "Aw"); +grub_keymap_add_by_string("bracketleft", "Af"); +grub_keymap_add_by_string("bracketright", "Ag"); +grub_keymap_add_by_string("greater", "Az"); +grub_keymap_add_by_string("numbersign", "Ax"); +grub_keymap_add_by_string("ampersand", "Ac"); +grub_keymap_add_by_string("at", "Av"); +grub_keymap_add_by_string("braceleft", "Ab"); +grub_keymap_add_by_string("braceright", "An"); +grub_keymap_add_by_string("less", "Am"); +grub_keymap_add_by_string("dollar", "colon"); +grub_keymap_add_by_string("question", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("at", "doublequote"); +grub_keymap_add_by_string("tilde", "A1"); +grub_keymap_add_by_string("caret", "A3"); +grub_keymap_add_by_string("backquote", "A7"); +grub_keymap_add_by_string("asterisk", "0"); +grub_keymap_add_by_string("dollar", "Asemicolon"); +grub_keymap_add_by_string("semicolon", "Acomma"); +grub_keymap_add_by_string("greater", "Aperiod"); +grub_keymap_add_by_string("asterisk", "Aslash"); +grub_keymap_add_by_string("backquote", "A9"); +grub_keymap_add_by_string("doublequote", "A0"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_QWERTZ_SLOV_CROAT(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("quote", "minus"); +grub_keymap_add_by_string("plus", "equal"); +grub_keymap_add_by_string("y", "z"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("doublequote", "tilde"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("asterisk", "plus"); +grub_keymap_add_by_string("Y", "Z"); +grub_keymap_add_by_string("semicolon", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("tilde", "A1"); +grub_keymap_add_by_string("caret", "A3"); +grub_keymap_add_by_string("backquote", "A7"); +grub_keymap_add_by_string("backslash", "Aq"); +grub_keymap_add_by_string("bar", "Aw"); +grub_keymap_add_by_string("bracketleft", "Af"); +grub_keymap_add_by_string("bracketright", "Ag"); +grub_keymap_add_by_string("at", "Av"); +grub_keymap_add_by_string("braceleft", "Ab"); +grub_keymap_add_by_string("braceright", "An"); +grub_keymap_add_by_string("less", "Acomma"); +grub_keymap_add_by_string("greater", "Aperiod"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_SPANISH(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("caret", "braceleft"); +grub_keymap_add_by_string("asterisk", "braceright"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("quote", "minus"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("greater", "bar"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("backslash", "backquote"); +grub_keymap_add_by_string("less", "backslash"); +grub_keymap_add_by_string("semicolon", "less"); +grub_keymap_add_by_string("backquote", "bracketleft"); +grub_keymap_add_by_string("plus", "bracketright"); +grub_keymap_add_by_string("plus", "colon"); +grub_keymap_add_by_string("at", "semicolon"); +grub_keymap_add_by_string("bar", "A1"); +grub_keymap_add_by_string("at", "A2"); +grub_keymap_add_by_string("numbersign", "A3"); +grub_keymap_add_by_string("tilde", "A4"); +grub_keymap_add_by_string("bracketleft", "Abracketleft"); +grub_keymap_add_by_string("bracketright", "Abracketright"); +grub_keymap_add_by_string("braceleft", "Aquote"); +grub_keymap_add_by_string("braceright", "Abackslash"); +grub_keymap_add_by_string("greater", "bar"); +grub_keymap_add_by_string("less", "backslash"); +grub_keymap_add_by_string("backslash", "Abackquote"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_SWEDISH(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("plus", "minus"); +grub_keymap_add_by_string("quote", "equal"); +grub_keymap_add_by_string("doublequote", "bracketright"); +grub_keymap_add_by_string("quote", "backslash"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("caret", "braceright"); +grub_keymap_add_by_string("asterisk", "bar"); +grub_keymap_add_by_string("backquote", "plus"); +grub_keymap_add_by_string("semicolon", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("bar", "Atilde"); +grub_keymap_add_by_string("backslash", "Abackquote"); +grub_keymap_add_by_string("greater", "tilde"); +grub_keymap_add_by_string("at", "A2"); +grub_keymap_add_by_string("dollar", "A4"); +grub_keymap_add_by_string("braceleft", "A7"); +grub_keymap_add_by_string("bracketleft", "A8"); +grub_keymap_add_by_string("bracketright", "A9"); +grub_keymap_add_by_string("braceright", "A0"); +grub_keymap_add_by_string("backslash", "Aminus"); +grub_keymap_add_by_string("less", "quote"); +grub_keymap_add_by_string("greater", "doublequote"); +grub_keymap_add_by_string("tilde", "Abracketright"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_TURKISH_Q(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("doublequote", "backquote"); +grub_keymap_add_by_string("asterisk", "minus"); +grub_keymap_add_by_string("minus", "equal"); +grub_keymap_add_by_string("comma", "backslash"); +grub_keymap_add_by_string("period", "slash"); +grub_keymap_add_by_string("quote", "at"); +grub_keymap_add_by_string("caret", "numbersign"); +grub_keymap_add_by_string("plus", "dollar"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("underscore", "plus"); +grub_keymap_add_by_string("semicolon", "bar"); +grub_keymap_add_by_string("colon", "question"); +grub_keymap_add_by_string("less", "Abackquote"); +grub_keymap_add_by_string("greater", "A1"); +grub_keymap_add_by_string("numbersign", "A3"); +grub_keymap_add_by_string("dollar", "A4"); +grub_keymap_add_by_string("braceleft", "A7"); +grub_keymap_add_by_string("bracketleft", "A8"); +grub_keymap_add_by_string("bracketright", "A9"); +grub_keymap_add_by_string("braceright", "A0"); +grub_keymap_add_by_string("backslash", "Aminus"); +grub_keymap_add_by_string("bar", "Aequal"); +grub_keymap_add_by_string("at", "Aq"); +grub_keymap_add_by_string("doublequote", "Abracketleft"); +grub_keymap_add_by_string("tilde", "Abracketright"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_VIETNAMESE(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("exclam", "A1"); +grub_keymap_add_by_string("at", "A2"); +grub_keymap_add_by_string("numbersign", "A3"); +grub_keymap_add_by_string("dollar", "A4"); +grub_keymap_add_by_string("percent", "A5"); +grub_keymap_add_by_string("caret", "A6"); +grub_keymap_add_by_string("ampersand", "A7"); +grub_keymap_add_by_string("asterisk", "A8"); +grub_keymap_add_by_string("parenleft", "A9"); +grub_keymap_add_by_string("parenright", "A0"); +grub_keymap_add_by_string("plus", "Aplus"); +grub_keymap_add_by_string("equal", "Aequal"); +grub_keymap_add_by_string("braceleft", "Abraceleft"); +grub_keymap_add_by_string("braceright", "Abraceright"); +grub_keymap_add_by_string("colon", "Acolon"); +grub_keymap_add_by_string("semicolon", "Asemicolon"); +grub_keymap_add_by_string("quote", "Aquote"); +grub_keymap_add_by_string("backslash", "Abackslash"); +grub_keymap_add_by_string("less", "Aless"); +grub_keymap_add_by_string("greater", "Agreater"); +grub_keymap_add_by_string("comma", "Acomma"); +grub_keymap_add_by_string("period", "Aperiod"); +grub_keymap_add_by_string("question", "Aquestion"); +grub_keymap_add_by_string("slash", "Aslash"); +grub_keymap_add_by_string("tilde", "Atilde"); +grub_keymap_add_by_string("backquote", "Abackquote"); +grub_keymap_add_by_string("bracketright", "Abracketright"); +grub_keymap_add_by_string("bracketleft", "Abracketleft"); +grub_keymap_add_by_string("bar", "Abar"); +grub_keymap_add_by_string("doublequote", "Adoublequote"); +grub_keymap_add_by_string("colon", "Acolon"); +grub_keymap_add_by_string("minus", "Aminus"); +grub_keymap_add_by_string("underscore", "Aunderscore"); +grub_keymap_enable(); +} +void ventoy_set_keyboard_layout(const char *layout); +void ventoy_set_keyboard_layout(const char *layout) { +ventoy_keyboard_set_layout(QWERTY_USA); +ventoy_keyboard_set_layout(AZERTY); +ventoy_keyboard_set_layout(CZECH_QWERTY); +ventoy_keyboard_set_layout(CZECH_QWERTZ); +ventoy_keyboard_set_layout(DANISH); +ventoy_keyboard_set_layout(DVORAK_USA); +ventoy_keyboard_set_layout(FRENCH); +ventoy_keyboard_set_layout(GERMAN); +ventoy_keyboard_set_layout(ITALIANO); +ventoy_keyboard_set_layout(JAPAN_106); +ventoy_keyboard_set_layout(LATIN_USA); +ventoy_keyboard_set_layout(PORTU_BRAZIL); +ventoy_keyboard_set_layout(QWERTY_UK); +ventoy_keyboard_set_layout(QWERTZ); +ventoy_keyboard_set_layout(QWERTZ_HUN); +ventoy_keyboard_set_layout(QWERTZ_SLOV_CROAT); +ventoy_keyboard_set_layout(SPANISH); +ventoy_keyboard_set_layout(SWEDISH); +ventoy_keyboard_set_layout(TURKISH_Q); +ventoy_keyboard_set_layout(VIETNAMESE); +} diff --git a/KBD/mkconfig.sh b/KBD/mkconfig.sh new file mode 100644 index 0000000..0e09792 --- /dev/null +++ b/KBD/mkconfig.sh @@ -0,0 +1,84 @@ +#!/bin/sh + +# +# Configfiles are from grubfilemanager project +# + +cfgfile=keyboard_layout.c +rm -f ${cfgfile} + +cat >>$cfgfile << EOF + +#define ventoy_keyboard_set_layout(name) if (grub_strcmp(layout, #name) == 0) return ventoy_keyboard_layout_##name() + +menuentry QWERTY_USA --class=debug_kbd { + setkey -r + setkey -d +} +EOF + +ls -1 cfg | while read line; do + kbd=${line%.cfg} + name=${kbd#KBD_} + + echo "menuentry $name --class=debug_kbd {" >> $cfgfile + grep '^setkey' cfg/$line >>$cfgfile + echo "}" >> $cfgfile +done + +dos2unix $cfgfile +sed 's/menuentry \([^ ]*\) .*/static void ventoy_keyboard_layout_\1(void) {/g' -i $cfgfile +sed 's/setkey *-r/grub_keymap_reset();/g' -i $cfgfile +sed 's/setkey *-d/grub_keymap_disable();/g' -i $cfgfile +sed 's/setkey *-e/grub_keymap_enable();/g' -i $cfgfile +sed 's/^setkey *\([^ ]*\) *\([^ ]*\)/grub_keymap_add_by_string("\1", "\2");/g' -i $cfgfile + +rm -f .tmpfunc +echo "void ventoy_set_keyboard_layout(const char *layout);" >> .tmpfunc +echo "void ventoy_set_keyboard_layout(const char *layout) {" >> .tmpfunc +grep 'void *ventoy_keyboard_layout_' $cfgfile | while read line; do + name=$(echo $line | sed 's/.*ventoy_keyboard_layout_\(.*\)(.*/\1/g') + echo "ventoy_keyboard_set_layout($name);" >> .tmpfunc +done + +echo "}" >> .tmpfunc + +cat .tmpfunc >> $cfgfile +rm -f .tmpfunc + +rm -f ../GRUB2/SRC/grub-2.04/grub-core/term/$cfgfile +cp -a $cfgfile ../GRUB2/SRC/grub-2.04/grub-core/term/$cfgfile + + + + + +############ +# +# cfg +############# + +cfgfile=../INSTALL/grub/keyboard.cfg +rm -f ${cfgfile} + +echo "submenu \"Keyboard Layouts\" --class=debug_krdlayout {" >>$cfgfile + +cat >>$cfgfile << EOF + menuentry QWERTY_USA --class=debug_kbd { + set_keyboard_layout QWERTY_USA + } +EOF + +ls -1 cfg | while read line; do + kbd=${line%.cfg} + name=${kbd#KBD_} + + echo " menuentry $name --class=debug_kbd {" >> $cfgfile + echo " set_keyboard_layout $name" >> $cfgfile + echo " }" >> $cfgfile +done + +echo "}" >>$cfgfile + + + diff --git a/LANGUAGES/README b/LANGUAGES/README new file mode 100644 index 0000000..7a5b4f2 --- /dev/null +++ b/LANGUAGES/README @@ -0,0 +1,17 @@ + +File encoding: UTF-8 + +language name must in the format: "Language-XXX (YYY)" + 1. Language- fixed 9 characters + 2. XXX: name in English + 3. a space (ASCII: 0x20) + 4. a left brace (ASCII: 0x28) + 5. YYY: name in the specified language + 6. a right brace (ASCII: 0x29) + +string translation: + all the String Define + #@ will be replaced with \r\n + +All the languages will be sorted by the name + diff --git a/LANGUAGES/check.sh b/LANGUAGES/check.sh new file mode 100644 index 0000000..9d6a3e1 --- /dev/null +++ b/LANGUAGES/check.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +VTOY_PATH=$1 + +if [ ! -f $VTOY_PATH/LANGUAGES/languages.json ]; then + exit 1 +fi + +gcc -DFOR_VTOY_JSON_CHECK $VTOY_PATH/Ventoy2Disk/Ventoy2Disk/VentoyJson.c -I $VTOY_PATH/Ventoy2Disk/Ventoy2Disk/ -o checkjson + +RET=0 + +./checkjson $VTOY_PATH/LANGUAGES/languages.json +ret=$? +if [ $ret -eq 0 ]; then + for i in $(ls $VTOY_PATH/INSTALL/grub/menu); do + echo "check INSTALL/grub/menu/$i ..." + ./checkjson $VTOY_PATH/INSTALL/grub/menu/$i + ret=$? + if [ $ret -ne 0 ]; then + echo "INSTALL/grub/menu/$i invalid json format" + break + fi + done +else + echo "languages.json invalid json format" +fi + +rm -f ./checkjson +[ $ret -eq 0 ] + diff --git a/LANGUAGES/languages.json b/LANGUAGES/languages.json new file mode 100644 index 0000000..5d90605 --- /dev/null +++ b/LANGUAGES/languages.json @@ -0,0 +1,3448 @@ +[ + { + "name":"Arabic (العربية)", + "FontFamily":"Courier New", + "FontSize":20, + "Author":"Omar Namis Mostafa", + + "STR_ERROR":"خطأ", + "STR_WARNING":"تحذير", + "STR_INFO":"معلومات", + "STR_INCORRECT_DIR":"يرجى التشغيل من المسار الصحيح!", + "STR_INCORRECT_TREE_DIR":"لا تقم بالتشغيل من هنا، يرجى تحميل حزمة التثبيت، وتشغيلها من هناك.", + "STR_DEVICE":"الجهاز", + "STR_LOCAL_VER":"في الحزمة Ventoy", + "STR_DISK_VER":"في الجهاز Ventoy", + "STR_STATUS":"الحالة - جاهز", + "STR_INSTALL":"تثبيت", + "STR_UPDATE":"تحديث", + "STR_UPDATE_TIP":"عملية التحديث آمنة, لن يتم عمل تغييرات على ملفات الـISO.#@المتابعة؟", + "STR_INSTALL_TIP":"سوف يتم تهيئة القرص وسيتم حذف جميع البيانات.#@المتابعة؟", + "STR_INSTALL_TIP2":"سوف يتم تهيئة القرص وسيتم حذف جميع البيانات.#@المتابعة؟ (التحقق مرة أخرى)", + "STR_INSTALL_SUCCESS":"مبروك!#@تم تثبيت Ventoy بنجاح على الجهاز.", + "STR_INSTALL_FAILED":"حدث خطأ أثناء التثبيت. يمكنك إعادة توصيل الـUSB والمحاولة مرة أخرى. تفقّد log.txt للتفاصيل.", + "STR_UPDATE_SUCCESS":"مبروك!#@تم تحديث Ventoy بنجاح على الجهاز.", + "STR_UPDATE_FAILED":"حدث خطأ أثناء التحديث. يمكنك إعادة توصيل الـUSB والمحاولة مرة أخرى. تفقّد log.txt للتفاصيل.", + "STR_WAIT_PROCESS":"هناك عملية نشطة، يرجى الانتظار...", + "STR_MENU_OPTION":"خيارات", + "STR_MENU_SECURE_BOOT":"تمهيد آمن", + "STR_MENU_PART_CFG":"تكوين التقسيم", + "STR_BTN_OK":"موافق", + "STR_BTN_CANCEL":"إلغاء", + "STR_PRESERVE_SPACE":"الحفاظ على بعض المساحة في الجزء السفلي من القرص", + "STR_SPACE_VAL_INVALID":"قيمة غير صالحة للمساحة المحجوزة", + "STR_MENU_CLEAR":"إزالة Ventoy", + "STR_CLEAR_SUCCESS":"تمت إزالة Ventoy من الجهاز بنجاح.", + "STR_CLEAR_FAILED":"حدث خطأ عند إزالة Ventoy من القرص. يمكنك إعادة توصيل الـUSB والمحاولة مرة أخرى. تفقد log.txt للتفاصيل.", + "STR_MENU_PART_STYLE":"أسلوب التقسيم", + "STR_DISK_2TB_MBR_ERROR":"يرجى اختيار GPT للأقراص الأكبر من 2 تيرابايت", + "STR_SHOW_ALL_DEV":"عرض كافة الأجهزة", + "STR_PART_ALIGN_4KB":"محاذاة الأقسام مع 4KB", + "STR_WEB_COMMUNICATION_ERR":"خطأ في الاتصال:", + "STR_WEB_REMOTE_ABNORMAL":"خطأ في الاتصال: بعيد غير طبيعي", + "STR_WEB_REQUEST_TIMEOUT":"خطأ في الاتصال: انتهت مهلة الطلب", + "STR_WEB_SERVICE_UNAVAILABLE":"خطأ في الاتصال: الخدمة غير متوفرة", + "STR_WEB_TOKEN_MISMATCH":"تم تحديث حالة البرنامج الخفي ، يرجى إعادة المحاولة لاحقًا.", + "STR_WEB_SERVICE_BUSY":"الخدمة مشغولة ، يرجى إعادة المحاولة لاحقًا.", + "STR_MENU_VTSI_CREATE":"إنشاء ملف VTSI", + "STR_VTSI_CREATE_TIP":"هذه المرة لن يتم الكتابة على الجهاز، ولكن سيتم إنشاء ملف VTSI#@المتابعة؟", + "STR_VTSI_CREATE_SUCCESS":"تم إنشاء ملف VTSI بنجاح!#@يمكنك استخدام Rufus(3.15+) للكتابة على الجهاز لاستكمال تثبيت Ventoy.", + "STR_VTSI_CREATE_FAILED":"فشل إنشاء ملف VTSI.", + "STR_MENU_PART_RESIZE":"تثبيت بدون تهيئة", + "STR_PART_RESIZE_TIP":"سيحاول Ventoy أن يقوم بالتثبيت بدون عمل تهيئة إن أمكن. #@المتابعة؟", + "STR_PART_RESIZE_SUCCESS":"تهانينا!#@اكتملت عملية تثبيت Ventoy بدون تهيئة بنجاح.", + "STR_PART_RESIZE_FAILED":"فشلت عملية التثبيت بدون تهيئة، تفقد ملف log.txt للتفاصيل.", + "STR_PART_RESIZE_UNSUPPORTED":"توقفت عملية تثبيت Ventoy بدون تهيئة لعدم استيفاء بعض الشروط. تفقد ملف log.txt للتفاصيل.", + "STR_INSTALL_YES_TIP1":"تحذير: سيتم فقدان البيانات!", + "STR_INSTALL_YES_TIP2":"يرجى إدخال YES في مربع النص في الأسفل للتأكيد بأنك تريد عمل تثبيت جديد بدلاً من التحديث.", + "STR_PART_VENTOY_FS":"نظام الملفات لقسم Ventoy", + "STR_PART_FS":"نظام الملفات", + "STR_PART_CLUSTER":"حجم الكتلة", + "STR_PART_CLUSTER_DEFAULT":"القيمة الافتراضية للنظام", + "STR_DONATE":"يتبرع", + "STR_4KN_UNSUPPORTED":"Currently Ventoy does not support 4K native devices.", + + "STRXXX":"" + }, + { + "name": "Urdu (اردو)", + "FontFamily": "Noto Nastaliq Urdu", + "FontSize": 16, + "Author": "Muhammad Ramzan", + + "STR_ERROR": "غلطی", + "STR_WARNING": "انتباہ", + "STR_INFO": "معلومات", + "STR_INCORRECT_DIR": "براہ کرم درست ڈائریکٹری میں چلائیں!", + "STR_INCORRECT_TREE_DIR": "یہاں نہ چلائیں، براہ کرم ریلیز پیکیج ڈاؤن لوڈ کریں اور وہاں چلائیں۔", + "STR_DEVICE": "ڈیوائس", + "STR_LOCAL_VER": "پیکج میں وینٹوی", + "STR_DISK_VER": "ڈیوائس میں وینٹوی", + "STR_STATUS": "اسٹیٹس - تیار", + "STR_INSTALL": "انسٹال کریں", + "STR_UPDATE": "اپڈیٹ کریں", + "STR_UPDATE_TIP": "اپگریڈ محفوظ ہے، ISO فائلز تبدیل نہیں ہوں گی۔#@کیا آپ جاری رکھنا چاہتے ہیں؟", + "STR_INSTALL_TIP": "ڈیوائس فارمیٹ ہو جائے گا اور تمام ڈیٹا ضائع ہو جائے گا۔#@کیا آپ جاری رکھنا چاہتے ہیں؟", + "STR_INSTALL_TIP2": "ڈیوائس فارمیٹ ہو جائے گا اور تمام ڈیٹا ضائع ہو جائے گا۔#@کیا آپ واقعی جاری رکھنا چاہتے ہیں؟ (دوبارہ تصدیق)", + "STR_INSTALL_SUCCESS": "مبارک ہو!#@وینٹوی کامیابی سے ڈیوائس پر انسٹال ہو گیا ہے۔", + "STR_INSTALL_FAILED": "انسٹالیشن کے دوران غلطی پیش آئی۔ دوبارہ USB لگائیں اور کوشش کریں۔ تفصیلات کے لیے log.txt چیک کریں۔ اگر مسئلہ برقرار رہے تو سرکاری ویب سائٹ کے FAQ دیکھیں۔", + "STR_UPDATE_SUCCESS": "مبارک ہو!#@وینٹوی کامیابی سے ڈیوائس پر اپڈیٹ ہو گیا ہے۔", + "STR_UPDATE_FAILED": "اپڈیٹ کے دوران غلطی پیش آئی۔ دوبارہ USB لگائیں اور کوشش کریں۔ تفصیلات کے لیے log.txt چیک کریں۔ اگر مسئلہ برقرار رہے تو سرکاری ویب سائٹ کے FAQ دیکھیں۔", + "STR_WAIT_PROCESS": "ایک عمل جاری ہے، براہ کرم انتظار کریں...", + "STR_MENU_OPTION": "اختیار", + "STR_MENU_SECURE_BOOT": "سکیور بوٹ سپورٹ", + "STR_MENU_PART_CFG": "پارٹیشن کنفیگریشن", + "STR_BTN_OK": "ٹھیک ہے", + "STR_BTN_CANCEL": "منسوخ کریں", + "STR_PRESERVE_SPACE": "ڈسک کے آخر میں کچھ جگہ محفوظ کریں", + "STR_SPACE_VAL_INVALID": "محفوظ جگہ کے لیے غلط ویلیو", + "STR_MENU_CLEAR": "وینٹوی ہٹائیں", + "STR_CLEAR_SUCCESS": "وینٹوی کامیابی سے ڈیوائس سے ہٹا دیا گیا ہے۔", + "STR_CLEAR_FAILED": "وینٹوی کو ہٹاتے وقت غلطی پیش آئی۔ دوبارہ USB لگائیں اور کوشش کریں۔ تفصیلات کے لیے log.txt چیک کریں۔", + "STR_MENU_PART_STYLE": "پارٹیشن اسٹائل", + "STR_DISK_2TB_MBR_ERROR": "2TB سے بڑی ڈیوائس کے لیے GPT منتخب کریں", + "STR_SHOW_ALL_DEV": "تمام ڈیوائسز دکھائیں", + "STR_PART_ALIGN_4KB": "پارٹیشنز کو 4KB کے ساتھ سیدھ میں رکھیں", + "STR_WEB_COMMUNICATION_ERR": "کمیونیکیشن ایرر:", + "STR_WEB_REMOTE_ABNORMAL": "کمیونیکیشن ایرر: ریموٹ ایرر", + "STR_WEB_REQUEST_TIMEOUT": "کمیونیکیشن ایرر: ریکویسٹ کا وقت ختم ہو گیا", + "STR_WEB_SERVICE_UNAVAILABLE": "کمیونیکیشن ایرر: سروس دستیاب نہیں", + "STR_WEB_TOKEN_MISMATCH": "ڈیمن اسٹیٹس اپڈیٹ ہو گیا، بعد میں دوبارہ کوشش کریں۔", + "STR_WEB_SERVICE_BUSY": "سروس مصروف ہے، بعد میں دوبارہ کوشش کریں۔", + "STR_MENU_VTSI_CREATE": "VTSI فائل بنائیں", + "STR_VTSI_CREATE_TIP": "یہ عمل ڈیوائس پر کچھ نہیں لکھے گا، صرف VTSI فائل بنائے گا۔#@کیا آپ جاری رکھنا چاہتے ہیں؟", + "STR_VTSI_CREATE_SUCCESS": "VTSI فائل کامیابی سے بن گئی!#@آپ Rufus(3.15+) کا استعمال کر کے اسے ڈیوائس پر لکھ سکتے ہیں تاکہ وینٹوی انسٹال مکمل ہو سکے۔", + "STR_VTSI_CREATE_FAILED": "VTSI فائل بنانے میں ناکام۔", + "STR_MENU_PART_RESIZE": "ڈیٹا محفوظ انسٹالیشن", + "STR_PART_RESIZE_TIP": "وینٹوی ممکن ہو تو ڈیٹا محفوظ انسٹالیشن کرے گا۔#@کیا آپ جاری رکھنا چاہتے ہیں؟", + "STR_PART_RESIZE_SUCCESS": "مبارک ہو!#@وینٹوی کی ڈیٹا محفوظ انسٹالیشن کامیابی سے مکمل ہو گئی۔", + "STR_PART_RESIZE_FAILED": "ڈیٹا محفوظ انسٹالیشن ناکام ہو گئی، تفصیلات کے لیے log.txt چیک کریں۔", + "STR_PART_RESIZE_UNSUPPORTED": "وینٹوی نے انسٹالیشن روک دی کیونکہ کچھ شرائط پوری نہیں ہو سکیں۔ تفصیلات کے لیے log.txt چیک کریں۔", + "STR_INSTALL_YES_TIP1": "انتباہ: ڈیٹا ضائع ہو جائے گا!", + "STR_INSTALL_YES_TIP2": "براہ کرم نیچے ٹیکسٹ باکس میں YES لکھیں تاکہ تصدیق ہو سکے کہ آپ اپگریڈ کی بجائے نیا انسٹال کرنا چاہتے ہیں۔", + "STR_PART_VENTOY_FS": "وینٹوی پارٹیشن کے لیے فائل سسٹم", + "STR_PART_FS": "فائل سسٹم", + "STR_PART_CLUSTER": "کلسٹر سائز", + "STR_PART_CLUSTER_DEFAULT": "سسٹم کا ڈیفالٹ ویلیو", + "STR_DONATE": "عطیہ کریں", + "STR_4KN_UNSUPPORTED": "فی الحال وینٹوی 4K نیٹو ڈیوائسز کو سپورٹ نہیں کرتا۔", + + "STRXXX": "" + }, + { + "name":"Azerbaijani (Azərbaycanca)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Xəyyam Qocayev", + + "STR_ERROR":"Xəta", + "STR_WARNING":"Xəbərdarlıq", + "STR_INFO":"Məlumat", + "STR_INCORRECT_DIR":"Lütfən, başqa kataloqda başladın!", + "STR_INCORRECT_TREE_DIR":"Lütfən məni burada başlatmayın, buraxılmış quraşdırıcı paketini endirin və başqa yerdə işə salın.", + "STR_DEVICE":"Cihaz", + "STR_LOCAL_VER":"Ventoy paketdə", + "STR_DISK_VER":"Ventoy cihazda", + "STR_STATUS":"Vəziyyəti - hazır", + "STR_INSTALL":"Quraşdırın", + "STR_UPDATE":"Yeniləyin", + "STR_UPDATE_TIP":"Yeniləmək təhlükəsizdir, ISO faylı dəyişməz qalır, #@Davam edək?", + "STR_INSTALL_TIP":"Disk formatlanacaq və ondakı bütün məlumatlkar itiriləcəkdir.#@Davam edək?", + "STR_INSTALL_TIP2":"Disk formatlanacaq və ondakı bütün məlumatlkar itiriləcəkdir.#@Həqiqətən davam etmək istəyirsiniz?", + "STR_INSTALL_SUCCESS":"Təbriklər!#@Ventoy, uğurla cihazınıza quraşdırıldı.", + "STR_INSTALL_FAILED":"Ventoyun quraşdırılması zamanı xəta baş verdi. Cihazı təkrar qoşun və yenidən cəhd edin. Daha çox məlumat almaq üçün log.txt jurnal faylına baxın.", + "STR_UPDATE_SUCCESS":"Təbriklər!#@Ventoy, uğurla cihazınıza quraşdırıldı.", + "STR_UPDATE_FAILED":"Ventoy yenilənən zaman xəta ba. verdi. Cihazı yenidən qoşun və yenidən cəhd edin. Daha ətraflı məlumat üçün log.txt jurnal faylına baxın.", + "STR_WAIT_PROCESS":"Proses başladıldı, lütfən gözləyin...", + "STR_MENU_OPTION":"Seçimlər", + "STR_MENU_SECURE_BOOT":"Secure Boot dəstəyi", + "STR_MENU_PART_CFG":"Əlavə bölmə", + "STR_BTN_OK":"ОLDU", + "STR_BTN_CANCEL":"Ləğv edin", + "STR_PRESERVE_SPACE":"Diskin sonunda əlavə bölmə yaradın", + "STR_SPACE_VAL_INVALID":"Bölmənin ölçüsündə səhv var", + "STR_MENU_CLEAR":"Ventoy'u silin", + "STR_CLEAR_SUCCESS":"Ventoy, cihazdan uğurla silindi.", + "STR_CLEAR_FAILED":"Ventoyun silinməsi zamanı xəta baş verdi. Cihazı yenidən qoşun və təkrar cəhd edin. Daha ətraflı məlumat üçün log.txt jurnal faylına baxın.", + "STR_MENU_PART_STYLE":"Diskin bölünməsi qaydası", + "STR_DISK_2TB_MBR_ERROR":"2TB-dan artıq disklər üçün GPT seçin", + "STR_SHOW_ALL_DEV":"Bütün cihazları göstərmək", + "STR_PART_ALIGN_4KB":"4KB ölçüsündəki bölməni düzləndirmək", + "STR_WEB_COMMUNICATION_ERR":"Bağlantı xətası:", + "STR_WEB_REMOTE_ABNORMAL":"Bağlantı xətası: Uzaq bağlantı aktiv deyil", + "STR_WEB_REQUEST_TIMEOUT":"Bağlantı xətası: Gözləmə vaxtı başa çatdı", + "STR_WEB_SERVICE_UNAVAILABLE":"Bağlantı xətası: Xidmət əlçatmazdır", + "STR_WEB_TOKEN_MISMATCH":"Domen vəziyyəti yeniləndi. Sonra yenidən cəhd edin.", + "STR_WEB_SERVICE_BUSY":"Xidmət mə.ğuldur, sonra cəhd edin.", + "STR_MENU_VTSI_CREATE":"VTSI faylı yaradın", + "STR_VTSI_CREATE_TIP":"Bu dəfə Ventoy, cihaza quraşdırılmayacaq, yalnız VTSI faylı yaradılacaq #@Davam edək?", + "STR_VTSI_CREATE_SUCCESS":"VTSI faylı uğurla yaradıldı!#@Ventoy'u quraşdırmağı tamamlamaq üçün həmin faylı diskə Rufus(3.15+) istifadə edərək yaza bilərsiniz.", + "STR_VTSI_CREATE_FAILED":"VTSI faylının yaradlmasında xəta.", + "STR_MENU_PART_RESIZE":"Zərər verməyən quraşdırma", + "STR_PART_RESIZE_TIP":"Ventoy mümkün olduqca zərər vermədən quraşdırmağa cəhd edir. #@Davam edək?", + "STR_PART_RESIZE_SUCCESS":"Təbriklər!#@Zərərsiz Ventoy quraşdırması başa çatdı.", + "STR_PART_RESIZE_FAILED":"Zərərsiz quraşdırma baş tutmadı, daha ətraflı öyrənmək üçün log.txt jurnal faylına baxın.", + "STR_PART_RESIZE_UNSUPPORTED":"ZƏrərsiz Ventoy quraşdırması dayandırıldı, belə ki, bəzi şərtlər yerinə yetirilə bilməd. Daha ətraflı məlumat üçün.txt jurnal faylına baxın.", + "STR_INSTALL_YES_TIP1":"Warning: Data will be lost!", + "STR_INSTALL_YES_TIP2":"Please enter YES in the text box below to confirm that you indeed want to do a fresh install instead of upgrade.", + "STR_PART_VENTOY_FS":"File System For Ventoy Partition", + "STR_PART_FS":"File System", + "STR_PART_CLUSTER":"Cluster Size", + "STR_PART_CLUSTER_DEFAULT":"System Default Value", + "STR_DONATE":"Ianə", + "STR_4KN_UNSUPPORTED":"Currently Ventoy does not support 4K native devices.", + + "STRXXX":"" + }, + { + "name":"Korean (한국어)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"VenusGirl, HYB1022", + + "STR_ERROR":"오류", + "STR_WARNING":"경고", + "STR_INFO":"정보", + "STR_INCORRECT_DIR":"올바른 파일 경로에서 실행하십시오!", + "STR_INCORRECT_TREE_DIR":"여기(INSTALL 경로)서 프로그램을 실행하지 말고 설치 패키지를 다운로드하여 압축을 푼 후 그곳에서 실행해 주십시오.", + "STR_DEVICE":"장치", + "STR_LOCAL_VER":"패키지의 Ventoy 버전", + "STR_DISK_VER":"장치 내부의 Ventoy 버전", + "STR_STATUS":"상태 - 준비 완료", + "STR_INSTALL":"설치", + "STR_UPDATE":"업데이트", + "STR_UPDATE_TIP":"업그레이드 작업은 안전하며 ISO 파일이 변경되지 않습니다.#@계속하시겠습니까?", + "STR_INSTALL_TIP":"디스크가 포맷되고 모든 데이터가 손실됩니다.#@계속하시겠습니까?", + "STR_INSTALL_TIP2":"디스크가 포맷되고 모든 데이터가 손실됩니다.#@계속하시겠습니까? (다시 확인)", + "STR_INSTALL_SUCCESS":"축하합니다!#@Ventoy가 장치에 성공적으로 설치되었습니다.", + "STR_INSTALL_FAILED":"설치 중 오류가 발생했습니다. USB를 다시 삽입하고 다시 시도할 수 있습니다. 자세한 내용은 log.txt를 확인하십시오.", + "STR_UPDATE_SUCCESS":"축하합니다! 장치에 설치된#@Ventoy가 성공적으로 업데이트되었습니다.", + "STR_UPDATE_FAILED":"업데이트 중에 오류가 발생했습니다. USB를 다시 삽입하고 다시 시도할 수 있습니다. 자세한 내용은 log.txt를 확인하십시오.", + "STR_WAIT_PROCESS":"현재 작업이 실행 중입니다. 기다려 주십시오...", + "STR_MENU_OPTION":"설정", + "STR_MENU_SECURE_BOOT":"보안 부트 (Secure Boot) 지원", + "STR_MENU_PART_CFG":"파티션 구성", + "STR_BTN_OK":"확인", + "STR_BTN_CANCEL":"취소", + "STR_PRESERVE_SPACE":"디스크의 끝에 예약된 공간 확보", + "STR_SPACE_VAL_INVALID":"예약된 공간의 값이 잘못되었습니다", + "STR_MENU_CLEAR":"Ventoy 제거", + "STR_CLEAR_SUCCESS":"Ventoy가 장치에서 성공적으로 제거되었습니다.", + "STR_CLEAR_FAILED":"디스크에서 Ventoy를 지울 때 오류가 발생했습니다. USB를 다시 삽입하고 다시 시도할 수 있습니다. 자세한 내용은 log.txt를 확인하십시오.", + "STR_MENU_PART_STYLE":"파티션 유형", + "STR_DISK_2TB_MBR_ERROR":"2TB 이상의 디스크는 GPT를 선택하십시오", + "STR_SHOW_ALL_DEV":"모든 장치 표시", + "STR_PART_ALIGN_4KB":"파티션을 4KB로 정렬", + "STR_WEB_COMMUNICATION_ERR":"통신 오류:", + "STR_WEB_REMOTE_ABNORMAL":"통신 오류: 원격 이상", + "STR_WEB_REQUEST_TIMEOUT":"통신 오류: 요청이 시간 초과됨", + "STR_WEB_SERVICE_UNAVAILABLE":"통신 오류: 서비스를 사용할 수 없음", + "STR_WEB_TOKEN_MISMATCH":"백그라운드 서비스 상태가 업데이트되었습니다. 나중에 다시 시도하십시오.", + "STR_WEB_SERVICE_BUSY":"서비스가 사용 중입니다. 나중에 다시 시도하십시오.", + "STR_MENU_VTSI_CREATE":"VTSI 파일 생성", + "STR_VTSI_CREATE_TIP":"이 작업은 장치에 데이터를 쓰지 않고 VTSI 파일#@만 생성합니다.#@계속하시겠습니까?", + "STR_VTSI_CREATE_SUCCESS":"VTSI 파일이 성공적으로 생성되었습니다!#@Rufus (3.15 이상)를 사용하여 장치에 기록하여 Ventoy 설치를 완료할 수 있습니다.", + "STR_VTSI_CREATE_FAILED":"VTSI 파일을 생성하지 못했습니다.", + "STR_MENU_PART_RESIZE":"무손실 설치", + "STR_PART_RESIZE_TIP":"가능하면 Ventoy가 무손실 설치를 시도합니다. #@계속하시겠습니까?", + "STR_PART_RESIZE_SUCCESS":"축하합니다!#@Ventoy 무손실 설치가 완료되었습니다.", + "STR_PART_RESIZE_FAILED":"무손실 설치에 실패했습니다. 자세한 내용은 log.txt를 확인하십시오.", + "STR_PART_RESIZE_UNSUPPORTED":"일부 조건을 충족할 수 없기 때문에 Ventoy 무손실 설치가 중지되었습니다. 자세한 내용은 log.txt를 확인하십시오.", + "STR_INSTALL_YES_TIP1":"경고: 데이터가 손실됩니다!", + "STR_INSTALL_YES_TIP2":"업그레이드 대신 새로 설치할지 확인하려면 아래 입력란에 YES를 입력하십시오.", + "STR_PART_VENTOY_FS":"Ventoy 파티션용 파일 시스템", + "STR_PART_FS":"파일 시스템", + "STR_PART_CLUSTER":"클러스터 크기", + "STR_PART_CLUSTER_DEFAULT":"시스템 기본값", + "STR_DONATE":"기부", + "STR_4KN_UNSUPPORTED":"현재 Ventoy는 네이티브 4K 섹터의 디스크를 지원하지 않습니다.", + + "STRXXX":"" + }, + { + "name":"Chinese Simplified (简体中文)", + "FontFamily":"宋体", + "FontSize":14, + "Author":"longpanda", + + "STR_ERROR":"错误", + "STR_WARNING":"警告", + "STR_INFO":"提醒", + "STR_INCORRECT_DIR":"请在正确的目录下运行!", + "STR_INCORRECT_TREE_DIR":"请不要在代码树下运行此程序(INSTALL目录),请下载安装包,解压后在那里运行。", + "STR_DEVICE":"设备", + "STR_LOCAL_VER":"安装包内 Ventoy 版本", + "STR_DISK_VER":"设备内部 Ventoy 版本", + "STR_STATUS":"状态 - 准备就绪", + "STR_INSTALL":"安装", + "STR_UPDATE":"升级", + "STR_UPDATE_TIP":"升级操作是安全的, ISO文件不会丢失#@是否继续?", + "STR_INSTALL_TIP":"磁盘会被格式化, 所有数据都会丢失!#@是否继续?", + "STR_INSTALL_TIP2":"磁盘会被格式化, 所有数据都会丢失!#@再次确认是否继续?", + "STR_INSTALL_SUCCESS":"恭喜你! Ventoy 已经成功安装到此设备中.", + "STR_INSTALL_FAILED":"安装 Ventoy 过程中发生错误. 你可以重新拔插一下U盘然后重试一次, 详细信息请查阅 log.txt 文件. 如果一直出错,请参考官网常见问题说明.", + "STR_UPDATE_SUCCESS":"恭喜你! 新版本的 Ventoy 已经成功更新到此设备中.", + "STR_UPDATE_FAILED":"更新 Ventoy 过程中遇到错误. 你可以重新拔插一下U盘然后重试一次, 详细信息请查阅 log.txt 文件. 如果一直出错,请参考官网常见问题说明.", + "STR_WAIT_PROCESS":"当前有任务正在运行, 请等待...", + "STR_MENU_OPTION":"配置选项", + "STR_MENU_SECURE_BOOT":"安全启动支持", + "STR_MENU_PART_CFG":"分区设置", + "STR_BTN_OK":"确定", + "STR_BTN_CANCEL":"取消", + "STR_PRESERVE_SPACE":"在磁盘最后保留一段空间", + "STR_SPACE_VAL_INVALID":"保留空间的数值非法", + "STR_MENU_CLEAR":"清除 Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy已经成功从此设备中清除.", + "STR_CLEAR_FAILED":"清除 Ventoy 过程中遇到错误. 你可以重新拔插一下U盘然后重试一次, 详细信息请查阅 log.txt 文件.", + "STR_MENU_PART_STYLE":"分区类型", + "STR_DISK_2TB_MBR_ERROR":"磁盘容量超过2TB,请选择GPT分区格式", + "STR_SHOW_ALL_DEV":"显示所有设备", + "STR_PART_ALIGN_4KB":"分区按照 4KB 对齐", + "STR_WEB_COMMUNICATION_ERR":"通信失败:", + "STR_WEB_REMOTE_ABNORMAL":"通信失败:服务端异常", + "STR_WEB_REQUEST_TIMEOUT":"通信失败:请求超时", + "STR_WEB_SERVICE_UNAVAILABLE":"通信失败:服务不可用", + "STR_WEB_TOKEN_MISMATCH":"后台服务状态更新,请稍后重试", + "STR_WEB_SERVICE_BUSY":"后台服务正忙,请稍后重试", + "STR_MENU_VTSI_CREATE":"创建 VTSI 文件", + "STR_VTSI_CREATE_TIP":"本操作不会向设备中写入数据,而只会生成一个 VTSI 文件#@是否继续?", + "STR_VTSI_CREATE_SUCCESS":"VTSI 文件创建成功,你可以使用Rufus(3.15+)将其写入对应设备,从而完成Ventoy的安装", + "STR_VTSI_CREATE_FAILED":"VTSI 文件创建失败", + "STR_MENU_PART_RESIZE":"无损安装", + "STR_PART_RESIZE_TIP":"Ventoy将尝试进行无损安装。注意:任何磁盘操作都有一定的风险,对于重要数据建议做好备份。#@是否继续?", + "STR_PART_RESIZE_SUCCESS":"恭喜你! Ventoy 成功完成了无损安装。", + "STR_PART_RESIZE_FAILED":"Ventoy 无损安装失败。详细信息请查阅 log.txt 文件。", + "STR_PART_RESIZE_UNSUPPORTED":"条件不满足,无法进行无损安装。详细信息请查阅 log.txt 文件。", + "STR_INSTALL_YES_TIP1":"警告: 所有数据将会丢失!", + "STR_INSTALL_YES_TIP2":"请在下面文本框中输入 YES 以确认你是要进行安装而不是升级。", + "STR_PART_VENTOY_FS":"Ventoy 分区文件系统类型", + "STR_PART_FS":"文件系统", + "STR_PART_CLUSTER":"簇大小", + "STR_PART_CLUSTER_DEFAULT":"系统默认值", + "STR_DONATE":"捐助", + "STR_4KN_UNSUPPORTED":"目前 Ventoy 不支持原生 4K 扇区的磁盘。", + + "STRXXX":"" + }, + { + "name":"Danish (Dansk)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"fhdk", + + "STR_ERROR":"Fejl", + "STR_WARNING":"Advarsel", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Skal udføres i den rette mappe!", + "STR_INCORRECT_TREE_DIR":"Udfør ikke her, download pakke udgivelsen og udfør i den mappe.", + "STR_DEVICE":"Enhed", + "STR_LOCAL_VER":"Pakke Version", + "STR_DISK_VER":"Enhed Version", + "STR_STATUS":"Status - KLAR", + "STR_INSTALL":"Installer", + "STR_UPDATE":"Opdater", + "STR_UPDATE_TIP":"Updatering er sikker, Data indhold bevares uændret.#@Fortsæt?", + "STR_INSTALL_TIP":"Alle data på enheden slettes og kan ikke gendannes.#@Fortsæt?", + "STR_INSTALL_TIP2":"BEKRÆFT! Alle data på enheden slettes og kan ikke gendannes.#@Fortsæt?", + "STR_INSTALL_SUCCESS":"SÅDAN!#@Ventoy er nu overført til enheden.", + "STR_INSTALL_FAILED":"Der opstod en fejl under overførslen. Fjern og indsæt enheden på ny for at prøve igen. Læs log.txt for detaljer. Hvis det gantager sig, Se FAQ på den officielle web.", + "STR_UPDATE_SUCCESS":"SÅDAN!#@Ventoy er nu opdaterert på enheden", + "STR_UPDATE_FAILED":"Der opstod en fejl opdateringen. Fjern og indsæt enheden på ny for at prøve igen. Læs log.txt for detaljer. Hvis det gantager sig, Se FAQ på den officielle web.", + "STR_WAIT_PROCESS":"Programmet er optaget, vent venligst...", + "STR_MENU_OPTION":"Valg", + "STR_MENU_SECURE_BOOT":"Secure Boot Support", + "STR_MENU_PART_CFG":"Partition Opsætning", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Afbryd", + "STR_PRESERVE_SPACE":"Efterlad reserveret plads på enheden", + "STR_SPACE_VAL_INVALID":"Ugyldig værdi for reserveret plads", + "STR_MENU_CLEAR":"Fjern Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy er nu fjernet fra enheden.", + "STR_CLEAR_FAILED":"Der opstod en fejl under fjernelse fra enheden. Fjern og indsæt enheden på ny for at prøve igen. Læs log.txt for detaljer.", + "STR_MENU_PART_STYLE":"Partition Type", + "STR_DISK_2TB_MBR_ERROR":"Vælg GPT for enheder over 2TB", + "STR_SHOW_ALL_DEV":"Vis Alle Enheder", + "STR_PART_ALIGN_4KB":"Juster partitioner til 4KB blokke.", + "STR_WEB_COMMUNICATION_ERR":"Kommunikationsfejl:", + "STR_WEB_REMOTE_ABNORMAL":"Kommunikationsfejl: Uventet server", + "STR_WEB_REQUEST_TIMEOUT":"Kommunikationsfejl: Server svarer ikke", + "STR_WEB_SERVICE_UNAVAILABLE":"Kommunikationsfejl: Server ikke tilgængelig", + "STR_WEB_TOKEN_MISMATCH":"Baggrundsstatus er opdateret. Prøv igen seenere.", + "STR_WEB_SERVICE_BUSY":"Webservice er optaget, prøv igen senere.", + "STR_MENU_VTSI_CREATE":"Opret VTSI File", + "STR_VTSI_CREATE_TIP":"Der skrives ikke til enheden, der bliver blot dannet en VTSI fil#@Fortsæt?", + "STR_VTSI_CREATE_SUCCESS":"VTSI fil oprettet!#@Du kan nu skrive til enheden ved at bruge Rufus(3.15+) og dermed færddiggøre enheds opsætningen.", + "STR_VTSI_CREATE_FAILED":"Oprettelse af VTSI mislykkedes.", + "STR_MENU_PART_RESIZE":"Ikke-Destruktiv overførsel", + "STR_PART_RESIZE_TIP":"Ventoy vil forsøge en ikke-destruktion overførsel om muligt. #@Fortsæt?", + "STR_PART_RESIZE_SUCCESS":"SÅDAN!#@ Den ikke-destruktive overførsel var perfekt.", + "STR_PART_RESIZE_FAILED":"Ikke-Destruktiv overførsel fejlede, Læs log.txt for detaljer.", + "STR_PART_RESIZE_UNSUPPORTED":"Ikke-Destruktiv overførsel er afbrudt. Betingelser er ikke opfyldt. Læs log.txt for detaljer.", + "STR_INSTALL_YES_TIP1":"Advarsel: Data vil gå tabt!", + "STR_INSTALL_YES_TIP2":"Indtast ordet YES for at bekræfte en ny overførsel istedet for en opdatring.", + "STR_PART_VENTOY_FS":"Fil System For Ventoy Partition", + "STR_PART_FS":"Fil System", + "STR_PART_CLUSTER":"Klynge størrelse", + "STR_PART_CLUSTER_DEFAULT":"System Standard Værdi", + "STR_DONATE":"Donering", + "STR_4KN_UNSUPPORTED":"Currently Ventoy does not support 4K native devices.", + + "STRXXX":"" + }, + { + "name":"English (English)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"longpanda", + + "STR_ERROR":"Error", + "STR_WARNING":"Warning", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Please run under the correct directory!", + "STR_INCORRECT_TREE_DIR":"Don't run me here, please download the released install package, and run there.", + "STR_DEVICE":"Device", + "STR_LOCAL_VER":"Ventoy In Package", + "STR_DISK_VER":"Ventoy In Device", + "STR_STATUS":"Status - READY", + "STR_INSTALL":"Install", + "STR_UPDATE":"Update", + "STR_UPDATE_TIP":"Upgrade operation is safe, ISO files will be unchanged.#@Continue?", + "STR_INSTALL_TIP":"The device will be formatted and all the data will be lost.#@Continue?", + "STR_INSTALL_TIP2":"The device will be formatted and all the data will be lost.#@Continue? (Double Check)", + "STR_INSTALL_SUCCESS":"Congratulations!#@Ventoy has been successfully installed to the device.", + "STR_INSTALL_FAILED":"An error occurred during the installation. You can reinsert the USB device and try again. Check log.txt for details. If it always fails, please refer the FAQ on the official website.", + "STR_UPDATE_SUCCESS":"Congratulations!#@Ventoy has been successfully updated on the device.", + "STR_UPDATE_FAILED":"An error occurred during the update. You can reinsert the USB device and try again. Check log.txt for details. If it always fails, please refer the FAQ on the official website.", + "STR_WAIT_PROCESS":"A thread is running, please wait...", + "STR_MENU_OPTION":"Option", + "STR_MENU_SECURE_BOOT":"Secure Boot Support", + "STR_MENU_PART_CFG":"Partition Configuration", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Cancel", + "STR_PRESERVE_SPACE":"Preserve some space at the end of the disk", + "STR_SPACE_VAL_INVALID":"Invalid value for reserved space", + "STR_MENU_CLEAR":"Clear Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy has been successfully removed from the device.", + "STR_CLEAR_FAILED":"An error occurred when removing Ventoy from disk. You can reinsert the USB device and try again. Check log.txt for details.", + "STR_MENU_PART_STYLE":"Partition Style", + "STR_DISK_2TB_MBR_ERROR":"Please select GPT for devices over 2TB", + "STR_SHOW_ALL_DEV":"Show All Devices", + "STR_PART_ALIGN_4KB":"Align partitions with 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STR_MENU_PART_RESIZE":"Non-destructive Install", + "STR_PART_RESIZE_TIP":"Ventoy will try non-destructive installation if possible. #@Continue?", + "STR_PART_RESIZE_SUCCESS":"Congratulations!#@Ventoy non-destructive installation successfully finished.", + "STR_PART_RESIZE_FAILED":"Non-destructive installation failed, Check log.txt for details.", + "STR_PART_RESIZE_UNSUPPORTED":"Ventoy non-destructive installation stopped because some conditions cannot be met. Check log.txt for details.", + "STR_INSTALL_YES_TIP1":"Warning: Data will be lost!", + "STR_INSTALL_YES_TIP2":"Please enter YES in the text box below to confirm that you indeed want to do a fresh install instead of upgrade.", + "STR_PART_VENTOY_FS":"File System For Ventoy Partition", + "STR_PART_FS":"File System", + "STR_PART_CLUSTER":"Cluster Size", + "STR_PART_CLUSTER_DEFAULT":"System Default Value", + "STR_DONATE":"Donate", + "STR_4KN_UNSUPPORTED":"Currently Ventoy does not support 4K native devices.", + + "STRXXX":"" + }, + { + "name": "georgian (ქართული)", + "FontFamily": "Courier New", + "FontSize": 16, + "Author": "44f33", + + "STR_ERROR": "შეცდომა", + "STR_WARNING": "გაფრთხილება", + "STR_INFO": "ინფორმაცია", + "STR_INCORRECT_DIR": "გთხოვთ გაუშვათ სწორ დირექტორიაში!", + "STR_INCORRECT_TREE_DIR": "აქ არ გაუშვათ, გთხოვთ ჩამოტვირთოთ გამოშვებული ინსტალაციის პაკეტი და იქ და-run-ოთ", + "STR_DEVICE": "მოწყობილობა", + "STR_INSTALL_YES_TIP1": "გაფრთხილება: მონაცემები დაიკარგება", + "STR_INSTALL_YES_TIP2": "გთხოვთ შეიყვანოთ YES რათა დამტკიცდეს რომ თვენ დარწმუნებული ხართ რომ გსურთ ხელახლა დაყენაბა ვიდრე განახლება", + "STR_LOCAL_VER": "Ventoy პაკეტში", + "STR_DISK_VER": "Ventoy მოწყობილობაში", + "STR_STATUS": "სტატუსი - მზადაა", + "STR_PART_RESIZE_FAILED": "არა-დესტრუქციული ინსტალაცია წარუმატებლივ დასრულა, ნახეთ log.txt დეტალებისთვის", + "STR_PART_RESIZE_SUCCESS": "გილოცავთ #@Ventoy არა-დესტრუქციული ინსტალაცია წარმატებით დასრულდა", + "STR_PART_RESIZE_UNSUPPORTED": "Ventoy-ს არასაზიანო ინსტალაცია შეჩერდა რადგან რაღაც პირობები არ კმაყოფილდება. ნახეთ log.txt დეტალებისთვის.", + "STR_INSTALL": "ინსტალაცია", + "STR_UPDATE": "განახლება", + "STR_UPDATE_TIP": "განახლების ოპერაცია უსაფრთხოა, ISO ფაილები არ შეიცვლება. გსურს გაგრძელება?", + "STR_INSTALL_TIP": "მოწყობილობა დაფორმატდება და ყველა მონაცემი დაიკარგება.გსურს გაგრძელება?", + "STR_INSTALL_TIP2": "მოწყობილობა დაფორმატდება და ყველა მონაცემი დაიკარგება! დარწმუნებული ხართ რომ ამის განხორციელება ნამდვილად გსურთ?", + "STR_INSTALL_SUCCESS": "გილოცავთ! Ventoy წარმატებით დაინსტალირდა თქვენს მოწყობილობაზე.", + "STR_INSTALL_FAILED": "დაყენებისას მოხდა შეცდომა. გთხოვთ მიმართოთ FAQ-ს ოფიციალურ ვებსაიტზე.", + "STR_UPDATE_SUCCESS": "გილოცავთ!#@Ventoy წარმატებით განახლდა მოწყობილობაზე.", + "STR_UPDATE_FAILED": "შეცდომა მოხდა განახლების დროს. შეგიძლიათ აკონტროლოთ… გაუქმება", + "STR_WAIT_PROCESS": "შეინარჩუნე გარკვეული სივრცე დისკის ბოლოს", + "STR_MENU_OPTION": "არასწორი მნიშვნელობა რეზერვირებული სივრცისთვის", + "STR_MENU_SECURE_BOOT": "გასუფთავება Ventoy", + "STR_MENU_PART_CFG": "Ventoy წარმატებით წაიშალა მოწყობილობიდან.", + "STR_BTN_OK": "დაიქმნა შეცდომა Ventoy-ის დისკიდან ამოღებისას მოწყობილობა და სცადეთ ხელახლა. შეამოწმეთ log.txt დეტალებისთვის.", + "STR_BTN_CANCEL": "პარტიციის სტილი", + "STR_PRESERVE_SPACE": "გთხოვთ აირჩიოთ GPT 2 ტერაბიატზე მეტი მოწყობილობებისთვის", + "STR_SPACE_VAL_INVALID": "ყველა მოწყობილობის ჩვენება", + "STR_MENU_CLEAR": "პარტიციის გასწორება 4KB-ით", + "STR_CLEAR_SUCCESS": "კომუნიკაციის შეცდომა:", + "STR_CLEAR_FAILED": "კომუნიკაციის შეცდომა: დისტანციური არანორმალური", + "STR_MENU_PART_STYLE": "კომუნიკაციის შეცდომა: მოთხოვნის დრო ამოიწურა", + "STR_DISK_2TB_MBR_ERROR": "კომუნიკაციის შეცდომა: სერვისი მიუწვდომელია", + "STR_SHOW_ALL_DEV": "Daemon-ის სტატუსი განახლებულია, გთხოვთ, სცადოთ მოგვიანებით.", + "STR_PART_ALIGN_4KB": "სერვისი დაკავებულია, გთხოვთ, სცადოთ მოგვიანებით.", + "STR_WEB_COMMUNICATION_ERR": "VTSI ფაილის გენერირება", + "STR_WEB_REMOTE_ABNORMAL": "ამჯერად არ დაწეროთ მოწყობილობაში, არამედ მხოლოდ შექმნათ VTSI ფაილი#@გაგრძელება?", + "STR_WEB_REQUEST_TIMEOUT": "VTSI ფაილი შეიქმნა წარმატებით!#@შეგიძლიათ გამოიყენოთ Rufus…ice, რათა დაასრულოთ Ventoy-ის ინსტალაცია.", + "STR_WEB_SERVICE_UNAVAILABLE": "VTSI ფაილი შეიქმნა ვერ მოხერხდა.", + "STR_WEB_TOKEN_MISMATCH": "არადესტრუქციული ინსტალაცია", + "STR_WEB_SERVICE_BUSY": "Ventoy შეეცდება არა-დესტრუქციულ ინსტალაციას, თუ ეს შესაძლებელია. #@გაგრძელება?", + "STR_MENU_VTSI_CREATE": "გილოცავთ! #@Ventoy არა-დესტრუქციული ინსტალაცია წარმატებით დასრულდა.", + "STR_VTSI_CREATE_TIP": "არადესტრუქციული ინსტალაცია ვერ მოხერხდა, შეამოწმეთ log.txt დეტალებისთვის.", + "STR_VTSI_CREATE_SUCCESS": "Ventoy არა-დესტრუქციული ინსტალაცია შეჩერდა, რადგან… პირობა ვერ შესრულდება . შეამოწმეთ log.txt დეტალებისთვის.", + "STR_VTSI_CREATE_FAILED": "გაფრთხილება: მონაცემები დაიკარგება!", + "STR_MENU_PART_RESIZE": "გთხოვთ, შეიყვანოთ YES ქვემოთ მოცემულ ტექსტურ ველში, რათა დაადასტუროთ... გსურთ განახლების ნაცვლად განახორციელოთ ახალი ინსტალაცია.", + "STR_PART_RESIZE_TIP": "Ventoy ჩეეცდება დააყენოს არა-დესტრუქციული რამდენადაც შეეცდება. გსურს გაგრძელება?", + "STR_PART_VENTOY_FS":"File System For Ventoy Partition", + "STR_PART_FS":"File System", + "STR_PART_CLUSTER":"Cluster Size", + "STR_PART_CLUSTER_DEFAULT":"System Default Value", + "STR_DONATE":"შემოწირულობა", + "STR_4KN_UNSUPPORTED":"Currently Ventoy does not support 4K native devices.", + + "STRXXX": "" + }, + { + "name":"Persian (فارسی)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"ivadham", + + "STR_ERROR":"خطا", + "STR_WARNING":"هشدار", + "STR_INFO":"توضیحات", + "STR_INCORRECT_DIR":".لطفاً در پوشه‌دان صحیح اجرا کنید", + "STR_INCORRECT_TREE_DIR":".این‌جا اجرا نکنید، لطفاً بستهٔ نصب را دانلود و آن‌جا اجرا کنید", + "STR_DEVICE":"حافظهٔ قابل حمل", + "STR_LOCAL_VER":"آمادهٔ نصب Ventoy", + "STR_DISK_VER":"نصب‌شده روی حافظه Ventoy", + "STR_STATUS":"وضعیت - آماده", + "STR_INSTALL":"فرمت و نصب", + "STR_UPDATE":"به‌روزرسانی", + "STR_UPDATE_TIP":"عملیات به‌روزرسانی بی‌خطر است و داده‌های روی حافظهٔ قابل حمل سالم باقی خواهند ماند. ادامه؟", + "STR_INSTALL_TIP":"حافظهٔ قابل حمل فرمت و تمامی داده‌های آن پاک خواهد شد. ادامه؟", + "STR_INSTALL_TIP2":"توجه: این عملیات غیرقابل بازگشت است. ادامه؟", + "STR_INSTALL_SUCCESS":".تبریک! عملیات نصب بر روی حافظهٔ قابل حمل با موفقیت پایان یافت", + "STR_INSTALL_FAILED":".خطا در عملیات نصب! یو‌اس‌بی را از نو متصل و دوباره تلاش کنید", + "STR_UPDATE_SUCCESS":".تبریک! نرم‌افزار با موفقیت بر روی حافظهٔ قابل حمل به‌روزرسانی شد", + "STR_UPDATE_FAILED":".خطا در به‌روزرسانی! یو‌اس‌بی را از نو متصل و دوباره تلاش کنید", + "STR_WAIT_PROCESS":"...پروسه‌ای در حال اجرا است، لطفاً صبر کنید", + "STR_MENU_OPTION":"تنظیمات", + "STR_MENU_SECURE_BOOT":"(Secure Boot) بوت امن", + "STR_MENU_PART_CFG":"پیکربندی پارتیشن", + "STR_BTN_OK":"تأیید", + "STR_BTN_CANCEL":"انصراف", + "STR_PRESERVE_SPACE":"اختصاص مقداری فضا به انتهای حافظهٔ قابل حمل", + "STR_SPACE_VAL_INVALID":".این مقدار فضا برای اختصاص‌یافتن نامعتبر است", + "STR_MENU_CLEAR":"Ventoy را پاک کنید", + "STR_CLEAR_SUCCESS":"Ventoy با موفقیت از دستگاه برداشته شد.", + "STR_CLEAR_FAILED":"هنگام پاک کردن Ventoy از روی دیسک خطایی روی داد. می توانید USB را دوباره از برق جدا کنید و دوباره امتحان کنید. log.txt را برای جزئیات بررسی کنید.", + "STR_MENU_PART_STYLE":"سبک پارتیشن بندی", + "STR_DISK_2TB_MBR_ERROR":"لطفاً GPT را برای دیسک بیش از 2 ترابایت انتخاب کنید", + "STR_SHOW_ALL_DEV":"نمایش همه دستگاه ها", + "STR_PART_ALIGN_4KB":"پارتیشن ها را با 4KB تراز کنید", + "STR_WEB_COMMUNICATION_ERR":"خطای ارتباطی:", + "STR_WEB_REMOTE_ABNORMAL":"خطای ارتباطی: از راه دور غیر طبیعی است", + "STR_WEB_REQUEST_TIMEOUT":"خطای ارتباطی: زمان درخواست به پایان رسیده است", + "STR_WEB_SERVICE_UNAVAILABLE":"خطای ارتباطی: سرویس موجود نیست", + "STR_WEB_TOKEN_MISMATCH":"وضعیت Daemon به روز شد ، لطفاً بعداً دوباره امتحان کنید.", + "STR_WEB_SERVICE_BUSY":"سرویس شلوغ است ، لطفاً بعداً دوباره امتحان کنید.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STR_MENU_PART_RESIZE":"Non-destructive Install", + "STR_PART_RESIZE_TIP":"Ventoy will try non-destructive installation if possible. #@Continue?", + "STR_PART_RESIZE_SUCCESS":"Congratulations!#@Ventoy non-destructive installation successfully finished.", + "STR_PART_RESIZE_FAILED":"Non-destructive installation failed, Check log.txt for details.", + "STR_PART_RESIZE_UNSUPPORTED":"Ventoy non-destructive installation stopped because some conditions cannot be met. Check log.txt for details.", + "STR_INSTALL_YES_TIP1":"Warning: Data will be lost!", + "STR_INSTALL_YES_TIP2":"Please enter YES in the text box below to confirm that you indeed want to do a fresh install instead of upgrade.", + "STR_PART_VENTOY_FS":"File System For Ventoy Partition", + "STR_PART_FS":"File System", + "STR_PART_CLUSTER":"Cluster Size", + "STR_PART_CLUSTER_DEFAULT":"System Default Value", + "STR_DONATE":"اهداء", + "STR_4KN_UNSUPPORTED":"Currently Ventoy does not support 4K native devices.", + + "STRXXX":"" + }, + { + "name":"Polish (Polski)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"B.O.S.S, ChuckMichael", + + "STR_ERROR":"Błąd", + "STR_WARNING":"Ostrzeżenie", + "STR_INFO":"Informacja", + "STR_INCORRECT_DIR":"Proszę uruchom w odpowiednim katalogu!", + "STR_INCORRECT_TREE_DIR":"Nie uruchamiaj mnie tutaj, pobierz pakiet instalacyjny i uruchom go.", + "STR_DEVICE":"Urządzenie", + "STR_LOCAL_VER":"Ventoy w programie", + "STR_DISK_VER":"Ventoy na urządzeniu", + "STR_STATUS":"Status - GOTOWY", + "STR_INSTALL":"Zainstaluj", + "STR_UPDATE":"Zaktualizuj", + "STR_UPDATE_TIP":"Operacja aktualizacji jest bezpieczna, pliki ISO pozostaną niezmienione.#@Kontynuować?", + "STR_INSTALL_TIP":"Dysk zostanie sformatowany, a wszystkie dane zostaną utracone.#@Kontynuować?", + "STR_INSTALL_TIP2":"Dysk zostanie sformatowany, a wszystkie dane zostaną utracone.#@Kontynuować? (Ponowne sprawdzenie)", + "STR_INSTALL_SUCCESS":"Gratulacje!#@Ventoy został pomyślnie zainstalowany na urządzeniu.", + "STR_INSTALL_FAILED":"Wystąpił błąd podczas instalacji. Możesz ponownie podłączyć USB i spróbować jeszcze raz. Szczegóły w log.txt.", + "STR_UPDATE_SUCCESS":"Gratulacje!#@Ventoy został pomyślnie zaktualizowany na urządzeniu.", + "STR_UPDATE_FAILED":"Wystąpił błąd podczas aktualizacji. Możesz ponownie podłączyć USB i spróbować jeszcze raz. Szczegóły w log.txt.", + "STR_WAIT_PROCESS":"Wątek jest uruchomiony, proszę czekać...", + "STR_MENU_OPTION":"Opcje", + "STR_MENU_SECURE_BOOT":"Wsparcie Secure Boot", + "STR_MENU_PART_CFG":"Konfiguracja partycji", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Anuluj", + "STR_PRESERVE_SPACE":"Zarezerwuj trochę miejsca na końcu dysku", + "STR_SPACE_VAL_INVALID":"Nieprawidłowa wartość dla zarezerwowanego miejsca", + "STR_MENU_CLEAR":"Usuń Ventoy z urządzenia", + "STR_CLEAR_SUCCESS":"Ventoy został pomyślnie usunięty z urządzenia.", + "STR_CLEAR_FAILED":"Wystąpił błąd podczas usuwania Ventoy z dysku. Możesz podłączyć USB i spróbować jeszcze raz. Szczegóły w log.txt.", + "STR_MENU_PART_STYLE":"Schemat partycjonowania", + "STR_DISK_2TB_MBR_ERROR":"Wybierz GPT dla dysku powyżej 2TB", + "STR_SHOW_ALL_DEV":"Pokaż wszystkie urządzenia", + "STR_PART_ALIGN_4KB":"Wyrównaj partycje do 4KB", + "STR_WEB_COMMUNICATION_ERR":"Błąd komunikacji:", + "STR_WEB_REMOTE_ABNORMAL":"Błąd komunikacji: nieprawidłowy serwer", + "STR_WEB_REQUEST_TIMEOUT":"Błąd komunikacji: przekroczono limit czasu żądania", + "STR_WEB_SERVICE_UNAVAILABLE":"Błąd komunikacji: usługa niedostępna", + "STR_WEB_TOKEN_MISMATCH":"Stan daemona został zaktualizowany, spróbuj ponownie później.", + "STR_WEB_SERVICE_BUSY":"Usługa jest zajęta, spróbuj ponownie później.", + "STR_MENU_VTSI_CREATE":"Wygeneruj plik VTSI", + "STR_VTSI_CREATE_TIP":"Tym razem nie zapisze na urządzeniu, ale tylko wygeneruje plik VTSI#@Kontynuować?", + "STR_VTSI_CREATE_SUCCESS":"Pomyślnie wygenerowany plik VTSI!#@Możesz teraz użyć Rufus'a(3.15+) aby zapisać go na urządzeniu by dokończyć instalację Ventoy.", + "STR_VTSI_CREATE_FAILED":"Wygenerowanie pliku VTSI nie powiodło się.", + "STR_MENU_PART_RESIZE":"Instalacja bez utraty danych", + "STR_PART_RESIZE_TIP":"Jeśli to możliwe, Ventoy spróbuje przeprowadzić instalację bez utraty danych. #@Kontynuować?", + "STR_PART_RESIZE_SUCCESS":"Gratulacje! Instalacja bez utraty danych #@Ventoy zakończona pomyślnie.", + "STR_PART_RESIZE_FAILED":"Instalacja bez utraty danych zakończyła się niepowodzeniem. Szczegóły znajdziesz w pliku log.txt.", + "STR_PART_RESIZE_UNSUPPORTED":"Instalacja bez utraty danych Ventoy została przerwana, ponieważ nie można spełnić niektórych warunków. Szczegóły znajdziesz w pliku log.txt.", + "STR_INSTALL_YES_TIP1":"Ostrzeżenie: Dane zostaną utracone!", + "STR_INSTALL_YES_TIP2":"Wpisz YES w poniższym polu tekstowym, aby potwierdzić, że naprawdę chcesz przeprowadzić nową instalację zamiast aktualizacji.", + "STR_PART_VENTOY_FS":"System plików dla partycji Ventoy", + "STR_PART_FS":"System plików", + "STR_PART_CLUSTER":"Wielkość klastra", + "STR_PART_CLUSTER_DEFAULT":"Wartość domyślna systemu", + "STR_DONATE":"Przekaż darowiznę", + "STR_4KN_UNSUPPORTED":"Obecnie Ventoy nie obsługuje urządzeń o fizycznym rozmiarze sektora 4K.", + + "STRXXX":"" + }, + { + "name":"Portuguese Brazilian (Português Brasileiro)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"EstevaoCostaG3, David BrazSan, Hildo Guillardi Júnior, Chrystian Rubio, Felipe", + + "STR_ERROR":"Erro", + "STR_WARNING":"Aviso", + "STR_INFO":"Informações", + "STR_INCORRECT_DIR":"Por favor execute no diretório correto!", + "STR_INCORRECT_TREE_DIR":"Não me execute aqui, por favor baixe o pacote de instalação lançado e me execute lá.", + "STR_DEVICE":"Dispositivo", + "STR_LOCAL_VER":"Ventoy no Pacote", + "STR_DISK_VER":"Ventoy no Dispositivo", + "STR_STATUS":"Status - PRONTO", + "STR_INSTALL":"Instalar", + "STR_UPDATE":"Atualizar", + "STR_UPDATE_TIP":"A operação de atualização é segura, os arquivos ISO não serão alterados.#@Continuar?", + "STR_INSTALL_TIP":"O dispositivo será formatado e todos os dados serão perdidos.#@Continuar?", + "STR_INSTALL_TIP2":"O dispositivo será formatado e todos os dados serão perdidos.#@Continuar? (Verificação Dupla)", + "STR_INSTALL_SUCCESS":"Parabéns!#@O Ventoy foi instalado com sucesso no dispositivo.", + "STR_INSTALL_FAILED":"Um erro ocorreu durante a instalação. Você pode re-inserir o dispositivo USB e tentar de novo. Verifique o log.txt para mais detalhes. Se ele sempre falha por favor refira-se ao FAQ no site oficial da web.", + "STR_UPDATE_SUCCESS":"Parabéns!#@O Ventoy foi atualizado com sucesso no dispositivo.", + "STR_UPDATE_FAILED":"Um erro ocorreu durante a atualização. Você pode re-inserir o dispositivo USB e tentar de novo. Verifique o log.txt para mais detalhes. Se ele sempre falha por favor refira-se ao FAQ no site oficial da web.", + "STR_WAIT_PROCESS":"Um thread está em execução, por favor espere...", + "STR_MENU_OPTION":"Opção", + "STR_MENU_SECURE_BOOT":"Suporte ao Boot Seguro", + "STR_MENU_PART_CFG":"Configuração da Partição", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Cancelar", + "STR_PRESERVE_SPACE":"Preservar algum espaço no fim do disco", + "STR_SPACE_VAL_INVALID":"Valor inválido para o espaço reservado", + "STR_MENU_CLEAR":"Limpar o Ventoy", + "STR_CLEAR_SUCCESS":"O Ventoy foi removido do dispositivo com sucesso.", + "STR_CLEAR_FAILED":"Um erro ocorreu quando removia o Ventoy do disco. Você pode re-inserir o dispositivo USB e tentar de novo. Verifique o log.txt para mais detalhes.", + "STR_MENU_PART_STYLE":"Estilo da Partição", + "STR_DISK_2TB_MBR_ERROR":"Por favor selecione o GPT para dispositivos acima de 2 TBs", + "STR_SHOW_ALL_DEV":"Mostrar Todos os Dispositivos", + "STR_PART_ALIGN_4KB":"Alinhar as partições com 4 KBs", + "STR_WEB_COMMUNICATION_ERR":"Erro de comunicação:", + "STR_WEB_REMOTE_ABNORMAL":"Erro de comunicação: Remoto Anormal", + "STR_WEB_REQUEST_TIMEOUT":"Erro de comunicação: O Tempo da Requisição se Esgotou", + "STR_WEB_SERVICE_UNAVAILABLE":"Erro de comunicação: Serviço Indisponível", + "STR_WEB_TOKEN_MISMATCH":"Status do daemon atualizado, por favor tente de novo mais tarde.", + "STR_WEB_SERVICE_BUSY":"O serviço está ocupado, por favor tente de novo mais tarde.", + "STR_MENU_VTSI_CREATE":"Gerar arquivo VTSI", + "STR_VTSI_CREATE_TIP":"Desta vez não gravará no dispositivo mas vai gerar apenas um arquivo VTSI.#@Continuar?", + "STR_VTSI_CREATE_SUCCESS":"Arquivo VTSI criado com sucesso!#@Você pode usar o Rufus (3.15+) pra gravá-lo no dispositivo e completar a instalação do Ventoy.", + "STR_VTSI_CREATE_FAILED":"A criação do arquivo VTSI falhou.", + "STR_MENU_PART_RESIZE":"Instalação não destrutiva", + "STR_PART_RESIZE_TIP":"O Ventoy tentará uma instalação não destrutiva se possível.#@Continuar?", + "STR_PART_RESIZE_SUCCESS":"Parabéns!#@Instalação não destrutiva do Ventoy concluída com sucesso.", + "STR_PART_RESIZE_FAILED":"A instalação não destrutiva falhou, verifique o log.txt para detalhes.", + "STR_PART_RESIZE_UNSUPPORTED":"A instalação não destrutiva do Ventoy parou porque algumas condições não podem ser atendidas. Verifique o log.txt para detalhes.", + "STR_INSTALL_YES_TIP1":"Aviso: Os dados serão perdidos!", + "STR_INSTALL_YES_TIP2":"Por favor insira YES na caixa de texto abaixo pra confirmar que você de fato quer fazer uma nova instalação ao invés de atualizar.", + "STR_PART_VENTOY_FS":"Sistema de Arquivos para a partição do Ventoy", + "STR_PART_FS":"Sistema de Arquivos", + "STR_PART_CLUSTER":"Tamanho do Cluster", + "STR_PART_CLUSTER_DEFAULT":"Valor Padrão do Sistema", + "STR_DONATE":"Doar", + "STR_4KN_UNSUPPORTED":"Atualmente o Ventoy não suporta dispositivos 4K nativos.", + + "STRXXX":"" + }, + { + "name":"Slovenian (Slovenščina)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Andrew Poženel, Urajmal", + + "STR_ERROR":"Napaka", + "STR_WARNING":"Opozorilo", + "STR_INFO":"Informacija", + "STR_INCORRECT_DIR":"Prosim, zaženite program v pravilni mapi!", + "STR_INCORRECT_TREE_DIR":"Ne izvajajte programa tukaj, prosim prenesite izdani namestitveni paket in ga izvedite tam.", + "STR_DEVICE":"Naprava", + "STR_LOCAL_VER":"Ventoy različica", + "STR_DISK_VER":"Ventoy v napravi", + "STR_STATUS":"Stanje - PRIPRAVLJEN", + "STR_INSTALL":"Namesti", + "STR_UPDATE":"Posodobi", + "STR_UPDATE_TIP":"Nadgradnja je varna, datoteke ISO ostanejo nespremenjene.#@Nadaljuj?", + "STR_INSTALL_TIP":"Naprava bo formatirana in vsi podatki bodo izgubljeni.#@Nadaljuj?", + "STR_INSTALL_TIP2":"Naprava bo formatirana in vsi podatki bodo izgubljeni.#@Nadaljuj? (dvakrat preverite)", + "STR_INSTALL_SUCCESS":"Čestitamo!#@Ventoy je bil uspešno nameščen na napravo.", + "STR_INSTALL_FAILED":"Med namestitvijo je prišlo do napake. Ponovno vstavite USB-napravo in poskusite znova. Podrobnosti najdete v datoteki log.txt. Če napaka še vedno obstaja, si oglejte pogosta vprašanja na uradni spletni strani.", + "STR_UPDATE_SUCCESS":"Čestitamo!#@Ventoy je bil uspešno posodobljen na napravi.", + "STR_UPDATE_FAILED":"Med posodobitvijo je prišlo do napake. Ponovno vstavite USB-napravo in poskusite znova. Podrobnosti najdete v datoteki log.txt. Če se napaka ponavlja, si oglejte pogosta vprašanja na uradni spletni strani.", + "STR_WAIT_PROCESS":"Nit se izvaja, prosimo počakajte...", + "STR_MENU_OPTION":"Možnost", + "STR_MENU_SECURE_BOOT":"Podpora za varen zagon", + "STR_MENU_PART_CFG":"Konfiguracija particije", + "STR_BTN_OK":"V redu", + "STR_BTN_CANCEL":"Prekliči", + "STR_PRESERVE_SPACE":"Ohrani nekaj prostora na koncu diska", + "STR_SPACE_VAL_INVALID":"Neveljavna vrednost za rezervirani prostor", + "STR_MENU_CLEAR":"Počisti Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy je bil uspešno odstranjen iz naprave.", + "STR_CLEAR_FAILED":"Pri odstranjevanju Ventoya z diska je prišlo do napake. Ponovno vstavite USB-napravo in poskusite znova. Podrobnosti najdete v datoteki log.txt.", + "STR_MENU_PART_STYLE":"Slog particije", + "STR_DISK_2TB_MBR_ERROR":"Za naprave z več kot 2 TB izberite GPT.", + "STR_SHOW_ALL_DEV":"Pokaži vse naprave", + "STR_PART_ALIGN_4KB":"Poravnaj particije s 4 KB", + "STR_WEB_COMMUNICATION_ERR":"Napaka pri komunikaciji:", + "STR_WEB_REMOTE_ABNORMAL":"Napaka pri komunikaciji: Oddaljena napaka", + "STR_WEB_REQUEST_TIMEOUT":"Napaka pri komunikaciji: Zahteva je potekla", + "STR_WEB_SERVICE_UNAVAILABLE":"Napaka pri komunikaciji: Storitev ni na voljo", + "STR_WEB_TOKEN_MISMATCH":"Stanje ozadnega procesa je bilo posodobljeno, poskusite pozneje.", + "STR_WEB_SERVICE_BUSY":"Storitev je zasedena, prosimo poskusite kasneje.", + "STR_MENU_VTSI_CREATE":"Ustvari datoteko VTSI", + "STR_VTSI_CREATE_TIP":"Tokrat ne bo zapisoval na napravo, ampak bo samo ustvaril datoteko VTSI#@Nadaljuj?", + "STR_VTSI_CREATE_SUCCESS":"Datoteka VTSI je bila uspešno ustvarjena!#@Za namestitev Ventoya jo lahko zapišete na napravo z uporabo programa Rufus (3.15+).", + "STR_VTSI_CREATE_FAILED":"Ustvarjanje datoteke VTSI ni uspelo.", + "STR_MENU_PART_RESIZE":"Neuničujoča namestitev", + "STR_PART_RESIZE_TIP":"Ventoy bo poskusil z neuničujočo namestitvijo, če je le mogoče. #@Nadaljuj?", + "STR_PART_RESIZE_SUCCESS":"Čestitamo!#@Ventoy neuničljiva namestitev je bila uspešno zaključena.", + "STR_PART_RESIZE_FAILED":"Neuničljiva namestitev ni uspela, podrobnosti preverite v datoteki log.txt.", + "STR_PART_RESIZE_UNSUPPORTED":"Neuničljiva namestitev Ventoy se je ustavila, ker nekateri pogoji niso izpolnjeni. Podrobnosti preverite v datoteki log.txt.", + "STR_INSTALL_YES_TIP1":"Opozorilo: Podatki bodo izgubljeni!", + "STR_INSTALL_YES_TIP2":"V spodnje besedilno polje vnesite DA, da potrdite, da res želite izvesti novo namestitev namesto nadgradnje.", + "STR_PART_VENTOY_FS":"Datotečni sistem za particijo Ventoy", + "STR_PART_FS":"Datotečni sistem", + "STR_PART_CLUSTER":"Velikost gruče", + "STR_PART_CLUSTER_DEFAULT":"Privzeta sistemska vrednost", + "STR_DONATE":"Donirajte", + "STR_4KN_UNSUPPORTED":"Trenutno Ventoy ne podpira naprav z ločljivostjo 4K.", + + "STRXXX":"" + }, + { + "name":"Turkish (Türkçe)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Erhan Kültür,Tayfun Akkoyun, Oğuz Ersen", + + "STR_ERROR":"Hata", + "STR_WARNING":"Uyarı", + "STR_INFO":"Bilgi", + "STR_INCORRECT_DIR":"Lütfen doğru dizin altında çalıştırın!", + "STR_INCORRECT_TREE_DIR":"Dosyayı burada çalıştırmayın, lütfen yayınlanan en son kurulum paketini indirin ve oradan çalıştırın.", + "STR_DEVICE":"Aygıt", + "STR_LOCAL_VER":"Ventoy GÜNCEL Sürüm", + "STR_DISK_VER":"Aygıttaki Ventoy Sürümü", + "STR_STATUS":"Durum - HAZIR", + "STR_INSTALL":"Kur", + "STR_UPDATE":"Güncelle", + "STR_UPDATE_TIP":"Yükseltme işlemi güvenlidir, ISO dosyalarınız bundan etkilenmeyecek.#@Devam edilsin mi?", + "STR_INSTALL_TIP":"Disk biçimlendirilecek ve tüm veriler kaybolacak.#@Devam edilsin mi?", + "STR_INSTALL_TIP2":"Disk biçimlendirilecek ve tüm veriler kaybolacak.#@Devam edilsin mi? (Son UYARI!)", + "STR_INSTALL_SUCCESS":"Tebrikler!#@Ventoy, aygıta başarıyla kuruldu.", + "STR_INSTALL_FAILED":"Kurulum sırasında bir hata oluştu. USB'yi yeniden takıp tekrar deneyebilirsiniz. Ayrıntılar için log.txt dosyasına bakın.", + "STR_UPDATE_SUCCESS":"Tebrikler!#@Ventoy, aygıtta başarıyla güncellendi.", + "STR_UPDATE_FAILED":"Güncelleme sırasında bir hata oluştu. USB'yi yeniden takıp tekrar deneyebilirsiniz. Ayrıntılar için log.txt dosyasına bakın.", + "STR_WAIT_PROCESS":"Mevcut işlem çalışıyor, lütfen bekleyin...", + "STR_MENU_OPTION":"Seçenek", + "STR_MENU_SECURE_BOOT":"Güvenli Önyükleme Desteği", + "STR_MENU_PART_CFG":"Bölüm Yapılandırması", + "STR_BTN_OK":"Tamam", + "STR_BTN_CANCEL":"İptal", + "STR_PRESERVE_SPACE":"Diskin sonunda biraz ayrılmış alan bırak", + "STR_SPACE_VAL_INVALID":"Ayrılmış alan için geçersiz değer girdiniz", + "STR_MENU_CLEAR":"Ventoy'u USB Diskten Sil", + "STR_CLEAR_SUCCESS":"Ventoy başarılı bir şekilde diskten silindi", + "STR_CLEAR_FAILED":"Ventoy USB diskten temizlenirken bir hata oluştu. USB'yi yeniden takıp tekrar deneyebilirsiniz. Ayrıntılar için log.txt dosyasına bakın", + "STR_MENU_PART_STYLE":"Bölüm Yapısı", + "STR_DISK_2TB_MBR_ERROR":"2TB üstündeki diskler için lütfen GPT disk yapısını seçin.", + "STR_SHOW_ALL_DEV":"Tüm Aygıtları Göster", + "STR_PART_ALIGN_4KB":"Tüm bölümleri 4KB düzeninde hizala", + "STR_WEB_COMMUNICATION_ERR":"İletişim Hatası:", + "STR_WEB_REMOTE_ABNORMAL":"İletişim Hatası:Uzaktan erişim hizmeti anormal durumda", + "STR_WEB_REQUEST_TIMEOUT":"İletişim hatası: Uzaktan erişim isteği zaman aşımına uğradı", + "STR_WEB_SERVICE_UNAVAILABLE":"İletişim hatası: Uzaktan web erişim hizmeti erişilemez durumda", + "STR_WEB_TOKEN_MISMATCH":"Daemon durumu güncellendi,lütfen daha sonra tekrar deneyin.", + "STR_WEB_SERVICE_BUSY":"Hizmet meşgul, lütfen daha sonra tekrar deneyin.", + "STR_MENU_VTSI_CREATE":"VTSI Dosyası Oluştur", + "STR_VTSI_CREATE_TIP":"Şu an aygıta yazılmayacak,sadece bir VTSI dosyası oluşturulacak#@Devam edilsin mi?", + "STR_VTSI_CREATE_SUCCESS":"VTSI dosyası başarılı bir şekilde oluşturuldu!#@Ventoy'un aygıta kurulumunu tamamlamak için Rufus(3.15+) programını kullanabilirsiniz.", + "STR_VTSI_CREATE_FAILED":"VTSI dosyası oluşturma başarısız oldu!", + "STR_MENU_PART_RESIZE":"Tahribatsız Kurulum", + "STR_PART_RESIZE_TIP":"Ventoy,mümkünse tahribatsız kurulumu deneyecektir. . #@Devam edilsin mi?", + "STR_PART_RESIZE_SUCCESS":"Tebrikler!#@Ventoy Tahribatsız Kurulum, başarıyla tamamlandı.", + "STR_PART_RESIZE_FAILED":"Tahribatsız kurulum başarısız oldu, ayrıntılar için log.txt dosyasını kontrol edin.", + "STR_PART_RESIZE_UNSUPPORTED":"Ventoy Tahribatsız Kurulum, bazı koşullar sağlanmadığı için durduruldu. Ayrıntılı bilgi için log.txt dosyasını kontrol edin.", + "STR_INSTALL_YES_TIP1":"Uyarı: Tüm verileriniz kaybolacak!", + "STR_INSTALL_YES_TIP2":"Güncelleme yapmak yerine,yeni bir kurulum yapmak istediğinizi doğrulamak için lütfen aşağıdaki metin kutusuna YES yazın.", + "STR_PART_VENTOY_FS":"Ventoy bölümü Dosya Sistemi", + "STR_PART_FS":"Dosya Sistemi", + "STR_PART_CLUSTER":"Sektör Boyutu", + "STR_PART_CLUSTER_DEFAULT":"Sistem varsayılan değeri", + "STR_DONATE":"Ventoy'a Bağış yap", + "STR_4KN_UNSUPPORTED":"Diskiniz 4K(4096byte) sektör yapısına sahip.Ventoy, 4K sektör yapısına sahip cihazlara şu anda destek vermemektedir.", + + "STRXXX":"" + }, + { + "name":"German (Deutsch)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"luzea & u!^DEV, wiz64", + + "STR_ERROR":"Fehler", + "STR_WARNING":"Warnung", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Bitte im richtigen Verzeichnis ausführen!", + "STR_INCORRECT_TREE_DIR":"Bitte nicht hier ausführen. Laden Sie das Installationspaket herunter und von dort aus ausführen.", + "STR_DEVICE":"Gerät", + "STR_LOCAL_VER":"Ventoy (lokal)", + "STR_DISK_VER":"Ventoy (Gerät)", + "STR_STATUS":"Status - BEREIT", + "STR_INSTALL":"Installieren", + "STR_UPDATE":"Aktualisieren", + "STR_UPDATE_TIP":"Die Durchführung der Aktualisierung ist sicher, ISO-Dateien bleiben unverändert.#@Fortfahren?", + "STR_INSTALL_TIP":"Das Gerät wird formatiert und alle Daten gehen verloren.#@Fortfahren?", + "STR_INSTALL_TIP2":"Das Gerät wird formatiert und alle Daten gehen verloren.#@Fortfahren? (erneute Überprüfung)", + "STR_INSTALL_SUCCESS":"Herzlichen Glückwunsch!#@Ventoy wurde erfolgreich auf dem Gerät installiert.", + "STR_INSTALL_FAILED":"Während der Installation ist ein Fehler aufgetreten. Stecken Sie das Gerät neu ein und versuchen Sie es erneut. Details finden Sie in log.txt. Falls der Vorgang immer fehlschlägt, lesen Sie bitte das FAQ auf der offiziellen Website.", + "STR_UPDATE_SUCCESS":"Herzlichen Glückwunsch!#@Ventoy wurde erfolgreich auf dem Gerät aktualisiert.", + "STR_UPDATE_FAILED":"Während der Aktualisierung ist ein Fehler aufgetreten. Stecken Sie das Gerät neu ein und versuchen Sie es erneut. Details finden Sie in log.txt. Falls der Vorgang immer fehlschlägt, lesen Sie bitte das FAQ auf der offiziellen Website.", + "STR_WAIT_PROCESS":"Ein anderer Thread läuft, bitte warten...", + "STR_MENU_OPTION":"Optionen", + "STR_MENU_SECURE_BOOT":"Secure Boot", + "STR_MENU_PART_CFG":"Partitionskonfiguration", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Abbrechen", + "STR_PRESERVE_SPACE":"Etwas Speicher am Ende des Datenträgers reservieren.", + "STR_SPACE_VAL_INVALID":"Ungültiger Wert für reservierten Speicherplatz!", + "STR_MENU_CLEAR":"Ventoy entfernen", + "STR_CLEAR_SUCCESS":"Ventoy wurde erfolgreich vom Gerät entfernt.", + "STR_CLEAR_FAILED":"Beim Versuch, Ventoy zu entfernen, ist ein Fehler aufgetreten. Stecken Sie das Gerät neu ein und versuchen Sie es erneut. Überprüfen Sie die log.txt auf Details.", + "STR_MENU_PART_STYLE":"Partitionsstil", + "STR_DISK_2TB_MBR_ERROR":"Wählen Sie GPT für Geräte > 2TB aus.", + "STR_SHOW_ALL_DEV":"Alle Geräte anzeigen", + "STR_PART_ALIGN_4KB":"Richten Sie Partitionen mit 4KB aus", + "STR_WEB_COMMUNICATION_ERR":"Kommunikationsfehler:", + "STR_WEB_REMOTE_ABNORMAL":"Kommunikationsfehler: Unnormales Verhalten", + "STR_WEB_REQUEST_TIMEOUT":"Kommunikationsfehler: Zeitüberschreitung der Anforderung", + "STR_WEB_SERVICE_UNAVAILABLE":"Kommunikationsfehler: Dienst nicht verfügbar", + "STR_WEB_TOKEN_MISMATCH":"Daemon-Status aktualisiert, bitte später erneut versuchen.", + "STR_WEB_SERVICE_BUSY":"Dienst ist ausgelastet, bitte später erneut versuchen.", + "STR_MENU_VTSI_CREATE":"VTSI-Datei erstellen", + "STR_VTSI_CREATE_TIP":"Es wird nur eine VTSI-Datei erstellt und nichts auf ein Gerät geschrieben. #@Fortfahren?", + "STR_VTSI_CREATE_SUCCESS":"VTSI-Datei erfolgreich erstellt!#@Sie können Rufus(3.15+) zum auf das Gerät schreiben verwenden um die Installation von Ventoy fertigzustellen.", + "STR_VTSI_CREATE_FAILED":"VTSI-Datei konnte nicht erstellt werden.", + "STR_MENU_PART_RESIZE":"Zerstörungsfreie Installation", + "STR_PART_RESIZE_TIP":"Ventoy wird eine Installation ohne vorherige Formatierung versuchen. #@Fortfahren?", + "STR_PART_RESIZE_SUCCESS":"Glückwunsch! #@Die Installation von Ventoy, ohne vorherige Formatierung, wurde erfolgreich abgeschlossen.", + "STR_PART_RESIZE_FAILED":"Installation ohne vorherige Formatierung fehlgeschlagen. Details dazu finden Sie in log.txt.", + "STR_PART_RESIZE_UNSUPPORTED":"Aufgrund einiger nicht erfüllbarer Bedingungen wurde die Installation, ohne vorherige Formatierung, gestoppt. Details dazu finden Sie in log.txt.", + "STR_INSTALL_YES_TIP1":"Warnung: Die Daten gehen verloren!", + "STR_INSTALL_YES_TIP2":"Bitte bestätigen Sie die untere Textbox, um eine Neuinstallation durchzuführen.", + "STR_PART_VENTOY_FS":"Dateisystem für die Ventoy-Partition", + "STR_PART_FS":"Dateisystem", + "STR_PART_CLUSTER":"Clustergröße", + "STR_PART_CLUSTER_DEFAULT":"Systemstandardwert", + "STR_DONATE":"Spenden", + "STR_4KN_UNSUPPORTED":"Ventoy unterstützt derzeit keine nativen 4K-Geräte.", + + "STRXXX":"" + }, + { + "name":"Occitan (Occitan)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"quentin", + + "STR_ERROR":"Error", + "STR_WARNING":"Avertiment", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Aqueste programa deu s’executar dins lo bon repertòri !", + "STR_INCORRECT_TREE_DIR":"Lancetz pas aquò, mercés de telecargar lo programa d’installacion e relançatz-lo.", + "STR_DEVICE":"Periferic", + "STR_LOCAL_VER":"Ventoy en local", + "STR_DISK_VER":"Ventoy sul periferic", + "STR_STATUS":"Estat - prèst", + "STR_INSTALL":"Installacion", + "STR_UPDATE":"Mesa a jorn", + "STR_UPDATE_TIP":"La mesa a jorn es segura, los fichièrs ISO seràn pas modificats.#@Continhar ?", + "STR_INSTALL_TIP":"Lo disc serà formatat e totas sas donadas seràn perdudas.#@Contunhar ?", + "STR_INSTALL_TIP2":"Lo disc serà formatat e totas sas donadas seràn perdudas.#@Contunhar ? (confirmacion)", + "STR_INSTALL_SUCCESS":"Felicitacion  !#@Ventoy es estat corrèctament installat sul periferic.", + "STR_INSTALL_FAILED":"Una error s’es producha pendent l’installacion. Podètz tornar brancar lo periferic USB e tornar ensajar. Agachatz lo fichièr log.txt per ne saber mai.", + "STR_UPDATE_SUCCESS":"Felicitacions !#@Ventoy es estat corrèctament mes a jorn sul periferic.", + "STR_UPDATE_FAILED":"Una error s’es producha pendent la mesa a jorn. Podètz tornar brancar lo periferic USB e tornar ensajar. Agachatz lo fichièr log.txt per ne saber mai.", + "STR_WAIT_PROCESS":"Una operacion es en cors, esperatz...", + "STR_MENU_OPTION":"Opcion", + "STR_MENU_SECURE_BOOT":"Secure Boot", + "STR_MENU_PART_CFG":"Configuracion de particion", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Anullar", + "STR_PRESERVE_SPACE":"Servar d’espaci a la fin del disc", + "STR_SPACE_VAL_INVALID":"Valor invalida per l’espaci reservat", + "STR_MENU_CLEAR":"Escafar Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy es estat corrèctament tirat del periferic.", + "STR_CLEAR_FAILED":"Una error s’es producha pendent l’esfaçament de Ventoy del disc. Podètz tornar brancar l’USB e tornar ensajar. Vejatz log.txt pels detalhs.", + "STR_MENU_PART_STYLE":"Estil de particion", + "STR_DISK_2TB_MBR_ERROR":"Pels disques de mai de 2 To seleccionatz GPT", + "STR_SHOW_ALL_DEV":"Mostrar totes los periferics", + "STR_PART_ALIGN_4KB":"Alinhar las particions sus 4 Ko", + "STR_WEB_COMMUNICATION_ERR":"Error de comunicacion :", + "STR_WEB_REMOTE_ABNORMAL":"Error de comunicacion : remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Error de comunicacion : requèsta tardièra", + "STR_WEB_SERVICE_UNAVAILABLE":"Error de comunicacion : servici pas disponible", + "STR_WEB_TOKEN_MISMATCH":"Estat del Daemon actualizat, tornatz ensajar mai tard.", + "STR_WEB_SERVICE_BUSY":"Lo servici es ocupat, tornatz ensajar mai tard.", + "STR_MENU_VTSI_CREATE":"Generar lo fichièr VTSI", + "STR_VTSI_CREATE_TIP":"Aqueste còp cap d’escritura al disc, generacion del fichiet VTSI sonque#@Contunhar ?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"Fracàs de la creacion del fichièr VTSI.", + "STR_MENU_PART_RESIZE":"Non-destructive Install", + "STR_PART_RESIZE_TIP":"Ventoy will try non-destructive installation if possible. #@Continue?", + "STR_PART_RESIZE_SUCCESS":"Congratulations!#@Ventoy non-destructive installation successfully finished.", + "STR_PART_RESIZE_FAILED":"Non-destructive installation failed, Check log.txt for details.", + "STR_PART_RESIZE_UNSUPPORTED":"Ventoy non-destructive installation stopped because some conditions cannot be met. Check log.txt for details.", + "STR_INSTALL_YES_TIP1":"Warning: Data will be lost!", + "STR_INSTALL_YES_TIP2":"Please enter YES in the text box below to confirm that you indeed want to do a fresh install instead of upgrade.", + "STR_PART_VENTOY_FS":"File System For Ventoy Partition", + "STR_PART_FS":"File System", + "STR_PART_CLUSTER":"Cluster Size", + "STR_PART_CLUSTER_DEFAULT":"System Default Value", + "STR_DONATE":"Donate", + "STR_4KN_UNSUPPORTED":"Currently Ventoy does not support 4K native devices.", + + "STRXXX":"" + }, + { + "name":"French (Français)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"vboucard, Silejonu, wiz64", + + "STR_ERROR":"Erreur", + "STR_WARNING":"Avertissement", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Ce programme doit s'exécuter dans le bon répertoire !", + "STR_INCORRECT_TREE_DIR":"Ne me lancez pas d'ici, veuillez télécharger le programme d'installation et relancez-le.", + "STR_DEVICE":"Périphérique", + "STR_LOCAL_VER":"Ventoy en local", + "STR_DISK_VER":"Ventoy sur le périphérique", + "STR_STATUS":"État - prêt", + "STR_INSTALL":"Installation", + "STR_UPDATE":"Mise à jour", + "STR_UPDATE_TIP":"La mise à jour est sûre, les fichiers ISO ne seront pas modifiés.#@Continuer ?", + "STR_INSTALL_TIP":"Le disque va être formaté et toutes ses données seront perdues.#@Continuer ?", + "STR_INSTALL_TIP2":"Le disque va être formaté et toutes ses données seront perdues.#@Continuer ? (Confirmation)", + "STR_INSTALL_SUCCESS":"Félicitations !#@Ventoy a été correctement installé sur le périphérique.", + "STR_INSTALL_FAILED":"Une erreur est survenue durant l'installation. Vous pouvez rebrancher le périphérique et réessayer. Consultez le fichier log.txt pour plus de détails.", + "STR_UPDATE_SUCCESS":"Félicitations !#@Ventoy a été correctement mis à jour sur le périphérique.", + "STR_UPDATE_FAILED":"Une erreur est survenue durant la mise à jour. Vous pouvez rebrancher le périphérique et réessayer. Consultez le fichier log.txt pour plus de détails.", + "STR_WAIT_PROCESS":"Une opération est en cours, veuillez patienter...", + "STR_MENU_OPTION":"Option", + "STR_MENU_SECURE_BOOT":"Secure Boot", + "STR_MENU_PART_CFG":"Configuration des partitions", + "STR_BTN_OK":"Valider", + "STR_BTN_CANCEL":"Annuler", + "STR_PRESERVE_SPACE":"Réservez de l'espace à la fin du disque", + "STR_SPACE_VAL_INVALID":"Valeur de l'espace réservé invalide", + "STR_MENU_CLEAR":"Effacer Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy a été retiré du périphérique avec succès.", + "STR_CLEAR_FAILED":"Une erreur est survenue pendant la suppression de Ventoy. Vous pouvez rebrancher le périphérique et réessayer. Consultez le fichier log.txt pour plus de détails.", + "STR_MENU_PART_STYLE":"Type de partition", + "STR_DISK_2TB_MBR_ERROR":"Sélectionnez le type GPT pour les disques de plus de 2 To", + "STR_SHOW_ALL_DEV":"Afficher tous les périphériques", + "STR_PART_ALIGN_4KB":"Alignez les partitions sur 4 Ko", + "STR_WEB_COMMUNICATION_ERR":"Erreur de communication :", + "STR_WEB_REMOTE_ABNORMAL":"Erreur de communication : anomalie sur le serveur", + "STR_WEB_REQUEST_TIMEOUT":"Erreur de communication : délai d'attente dépassé", + "STR_WEB_SERVICE_UNAVAILABLE":"Erreur de communication : service inaccessible", + "STR_WEB_TOKEN_MISMATCH":"Statut du démon mis à jour, veuillez réessayer plus tard.", + "STR_WEB_SERVICE_BUSY":"Service surchargé, veuillez réessayer plus tard.", + "STR_MENU_VTSI_CREATE":"Générer un fichier VTSI", + "STR_VTSI_CREATE_TIP":"N'écrira pas sur le périphérique cette fois-ci, mais générera uniquement un fichier VTSI#@Continuer ?", + "STR_VTSI_CREATE_SUCCESS":"Fichier VTSI créé avec succès!#@Vous pouvez utiliser Rufus (3.15+) pour l'écrire sur le périphérique afin de terminer l'installation de Ventoy.", + "STR_VTSI_CREATE_FAILED":"La création du fichier VTSI a échoué.", + "STR_MENU_PART_RESIZE":"Installation non destructive", + "STR_PART_RESIZE_TIP":"Si possible, Ventoy essaiera une installation non destructive. #@Continuer ?", + "STR_PART_RESIZE_SUCCESS":"Félicitations !#@L'installation non destructive de Ventoy s'est terminée avec succès.", + "STR_PART_RESIZE_FAILED":"L'installation non destructive a échoué, consultez log.txt pour plus de détails.", + "STR_PART_RESIZE_UNSUPPORTED":"L'installation non destructive de Ventoy s'est arrêtée car certaines conditions ne peuvent pas être remplies. Consultez log.txt pour plus de détails.", + "STR_INSTALL_YES_TIP1":"Attention : les données seront perdues !", + "STR_INSTALL_YES_TIP2":"Veuillez saisir YES dans la zone de texte ci-dessous pour confirmer que vous souhaitez bien effectuer une nouvelle installation au lieu d'une mise à niveau.", + "STR_PART_VENTOY_FS":"Système de fichiers pour la partition Ventoy", + "STR_PART_FS":"Système de fichiers", + "STR_PART_CLUSTER":"Taille de cluster", + "STR_PART_CLUSTER_DEFAULT":"Valeur par défaut du système", + "STR_DONATE":"Faire un don", + "STR_4KN_UNSUPPORTED":"Actuellement, Ventoy ne prend pas en charge les appareils natifs 4K.", + + "STRXXX":"" + }, + { + "name":"Czech (Čeština)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"vavanade, lev741", + + "STR_ERROR":"Chyba", + "STR_WARNING":"Varování", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Spusťte Ventoy ve správném adresáři!", + "STR_INCORRECT_TREE_DIR":"Nespouštějte mě zde, stáhněte si prosím vydaný instalační balík a spusťte v něm.", + "STR_DEVICE":"Zařízení", + "STR_LOCAL_VER":"Ventoy v Balíčku", + "STR_DISK_VER":"Ventoy v Zařízení", + "STR_STATUS":"Status - PŘIPRAVENO", + "STR_INSTALL":"Instalovat", + "STR_UPDATE":"Aktualizovat", + "STR_UPDATE_TIP":"Operace aktualizace je bezpečná, ISO soubory nebudou změněny.#@Pokračovat?", + "STR_INSTALL_TIP":"Disk bude zformátován a všechna data budou ztracena!#@Pokračovat?", + "STR_INSTALL_TIP2":"Disk bude zformátován a všechna data budou ztracena!#@Pokračovat? (druhé potvrzení)", + "STR_INSTALL_SUCCESS":"Gratulujeme!#@Ventoy byla na zařízení úspěšně nainstalována.", + "STR_INSTALL_FAILED":"V průběhu instalace se vyskytla chyba. Můžete vyjmout a znovu zastrčit USB zařízení a zkusit to znovu. Pro podrobnosti se podívejte do souboru log.txt.", + "STR_UPDATE_SUCCESS":"Gratulujeme!#@Ventoy byla na zařízení úspěšně aktualizována.", + "STR_UPDATE_FAILED":"V průběhu aktualizace se vyskytla chyba. Můžete vyjmout a znovu zastrčit USB zařízení a zkusit to znovu. Pro podrobnosti se podívejte do souboru log.txt.", + "STR_WAIT_PROCESS":"Vlákno běží, prosíme vyčkejte...", + "STR_MENU_OPTION":"Možnosti", + "STR_MENU_SECURE_BOOT":"Podpora Secure Boot", + "STR_MENU_PART_CFG":"Konfigurace Oddílu", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Zrušit", + "STR_PRESERVE_SPACE":"Zachovejte místo na konci disku", + "STR_SPACE_VAL_INVALID":"Neplatná hodnota pro vyhrazený prostor", + "STR_MENU_CLEAR":"Odstranit Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy byl ze zařízení úspěšne odstraněn.", + "STR_CLEAR_FAILED":"Nastala chyba při odstraňovaní Ventoy z disku. Múžete USB vytáhnout a znova zastrčit a vyskoušet to znovu. Pro podrobnosti se podívejte do souboru log.txt", + "STR_MENU_PART_STYLE":"Styl Oddílu", + "STR_DISK_2TB_MBR_ERROR":"Vyberte GPT pro disk větší než 2TB", + "STR_SHOW_ALL_DEV":"Zobrazit všechna zařízení", + "STR_PART_ALIGN_4KB":"Zarovnat oddíly s velikostí 4KB", + "STR_WEB_COMMUNICATION_ERR":"Chyba komunikace:", + "STR_WEB_REMOTE_ABNORMAL":"Chyba komunikace: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Chyba komunikace: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Chyba komunikace: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status byl aktualizován, prosím vyskoušejte to později.", + "STR_WEB_SERVICE_BUSY":"Služba je zaneprázdnená, prosím vyskoušejte to později.", + "STR_MENU_VTSI_CREATE":"Vygenerovat VTSI Soubor", + "STR_VTSI_CREATE_TIP":"Tentokrát se do zařízení nebude zapisovat, jenom se vygeneruje VTSI soubor#@Pokračovat?", + "STR_VTSI_CREATE_SUCCESS":"VTSI soubor úspěšne vytvořen!#@Múžete použit Rufus(3.15+) na jeho zapsání do zařízení pro dokončení instalace Ventoy.", + "STR_VTSI_CREATE_FAILED":"Chyba při vytváření VTSI souboru.", + "STR_MENU_PART_RESIZE":"Nedestruktivní Instalace", + "STR_PART_RESIZE_TIP":"Ventoy se pokusí o nedestruktivní instalaci. #@Pokračovat?", + "STR_PART_RESIZE_SUCCESS":"Gratulujeme!#@Nedestruktivní instalace Ventoy byla úspěšně dokončena.", + "STR_PART_RESIZE_FAILED":"Nedestruktivní instalace selhala. Pro podrobnosti se podívejte do souboru log.txt.", + "STR_PART_RESIZE_UNSUPPORTED":"Nedestruktivní instalace Ventoy selhala, protože některé podmínky pro ni nemohly být splněny. Pro podrobnosti se podívejte do souboru log.txt.", + "STR_INSTALL_YES_TIP1":"Varování: Data budou ztracena!", + "STR_INSTALL_YES_TIP2":"Do níže uvedeného textového pole zadejte YES a potvrďte, že skutečně chcete provést novou instalaci namísto aktualizace.", + "STR_PART_VENTOY_FS":"Souborový systém pro Ventoy Partition", + "STR_PART_FS":"Souborový systém", + "STR_PART_CLUSTER":"Velikost clusteru", + "STR_PART_CLUSTER_DEFAULT":"Výchozí hodnota systému", + "STR_DONATE":"Darovat", + "STR_4KN_UNSUPPORTED":"Currently Ventoy does not support 4K native devices.", + + "STRXXX":"" + }, + { + "name":"Slovak (Slovenčina)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"reggiiie/jose1711", + + "STR_ERR":"Chyba", + "STR_WARNING":"Varovanie", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Spustite, prosím, v správnom adresári!", + "STR_INCORRECT_TREE_DIR":"Nespúšťajte ma tu, stiahnite si, prosím, vydaný inštalačný balík a spustite ma v ňom.", + "STR_DEVICE":"Zariadenie", + "STR_LOCAL_VER":"Ventoy v balíčku", + "STR_DISK_VER":"Ventoy v zariadení", + "STR_STATUS":"Stav - PRIPRAVENÝ", + "STR_INSTALL":"Inštalovať", + "STR_UPDATE":"Aktualizovať", + "STR_UPDATE_TIP":"Aktualizácia je bezpečná, ISO súbory zostanú nezmenené.#@Pokračovať?", + "STR_INSTALL_TIP":"Disk bude formátovaný a všetky údaje sa stratia!#@Pokračovať?", + "STR_INSTALL_TIP2":"Disk bude formátovaný a všetky údaje sa stratia!#@Pokračovať? (dvojitá kontrola)", + "STR_INSTALL_SUCCESS":"Gratulujeme!#@Ventoy bol úspešne nainštalovaný na zariadenie.", + "STR_INSTALL_FAILED":"V priebehu inštalácie sa vyskytla chyba. Môžete USB vytiahnuť, znova ho zasunúť a skúsiť to znovu. Podrobnosti nájdete v súbore log.txt. Ak sa chyba stále opakuje, skontrolujte, prosím, FAQ na oficiálnej stránke.", + "STR_UPDATE_SUCCESS":"Gratulujeme!#@Ventoy na zariadení bol úspešne aktualizovaný.", + "STR_UPDATE_FAILED":"V priebehu aktualizácie sa vyskytla chyba. Môžete USB vytiahnuť, znova ho zasunúť a skúsiť to znovu. Podrobnosti nájdete v súbore log.txt. Ak sa chyba stále opakuje, skontrolujte, prosím, FAQ na oficiálnej stránke.", + "STR_MENU_OPTION":"Možnosti", + "STR_MENU_SECURE_BOOT":"Podpora pre Secure Boot", + "STR_MENU_PART_CFG":"Konfigurácia oddielu", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Zrušiť", + "STR_PRESERVE_SPACE":"Zachovať nejaké miesto na konci disku", + "STR_SPACE_VAL_INVALID":"Neplatná hodnota pre vyhradený priestor", + "STR_MENU_CLEAR":"Vymazať Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy bol zo zariadenia úspešne odstránený.", + "STR_CLEAR_FAILED":"Nastala chyba pri odstraňovaní Ventoy z disku. Môžete USB vytiahnuť, znova ho zasunúť a skúsiť to znovu. Podrobnosti nájdete v súbore log.txt.", + "STR_MENU_PART_STYLE":"Štýl oddielu", + "STR_DISK_2TB_MBR_ERROR":"Prosím vyberte GPT pre disk väčší ako 2 TB", + "STR_SHOW_ALL_DEV":"Zobraziť všetky zariadenia", + "STR_PART_ALIGN_4KB":"Zarovnať oddiely na 4 KB", + "STR_WEB_COMMUNICATION_ERR":"Chyba komunikácie:", + "STR_WEB_REMOTE_ABNORMAL":"Chyba komunikácie: Chyba vzdialeného hostiteľa", + "STR_WEB_REQUEST_TIMEOUT":"Chyba komunikácie: Požiadavka vypršala", + "STR_WEB_SERVICE_UNAVAILABLE":"Chyba komunikácie: Služba je nedostupná", + "STR_WEB_TOKEN_MISMATCH":"Stav démona bol aktualizovaný, skúste to, prosím, neskôr.", + "STR_WEB_SERVICE_BUSY":"Služba je zaneprázdnená, skúste to, prosím, neskôr.", + "STR_MENU_VTSI_CREATE":"Vygenerovať VTSI Súbor", + "STR_VTSI_CREATE_TIP":"Tentokrát sa nebude na zariadenie zapisovať, len sa vygeneruje VTSI súbor#@Pokračovať?", + "STR_VTSI_CREATE_SUCCESS":"VTSI súbor bol úspešne vytvorený!#@Môžete použiť Rufus(3.15+) na jeho zapísanie na zariadenie, aby ste mohli dokončiť inštaláciu Ventoy.", + "STR_VTSI_CREATE_FAILED":"Chyba pri vytváraní VTSI súboru.", + "STR_MENU_PART_RESIZE":"Nedeštruktívna inštalácia", + "STR_PART_RESIZE_TIP":"Ventoy sa pokúsi o nedeštruktívnu inštaláciu. #@Pokračovať?", + "STR_PART_RESIZE_SUCCESS":"Gratulujeme!#@Nedeštruktívna inštalácia Ventoy bola úspešne dokončená.", + "STR_PART_RESIZE_FAILED":"Nedeštruktívna inštalácia zlyhala. Podrobnosti nájdete v súbore log.txt.", + "STR_PART_RESIZE_UNSUPPORTED":"Nedeštruktívna inštalácia Ventoy zlyhala, lebo niektoré podmienky nemohli byť splnené. Podrobnosti nájdete v súbore log.txt.", + "STR_INSTALL_YES_TIP1":"Varovanie: Dôjde k strate údajov!", + "STR_INSTALL_YES_TIP2":"Prosím, zadajte YES v textovom poli nižšie, čím potvrdíte, že naozaj chcete vykonať novú inštaláciu miesto aktualizácie.", + "STR_PART_VENTOY_FS":"File System For Ventoy Partition", + "STR_PART_FS":"File System", + "STR_PART_CLUSTER":"Cluster Size", + "STR_PART_CLUSTER_DEFAULT":"System Default Value", + "STR_DONATE":"Darovať", + "STR_4KN_UNSUPPORTED":"Currently Ventoy does not support 4K native devices.", + + "STRXXX":"" + }, + { + "name":"Spanish (Latinoamérica)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"MELERIX, independent-arg", + + "STR_ERROR":"Error", + "STR_WARNING":"Advertencia", + "STR_INFO":"Información", + "STR_INCORRECT_DIR":"¡Por favor, ejecuta el programa bajo el directorio correcto!", + "STR_INCORRECT_TREE_DIR":"No me ejecutes aquí. Por favor descarga el paquete de instalación oficial y ejecútalo desde allí.", + "STR_DEVICE":"Dispositivo", + "STR_LOCAL_VER":"Ventoy En Paquete", + "STR_DISK_VER":"Ventoy En Dispositivo", + "STR_STATUS":"Estado - LISTO", + "STR_INSTALL":"Instalar", + "STR_UPDATE":"Actualizar", + "STR_UPDATE_TIP":"La operación de actualización es segura, Los archivo ISO no se modificarán.#@¿Continuar?", + "STR_INSTALL_TIP":"El dispositivo será formateado y todos los datos se perderán.#@¿Continuar?", + "STR_INSTALL_TIP2":"El dispositivo será formateado y todos los datos se perderán.#@¿Continuar? (Doble Comprobación)", + "STR_INSTALL_SUCCESS":"¡Felicitaciones!#@Ventoy ha sido instalado exitosamente en el dispositivo.", + "STR_INSTALL_FAILED":"Ocurrió un error durante la instalación. Puedes reinsertar el dispositivo USB e intentar de nuevo. Comprueba log.txt para más detalles. Si siempre falla, consulta las preguntas frecuentes (FAQ) en el sitio web oficial.", + "STR_UPDATE_SUCCESS":"¡Felicitaciones!#@Ventoy ha sido actualizado exitosamente en el dispositivo.", + "STR_UPDATE_FAILED":"Ocurrió un error durante la actualización. Puedes reinsertar el dispositivo USB e intentar de nuevo. Comprueba log.txt para más detalles. Si siempre falla, consulta las preguntas frecuentes (FAQ) en el sitio web oficial.", + "STR_WAIT_PROCESS":"Un hilo del sistema está ejecutándose, por favor espera...", + "STR_MENU_OPTION":"Opción", + "STR_MENU_SECURE_BOOT":"Soporte de arranque seguro", + "STR_MENU_PART_CFG":"Configuración de partición", + "STR_BTN_OK":"Aceptar", + "STR_BTN_CANCEL":"Cancelar", + "STR_PRESERVE_SPACE":"Preservar algo de espacio al final del dispositivo", + "STR_SPACE_VAL_INVALID":"Valor inválido para el espacio reservado", + "STR_MENU_CLEAR":"Limpiar Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy ha sido eliminado exitosamente del dispositivo.", + "STR_CLEAR_FAILED":"Ocurrió un error al eliminar Ventoy del dispositivo. Puedes reinsertar el dispositivo USB e intentar de nuevo. Comprueba log.txt para más detalles.", + "STR_MENU_PART_STYLE":"Estilo de partición", + "STR_DISK_2TB_MBR_ERROR":"Por favor selecciona GPT para dispositivos de más de 2TB", + "STR_SHOW_ALL_DEV":"Mostrar todos los dispositivos", + "STR_PART_ALIGN_4KB":"Alinear particiones a 4KB", + "STR_WEB_COMMUNICATION_ERR":"Error de comunicación:", + "STR_WEB_REMOTE_ABNORMAL":"Error de comunicación: anomalía remoto", + "STR_WEB_REQUEST_TIMEOUT":"Error de comunicación: tiempo de espera agotado", + "STR_WEB_SERVICE_UNAVAILABLE":"Error de comunicación: servicio no disponible", + "STR_WEB_TOKEN_MISMATCH":" Estado del daemon actualizado, por favor reintenta más tarde.", + "STR_WEB_SERVICE_BUSY":" El servicio está ocupado, por favor reintenta más tarde.", + "STR_MENU_VTSI_CREATE":"Generar archivo VTSI", + "STR_VTSI_CREATE_TIP":"Esta acción no escribirá en el dispositivo, sólo generará un archivo VTSI.#@¿Continuar?", + "STR_VTSI_CREATE_SUCCESS":"¡Archivo VTSI creado exitosamente!#@Puedes usar Rufus(3.15+) para escribirlo al dispositivo a fin de completar la instalación de Ventoy.", + "STR_VTSI_CREATE_FAILED":"Error al crear el archivo VTSI.", + "STR_MENU_PART_RESIZE":"Instalación no destructiva", + "STR_PART_RESIZE_TIP":"Ventoy intentará una instalación no destructiva si es posible. #@¿Continuar?", + "STR_PART_RESIZE_SUCCESS":"¡Felicitaciones!#@La instalación no destructiva de Ventoy a finalizado exitosamente.", + "STR_PART_RESIZE_FAILED":"Instalación no destructiva fallida, Comprueba log.txt para detalles.", + "STR_PART_RESIZE_UNSUPPORTED":"Instalación no destructiva de Ventoy detenida porque algunas condiciones no se pueden cumplir. Comprueba log.txt para más detalles.", + "STR_INSTALL_YES_TIP1":"Advertencia: ¡Los datos se perderán!", + "STR_INSTALL_YES_TIP2":"Por favor ingresa YES en el cuadro de texto a continuación para confirmar que realmente quieres realizar una instalación nueva en vez de actualizar.", + "STR_PART_VENTOY_FS":"Sistema de archivos para partición de Ventoy", + "STR_PART_FS":"Sistema de archivos", + "STR_PART_CLUSTER":"Tamaño del clúster", + "STR_PART_CLUSTER_DEFAULT":"Valor predeterminado del sistema", + "STR_DONATE":"Donar", + "STR_4KN_UNSUPPORTED":"Actualmente Ventoy no es compatible con dispositivos nativos 4K.", + + "STRXXX":"" + }, + { + "name":"Spanish (España)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Carlos Sánchez, MELERIX, shulkalala", + + "STR_ERROR":"Error", + "STR_WARNING":"Advertencia", + "STR_INFO":"Información", + "STR_INCORRECT_DIR":"¡Por favor, ejecute Ventoy desde el directorio correcto!", + "STR_INCORRECT_TREE_DIR":"No inicie Ventoy aquí, descargue el paquete de instalación publicado y ejecútelo allí.", + "STR_DEVICE":"Dispositivo", + "STR_LOCAL_VER":"Ventoy en paquete", + "STR_DISK_VER":"Ventoy en dispositivo", + "STR_STATUS":"Estado - LISTO", + "STR_INSTALL":"Instalar", + "STR_UPDATE":"Actualizar", + "STR_UPDATE_TIP":"La operación de actualización es segura. Los archivos ISO no se modificarán.#@¿Continuar?", + "STR_INSTALL_TIP":"Se va a formatear el dispositivo y a perder todos sus datos.#@¿Continuar?", + "STR_INSTALL_TIP2":"Se va a formatear el dispositivo y a perder todos sus datos.#@¿Continuar? (Segunda confirmación)", + "STR_INSTALL_SUCCESS":"¡Enhorabuena!#@Ventoy se ha instalado correctamente en el dispositivo.", + "STR_INSTALL_FAILED":"Ocurrió un error durante la instalación. Puede reinsertar el dispositivo USB e intentarlo de nuevo.#@Compruebe el archivo log.txt para más información.#@Si la instalación no deja de fallar, consulte el apartado de preguntas frecuentes en el sitio web oficial.", + "STR_UPDATE_SUCCESS":"¡Enhorabuena!#@Ventoy se ha actualizado correctamente en el dispositivo.", + "STR_UPDATE_FAILED":"Ocurrió un error durante la actualización. Puede reinsertar el dispositivo USB e intentarlo de nuevo.#@Compruebe el archivo log.txt para más información.#@Si la instalación no deja de fallar, consulte el apartado de preguntas frecuentes en el sitio web oficial.", + "STR_WAIT_PROCESS":"Un hilo está ejecutándose, por favor espere...", + "STR_MENU_OPTION":"Opción", + "STR_MENU_SECURE_BOOT":"Soporte de arranque seguro", + "STR_MENU_PART_CFG":"Configuración de particiones", + "STR_BTN_OK":"Aceptar", + "STR_BTN_CANCEL":"Cancelar", + "STR_PRESERVE_SPACE":"Reservar espacio de almacenamiento al final del dispositivo", + "STR_SPACE_VAL_INVALID":"Valor inválido para el espacio reservado", + "STR_MENU_CLEAR":"Limpiar Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy se ha eliminado correctamente del dispositivo.", + "STR_CLEAR_FAILED":"Ocurrió un error al eliminar Ventoy del dispositivo. Puede reinsertar el dispositivo USB e intentarlo de nuevo.#@Compruebe el archivo log.txt para más información.", + "STR_MENU_PART_STYLE":"Estilo de partición", + "STR_DISK_2TB_MBR_ERROR":"Por favor, seleccione GPT para dispositivos con capacidad mayor de 2 TB", + "STR_SHOW_ALL_DEV":"Mostrar todos los dispositivos", + "STR_PART_ALIGN_4KB":"Alinear particiones a 4 KB", + "STR_WEB_COMMUNICATION_ERR":"Error de comunicación:", + "STR_WEB_REMOTE_ABNORMAL":"Error de comunicación: anormal remoto", + "STR_WEB_REQUEST_TIMEOUT":"Error de comunicación: tiempo de espera agotado", + "STR_WEB_SERVICE_UNAVAILABLE":"Error de comunicación: servicio no disponible", + "STR_WEB_TOKEN_MISMATCH":"Se ha actualizado el estado del servicio, por favor inténtelo de nuevo más tarde.", + "STR_WEB_SERVICE_BUSY":" El servicio está ocupado, por favor inténtelo de nuevo más tarde.", + "STR_MENU_VTSI_CREATE":"Generar archivo VTSI", + "STR_VTSI_CREATE_TIP":"Esta vez no se escribirá en el dispositivo, tan sólo se generará un archivo VTSI#@¿Continuar?", + "STR_VTSI_CREATE_SUCCESS":"¡El archivo VTSI se ha creado correctamente!#@Puede usar Rufus (3.15+) para escribirlo al dispositivo y completar la instalación de Ventoy.", + "STR_VTSI_CREATE_FAILED":"Se ha producido un error al intentar crear el archivo VTSI.", + "STR_MENU_PART_RESIZE":"Instalación no destructiva", + "STR_PART_RESIZE_TIP":"Ventoy intentará realizar una instalación no destructiva.#@¿Continuar?", + "STR_PART_RESIZE_SUCCESS":"¡Enhorabuena!#@La instalación no destructiva de Ventoy se ha completado correctamente.", + "STR_PART_RESIZE_FAILED":"La instalación no destructiva ha fallado.#@Compruebe el archivo log.txt para más información.", + "STR_PART_RESIZE_UNSUPPORTED":"La instalación no destructiva de Ventoy se ha detenido porque no se han cumplido todos los prerrequisitos.#@Compruebe el archivo log.txt para más información.", + "STR_INSTALL_YES_TIP1":"Advertencia: ¡Los datos se perderán!", + "STR_INSTALL_YES_TIP2":"Por favor, escriba YES en el cuadro de texto a continuación para confirmar que realmente quiere realizar una nueva instalación de Ventoy en vez de actualizarlo.", + "STR_PART_VENTOY_FS":"Sistema de archivos para partición de Ventoy", + "STR_PART_FS":"Sistema de archivos", + "STR_PART_CLUSTER":"Tamaño de cluster", + "STR_PART_CLUSTER_DEFAULT":"Valor predeterminado del sistema", + "STR_DONATE":"Donar", + "STR_4KN_UNSUPPORTED":"Currently Ventoy does not support 4K native devices.", + + "STRXXX":"" + }, + { + "name":"Russian (Русский)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Dmitry Yerokhin, BL4CKH47H4CK3R, Teraskull, thehugonote, wiz64, dmitrygribenchuk, Темак", + + "STR_ERROR":"Ошибка", + "STR_WARNING":"Внимание", + "STR_INFO":"Информация", + "STR_INCORRECT_DIR":"Запустите в другой папке!", + "STR_INCORRECT_TREE_DIR":"Не запускайте приложение здесь, загрузите установочный пакет и запустите его в другом месте.", + "STR_DEVICE":"Устройство", + "STR_LOCAL_VER":"Ventoy в пакете", + "STR_DISK_VER":"Ventoy на накопителе", + "STR_STATUS":"Состояние — ГОТОВ", + "STR_INSTALL":"Установить", + "STR_UPDATE":"Обновить", + "STR_UPDATE_TIP":"Обновление безопасно, ISO-образы останутся без изменений.#@Продолжить?", + "STR_INSTALL_TIP":"Это действие отформатирует накопитель, все данные на нём будут уничтожены.#@Продолжить?", + "STR_INSTALL_TIP2":"Это действие отформатирует накопитель, все данные на нём будут уничтожены.#@Вы действительно хотите продолжить?", + "STR_INSTALL_SUCCESS":"Поздравляем!#@Установка Ventoy на устройстве успешно выполнена.", + "STR_INSTALL_FAILED":"Ошибка при установке. Переподключите USB-накопитель и попробуйте снова. См. файл log.txt с подробностями. Если ошибка не исчезает, см. «FAQ» на официальном сайте.", + "STR_UPDATE_SUCCESS":"Поздравляем!#@Обновление Ventoy на устройстве успешно выполнено.", + "STR_UPDATE_FAILED":"Ошибка при обновлении Ventoy. Переподключите USB-накопитель и попробуйте снова. См. файл log.txt с подробностями. Если ошибка не исчезает, см. «FAQ» на официальном сайте.", + "STR_WAIT_PROCESS":"Действие запущено, подождите...", + "STR_MENU_OPTION":"Настройки", + "STR_MENU_SECURE_BOOT":"Поддержка Secure Boot", + "STR_MENU_PART_CFG":"Дополнительный раздел", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Отмена", + "STR_PRESERVE_SPACE":"Создать дополнительный раздел в конце накопителя", + "STR_SPACE_VAL_INVALID":"Недействительное значение размера раздела", + "STR_MENU_CLEAR":"Удалить Ventoy", + "STR_CLEAR_SUCCESS":"Удаление Ventoy с устройства успешно выполнено.", + "STR_CLEAR_FAILED":"Ошибка при удалении Ventoy. Переподключите USB-накопитель и попробуйте снова. См. файл log.txt с подробностями.", + "STR_MENU_PART_STYLE":"Стиль разметки разделов", + "STR_DISK_2TB_MBR_ERROR":"Для накопителей объёмом более 2 ТБ выберите GPT", + "STR_SHOW_ALL_DEV":"Показывать все устройства", + "STR_PART_ALIGN_4KB":"Выравнивать разделы с кластерами по 4 КБ", + "STR_WEB_COMMUNICATION_ERR":"Ошибка связи:", + "STR_WEB_REMOTE_ABNORMAL":"Ошибка связи: удалённое соединение недействительно", + "STR_WEB_REQUEST_TIMEOUT":"Ошибка связи: истекло время ожидания запроса", + "STR_WEB_SERVICE_UNAVAILABLE":"Ошибка связи: служба недоступна", + "STR_WEB_TOKEN_MISMATCH":"Состояние службы обновлено, повторите попытку позже.", + "STR_WEB_SERVICE_BUSY":"Служба занята, повторите попытку позже.", + "STR_MENU_VTSI_CREATE":"Создать файл .vtsi", + "STR_VTSI_CREATE_TIP":"Вместо установки Ventoy на накопитель будет создан только vtsi-файл.#@Продолжить?", + "STR_VTSI_CREATE_SUCCESS":"Файл .vtsi успешно создан.#@Вы можете записать его на накопитель с помощью приложения Rufus (v3.15+), чтобы завершить установку Ventoy.", + "STR_VTSI_CREATE_FAILED":"Ошибка создания vtsi-файла.", + "STR_MENU_PART_RESIZE":"Неразрушающая установка", + "STR_PART_RESIZE_TIP":"Ventoy попробует выполнить неразрушающую установку. #@Продолжить?", + "STR_PART_RESIZE_SUCCESS":"Поздравляем!#@Неразрушающая установка Ventoy успешно выполнена.", + "STR_PART_RESIZE_FAILED":"Не удалось выполнить неразрушающую установку, см. файл log.txt с подробностями.", + "STR_PART_RESIZE_UNSUPPORTED":"Неразрушающая установка Ventoy остановлена из-за несоответствия некоторым требованиям. См. файл log.txt с подробностями.", + "STR_INSTALL_YES_TIP1":"ВНИМАНИЕ: все данные будут потеряны!", + "STR_INSTALL_YES_TIP2":"Введите «YES» в текстовом поле ниже, чтобы подтвердить, что Вы действительно хотите выполнить новую установку, а не обновление.", + "STR_PART_VENTOY_FS":"Файловая система для раздела Ventoy", + "STR_PART_FS":"Тип:", + "STR_PART_CLUSTER":"Размер кластера:", + "STR_PART_CLUSTER_DEFAULT":"Системное значение по умолчанию", + "STR_DONATE":"Пожертвовать", + "STR_4KN_UNSUPPORTED":"В настоящее время Ventoy не поддерживает родные устройства 4K.", + + "STRXXX":"" + }, + { + "name":"Bengali (বাংলা)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"BL4CKH47H4CK3R, wiz64", + + "STR_ERROR":"ত্রুটি", + "STR_WARNING":"সতর্কতা", + "STR_INFO":"তথ্য", + "STR_INCORRECT_DIR":"দয়া করে সঠিক ডিরেক্টরিতে চালান!", + "STR_INCORRECT_TREE_DIR":"আমাকে এখানে চালাবেন না, দয়া করে প্রকাশিত ইনস্টল প্যাকেজটি ডাউনলোড করুন এবং সেখানে চালান।", + "STR_DEVICE":"ডিভাইস", + "STR_LOCAL_VER":"Ventoy প্যাকেজে আছে", + "STR_DISK_VER":"Ventoy ডিভাইসে আছে", + "STR_STATUS":"স্থিতি - প্রস্তুত", + "STR_INSTALL":"ইনস্টল করুন", + "STR_UPDATE":"আপডেট করুন", + "STR_UPDATE_TIP":"আপগ্রেড অপারেশন নিরাপদ, ISO ফাইলগুলি অপরিবর্তিত থাকবে।#@চালিয়ে যাবেন?", + "STR_INSTALL_TIP":"ডিস্কটি ফর্ম্যাট করা হবে এবং সমস্ত ডেটা হারিয়ে যাবে।#@চালিয়ে যাবেন?", + "STR_INSTALL_TIP2":"ডিস্কটি ফর্ম্যাট করা হবে এবং সমস্ত ডেটা হারিয়ে যাবে।#@চালিয়ে যাবেন? (পুনঃনিরীক্ষণ)", + "STR_INSTALL_SUCCESS":"অভিনন্দন! #@Ventoy সফলভাবে ডিভাইসে ইনস্টল করা হয়েছে।", + "STR_INSTALL_FAILED":"ইনস্টলেশন চলাকালীন একটি ত্রুটি ঘটেছে। আপনি USB পুনরায় প্লাগ করতে পারেন এবং আবার চেষ্টা করতে পারেন। বিস্তারিত জানার জন্য log.txt পরীক্ষা করুন।", + "STR_UPDATE_SUCCESS":"অভিনন্দন! #@Ventoy সফলভাবে ডিভাইসে আপডেট করা হয়েছে।", + "STR_UPDATE_FAILED":"আপডেটের সময় একটি ত্রুটি ঘটেছে। আপনি USB পুনরায় প্লাগ করতে পারেন এবং আবার চেষ্টা করতে পারেন। বিস্তারিত জানার জন্য log.txt পরীক্ষা করুন।", + "STR_WAIT_PROCESS":"একটি থ্রেড চলছে, দয়া করে অপেক্ষা করুন ...", + "STR_MENU_OPTION":"অপসন", + "STR_MENU_SECURE_BOOT":"নিরাপদ বুট", + "STR_MENU_PART_CFG":"পার্টিশন কনফিগারেশন", + "STR_BTN_OK":"ঠিক আছে", + "STR_BTN_CANCEL":"বাতিল", + "STR_PRESERVE_SPACE":"ডিস্কের নীচে কিছু স্থান সংরক্ষণ করুন", + "STR_SPACE_VAL_INVALID":"সংরক্ষিত জায়গার জন্য অবৈধ মান", + "STR_MENU_CLEAR":"Ventoy সাফ", + "STR_CLEAR_SUCCESS":"Ventoy সফলভাবে ডিভাইস থেকে সরানো হয়েছে।", + "STR_CLEAR_FAILED":"ডিস্ক থেকে Ventoy সাফ করার সময় একটি ত্রুটি ঘটেছে। আপনি USB পুনরায় প্লাগ করতে পারেন এবং আবার চেষ্টা করতে পারেন। বিস্তারিত জানার জন্য log.txt পরীক্ষা করুন।", + "STR_MENU_PART_STYLE":"পার্টিশন স্টাইল", + "STR_DISK_2TB_MBR_ERROR":"2TB এর বেশি ডিস্কের জন্য দয়া করে GPT নির্বাচন করুন", + "STR_SHOW_ALL_DEV":"সমস্ত ডিভাইস দেখান", + "STR_PART_ALIGN_4KB":"4KB দিয়ে পার্টিশন সারিবদ্ধ করুন", + "STR_WEB_COMMUNICATION_ERR":"যোগাযোগে ত্রুটি:", + "STR_WEB_REMOTE_ABNORMAL":"যোগাযোগ ত্রুটি: দূরবর্তী অস্বাভাবিক", + "STR_WEB_REQUEST_TIMEOUT":"যোগাযোগ ত্রুটি: অনুরোধের সময় শেষ হয়েছে৷", + "STR_WEB_SERVICE_UNAVAILABLE":"যোগাযোগ ত্রুটি: পরিষেবা অনুপলব্ধ৷", + "STR_WEB_TOKEN_MISMATCH":"ডেমন স্ট্যাটাস আপডেট হয়েছে, অনুগ্রহ করে পরে আবার চেষ্টা করুন।", + "STR_WEB_SERVICE_BUSY":"পরিষেবা ব্যস্ত, পরে আবার চেষ্টা করুন।", + "STR_MENU_VTSI_CREATE":"VTSI ফাইল তৈরি করুন", + "STR_VTSI_CREATE_TIP":"এই সময় ডিভাইসে লিখবেন না, তবে শুধুমাত্র একটি VTSI ফাইল তৈরি করবেন#@চালিয়ে যান?", + "STR_VTSI_CREATE_SUCCESS":"VTSI ফাইলটি সফলভাবে তৈরি হয়েছে!#@ আপনি Rufus(3.15+) ব্যবহার করে এটিকে ডিভাইসে লিখতে পারেন যাতে Ventoy-এর ইনস্টলেশন সম্পূর্ণ করা যায়।", + "STR_VTSI_CREATE_FAILED":"VTSI ফাইল তৈরি করা ব্যর্থ হয়েছে৷", + "STR_MENU_PART_RESIZE":"অ-ধ্বংসাত্মক ইনস্টল", + "STR_PART_RESIZE_TIP":"Ventoy সম্ভব হলে অ-ধ্বংসাত্মক ইনস্টলেশন চেষ্টা করবে। #@চালিয়ে যান?", + "STR_PART_RESIZE_SUCCESS":"অভিনন্দন!#@Ventoy অ-ধ্বংসাত্মক ইনস্টলেশন সফলভাবে শেষ হয়েছে।", + "STR_PART_RESIZE_FAILED":"অ-ধ্বংসাত্মক ইনস্টলেশন ব্যর্থ হয়েছে, বিস্তারিত জানার জন্য log.txt চেক করুন।", + "STR_PART_RESIZE_UNSUPPORTED":"Ventoy অ-ধ্বংসাত্মক ইনস্টলেশন বন্ধ করা হয়েছে কারণ কিছু শর্ত পূরণ করা যাবে না। বিস্তারিত জানার জন্য log.txt দেখুন।", + "STR_INSTALL_YES_TIP1":"সতর্কতা: ডেটা হারিয়ে যাবে!", + "STR_INSTALL_YES_TIP2":"আপনি আপগ্রেড করার পরিবর্তে একটি নতুন ইনস্টল করতে চান তা নিশ্চিত করতে দয়া করে নীচের পাঠ্য বাক্সে Yes লিখুন৷।", + "STR_PART_VENTOY_FS":"Ventoy পার্টিশনের জন্য ফাইল সিস্টেম", + "STR_PART_FS":"ফাইল সিস্টেম", + "STR_PART_CLUSTER":"ক্লাস্টারের আকার", + "STR_PART_CLUSTER_DEFAULT":"সিস্টেমের ডিফল্ট মান", + "STR_DONATE":"দান করুন", + "STR_4KN_UNSUPPORTED":"বর্তমানে Ventoy 4K নেটিভ ডিভাইস সমর্থন করে না।", + + "STRXXX":"" + }, + { + "name":"Hindi (हिन्दी)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"BL4CKH47H4CK3R, wiz64", + + "STR_ERROR":"त्रुटि", + "STR_WARNING":"चेतावनी", + "STR_INFO":"जानकारी", + "STR_INCORRECT_DIR":"कृपया सही निर्देशिका के तहत चलाएं!", + "STR_INCORRECT_TREE_DIR":"मुझे यहां न चलाएं, कृपया जारी किए गए इंस्टॉल पैकेज को डाउनलोड करें, और वहां चलाएं।", + "STR_DEVICE":"डिवाइस", + "STR_LOCAL_VER":"पैकेज में Ventoy", + "STR_DISK_VER":"डिवाइस में Ventoy", + "STR_STATUS":"स्थिति - तैयार", + "STR_INSTALL":"इंस्टॉल", + "STR_UPDATE":"अपडेट करें", + "STR_UPDATE_TIP":"नवीनीकरण ऑपरेशन सुरक्षित है, ISO फाइल अपरिवर्तित रहेंगी।#@जारी रखें?", + "STR_INSTALL_TIP":"डिस्क को स्वरूपित किया जाएगा और सभी डेटा खो जाएगा।#@जारी रखें?", + "STR_INSTALL_TIP2":"डिस्क को स्वरूपित किया जाएगा और सभी डेटा खो जाएगा।#@जारी रखें? (दोहरी जाँच)", + "STR_INSTALL_SUCCESS":"बधाई! #@Ventoy डिवाइस में सफलतापूर्वक स्थापित किया गया है।", + "STR_INSTALL_FAILED":"स्थापना के दौरान एक त्रुटि हुई। आप USB को पुन: स्थापित कर सकते हैं और पुनः प्रयास कर सकते हैं। विस्तार के लिए log.txt की जाँच करें।", + "STR_UPDATE_SUCCESS":"बधाई! #@Ventoy डिवाइस में सफलतापूर्वक अपडेट हो गई है।", + "STR_UPDATE_FAILED":"अपडेट के दौरान एक त्रुटि हुई। आप USB को पुन: भर सकते हैं और पुनः प्रयास कर सकते हैं। विस्तार के लिए log.txt की जाँच करें।", + "STR_WAIT_PROCESS":"एक धागा चल रहा है, कृपया प्रतीक्षा करें ...", + "STR_MENU_OPTION":"विकल्प", + "STR_MENU_SECURE_BOOT":"सुरक्षित बूट", + "STR_MENU_PART_CFG":"विभाजन विन्यास", + "STR_BTN_OK":"ठीक है", + "STR_BTN_CANCEL":"रद्द करना", + "STR_PRESERVE_SPACE":"डिस्क के निचले भाग में कुछ स्थान सुरक्षित रखें", + "STR_SPACE_VAL_INVALID":"आरक्षित स्थान के लिए अमान्य मान", + "STR_MENU_CLEAR":"Ventoy को हटा दें", + "STR_CLEAR_SUCCESS":"डिवाइस से Ventoy को सफलतापूर्वक हटा दिया गया है।", + "STR_CLEAR_FAILED":"डिस्क से Ventoy को साफ़ करते समय एक त्रुटि हुई। आप USB को पुन: भर सकते हैं और पुनः प्रयास कर सकते हैं। विस्तार के लिए log.txt की जाँच करें।", + "STR_MENU_PART_STYLE":"विभाजन शैली", + "STR_DISK_2TB_MBR_ERROR":"कृपया 2TB से अधिक डिस्क के लिए GPT का चयन करें", + "STR_SHOW_ALL_DEV":"सभी डिवाइस दिखाएं", + "STR_PART_ALIGN_4KB":"4KB के साथ partitions संरेखित करें", + "STR_WEB_COMMUNICATION_ERR":"संपर्क त्रुटि:", + "STR_WEB_REMOTE_ABNORMAL":"संचार त्रुटि: remote असामान्य", + "STR_WEB_REQUEST_TIMEOUT":"संचार त्रुटि: अनुरोध समयबाह्य (request timeout)", + "STR_WEB_SERVICE_UNAVAILABLE":"संचार त्रुटि: सेवा अनुपलब्ध", + "STR_WEB_TOKEN_MISMATCH":"Daemon की स्थिति अपडेट की गई, कृपया बाद में पुन: प्रयास करें।", + "STR_WEB_SERVICE_BUSY":"सेवा व्यस्त है, कृपया बाद में पुनः प्रयास करें।", + "STR_MENU_VTSI_CREATE":"VTSI File उत्पन्न करें", + "STR_VTSI_CREATE_TIP":"इस बार डिवाइस पर नहीं लिखा जाएगा, लेकिन केवल एक VTSI File उत्पन्न होगी#@जारी रखें?", + "STR_VTSI_CREATE_SUCCESS":"VTSI फ़ाइल सफलतापूर्वक बनाई गई!#@ आप इसे डिवाइस पर लिखने के लिए Rufus(3.15+) का उपयोग कर सकते हैं ताकि Ventoy की स्थापना को पूरा किया जा सके।", + "STR_VTSI_CREATE_FAILED":"बनाई गई VTSI file विफल रही।", + "STR_MENU_PART_RESIZE":"गैर-विनाशकारी इंस्टॉल", + "STR_PART_RESIZE_TIP":"यदि संभव हो तो Ventoy गैर-विनाशकारी स्थापना का प्रयास करेगा। #@जारी रखना?", + "STR_PART_RESIZE_SUCCESS":"बधाई हो!#@Ventoy गैर-विनाशकारी स्थापना सफलतापूर्वक समाप्त हो गई।", + "STR_PART_RESIZE_FAILED":"गैर-विनाशकारी स्थापना विफल, विवरण के लिए log.txt की जाँच करें।", + "STR_PART_RESIZE_UNSUPPORTED":"वेंटोय गैर-विनाशकारी स्थापना रोक दी गई, कुछ शर्तों को पूरा नहीं किया जा सकता है। विवरण के लिए log.txt की जाँच करें।", + "STR_INSTALL_YES_TIP1":"चेतावनी: डेटा खो जाएगा!", + "STR_INSTALL_YES_TIP2":"यह पुष्टि करने के लिए कि आप वास्तव में अपग्रेड के बजाय एक नया इंस्टॉल करना चाहते हैं, कृपया नीचे दिए टेक्स्ट बॉक्स में Yes दर्ज करें।", + "STR_PART_VENTOY_FS":"Ventoy विभाजन के लिए फाइल सिस्टम", + "STR_PART_FS":"फाइल सिस्टम", + "STR_PART_CLUSTER":"क्लस्टर साइज", + "STR_PART_CLUSTER_DEFAULT":"सिस्टम डिफ़ॉल्ट मान", + "STR_DONATE":"दान करें", + "STR_4KN_UNSUPPORTED":"वर्तमान में Ventoy 4K नेटिव डिवाइस को सपोर्ट नहीं करता है।", + + "STRXXX":"" + }, + { + "name":"Dutch (Nederlands)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"UmitCanbolat, RockyTDR", + + "STR_ERROR":"Fout", + "STR_WARNING":"Waarschuwing", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Voer Ventoy uit in de juiste map!", + "STR_INCORRECT_TREE_DIR":"Ventoy kan hier niet worden uitgevoerd. Download het installatiepakket en probeer Ventoy daarmee te starten.", + "STR_DEVICE":"Apparaat", + "STR_LOCAL_VER":"Ventoy in pakket", + "STR_DISK_VER":"Ventoy op apparaat", + "STR_STATUS":"Status - KLAAR", + "STR_INSTALL":"Installeren", + "STR_UPDATE":"Bijwerken", + "STR_UPDATE_TIP":"Bijwerken is veilig: ISO-bestanden blijven ongewijzigd.#@Doorgaan?", + "STR_INSTALL_TIP":"Het apparaat wordt geformatteerd en alle gegevens gaan verloren.#@Doorgaan?", + "STR_INSTALL_TIP2":"Het apparaat wordt geformatteerd en alle gegevens gaan verloren.#@Doorgaan? (Dubbelcheck)", + "STR_INSTALL_SUCCESS":"Gefeliciteerd!#@Ventoy is met succes op het apparaat geïnstalleerd.", + "STR_INSTALL_FAILED":"Er is een fout opgetreden tijdens de installatie. U kunt het USB-apparaat opnieuw aansluiten en het nogmaals proberen. Controleer log.txt voor details. Raadpleeg de FAQ op de officiële website als het blijft mislukken.", + "STR_UPDATE_SUCCESS":"Gefeliciteerd!#@Ventoy is met succes bijgewerkt op het apparaat.", + "STR_UPDATE_FAILED":"Er is een fout opgetreden tijdens de update. U kunt het USB-apparaat opnieuw aansluiten en het nogmaals proberen. Controleer log.txt voor details. Raadpleeg de FAQ op de officiële website als het blijft mislukken.", + "STR_WAIT_PROCESS":"Ventoy is nog bezig, even geduld...", + "STR_MENU_OPTION":"Opties", + "STR_MENU_SECURE_BOOT":"Ondersteuning voor Secure Boot", + "STR_MENU_PART_CFG":"Partitieconfiguratie", + "STR_BTN_OK":"Ok", + "STR_BTN_CANCEL":"Annuleren", + "STR_PRESERVE_SPACE":"Ruimte aan het einde van de schijf reserveren", + "STR_SPACE_VAL_INVALID":"Ongeldige waarde voor gereserveerde ruimte", + "STR_MENU_CLEAR":"Ventoy verwijderen", + "STR_CLEAR_SUCCESS":"Ventoy is met succes verwijderd van het apparaat.", + "STR_CLEAR_FAILED":"Er is een fout opgetreden bij het verwijderen van Ventoy. U kunt het USB-apparaat opnieuw aansluiten en het nogmaals proberen. Controleer log.txt voor details.", + "STR_MENU_PART_STYLE":"Partitietabel", + "STR_DISK_2TB_MBR_ERROR":"Selecteer GPT voor apparaten groter dan 2 TB", + "STR_SHOW_ALL_DEV":"Alle apparaten weergeven", + "STR_PART_ALIGN_4KB":"Partities uitlijnen met 4 KB", + "STR_WEB_COMMUNICATION_ERR":"Communicatiefout:", + "STR_WEB_REMOTE_ABNORMAL":"Communicatiefout: extern abnormaal", + "STR_WEB_REQUEST_TIMEOUT":"Communicatiefout: time-out van verzoek", + "STR_WEB_SERVICE_UNAVAILABLE":"Communicatiefout: service niet beschikbaar", + "STR_WEB_TOKEN_MISMATCH":"Daemon-status bijgewerkt, probeer het later opnieuw.", + "STR_WEB_SERVICE_BUSY":"Service is bezet. Probeer het later opnieuw.", + "STR_MENU_VTSI_CREATE":"VTSI-bestand genereren", + "STR_VTSI_CREATE_TIP":"Deze keer wordt er niet naar het apparaat geschreven, maar wordt er alleen een VTSI-bestand gegenereerd#@Doorgaan?", + "STR_VTSI_CREATE_SUCCESS":"VTSI-bestand met succes aangemaakt!#@U kunt Rufus(3.15+) gebruiken om het bestand naar het apparaat te schrijven om de installatie van Ventoy te voltooien.", + "STR_VTSI_CREATE_FAILED":"Aanmaken van VTSI-bestand mislukt.", + "STR_MENU_PART_RESIZE":"Niet-destructieve installatie", + "STR_PART_RESIZE_TIP":"Ventoy zal indien mogelijk een niet-destructieve installatie proberen. #@Doorgaan?", + "STR_PART_RESIZE_SUCCESS":"Gefeliciteerd!#@De niet-destructieve installatie van Ventoy is met succes voltooid.", + "STR_PART_RESIZE_FAILED":"Niet-destructieve installatie mislukt. Controleer log.txt voor details.", + "STR_PART_RESIZE_UNSUPPORTED":"De niet-destructieve installatie van Ventoy is gestopt omdat aan sommige voorwaarden niet kan worden voldaan. Controleer log.txt voor details.", + "STR_INSTALL_YES_TIP1":"Waarschuwing: alle gegevens zullen verloren gaan!", + "STR_INSTALL_YES_TIP2":"Vul in het onderstaande tekstvak YES in om te bevestigen dat u inderdaad een nieuwe installatie wilt uitvoeren in plaats van een upgrade.", + "STR_PART_VENTOY_FS":"Bestandssysteem voor Ventoy-partitie", + "STR_PART_FS":"Bestandssysteem", + "STR_PART_CLUSTER":"Clustergrootte", + "STR_PART_CLUSTER_DEFAULT":"Standaardwaarde systeem", + "STR_DONATE":"Doneer", + "STR_4KN_UNSUPPORTED":"Currently Ventoy does not support 4K native devices.", + + "STRXXX":"" + }, + { + "name":"Romanian (Română)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"DorinMol, cezarlacatus, wiz64", + + "STR_ERROR":"Eroare", + "STR_WARNING":"Avertisment", + "STR_INFO":"Informare", + "STR_INCORRECT_DIR":"Vă rugăm executați în directorul corect!", + "STR_INCORRECT_TREE_DIR":"Nu rulați aici, vă rugăm să descărcați pachetul de instalare și executati acolo.", + "STR_DEVICE":"Dispozitiv", + "STR_LOCAL_VER":"Ventoy În Pachet", + "STR_DISK_VER":"Ventoy În Dispozitiv", + "STR_STATUS":"Stare - PREGĂTIT", + "STR_INSTALL":"Instalare", + "STR_UPDATE":"Actualizare", + "STR_UPDATE_TIP":"Operația de actualizare este sigură, fișierele ISO nu vor fi alterate / modificate.#@Continuați?", + "STR_INSTALL_TIP":"Unitatea disc va fi formatată și toate datele vor fi pierdute.#@Continuați?", + "STR_INSTALL_TIP2":"Unitatea disc va fi formatată și toate datele vor fi pierdute.#@Continuați? (Verificare Dublă)", + "STR_INSTALL_SUCCESS":"Felicitări!#@Ventoy a fost instalat cu succes pe dispozitiv.", + "STR_INSTALL_FAILED":"A apărut o eroare în timpul instalării. Reintroduceți dispozitivul USB și încercați din nou. Verificați log.txt pentru detalii.", + "STR_UPDATE_SUCCESS":"Felicitări!#@Ventoy a fost actualizat cu succes pe dispozitiv.", + "STR_UPDATE_FAILED":"A apărut o eroare în timpul actualizării. Reintroduceți dispozitivul USB și încercați din nou. Verificați log.txt pentru detalii.", + "STR_WAIT_PROCESS":"Rulează un fir de execuție, vă rugăm așteptați...", + "STR_MENU_OPTION":"Opțiune", + "STR_MENU_SECURE_BOOT":"Încărcare Sigură", + "STR_MENU_PART_CFG":"Configurare partiție", + "STR_BTN_OK":"O.K", + "STR_BTN_CANCEL":"Anulare", + "STR_PRESERVE_SPACE":"Păstrați puțin spațiu în partea de jos a discului", + "STR_SPACE_VAL_INVALID":"Valoare nevalidă pentru spațiul rezervat", + "STR_MENU_CLEAR":"Curata Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy a fost eliminat cu succes de pe dispozitiv.", + "STR_CLEAR_FAILED":"A apărut o eroare la ștergerea Ventoy de pe disc. Puteți reconecta USB-ul și încerca din nou. Verificați log.txt pentru detalii.", + "STR_MENU_PART_STYLE":"Stil partiție", + "STR_DISK_2TB_MBR_ERROR":"Vă rugăm să selectați GPT pentru disc de peste 2 TB", + "STR_SHOW_ALL_DEV":"Afișați toate dispozitivele", + "STR_PART_ALIGN_4KB":"Aliniați partițiile cu 4KB", + "STR_WEB_COMMUNICATION_ERR":"Eroare de comunicare:", + "STR_WEB_REMOTE_ABNORMAL":"Eroare de comunicare: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Eroare de comunicare: Solicitarea a expirat", + "STR_WEB_SERVICE_UNAVAILABLE":"Eroare de comunicare: Serviciu indisponibil", + "STR_WEB_TOKEN_MISMATCH":"Starea demonului a fost actualizată, vă rugăm să reîncercați mai târziu.", + "STR_WEB_SERVICE_BUSY":"Serviciul este ocupat, vă rugăm să reîncercați mai târziu.", + "STR_MENU_VTSI_CREATE":"Generați fișierul VTSI", + "STR_VTSI_CREATE_TIP":"De data aceasta nu va scrie pe dispozitiv, ci va genera doar un fișier VTSI#@Continuați?", + "STR_VTSI_CREATE_SUCCESS":"Fișierul VTSI creat cu succes!#@Puteți folosi Rufus(3.15+) pentru a-l scrie pe dispozitiv, astfel încât să finalizați instalarea Ventoy.", + "STR_VTSI_CREATE_FAILED":"Fișierul VTSI creat a eșuat.", + "STR_MENU_PART_RESIZE":"Instalare nedistructivă", + "STR_PART_RESIZE_TIP":"Ventoy va încerca instalarea nedistructivă, dacă este posibil. #@Continuă?", + "STR_PART_RESIZE_SUCCESS":"Felicitări!#@Ventoy instalarea nedistructivă s-a încheiat cu succes.", + "STR_PART_RESIZE_FAILED":"Instalarea nedistructivă a eșuat. Verificați log.txt pentru detalii.", + "STR_PART_RESIZE_UNSUPPORTED":"Instalarea nedistructivă Ventoy a fost oprită deoarece unele condiții nu pot fi îndeplinite. Verificați log.txt pentru detalii.", + "STR_INSTALL_YES_TIP1":"Atenție: Datele se vor pierde!", + "STR_INSTALL_YES_TIP2":"Introduceți DA în caseta de text de mai jos pentru a confirma că într-adevăr doriți să faceți o nouă instalare în loc să faceți upgrade.", + "STR_PART_VENTOY_FS":"Sistem de fișiere pentru partiția Ventoy", + "STR_PART_FS":"Sistemul de fișiere", + "STR_PART_CLUSTER":"Dimensiunea clusterului", + "STR_PART_CLUSTER_DEFAULT":"Valoarea implicită a sistemului", + "STR_DONATE":"Donează", + "STR_4KN_UNSUPPORTED":"Momentan, Ventoy nu suporta dispozitive native 4k.", + + "STRXXX":"" + }, + { + "name":"Japanese (日本語)", + "FontFamily":"Yu Gothic UI", + "FontSize":16, + "Author":"taichi eto, Bentnand, cmplstofB, Re*Index.(ot_inc)", + + "STR_ERROR":"エラー", + "STR_WARNING":"警告", + "STR_INFO":"情報", + "STR_INCORRECT_DIR":"正しいディレクトリで実行してください!", + "STR_INCORRECT_TREE_DIR":"ここで実行をしないでください。リリースされたインストールパッケージをダウンロードして、実行をしてください。", + "STR_DEVICE":"デバイス", + "STR_LOCAL_VER":"パッケージ内のVentoy", + "STR_DISK_VER":"デバイス内のVentoy", + "STR_STATUS":"状態 - 準備完了", + "STR_INSTALL":"インストール", + "STR_UPDATE":"アップデート", + "STR_UPDATE_TIP":"アップグレードの操作は安全に行なわれ、ISOファイルは変更もされません。#@続行しますか?", + "STR_INSTALL_TIP":"デバイスはフォーマットされ、すべてのデータが失われます。#@続行しますか?", + "STR_INSTALL_TIP2":"デバイスはフォーマットされ、すべてのデータが失われます。#@続行しますか? (再確認)", + "STR_INSTALL_SUCCESS":"おめでとうございます!#@Ventoyがデバイスにインストールされました。", + "STR_INSTALL_FAILED":"インストール中にエラーが発生しました。USBデバイスを再接続をして再試行ができます。詳細については、log.txtを確認してください。何度も失敗する場合は、公式サイト内のFAQをご参照ください。", + "STR_UPDATE_SUCCESS":"おめでとうございます!#@Ventoyがデバイスで正常にアップデートされました。", + "STR_UPDATE_FAILED":"アップデート中にエラーが発生しました。USBデバイスを再接続して再試行ができます。詳細については、log.txtを確認してください。何度も失敗する場合は、公式サイトのFAQをご参照ください。", + "STR_WAIT_PROCESS":"スレッドが実行中です。お待ちください...", + "STR_MENU_OPTION":"オプション", + "STR_MENU_SECURE_BOOT":"セキュアブートのサポート", + "STR_MENU_PART_CFG":"パーティションの設定", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"キャンセル", + "STR_PRESERVE_SPACE":"ディスクの最後にある程度の容量を確保する", + "STR_SPACE_VAL_INVALID":"システム予約済みパーティションの値が無効です", + "STR_MENU_CLEAR":"Ventoyを削除する", + "STR_CLEAR_SUCCESS":"Ventoyがデバイスから正常に削除されました。", + "STR_CLEAR_FAILED":"Ventoyをディスクから削除するときにエラーが発生しました。USBデバイスを再接続して再試行ができます。詳細については、log.txtを確認してください。", + "STR_MENU_PART_STYLE":"パーティションのスタイル", + "STR_DISK_2TB_MBR_ERROR":"2TBを超えるデバイスの場合はGPTを選択してください", + "STR_SHOW_ALL_DEV":"すべてのデバイスを表示", + "STR_PART_ALIGN_4KB":"パーティションを4KBに揃える", + "STR_WEB_COMMUNICATION_ERR":"コミュニケーションエラー:", + "STR_WEB_REMOTE_ABNORMAL":"コミュニケーションエラー: リモート先が異常になっています", + "STR_WEB_REQUEST_TIMEOUT":"コミュニケーションエラー: リクエストがタイムアウトしました", + "STR_WEB_SERVICE_UNAVAILABLE":"コミュニケーションエラー: サービスが利用できません", + "STR_WEB_TOKEN_MISMATCH":"デーモンのステータスが更新されました。後で再試行してください。", + "STR_WEB_SERVICE_BUSY":"サービスがビジーの状態です。後で再試行してください。", + "STR_MENU_VTSI_CREATE":"VTSIファイルを作成する", + "STR_VTSI_CREATE_TIP":"今回はデバイスへの書き込みを行なわず、VTSIファイルの作成のみを行ないます。#@続行しますか?", + "STR_VTSI_CREATE_SUCCESS":"VTSIファイルが正常に作成されました!#@Rufus(3.15以降)を使用してデバイスに書き込むことでVentoyのインストールが完了します。", + "STR_VTSI_CREATE_FAILED":"VTSIファイルの作成に失敗しました。", + "STR_MENU_PART_RESIZE":"非破壊なインストール", + "STR_PART_RESIZE_TIP":"Ventoyは、可能であれば非破壊なインストールを試みます。#@続行しますか?", + "STR_PART_RESIZE_SUCCESS":"おめでとうございます!#@Ventoyの非破壊なインストールが正常に完了しました。", + "STR_PART_RESIZE_FAILED":"非破壊なインストールが失敗しました。詳細については、log.txtを確認してください。", + "STR_PART_RESIZE_UNSUPPORTED":"いくつかの条件を満たしていないため、Ventoyの非破壊なインストールは停止されました。詳細については、log.txtを確認してください。", + "STR_INSTALL_YES_TIP1":"警告: データが失われます!", + "STR_INSTALL_YES_TIP2":"アップグレードではなく新規インストールを実行するには、下のテキストボックスに「YES」と入力してください。", + "STR_PART_VENTOY_FS":"Ventoyパーティションのファイルシステム", + "STR_PART_FS":"ファイルシステム", + "STR_PART_CLUSTER":"クラスタサイズ", + "STR_PART_CLUSTER_DEFAULT":"システムの既定値", + "STR_DONATE":"寄付", + "STR_4KN_UNSUPPORTED":"現在、Ventoyは4Kネイティブデバイスをサポートしていません。", + + "STRXXX":"" + }, + { + "name":"Italian (Italiano)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"AverageUser2,Albano Battistella,bovirus,passero", + + "STR_ERROR":"Errore", + "STR_WARNING":"Attenzione", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Eseguilo nella cartella corretta", + "STR_INCORRECT_TREE_DIR":"Non eseguirlo qui.#@Scarica il pacchetto di installazione ed avvialo.", + "STR_DEVICE":"Dispositivo", + "STR_LOCAL_VER":"Versione installata", + "STR_DISK_VER":"Versione nel dispositivo", + "STR_STATUS":"Stato - PRONTO", + "STR_INSTALL":"Installa", + "STR_UPDATE":"Aggiorna", + "STR_UPDATE_TIP":"L'aggiornamento è sicuro, i file presenti nel dispositivo rimarranno invariati.#@#@Vuoi continuare?", + "STR_INSTALL_TIP":"Il dispositivo verrà formattato e tutti i dati saranno persi.#@#@Vuoi continuare?", + "STR_INSTALL_TIP2":"Il dispositivo verrà formattato e tutti i dati saranno persi.#@#@Vuoi continuare (seconda verifica)?", + "STR_INSTALL_SUCCESS":"Congratulazioni!#@#@Installazione di Ventoy nel dispositivo completata.", + "STR_INSTALL_FAILED":"Si è verificato un errore durante l'installazione.#@#@Riconnetti il dispositivo e riprova.#@#@Per i dettagli controlla il file log.txt .", + "STR_UPDATE_SUCCESS":"Congratulazioni!#@#@Aggiornamento di Ventoy nel dispositivo completato", + "STR_UPDATE_FAILED":"Si è verificato un errore durante l'aggiornamento.#@È possibile riconnettere il dispositivo USB e riprovare.#@Per i dettagli controlla il file log.txt.#@Se l'aggiornamento non va a buon fine, consulta le FAQ sul sito ufficiale", + "STR_WAIT_PROCESS":"Un processo è in esecuzione. Attendi...", + "STR_MENU_OPTION":"Opzioni", + "STR_MENU_SECURE_BOOT":"Avvio protetto (secure boot)", + "STR_MENU_PART_CFG":"Configurazione partizione", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Annulla", + "STR_PRESERVE_SPACE":"Riserva un po' di spazio alla fine del dispositivo", + "STR_SPACE_VAL_INVALID":"Quantità di spazio da riservare non valida", + "STR_MENU_CLEAR":"Rimuovi Ventoy dal dispositivo", + "STR_CLEAR_SUCCESS":"Rimozione di Ventoy dal dispositivo completata.", + "STR_CLEAR_FAILED":"Si è verificato un errore durante la rimozione di Ventoy dal dispositivo.#@È possibile riconnettere il dispositivo USB e riprovare.#@Per i dettagli controlla il file log.txt ", + "STR_MENU_PART_STYLE":"Stile tabella partizioni", + "STR_DISK_2TB_MBR_ERROR":"Seleziona GPT per i dispositivi più grandi di 2TB", + "STR_SHOW_ALL_DEV":"Visualizza tutti i dispositivi", + "STR_PART_ALIGN_4KB":"Allinea le partizioni con 4KB", + "STR_WEB_COMMUNICATION_ERR":"Errore di comunicazione:", + "STR_WEB_REMOTE_ABNORMAL":"Errore di comunicazione: remoto non normale", + "STR_WEB_REQUEST_TIMEOUT":"Errore di comunicazione: richiesta scaduta", + "STR_WEB_SERVICE_UNAVAILABLE":"Errore di comunicazione: servizio non disponibile", + "STR_WEB_TOKEN_MISMATCH":"Stato del demon aggiornato. Riprova più tardi.", + "STR_WEB_SERVICE_BUSY":"Il servizio è occupato. Riprova più tardi.", + "STR_MENU_VTSI_CREATE":"Genera file VTSI", + "STR_VTSI_CREATE_TIP":"Questa volta non scriverà sul dispositivo, ma genererà solo un file VTSI#@#@Vuoi continuare?", + "STR_VTSI_CREATE_SUCCESS":"Creazione file VTSI completata!#@Per scriverlo nel dispositivo in modo da completare l'installazione di Ventoy puoi usare Rufus (versione 3.15 o successiva).", + "STR_VTSI_CREATE_FAILED":"Creazione file VTSI non riuscita.", + "STR_MENU_PART_RESIZE":"Installazione non distruttiva", + "STR_PART_RESIZE_TIP":"Ventoy proverà, se possibile, l'installazione non distruttiva.#@#@Vuoi continuare?", + "STR_PART_RESIZE_SUCCESS":"Congratulazioni!#@Installazione non distruttiva di Ventoy completata.", + "STR_PART_RESIZE_FAILED":"Installazione non distruttiva fallita.#@Controlla il file log.txt per i dettagli.", + "STR_PART_RESIZE_UNSUPPORTED":"L'installazione non distruttiva di Ventoy è stata interrotta perché alcune condizioni non possono essere soddisfatte.#@Controlla il file log.txt per i dettagli.", + "STR_INSTALL_YES_TIP1":"Attenzione: i dati verranno persi!", + "STR_INSTALL_YES_TIP2":"Per confermare che vuoi davvero eseguire un'installazione pulita anziché un aggiornamento digita YES nella casella di testo qui sotto .", + "STR_PART_VENTOY_FS":"File system partizione Ventoy", + "STR_PART_FS":"File system", + "STR_PART_CLUSTER":"Dimensione cluster", + "STR_PART_CLUSTER_DEFAULT":"Valore predefinito sistema", + "STR_DONATE":"Dona", + "STR_4KN_UNSUPPORTED":"Attualmente Ventoy non supporta dispositivi nativi 4K.", + + "STRXXX":"" + }, + { + "name":"Croatian (Hrvatski)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Valnjes", + + "STR_ERROR":"Pogreška", + "STR_WARNING":"Upozorenje", + "STR_INFO":"Informacija", + "STR_INCORRECT_DIR":"Molim vas pokrenite unutar pravog direktorija!", + "STR_INCORRECT_TREE_DIR":"Ne pokrećite me ovdje, molim vas downloadajte poslijednju verziju, te ponovno pokrenite!", + "STR_DEVICE":"Uređaj", + "STR_LOCAL_VER":"Ventoy (lokalni)", + "STR_DISK_VER":"Ventoy (na uređaju)", + "STR_STATUS":"Status - SPREMAN", + "STR_INSTALL":"Instaliraj", + "STR_UPDATE":"Ažuriraj", + "STR_UPDATE_TIP":"Nadogradnja je sigurna, ISO datoteke neće biti promjenjene.#@Nastaviti?", + "STR_INSTALL_TIP":"USB disk će biti formatiran i svi podatci će biti izgubljeni!#@Nastaviti?", + "STR_INSTALL_TIP2":"USB disk će biti formatiran i svi podatci će biti izgubljeni!#@Nastaviti? (Dodatna provjera)", + "STR_INSTALL_SUCCESS":"Čestitam!#@Ventoy je uspješno instaliran na vaš uređaj.", + "STR_INSTALL_FAILED":"Dogodila se pogreška tokom instalacije. Pokušajte ponovno spojiti USB i pokušati ponovno. Provjerite log.txt za više detalja o nastaloj pogrešci.", + "STR_UPDATE_SUCCESS":"Čestitam!#@Ventoy je uspješno ažuriran na vašem uređaju.", + "STR_UPDATE_FAILED":"Dogodila se pogreška tokom ažuriranja. Pokušajte ponovno spojiti USB i pokušati ponovno. Provjerite log.txt za više detalja o nastaloj pogrešci.", + "STR_WAIT_PROCESS":"Instanca je vec pokrenuta, molimo vas pričekajte...", + "STR_MENU_OPTION":"Opcije", + "STR_MENU_SECURE_BOOT":"Secure Boot", + "STR_MENU_PART_CFG":"Konfiguracija particije", + "STR_BTN_OK":"u redu", + "STR_BTN_CANCEL":"Otkazati", + "STR_PRESERVE_SPACE":"Sačuvajte malo prostora na dnu diska", + "STR_SPACE_VAL_INVALID":"Nevažeća vrijednost rezerviranog prostora", + "STR_MENU_CLEAR":"Obriši Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy je uspesno obrisan sa uređaja", + "STR_CLEAR_FAILED":"Dogodila se greška tokom brisanja Ventoy sa diska. Možeš ponovo ubacit USB i pokušati opet. Pogledaj log.txt za još detalja.", + "STR_MENU_PART_STYLE":"Stil particija", + "STR_DISK_2TB_MBR_ERROR":"Molim te, koristi GPT za diskove preko 2TB", + "STR_SHOW_ALL_DEV":"Show All Devices", + "STR_PART_ALIGN_4KB":"Align partitions with 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STR_MENU_PART_RESIZE":"Non-destructive Install", + "STR_PART_RESIZE_TIP":"Ventoy will try non-destructive installation if possible. #@Continue?", + "STR_PART_RESIZE_SUCCESS":"Congratulations!#@Ventoy non-destructive installation successfully finished.", + "STR_PART_RESIZE_FAILED":"Non-destructive installation failed, Check log.txt for details.", + "STR_PART_RESIZE_UNSUPPORTED":"Ventoy non-destructive installation stopped because some conditions cannot be met. Check log.txt for details.", + "STR_INSTALL_YES_TIP1":"Warning: Data will be lost!", + "STR_INSTALL_YES_TIP2":"Please enter YES in the text box below to confirm that you indeed want to do a fresh install instead of upgrade.", + "STR_PART_VENTOY_FS":"File System For Ventoy Partition", + "STR_PART_FS":"File System", + "STR_PART_CLUSTER":"Cluster Size", + "STR_PART_CLUSTER_DEFAULT":"System Default Value", + "STR_DONATE":"Donirajte", + "STR_4KN_UNSUPPORTED":"Currently Ventoy does not support 4K native devices.", + + "STRXXX":"" + }, + { + "name":"Hungarian (Magyar)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Bitfarago, gidano, meskobalazs", + + "STR_ERROR":"Hiba", + "STR_WARNING":"Figyelmeztetés", + "STR_INFO":"Információ", + "STR_INCORRECT_DIR":"Futtassa a megfelelő könyvtárból.", + "STR_INCORRECT_TREE_DIR":"Ne innen futtassa, töltse le a kiadott telepítőcsomagot, és futtassa onnan.", + "STR_DEVICE":"Eszköz", + "STR_LOCAL_VER":"A csomagban lévő Ventoy", + "STR_DISK_VER":"Az eszközön lévő Ventoy", + "STR_STATUS":"Állapot – KÉSZ", + "STR_INSTALL":"Telepítés", + "STR_UPDATE":"Frissítés", + "STR_UPDATE_TIP":"A frissítés biztonságos, az ISO-fájlok nem változnak.#@Folytatja?", + "STR_INSTALL_TIP":"A meghajtó formázva lesz, és minden rajta lévő adat elvész.#@Folytatja?", + "STR_INSTALL_TIP2":"A meghajtó formázva lesz, és minden rajta lévő adat elvész.#@Folytatja? (Második jóváhagyás)", + "STR_INSTALL_SUCCESS":"Gratulálunk!#@A Ventoy sikeresen telepítve lett az eszközön.", + "STR_INSTALL_FAILED":"Hiba történt a telepítés során. Csatlakoztassa újra az USB-eszközt, és próbálja újra.#@A részleteket lásd a log.txt fájlban.", + "STR_UPDATE_SUCCESS":"Gratulálunk!#@A Ventoy sikeresen frissítve lett az eszközön.", + "STR_UPDATE_FAILED":"Hiba történt a frissítés során. Csatlakoztassa újra az USB-eszközt, és próbálja újra.#@A részleteket lásd a log.txt fájlban.", + "STR_WAIT_PROCESS":"A feldolgozás még folyamatban van, kis türelmet…", + "STR_MENU_OPTION":"Beállítás", + "STR_MENU_SECURE_BOOT":"Secure Boot támogatás", + "STR_MENU_PART_CFG":"Partíció konfiguráció", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Mégse", + "STR_PRESERVE_SPACE":"Szabad terület maradjon a lemez végén", + "STR_SPACE_VAL_INVALID":"Érvénytelen érték a fenntartott helynél", + "STR_MENU_CLEAR":"A Ventoy eltávolítása", + "STR_CLEAR_SUCCESS":"A Ventoy sikeresen eltávolítva az eszközről.", + "STR_CLEAR_FAILED":"Hiba történt a Ventoy lemezről törlése során. Újra csatlakoztathatja az USB-t, és megpróbálhatja újra. A részleteket lásd a log.txt fájlban.", + "STR_MENU_PART_STYLE":"Partíció fajtája", + "STR_DISK_2TB_MBR_ERROR":"2 TB-nál nagyobb lemezhez válassza a GPT-t", + "STR_SHOW_ALL_DEV":"Az összes eszköz megjelenítése", + "STR_PART_ALIGN_4KB":"A partíciók 4 kB-hoz igazítása", + "STR_WEB_COMMUNICATION_ERR":"Kommunikációs hiba:", + "STR_WEB_REMOTE_ABNORMAL":"Kommunikációs hiba: Távoli hiba", + "STR_WEB_REQUEST_TIMEOUT":"Kommunikációs hiba: Kérés időtúllépése", + "STR_WEB_SERVICE_UNAVAILABLE":"Kommunikációs hiba: A szolgáltatás nem érhető el", + "STR_WEB_TOKEN_MISMATCH":"A démon állapota frissítve, próbálja újra később.", + "STR_WEB_SERVICE_BUSY":"A szolgáltatás foglalt, próbálja újra később.", + "STR_MENU_VTSI_CREATE":"VTSI fájl előállítása", + "STR_VTSI_CREATE_TIP":"Ez alkalommal nem ír az eszközre, csak egy VTSI fájlt állít elő.#@Folytatja?", + "STR_VTSI_CREATE_SUCCESS":"A VTSI fájl sikeresen létrehozva!#@A Rufus(3.15+) segítségével az eszközre írhatja a Ventoy telepítésének befejezéséhez.", + "STR_VTSI_CREATE_FAILED":"A VTSI fájl létrehozása nem sikerült.", + "STR_MENU_PART_RESIZE":"Rombolásmentes telepítés", + "STR_PART_RESIZE_TIP":"A Ventoy lehetőség szerint megpróbálja a rombolásmentes telepítést. #@Folytatja?", + "STR_PART_RESIZE_SUCCESS":"Gratulálunk!#@A Ventoy rombolásmentes telepítése sikeresen befejeződött.", + "STR_PART_RESIZE_FAILED":"A rombolásmentes telepítés nem sikerült, a részleteket lásd a log.txt fájlban.", + "STR_PART_RESIZE_UNSUPPORTED":"A Ventoy rombolásmentes telepítése leállt, mert bizonyos feltételek nem teljesíthetők. A részleteket lásd a log.txt fájlban.", + "STR_INSTALL_YES_TIP1":"Figyelmeztetés: Az adatok elvesznek!", + "STR_INSTALL_YES_TIP2":"Írja a YES szót az alábbi szövegmezőbe, hogy megerősítse, valóban új telepítést szeretne végrehajtani a frissítés helyett.", + "STR_PART_VENTOY_FS":"Fájlrendszer a Ventoy partícióhoz", + "STR_PART_FS":"Fájlrendszer", + "STR_PART_CLUSTER":"Klaszter méret", + "STR_PART_CLUSTER_DEFAULT":"Rendszer alapérték", + "STR_DONATE":"Adományoz", + "STR_4KN_UNSUPPORTED":"Jelenleg a Ventoy nem támogat natív 4K eszközt.", + + "STRXXX":"" + }, + { + "name":"Traditional Chinese(正體中文)", + "FontFamily":"新細明體", + "FontSize":14, + "Author":"penut85420,tony8077616", + + "STR_ERROR":"錯誤", + "STR_WARNING":"警告", + "STR_INFO":"提醒", + "STR_INCORRECT_DIR":"請在正確的資料夾下開啟!", + "STR_INCORRECT_TREE_DIR":"請下載並使用發行版本的安裝包", + "STR_DEVICE":"裝置", + "STR_LOCAL_VER":"安裝包內 Ventoy 版本", + "STR_DISK_VER":"裝置內 Ventoy 版本", + "STR_STATUS":"狀態 - 準備就緒", + "STR_INSTALL":"安裝", + "STR_UPDATE":"升級", + "STR_UPDATE_TIP":"升級操作是安全的,磁碟內的 ISO 檔案不會被清除#@請問是否繼續?", + "STR_INSTALL_TIP":"磁碟將會被格式化,所有內容將會被清除!#@請問是否繼續?", + "STR_INSTALL_TIP2":"磁碟將會被格式化,所有內容將會被清除!#@請再次確認是否繼續?", + "STR_INSTALL_SUCCESS":"恭喜,Ventoy 已經成功安裝到此裝置中!", + "STR_INSTALL_FAILED":"安裝 Ventoy 的過程中發生錯誤,請再次重新插入磁碟重試,詳細訊息請檢視 log.txt 檔案。", + "STR_UPDATE_SUCCESS":"恭喜,新版本的 Ventoy 已經成功更新到此裝置中!", + "STR_UPDATE_FAILED":"更新 Ventoy 的過程中發生錯誤,請再次重新插入磁碟重試,詳細訊息請檢視 log.txt 檔案。", + "STR_WAIT_PROCESS":"目前仍有執行緒正在運作中,請稍候...", + "STR_MENU_OPTION":"選項", + "STR_MENU_SECURE_BOOT":"支援安全開機", + "STR_MENU_PART_CFG":"設定分割磁區", + "STR_BTN_OK":"確定", + "STR_BTN_CANCEL":"取消", + "STR_PRESERVE_SPACE":"在磁區最後保留一部分空間", + "STR_SPACE_VAL_INVALID":"保留空間的容量不正確", + "STR_MENU_CLEAR":"清除 Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy 已成功從裝置中清除", + "STR_CLEAR_FAILED":"清除 Ventoy 的過程中發生錯誤,請再次重新插入磁碟重試,詳細訊息請檢視 log.txt 檔案。", + "STR_MENU_PART_STYLE":"分割表格式", + "STR_DISK_2TB_MBR_ERROR":"超過 2TB 的磁碟請選擇 GPT 格式分割表", + "STR_SHOW_ALL_DEV":"顯示所有裝置", + "STR_PART_ALIGN_4KB":"磁碟分割區按照 4KB 對齊", + "STR_WEB_COMMUNICATION_ERR":"通訊錯誤:", + "STR_WEB_REMOTE_ABNORMAL":"通訊錯誤: 伺服器端發生異常", + "STR_WEB_REQUEST_TIMEOUT":"通訊錯誤: 請求逾時", + "STR_WEB_SERVICE_UNAVAILABLE":"通訊錯誤: 伺服器無法使用", + "STR_WEB_TOKEN_MISMATCH":"伺服器狀態已更新", + "STR_WEB_SERVICE_BUSY":"伺服器忙碌中,請稍後再試", + "STR_MENU_VTSI_CREATE":"建立 VTSI 檔案", + "STR_VTSI_CREATE_TIP":"這項操作將只會在原地目錄建立一個 VTSI 的檔案#@請問是否繼續?", + "STR_VTSI_CREATE_SUCCESS":"VTSI 檔案建立完成!#@您可以使用 Rufus(3.15+) 將 VTSI 檔案寫入指定的裝置以完成 Ventoy 的安裝。", + "STR_VTSI_CREATE_FAILED":"VTSI 檔案建立失敗。", + "STR_MENU_PART_RESIZE":"無損安裝", + "STR_PART_RESIZE_TIP":"Ventoy 將嘗試進行無損安裝。#@請注意:任何對於磁碟的任何操作都存在一定的風險,對於重要的資料建議您做好備份!#@請問您是否繼續?", + "STR_PART_RESIZE_SUCCESS":"恭喜!#@Ventoy 已完成無損安裝。", + "STR_PART_RESIZE_FAILED":"Ventoy 無損安裝失敗。詳細訊息請檢視 log.txt 檔案。", + "STR_PART_RESIZE_UNSUPPORTED":"Ventoy 無損安裝已中止因為未滿足部分條件。詳細訊息請檢視 log.txt 檔案。", + "STR_INSTALL_YES_TIP1":"警告:資料將會遺失!", + "STR_INSTALL_YES_TIP2":"請在下方的文字輸入框輸入 YES 來證實您想要進行全新安裝取代升級。", + "STR_PART_VENTOY_FS":"Ventoy 磁區的檔案系統", + "STR_PART_FS":"檔案系統", + "STR_PART_CLUSTER":"磁區單位大小", + "STR_PART_CLUSTER_DEFAULT":"系統預設值", + "STR_DONATE":"贊助", + "STR_4KN_UNSUPPORTED":"目前 Ventoy 不支援單位磁區格式為4K的硬碟。", + + "STRXXX":"" + }, + { + "name":"Serbian Latin (Srpski)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Bojan Maksimović, panickingkernel, Zoran Jankov, Stefan Šućur, Kosta Stojiljković", + + "STR_ERROR":"Greška", + "STR_WARNING":"Upozorenje", + "STR_INFO":"Informacija", + "STR_INCORRECT_DIR":"Molim Vas, pokrenite me u pravom direktorijumu!", + "STR_INCORRECT_TREE_DIR":"Nemojtе me pokretati ovde, molim Vas preuzmite objavljeni instalacioni paket i pokrenite me tamo.", + "STR_DEVICE":"Uređaj", + "STR_LOCAL_VER":"Ventoy u paketu", + "STR_DISK_VER":"Ventoy u uređaju", + "STR_STATUS":"Status - SPREMAN", + "STR_INSTALL":"Instaliraj", + "STR_UPDATE":"Nadogradi", + "STR_UPDATE_TIP":"Nadogradnja je sigurna, ISO datoteke neće biti promenjene.#@Nastavi?", + "STR_INSTALL_TIP":"Disk će biti formatiran i svi podaci će biti izgubljeni.#@Nastavi?", + "STR_INSTALL_TIP2":"Disk će biti formatiran i svi podaci će biti izgubljeni.#@Nastavi? (Dvostruka provera)", + "STR_INSTALL_SUCCESS":"Čestitam!#@Ventoy je uspešno instaliran na ovom uređaju.", + "STR_INSTALL_FAILED":"Dogodila se greška tokom instalacije. Možete izvaditi i ponovo ubaciti USB, pa pokušati opet. Pogledajte log.txt za još detalja.", + "STR_UPDATE_SUCCESS":"Čestitam!#@Ventoy je uspešno nadograđen na ovom uređaju.", + "STR_UPDATE_FAILED":"Dogodila se greška prilikom nadogradnje. Možeте izvaditi i ponovo ubaciti USB, pa pokušati opet. Pogledajte log.txt za još detalja.", + "STR_WAIT_PROCESS":"Odvija se operacija, molim Vas sačekajte...", + "STR_MENU_OPTION":"Opcije", + "STR_MENU_SECURE_BOOT":"Sigurno uključivanje je podržano", + "STR_MENU_PART_CFG":"Konfiguracija particija", + "STR_BTN_OK":"U redu", + "STR_BTN_CANCEL":"Otkaži", + "STR_PRESERVE_SPACE":"Sačuvaj nešto prostora na kraju diska", + "STR_SPACE_VAL_INVALID":"Neispravna vrednost za prezervirani prostor", + "STR_MENU_CLEAR":"Obriši Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy je uspešno obrisan sa uređaja", + "STR_CLEAR_FAILED":"Dogodila se greška tokom brisanja Ventoy sa diska. Možete ponovo ubaciti USB i pokušati opet. Pogledajte log.txt za još detalja.", + "STR_MENU_PART_STYLE":"Stil particija", + "STR_DISK_2TB_MBR_ERROR":"Molim Vas, izaberite GPT za diskove preko 2TB", + "STR_SHOW_ALL_DEV":"Pokaži sve uređaje", + "STR_PART_ALIGN_4KB":"Poravnajte sve particije sa 4KB", + "STR_WEB_COMMUNICATION_ERR":"Greška u komunikaciji:", + "STR_WEB_REMOTE_ABNORMAL":"Greška u komunikaciji: nenormalno daljinsko upravljanje", + "STR_WEB_REQUEST_TIMEOUT":"Greška u komunikaciji: Zahtev je istekao", + "STR_WEB_SERVICE_UNAVAILABLE":"Greška u komunikaciji: Servis nije dostupan", + "STR_WEB_TOKEN_MISMATCH":"Status demona ažuriran, pokušajte ponovo kasnije.", + "STR_WEB_SERVICE_BUSY":"Servis je zauzet, pokušajte ponovo kasnije.", + "STR_MENU_VTSI_CREATE":"Stvori VTSI datoteku", + "STR_VTSI_CREATE_TIP":"Ovaj put ne pisati na uređaj, nego samo stvoriti VTSI datoteku#@Nastavi?", + "STR_VTSI_CREATE_SUCCESS":"VTSI datoteka uspešno stvorena!#@Možete koristiti Rufus(3.15+) da je zapišete na uređaj da biste završili instalaciju Ventoy.", + "STR_VTSI_CREATE_FAILED":"Greška u stvaranju VTSI datoteke.", + "STR_MENU_PART_RESIZE":"Nedestruktivna instalacija", + "STR_PART_RESIZE_TIP":"Ventoy će pokušati nedestruktivnu instalaciju ako je moguće. #@Nastavi?", + "STR_PART_RESIZE_SUCCESS":"Čestitam!#@Ventoy nedestruktivna instalacija je bila uspešna.", + "STR_PART_RESIZE_FAILED":"Nedestruktivna instalacija je bila neuspešna. Pogledajte log.txt za još detalja.", + "STR_PART_RESIZE_UNSUPPORTED":"Ventoy nedestruktivna instalacija se zaustavila jer nisu postignuti neki uslovi. Pogledajte log.txt za još detalja.", + "STR_INSTALL_YES_TIP1":"Upozorenje: podaci će biti izgubljeni!", + "STR_INSTALL_YES_TIP2":"Molim Vas, unesite YES u polje ispod da biste potvrdili da zaista želite da uradite novu instalaciju umesto nadogradnje.", + "STR_PART_VENTOY_FS":"Datotečni sistem za Ventoy particiju", + "STR_PART_FS":"Datotoečni sistem", + "STR_PART_CLUSTER":"Veličina klastera", + "STR_PART_CLUSTER_DEFAULT":"Podrazumevana sistemska vrednost", + "STR_DONATE":"Donirajte", + "STR_4KN_UNSUPPORTED":"Ventoy trenutno ne podržava 4K izvorne uređaje.", + + "STRXXX":"" + }, + { + "name":"Serbian Cyrillic (Српски)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Bojan Maksimović, panickingkernel, Zoran Jankov, Stefan Šućur, Kosta Stojiljković", + + "STR_ERROR":"Грешка", + "STR_WARNING":"Упозорење", + "STR_INFO":"Информација", + "STR_INCORRECT_DIR":"Молим Вас, покрените ме у правом директоријуму!", + "STR_INCORRECT_TREE_DIR":"Немојте ме покретати овде, молим Вас преузмите објављени инсталациони пакет и покрените ме тамо.", + "STR_DEVICE":"Уређај", + "STR_LOCAL_VER":"Ventoy у пакету", + "STR_DISK_VER":"Ventoy у уређају", + "STR_STATUS":"Статус - СПРЕМАН", + "STR_INSTALL":"Инсталирај", + "STR_UPDATE":"Надогради", + "STR_UPDATE_TIP":"Надоградња је сигурна, ISO датотеке неће бити промењене.#@Настави?", + "STR_INSTALL_TIP":"Диск ће бити форматиран и сви подаци ће бити изгубљени.#@Настави?", + "STR_INSTALL_TIP2":"Диск ће бити форматиран и сви подаци ће бити изгубљени.#@Настави? (Двострука провера)", + "STR_INSTALL_SUCCESS":"Честитам!#@Ventoy је успешно инсталиран на овом уређају.", + "STR_INSTALL_FAILED":"Догодила се грешка током инсталације. Можете извадити и поново убацити USB, па покушати опет. Погледајте log.txt за још детаља.", + "STR_UPDATE_SUCCESS":"Честитам!#@Ventoy је био успешно надограђен на овом уређају.", + "STR_UPDATE_FAILED":"Догодила се грешка током надоградње. Можете извадити и поново убацити USB, па покушати опет. Погледајте log.txt за још детаља.", + "STR_WAIT_PROCESS":"Одвија се операција, молим Вас сачекајте...", + "STR_MENU_OPTION":"Опције", + "STR_MENU_SECURE_BOOT":"Сигурно укључивање је подржано", + "STR_MENU_PART_CFG":"Конфигурација партиција", + "STR_BTN_OK":"У реду", + "STR_BTN_CANCEL":"Откажи", + "STR_PRESERVE_SPACE":"Сачувај нешто простора на крају диска", + "STR_SPACE_VAL_INVALID":"Неисправна вредност за презервирани простор", + "STR_MENU_CLEAR":"Обриши Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy је успешно обрисан са уређаја", + "STR_CLEAR_FAILED":"Догодила се грешка током брисања Ventoy са диска. Можете поново убацити USB и покушати опет. Погледајте log.txt за још детаља.", + "STR_MENU_PART_STYLE":"Стил партиција", + "STR_DISK_2TB_MBR_ERROR":"Молим Вас, изаберите GPT за дискове преко 2ТB", + "STR_SHOW_ALL_DEV":"Прикажи све уређаје", + "STR_PART_ALIGN_4KB":"Поравнајте партиције са 4KB", + "STR_WEB_COMMUNICATION_ERR":"Комуникациона грешка:", + "STR_WEB_REMOTE_ABNORMAL":"Комуникациона грешка: Ненормално даљинско управљање", + "STR_WEB_REQUEST_TIMEOUT":"Комуникациона грешка: Захтев је истекао", + "STR_WEB_SERVICE_UNAVAILABLE":"Комуникациона грешка: Сервис је недоступан", + "STR_WEB_TOKEN_MISMATCH":"Статус демона ажуриран, покушајте поново касније.", + "STR_WEB_SERVICE_BUSY":"Севис је заузет, покушајте поново касније.", + "STR_MENU_VTSI_CREATE":"Створи VTSI датотеку", + "STR_VTSI_CREATE_TIP":"Овај пут не писати на уређај, него само створити VTSI датотеку#@Настави?", + "STR_VTSI_CREATE_SUCCESS":"VTSI датотека успешно створена!#@Можете користити Rufus(3.15+) да је запишете на уређај да бисте завршили инсталацију Ventoy.", + "STR_VTSI_CREATE_FAILED":"Грешка у стварању VTSI датотеке.", + "STR_MENU_PART_RESIZE":"Недеструктивна инсталација", + "STR_PART_RESIZE_TIP":"Ventoy ће покушати недеструктивну инсталацију ако је могуће. #@Настави?", + "STR_PART_RESIZE_SUCCESS":"Честитам!#@Ventoy недеструктивна инсталација је била успешна.", + "STR_PART_RESIZE_FAILED":"Недеструктивна инсталација је била неуспешна. Погледајте log.txt за више детаља.", + "STR_PART_RESIZE_UNSUPPORTED":"Ventoy недеструктивна инсталација се зауставила јер нису постигнути неки услови. Погледајте log.txt за још детаља.", + "STR_INSTALL_YES_TIP1":"Упозорење: подаци ће бити изгубљени!", + "STR_INSTALL_YES_TIP2":"Молим Вас, унесите YES у поље испод да бисте потврдили да заиста желите да урадите нову инсталацију уместо надоградње.", + "STR_PART_VENTOY_FS":"Датотечни систем за Ventoy партицију", + "STR_PART_FS":"Датотечни систем", + "STR_PART_CLUSTER":"Величина кластера", + "STR_PART_CLUSTER_DEFAULT":"Подразумевана системска вредност", + "STR_DONATE":"Донирајте", + "STR_4KN_UNSUPPORTED":"Ventoy тренутно не подржава 4К изворне уређаје.", + + "STRXXX":"" + }, + { + "name":"Thai (ไทย)", + "FontFamily":"Courier New", + "FontSize":17, + "Author":"longpanda", + + "STR_ERROR":"ผิดพลาด", + "STR_WARNING":"คำเตือน", + "STR_INFO":"ข้อมูล", + "STR_INCORRECT_DIR":"กรุณาเรียกใช้ในอุปกรณ์ที่ถูกต้อง!", + "STR_INCORRECT_TREE_DIR":"อย่าติดตั้งในนี้, โปรดดาวน์โหลดและใช้แพ็คเกจการติดตั้งของรุ่นที่วางจำหน่าย", + "STR_DEVICE":"อุปกรณ์", + "STR_LOCAL_VER":"เวอร์ชั่น Ventoy ", + "STR_DISK_VER":"ลง Ventoy ในอุปกรณ์", + "STR_STATUS":"สถานะ - พร้อม", + "STR_INSTALL":"ติดตั้ง", + "STR_UPDATE":"ปรับปรุง", + "STR_UPDATE_TIP":"การดำเนินการอัปเกรดปลอดภัย, ไฟล์ ISO จะไม่มีการเปลี่ยนแปลง.#@ต่อเนื่อง?", + "STR_INSTALL_TIP":"ดิสก์จะถูกฟอร์แมตและข้อมูลทั้งหมดจะสูญหาย.#@ต่อเนื่อง?", + "STR_INSTALL_TIP2":"ดิสก์จะถูกฟอร์แมตและข้อมูลทั้งหมดจะสูญหาย#@ต่อเนื่อง? (ตรวจสอบอีกครั้ง)", + "STR_INSTALL_SUCCESS":"ขอแสดงความยินดี!#@Ventoy ติดตั้งไปยังอุปกรณ์สำเร็จแล้ว", + "STR_INSTALL_FAILED":"เกิดข้อผิดพลาดระหว่างการติดตั้ง. คุณสามารถถอด USB และลองอีกครั้ง. ตรวจสอบรายละเอียดได้ที่ log.txt.", + "STR_UPDATE_SUCCESS":"ขอแสดงความยินดี!#@Ventoy อัปเดตไปยังอุปกรณ์สำเร็จแล้ว.", + "STR_UPDATE_FAILED":"เกิดข้อผิดพลาดระหว่างการอัพเดต. คุณสามารถถอด USB และลองอีกครั้ง. ตรวจสอบรายละเอียดได้ที่ log.txt.", + "STR_WAIT_PROCESS":"CPU กำลังทำงานอยู่,ได้โปรดรอ...", + "STR_MENU_OPTION":"ตัวเลือก", + "STR_MENU_SECURE_BOOT":"สนับสนุนการบูตที่ปลอดภัย", + "STR_MENU_PART_CFG":"กำหนดค่าพาร์ติชัน", + "STR_BTN_OK":"ตกลง", + "STR_BTN_CANCEL":"ยกเลิก", + "STR_PRESERVE_SPACE":"เก็บพื้นที่บางส่วนของอุปกรณ์ไว้", + "STR_SPACE_VAL_INVALID":"มีปัญหาสำหรับพื้นที่ที่สงวนไว้(กรุณา ฟอร์แมต และติดตั้งใหม่)", + "STR_MENU_CLEAR":"Clear Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy has been successfully removed from the device.", + "STR_CLEAR_FAILED":"An error occurred when clear Ventoy from disk. You can replug the USB and try again. Check log.txt for detail.", + "STR_MENU_PART_STYLE":"Partition Style", + "STR_DISK_2TB_MBR_ERROR":"Please select GPT for disk over 2TB", + "STR_SHOW_ALL_DEV":"Show All Devices", + "STR_PART_ALIGN_4KB":"Align partitions with 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STR_MENU_PART_RESIZE":"Non-destructive Install", + "STR_PART_RESIZE_TIP":"Ventoy will try non-destructive installation if possible. #@Continue?", + "STR_PART_RESIZE_SUCCESS":"Congratulations!#@Ventoy non-destructive installation successfully finished.", + "STR_PART_RESIZE_FAILED":"Non-destructive installation failed, Check log.txt for details.", + "STR_PART_RESIZE_UNSUPPORTED":"Ventoy non-destructive installation stopped because some conditions cannot be met. Check log.txt for details.", + "STR_INSTALL_YES_TIP1":"Warning: Data will be lost!", + "STR_INSTALL_YES_TIP2":"Please enter YES in the text box below to confirm that you indeed want to do a fresh install instead of upgrade.", + "STR_PART_VENTOY_FS":"File System For Ventoy Partition", + "STR_PART_FS":"File System", + "STR_PART_CLUSTER":"Cluster Size", + "STR_PART_CLUSTER_DEFAULT":"System Default Value", + "STR_DONATE":"บริจาค", + "STR_4KN_UNSUPPORTED":"Currently Ventoy does not support 4K native devices.", + + "STRXXX":"" + }, + { + "name":"Norwegian (Norsk)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Stein-Ove Bøthun", + + "STR_ERROR":"Feil", + "STR_WARNING":"Advarsel", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Vennligst kjør fra den riktige mappen!", + "STR_INCORRECT_TREE_DIR":"Ikke kjør meg her, vennligst last ned den utgitte installasjonspakken og kjør den der.", + "STR_DEVICE":"Enhet", + "STR_LOCAL_VER":"Ventoy i Pakken", + "STR_DISK_VER":"Ventoy på Enheten", + "STR_STATUS":"Status - KLAR", + "STR_INSTALL":"Installer", + "STR_UPDATE":"Oppdater", + "STR_UPDATE_TIP":"Oppgraderingen er trygg, ISO-filene vil være uendret.#@Fortsette?", + "STR_INSTALL_TIP":"Disken blir formatert og alle dataene vil gå tapt.#@Fortsette?", + "STR_INSTALL_TIP2":"Disken blir formatert og alle dataene vil gå tapt.#@Fortsette? (Dobbelsjekk)", + "STR_INSTALL_SUCCESS":"Gratulerer!#@Ventoy er blitt installert på enheten.", + "STR_INSTALL_FAILED":"Det oppstod en feil under installasjonen. Du kan koble til USB-en på nytt og prøve igjen. Check log.txt for flere detaljer.", + "STR_UPDATE_SUCCESS":"Gratulerer!#@Ventoy har blitt oppdatert på enheten.", + "STR_UPDATE_FAILED":"Det oppstod en feil under oppdateringen. Du kan koble til USB-en på nytt og prøve igjen. Se log.txt for flere detaljer.", + "STR_WAIT_PROCESS":"En prosess kjører, vennligst vent...", + "STR_MENU_OPTION":"Alternativ", + "STR_MENU_SECURE_BOOT":"Støtte for sikker oppstart", + "STR_MENU_PART_CFG":"Partisjonskonfigirasjon", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Avbryt", + "STR_PRESERVE_SPACE":"Bevar litt plass på bunnen av disken", + "STR_SPACE_VAL_INVALID":"Ugyldig verdi for reservert plass", + "STR_MENU_CLEAR":"Fjern Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy er blitt fjernet fra enheten.", + "STR_CLEAR_FAILED":"Det oppstod en feil da Ventoy bler fjernet fra disken. Du kan koble til USB-en på nytt og prøve igjen. Sjekk log.txt for flere detaljer.", + "STR_MENU_PART_STYLE":"Partisjonsstil", + "STR_DISK_2TB_MBR_ERROR":"Velg GPT for disker over 2 TB", + "STR_SHOW_ALL_DEV":"Vis alle enheter", + "STR_PART_ALIGN_4KB":"Juster partisjoner med 4KB", + "STR_WEB_COMMUNICATION_ERR":"Kommunikasjonsfeil:", + "STR_WEB_REMOTE_ABNORMAL":"Kommunokasjonsfeil: unormalt fjerntliggende", + "STR_WEB_REQUEST_TIMEOUT":"Kommunikasjonsfeil: Forespørselen ble tidsavbrutt", + "STR_WEB_SERVICE_UNAVAILABLE":"Kommunikasjonsfeil: Tjeneste utilgjengelig", + "STR_WEB_TOKEN_MISMATCH":"Daemon status er oppdatert, vennligst prøv igjen senere.", + "STR_WEB_SERVICE_BUSY":"Tjenesten er opptatt, vennligst prøv igjen senere.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STR_MENU_PART_RESIZE":"Non-destructive Install", + "STR_PART_RESIZE_TIP":"Ventoy will try non-destructive installation if possible. #@Continue?", + "STR_PART_RESIZE_SUCCESS":"Congratulations!#@Ventoy non-destructive installation successfully finished.", + "STR_PART_RESIZE_FAILED":"Non-destructive installation failed, Check log.txt for details.", + "STR_PART_RESIZE_UNSUPPORTED":"Ventoy non-destructive installation stopped because some conditions cannot be met. Check log.txt for details.", + "STR_INSTALL_YES_TIP1":"Warning: Data will be lost!", + "STR_INSTALL_YES_TIP2":"Please enter YES in the text box below to confirm that you indeed want to do a fresh install instead of upgrade.", + "STR_PART_VENTOY_FS":"File System For Ventoy Partition", + "STR_PART_FS":"File System", + "STR_PART_CLUSTER":"Cluster Size", + "STR_PART_CLUSTER_DEFAULT":"System Default Value", + "STR_DONATE":"donere", + "STR_4KN_UNSUPPORTED":"Currently Ventoy does not support 4K native devices.", + + "STRXXX":"" + }, + { + "name":"Vietnamese (Tiếng Việt)", + "FontFamily":"Tahoma", + "FontSize":14, + "Author":"Nguyen Quoc Hoang - cuumay.win, HoangNPV - @isoamyl50", + + "STR_ERROR":"Lỗi", + "STR_WARNING":"Cảnh báo", + "STR_INFO":"Thông tin", + "STR_INCORRECT_DIR":"Vui lòng chạy Ventoy2Disk tại đúng thư mục của nó !", + "STR_INCORRECT_TREE_DIR":"Không được chạy Ventoy2Disk ở đây, vui lòng tải gói cài đặt đã phát hành và chạy ở đó.", + "STR_DEVICE":"Thiết bị", + "STR_LOCAL_VER":"Phiên bản Ventoy", + "STR_DISK_VER":"Phiên bản Ventoy ở thiết bị", + "STR_STATUS":"Trạng thái - SẴN SÀNG", + "STR_INSTALL":"Cài đặt", + "STR_UPDATE":"Cập nhật", + "STR_UPDATE_TIP":"Việc cập nhật Ventoy là an toàn, các tập tin ISO của bạn sẽ được giữ nguyên trạng.#@Bạn thật sự muốn tiếp tục?", + "STR_INSTALL_TIP":"Thiết bị sẽ được định dạng và do đó TẤT CẢ DỮ LIỆU trên thiết bị sẽ bị mất.#@Bạn thật sự muốn tiếp tục?", + "STR_INSTALL_TIP2":"Thiết bị sẽ được định dạng và do đó TẤT CẢ DỮ LIỆU trên thiết bị sẽ bị mất.#@Bạn thật sự muốn tiếp tục? (Xác nhận lần hai)", + "STR_INSTALL_SUCCESS":"Chúc mừng bạn!#@Thiết bị đã được cài Ventoy thành công.", + "STR_INSTALL_FAILED":"Đã xảy ra lỗi trong quá trình cài đặt Ventoy. Bạn có thể cắm lại USB và thử lại. Xem chi tiết ở tệp log.txt. Nếu lỗi tiếp tục xảy ra, vui lòng đọc FAQ tại trang web chính thức.", + "STR_UPDATE_SUCCESS":"Chúc mừng bạn!#@Thiết bị đã được cập nhật Ventoy thành công.", + "STR_UPDATE_FAILED":"Đã xảy ra lỗi trong quá trình cập nhật Ventoy. Bạn có thể cắm lại USB và thử lại. Xem chi tiết ở tệp log.txt. Nếu lỗi tiếp tục xảy ra, vui lòng đọc FAQ tại trang web chính thức.", + "STR_WAIT_PROCESS":"Một luồng xử lý đang chạy, vui lòng chờ...", + "STR_MENU_OPTION":"Tùy chọn", + "STR_MENU_SECURE_BOOT":"Bật hỗ trợ Secure Boot", + "STR_MENU_PART_CFG":"Cấu hình phân vùng", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Hủy", + "STR_PRESERVE_SPACE":"Giữ lại phần dung lượng ở cuối thiết bị", + "STR_SPACE_VAL_INVALID":"Giá trị dung lượng giữ lại không hợp lệ.", + "STR_MENU_CLEAR":"Gỡ bỏ Ventoy", + "STR_CLEAR_SUCCESS":"Chúc mừng bạn!#@Thiết bị đã được gỡ bỏ Ventoy thành công.", + "STR_CLEAR_FAILED":"Đã xảy ra lỗi trong quá trình gỡ bỏ Ventoy. Bạn có thể cắm lại USB và thử lại. Xem chi tiết ở tệp log.txt.", + "STR_MENU_PART_STYLE":"Kiểu phân vùng", + "STR_DISK_2TB_MBR_ERROR":"Thiết bị có dung lượng lớn hơn 2TB. Vui lòng chọn Kiểu phân vùng là GPT.", + "STR_SHOW_ALL_DEV":"Hiện tất cả Thiết bị", + "STR_PART_ALIGN_4KB":"Căn chỉnh phân vùng với 4KB", + "STR_WEB_COMMUNICATION_ERR":"Lỗi giao tiếp:", + "STR_WEB_REMOTE_ABNORMAL":"Lỗi giao tiếp: Remote bất thường", + "STR_WEB_REQUEST_TIMEOUT":"Lỗi giao tiếp: Yêu cầu đã hết thời gian chờ", + "STR_WEB_SERVICE_UNAVAILABLE":"Lỗi giao tiếp: Dịch vụ không sẵn có", + "STR_WEB_TOKEN_MISMATCH":"Đã cập nhật trạng thái Daemon, vui lòng thử lại sau.", + "STR_WEB_SERVICE_BUSY":"Dịch vụ bận, vui lòng thử lại sau.", + "STR_MENU_VTSI_CREATE":"Tạo tệp VTSI", + "STR_VTSI_CREATE_TIP":"Lần này sẽ không ghi vào thiết bị, chỉ tạo một tệp VTSI#@Bạn muốn tiếp tục?", + "STR_VTSI_CREATE_SUCCESS":"Tạo tệp VTSI thành công!#@Để hoàn thành cài đặt Ventoy, bạn có thể dùng Rufus (3.15+) để ghi tệp này vào thiết bị.", + "STR_VTSI_CREATE_FAILED":"Tạo tệp VTSI đã gặp lỗi.", + "STR_MENU_PART_RESIZE":"Cài đặt không phá hủy", + "STR_PART_RESIZE_TIP":"Ventoy sẽ thử cài đặt không phá hủy nếu có thể. #@Bạn muốn tiếp tục?", + "STR_PART_RESIZE_SUCCESS":"Chúc mừng bạn!#@Thiết bị đã được cài Ventoy thành công theo cách cài đặt không phá hủy.", + "STR_PART_RESIZE_FAILED":"Đã xảy ra lỗi trong quá trình cài Ventoy theo cách cài đặt không phá hủy. Xem chi tiết ở tệp log.txt.", + "STR_PART_RESIZE_UNSUPPORTED":"Cài Ventoy theo cách cài đặt không phá hủy đã bị dừng lại vì chưa đúng điều kiện. Xem chi tiết ở tệp log.txt.", + "STR_INSTALL_YES_TIP1":"Cảnh báo: Dữ liệu sẽ bị mất !", + "STR_INSTALL_YES_TIP2":"Vui lòng nhập YES vào ô bên dưới để xác nhận bạn muốn cài mới thay vì cài nâng cấp.", + "STR_PART_VENTOY_FS":"Hệ thống tập tin cho Phân vùng Ventoy", + "STR_PART_FS":"Hệ thống tập tin", + "STR_PART_CLUSTER":"Kích thước Cluster", + "STR_PART_CLUSTER_DEFAULT":"Theo giá trị mặc định của hệ thống", + "STR_DONATE":"Ủng hộ tác giả", + "STR_4KN_UNSUPPORTED":"Hiện tại Ventoy không hỗ trợ các thiết bị 4K native.", + + "STRXXX":"" + }, + { + "name":"Lithuanian (Lietuvių)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"r0manas", + + "STR_ERROR ":"Klaida", + "STR_WARNING ":"Įspėjimas", + "STR_INFO ":"Informacija", + "STR_INCORRECT_DIR ":"Prašome paleisti teisingame kataloge!", + "STR_INCORRECT_TREE_DIR ":"Nepaleiskite manęs čia, atsisiųskite išleistą diegimo paketą ir paleiskite ten.", + "STR_DEVICE ":"Įrenginys", + "STR_LOCAL_VER ":"„Ventoy“ versija pakuotėje", + "STR_DISK_VER ":"„Ventoy“ versija įrenginyje", + "STR_STATUS ":"Būsena - PASIRENGĘS", + "STR_INSTALL ":"Įdiegti", + "STR_UPDATE ":"Atnaujinti", + "STR_UPDATE_TIP ":"Atnaujinti - saugu, ISO failai liks nepažeisti.#@Tęsti?", + "STR_INSTALL_TIP ":"Įrenginys bus suformatuotas ir visi duomenys bus prarasti.#@Tęsti?", + "STR_INSTALL_TIP2 ":"Įrenginys bus suformatuotas ir visi duomenys bus prarasti.#@Tęsti? (TIKRAI TĘSTI?)", + "STR_INSTALL_SUCCESS ":"Sveikinu!#@Ventoy sėkmingai įdiegtas įrenginyje.", + "STR_INSTALL_FAILED ":"Diegimo metu įvyko klaida. Galite iš naujo prijungti USB ir bandyti dar kartą. Patikrinkite log.txt, jei norite sužinoti daugiau.", + "STR_UPDATE_SUCCESS ":"Sveikinu!#@Ventoy sėkmingai atnaujintas įrenginyje.", + "STR_UPDATE_FAILED ":"Atnaujinant įvyko klaida. Galite iš naujo prijungti USB ir bandyti dar kartą. Patikrinkite log.txt, jei norite sužinoti daugiau.", + "STR_WAIT_PROCESS ":"Pradėtas procesas, palaukite ...", + "STR_MENU_OPTION ":"Nustatymai", + "STR_MENU_SECURE_BOOT ":"Secure Boot palaikymas", + "STR_MENU_PART_CFG ":"Skirsnio konfigūracija", + "STR_BTN_OK ":"Gerai", + "STR_BTN_CANCEL ":"Atšaukti", + "STR_PRESERVE_SPACE ":"Rezervuoti vietos įrenginyje", + "STR_SPACE_VAL_INVALID ":"Neteisinga rezervuotos vietos vertė", + "STR_MENU_CLEAR ":"Pašalinti „Ventoy“", + "STR_CLEAR_SUCCESS ":"„Ventoy“ sėkmingai pašalintas iš įrenginio.", + "STR_CLEAR_FAILED ":"Įvyko klaida pašalinant „Ventoy“ iš įrenginio. USB ir bandyti dar kartą. Patikrinkite log.txt, jei norite sužinoti daugiau.", + "STR_MENU_PART_STYLE ":"Skirsnio formatas", + "STR_DISK_2TB_MBR_ERROR ":"Prašome pasirinkti GPT, jei įrenginys didesnis nei 2 TB.", + "STR_SHOW_ALL_DEV":"Show All Devices", + "STR_PART_ALIGN_4KB":"Align partitions with 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STR_MENU_PART_RESIZE":"Non-destructive Install", + "STR_PART_RESIZE_TIP":"Ventoy will try non-destructive installation if possible. #@Continue?", + "STR_PART_RESIZE_SUCCESS":"Congratulations!#@Ventoy non-destructive installation successfully finished.", + "STR_PART_RESIZE_FAILED":"Non-destructive installation failed, Check log.txt for details.", + "STR_PART_RESIZE_UNSUPPORTED":"Ventoy non-destructive installation stopped because some conditions cannot be met. Check log.txt for details.", + "STR_INSTALL_YES_TIP1":"Warning: Data will be lost!", + "STR_INSTALL_YES_TIP2":"Please enter YES in the text box below to confirm that you indeed want to do a fresh install instead of upgrade.", + "STR_PART_VENTOY_FS":"File System For Ventoy Partition", + "STR_PART_FS":"File System", + "STR_PART_CLUSTER":"Cluster Size", + "STR_PART_CLUSTER_DEFAULT":"System Default Value", + "STR_DONATE":"paaukoti", + "STR_4KN_UNSUPPORTED":"Currently Ventoy does not support 4K native devices.", + + "STRXXX":"" + }, + { + "name":"Macedonian (Македонски)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Влатко Стојанов", + + "STR_ERROR":"Грешка", + "STR_WARNING":"Предупредување", + "STR_INFO":"Инфо", + "STR_INCORRECT_DIR":"Ве молам покренете ме од коректната папка!", + "STR_INCORRECT_TREE_DIR":"Не покренувајте ме овде, ве молам превземете ја последната верзија и покренете ме таму.", + "STR_DEVICE":"УСБ уред", + "STR_LOCAL_VER":"Ventoy во пакетот", + "STR_DISK_VER":"Ventoy на УСБ уредот", + "STR_STATUS":"Статус - Спремен", + "STR_INSTALL":"Инсталирај", + "STR_UPDATE":"Ажурирај", + "STR_UPDATE_TIP":"Операцијата ажурирање е безбедна, ISO датотеките нема да бидат променети.#@Продолжи?", + "STR_INSTALL_TIP":"УСБ уредот ќе биде форматиран и сите податоци ќе бидат уништени.#@Продолжи?", + "STR_INSTALL_TIP2":"УСБ уредот ќе биде форматиран и сите податоци ќе бидат уништени.#@Продолжи? (Двојна проверка)", + "STR_INSTALL_SUCCESS":"Честитки!#@Ventoy е успешно инсталиран на УСБ уредот.", + "STR_INSTALL_FAILED":"Се појави грешка при инсталацијата. Отстранете го УСБ уредот и пробајте повторно. Проверете го log.txt за детали.", + "STR_UPDATE_SUCCESS":"Честитки!#@Ventoy е успешно ажуриран на УСБ уредот.", + "STR_UPDATE_FAILED":"Се појави грешка при ажурирањето. Отстранете го УСБ уредот и пробајте повторно. Проверете го log.txt за детали.", + "STR_WAIT_PROCESS":"Процесот е вклучен, ве молиме почекајте...", + "STR_MENU_OPTION":"Опции", + "STR_MENU_SECURE_BOOT":"Secure Boot Поддршка", + "STR_MENU_PART_CFG":"Конфигурирање на партиции", + "STR_BTN_OK":"ОК", + "STR_BTN_CANCEL":"Излез", + "STR_PRESERVE_SPACE":"Резервирај место на крајот на дискот", + "STR_SPACE_VAL_INVALID":"Невалидна вредност за резервираното место", + "STR_MENU_CLEAR":"Отстрани го Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy е успешно отстранет од УСБ уредот.", + "STR_CLEAR_FAILED":"Се појави грешка при отстранувањето на Ventoy од уредот. Отстранете го УСБ уредот и пробајте повторно. Проверете го log.txt за детали.", + "STR_MENU_PART_STYLE":"Тип на партиција", + "STR_DISK_2TB_MBR_ERROR":"Ве молиме изберете GPT за уреди поголеми од 2TB", + "STR_SHOW_ALL_DEV":"Прикажи ги сите уреди", + "STR_PART_ALIGN_4KB":"Порамнете ги партициите со 4KB", + "STR_WEB_COMMUNICATION_ERR":"Комуникациска грешка:", + "STR_WEB_REMOTE_ABNORMAL":"Комуникациска грешка: Абнормално далечинско управување", + "STR_WEB_REQUEST_TIMEOUT":"Комуникациска грешка: Барањето е истечено", + "STR_WEB_SERVICE_UNAVAILABLE":"Комуникациска грешка: Недостапен сервис", + "STR_WEB_TOKEN_MISMATCH":"Ажуриран статус на даемонот, молиме обидете се подоцна.", + "STR_WEB_SERVICE_BUSY":"Сервисот е зафатен, молиме обидете се подоцна.", + "STR_MENU_VTSI_CREATE":"Генерирај VTSI датотека", + "STR_VTSI_CREATE_TIP":"Овој пат ништо нема да се запише на УСБ уредот туку само ќе се генерира VTSI датотека#@Продолжи?", + "STR_VTSI_CREATE_SUCCESS":"Успешно креирана VTSI датотека!#@Можете да го користите Rufus(3.15+) за да ја запишете на уредот како и да ја комплетирате инсталацијата на Ventoy.", + "STR_VTSI_CREATE_FAILED":"Креирањето на VTSI датотека е неуспешно.", + "STR_MENU_PART_RESIZE":"Недеструктивна инсталација", + "STR_PART_RESIZE_TIP":"Ventoy ќе се обиде со недеструктивна инсталација доколку е возможно. #@Продолжи?", + "STR_PART_RESIZE_SUCCESS":"Честитки! Недеструктивната инсталација е успешно завршена.", + "STR_PART_RESIZE_FAILED":"Недеструктивната инсталација не успеа. Проверете го log.txt за детали.", + "STR_PART_RESIZE_UNSUPPORTED":"Недеструктивната инсталација на Ventoy е запрена бидејќи некои услови не се исполнети. Проверете го log.txt за детали.", + "STR_INSTALL_YES_TIP1":"Warning: Data will be lost!", + "STR_INSTALL_YES_TIP2":"Please enter YES in the text box below to confirm that you indeed want to do a fresh install instead of upgrade.", + "STR_PART_VENTOY_FS":"File System For Ventoy Partition", + "STR_PART_FS":"File System", + "STR_PART_CLUSTER":"Cluster Size", + "STR_PART_CLUSTER_DEFAULT":"System Default Value", + "STR_DONATE":"донира", + "STR_4KN_UNSUPPORTED":"Currently Ventoy does not support 4K native devices.", + + "STRXXX":"" + }, + { + "name":"Hebrew (עברית)", + "FontFamily":"tahoma", + "FontSize":16, + "Author":"chaim-chv", + + "STR_ERROR":"תקלה", + "STR_WARNING":"אזהרה", + "STR_INFO":"מידע", + "STR_INCORRECT_DIR":"הרץ בבקשה בתיקייה הנכונה!", + "STR_INCORRECT_TREE_DIR":"אל תריץ אותי כאן. בבקשה הורד את חבילת ההתקנה ששוחררה, ותריץ אותי שם.", + "STR_DEVICE":"התקן", + "STR_LOCAL_VER":"גרסת Ventoy מקומית", + "STR_DISK_VER":"גרסת Ventoy בהתקן", + "STR_STATUS":"סטטוס - מוכן", + "STR_INSTALL":"התקנה", + "STR_UPDATE":"עדכון", + "STR_UPDATE_TIP":"אופציית העדכון היא בטוחה לשימוש. קבצי ה-ISO לא ייפגעו.#@להמשיך?", + "STR_INSTALL_TIP":"הדיסק יפורמט וכל המידע שבו ייעלם.#@להמשיך?", + "STR_INSTALL_TIP2":"הדיסק יפורמט וכל המידע שבו ייעלפ ויימחק לחלוטין.#@להמשיך? (בדיקה לווידוא)", + "STR_INSTALL_SUCCESS":"הצלחה!#@Ventoy הותקנה בהצלחה על הדיסק הנבחר", + "STR_INSTALL_FAILED":"אירעה תקלה בניסיון ההתקנה. אפשר לנסות לחבר את הדיסק מחדש ולבצע ניסיון התקנה נוסף. עיין בקובץ ה-log.txt לפרטים נוספים.", + "STR_UPDATE_SUCCESS":"הצלחה!#@Ventoy הותקנה בהצלחה על הדיסק הנבחר", + "STR_UPDATE_FAILED":"אירעה תקלה בניסיון העדכון. אפשר לנסות לחבר את הדיסק מחדש ולבצע ניסיון נוסף לעדכון. עיין בקובץ ה-log.txt לפרטים נוספים.", + "STR_WAIT_PROCESS":"עובד... נא המתן", + "STR_MENU_OPTION":"אפשרויות", + "STR_MENU_SECURE_BOOT":"תמיכה ב-Secure Boot", + "STR_MENU_PART_CFG":"הגדרת מחיצות", + "STR_BTN_OK":"אישור", + "STR_BTN_CANCEL":"ביטול", + "STR_PRESERVE_SPACE":"הגדר מקום לשמירה בדיסק", + "STR_SPACE_VAL_INVALID":"ערך לא חוקי עבור שטח לשמירה", + "STR_MENU_CLEAR":"נקה את Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy נמחקה בהצלחה מהדיסק הנבחר.", + "STR_CLEAR_FAILED":"אירעה תקלה בניסיון למחוק את Ventoy מהדיסק הנבחר. אפשר לנסות לחבר את הדיסק מחדש ולבצע שוב מחיקה. עיין בקובץ ה-log.txt לפרטים נוספים.", + "STR_MENU_PART_STYLE":"סוג מחיצה", + "STR_DISK_2TB_MBR_ERROR":"בחר ב-GPT עבור דיסק שגדול מ-2TB", + "STR_SHOW_ALL_DEV":"Show All Devices", + "STR_PART_ALIGN_4KB":"Align partitions with 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STR_MENU_PART_RESIZE":"Non-destructive Install", + "STR_PART_RESIZE_TIP":"Ventoy will try non-destructive installation if possible. #@Continue?", + "STR_PART_RESIZE_SUCCESS":"Congratulations!#@Ventoy non-destructive installation successfully finished.", + "STR_PART_RESIZE_FAILED":"Non-destructive installation failed, Check log.txt for details.", + "STR_PART_RESIZE_UNSUPPORTED":"Ventoy non-destructive installation stopped because some conditions cannot be met. Check log.txt for details.", + "STR_INSTALL_YES_TIP1":"Warning: Data will be lost!", + "STR_INSTALL_YES_TIP2":"Please enter YES in the text box below to confirm that you indeed want to do a fresh install instead of upgrade.", + "STR_PART_VENTOY_FS":"File System For Ventoy Partition", + "STR_PART_FS":"File System", + "STR_PART_CLUSTER":"Cluster Size", + "STR_PART_CLUSTER_DEFAULT":"System Default Value", + "STR_DONATE":"לִתְרוֹם", + "STR_4KN_UNSUPPORTED":"Currently Ventoy does not support 4K native devices.", + + "STRXXX":"" + }, + { + "name":"Portuguese (Português de Portugal)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Eskiso, Hugo Carvalho", + + "STR_ERROR":"Erro", + "STR_WARNING":"Aviso", + "STR_INFO":"Informação", + "STR_INCORRECT_DIR":"Execute na pasta correta!", + "STR_INCORRECT_TREE_DIR":"Não me execute aqui, transfira o pacote de instalação e execute lá.", + "STR_DEVICE":"Dispositivo", + "STR_LOCAL_VER":"Ventoy em pacote", + "STR_DISK_VER":"Ventoy no dispositivo", + "STR_STATUS":"Estado - PRONTO", + "STR_INSTALL":"Instalar", + "STR_UPDATE":"Atualizar", + "STR_UPDATE_TIP":"A operação de atualização é segura, os ficheiros ISO não serão alterados.#@Continuar?", + "STR_INSTALL_TIP":"O disco será formatado e todos os dados serão perdidos.#@Continuar?", + "STR_INSTALL_TIP2":"O disco será formatado e todos os dados serão perdidos.#@Continuar? (Confirmação)", + "STR_INSTALL_SUCCESS":"Parabéns!#@Ventoy foi instalado com sucesso no dispositivo.", + "STR_INSTALL_FAILED":"Ocorreu um erro durante a instalação. Pode voltar a ligar o dispositivo USB e tentar novamente. Verifique o ficheiro log.txt para mais detalhes.", + "STR_UPDATE_SUCCESS":"Parabéns!#@Ventoy foi atualizado com sucesso no dispositivo.", + "STR_UPDATE_FAILED":"Ocorreu um erro durante a atualização. Pode voltar a ligar o dispositivo USB e tentar novamente. Verifique o ficheiro log.txt para mais detalhes.", + "STR_WAIT_PROCESS":"Uma thread está em execução, aguarde...", + "STR_MENU_OPTION":"Opção", + "STR_MENU_SECURE_BOOT":"Arranque seguro", + "STR_MENU_PART_CFG":"Configuração da partição", + "STR_BTN_OK":"Aceitar", + "STR_BTN_CANCEL":"Cancelar", + "STR_PRESERVE_SPACE":"Reservar algum espaço no final do disco", + "STR_SPACE_VAL_INVALID":"Valor inválido para o espaço reservado", + "STR_MENU_CLEAR":"Remover o Ventoy", + "STR_CLEAR_SUCCESS":"O Ventoy foi removido deste dispositivo com sucesso.", + "STR_CLEAR_FAILED":"Um erro ocorreu ao remover o Ventoy do disco. Pode voltar a ligar o dispositivo USB e tentar novamente. Verifique o ficheiro log.txt para mais detalhes.", + "STR_MENU_PART_STYLE":"Estilo de partição", + "STR_DISK_2TB_MBR_ERROR":"Selecione GPT para discos maiores que 2TB", + "STR_SHOW_ALL_DEV":"Mostrar todos os dispositivos", + "STR_PART_ALIGN_4KB":"Alinhar as partições com 4KB", + "STR_WEB_COMMUNICATION_ERR":"Erro de comunicação:", + "STR_WEB_REMOTE_ABNORMAL":"Erro de comunicação: Anomalia remota", + "STR_WEB_REQUEST_TIMEOUT":"Erro de comunicação: Pedido de tempo limite", + "STR_WEB_SERVICE_UNAVAILABLE":"Erro de comunicação: Serviço indisponível", + "STR_WEB_TOKEN_MISMATCH":"Estado do daemon atualizado, tente novamente mais tarde.", + "STR_WEB_SERVICE_BUSY":"Serviço está ocupado, tente novamente mais tarde.", + "STR_MENU_VTSI_CREATE":"Gerar ficheiro VTSI", + "STR_VTSI_CREATE_TIP":"Desta vez não irá gravar no dispositivo, mas apenas gerar um ficheiro VTSI#@Continuar?", + "STR_VTSI_CREATE_SUCCESS":"Ficheiro VTSI criado com sucesso!#@Pode utilizar o Rufus(3.15+) para o gravar no dispositivo de modo a completar a instalação do Ventoy.", + "STR_VTSI_CREATE_FAILED":"Falha no ficheiro VTSI criado.", + "STR_MENU_PART_RESIZE":"Instalação não destrutiva", + "STR_PART_RESIZE_TIP":"O Ventoy tentará uma instalação não destrutiva, se possível. #@Continuar?", + "STR_PART_RESIZE_SUCCESS":"Parabéns!#@Instalação não destrutiva do Ventoy concluída com sucesso.", + "STR_PART_RESIZE_FAILED":"Falha na instalação não destrutiva. Leia o ficheiro log.txt para mais detalhes.", + "STR_PART_RESIZE_UNSUPPORTED":"A instalação não destrutiva do Ventoy foi interrompida porque algumas condições não podem ser cumpridas. Leia o ficheiro log.txt para mais detalhes.", + "STR_INSTALL_YES_TIP1":"Aviso: Os dados serão perdidos!", + "STR_INSTALL_YES_TIP2":"Escreva YES na caixa de texto abaixo para confirmar que deseja de facto fazer uma nova instalação em vez de uma atualização.", + "STR_PART_VENTOY_FS":"Sistema de ficheiros para a partição Ventoy", + "STR_PART_FS":"Sistema de ficheiros", + "STR_PART_CLUSTER":"Tamanho do cluster", + "STR_PART_CLUSTER_DEFAULT":"Valor predefinido do sistema", + "STR_DONATE":"Doar", + "STR_4KN_UNSUPPORTED":"Atualmente, o Ventoy não é compatível com dispositivos nativos 4K.", + + "STRXXX":"" + }, + { + "name":"Indonesian (Bahasa Indonesia)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Ida Bagus Anom Sanjaya", + + "STR_ERROR":"Kesalahan", + "STR_WARNING":"Peringatan", + "STR_INFO":"Informasi", + "STR_INCORRECT_DIR":"Silakan jalankan pada direktori yang benar!", + "STR_INCORRECT_TREE_DIR":"Jangan jalankan di sini, silakan unduh paket pemasangan yang diliris, dan jalankan di sana.", + "STR_DEVICE":"Perangkat", + "STR_LOCAL_VER":"Ventoy pada Paket", + "STR_DISK_VER":"Ventoy pada Perangkat", + "STR_STATUS":"Status - SIAP", + "STR_INSTALL":"Pasang", + "STR_UPDATE":"Perbarui", + "STR_UPDATE_TIP":"Operasi pembaruan ini aman, tidak akan ada perubahan pada berkas ISO.#@Lanjutkan?", + "STR_INSTALL_TIP":"Disk akan di-format dan semua data akan hilang.#@Lanjutkan?", + "STR_INSTALL_TIP2":"Disk akan di-format dan semua data akan hilang.#@Lanjutkan? (YAKIN)", + "STR_INSTALL_SUCCESS":"Selamat!#@Ventoy telah berhasil terpasang di perangkat ini.", + "STR_INSTALL_FAILED":"Terjadi kesalahan ketika pemasangan berlangsung. Anda perlu mencabut-pasang ulang USB dan coba lagi. Cek log.txt untuk detil.", + "STR_UPDATE_SUCCESS":"Selamat!#@Ventoy telah berhasil diperbarui di perangkat ini.", + "STR_UPDATE_FAILED":"Terjadi kesalahan ketika pembaruan berlangsung. Anda perlu mencabut-pasang ulang USB dan coba lagi. Cek log.txt untuk detil.", + "STR_WAIT_PROCESS":"Tugas sedang berjalan, silakan tunggu...", + "STR_MENU_OPTION":"Pilihan", + "STR_MENU_SECURE_BOOT":"Dukungan Secure Boot", + "STR_MENU_PART_CFG":"Konfigurasi Partisi", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Batal", + "STR_PRESERVE_SPACE":"Pertahankan sisa ruang penyimpanan pada disk ini", + "STR_SPACE_VAL_INVALID":"Nilai sisa ruang tidak valid", + "STR_MENU_CLEAR":"Bersihkan Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy telah berhasil dihapus pada perangkat ini.", + "STR_CLEAR_FAILED":"Terjadi kesalahan ketika penghapusan berlangsung. Anda perlu mencabut-pasang ulang USB dan coba lagi. Periksa berkas log.txt untuk detil.", + "STR_MENU_PART_STYLE":"Model Partisi", + "STR_DISK_2TB_MBR_ERROR":"Silakan pilih GPT untuk disk yang lebih dari 2TB", + "STR_SHOW_ALL_DEV":"Tampilkan semua perangkat", + "STR_PART_ALIGN_4KB":"Mensejajarkan dengan partisi 4KB", + "STR_WEB_COMMUNICATION_ERR":"Kesalahan komunikasi:", + "STR_WEB_REMOTE_ABNORMAL":"Kesalahan komunikasi: pengendali bermasalah", + "STR_WEB_REQUEST_TIMEOUT":"Kesalahan komunikasi: Waktu permintaan habis", + "STR_WEB_SERVICE_UNAVAILABLE":"Kesalahan komunikasi: Layanan tidak tersedia", + "STR_WEB_TOKEN_MISMATCH":"Status daemon diperbarui, silakan coba lagi nanti.", + "STR_WEB_SERVICE_BUSY":"Layanan sedang sibuk, silakan coba lagi nanti.", + "STR_MENU_VTSI_CREATE":"Membuat berkas VTSI", + "STR_VTSI_CREATE_TIP":"Saat ini tidak akan menuliskan di perangkat, tetapi hanya membuat berkas VTSI #@Lanjutkan?", + "STR_VTSI_CREATE_SUCCESS":"Berkas VTSI berhasil dibuat#@Anda bisa menggunakan Rufus(3.15+) untuk menuliskannya ke perangkat untuk menyelesaikan pemasangan Ventoy.", + "STR_VTSI_CREATE_FAILED":"Berkas VTSI gagal dibuat.", + "STR_MENU_PART_RESIZE":"Pemasangan tanpa merusakkan", + "STR_PART_RESIZE_TIP":"Ventoy akan mencoba pemasangan tanpa merusakkan apabila memungkinkan. #@Lanjutkan?", + "STR_PART_RESIZE_SUCCESS":"Selamat!#@Pemasangan tanpa merusakkan Ventoy berhasil.", + "STR_PART_RESIZE_FAILED":"Pemasangan tanpa merusakkan gagal, periksa berkas log.txt untuk detil.", + "STR_PART_RESIZE_UNSUPPORTED":"Pemasangan tanpa merusakkan Ventoy terhenti karena beberapa kondisi yang tidak mendukung. Periksa berkas log.txt untuk detil.", + "STR_INSTALL_YES_TIP1":"Peringatan: Data akan hilang!", + "STR_INSTALL_YES_TIP2":"Silakan ketik YES pada kotak tulis di bawah untuk mengonfirmasikan bahwa anda memang yakin melakukan pemasangan baru ketimbang memperbaruinya", + "STR_PART_VENTOY_FS":"Sistem Berkas Untuk Partisi Ventoy", + "STR_PART_FS":"Sistem Berkas", + "STR_PART_CLUSTER":"Ukuran Kluster", + "STR_PART_CLUSTER_DEFAULT":"Nilai Standar Sistem", + "STR_DONATE":"Donasi sukarela", + "STR_4KN_UNSUPPORTED":"Saat ini Ventoy tidak mendukung perangkat 4K yang asli.", + + "STRXXX":"" + }, + { + "name":"Norwegian Bokmål (Norsk Bokmål)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Allan Nordhøy", + + "STR_ERROR":"Feil", + "STR_WARNING":"Advarsel", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Start programmet i rett mappe først.", + "STR_INCORRECT_TREE_DIR":"Ikke kjør meg her. Last ned utgitt installasjonspakke og kjør det der.", + "STR_DEVICE":"Enhet", + "STR_LOCAL_VER":"Ventoy i pakke", + "STR_DISK_VER":"Ventoy i enhet", + "STR_STATUS":"Status — Klar", + "STR_INSTALL":"Installer", + "STR_UPDATE":"Updater", + "STR_UPDATE_TIP":"Oppgradering er trygt. ISO-filer vil forbli uendret.#@Fortsett?", + "STR_INSTALL_TIP":"Enheten vil bli formatert og all data på den vil gå tapt.#@Fortsett?", + "STR_INSTALL_TIP2":"Enheten vil bli formatert og all data på den vil gå tapt.#@Fortsett? (Dobbeltsjekk)", + "STR_INSTALL_SUCCESS":"Gratulerer!#@Ventoy har blitt installert på enheten.", + "STR_INSTALL_FAILED":"Noe gikk galt under installasjonen. Du kan plugge ut og inn USB-enheten og prøve igjen. Sjekk log.txt for detaljer. Hvis feilen vedvarer kan du sjekke O-S-S på nettsiden.", + "STR_UPDATE_SUCCESS":"Gratulerer!#@Ventoy har blitt installert på enheten.", + "STR_UPDATE_FAILED":"Noe gikk galt under oppdateringen. Du kan plugge ut og inn USB-enheten og prøve igjen. Sjekk log.txt for detaljer. Hvis feilen vedvarer kan du sjekke O-S-S på nettsiden.", + "STR_WAIT_PROCESS":"Vent mens en tråd kjører …", + "STR_MENU_OPTION":"Alternativ", + "STR_MENU_SECURE_BOOT":"Secure Boot-støtte", + "STR_MENU_PART_CFG":"Partisjonsoppsett", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Avbryt", + "STR_PRESERVE_SPACE":"Hold av litt plass på slutten av disken", + "STR_SPACE_VAL_INVALID":"Ugyldig verdi for avholdt plass", + "STR_MENU_CLEAR":"Tøm Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy har blitt fjernet fra enheten.", + "STR_CLEAR_FAILED":"Noe gikk galt ved fjerning av Ventoy fra disken. Du kan plugge ut og inn USB-enheten og prøve igjen. Sjekk log.txt for detaljer.", + "STR_MENU_PART_STYLE":"Partisjonsstil", + "STR_DISK_2TB_MBR_ERROR":"Velg «GPT» for enheter over 2 TB", + "STR_SHOW_ALL_DEV":"Vis alle enheter", + "STR_PART_ALIGN_4KB":"Juster partisjoner til 4 KB", + "STR_WEB_COMMUNICATION_ERR":"Kommunikasjonsfeil:", + "STR_WEB_REMOTE_ABNORMAL":"Kommunikasjonsfeil: Noe er galt annensteds hen", + "STR_WEB_REQUEST_TIMEOUT":"Kommunikasjonsfeil: Tidsavbrudd for forespørsel", + "STR_WEB_SERVICE_UNAVAILABLE":"Kommunikasjonsfeil: Utilgjengelig tjeneste", + "STR_WEB_TOKEN_MISMATCH":"Nisse-status oppdatert. Prøv igjen senere.", + "STR_WEB_SERVICE_BUSY":"Tjensten er opptatt. Prøv igjen senere.", + "STR_MENU_VTSI_CREATE":"Generer VTSI-fil", + "STR_VTSI_CREATE_TIP":"Dette vil ikke skrive til enheten, men kun generere en VTSIfil#@Fortsett?", + "STR_VTSI_CREATE_SUCCESS":"VTSI-fil opprettet.#@Du kan bruke Rufus(3.15+) til å skrive den til enheten for å fullføre installasjonen av Ventoy.", + "STR_VTSI_CREATE_FAILED":"Noe gikk galt under opprettelse av VTSI-fil.", + "STR_MENU_PART_RESIZE":"Non-destructive Install", + "STR_PART_RESIZE_TIP":"Ventoy will try non-destructive installation if possible. #@Continue?", + "STR_PART_RESIZE_SUCCESS":"Congratulations!#@Ventoy non-destructive installation successfully finished.", + "STR_PART_RESIZE_FAILED":"Non-destructive installation failed, Check log.txt for details.", + "STR_PART_RESIZE_UNSUPPORTED":"Ventoy non-destructive installation stopped because some conditions cannot be met. Check log.txt for details.", + "STR_INSTALL_YES_TIP1":"Warning: Data will be lost!", + "STR_INSTALL_YES_TIP2":"Please enter YES in the text box below to confirm that you indeed want to do a fresh install instead of upgrade.", + "STR_PART_VENTOY_FS":"File System For Ventoy Partition", + "STR_PART_FS":"File System", + "STR_PART_CLUSTER":"Cluster Size", + "STR_PART_CLUSTER_DEFAULT":"System Default Value", + "STR_DONATE":"Donere", + "STR_4KN_UNSUPPORTED":"Currently Ventoy does not support 4K native devices.", + + "STRXXX":"" + }, + { + "name":"Ukrainian (Українська)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Teraskull, thehugonote, dmitrygribenchuk", + + "STR_ERROR":"Помилка", + "STR_WARNING":"Попередження", + "STR_INFO":"Інформація", + "STR_INCORRECT_DIR":"Будь ласка, запустіть у правильному каталозі!", + "STR_INCORRECT_TREE_DIR":"Не запускайте мене тут, завантажте реліз інсталяційного пакету і запустіть там.", + "STR_DEVICE":"Пристрій", + "STR_LOCAL_VER":"Ventoy в пакеті", + "STR_DISK_VER":"Ventoy на пристрої", + "STR_STATUS":"Стан - ГОТОВИЙ", + "STR_INSTALL":"Встановити", + "STR_UPDATE":"Оновити", + "STR_UPDATE_TIP":"Процес оновлення безпечний, файли ISO залишаться незмінними.#@Продовжити?", + "STR_INSTALL_TIP":"Диск буде відформатовано, і всі дані будуть втрачені.#@Продовжити?", + "STR_INSTALL_TIP2":"Диск буде відформатовано, і всі дані будуть втрачені.#@Ви дійсно хочете продовжити?", + "STR_INSTALL_SUCCESS":"Вітаємо!#@Ventoy успішно встановлено на пристрій.", + "STR_INSTALL_FAILED":"Під час встановлення сталася помилка. Ви можете ще раз підключити USB і повторити спробу. Перевірте log.txt для отримання детальної інформації.", + "STR_UPDATE_SUCCESS":"Вітаємо!#@Ventoy на пристрої успішно оновлено.", + "STR_UPDATE_FAILED":"Під час оновлення сталася помилка. Ви можете ще раз підключити USB і повторити спробу. Перевірте log.txt для отримання детальної інформації.", + "STR_WAIT_PROCESS":"Потік запущено, зачекайте...", + "STR_MENU_OPTION":"Опції", + "STR_MENU_SECURE_BOOT":"Підтримка Secure Boot", + "STR_MENU_PART_CFG":"Конфігурація розділів", + "STR_BTN_OK":"ОК", + "STR_BTN_CANCEL":"Скасувати", + "STR_PRESERVE_SPACE":"Зарезервувати простір в кінці диска", + "STR_SPACE_VAL_INVALID":"Недійсне значення для зарезервованого простору", + "STR_MENU_CLEAR":"Видалити Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy успішно видалено з пристрою.", + "STR_CLEAR_FAILED":"Під час видалення Ventoy сталася помилка. Ви можете ще раз підключити USB і повторити спробу. Перевірте log.txt для отримання детальної інформації.", + "STR_MENU_PART_STYLE":"Стиль розмітки розділів", + "STR_DISK_2TB_MBR_ERROR":"Будь ласка, виберіть GPT для дисків понад 2TB", + "STR_SHOW_ALL_DEV":"Показати всі пристрої", + "STR_PART_ALIGN_4KB":"Вирівняти розділи з розміром 4КБ", + "STR_WEB_COMMUNICATION_ERR":"Помилка зв'язку: ", + "STR_WEB_REMOTE_ABNORMAL":"Помилка зв'язку: віддалене з'єднання недійсне", + "STR_WEB_REQUEST_TIMEOUT":"Помилка зв'язку: Час очікування запиту минув", + "STR_WEB_SERVICE_UNAVAILABLE":"Помилка зв'язку: Служба недоступна", + "STR_WEB_TOKEN_MISMATCH":"Статус демона оновлено. Повторіть спробу пізніше.", + "STR_WEB_SERVICE_BUSY":"Служба зайнята, повторіть спробу пізніше.", + "STR_MENU_VTSI_CREATE":"Створити файл VTSI", + "STR_VTSI_CREATE_TIP":"Цього разу Ventoy не буде встановлено на пристрій, а лише буде створено файл VTSI#@Продовжити?", + "STR_VTSI_CREATE_SUCCESS":"Файл VTSI створено успішно!#@Ви можете використати Rufus(3.15+), щоб записати його на пристрій, для завершення встановлення Ventoy", + "STR_VTSI_CREATE_FAILED":"Не вдалося створити файл VTSI.", + "STR_MENU_PART_RESIZE":"Неруйнівна установка", + "STR_PART_RESIZE_TIP":"Ventoy спробує виконати неруйнівну установку, якщо це можливо. #@Продовжити?", + "STR_PART_RESIZE_SUCCESS":"Вітаємо!#@Неруйнівна установка Ventoy успішно завершена.", + "STR_PART_RESIZE_FAILED":"Збій неруйнівної установки, перевірте log.txt для отримання детальної інформації.", + "STR_PART_RESIZE_UNSUPPORTED":"Неруйнівна установка Ventoy зупинена через неможливість виконання деяких умов. Перевірте log.txt для отримання детальної інформації.", + "STR_INSTALL_YES_TIP1":"Попередження: дані будуть втрачені!", + "STR_INSTALL_YES_TIP2":"Будь ласка, введіть ТАК у текстове поле нижче, щоб підтвердити, що ви справді бажаєте виконати нове встановлення замість оновлення.", + "STR_PART_VENTOY_FS":"Файлова система для розділу Ventoy", + "STR_PART_FS":"Файлова система", + "STR_PART_CLUSTER":"Розмір кластера", + "STR_PART_CLUSTER_DEFAULT":"Системне значення за умовчанням", + "STR_DONATE":"Пожертвуйте", + "STR_4KN_UNSUPPORTED":"Наразі Ventoy не підтримує рідні пристрої 4K.", + + "STRXXX":"" + }, + { + "name":"Greek (Ελληνικά)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"grmasa, Vasilis Kosmidis", + + "STR_ERROR":"Σφάλμα", + "STR_WARNING":"Προειδοποίηση", + "STR_INFO":"Πληροφορίες", + "STR_INCORRECT_DIR":"Παρακαλώ εκτελέστε στον σωστό κατάλογο!", + "STR_INCORRECT_TREE_DIR":"Μην με εκτελείτε εδώ, κατεβάστε το πακέτο εγκατάστασης και εκτελέστε εκεί.", + "STR_DEVICE":"Συσκευή", + "STR_LOCAL_VER":"Ventoy στο πρόγραμμα", + "STR_DISK_VER":"Ventoy στη συσκευή", + "STR_STATUS":"Κατάσταση - ΕΤΟΙΜΟ", + "STR_INSTALL":"Εγκατάσταση", + "STR_UPDATE":"Αναβάθμιση", + "STR_UPDATE_TIP":"Η λειτουργία αναβάθμισης είναι ασφαλής, τα αρχεία ISO δεν θα αλλάξουν.#@Συνέχεια;", + "STR_INSTALL_TIP":"Ο δίσκος θα μορφοποιηθεί και όλα τα δεδομένα θα χαθούν.#@Συνέχεια;", + "STR_INSTALL_TIP2":"Ο δίσκος θα μορφοποιηθεί και όλα τα δεδομένα θα χαθούν.#@Συνέχεια; (Επανελέγξτε)", + "STR_INSTALL_SUCCESS":"Συγχαρητήρια!#@Ventoy έχει εγκατασταθεί με επιτυχία στη συσκευή.", + "STR_INSTALL_FAILED":"Παρουσιάστηκε σφάλμα κατά την εγκατάσταση. Μπορείτε να επανασυνδέσετε το USB και να δοκιμάσετε ξανά. Ελέγξτε το αρχείο log.txt για λεπτομέρειες.", + "STR_UPDATE_SUCCESS":"Συγχαρητήρια!#@Ventoy ενημερώθηκε με επιτυχία στη συσκευή.", + "STR_UPDATE_FAILED":"Παρουσιάστηκε σφάλμα κατά την ενημέρωση. Μπορείτε να επανασυνδέσετε το USB και να δοκιμάσετε ξανά. Ελέγξτε το αρχείο log.txt για λεπτομέρειες.", + "STR_WAIT_PROCESS":"Μια εργασία εκτελείται, παρακαλώ περιμένετε...", + "STR_MENU_OPTION":"Επιλογές", + "STR_MENU_SECURE_BOOT":"Υποστήριξη ασφαλούς εκκίνησης (Secure Boot)", + "STR_MENU_PART_CFG":"Διαμόρφωση κατατμήσεων", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Ακύρωση", + "STR_PRESERVE_SPACE":"Διατηρήστε λίγο χώρο στο κάτω μέρος του δίσκου", + "STR_SPACE_VAL_INVALID":"Μη έγκυρη τιμή για τον δεσμευμένο χώρο", + "STR_MENU_CLEAR":"Κατάργηση του Ventoy", + "STR_CLEAR_SUCCESS":"Το Ventoy καταργήθηκε με επιτυχία από τη συσκευή.", + "STR_CLEAR_FAILED":"Παρουσιάστηκε σφάλμα κατά την εκκαθάριση του Ventoy από το δίσκο. Μπορείτε να επανασυνδέσετε το USB και να δοκιμάσετε ξανά. Ελέγξτε το αρχείο log.txt για λεπτομέρειες.", + "STR_MENU_PART_STYLE":"Στυλ κατατμήσεων", + "STR_DISK_2TB_MBR_ERROR":"Παρακαλώ επιλέξτε GPT για δίσκο άνω των 2 TB", + "STR_SHOW_ALL_DEV":"Προβολή όλων των συσκευών", + "STR_PART_ALIGN_4KB":"Ευθυγράμμιση κατατμήσεων με 4KB", + "STR_WEB_COMMUNICATION_ERR":"Σφάλμα επικοινωνίας:", + "STR_WEB_REMOTE_ABNORMAL":"Σφάλμα επικοινωνίας: απομακρυσμένη ανωμαλία", + "STR_WEB_REQUEST_TIMEOUT":"Σφάλμα επικοινωνίας: χρονική λήξη αιτήματος", + "STR_WEB_SERVICE_UNAVAILABLE":"Σφάλμα επικοινωνίας: υπηρεσία μη διαθέσιμη", + "STR_WEB_TOKEN_MISMATCH":"Η κατάσταση του δαίμονα επικαιροποιήθηκε. Παρακαλώ δοκιμάστε αργότερα.", + "STR_WEB_SERVICE_BUSY":"Η υπηρεσία είναι απασχολημένη. Παρακαλώ δοκιμάστε αργότερα.", + "STR_MENU_VTSI_CREATE":"Δημιουργία αρχείου VTSI", + "STR_VTSI_CREATE_TIP":"Αυτή τη φορά δε θα γράψει στη συσκευή, αλλά θα δημιουργήσει μόνο ένα αρχείο VTSI#@Συνέχεια;", + "STR_VTSI_CREATE_SUCCESS":"Το αρχείο VTSI δημιουργήθηκε με επιτυχία!#@Μπορείτε να χρησιμοποιήσετε το Rufus(3.15+) για να το γράψετε στη συσκευή ώστε να ολοκληρώσετε την εγκατάσταση του Ventoy.", + "STR_VTSI_CREATE_FAILED":"Αποτυχία δημιουργίας αρχείου VTSI.", + "STR_MENU_PART_RESIZE":"Μη καταστροφική εγκατάσταση", + "STR_PART_RESIZE_TIP":"Το Ventoy θα δοκιμάσει μη καταστροφική εγκατάσταση, αν είναι δυνατόν. #@Συνέχεια;", + "STR_PART_RESIZE_SUCCESS":"Συγχαρητήρια!#@Η μη καταστροφική εγκατάσταση του Ventoy ολοκληρώθηκε με επιτυχία.", + "STR_PART_RESIZE_FAILED":"Η μη καταστροφική εγκατάσταση απέτυχε. Ελέγξτε το log.txt για λεπτομέρειες.", + "STR_PART_RESIZE_UNSUPPORTED":"Η μη καταστρεπτική εγκατάσταση του Ventoy σταμάτησε επειδή δεν μπορούν να τηρηθούν ορισμένες προϋποθέσεις. Ελέγξτε το log.txt για λεπτομέρειες.", + "STR_INSTALL_YES_TIP1":"Προειδοποίηση: Τα δεδομένα θα χαθούν!", + "STR_INSTALL_YES_TIP2":"Εισάγετε ΝΑΙ στο παρακάτω πλαίσιο κειμένου για να επιβεβαιώσετε ότι όντως θέλετε να κάνετε μια νέα εγκατάσταση αντί για αναβάθμιση.", + "STR_PART_VENTOY_FS":"Σύστημα αρχείων για το διαμέρισμα Ventoy", + "STR_PART_FS":"Σύστημα αρχείων", + "STR_PART_CLUSTER":"Μέγεθος συμπλέγματος", + "STR_PART_CLUSTER_DEFAULT":"Προεπιλεγμένη τιμή συστήματος", + "STR_DONATE":"Δωρεά", + "STR_4KN_UNSUPPORTED":"Επί του παρόντος, το Ventoy δεν υποστηρίζει εγγενείς συσκευές 4K.", + + "STRXXX":"" + }, + + { + "name":"Swedish (Svenska)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Sopor", + + "STR_ERROR":"Fel", + "STR_WARNING":"Varning", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Kör programmet från korrekt katalog!", + "STR_INCORRECT_TREE_DIR":"Kör inte programmet här. Ladda ner installationspaketet och kör programmet där.", + "STR_DEVICE":"Enhet", + "STR_LOCAL_VER":"Ventoy i paketet", + "STR_DISK_VER":"Ventoy på enheten", + "STR_STATUS":"Status - REDO", + "STR_INSTALL":"Installera", + "STR_UPDATE":"Uppdatera", + "STR_UPDATE_TIP":"Uppdateringen är säker, ISO-filerna kommer att vara oförändrade.#@Fortsätta?", + "STR_INSTALL_TIP":"Enheten kommer att formateras och all data kommer att gå förlorad.#@Fortsätta?", + "STR_INSTALL_TIP2":"Enheten kommer att formateras och all data kommer att gå förlorad.#@Fortsätta? (Sista varningen!)", + "STR_INSTALL_SUCCESS":"Gratulerar!#@Ventoy har installerats på enheten.", + "STR_INSTALL_FAILED":"Ett fel inträffade under installationen. Prova att återansluta USB-enheten och försök igen. Läs i log.txt för mer information.", + "STR_UPDATE_SUCCESS":"Gratulerar!#@Ventoy har uppdaterats på enheten.", + "STR_UPDATE_FAILED":"Ett fel inträffade under uppdateringen. Prova att återansluta USB-enheten och försök igen. Läs i log.txt för mer information.", + "STR_WAIT_PROCESS":"En tråd körs redan, vänta...", + "STR_MENU_OPTION":"Alternativ", + "STR_MENU_SECURE_BOOT":"Stöd för säker start", + "STR_MENU_PART_CFG":"Partitionskonfiguration", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Avbryt", + "STR_PRESERVE_SPACE":"Spara lite utrymme i slutet av enheten", + "STR_SPACE_VAL_INVALID":"Ogiltigt värde för reserverat utrymme", + "STR_MENU_CLEAR":"Ta bort Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy har tagits bort från enheten.", + "STR_CLEAR_FAILED":"Ett fel inträffade när Ventoy skulle tas bort från enheten. Prova att återansluta USB-enheten och försök igen. Läs i log.txt för mer information.", + "STR_MENU_PART_STYLE":"Partitionsstil", + "STR_DISK_2TB_MBR_ERROR":"Välj GPT för enhet över 2 TB", + "STR_SHOW_ALL_DEV":"Visa alla enheter", + "STR_PART_ALIGN_4KB":"Justera partitioner med 4KB", + "STR_WEB_COMMUNICATION_ERR":"Kommunikationsfel:", + "STR_WEB_REMOTE_ABNORMAL":"Kommunikationsfel: onormal fjärr", + "STR_WEB_REQUEST_TIMEOUT":"Kommunikationsfel: Begäran tog för lång tid", + "STR_WEB_SERVICE_UNAVAILABLE":"Kommunikationsfel: Tjänsten är inte tillgänglig", + "STR_WEB_TOKEN_MISMATCH":"Daemon-status uppdaterad. Försök igen senare.", + "STR_WEB_SERVICE_BUSY":"Tjänsten är upptagen. Försök igen senare.", + "STR_MENU_VTSI_CREATE":"Skapa VTSI-fil", + "STR_VTSI_CREATE_TIP":"Den här gången skrivs det inget till enheten, utan det skapas endast en VTSI-fil#@Fortsätta?", + "STR_VTSI_CREATE_SUCCESS":"VTSI-filen skapad!#@Använd Rufus (3.15+) till att skriva till enheten för att slutföra installationen av Ventoy.", + "STR_VTSI_CREATE_FAILED":"Misslyckades med att skapa VTSI-filen.", + "STR_MENU_PART_RESIZE":"Icke-förstörande installation", + "STR_PART_RESIZE_TIP":"Om det är möjligt kommer Ventoy att försöka göra en icke-förstörande installation. #@Fortsätta?", + "STR_PART_RESIZE_SUCCESS":"Gratulerar!#@Ventoy lyckades slutföra en icke-förstörande installation.", + "STR_PART_RESIZE_FAILED":"Ventoy misslyckades slutföra en icke-förstörande installation. Mer information finns i log.txt.", + "STR_PART_RESIZE_UNSUPPORTED":"Icke-förstörande installation stoppades eftersom vissa villkor inte kunde uppfyllas. Mer information finns i log.txt.", + "STR_INSTALL_YES_TIP1":"Varning: Data kommer att gå förlorad!", + "STR_INSTALL_YES_TIP2":"Skriv YES i textrutan nedan för att bekräfta att du verkligen vill göra en nyinstallation i stället för att uppgradera.", + "STR_PART_VENTOY_FS":"Filsystem för Ventoy-partition", + "STR_PART_FS":"Filsystem", + "STR_PART_CLUSTER":"Klusterstorlek", + "STR_PART_CLUSTER_DEFAULT":"Systemets standardvärde", + "STR_DONATE":"Donera", + "STR_4KN_UNSUPPORTED":"För närvarande stöder inte Ventoy 4K-enheter.", + + "STRXXX":"" + }, + { + "name":"Bulgarian (Български)", + "FontFamily":"Segoe", + "FontSize":16, + "Author":"jekovcar", + + "STR_ERROR":"Грешка", + "STR_WARNING":"Предупреждение", + "STR_INFO":"Информация", + "STR_INCORRECT_DIR":"Стартирайте от правилната папка!", + "STR_INCORRECT_TREE_DIR":"Не стартирайте оттук, изтеглете инсталационен пакет и стартирайте него.", + "STR_DEVICE":"Устройство", + "STR_LOCAL_VER":"Ventoy в пакета", + "STR_DISK_VER":"Ventoy на устройството", + "STR_STATUS":"Състояние - В готовност", + "STR_INSTALL":"Инсталиране", + "STR_UPDATE":"Обновяване", + "STR_UPDATE_TIP":"Обновяването е безопасно, файловете на ISO няма да бъдат променени.#@Продължаване?", + "STR_INSTALL_TIP":"Устройството ще бъде форматирано, а всички данни - премахнати.#@Продължаване?", + "STR_INSTALL_TIP2":"Устройството ще бъде форматирано, а всички данни - премахнати.#@Продължаване? (повторно потвърждаване)", + "STR_INSTALL_SUCCESS":"Поздравления!#@Ventoy е успешно инсталиран на устройството.", + "STR_INSTALL_FAILED":"По време на инсталацията е възникнала грешка. Можете да поставите отново USB устройството и да опитате отново. Проверете log.txt за подробности. Ако инсталацията винаги е неуспешна, направете справка с често задаваните въпроси на официалната страница.", + "STR_UPDATE_SUCCESS":"Поздравление!#@Ventoy е успешно обновен на устройството.", + "STR_UPDATE_FAILED":"По време на обновяването е възникнала грешка. Можете да поставите отново USB устройството и да опитате отново. Проверете log.txt за подробности. Ако обновяването винаги е неуспешно, направете справка с често задаваните въпроси на официалната страница.", + "STR_WAIT_PROCESS":"В процес, изчакайте…", + "STR_MENU_OPTION":"Настройки", + "STR_MENU_SECURE_BOOT":"Поддръжка на Secure Boot", + "STR_MENU_PART_CFG":"Допълнителен дял", + "STR_BTN_OK":"Добре", + "STR_BTN_CANCEL":"Отказ", + "STR_PRESERVE_SPACE":"Създаване на допълнителен дял в края на диска", + "STR_SPACE_VAL_INVALID":"Невярна стойност за запазено пространство", + "STR_MENU_CLEAR":"Премахване на Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy е успешно премахнат от устройството.", + "STR_CLEAR_FAILED":"По време на премахването е възникнала грешка. Можете да поставите отново USB устройството и да опитате отново. Проверете log.txt за подробности.", + "STR_MENU_PART_STYLE":"Вид на дяловете", + "STR_DISK_2TB_MBR_ERROR":"Изберете GPT за устройства по-големи от 2ТБ", + "STR_SHOW_ALL_DEV":"Показване на всички устройства", + "STR_PART_ALIGN_4KB":"Подравняване на дяловете по 4КБ", + "STR_WEB_COMMUNICATION_ERR":"Грешка при свързване:", + "STR_WEB_REMOTE_ABNORMAL":"Грешка при свързване: Отдалечената връзка е недействителна", + "STR_WEB_REQUEST_TIMEOUT":"Грешка при свързване: Времето за изчакване на заявката е просрочено", + "STR_WEB_SERVICE_UNAVAILABLE":"Грешка при свързване: Услугата е недостъпна", + "STR_WEB_TOKEN_MISMATCH":"Състоянието на услугата е обновено, опитайте по-късно.", + "STR_WEB_SERVICE_BUSY":"Услугата е заета, опитайте по-късно.", + "STR_MENU_VTSI_CREATE":"Създаване на файл на VTSI", + "STR_VTSI_CREATE_TIP":"Този път няма да се извършва запис на устройството, а само ще бъде създаден файл на VTSI#@Продължаване?", + "STR_VTSI_CREATE_SUCCESS":"Файлът на VTSI е създаден успешно!#@Може да използвате Rufus(3.15+), за да го запишете на устройството и така да завършите инсталацията на Ventoy.", + "STR_VTSI_CREATE_FAILED":"Грешка при създаване на файла на VTSI.", + "STR_MENU_PART_RESIZE":"Неразрушително инсталиране", + "STR_PART_RESIZE_TIP":"Ventoy ще направи опит за неразрушително инсталиране, ако е възможно.#@Продължаване?", + "STR_PART_RESIZE_SUCCESS":"Поздравления!#@Неразрушителното инсталиране на Ventoy е успешно.", + "STR_PART_RESIZE_FAILED":"Неразрушителното инсталиране на Ventoy е неуспешно. Проверете log.txt за подробности.", + "STR_PART_RESIZE_UNSUPPORTED":"Неразрушителното инсталиране на Ventoy е спряно, защото някои от условията не могат да бъдат изпълнени. Проверете log.txt за подробности.", + "STR_INSTALL_YES_TIP1":"Внимание: Ще има загуба на данни!", + "STR_INSTALL_YES_TIP2":"Въведете „YES“ в полето отдолу, за да потвърдите, че искате да извършите нова инсталация вместо обновяване.", + "STR_PART_VENTOY_FS":"Файлова система за дял на Ventoy", + "STR_PART_FS":"Файлова система", + "STR_PART_CLUSTER":"Размер на клъстера", + "STR_PART_CLUSTER_DEFAULT":"По подразбиране от системата", + "STR_DONATE":"Дарете", + "STR_4KN_UNSUPPORTED":"За момента Ventoy не поддържа устройства с клъстери, чиито размери са 4КБ.", + + "STRXXX":"" + }, + { + "name":"Armenian (Հայերեն)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Egho", + + "STR_ERROR":"Սխալ", + "STR_WARNING":"Զգուշացում", + "STR_INFO":"Տեղեկություն", + "STR_INCORRECT_DIR":"Խնդրում ենք գործարկել ճիշտ թղթախանակում!", + "STR_INCORRECT_TREE_DIR":"Չգործարկել այստեղ, խնդրում եմ ներբեռնեք թողարկված տեղադրման փաթեթը և գործարկել այնտեղ:", + "STR_DEVICE":"Կրիչը", + "STR_LOCAL_VER":"Ventoy-ը փաթեթում", + "STR_DISK_VER":"Ventoy-ը կրիչում", + "STR_STATUS":"Կարգավիճակ - ՊԱՏՐԱՍՏ", + "STR_INSTALL":"Տեղադրել", + "STR_UPDATE":"Թարմացնել", + "STR_UPDATE_TIP":"Թարմացման գործողությունը անվտանգ է, ISO ֆայլերը կմնան անփոփոխ.#@Շարունակել?", + "STR_INSTALL_TIP":"Սկավառակը կձևաչափվի և բոլոր տվյալները կկորչեն.#@Շարունակել?", + "STR_INSTALL_TIP2":"Սկավառակը կձևաչափվի և բոլոր տվյալները կկորչեն:#@Դուք համոզված եք, մաքրել կրիչը? (Double Check)", + "STR_INSTALL_SUCCESS":"Շնորհավորում ենք!#@Ventoy- ը հաջողությամբ տեղադրվել է կրիչում:", + "STR_INSTALL_FAILED":"Տեղադրման ընթացքում տեղի ունեցավ սխալ: Կարող եք նորից միացնել USB- կրիչը և կրկին փորձել: Մանրամասների համար ստուգել log.txt-ը ", + "STR_UPDATE_SUCCESS":"Շնորհավորում ենք!#@Ventoy-ը հաջողությամբ թարմացվեց կրիչում:", + "STR_UPDATE_FAILED":"Թարմացման ընթացքում տեղի ունեցավ սխալ: Կարող եք նորից միացնել USB- կրիչը և կրկին փորձել: Մանրամասների համար ստուգել log.txt-ը ", + "STR_WAIT_PROCESS":"Աշխատանքն ընթանում, խնդրում ենք սպասել...", + "STR_MENU_OPTION":"Ընտրանքներ", + "STR_MENU_SECURE_BOOT":"Secure Boot աջակցություն", + "STR_MENU_PART_CFG":"Partition կազմաձևում", + "STR_BTN_OK":"Այո", + "STR_BTN_CANCEL":"Չեղարկել", + "STR_PRESERVE_SPACE":"Պահպանեք որոշակի տարածք կրիչի վերջում", + "STR_SPACE_VAL_INVALID":"Պահված տարածքի անվավեր արժեք", + "STR_MENU_CLEAR":"Մաքրել Ventoy-ը", + "STR_CLEAR_SUCCESS":"Ventoy-ը հաջողությամբ հեռացված է կրիչից:", + "STR_CLEAR_FAILED":"Ventoy-ը կրիչից մաքրելիս տեղի ունեցավ սխալ: Կարող եք նորից միացնել USB-կրիչը և կրկին փորձել: Մանրամասների համար ստուգել log.txt-ը", + "STR_MENU_PART_STYLE":"Partition-ի տեսակը", + "STR_DISK_2TB_MBR_ERROR":"Խնդրում ենք ընտրել GPT 2TB-ից մեծ կրիչի դեպքում", + "STR_SHOW_ALL_DEV":"Ցուցադրել բոլոր կրիչները", + "STR_PART_ALIGN_4KB":"partition-երը գծանշել 4KB-ով", + "STR_WEB_COMMUNICATION_ERR":"Համակցման սխալ․", + "STR_WEB_REMOTE_ABNORMAL":"Համակցման սխալ․ Հեռահար համակցումն չստացվեց", + "STR_WEB_REQUEST_TIMEOUT":"Համակցման սխալ․: Սպասման ժամանակը սպառվեց", + "STR_WEB_SERVICE_UNAVAILABLE":"Համակցման սխալ․: Ծառայությունը անհասանելի է", + "STR_WEB_TOKEN_MISMATCH":"Թարմացվել է Demon-ի կարգավիճակը, խնդրում եմ նորից փորձել ավելի ուշ:", + "STR_WEB_SERVICE_BUSY":"Ծառայությունը զբաղված է, խնդրում եմ նորից փորձել ավելի ուշ:", + "STR_MENU_VTSI_CREATE":"Ստեղծել VTSI ֆայլ", + "STR_VTSI_CREATE_TIP":"Այս անգամ չի գրվի կրիչի վրա, այլ միայն կստեղծվի VTSI ֆայլ#@Շարունակել?", + "STR_VTSI_CREATE_SUCCESS":"VTSI ֆայլը հաջողությամբ ստեղծվեց!#@Դուք կարող եք օգտագործել Rufus (3.15+) կրիչում ձայնագրելու համար, որպեսզի ավարտեք Ventoy-ի տեղադրումը:", + "STR_VTSI_CREATE_FAILED":"VTSI ֆայլի ստեղծումը ձախողվեց։", + "STR_MENU_PART_RESIZE":"Non-destructive Install", + "STR_PART_RESIZE_TIP":"Ventoy will try non-destructive installation if possible. #@Continue?", + "STR_PART_RESIZE_SUCCESS":"Congratulations!#@Ventoy non-destructive installation successfully finished.", + "STR_PART_RESIZE_FAILED":"Non-destructive installation failed, Check log.txt for details.", + "STR_PART_RESIZE_UNSUPPORTED":"Ventoy non-destructive installation stopped because some conditions cannot be met. Check log.txt for details.", + "STR_INSTALL_YES_TIP1":"Warning: Data will be lost!", + "STR_INSTALL_YES_TIP2":"Please enter YES in the text box below to confirm that you indeed want to do a fresh install instead of upgrade.", + "STR_PART_VENTOY_FS":"File System For Ventoy Partition", + "STR_PART_FS":"File System", + "STR_PART_CLUSTER":"Cluster Size", + "STR_PART_CLUSTER_DEFAULT":"System Default Value", + "STR_DONATE":"Նվիրաբերել", + "STR_4KN_UNSUPPORTED":"Currently Ventoy does not support 4K native devices.", + + "STRXXX":"" + }, + { + "name":"Finnish (suomi)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"heidi.wenger", + + "STR_ERROR":"Virhe", + "STR_WARNING":"Varoitus", + "STR_INFO":"Tiedot", + "STR_INCORRECT_DIR":"Ole hyvä ja aja oikean kansion alla!", + "STR_INCORRECT_TREE_DIR":"Älä aja minua tässä, ole hyvä ja lataa julkaistu asennuspaketti, ja suorita ajo siellä.", + "STR_DEVICE":"Laite", + "STR_LOCAL_VER":"Ventoy paketissa", + "STR_DISK_VER":"Ventoy laitteessa", + "STR_STATUS":"Tila - VALMIS", + "STR_INSTALL":"Asenna", + "STR_UPDATE":"Päivitä", + "STR_UPDATE_TIP":"Päivytystoiminto on turvallinen, ISO -tiedostot pysyvät muuttumattomana.#@Jatketaanko?", + "STR_INSTALL_TIP":"Laite tullaan alustamaan ja tämän johdosta kaikki tieto sen sisällä menetetään.#@Jatketaanko?", + "STR_INSTALL_TIP2":"Laite tullaan alustamaan ja tämän johdosta kaikki tieto sen sisällä menetetään.#@Jatketaanko? (Kaksoistarkistus)", + "STR_INSTALL_SUCCESS":"Onnittelut!#@Ventoy on asennettu laitteeseen onnistuneesti.", + "STR_INSTALL_FAILED":"Asennuksen yhteydessä ilmeni virhe. Voit nypätä USB-laitteen irti ja koettaa uudelleen. Katso log.txt nähdäksesi yksityiskohdat. Mikäli toimi epäonnistuu aina, lue usein kysytyt kysymykset (FAQ) virallisella sivustolla.", + "STR_UPDATE_SUCCESS":"Onnittelut!#@Ventoy päivitettiin laitteeseen onnistuneesti.", + "STR_UPDATE_FAILED":"Päivityksen aikana ilmeni virhe. Voit nypätä USB-laitteen irti ja koettaa uudelleen. Katso log.txt nähdäksesi yksityiskohdat. Mikäli toimi epäonnistuu aina, lue usein kysytyt kysymykset (FAQ) virallisella sivustolla.", + "STR_WAIT_PROCESS":"Toimi on ajossa juuri nyt, ole hyvä ja odota...", + "STR_MENU_OPTION":"Vaihtoehto", + "STR_MENU_SECURE_BOOT":"Secure Boot (turvakäynnistys) -tuki", + "STR_MENU_PART_CFG":"Osioasetukset", + "STR_BTN_OK":"SELVÄ", + "STR_BTN_CANCEL":"Peruuta", + "STR_PRESERVE_SPACE":"Jätä hiukan vapaata tilaa levyn loppuun", + "STR_SPACE_VAL_INVALID":"Epäkelpo määrä tilavaraukselle", + "STR_MENU_CLEAR":"Poista Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy on nyt poistettu laitteesta onnistuneesti.", + "STR_CLEAR_FAILED":"Ilmeni virhe poistettaessa Ventoyta levyltä. Voit nypätä laitteen irti ja koettaa uudelleen. Katso log.txt nähdäksesi yksityiskohdat.", + "STR_MENU_PART_STYLE":"Osiotyyli", + "STR_DISK_2TB_MBR_ERROR":"Ole hyvä ja valitse GPT laitteille joissa on tilavuutta yli 2 teratavua", + "STR_SHOW_ALL_DEV":"Näytä kaikki laitteet", + "STR_PART_ALIGN_4KB":"Järjestä osiot 4Kt mukaisesti", + "STR_WEB_COMMUNICATION_ERR":"Kommunikaatiovirhe:", + "STR_WEB_REMOTE_ABNORMAL":"Kommunikaatiovirhe: epätavanomainen etävaste", + "STR_WEB_REQUEST_TIMEOUT":"Kommunikaatiovirhe: pyynnön aikavaste ylittyi", + "STR_WEB_SERVICE_UNAVAILABLE":"Kommunikaatiovirhe: palvelu on tavoittamattomissa", + "STR_WEB_TOKEN_MISMATCH":"Taustaohjelman tila päivittyi, ole hyvä ja yritä myöhemmin uudelleen.", + "STR_WEB_SERVICE_BUSY":"Palvelu ruuhkautunut, ole hyvä ja yritä myöhemmin uudelleen.", + "STR_MENU_VTSI_CREATE":"Luo VTSI -tiedosto", + "STR_VTSI_CREATE_TIP":"Tällä kerralla laitteeseen ei kirjoiteta, vaan luodaan ainoastaan VTSI -tiedosto#@Jatketaanko?", + "STR_VTSI_CREATE_SUCCESS":"VTSI -tiedosto luotiin onnistuneesti!#@Voit käyttää Rufus-ohjelmaa(3.15+) kirjoittaaksesi sen laitteeseen viimeistelläksesi Ventoy-asennuksen.", + "STR_VTSI_CREATE_FAILED":"VTSI -tiedoston luominen epäonnistui.", + "STR_MENU_PART_RESIZE":"Ei-tuhoisa asennus", + "STR_PART_RESIZE_TIP":"Ventoy kokeilee ei-tuhoisaa asennusta mikäli tämä on mahdollista. #@Jatketaanko?", + "STR_PART_RESIZE_SUCCESS":"Onnittelut!#@Ventoyn ei-tuhoisa asennus saapui päätökseen onnistuneesti.", + "STR_PART_RESIZE_FAILED":"Ei-tuhoisa asennusmuoto epäonnistui, tarkista log.txt nähdäksesi yksityiskohtaiset tiedot.", + "STR_PART_RESIZE_UNSUPPORTED":"Ventoyn ei-tuhoisa asennus pysähtyi koska jotkut ehdot eivät täyttyneet. Tarkista log.txt nähdäksesi yksityiskohdat.", + "STR_INSTALL_YES_TIP1":"Varoitus: Data menetetään!", + "STR_INSTALL_YES_TIP2":"Kirjoita YES alla olevaan tekstikenttään vahvistaaksesi että haluat tehdä uuden asennuksen päivityksen sijaan.", + "STR_PART_VENTOY_FS":"Ventoy -osion tiedostojärjestelmä", + "STR_PART_FS":"Tiedostojärjestelmä", + "STR_PART_CLUSTER":"Klusterin koko", + "STR_PART_CLUSTER_DEFAULT":"Järjestelmän oletusarvo", + "STR_DONATE":"Lahjoittaa", + "STR_4KN_UNSUPPORTED":"Tällä hetkellä Ventoy ei tue 4K laitteita.", + + "STRXXX":"" + }, + { + "name":"Galician (Galego)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"gbrea", + + "STR_ERROR":"Erro", + "STR_WARNING":"Atención", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Por favor, execute no directorio correto!", + "STR_INCORRECT_TREE_DIR":"Non me executes aquí, por favor transfire o pacote de instalación, e execute alí.", + "STR_DEVICE":"Dispositivo", + "STR_LOCAL_VER":"Ventoy na aplicación", + "STR_DISK_VER":"Ventoy no dispositivo", + "STR_STATUS":"Estado - PRONTO", + "STR_INSTALL":"Instalar", + "STR_UPDATE":"Actualizar", + "STR_UPDATE_TIP":"A operación de atualización é segura, os ficheiros ISO non serán alterados.#@Continuar?", + "STR_INSTALL_TIP":"O disco será formatado e perderanse todos os datos.#@Continuar?", + "STR_INSTALL_TIP2":"O disco será formatado e perderanse todos os datos.#@Continuar? (Confirmación)", + "STR_INSTALL_SUCCESS":"Parabéns!#@Ventoy foi instalado con suceso no dispositivo.", + "STR_INSTALL_FAILED":"Un erro ocorreu durante a instalación. Podes reconectar o dispositivo USB e tentar novamente. Verifica o ficheiro log.txt para máis detalles.", + "STR_UPDATE_SUCCESS":"Parabéns!#@Ventoy foi actualizado con suceso no dispositivo.", + "STR_UPDATE_FAILED":"Un erro ocorreu durante a actualización. Podes reconectar o dispositivo USB e tentar novamente. Verifica o ficheiro log.txt para máis detalles.", + "STR_WAIT_PROCESS":"Un proceso está en execución, por favor espera...", + "STR_MENU_OPTION":"Opción", + "STR_MENU_SECURE_BOOT":"Soporte de arranque seguro", + "STR_MENU_PART_CFG":"Configuración da Partición", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Cancelar", + "STR_PRESERVE_SPACE":"Preservar algún espazo no final do disco", + "STR_SPACE_VAL_INVALID":"Valor inválido para o espazo reservado", + "STR_MENU_CLEAR":"Remover o Ventoy", + "STR_CLEAR_SUCCESS":"O Ventoy foi removido deste dispositivo con suceso.", + "STR_CLEAR_FAILED":"Un erro ocorreu ao remover o Ventoy do disco. Podes reconectar o dispositivo USB e tentar novamente. Verifica o ficheiro log.txt para máis detalles.", + "STR_MENU_PART_STYLE":"Estilo de Partición", + "STR_DISK_2TB_MBR_ERROR":"Por favor seleciona GPT para discos maiores que 2TB", + "STR_SHOW_ALL_DEV":"Mostrar todos os dispositivos", + "STR_PART_ALIGN_4KB":"Aliñar particións con 4KB", + "STR_WEB_COMMUNICATION_ERR":"Erro de comunicación:", + "STR_WEB_REMOTE_ABNORMAL":"Erro de comunicación: remoto anormal", + "STR_WEB_REQUEST_TIMEOUT":"Erro de comunicación: Tempo de espera esgotado", + "STR_WEB_SERVICE_UNAVAILABLE":"Erro de comunicación: Servizo non dispoñible", + "STR_WEB_TOKEN_MISMATCH":"Estado do daemon actualizado, por favor inténtao máis tarde.", + "STR_WEB_SERVICE_BUSY":"O servizo está ocupado, por favor inténtao máis tarde.", + "STR_MENU_VTSI_CREATE":"Xerar arquivo VTSI", + "STR_VTSI_CREATE_TIP":"Non será grabado no dispositivo, desta vez, apenas se xerará un ficheiro VTSI#@Continuar?", + "STR_VTSI_CREATE_SUCCESS":"Arquivo VTSI creado con suceso!#@Podes usar Rufus(3.15+) para grabalo no dispositivo e completar a instalación do Ventoy.", + "STR_VTSI_CREATE_FAILED":"Erro na creación do arquivo VTSI.", + "STR_MENU_PART_RESIZE":"Instalación non destructiva", + "STR_PART_RESIZE_TIP":"Ventoy tentará unha instalación non destructiva, se é posible.#@Continuar?", + "STR_PART_RESIZE_SUCCESS":"Parabéns!#@Instalación non destructiva do Ventoy concluida con suceso.", + "STR_PART_RESIZE_FAILED":"Erro na instalación non destructiva, revisa o arquivo log.txt para ver os detalles.", + "STR_PART_RESIZE_UNSUPPORTED":"Instalación non destructiva do Ventoy interrompida porque non se poden cumprir algunhas condicións. Revisa o arquivo log.txt para mais detalles.", + "STR_INSTALL_YES_TIP1":"Warning: Data will be lost!", + "STR_INSTALL_YES_TIP2":"Please enter YES in the text box below to confirm that you indeed want to do a fresh install instead of upgrade.", + "STR_PART_VENTOY_FS":"File System For Ventoy Partition", + "STR_PART_FS":"File System", + "STR_PART_CLUSTER":"Cluster Size", + "STR_PART_CLUSTER_DEFAULT":"System Default Value", + "STR_DONATE":"Doa", + "STR_4KN_UNSUPPORTED":"Currently Ventoy does not support 4K native devices.", + + "STRXXX":"" + }, + { + "name":"Catalan (Català)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"guillemglez", + + "STR_ERROR":"Error", + "STR_WARNING":"Avís", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Cal executar-ho en el directori correcte!", + "STR_INCORRECT_TREE_DIR":"No m'executis aquí, si us plau, baixa el paquet d'instal·lació publicat i executa-ho allí.", + "STR_DEVICE":"Dispositiu", + "STR_LOCAL_VER":"Ventoy localment", + "STR_DISK_VER":"Ventoy al dispositiu", + "STR_STATUS":"Estat - Llest", + "STR_INSTALL":"Instal·la", + "STR_UPDATE":"Actualitza", + "STR_UPDATE_TIP":"L'actualització és segura i els fitxers ISO no es veuran afectats.#@Continuar?", + "STR_INSTALL_TIP":"El dispositiu serà formatat i totes les dades es perdran.#@Continuar?", + "STR_INSTALL_TIP2":"El dispositiu serà formatat i totes les dades es perdran.#@Continuar? (Confirmeu)", + "STR_INSTALL_SUCCESS":"Enhorabona!#@Ventoy s'ha instal·lat al vostre dispositiu de forma satisfactòria.", + "STR_INSTALL_FAILED":"Hi ha hagut un error durant el procés d'instal·lació. Podeu desconnectar i tornar-lo a connectar i provar-ho de nou. Comproveu el fitxer log.txt per a més detalls. Si això passa sovint visiteu el FAQs a la nostra pàgina oficial.", + "STR_UPDATE_SUCCESS":"Enhorabona!#@Ventoy s'ha actualitzat al vostre dispositiu de forma satisfactòria.", + "STR_UPDATE_FAILED":"Hi ha hagut un error durant el procés d'actualització. Podeu desconnectar i tornar-lo a connectar i provar-ho de nou. Comproveu el fitxer log.txt per a més detalls. Si això passa sovint visiteu el FAQs a la nostra pàgina oficial.", + "STR_WAIT_PROCESS":"Hi ha una operació en curs, espereu si us plau...", + "STR_MENU_OPTION":"Opcions", + "STR_MENU_SECURE_BOOT":"Arrencada segura", + "STR_MENU_PART_CFG":"Ajustaments de partició", + "STR_BTN_OK":"D'acord", + "STR_BTN_CANCEL":"Cancel·la", + "STR_PRESERVE_SPACE":"Preserva espai al final del disc", + "STR_SPACE_VAL_INVALID":"Valor d'espai reservat invàlid", + "STR_MENU_CLEAR":"Esborra el Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy s'ha esborrat satisfactòriament del dispositiu.", + "STR_CLEAR_FAILED":"Hi ha hagut un error mentre s'esborrava Ventoy del dispositiu. Podeu desconnectar i tornar-lo a connectar i provar-ho de nou. Comproveu el fitxer log.txt per a més detalls.", + "STR_MENU_PART_STYLE":"Estil de partició", + "STR_DISK_2TB_MBR_ERROR":"Sel·leccioneu GPT per dispositius de més de 2 TB", + "STR_SHOW_ALL_DEV":"Mostra tots els dispositius", + "STR_PART_ALIGN_4KB":"Alinea les particions a 4 KB", + "STR_WEB_COMMUNICATION_ERR":"Error de comunicació:", + "STR_WEB_REMOTE_ABNORMAL":"Error de comunicació: anomalia al servidor", + "STR_WEB_REQUEST_TIMEOUT":"Error de comunicació: s'ha esgotat el temps d'espera", + "STR_WEB_SERVICE_UNAVAILABLE":"Error de comunicació: servei no disponible", + "STR_WEB_TOKEN_MISMATCH":"S'ha actualitzat l'estat del dimoni, torneu a provar-ho més tard.", + "STR_WEB_SERVICE_BUSY":"El servei està sobrecarregat, torneu a provar-ho més tard.", + "STR_MENU_VTSI_CREATE":"Genera un fitxer VTSI", + "STR_VTSI_CREATE_TIP":"Aquest cop no s'escriuran els canvis al dispositiu, sinó que es generarà un fitxer VTSI#@Continuar?", + "STR_VTSI_CREATE_SUCCESS":"El fitxer VTSI s'ha creat satisfactòriament!#@Pots fer servir Rufus(3.15+) per escriure'l al dispositiu i completar així la instal·lació de Ventoy.", + "STR_VTSI_CREATE_FAILED":"No s'ha pogut crear el fitxer VTSI", + "STR_MENU_PART_RESIZE":"Instal·lació no destructiva", + "STR_PART_RESIZE_TIP":"El Ventoy intentarà una instal·lació no destructiva si és possible. #@Continuar?", + "STR_PART_RESIZE_SUCCESS":"Enhorabona!#@La instal·lació no destructiva s'ha completat de forma satisfactòria.", + "STR_PART_RESIZE_FAILED":"Hi ha hagut un error durant el procés d'instal·lació no destructiva, comproveu el fitxer log.txt per a més detalls.", + "STR_PART_RESIZE_UNSUPPORTED":"La instal·lació no destructiva de Ventoy no ha estat possible perquè els requeriments no es compleixen. Comproveu el fitxer log.txt per a més detalls.", + "STR_INSTALL_YES_TIP1":"Warning: Data will be lost!", + "STR_INSTALL_YES_TIP2":"Please enter YES in the text box below to confirm that you indeed want to do a fresh install instead of upgrade.", + "STR_PART_VENTOY_FS":"File System For Ventoy Partition", + "STR_PART_FS":"File System", + "STR_PART_CLUSTER":"Cluster Size", + "STR_PART_CLUSTER_DEFAULT":"System Default Value", + "STR_DONATE":"Donar", + "STR_4KN_UNSUPPORTED":"Currently Ventoy does not support 4K native devices.", + + "STRXXX":"" + }, + + { + "name":"Georgian (ქართული)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Levan Baindurashvili", + + "STR_ERROR":"შეცდომა", + "STR_WARNING":"გაფრთხილება", + "STR_INFO":"ინფორმაცია", + "STR_INCORRECT_DIR":"გთხოვთ, გაუშვით სხვა კატალოგში!", + "STR_INCORRECT_TREE_DIR":"ნუ გამიშვებ აქ, გთხოვთ გადმოწეროთ გამოშვებული ინსტალაციის პაკეტი და გაუშვათ სხვაგან.", + "STR_DEVICE":"მოწყობილობა", + "STR_LOCAL_VER":"Ventoy პაკეტში", + "STR_DISK_VER":"Ventoy მოწყობილობაზე", + "STR_STATUS":"სტატუსი - მზადაა", + "STR_INSTALL":"დაყენება", + "STR_UPDATE":"განახლება", + "STR_UPDATE_TIP":"განახლება უსაფრთხოა და ISO ფაილები უცვლელი დარჩება.#@გაგრძელება?", + "STR_INSTALL_TIP":"დისკი დაფორმატდება და ყველა მონაცემი დაიკარგება.#@გსურთ გააგრძელოთ?", + "STR_INSTALL_TIP2":"დისკი დაფორმატდება და ყველა მონაცემი დაიკარგება.#@ ნამდვილად გსურთ გაგრძელება?", + "STR_INSTALL_SUCCESS":"გილოცავთ!#@Ventoy წარმატებით დაინსტალირდა თქვენს მოწყობილობაზე.", + "STR_INSTALL_FAILED":"Ventoy-ის ინსტალაციისას მოხდა შეცდომა. ხელახლა შეაერთეთ თქვენი მოწყობილობა და სცადეთ ხელახლა. შეამოწმეთ log.txt შეცდომებისთვის.", + "STR_UPDATE_SUCCESS":"გილოცავთ!#@Ventoy წარმატებით განახლდა თქვენს მოწყობილობაზე.", + "STR_UPDATE_FAILED":"Ventoy-ის განახლებისას მოხდა შეცდომა. ხელახლა შეაერთეთ თქვენი მოწყობილობა და სცადეთ ხელახლა. შეამოწმეთ log.txt შეცდომებისთვის.", + "STR_WAIT_PROCESS":"პროცესი დაიწყო, გთხოვთ დაელოდოთ...", + "STR_MENU_OPTION":"Პარამეტრები", + "STR_MENU_SECURE_BOOT":"Secure Boot-ის მხარდაჭერა", + "STR_MENU_PART_CFG":"დამატებითი განყოფილება", + "STR_BTN_OK":"ОК", + "STR_BTN_CANCEL":"უარყოფა", + "STR_PRESERVE_SPACE":"შექმენით დამატებითი დანაყოფი დისკის ბოლოს", + "STR_SPACE_VAL_INVALID":"დანაყოფის ზომა არასწორია", + "STR_MENU_CLEAR":"Ventoy-ს წაშლა", + "STR_CLEAR_SUCCESS":"Ventoy წარმატებით წაიშალა მოწყობილობიდან.", + "STR_CLEAR_FAILED":"Ventoy-ის დეინსტალაციისას მოხდა შეცდომა. ხელახლა შეაერთეთ თქვენი მოწყობილობა და სცადეთ ხელახლა. შეამოწმეთ log.txt შეცდომებზე.", + "STR_MENU_PART_STYLE":"განყოფილების განლაგების სტილი", + "STR_DISK_2TB_MBR_ERROR":"გთხოვთ, აირჩიოთ GPT 2 ტბაიტზე მეტი დისკებისთვის", + "STR_SHOW_ALL_DEV":"ყველა მოწყობილობის ჩვენება", + "STR_PART_ALIGN_4KB":"ტიხრების გასწორება 4 KB ზომით", + "STR_WEB_COMMUNICATION_ERR":"დაკავშირების შეცდომა:", + "STR_WEB_REMOTE_ABNORMAL":"კომუნიკაციის შეცდომა: დისტანციური კავშირი არასწორია", + "STR_WEB_REQUEST_TIMEOUT":"კომუნიკაციის შეცდომა: მოთხოვნის დრო ამოიწურა", + "STR_WEB_SERVICE_UNAVAILABLE":"კომუნიკაციის შეცდომა: სერვისი მიუწვდომელია", + "STR_WEB_TOKEN_MISMATCH":"დემონის სტატუსი განახლებულია. გთხოვთ სცადოთ მოგვიანებით.", + "STR_WEB_SERVICE_BUSY":"სერვისი დაკავებულია, გთხოვთ, სცადოთ მოგვიანებით.", + "STR_MENU_VTSI_CREATE":"VTSI ფაილის შექმნა", + "STR_VTSI_CREATE_TIP":"ამჯერად Ventoy არ დაინსტალირდება მოწყობილობაზე, მაგრამ შეიქმნება მხოლოდ VTSI ფაილი#@გაგრძელება?", + "STR_VTSI_CREATE_SUCCESS":"VTSI ფაილი წარმატებით შეიქმნა!#@შეგიძლიათ გამოიყენოთ Rufus(3.15+) ჩაწეროთ მოწყობილობაზე Ventoy ინსტალაციის დასასრულებლად.", + "STR_VTSI_CREATE_FAILED":"VTSI ფაილის შექმნის შეცდომა.", + "STR_MENU_PART_RESIZE":"Non-destructive Install", + "STR_PART_RESIZE_TIP":"Ventoy will try non-destructive installation if possible. #@Continue?", + "STR_PART_RESIZE_SUCCESS":"Congratulations!#@Ventoy non-destructive installation successfully finished.", + "STR_PART_RESIZE_FAILED":"Non-destructive installation failed, Check log.txt for details.", + "STR_PART_RESIZE_UNSUPPORTED":"Ventoy non-destructive installation stopped because some conditions cannot be met. Check log.txt for details.", + "STR_INSTALL_YES_TIP1":"Warning: Data will be lost!", + "STR_INSTALL_YES_TIP2":"Please enter YES in the text box below to confirm that you indeed want to do a fresh install instead of upgrade.", + "STR_PART_VENTOY_FS":"File System For Ventoy Partition", + "STR_PART_FS":"File System", + "STR_PART_CLUSTER":"Cluster Size", + "STR_PART_CLUSTER_DEFAULT":"System Default Value", + "STR_DONATE":"შემოწირულობა", + "STR_4KN_UNSUPPORTED":"Currently Ventoy does not support 4K native devices.", + + "STRXXX":"" + }, + { + "name":"Tamil (தமிழ்)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"K.B.Dharun Krishna", + + "STR_ERROR":"பிழை", + "STR_WARNING":"எச்சரிக்கை", + "STR_INFO":"தகவல்", + "STR_INCORRECT_DIR":"சரியான கோப்பகத்தின் கீழ் இயக்கவும்!", + "STR_INCORRECT_TREE_DIR":"என்னை இங்கே இயக்க வேண்டாம், வெளியிடப்பட்ட நிறுவல் தொகுப்பை பதிவிறக்கம் செய்து, அங்கு இயக்கவும்.", + "STR_DEVICE":"சாதனம்", + "STR_LOCAL_VER":"தொகுப்பில் வென்டோய்", + "STR_DISK_VER":"சாதனத்தில் வென்டோய்", + "STR_STATUS":"நிலை - தயார்", + "STR_INSTALL":"நிறுவு", + "STR_UPDATE":"புதுப்பிக்கவும்", + "STR_UPDATE_TIP":"மேம்படுத்தல் செயல்பாடு பாதுகாப்பானது, ISO கோப்புகள் மாறாமல் இருக்கும்.#@தொடரவா?", + "STR_INSTALL_TIP":"சாதனம் வடிவமைக்கப்படும் மற்றும் எல்லா தரவும் இழக்கப்படும்.#@தொடரவா?", + "STR_INSTALL_TIP2":"சாதனம் வடிவமைக்கப்படும் மற்றும் எல்லா தரவும் இழக்கப்படும்.#@தொடரவா? (இருமுறை சரிபார்க்கவும்)", + "STR_INSTALL_SUCCESS":"வாழ்த்துகள்!#@வென்டோய் சாதனத்தில் வெற்றிகரமாக நிறுவப்பட்டது.", + "STR_INSTALL_FAILED":"நிறுவலின் போது பிழை ஏற்பட்டது. USB சாதனத்தை மீண்டும் செருகி மீண்டும் முயற்சிக்கவும். விவரங்களுக்கு log.txt ஐப் பார்க்கவும். அது எப்போதும் தோல்வியுற்றால், அதிகாரப்பூர்வ இணையதளத்தில் அடிக்கடி கேட்கப்படும் கேள்விகளைப் பார்க்கவும்.", + "STR_UPDATE_SUCCESS":"வாழ்த்துகள்!#@வென்டோய் சாதனத்தில் வெற்றிகரமாக புதுப்பிக்கப்பட்டது.", + "STR_UPDATE_FAILED":"புதுப்பித்தலின் போது பிழை ஏற்பட்டது. USB சாதனத்தை மீண்டும் செருகி மீண்டும் முயற்சிக்கவும். விவரங்களுக்கு log.txt ஐப் பார்க்கவும். அது எப்போதும் தோல்வியுற்றால், அதிகாரப்பூர்வ இணையதளத்தில் அடிக்கடி கேட்கப்படும் கேள்விகளைப் பார்க்கவும்.", + "STR_WAIT_PROCESS":"ஒரு நூல் இயங்குகிறது, காத்திருக்கவும்...", + "STR_MENU_OPTION":"விருப்பத்தேர்வுகள்", + "STR_MENU_SECURE_BOOT":"பாதுகாப்பான பூட் ஆதரவு", + "STR_MENU_PART_CFG":"பகிர்வு கட்டமைப்பு", + "STR_BTN_OK":"சரி", + "STR_BTN_CANCEL":"ரத்துசெய்", + "STR_PRESERVE_SPACE":"வட்டின் முடிவில் சிறிது இடத்தை சேமிக்கவும்", + "STR_SPACE_VAL_INVALID":"ஒதுக்கப்பட்ட இடத்திற்கான தவறான மதிப்பு", + "STR_MENU_CLEAR":"தெளிவான வெண்டோய்", + "STR_CLEAR_SUCCESS":"சாதனத்திலிருந்து வென்டோய் வெற்றிகரமாக அகற்றப்பட்டது.", + "STR_CLEAR_FAILED":"வென்டோயை வட்டில் இருந்து அகற்றும்போது பிழை ஏற்பட்டது. USB சாதனத்தை மீண்டும் செருகி மீண்டும் முயற்சிக்கவும். விவரங்களுக்கு log.txt ஐப் பார்க்கவும்.", + "STR_MENU_PART_STYLE":"பகிர்வு நடை", + "STR_DISK_2TB_MBR_ERROR":"2TB க்கும் அதிகமான சாதனங்களுக்கு GPTஐத் தேர்ந்தெடுக்கவும்", + "STR_SHOW_ALL_DEV":"எல்லா சாதனங்களையும் காட்டு", + "STR_PART_ALIGN_4KB":"பகிர்வுகளை 4KB உடன் சீரமைக்கவும்", + "STR_WEB_COMMUNICATION_ERR":"தகவல் பிழை:", + "STR_WEB_REMOTE_ABNORMAL":"தொடர்பு பிழை: தொலைநிலை அசாதாரணமானது", + "STR_WEB_REQUEST_TIMEOUT":"தகவல்தொடர்பு பிழை: கோரிக்கை நேரம் முடிந்தது", + "STR_WEB_SERVICE_UNAVAILABLE":"தொடர்பு பிழை: சேவை கிடைக்கவில்லை", + "STR_WEB_TOKEN_MISMATCH":"டீமான் நிலை புதுப்பிக்கப்பட்டது, பிறகு முயற்சிக்கவும்.", + "STR_WEB_SERVICE_BUSY":"சேவை பிஸியாக உள்ளது, பிறகு முயற்சிக்கவும்.", + "STR_MENU_VTSI_CREATE":"VTSI கோப்பை உருவாக்கவும்", + "STR_VTSI_CREATE_TIP":"இந்த முறை சாதனத்தில் எழுதப்படாது, ஆனால் VTSI கோப்பை மட்டும் உருவாக்குகிறது#@தொடரவா?", + "STR_VTSI_CREATE_SUCCESS":"VTSI கோப்பு வெற்றிகரமாக உருவாக்கப்பட்டது!#@ரூஃபஸ்(3.15+) ஐப் பயன்படுத்தி, வென்டோயின் நிறுவலை முடிக்க, சாதனத்தில் எழுதலாம்.", + "STR_VTSI_CREATE_FAILED":"VTSI கோப்பு உருவாக்கப்படுவதில் தோல்வி.", + "STR_MENU_PART_RESIZE":"அழிவில்லாத நிறுவல்", + "STR_PART_RESIZE_TIP":"வென்டோய் முடிந்தால், அழிவில்லாத நிறுவலை முயற்சிக்கும். #@தொடரவா?", + "STR_PART_RESIZE_SUCCESS":"வாழ்த்துகள்!#@வென்டோய் அழிவில்லாத நிறுவல் வெற்றிகரமாக முடிந்தது.", + "STR_PART_RESIZE_FAILED":"அழிவில்லாத நிறுவல் தோல்வியடைந்தது, விவரங்களுக்கு log.txt ஐப் பார்க்கவும்.", + "STR_PART_RESIZE_UNSUPPORTED":"சில நிபந்தனைகளை பூர்த்தி செய்ய முடியாததால், வென்டோய் அழிவில்லாத நிறுவல் நிறுத்தப்பட்டது. விவரங்களுக்கு log.txt ஐப் பார்க்கவும்.", + "STR_INSTALL_YES_TIP1":"எச்சரிக்கை: தரவு தொலைந்து போகும்!", + "STR_INSTALL_YES_TIP2":"மேம்படுத்துவதற்குப் பதிலாக புதிதாக நிறுவ விரும்புகிறீர்கள் என்பதை உறுதிப்படுத்த, கீழே உள்ள உரைப் பெட்டியில் ஆம் என உள்ளிடவும்.", + "STR_PART_VENTOY_FS":"வென்டோய் பகிர்வுக்கான கோப்பு முறைமை", + "STR_PART_FS":"கோப்பு முறைமை", + "STR_PART_CLUSTER":"கொத்து அளவு", + "STR_PART_CLUSTER_DEFAULT":"கணினி இயல்புநிலை மதிப்பு", + "STR_DONATE":"தானம் செய்", + "STR_4KN_UNSUPPORTED":"தற்போது, வெண்டோய் 4K சொந்த சாதனங்களை ஆதரிக்கவில்லை.", + + "STRXXX":"" + }, + { + "name":"Belarussian (Беларуская)", + "FontFamily":"Courier New", + "FontSize":16, + "Author": "dmitrygribenchuk", + + "STR_ERROR":"Памылка", + "STR_WARNING":"Папярэджанне", + "STR_INFO":"Інфармацыя", + "STR_INCORRECT_DIR":"Калі ласка, запусціце ў іншым каталогу!", + "STR_INCORRECT_TREE_DIR":"Не запускайце мяне тут, калі ласка, загрузіце выпушчаны ўсталявальны пакет і запусціце яго ў іншым месцы.", + "STR_DEVICE":"Прылада", + "STR_LOCAL_VER":"Ventoy у пакеце", + "STR_DISK_VER":"Ventoy на прыладзе", + "STR_STATUS":"Статус - ГАТОВЫ", + "STR_INSTALL":"Усталяваць", + "STR_UPDATE":"Абнавіць", + "STR_UPDATE_TIP":"Абнаўленне бяспечна, ISO-файлы застануцца без змен. #@Працягнуць?", + "STR_INSTALL_TIP":"Дыск будзе адфарматаваны і ўсе дадзеныя будуць страчаныя. #@Працягнуць?", + "STR_INSTALL_TIP2":"Дыск будзе адфарматаваны і ўсе дадзеныя будуць страчаныя. #@ Вы сапраўды жадаеце працягнуць?", + "STR_INSTALL_SUCCESS":"Віншуем! #@ Ventoy быў паспяхова ўстаноўлены на прыладу.", + "STR_INSTALL_FAILED":"Падчас усталёўкі Ventoy адбылася памылка. Перападлучыце прыладу і паспрабуйце зноў. Праверце файл log.txt для атрымання падрабязнай інфармацыі.", + "STR_UPDATE_SUCCESS":"Віншуем! #@ Ventoy быў паспяхова абноўлены на прыладзе.", + "STR_UPDATE_FAILED":"Падчас абнаўлення Ventoy адбылася памылка. Перападлучыце прыладу і паспрабуйце зноў. Праверце файл log.txt для атрымання падрабязнай інфармацыі.", + "STR_WAIT_PROCESS":"Працэс запушчаны, калі ласка пачакайце...", + "STR_MENU_OPTION":"Параметры", + "STR_MENU_SECURE_BOOT":"Падтрымка Secure Boot", + "STR_MENU_PART_CFG":"Дадатковы раздзел", + "STR_BTN_OK":"ОК", + "STR_BTN_CANCEL":"Адмена", + "STR_PRESERVE_SPACE":"Стварыць дадатковы раздзел ў канцы дыска", + "STR_SPACE_VAL_INVALID":"Няправільнае значэнне памеру раздзела", + "STR_MENU_CLEAR":"Выдалiць Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy быў паспяхова выдалены з прылады.", + "STR_CLEAR_FAILED":"Падчас выдалення Ventoy адбылася памылка. Перападлучыце прыладу і паспрабуйце зноў. Праверце файл log.txt для атрымання падрабязнай інфармацыі.", + "STR_MENU_PART_STYLE":"Стыль разметкі раздзелаў", + "STR_DISK_2TB_MBR_ERROR":"Калі ласка, абярыце GPT для дыскаў больш за 2ТБ", + "STR_SHOW_ALL_DEV":"Паказаць усе прылады", + "STR_PART_ALIGN_4KB":"Выраўнаваць раздзелы з памерам 4КБ", + "STR_WEB_COMMUNICATION_ERR":"Памылка сувязі:", + "STR_WEB_REMOTE_ABNORMAL":"Памылка сувязі: Выдаленае злучэнне несапраўдна", + "STR_WEB_REQUEST_TIMEOUT":"Памылка сувязі: Скончыўся час чакання запыту", + "STR_WEB_SERVICE_UNAVAILABLE":"Памылка сувязі: Служба недаступная", + "STR_WEB_TOKEN_MISMATCH":"Статус дэмана абноўлены. Паўтарыце спробу пазней.", + "STR_WEB_SERVICE_BUSY":"Служба занятая, паспрабуйце пазней.", + "STR_MENU_VTSI_CREATE":"Стварыць файл VTSI", + "STR_VTSI_CREATE_TIP":"На гэты раз Ventoy не будзе ўсталяваны на прыладу, а будзе толькі створаны файл VTSI#@Працягнуць?", + "STR_VTSI_CREATE_SUCCESS":"Файл VTSI створаны паспяхова! #@ Вы можаце выкарыстоўваць Rufus (3.15 +), каб запісаць яго на прыладу, для завяршэння ўстаноўкі Ventoy.", + "STR_VTSI_CREATE_FAILED":"Памылка стварэння файла VTSI.", + "STR_MENU_PART_RESIZE":"Неразбуральная ўстаноўка", + "STR_PART_RESIZE_TIP":"Ventoy паспрабуе неразбуральную ўстаноўку, калі гэта магчыма. #@Працягнуць?", + "STR_PART_RESIZE_SUCCESS":"Віншуем! #@ Неразбуральная ўстаноўка Ventoy паспяхова завершана.", + "STR_PART_RESIZE_FAILED":"Не атрымалася выканаць неразбуральную ўстаноўку, праверце файл log.txt для атрымання падрабязнай інфармацыі.", + "STR_PART_RESIZE_UNSUPPORTED":"Неразбуральная ўстаноўка Ventoy спынена, паколькі некаторыя ўмовы не могуць быць выкананы. Праверце файл log.txt для атрымання падрабязнай інфармацыі.", + "STR_INSTALL_YES_TIP1":"Папярэджанне: Дадзеныя будуць страчаныя!", + "STR_INSTALL_YES_TIP2":"Калі ласка, увядзіце YES у тэкставае поле ніжэй, каб пацвердзіць, што вы сапраўды хочаце выканаць новую ўстаноўку замест абнаўлення.", + "STR_PART_VENTOY_FS":"Файлавая сістэма для Ventoy раздзела", + "STR_PART_FS":"Файлавая сістэма", + "STR_PART_CLUSTER":"Памер кластара", + "STR_PART_CLUSTER_DEFAULT":"Сістэмнае значэнне па змаўчанні", + "STR_DONATE":"Ахвяраваць", + "STR_4KN_UNSUPPORTED":"Зараз Ventoy не падтрымлівае ўласныя прылады 4K.", + + "STRXXX":"" + }, + { + "name":"Malayalam (മലയാളം)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"SIDDHARTH K P", + + "STR_ERROR":"പിശക്", + "STR_WARNING":"മുന്നറിയിപ്പ്", + "STR_INFO":"വിവരം", + "STR_INCORRECT_DIR":"ദയവായി ശരിയായ ഡയറക്ടറിയിൽ പ്രവർത്തിപ്പിക്കുക!", + "STR_INCORRECT_TREE_DIR":"എന്നെ ഇവിടെ പ്രവർത്തിപ്പിക്കരുത്, ദയവായി ഇൻസ്റ്റാളേഷൻ പാക്കേജ് ഡൗൺലോഡ് ചെയ്ത് അവിടെ പ്രവർത്തിപ്പിക്കുക.", + "STR_DEVICE":"ഉപകരണം", + "STR_LOCAL_VER":"പാക്കേജിലെ വെൻ്റോയ്", + "STR_DISK_VER":"ഉപകരണത്തിലെ വെൻ്റോയ്", + "STR_STATUS":"നില - തയ്യാറാണ്", + "STR_INSTALL":"ഇൻസ്റ്റാൾ ചെയ്യുക", + "STR_UPDATE":"അപ്ഡേറ്റ് ചെയ്യുക", + "STR_UPDATE_TIP":"അപ്‌ഡേറ്റ് പ്രവർത്തനം സുരക്ഷിതമാണ്, ISO ഫയലുകൾ മാറ്റമില്ലാതെ തുടരും.#@തുടരട്ടേ?", + "STR_INSTALL_TIP":"ഡിസ്ക് ഫോർമാറ്റ് ചെയ്യപ്പെടും, എല്ലാ ഡാറ്റയും നഷ്‌ടപ്പെടും.#@തുടരട്ടേ?", + "STR_INSTALL_TIP2":"ഡിസ്ക് ഫോർമാറ്റ് ചെയ്യപ്പെടും, എല്ലാ ഡാറ്റയും നഷ്‌ടപ്പെടും.#@തുടരട്ടേ? (ഒന്നുകൂടി ഉറപ്പിക്കുക)", + "STR_INSTALL_SUCCESS":"അഭിനന്ദനങ്ങൾ!#@വെൻ്റോയ് ഉപകരണത്തിൽ വിജയകരമായി ഇൻസ്റ്റാൾ ചെയ്തു.", + "STR_INSTALL_FAILED":"ഇൻസ്റ്റാളേഷൻ സമയത്ത് ഒരു പിശക് സംഭവിച്ചു. നിങ്ങൾക്ക് യുഎസ്ബി ഉപകരണം വീണ്ടും ഘടിപ്പിച്ച് വീണ്ടും ശ്രമിക്കാവുന്നതാണ്. വിവരങ്ങൾക്കായി log.txt പരിശോധിക്കുക.", + "STR_UPDATE_SUCCESS":"അഭിനന്ദനങ്ങൾ!#@വെൻ്റോയ് ഉപകരണത്തിൽ വിജയകരമായി അപ്ഡേറ്റ് ചെയ്തു.", + "STR_UPDATE_FAILED":"അപ്‌ഡേറ്റ് ചെയ്യുമ്പോൾ ഒരു പിശക് സംഭവിച്ചു. നിങ്ങൾക്ക് യുഎസ്ബി ഉപകരണം വീണ്ടും ഘടിപ്പിച്ച് വീണ്ടും ശ്രമിക്കാവുന്നതാണ്. വിവരങ്ങൾക്കായി log.txt പരിശോധിക്കുക.", + "STR_WAIT_PROCESS":"ഒരു പ്രവർത്തനം പുരോഗമിക്കുന്നു, ദയവായി കാത്തിരിക്കുക...", + "STR_MENU_OPTION":"ഓപ്ഷനുകൾ", + "STR_MENU_SECURE_BOOT":"സുരക്ഷിത ബൂട്ട് പിന്തുണ", + "STR_MENU_PART_CFG":"പാർട്ടീഷൻ കോൺഫിഗറേഷൻ", + "STR_BTN_OK":"ശരി", + "STR_BTN_CANCEL":"റദ്ദാക്കുക", + "STR_PRESERVE_SPACE":"ഡിസ്കിൻ്റെ അവസാനം കുറച്ച് സ്ഥലം ഒഴിച്ചിടുക", + "STR_SPACE_VAL_INVALID":"സംവരണം ചെയ്ത സ്ഥലത്തിന് അസാധുവായ മൂല്യം", + "STR_MENU_CLEAR":"വെൻ്റോയ് നീക്കംചെയ്യുക", + "STR_CLEAR_SUCCESS":"ഉപകരണത്തിൽ നിന്ന് വെൻ്റോയ് വിജയകരമായി നീക്കംചെയ്‌തു.", + "STR_CLEAR_FAILED":"ഡിസ്കിൽ നിന്ന് വെൻ്റോയ് നീക്കം ചെയ്യുമ്പോൾ ഒരു പിശക് സംഭവിച്ചു. നിങ്ങൾക്ക് യുഎസ്ബി ഉപകരണം വീണ്ടും ഘടിപ്പിച്ച് വീണ്ടും ശ്രമിക്കാവുന്നതാണ്. വിവരങ്ങൾക്കായി log.txt പരിശോധിക്കുക.", + "STR_MENU_PART_STYLE":"പാർട്ടീഷൻ രീതി", + "STR_DISK_2TB_MBR_ERROR":"2TB-യിൽ കൂടുതൽ വലുപ്പമുള്ള ഡിസ്കിനായി ദയവായി GPT തിരഞ്ഞെടുക്കുക", + "STR_SHOW_ALL_DEV":"എല്ലാ ഉപകരണങ്ങളും കാണിക്കുക", + "STR_PART_ALIGN_4KB":"പാർട്ടീഷനുകൾ 4KB ഉപയോഗിച്ച് വിന്യസിക്കുക", + "STR_WEB_COMMUNICATION_ERR":"ആശയവിനിമയ പിശക്:", + "STR_WEB_REMOTE_ABNORMAL":"ആശയവിനിമയ പിശക്: റിമോട്ട് തകരാറ്", + "STR_WEB_REQUEST_TIMEOUT":"ആശയവിനിമയ പിശക്: അഭ്യർത്ഥനയുടെ സമയം കഴിഞ്ഞു", + "STR_WEB_SERVICE_UNAVAILABLE":"ആശയവിനിമയ പിശക്: സേവനം ലഭ്യമല്ല", + "STR_WEB_TOKEN_MISMATCH":"ഡെമൺ നില അപ്‌ഡേറ്റ് ചെയ്‌തു, ദയവായി പിന്നീട് വീണ്ടും ശ്രമിക്കുക.", + "STR_WEB_SERVICE_BUSY":"സേവനം തിരക്കിലാണ്, ദയവായി പിന്നീട് വീണ്ടും ശ്രമിക്കുക.", + "STR_MENU_VTSI_CREATE":"VTSI ഫയൽ സൃഷ്‌ടിക്കുക", + "STR_VTSI_CREATE_TIP":"ഇത് ഇത്തവണ ഉപകരണത്തിലേക്ക് എഴുതുകയില്ല, ഒരു VTSI ഫയൽ മാത്രം സൃഷ്ടിക്കും#@തുടരട്ടേ?", + "STR_VTSI_CREATE_SUCCESS":"VTSI ഫയൽ വിജയകരമായി സൃഷ്ടിച്ചു!#@വെൻ്റോയ് ഇൻസ്റ്റാളേഷൻ പൂർത്തിയാക്കുന്നതിന് നിങ്ങൾക്ക് Rufus(3.15+) ഉപയോഗിച്ച് ഇത് ഉപകരണത്തിലേക്ക് എഴുതാം.", + "STR_VTSI_CREATE_FAILED":"VTSI ഫയൽ നിർമ്മാണം പരാജയപ്പെട്ടു.", + "STR_MENU_PART_RESIZE":"ഡാറ്റാ നഷ്ടപ്പെടാതെയുള്ള ഇൻസ്റ്റാളേഷൻ", + "STR_PART_RESIZE_TIP":"സാധ്യമെങ്കിൽ, ഡാറ്റാ നഷ്ടപ്പെടാതെയുള്ള ഇൻസ്റ്റാളേഷൻ വെൻ്റോയ് ശ്രമിക്കും. #@തുടരട്ടേ?", + "STR_PART_RESIZE_SUCCESS":"അഭിനന്ദനങ്ങൾ!#@വെൻ്റോയ് ഡാറ്റാ നഷ്ടപ്പെടാതെയുള്ള ഇൻസ്റ്റാളേഷൻ വിജയകരമായി പൂർത്തിയാക്കി.", + "STR_PART_RESIZE_FAILED":"ഡാറ്റാ നഷ്ടപ്പെടാതെയുള്ള ഇൻസ്റ്റാളേഷൻ പരാജയപ്പെട്ടു, വിശദാംശങ്ങൾക്കായി log.txt പരിശോധിക്കുക.", + "STR_PART_RESIZE_UNSUPPORTED":"ചില വ്യവസ്ഥകൾ പാലിക്കാൻ കഴിയാത്തതിനാൽ വെൻ്റോയ് ഡാറ്റാ നഷ്ടപ്പെടാതെയുള്ള ഇൻസ്റ്റാളേഷൻ നിർത്തി. വിശദാംശങ്ങൾക്കായി log.txt പരിശോധിക്കുക.", + "STR_INSTALL_YES_TIP1":"മുന്നറിയിപ്പ്: ഡാറ്റ നഷ്ടപ്പെടും!", + "STR_INSTALL_YES_TIP2":"അപ്‌ഗ്രേഡിന് പകരം ഒരു പുതിയ ഇൻസ്റ്റാളേഷൻ നടത്താൻ നിങ്ങൾ ആഗ്രഹിക്കുന്നുവെന്ന് സ്ഥിരീകരിക്കുന്നതിന് ദയവായി താഴെയുള്ള ടെക്സ്റ്റ് ബോക്സിൽ YES എന്ന് നൽകുക.", + "STR_PART_VENTOY_FS":"വെൻ്റോയ് പാർട്ടീഷനായുള്ള ഫയൽ സിസ്റ്റം", + "STR_PART_FS":"ഫയൽ സിസ്റ്റം", + "STR_PART_CLUSTER":"ക്ലസ്റ്റർ വലുപ്പം", + "STR_PART_CLUSTER_DEFAULT":"സിസ്റ്റം ഡിഫോൾട്ട് മൂല്യം", + "STR_DONATE":"സംഭാവന ചെയ്യുക", + "STR_4KN_UNSUPPORTED":"നിലവിൽ വെൻ്റോയ് 4K നേറ്റീവ് ഉപകരണങ്ങളെ പിന്തുണയ്ക്കുന്നില്ല.", + + "STRXXX":"" + } +] diff --git a/LZIP/buildlz4.txt b/LZIP/buildlz4.txt new file mode 100644 index 0000000..deb0b5f --- /dev/null +++ b/LZIP/buildlz4.txt @@ -0,0 +1,8 @@ + +/opt/diet64/bin/diet -Os gcc -D_FILE_OFFSET_BITS=64 smallz4cat.c -o lz4cat64 + +aarch64-buildroot-linux-uclibc-gcc -Os -static -D_FILE_OFFSET_BITS=64 smallz4cat.c -o lz4cataa64 + +mips64el-linux-musl-gcc -mips64r2 -mabi=64 -static -Os -D_FILE_OFFSET_BITS=64 smallz4cat.c -o lz4catm64e + + diff --git a/LZIP/lunzip-1.11.tar.gz b/LZIP/lunzip-1.11.tar.gz new file mode 100644 index 0000000..3ef326f Binary files /dev/null and b/LZIP/lunzip-1.11.tar.gz differ diff --git a/LZIP/lunzip32 b/LZIP/lunzip32 new file mode 100644 index 0000000..a422baf Binary files /dev/null and b/LZIP/lunzip32 differ diff --git a/LZIP/lunzip64 b/LZIP/lunzip64 new file mode 100644 index 0000000..f5ab4df Binary files /dev/null and b/LZIP/lunzip64 differ diff --git a/LZIP/lunzipaa64 b/LZIP/lunzipaa64 new file mode 100644 index 0000000..72efbab Binary files /dev/null and b/LZIP/lunzipaa64 differ diff --git a/LZIP/lz4cat64 b/LZIP/lz4cat64 new file mode 100644 index 0000000..2790fa9 Binary files /dev/null and b/LZIP/lz4cat64 differ diff --git a/LZIP/lz4cataa64 b/LZIP/lz4cataa64 new file mode 100644 index 0000000..7e025d4 Binary files /dev/null and b/LZIP/lz4cataa64 differ diff --git a/LZIP/lz4catm64e b/LZIP/lz4catm64e new file mode 100644 index 0000000..3d80330 Binary files /dev/null and b/LZIP/lz4catm64e differ diff --git a/LZIP/smallz4cat.c b/LZIP/smallz4cat.c new file mode 100644 index 0000000..db3778b --- /dev/null +++ b/LZIP/smallz4cat.c @@ -0,0 +1,417 @@ +// ////////////////////////////////////////////////////////// +// smallz4cat.c +// Copyright (c) 2016-2019 Stephan Brumme. All rights reserved. +// see https://create.stephan-brumme.com/smallz4/ +// +// "MIT License": +// 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. + +// This program is a shorter, more readable, albeit slower re-implementation of lz4cat ( https://github.com/Cyan4973/xxHash ) + +// compile: gcc smallz4cat.c -O3 -o smallz4cat -Wall -pedantic -std=c99 -s +// The static 8k binary was compiled using Clang and dietlibc (see https://www.fefe.de/dietlibc/ ) + +// Limitations: +// - skippable frames and legacy frames are not implemented (and most likely never will) +// - checksums are not verified (see https://create.stephan-brumme.com/xxhash/ for a simple implementation) + +// Replace getByteFromIn() and sendToOut() by your own code if you need in-memory LZ4 decompression. +// Corrupted data causes a call to unlz4error(). + +// suppress warnings when compiled by Visual C++ +#define _CRT_SECURE_NO_WARNINGS + +#include // stdin/stdout/stderr, fopen, ... +#include // exit() +#include // memcpy + +#ifndef FALSE +#define FALSE 0 +#define TRUE 1 +#endif + +/// error handler +static void unlz4error(const char* msg) +{ + // smaller static binary than fprintf(stderr, "ERROR: %s\n", msg); + fputs("ERROR: ", stderr); + fputs(msg, stderr); + fputc('\n', stderr); + exit(1); +} + + +// ==================== I/O INTERFACE ==================== + + +// read one byte from input, see getByteFromIn() for a basic implementation +typedef unsigned char (*GET_BYTE) (void* userPtr); +// write several bytes, see sendBytesToOut() for a basic implementation +typedef void (*SEND_BYTES)(const unsigned char*, unsigned int, void* userPtr); + +struct UserPtr +{ + // file handles + FILE* in; + FILE* out; + // modify input buffer size as you like ... for most use cases, bigger buffer aren't faster anymore - and even reducing to 1 byte works ! +#define READ_BUFFER_SIZE 4*1024 + unsigned char readBuffer[READ_BUFFER_SIZE]; + unsigned int pos; + unsigned int available; +}; + +/// read a single byte (with simple buffering) +static unsigned char getByteFromIn(void* userPtr) // parameter "userPtr" not needed +{ + /// cast user-specific data + struct UserPtr* user = (struct UserPtr*)userPtr; + + // refill buffer + if (user->pos == user->available) + { + user->pos = 0; + user->available = fread(user->readBuffer, 1, READ_BUFFER_SIZE, user->in); + if (user->available == 0) + unlz4error("out of data"); + } + + // return a byte + return user->readBuffer[user->pos++]; +} + +/// write a block of bytes +static void sendBytesToOut(const unsigned char* data, unsigned int numBytes, void* userPtr) +{ + /// cast user-specific data + struct UserPtr* user = (struct UserPtr*)userPtr; + if (data != NULL && numBytes > 0) + fwrite(data, 1, numBytes, user->out); +} + + +// ==================== LZ4 DECOMPRESSOR ==================== + + +/// decompress everything in input stream (accessed via getByte) and write to output stream (via sendBytes) +void unlz4_userPtr(GET_BYTE getByte, SEND_BYTES sendBytes, const char* dictionary, void* userPtr) +{ + // signature + unsigned char signature1 = getByte(userPtr); + unsigned char signature2 = getByte(userPtr); + unsigned char signature3 = getByte(userPtr); + unsigned char signature4 = getByte(userPtr); + unsigned int signature = (signature4 << 24) | (signature3 << 16) | (signature2 << 8) | signature1; + unsigned char isModern = (signature == 0x184D2204); + unsigned char isLegacy = (signature == 0x184C2102); + if (!isModern && !isLegacy) + unlz4error("invalid signature"); + + unsigned char hasBlockChecksum = FALSE; + unsigned char hasContentSize = FALSE; + unsigned char hasContentChecksum = FALSE; + unsigned char hasDictionaryID = FALSE; + if (isModern) + { + // flags + unsigned char flags = getByte(userPtr); + hasBlockChecksum = flags & 16; + hasContentSize = flags & 8; + hasContentChecksum = flags & 4; + hasDictionaryID = flags & 1; + + // only version 1 file format + unsigned char version = flags >> 6; + if (version != 1) + unlz4error("only LZ4 file format version 1 supported"); + + // ignore blocksize + char numIgnore = 1; + + // ignore, skip 8 bytes + if (hasContentSize) + numIgnore += 8; + // ignore, skip 4 bytes + if (hasDictionaryID) + numIgnore += 4; + + // ignore header checksum (xxhash32 of everything up this point & 0xFF) + numIgnore++; + + // skip all those ignored bytes + while (numIgnore--) + getByte(userPtr); + } + + // don't lower this value, backreferences can be 64kb far away +#define HISTORY_SIZE 64*1024 + // contains the latest decoded data + unsigned char history[HISTORY_SIZE]; + // next free position in history[] + unsigned int pos = 0; + + // dictionary compression is a recently introduced feature, just move its contents to the buffer + if (dictionary != NULL) + { + // open dictionary + FILE* dict = fopen(dictionary, "rb"); + if (!dict) + unlz4error("cannot open dictionary"); + + // get dictionary's filesize + fseek(dict, 0, SEEK_END); + long dictSize = ftell(dict); + // only the last 64k are relevant + long relevant = dictSize < 65536 ? 0 : dictSize - 65536; + fseek(dict, relevant, SEEK_SET); + if (dictSize > 65536) + dictSize = 65536; + // read it and store it at the end of the buffer + fread(history + HISTORY_SIZE - dictSize, 1, dictSize, dict); + fclose(dict); + } + + // parse all blocks until blockSize == 0 + while (1) + { + // block size + unsigned int blockSize = getByte(userPtr); + blockSize |= (unsigned int)getByte(userPtr) << 8; + blockSize |= (unsigned int)getByte(userPtr) << 16; + blockSize |= (unsigned int)getByte(userPtr) << 24; + + // highest bit set ? + unsigned char isCompressed = isLegacy || (blockSize & 0x80000000) == 0; + if (isModern) + blockSize &= 0x7FFFFFFF; + + // stop after last block + if (blockSize == 0) + break; + + if (isCompressed) + { + // decompress block + unsigned int blockOffset = 0; + unsigned int numWritten = 0; + while (blockOffset < blockSize) + { + // get a token + unsigned char token = getByte(userPtr); + blockOffset++; + + // determine number of literals + unsigned int numLiterals = token >> 4; + if (numLiterals == 15) + { + // number of literals length encoded in more than 1 byte + unsigned char current; + do + { + current = getByte(userPtr); + numLiterals += current; + blockOffset++; + } while (current == 255); + } + + blockOffset += numLiterals; + + // copy all those literals + if (pos + numLiterals < HISTORY_SIZE) + { + // fast loop + while (numLiterals-- > 0) + history[pos++] = getByte(userPtr); + } + else + { + // slow loop + while (numLiterals-- > 0) + { + history[pos++] = getByte(userPtr); + + // flush output buffer + if (pos == HISTORY_SIZE) + { + sendBytes(history, HISTORY_SIZE, userPtr); + numWritten += HISTORY_SIZE; + pos = 0; + } + } + } + + // last token has only literals + if (blockOffset == blockSize) + break; + + // match distance is encoded in two bytes (little endian) + unsigned int delta = getByte(userPtr); + delta |= (unsigned int)getByte(userPtr) << 8; + // zero isn't allowed + if (delta == 0) + unlz4error("invalid offset"); + blockOffset += 2; + + // match length (always >= 4, therefore length is stored minus 4) + unsigned int matchLength = 4 + (token & 0x0F); + if (matchLength == 4 + 0x0F) + { + unsigned char current; + do // match length encoded in more than 1 byte + { + current = getByte(userPtr); + matchLength += current; + blockOffset++; + } while (current == 255); + } + + // copy match + unsigned int referencePos = (pos >= delta) ? (pos - delta) : (HISTORY_SIZE + pos - delta); + // start and end within the current 64k block ? + if (pos + matchLength < HISTORY_SIZE && referencePos + matchLength < HISTORY_SIZE) + { + // read/write continuous block (no wrap-around at the end of history[]) + // fast copy + if (pos >= referencePos + matchLength || referencePos >= pos + matchLength) + { + // non-overlapping + memcpy(history + pos, history + referencePos, matchLength); + pos += matchLength; + } + else + { + // overlapping, slower byte-wise copy + while (matchLength-- > 0) + history[pos++] = history[referencePos++]; + } + } + else + { + // either read or write wraps around at the end of history[] + while (matchLength-- > 0) + { + // copy single byte + history[pos++] = history[referencePos++]; + + // cannot write anymore ? => wrap around + if (pos == HISTORY_SIZE) + { + // flush output buffer + sendBytes(history, HISTORY_SIZE, userPtr); + numWritten += HISTORY_SIZE; + pos = 0; + } + // wrap-around of read location + referencePos %= HISTORY_SIZE; + } + } + } + + // all legacy blocks must be completely filled - except for the last one + if (isLegacy && numWritten + pos < 8*1024*1024) + break; + } + else + { + // copy uncompressed data and add to history, too (if next block is compressed and some matches refer to this block) + while (blockSize-- > 0) + { + // copy a byte ... + history[pos++] = getByte(userPtr); + // ... until buffer is full => send to output + if (pos == HISTORY_SIZE) + { + sendBytes(history, HISTORY_SIZE, userPtr); + pos = 0; + } + } + } + + if (hasBlockChecksum) + { + // ignore checksum, skip 4 bytes + getByte(userPtr); getByte(userPtr); getByte(userPtr); getByte(userPtr); + } + } + + if (hasContentChecksum) + { + // ignore checksum, skip 4 bytes + getByte(userPtr); getByte(userPtr); getByte(userPtr); getByte(userPtr); + } + + // flush output buffer + sendBytes(history, pos, userPtr); +} + +/// old interface where getByte and sendBytes use global file handles +void unlz4(GET_BYTE getByte, SEND_BYTES sendBytes, const char* dictionary) +{ + unlz4_userPtr(getByte, sendBytes, dictionary, NULL); +} + + +// ==================== COMMAND-LINE HANDLING ==================== + + +/// parse command-line +int main(int argc, const char* argv[]) +{ + // default input/output streams + struct UserPtr user = + { + .in = stdin, + .out = stdout, + .pos = 0, // initial input buffer is empty + .available = 0 + }; + + const char* dictionary = NULL; + + // first command-line parameter is our input filename / but ignore "-" which stands for STDIN + int parameter; + for (parameter = 1; parameter < argc; parameter++) + { + const char* current = argv[parameter]; + // dictionary + if (current[0] == '-' && current[1] == 'D') + { + if (parameter + 1 >= argc) + unlz4error("no dictionary filename found"); + dictionary = argv[++parameter]; + continue; + } + + // filename + // read from STDIN, default behavior + if (current[0] != '-' && current[1] != '\0') + { + // already have a filename - at most one filename is allowed (except for dictionary) ? + if (user.in != stdin) + unlz4error("can only decompress one file at a time"); + // get handle + user.in = fopen(argv[1], "rb"); + if (!user.in) + unlz4error("file not found"); + } + } + + // and go ! + unlz4_userPtr(getByteFromIn, sendBytesToOut, dictionary, &user); + return 0; +} diff --git a/License/BSD-2-Clause-Patent.txt b/License/BSD-2-Clause-Patent.txt new file mode 100644 index 0000000..3795caf --- /dev/null +++ b/License/BSD-2-Clause-Patent.txt @@ -0,0 +1,51 @@ +Copyright (c) 2019, TianoCore and contributors. All rights reserved. + +SPDX-License-Identifier: BSD-2-Clause-Patent + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +Subject to the terms and conditions of this license, each copyright holder +and contributor hereby grants to those receiving rights under this license +a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable +(except for failure to satisfy the conditions of this license) patent +license to make, have made, use, offer to sell, sell, import, and otherwise +transfer this software, where such license applies only to those patent +claims, already acquired or hereafter acquired, licensable by such copyright +holder or contributor that are necessarily infringed by: + +(a) their Contribution(s) (the licensed copyrights of copyright holders and + non-copyrightable additions of contributors, in source or binary form) + alone; or + +(b) combination of their Contribution(s) with the work of authorship to + which such Contribution(s) was added by such copyright holder or + contributor, if, at the time the Contribution is added, such addition + causes such combination to be necessarily infringed. The patent license + shall not apply to any other combinations which include the + Contribution. + +Except as expressly stated above, no rights or licenses from any copyright +holder or contributor is granted under this license, whether expressly, by +implication, estoppel or otherwise. + +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 HOLDERS 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. \ No newline at end of file diff --git a/License/BSD.txt b/License/BSD.txt new file mode 100644 index 0000000..dbdb05e --- /dev/null +++ b/License/BSD.txt @@ -0,0 +1,30 @@ +BSD License + +For Zstandard software + +Copyright (c) 2016-present, Facebook, Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name Facebook nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + prior written permission. + +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 HOLDER 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. \ No newline at end of file diff --git a/License/MIT.txt b/License/MIT.txt new file mode 100644 index 0000000..f47dc84 --- /dev/null +++ b/License/MIT.txt @@ -0,0 +1,8 @@ +The MIT License (MIT) +Copyright © 2020 + +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. \ No newline at end of file diff --git a/License/gpl-2.0.txt b/License/gpl-2.0.txt new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/License/gpl-2.0.txt @@ -0,0 +1,339 @@ + 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/License/gpl-3.0.txt b/License/gpl-3.0.txt new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/License/gpl-3.0.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. 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 +them 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 prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. 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. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey 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; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If 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 convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU 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 that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + 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. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +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. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + 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 +state 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 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program 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, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU 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. But first, please read +. diff --git a/License/lgpl-3.0.txt b/License/lgpl-3.0.txt new file mode 100644 index 0000000..80d241e --- /dev/null +++ b/License/lgpl-3.0.txt @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + 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 that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU 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 as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. \ No newline at end of file diff --git a/License/license-7z.txt b/License/license-7z.txt new file mode 100644 index 0000000..41cc032 --- /dev/null +++ b/License/license-7z.txt @@ -0,0 +1,37 @@ + +imdisk follows LGPL license (see lgpl-3.0.txt) + +Ventoy only use its binaries 7za.exe + +========7zip License Information=============== + 7-Zip Extra + ~~~~~~~~~~~ + License for use and distribution + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Copyright (C) 1999-2019 Igor Pavlov. + + 7-Zip Extra files are under the GNU LGPL license. + + + Notes: + You can use 7-Zip Extra on any computer, including a computer in a commercial + organization. You don't need to register or pay for 7-Zip. + + + GNU LGPL information + -------------------- + + 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 can receive a copy of the GNU Lesser General Public License from + http://www.gnu.org/ + diff --git a/License/license-AdminLTE.txt b/License/license-AdminLTE.txt new file mode 100644 index 0000000..a751318 --- /dev/null +++ b/License/license-AdminLTE.txt @@ -0,0 +1 @@ +AdminLTE follows the MIT License (see MIT.txt) diff --git a/License/license-PorteusKiosk.txt b/License/license-PorteusKiosk.txt new file mode 100644 index 0000000..ecc0ce2 --- /dev/null +++ b/License/license-PorteusKiosk.txt @@ -0,0 +1,3 @@ +Porteus Kiosk follows GPL license (see gpl-3.0.txt) + +Ventoy does not modify its source code, only its library is used. diff --git a/License/license-bootstrap.txt b/License/license-bootstrap.txt new file mode 100644 index 0000000..3dc9e9d --- /dev/null +++ b/License/license-bootstrap.txt @@ -0,0 +1 @@ +bootstrap follows the MIT License (see MIT.txt) diff --git a/License/license-busybox.txt b/License/license-busybox.txt new file mode 100644 index 0000000..65dfcb4 --- /dev/null +++ b/License/license-busybox.txt @@ -0,0 +1,3 @@ +BusyBox follows GPLv2 license (see gpl-2.0.txt) + +Ventoy does not modify its source code, only its binary is used. diff --git a/License/license-device-mapper.txt b/License/license-device-mapper.txt new file mode 100644 index 0000000..e8ffffa --- /dev/null +++ b/License/license-device-mapper.txt @@ -0,0 +1,4 @@ + +Device Mapper follows GPLv2 License (see gpl-2.0.txt) + +Ventoy modify its source code, these code modified by Ventoy follows the same license as Device Mapper. diff --git a/License/license-edk2.txt b/License/license-edk2.txt new file mode 100644 index 0000000..849aa70 --- /dev/null +++ b/License/license-edk2.txt @@ -0,0 +1,2 @@ +EDK2 follows BSD-2-Clause Plus Patent License (see BSD-2-Clause-Patent.txt) +Ventoy add an uefi application module in MdeModulePkg, the code is developed by ventoy and is under GPLv3+ License (see gpl-3.0.txt). diff --git a/License/license-efifs.txt b/License/license-efifs.txt new file mode 100644 index 0000000..3fd3627 --- /dev/null +++ b/License/license-efifs.txt @@ -0,0 +1,2 @@ +efifs follows GPLv3 (see gpl-3.0.txt) License. +Ventoy modify its source code, these code modified by Ventoy follows the same license as efifs. diff --git a/License/license-exfat.txt b/License/license-exfat.txt new file mode 100644 index 0000000..a4c7a17 --- /dev/null +++ b/License/license-exfat.txt @@ -0,0 +1,2 @@ +exfat follows GPLv2 (see gpl-2.0.txt) License. +Ventoy modify its source code, these code modified by Ventoy follows the same license as exfat. diff --git a/License/license-fat-filelib.txt b/License/license-fat-filelib.txt new file mode 100644 index 0000000..73b8c28 --- /dev/null +++ b/License/license-fat-filelib.txt @@ -0,0 +1,3 @@ +fat-filelib follows GPL license (see gpl-3.0.txt) + +Ventoy does not modify its source code, only its library is used. diff --git a/License/license-fatfs.txt b/License/license-fatfs.txt new file mode 100644 index 0000000..83abcac --- /dev/null +++ b/License/license-fatfs.txt @@ -0,0 +1,4 @@ +Therefore FatFs license is one of the BSD-style licenses but there is a significant feature. FatFs is mainly intended for embedded systems. In order to extend the usability for commercial products, the redistributions of FatFs in binary form, such as embedded code, binary library and any forms without source code, does not need to include about FatFs in the documentations. This is equivalent to the 1-clause BSD license. Of course FatFs is compatible with the most of open source software licenses including GNU GPL. When you redistribute the FatFs source code with any changes or create a fork, the license can also be changed to GNU GPL, BSD-style license or any open source software license that not conflict with FatFs license. + +Ventoy modify its source code, these code modified by Ventoy follow the same license as FatFs. + diff --git a/License/license-grub2.txt b/License/license-grub2.txt new file mode 100644 index 0000000..7d4dfd7 --- /dev/null +++ b/License/license-grub2.txt @@ -0,0 +1,3 @@ +GRUB2 follows GPLv3+ license (see gpl-3.0.txt) +Ventoy modify its source code, these code modified by Ventoy follow the same license as grub2. + diff --git a/License/license-imdisk.txt b/License/license-imdisk.txt new file mode 100644 index 0000000..72122f6 --- /dev/null +++ b/License/license-imdisk.txt @@ -0,0 +1,4 @@ +imdisk follows GPL license (see gpl-3.0.txt) + +Ventoy does not modify its source code, only its binary is used. + diff --git a/License/license-ipxe.txt b/License/license-ipxe.txt new file mode 100644 index 0000000..7045ba9 --- /dev/null +++ b/License/license-ipxe.txt @@ -0,0 +1,2 @@ +iPXE follows GPLv2 (see gpl-2.0.txt) or Unmodified Binary Distribution Licence (see ubdl.txt) +Ventoy modify its source code, these code modified by Ventoy follow the same license as iPXE. diff --git a/License/license-jquery.txt b/License/license-jquery.txt new file mode 100644 index 0000000..8b0fac0 --- /dev/null +++ b/License/license-jquery.txt @@ -0,0 +1 @@ +jquery follows the MIT License (see MIT.txt) diff --git a/License/license-libfuse.txt b/License/license-libfuse.txt new file mode 100644 index 0000000..5b3759c --- /dev/null +++ b/License/license-libfuse.txt @@ -0,0 +1,3 @@ +libfuse follows LGPL license (see lgpl.txt) + +Ventoy does not modify its source code, only its library is used. diff --git a/License/license-libhttp.txt b/License/license-libhttp.txt new file mode 100644 index 0000000..828f85d --- /dev/null +++ b/License/license-libhttp.txt @@ -0,0 +1,3 @@ +libhttp follows the MIT License (see MIT.txt) + +Ventoy does not modify its source code, only its header file and lib is used. diff --git a/License/license-liblzma.txt b/License/license-liblzma.txt new file mode 100644 index 0000000..7a7b7b2 --- /dev/null +++ b/License/license-liblzma.txt @@ -0,0 +1,3 @@ +liblzma follows LGPL license (see lgpl.txt) + +Ventoy does not modify its source code, only its library is used. diff --git a/License/license-logo.txt b/License/license-logo.txt new file mode 100644 index 0000000..cfaa877 --- /dev/null +++ b/License/license-logo.txt @@ -0,0 +1,5 @@ +Ventoy Logo was downloaded from https://www.easyicon.net/29165-usb_icon.html +As descripted in the website: + +Author: Ahmad Hania +License: Creative Commons (Attribution-Noncommercial-Share Alike 3.0 Unported) diff --git a/License/license-lunzip.txt b/License/license-lunzip.txt new file mode 100644 index 0000000..8b4f5d0 --- /dev/null +++ b/License/license-lunzip.txt @@ -0,0 +1,3 @@ +lunzip follows GPLv2+ license (see gpl-2.0.txt) + +Ventoy does not modify its source code, only its binary is used. diff --git a/License/license-lz4.txt b/License/license-lz4.txt new file mode 100644 index 0000000..dc4fd58 --- /dev/null +++ b/License/license-lz4.txt @@ -0,0 +1,5 @@ + +Ventoy does not modify its source code, only its library is used. + +The library source of lz4 follows the BSD 2-Clause License. + diff --git a/License/license-lzo.txt b/License/license-lzo.txt new file mode 100644 index 0000000..28f3456 --- /dev/null +++ b/License/license-lzo.txt @@ -0,0 +1,3 @@ +lzo follows GPLv2+ license (see gpl-2.0.txt) + +Ventoy does not modify its source code, only its library is used. diff --git a/License/license-mini_gzip.txt b/License/license-mini_gzip.txt new file mode 100644 index 0000000..296be62 --- /dev/null +++ b/License/license-mini_gzip.txt @@ -0,0 +1,13 @@ + +https://github.com/wkoszek/mini_gzip + +Ventoy modify its source code, these code modified by Ventoy follow the same license as mini_gzip. + +=====================================License================================================= +Copyright (c) 2015, Wojciech Adam Koszek wojciech@koszek.com All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. \ No newline at end of file diff --git a/License/license-rufus.txt b/License/license-rufus.txt new file mode 100644 index 0000000..fb2244d --- /dev/null +++ b/License/license-rufus.txt @@ -0,0 +1,3 @@ +Rufus follows GPLv3+ license (see gpl-3.0.txt) +Ventoy uses some function from Rufus, and all the Ventoy's code also follow GPLv3+ license. + diff --git a/License/license-smallz4.txt b/License/license-smallz4.txt new file mode 100644 index 0000000..956869f --- /dev/null +++ b/License/license-smallz4.txt @@ -0,0 +1,4 @@ +smalLz4 follows MIT license (see MIT.txt) + +Ventoy does not modify its source code, only its binary is used. + diff --git a/License/license-squashfs-tools.txt b/License/license-squashfs-tools.txt new file mode 100644 index 0000000..bf9785e --- /dev/null +++ b/License/license-squashfs-tools.txt @@ -0,0 +1,4 @@ + +squashfs-tools follows the GPLv2 License (see gpl-2.0.txt). +Ventoy modify its source code, these code modified by Ventoy follow the same license as squashfs-tools. + diff --git a/License/license-tinycore.txt b/License/license-tinycore.txt new file mode 100644 index 0000000..4b8650a --- /dev/null +++ b/License/license-tinycore.txt @@ -0,0 +1,4 @@ +tinycore follows the GPL-v2 License (see gpl-2.0.txt) + +Ventoy does not modify its source code, only its binraries are used. + diff --git a/License/license-vblade.txt b/License/license-vblade.txt new file mode 100644 index 0000000..a0b45cb --- /dev/null +++ b/License/license-vblade.txt @@ -0,0 +1,3 @@ +vblade follows GPLv2 license (see gpl-2.0.txt) +Ventoy modify its source code, these code modified by Ventoy follow the same license as vblade. + diff --git a/License/license-ventoy.txt b/License/license-ventoy.txt new file mode 100644 index 0000000..f6c5012 --- /dev/null +++ b/License/license-ventoy.txt @@ -0,0 +1 @@ +All the modules and tools developed by Ventoy are under GPLv3+ (see gpl-3.0.txt) License. diff --git a/License/license-wimboot.txt b/License/license-wimboot.txt new file mode 100644 index 0000000..8ab4754 --- /dev/null +++ b/License/license-wimboot.txt @@ -0,0 +1,4 @@ +wimboot follows GPLv2+ license (see gpl-2.0.txt) + +Ventoy modified the code and follow the same license as wimboot. + diff --git a/License/license-xzembedded.txt b/License/license-xzembedded.txt new file mode 100644 index 0000000..4641c7f --- /dev/null +++ b/License/license-xzembedded.txt @@ -0,0 +1 @@ +XZ Embedded has been put into the public domain, thus you can do whatever you want with it. diff --git a/License/license-zlib.txt b/License/license-zlib.txt new file mode 100644 index 0000000..cad708d --- /dev/null +++ b/License/license-zlib.txt @@ -0,0 +1,27 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.11, January 15th, 2017 + + Copyright (C) 1995-2017 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 + +*/ + +Ventoy does not modify its source code, only its library is used. diff --git a/License/license-zstd.txt b/License/license-zstd.txt new file mode 100644 index 0000000..f2cad9f --- /dev/null +++ b/License/license-zstd.txt @@ -0,0 +1,3 @@ +zstd follows the BSD License (see BSD.txt) + +Ventoy does not modify its source code, only its binrary is used. diff --git a/License/ubdl.txt b/License/ubdl.txt new file mode 100644 index 0000000..780ddcd --- /dev/null +++ b/License/ubdl.txt @@ -0,0 +1,59 @@ +UNMODIFIED BINARY DISTRIBUTION LICENCE + + +PREAMBLE + +The GNU General Public License provides a legal guarantee that +software covered by it remains free (in the sense of freedom, not +price). It achieves this guarantee by imposing obligations on anyone +who chooses to distribute the software. + +Some of these obligations may be seen as unnecessarily burdensome. In +particular, when the source code for the software is already publicly +and freely available, there is minimal value in imposing upon each +distributor the obligation to provide the complete source code (or an +equivalent written offer to provide the complete source code). + +This Licence allows for the distribution of unmodified binaries built +from publicly available source code, without imposing the obligations +of the GNU General Public License upon anyone who chooses to +distribute only the unmodified binaries built from that source code. + +The extra permissions granted by this Licence apply only to unmodified +binaries built from source code which has already been made available +to the public in accordance with the terms of the GNU General Public +Licence. Nothing in this Licence allows for the creation of +closed-source modified versions of the Program. Any modified versions +of the Program are subject to the usual terms and conditions of the +GNU General Public License. + + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +This Licence 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 Unmodified Binary Distribution Licence. All +terms used in the text of this Licence are to be interpreted as they +are used in version 2 of the GNU General Public License as published +by the Free Software Foundation. + +If you have made this Program available to the public in both source +code and executable form in accordance with 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, then you are hereby granted an additional permission to use, +copy, and distribute the unmodified executable form of this Program +(the "Unmodified Binary") without restriction, including the right to +permit persons to whom the Unmodified Binary is furnished to do +likewise, subject to the following conditions: + +- when started running, the Program must display an announcement which + includes the details of your existing publication of the Program + made in accordance with the terms of the GNU General Public License. + For example, the Program could display the URL of the publicly + available source code from which the Unmodified Binary was built. + +- when exercising your right to grant permissions under this Licence, + you do not need to refer directly to the text of this Licence, but + you may not grant permissions beyond those granted to you by this + Licence. diff --git a/LinuxGUI/EXLIB/README.txt b/LinuxGUI/EXLIB/README.txt new file mode 100644 index 0000000..ecbe557 --- /dev/null +++ b/LinuxGUI/EXLIB/README.txt @@ -0,0 +1,60 @@ + +====== ARM64 ====== +1. Download CentOS-7-aarch64-Everything-2009.iso from internet. +2. mount CentOS-7-aarch64-Everything-2009.iso /mnt +3. sh prepare_lib_aarch64.sh /mnt/Packages/ + + +====== MIPS64EL ====== +1. build dpkg for CentOS7 +download dpkg_1.18.25.tar.xz from internet. +cd dpkg-1.18.25 +./configure +make +cp -a ./src/dpkg /sbin/ +cp -a ./dpkg-deb/dpkg-deb /sbin/ + +2. download debian 10.x mips64el DVD iso (e.g. debian-10.9.0-mips64el-DVD-1.iso) form internet +3. mount debian-10.9.0-mips64el-DVD-1.iso /mnt +4. sh prepare_gtk_lib_mips64el.sh /mnt/ +5. download the following packages from internet and dpkg -x each of them +pool/main/g/gtk+3.0/libgtk-3-dev_3.24.5-1_mips64el.deb +pool/main/b/brotli/libbrotli1_1.0.9-2+b2_mips64el.deb +pool/main/d/double-conversion/libdouble-conversion3_3.1.5-6.1_mips64el.deb +pool/main/d/double-conversion/libdouble-conversion1_3.1.0-3_mips64el.deb +pool/main/libg/libglvnd/libgl1_1.3.2-1~bpo10+2_mips64el.deb +pool/main/libg/libglvnd/libglvnd0_1.3.2-1~bpo10+2_mips64el.deb +pool/main/libg/libglvnd/libglx0_1.3.2-1~bpo10+2_mips64el.deb +pool/main/q/qtbase-opensource-src/libqt5concurrent5_5.11.3+dfsg1-1+deb10u4_mips64el.deb +pool/main/q/qtbase-opensource-src/libqt5core5a_5.11.3+dfsg1-1+deb10u4_mips64el.deb +pool/main/q/qtbase-opensource-src/libqt5dbus5_5.11.3+dfsg1-1+deb10u4_mips64el.deb +pool/main/q/qtbase-opensource-src/libqt5gui5_5.11.3+dfsg1-1+deb10u4_mips64el.deb +pool/main/q/qtbase-opensource-src/libqt5network5_5.11.3+dfsg1-1+deb10u4_mips64el.deb +pool/main/q/qtbase-opensource-src/libqt5opengl5_5.11.3+dfsg1-1+deb10u4_mips64el.deb +pool/main/q/qtbase-opensource-src/libqt5opengl5-dev_5.11.3+dfsg1-1+deb10u4_mips64el.deb +pool/main/q/qtbase-opensource-src/libqt5widgets5_5.11.3+dfsg1-1+deb10u4_mips64el.deb +pool/main/q/qtbase-opensource-src/libqt5xml5_5.11.3+dfsg1-1+deb10u4_mips64el.deb +pool/main/q/qtbase-opensource-src/qt5-qmake_5.11.3+dfsg1-1+deb10u4_mips64el.deb +pool/main/q/qtbase-opensource-src/qtbase5-dev_5.11.3+dfsg1-1+deb10u4_mips64el.deb +pool/main/q/qtbase-opensource-src/qtbase5-dev-tools_5.11.3+dfsg1-1+deb10u4_mips64el.deb +pool/main/q/qtbase-opensource-src/qtbase5-examples_5.11.3+dfsg1-1+deb10u4_mips64el.deb +pool/main/q/qtbase-opensource-src/qtbase5-private-dev_5.11.3+dfsg1-1+deb10u4_mips64el.deb + + +==== I386 === +We need a CentOS8 environment +Install CentOS 8 x86_64 system. +yum update +yum install gcc +yum install gcc-c++ +yum install gcc.i686 +yum install glibc.i686 glibc-devel.i686 glibc-headers.i686 glibc-static.i686 glibc-nss-devel.i686 +yum install libstdc++.i686 +yum install harfbuzz.i686 +yum install zlib.i686 +yum install mesa-libGL.i686 + +pack all /usr /etc directories and extract to /opt/CentOS8/ + + + diff --git a/LinuxGUI/EXLIB/aarch64libs b/LinuxGUI/EXLIB/aarch64libs new file mode 100644 index 0000000..ac280e7 --- /dev/null +++ b/LinuxGUI/EXLIB/aarch64libs @@ -0,0 +1,57 @@ +gtk3- +qt5 +GL +icu +glib2- +pango- +cairo- +gdk-pixbuf2- +libXcursor- +libcap- +pcre- +libffi- +libthai- +fribidi- +libXrender- +libxcb- +pixman- +libpng- +libselinux- +zlib- +libwayland- +wayland- +libglvnd- +elfutils- +libattr- +libX11- +libXi- +libXfixes- +libepoxy- +harfbuzz- +fontconfig- +freetype- +libXinerama- +libXrandr- +libXcomposite- +libXdamage- +libxkbcommon- +libuuid- +libmount- +atk- +libblkid- +graphite2- +libXau- +bzip2- +expat- +libXext- +pcre2- +pcre- +at-spi2-atk +dbus- +dbus-libs +systemd-libs +at-spi2-core +xz-libs +lz4- +libgcrypt- +libgpg-error- diff --git a/LinuxGUI/EXLIB/download_lib.sh b/LinuxGUI/EXLIB/download_lib.sh new file mode 100644 index 0000000..54442cd --- /dev/null +++ b/LinuxGUI/EXLIB/download_lib.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +if [ -z "$1" ]; then + echo "please input url" + exit 1 +fi + +if [ -n "$2" ]; then + proxy_opt="-x $2" +fi + +rm -rf download +mkdir -p download +cd download + +grep pool ../README.txt | while read line; do + a="$line" + b=$(basename "$a") + echo "downloading $b ..." + curl -s $1/debian/"$a" $proxy_opt -o "$b" + + a=$(echo $line | sed "s/mips64el/i386/g") + b=$(basename "$a") + echo "downloading $b ..." + curl -s $1/debian/"$a" $proxy_opt -o "$b" +done + +cd .. diff --git a/LinuxGUI/EXLIB/i386libs b/LinuxGUI/EXLIB/i386libs new file mode 100644 index 0000000..3e548f6 --- /dev/null +++ b/LinuxGUI/EXLIB/i386libs @@ -0,0 +1,7 @@ +libmd +libzstd +libpcre2-16 +libicu +qt5 +libgpg-error +libpng diff --git a/LinuxGUI/EXLIB/mips64ellibs b/LinuxGUI/EXLIB/mips64ellibs new file mode 100644 index 0000000..705631e --- /dev/null +++ b/LinuxGUI/EXLIB/mips64ellibs @@ -0,0 +1,52 @@ +libmd +libzstd +libpcre2-16 +libicu +qt5 +libglib2 +libgtk-3 +libpango +libharfbuzz +pixbuf2 +atk +wayland +libx11 +libxi6 +epoxy +cairo +composite +damage +libxfixes +libxkbcommon +libfontconfig +libfreetype +libxinerama +libxrandr +libxcursor +libxext +libthai +libfribidi +libpixman +libpng +libxcb +libxrender +zlib1g +libmount +libselinux +libffi +libpcre3 +libdbus +libatspi +libgraphite +libexpat +libuuid +libdatrie +libxdmcp +libblkid +libxau +libsystemd +libbsd +liblz4 +liblzma +libgcrypt +libgpg-error diff --git a/LinuxGUI/EXLIB/prepare_lib_aarch64.sh b/LinuxGUI/EXLIB/prepare_lib_aarch64.sh new file mode 100644 index 0000000..33075ae --- /dev/null +++ b/LinuxGUI/EXLIB/prepare_lib_aarch64.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +if [ ! -d $1 ]; then + echo "$1 not exist" + exit 1 +fi + +rm -rf aarch64 +mkdir aarch64 +cd aarch64 + +cat ../aarch64libs | while read a; do + ls -1 $1/*$a* | while read rpm; do + echo "extract ${rpm##*/} ..." + rpm2cpio $rpm | cpio -idmu --quiet + done +done + +cd .. diff --git a/LinuxGUI/EXLIB/prepare_lib_i386.sh b/LinuxGUI/EXLIB/prepare_lib_i386.sh new file mode 100644 index 0000000..540c94b --- /dev/null +++ b/LinuxGUI/EXLIB/prepare_lib_i386.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +if [ ! -d $1/pool ]; then + echo "$1/pool not exist" + exit 1 +fi + +rm -rf i386 +mkdir i386 +cd i386 + +cat ../i386libs | while read line; do + find "$1/pool" -name "*${line}*.deb" | while read deb; do + echo "extract ${deb##*/} ..." + dpkg -x $deb . + done +done + +ls -1 ../download/*i386.deb | while read line; do + echo "extract ${line} ..." + dpkg -x "$line" . +done + +cd .. + diff --git a/LinuxGUI/EXLIB/prepare_lib_mips64el.sh b/LinuxGUI/EXLIB/prepare_lib_mips64el.sh new file mode 100644 index 0000000..73e9786 --- /dev/null +++ b/LinuxGUI/EXLIB/prepare_lib_mips64el.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +if [ ! -d $1/pool ]; then + echo "$1/pool not exist" + exit 1 +fi + +rm -rf mips64el +mkdir mips64el +cd mips64el + +cat ../mips64ellibs | while read line; do + find "$1/pool" -name "*${line}*.deb" | while read deb; do + echo "extract ${deb##*/} ..." + dpkg -x $deb . + done +done + +ls -1 ../download/*mips64el.deb | while read line; do + echo "extract ${line} ..." + dpkg -x "$line" . +done + +cd .. + diff --git a/LinuxGUI/Ventoy2Disk/Core/ventoy_crc32.c b/LinuxGUI/Ventoy2Disk/Core/ventoy_crc32.c new file mode 100644 index 0000000..9f80c61 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Core/ventoy_crc32.c @@ -0,0 +1,299 @@ +/****************************************************************************** + * crc32.c ---- ventoy crc32 + * + * Copyright (c) 2021, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ +#include +#include +#include +#include +#include +#include + +static uint32_t g_crc_table[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 +}; + +uint32_t ventoy_crc32(void *Buffer, uint32_t Length) +{ + uint32_t i; + uint8_t *Ptr = Buffer; + uint32_t Crc = 0xFFFFFFFF; + + for (i = 0; i < Length; i++, Ptr++) + { + Crc = (Crc >> 8) ^ g_crc_table[(uint8_t) Crc ^ *Ptr]; + } + + return Crc ^ 0xffffffff; +} + diff --git a/LinuxGUI/Ventoy2Disk/Core/ventoy_define.h b/LinuxGUI/Ventoy2Disk/Core/ventoy_define.h new file mode 100644 index 0000000..ba1a4d2 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Core/ventoy_define.h @@ -0,0 +1,190 @@ +/****************************************************************************** + * ventoy_define.h + * + * Copyright (c) 2021, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ +#ifndef __VENTOY_DEFINE_H__ +#define __VENTOY_DEFINE_H__ + +#define MAX_DISK_NUM 256 + +#define SIZE_1MB 1048576 +#define SIZE_1GB 1073741824 + +#define VTOYIMG_PART_START_BYTES (1024 * 1024) +#define VTOYIMG_PART_START_SECTOR 2048 + +#define VTOYEFI_PART_BYTES (32 * 1024 * 1024) +#define VTOYEFI_PART_SECTORS 65536 + +#pragma pack(1) + +typedef struct vtoy_guid +{ + uint32_t data1; + uint16_t data2; + uint16_t data3; + uint8_t data4[8]; +}vtoy_guid; + +typedef struct PART_TABLE +{ + uint8_t Active; // 0x00 0x80 + + uint8_t StartHead; + uint16_t StartSector : 6; + uint16_t StartCylinder : 10; + + uint8_t FsFlag; + + uint8_t EndHead; + uint16_t EndSector : 6; + uint16_t EndCylinder : 10; + + uint32_t StartSectorId; + uint32_t SectorCount; +}PART_TABLE; + +typedef struct MBR_HEAD +{ + uint8_t BootCode[446]; + PART_TABLE PartTbl[4]; + uint8_t Byte55; + uint8_t ByteAA; +}MBR_HEAD; + +typedef struct VTOY_GPT_HDR +{ + char Signature[8]; /* EFI PART */ + uint8_t Version[4]; + uint32_t Length; + uint32_t Crc; + uint8_t Reserved1[4]; + uint64_t EfiStartLBA; + uint64_t EfiBackupLBA; + uint64_t PartAreaStartLBA; + uint64_t PartAreaEndLBA; + vtoy_guid DiskGuid; + uint64_t PartTblStartLBA; + uint32_t PartTblTotNum; + uint32_t PartTblEntryLen; + uint32_t PartTblCrc; + uint8_t Reserved2[420]; +}VTOY_GPT_HDR; + +typedef struct VTOY_GPT_PART_TBL +{ + vtoy_guid PartType; + vtoy_guid PartGuid; + uint64_t StartLBA; + uint64_t LastLBA; + uint64_t Attr; + uint16_t Name[36]; +}VTOY_GPT_PART_TBL; + +typedef struct VTOY_GPT_INFO +{ + MBR_HEAD MBR; + VTOY_GPT_HDR Head; + VTOY_GPT_PART_TBL PartTbl[128]; +}VTOY_GPT_INFO; +#pragma pack() + + +#define MBR_PART_STYLE 0 +#define GPT_PART_STYLE 1 + +typedef struct disk_ventoy_data +{ + int ventoy_valid; + + char ventoy_ver[32]; // 1.0.33 ... + int secure_boot_flag; + uint64_t preserved_space; + + uint64_t part2_start_sector; + + int partition_style; // MBR_PART_STYLE/GPT_PART_STYLE + VTOY_GPT_INFO gptinfo; + uint8_t rsvdata[4096]; +}disk_ventoy_data; + + +typedef struct ventoy_disk +{ + char disk_name[32]; // sda + char disk_path[64]; // /dev/sda + + char part1_name[32]; // sda1 + char part1_path[64]; // /dev/sda1 + char part2_name[32]; // sda2 + char part2_path[64]; // /dev/sda2 + + char disk_model[256]; // Sandisk/Kingston ... + char human_readable_size[32]; + + int is4kn; + int major; + int minor; + int type; + int partstyle; + uint64_t size_in_byte; + + disk_ventoy_data vtoydata; +}ventoy_disk; + +#pragma pack(1) +typedef struct ventoy_guid +{ + uint32_t data1; + uint16_t data2; + uint16_t data3; + uint8_t data4[8]; +}ventoy_guid; +#pragma pack() + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +#define VLOG_LOG 1 +#define VLOG_DEBUG 2 + +#define ulong unsigned long +#define _ll long long +#define _ull unsigned long long +#define strlcpy(dst, src) strncpy(dst, src, sizeof(dst) - 1) +#define scnprintf(dst, fmt, args...) snprintf(dst, sizeof(dst) - 1, fmt, ##args) + +#define vlog(fmt, args...) ventoy_syslog(VLOG_LOG, fmt, ##args) +#define vdebug(fmt, args...) ventoy_syslog(VLOG_DEBUG, fmt, ##args) + +void ventoy_syslog(int level, const char *Fmt, ...); +void ventoy_set_loglevel(int level); +uint32_t ventoy_crc32(void *Buffer, uint32_t Length); + + +static inline void * zalloc(size_t n) +{ + void *p = malloc(n); + if (p) memset(p, 0, n); + return p; +} + + +#endif /* __VENTOY_DEFINE_H__ */ + diff --git a/LinuxGUI/Ventoy2Disk/Core/ventoy_disk.c b/LinuxGUI/Ventoy2Disk/Core/ventoy_disk.c new file mode 100644 index 0000000..5d4bbff --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Core/ventoy_disk.c @@ -0,0 +1,779 @@ +/****************************************************************************** + * ventoy_disk.c ---- ventoy disk + * Copyright (c) 2021, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int g_disk_num = 0; +static int g_fatlib_media_fd = 0; +static uint64_t g_fatlib_media_offset = 0; +ventoy_disk *g_disk_list = NULL; + +static const char *g_ventoy_dev_type_str[VTOY_DEVICE_END] = +{ + "unknown", "scsi", "USB", "ide", "dac960", + "cpqarray", "file", "ataraid", "i2o", + "ubd", "dasd", "viodasd", "sx8", "dm", + "xvd", "sd/mmc", "virtblk", "aoe", + "md", "loopback", "nvme", "brd", "pmem" +}; + +static const char * ventoy_get_dev_type_name(ventoy_dev_type type) +{ + return (type < VTOY_DEVICE_END) ? g_ventoy_dev_type_str[type] : "unknown"; +} + +static int ventoy_check_blk_major(int major, const char *type) +{ + int flag = 0; + int valid = 0; + int devnum = 0; + int len = 0; + char line[64]; + char *pos = NULL; + FILE *fp = NULL; + + fp = fopen("/proc/devices", "r"); + if (!fp) + { + return 0; + } + + len = (int)strlen(type); + while (fgets(line, sizeof(line), fp)) + { + if (flag) + { + pos = strchr(line, ' '); + if (pos) + { + devnum = (int)strtol(line, NULL, 10); + if (devnum == major) + { + if (strncmp(pos + 1, type, len) == 0) + { + valid = 1; + } + break; + } + } + } + else if (strncmp(line, "Block devices:", 14) == 0) + { + flag = 1; + } + } + + fclose(fp); + return valid; +} + +static int ventoy_get_disk_devnum(const char *name, int *major, int* minor) +{ + int rc; + char *pos; + char devnum[16] = {0}; + + rc = ventoy_get_sys_file_line(devnum, sizeof(devnum), "/sys/block/%s/dev", name); + if (rc) + { + return 1; + } + + pos = strstr(devnum, ":"); + if (!pos) + { + return 1; + } + + *major = (int)strtol(devnum, NULL, 10); + *minor = (int)strtol(pos + 1, NULL, 10); + + return 0; +} + +static ventoy_dev_type ventoy_get_dev_type(const char *name, int major, int minor) +{ + int rc; + char syspath[128]; + char dstpath[256]; + + memset(syspath, 0, sizeof(syspath)); + memset(dstpath, 0, sizeof(dstpath)); + + scnprintf(syspath, "/sys/block/%s", name); + rc = readlink(syspath, dstpath, sizeof(dstpath) - 1); + if (rc > 0 && strstr(dstpath, "/usb")) + { + return VTOY_DEVICE_USB; + } + + if (SCSI_BLK_MAJOR(major) && (minor % 0x10 == 0)) + { + return VTOY_DEVICE_SCSI; + } + else if (IDE_BLK_MAJOR(major) && (minor % 0x40 == 0)) + { + return VTOY_DEVICE_IDE; + } + else if (major == DAC960_MAJOR && (minor % 0x8 == 0)) + { + return VTOY_DEVICE_DAC960; + } + else if (major == ATARAID_MAJOR && (minor % 0x10 == 0)) + { + return VTOY_DEVICE_ATARAID; + } + else if (major == AOE_MAJOR && (minor % 0x10 == 0)) + { + return VTOY_DEVICE_AOE; + } + else if (major == DASD_MAJOR && (minor % 0x4 == 0)) + { + return VTOY_DEVICE_DASD; + } + else if (major == VIODASD_MAJOR && (minor % 0x8 == 0)) + { + return VTOY_DEVICE_VIODASD; + } + else if (SX8_BLK_MAJOR(major) && (minor % 0x20 == 0)) + { + return VTOY_DEVICE_SX8; + } + else if (I2O_BLK_MAJOR(major) && (minor % 0x10 == 0)) + { + return VTOY_DEVICE_I2O; + } + else if (CPQARRAY_BLK_MAJOR(major) && (minor % 0x10 == 0)) + { + return VTOY_DEVICE_CPQARRAY; + } + else if (UBD_MAJOR == major && (minor % 0x10 == 0)) + { + return VTOY_DEVICE_UBD; + } + else if (XVD_MAJOR == major && (minor % 0x10 == 0)) + { + return VTOY_DEVICE_XVD; + } + else if (SDMMC_MAJOR == major && (minor % 0x8 == 0)) + { + return VTOY_DEVICE_SDMMC; + } + else if (ventoy_check_blk_major(major, "virtblk")) + { + return VTOY_DEVICE_VIRTBLK; + } + else if (major == LOOP_MAJOR) + { + return VTOY_DEVICE_LOOP; + } + else if (major == MD_MAJOR) + { + return VTOY_DEVICE_MD; + } + else if (major == RAM_MAJOR) + { + return VTOY_DEVICE_RAM; + } + else if (strstr(name, "nvme") && ventoy_check_blk_major(major, "blkext")) + { + return VTOY_DEVICE_NVME; + } + else if (strstr(name, "pmem") && ventoy_check_blk_major(major, "blkext")) + { + return VTOY_DEVICE_PMEM; + } + + return VTOY_DEVICE_END; +} + +static int ventoy_is_possible_blkdev(const char *name) +{ + if (name[0] == '.') + { + return 0; + } + + /* /dev/ramX */ + if (name[0] == 'r' && name[1] == 'a' && name[2] == 'm') + { + return 0; + } + + /* /dev/zramX */ + if (name[0] == 'z' && name[1] == 'r' && name[2] == 'a' && name[3] == 'm') + { + return 0; + } + + /* /dev/loopX */ + if (name[0] == 'l' && name[1] == 'o' && name[2] == 'o' && name[3] == 'p') + { + return 0; + } + + /* /dev/dm-X */ + if (name[0] == 'd' && name[1] == 'm' && name[2] == '-' && isdigit(name[3])) + { + return 0; + } + + /* /dev/srX */ + if (name[0] == 's' && name[1] == 'r' && isdigit(name[2])) + { + return 0; + } + + return 1; +} + +int ventoy_is_disk_4k_native(const char *disk) +{ + int fd; + int rc = 0; + int logsector = 0; + int physector = 0; + char diskpath[256] = {0}; + + snprintf(diskpath, sizeof(diskpath) - 1, "/dev/%s", disk); + + fd = open(diskpath, O_RDONLY | O_BINARY); + if (fd >= 0) + { + ioctl(fd, BLKSSZGET, &logsector); + ioctl(fd, BLKPBSZGET, &physector); + + if (logsector == 4096 && physector == 4096) + { + rc = 1; + } + close(fd); + } + + vdebug("is 4k native disk <%s> <%d>\n", disk, rc); + return rc; +} + +uint64_t ventoy_get_disk_size_in_byte(const char *disk) +{ + int fd; + int rc; + unsigned long long size = 0; + char diskpath[256] = {0}; + char sizebuf[64] = {0}; + + // Try 1: get size from sysfs + snprintf(diskpath, sizeof(diskpath) - 1, "/sys/block/%s/size", disk); + if (access(diskpath, F_OK) >= 0) + { + vdebug("get disk size from sysfs for %s\n", disk); + + fd = open(diskpath, O_RDONLY | O_BINARY); + if (fd >= 0) + { + read(fd, sizebuf, sizeof(sizebuf)); + size = strtoull(sizebuf, NULL, 10); + close(fd); + return (uint64_t)(size * 512); + } + } + else + { + vdebug("%s not exist \n", diskpath); + } + + // Try 2: get size from ioctl + snprintf(diskpath, sizeof(diskpath) - 1, "/dev/%s", disk); + fd = open(diskpath, O_RDONLY); + if (fd >= 0) + { + vdebug("get disk size from ioctl for %s\n", disk); + rc = ioctl(fd, BLKGETSIZE64, &size); + if (rc == -1) + { + size = 0; + vdebug("failed to ioctl %d\n", rc); + } + close(fd); + } + else + { + vdebug("failed to open %s %d\n", diskpath, errno); + } + + vdebug("disk %s size %llu bytes\n", disk, size); + return size; +} + +int ventoy_get_disk_vendor(const char *name, char *vendorbuf, int bufsize) +{ + return ventoy_get_sys_file_line(vendorbuf, bufsize, "/sys/block/%s/device/vendor", name); +} + +int ventoy_get_disk_model(const char *name, char *modelbuf, int bufsize) +{ + return ventoy_get_sys_file_line(modelbuf, bufsize, "/sys/block/%s/device/model", name); +} + +static int fatlib_media_sector_read(uint32 sector, uint8 *buffer, uint32 sector_count) +{ + lseek(g_fatlib_media_fd, (sector + g_fatlib_media_offset) * 512ULL, SEEK_SET); + read(g_fatlib_media_fd, buffer, sector_count * 512); + + return 1; +} + +static int fatlib_is_secure_boot_enable(void) +{ + void *flfile = NULL; + + flfile = fl_fopen("/EFI/BOOT/grubx64_real.efi", "rb"); + if (flfile) + { + vlog("/EFI/BOOT/grubx64_real.efi find, secure boot in enabled\n"); + fl_fclose(flfile); + return 1; + } + else + { + vlog("/EFI/BOOT/grubx64_real.efi not exist\n"); + } + + return 0; +} + +static int fatlib_get_ventoy_version(char *verbuf, int bufsize) +{ + int rc = 1; + int size = 0; + char *buf = NULL; + char *pos = NULL; + char *end = NULL; + void *flfile = NULL; + + flfile = fl_fopen("/grub/grub.cfg", "rb"); + if (flfile) + { + fl_fseek(flfile, 0, SEEK_END); + size = (int)fl_ftell(flfile); + + fl_fseek(flfile, 0, SEEK_SET); + + buf = malloc(size + 1); + if (buf) + { + fl_fread(buf, 1, size, flfile); + buf[size] = 0; + + pos = strstr(buf, "VENTOY_VERSION="); + if (pos) + { + pos += strlen("VENTOY_VERSION="); + if (*pos == '"') + { + pos++; + } + + end = pos; + while (*end != 0 && *end != '"' && *end != '\r' && *end != '\n') + { + end++; + } + + *end = 0; + + snprintf(verbuf, bufsize - 1, "%s", pos); + rc = 0; + } + free(buf); + } + + fl_fclose(flfile); + } + else + { + vdebug("No grub.cfg found\n"); + } + + return rc; +} + +int ventoy_get_vtoy_data(ventoy_disk *info, int *ppartstyle) +{ + int i; + int fd; + int len; + int rc = 1; + int ret = 1; + int part_style; + uint64_t part1_start_sector; + uint64_t part1_sector_count; + uint64_t part2_start_sector; + uint64_t part2_sector_count; + uint64_t preserved_space; + char name[64] = {0}; + disk_ventoy_data *vtoy = NULL; + VTOY_GPT_INFO *gpt = NULL; + + vtoy = &(info->vtoydata); + gpt = &(vtoy->gptinfo); + memset(vtoy, 0, sizeof(disk_ventoy_data)); + + vdebug("ventoy_get_vtoy_data %s\n", info->disk_path); + + if (info->size_in_byte < (2 * VTOYEFI_PART_BYTES)) + { + vdebug("disk %s is too small %llu\n", info->disk_path, (_ull)info->size_in_byte); + return 1; + } + + fd = open(info->disk_path, O_RDONLY | O_BINARY); + if (fd < 0) + { + vdebug("failed to open %s %d\n", info->disk_path, errno); + return 1; + } + + len = (int)read(fd, &(vtoy->gptinfo), sizeof(VTOY_GPT_INFO)); + if (len != sizeof(VTOY_GPT_INFO)) + { + vdebug("failed to read %s %d\n", info->disk_path, errno); + goto end; + } + + if (gpt->MBR.Byte55 != 0x55 || gpt->MBR.ByteAA != 0xAA) + { + vdebug("Invalid mbr magic 0x%x 0x%x\n", gpt->MBR.Byte55, gpt->MBR.ByteAA); + goto end; + } + + if (gpt->MBR.PartTbl[0].FsFlag == 0xEE && strncmp(gpt->Head.Signature, "EFI PART", 8) == 0) + { + part_style = GPT_PART_STYLE; + if (ppartstyle) + { + *ppartstyle = part_style; + } + + if (gpt->PartTbl[0].StartLBA == 0 || gpt->PartTbl[1].StartLBA == 0) + { + vdebug("NO ventoy efi part layout <%llu %llu>\n", + (_ull)gpt->PartTbl[0].StartLBA, + (_ull)gpt->PartTbl[1].StartLBA); + goto end; + } + + for (i = 0; i < 36; i++) + { + name[i] = (char)(gpt->PartTbl[1].Name[i]); + } + if (strcmp(name, "VTOYEFI")) + { + vdebug("Invalid efi part2 name <%s>\n", name); + goto end; + } + + part1_start_sector = gpt->PartTbl[0].StartLBA; + part1_sector_count = gpt->PartTbl[0].LastLBA - part1_start_sector + 1; + part2_start_sector = gpt->PartTbl[1].StartLBA; + part2_sector_count = gpt->PartTbl[1].LastLBA - part2_start_sector + 1; + + preserved_space = info->size_in_byte - (part2_start_sector + part2_sector_count + 33) * 512; + } + else + { + part_style = MBR_PART_STYLE; + if (ppartstyle) + { + *ppartstyle = part_style; + } + + part1_start_sector = gpt->MBR.PartTbl[0].StartSectorId; + part1_sector_count = gpt->MBR.PartTbl[0].SectorCount; + part2_start_sector = gpt->MBR.PartTbl[1].StartSectorId; + part2_sector_count = gpt->MBR.PartTbl[1].SectorCount; + + preserved_space = info->size_in_byte - (part2_start_sector + part2_sector_count) * 512; + } + + if (part1_start_sector != VTOYIMG_PART_START_SECTOR || + part2_sector_count != VTOYEFI_PART_SECTORS || + (part1_start_sector + part1_sector_count) != part2_start_sector) + { + vdebug("Not valid ventoy partition layout [%llu %llu] [%llu %llu]\n", + part1_start_sector, part1_sector_count, part2_start_sector, part2_sector_count); + goto end; + } + + vdebug("ventoy partition layout check OK: [%llu %llu] [%llu %llu]\n", + part1_start_sector, part1_sector_count, part2_start_sector, part2_sector_count); + + vtoy->ventoy_valid = 1; + + vdebug("now check secure boot for %s ...\n", info->disk_path); + + g_fatlib_media_fd = fd; + g_fatlib_media_offset = part2_start_sector; + fl_init(); + + if (0 == fl_attach_media(fatlib_media_sector_read, NULL)) + { + ret = fatlib_get_ventoy_version(vtoy->ventoy_ver, sizeof(vtoy->ventoy_ver)); + if (ret == 0 && vtoy->ventoy_ver[0]) + { + vtoy->secure_boot_flag = fatlib_is_secure_boot_enable(); + } + else + { + vdebug("fatlib_get_ventoy_version failed %d\n", ret); + } + } + else + { + vdebug("fl_attach_media failed\n"); + } + + fl_shutdown(); + g_fatlib_media_fd = -1; + g_fatlib_media_offset = 0; + + if (vtoy->ventoy_ver[0] == 0) + { + vtoy->ventoy_ver[0] = '?'; + } + + if (0 == vtoy->ventoy_valid) + { + goto end; + } + + lseek(fd, 2040 * 512, SEEK_SET); + read(fd, vtoy->rsvdata, sizeof(vtoy->rsvdata)); + + vtoy->preserved_space = preserved_space; + vtoy->partition_style = part_style; + vtoy->part2_start_sector = part2_start_sector; + + rc = 0; +end: + vtoy_safe_close_fd(fd); + return rc; +} + +int ventoy_get_disk_info(const char *name, ventoy_disk *info) +{ + char vendor[64] = {0}; + char model[128] = {0}; + + vdebug("get disk info %s\n", name); + + strlcpy(info->disk_name, name); + scnprintf(info->disk_path, "/dev/%s", name); + + if (strstr(name, "nvme") || strstr(name, "mmc") || strstr(name, "nbd")) + { + scnprintf(info->part1_name, "%sp1", name); + scnprintf(info->part1_path, "/dev/%sp1", name); + scnprintf(info->part2_name, "%sp2", name); + scnprintf(info->part2_path, "/dev/%sp2", name); + } + else + { + scnprintf(info->part1_name, "%s1", name); + scnprintf(info->part1_path, "/dev/%s1", name); + scnprintf(info->part2_name, "%s2", name); + scnprintf(info->part2_path, "/dev/%s2", name); + } + + info->is4kn = ventoy_is_disk_4k_native(name); + info->size_in_byte = ventoy_get_disk_size_in_byte(name); + + ventoy_get_disk_devnum(name, &info->major, &info->minor); + info->type = ventoy_get_dev_type(name, info->major, info->minor); + ventoy_get_disk_vendor(name, vendor, sizeof(vendor)); + ventoy_get_disk_model(name, model, sizeof(model)); + + scnprintf(info->human_readable_size, "%llu GB", (_ull)ventoy_get_human_readable_gb(info->size_in_byte)); + scnprintf(info->disk_model, "%s %s (%s)", vendor, model, ventoy_get_dev_type_name(info->type)); + + ventoy_get_vtoy_data(info, &(info->partstyle)); + + vdebug("disk:<%s %d:%d> model:<%s> size:%llu (%s)\n", + info->disk_path, info->major, info->minor, info->disk_model, info->size_in_byte, info->human_readable_size); + + if (info->vtoydata.ventoy_valid) + { + vdebug("%s Ventoy:<%s> %s secureboot:%d preserve:%llu\n", info->disk_path, info->vtoydata.ventoy_ver, + info->vtoydata.partition_style == MBR_PART_STYLE ? "MBR" : "GPT", + info->vtoydata.secure_boot_flag, (_ull)(info->vtoydata.preserved_space)); + } + else + { + vdebug("%s NO Ventoy detected\n", info->disk_path); + } + + return 0; +} + +static int ventoy_disk_compare(const ventoy_disk *disk1, const ventoy_disk *disk2) +{ + if (disk1->type == VTOY_DEVICE_USB && disk2->type == VTOY_DEVICE_USB) + { + return strcmp(disk1->disk_name, disk2->disk_name); + } + else if (disk1->type == VTOY_DEVICE_USB) + { + return -1; + } + else if (disk2->type == VTOY_DEVICE_USB) + { + return 1; + } + else + { + return strcmp(disk1->disk_name, disk2->disk_name); + } +} + +static int ventoy_disk_sort(void) +{ + int i, j; + ventoy_disk *tmp; + + tmp = malloc(sizeof(ventoy_disk)); + if (!tmp) + { + return 1; + } + + for (i = 0; i < g_disk_num; i++) + for (j = i + 1; j < g_disk_num; j++) + { + if (ventoy_disk_compare(g_disk_list + i, g_disk_list + j) > 0) + { + memcpy(tmp, g_disk_list + i, sizeof(ventoy_disk)); + memcpy(g_disk_list + i, g_disk_list + j, sizeof(ventoy_disk)); + memcpy(g_disk_list + j, tmp, sizeof(ventoy_disk)); + } + } + + free(tmp); + return 0; +} + +int ventoy_disk_enumerate_all(void) +{ + int rc = 0; + DIR* dir = NULL; + struct dirent* p = NULL; + + vdebug("ventoy_disk_enumerate_all\n"); + + dir = opendir("/sys/block"); + if (!dir) + { + vlog("Failed to open /sys/block %d\n", errno); + return 1; + } + + while (((p = readdir(dir)) != NULL) && (g_disk_num < MAX_DISK_NUM)) + { + if (ventoy_is_possible_blkdev(p->d_name)) + { + memset(g_disk_list + g_disk_num, 0, sizeof(ventoy_disk)); + if (0 == ventoy_get_disk_info(p->d_name, g_disk_list + g_disk_num)) + { + g_disk_num++; + } + } + } + closedir(dir); + + ventoy_disk_sort(); + + return rc; +} + +void ventoy_disk_dump(ventoy_disk *cur) +{ + if (cur->vtoydata.ventoy_valid) + { + vdebug("%s [%s] %s\tVentoy: %s %s secureboot:%d preserve:%llu\n", + cur->disk_path, cur->human_readable_size, cur->disk_model, + cur->vtoydata.ventoy_ver, cur->vtoydata.partition_style == MBR_PART_STYLE ? "MBR" : "GPT", + cur->vtoydata.secure_boot_flag, (_ull)(cur->vtoydata.preserved_space)); + } + else + { + vdebug("%s [%s] %s\tVentoy: NA\n", cur->disk_path, cur->human_readable_size, cur->disk_model); + } +} + +void ventoy_disk_dump_all(void) +{ + int i; + + vdebug("============= DISK DUMP ============\n"); + for (i = 0; i < g_disk_num; i++) + { + ventoy_disk_dump(g_disk_list + i); + } +} + +int ventoy_disk_install(ventoy_disk *disk, void *efipartimg) +{ + return 0; +} + + +int ventoy_disk_init(void) +{ + g_disk_list = malloc(sizeof(ventoy_disk) * MAX_DISK_NUM); + + ventoy_disk_enumerate_all(); + ventoy_disk_dump_all(); + + return 0; +} + +void ventoy_disk_exit(void) +{ + check_free(g_disk_list); + g_disk_list = NULL; + g_disk_num = 0; +} + + diff --git a/LinuxGUI/Ventoy2Disk/Core/ventoy_disk.h b/LinuxGUI/Ventoy2Disk/Core/ventoy_disk.h new file mode 100644 index 0000000..50618dc --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Core/ventoy_disk.h @@ -0,0 +1,145 @@ +/****************************************************************************** + * ventoy_disk.h + * + * Copyright (c) 2021, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ +#ifndef __VENTOY_DISK_H__ +#define __VENTOY_DISK_H__ + +typedef enum +{ + VTOY_DEVICE_UNKNOWN = 0, + VTOY_DEVICE_SCSI, + VTOY_DEVICE_USB, + VTOY_DEVICE_IDE, + VTOY_DEVICE_DAC960, + VTOY_DEVICE_CPQARRAY, + VTOY_DEVICE_FILE, + VTOY_DEVICE_ATARAID, + VTOY_DEVICE_I2O, + VTOY_DEVICE_UBD, + VTOY_DEVICE_DASD, + VTOY_DEVICE_VIODASD, + VTOY_DEVICE_SX8, + VTOY_DEVICE_DM, + VTOY_DEVICE_XVD, + VTOY_DEVICE_SDMMC, + VTOY_DEVICE_VIRTBLK, + VTOY_DEVICE_AOE, + VTOY_DEVICE_MD, + VTOY_DEVICE_LOOP, + VTOY_DEVICE_NVME, + VTOY_DEVICE_RAM, + VTOY_DEVICE_PMEM, + + VTOY_DEVICE_END +}ventoy_dev_type; + +/* from */ +#define IDE0_MAJOR 3 +#define IDE1_MAJOR 22 +#define IDE2_MAJOR 33 +#define IDE3_MAJOR 34 +#define IDE4_MAJOR 56 +#define IDE5_MAJOR 57 +#define SCSI_CDROM_MAJOR 11 +#define SCSI_DISK0_MAJOR 8 +#define SCSI_DISK1_MAJOR 65 +#define SCSI_DISK2_MAJOR 66 +#define SCSI_DISK3_MAJOR 67 +#define SCSI_DISK4_MAJOR 68 +#define SCSI_DISK5_MAJOR 69 +#define SCSI_DISK6_MAJOR 70 +#define SCSI_DISK7_MAJOR 71 +#define SCSI_DISK8_MAJOR 128 +#define SCSI_DISK9_MAJOR 129 +#define SCSI_DISK10_MAJOR 130 +#define SCSI_DISK11_MAJOR 131 +#define SCSI_DISK12_MAJOR 132 +#define SCSI_DISK13_MAJOR 133 +#define SCSI_DISK14_MAJOR 134 +#define SCSI_DISK15_MAJOR 135 +#define COMPAQ_SMART2_MAJOR 72 +#define COMPAQ_SMART2_MAJOR1 73 +#define COMPAQ_SMART2_MAJOR2 74 +#define COMPAQ_SMART2_MAJOR3 75 +#define COMPAQ_SMART2_MAJOR4 76 +#define COMPAQ_SMART2_MAJOR5 77 +#define COMPAQ_SMART2_MAJOR6 78 +#define COMPAQ_SMART2_MAJOR7 79 +#define COMPAQ_SMART_MAJOR 104 +#define COMPAQ_SMART_MAJOR1 105 +#define COMPAQ_SMART_MAJOR2 106 +#define COMPAQ_SMART_MAJOR3 107 +#define COMPAQ_SMART_MAJOR4 108 +#define COMPAQ_SMART_MAJOR5 109 +#define COMPAQ_SMART_MAJOR6 110 +#define COMPAQ_SMART_MAJOR7 111 +#define DAC960_MAJOR 48 +#define ATARAID_MAJOR 114 +#define I2O_MAJOR1 80 +#define I2O_MAJOR2 81 +#define I2O_MAJOR3 82 +#define I2O_MAJOR4 83 +#define I2O_MAJOR5 84 +#define I2O_MAJOR6 85 +#define I2O_MAJOR7 86 +#define I2O_MAJOR8 87 +#define UBD_MAJOR 98 +#define DASD_MAJOR 94 +#define VIODASD_MAJOR 112 +#define AOE_MAJOR 152 +#define SX8_MAJOR1 160 +#define SX8_MAJOR2 161 +#define XVD_MAJOR 202 +#define SDMMC_MAJOR 179 +#define LOOP_MAJOR 7 +#define MD_MAJOR 9 +#define BLKEXT_MAJOR 259 +#define RAM_MAJOR 1 + +#define SCSI_BLK_MAJOR(M) ( \ + (M) == SCSI_DISK0_MAJOR \ + || (M) == SCSI_CDROM_MAJOR \ + || ((M) >= SCSI_DISK1_MAJOR && (M) <= SCSI_DISK7_MAJOR) \ + || ((M) >= SCSI_DISK8_MAJOR && (M) <= SCSI_DISK15_MAJOR)) + +#define IDE_BLK_MAJOR(M) \ + ((M) == IDE0_MAJOR || \ + (M) == IDE1_MAJOR || \ + (M) == IDE2_MAJOR || \ + (M) == IDE3_MAJOR || \ + (M) == IDE4_MAJOR || \ + (M) == IDE5_MAJOR) + +#define SX8_BLK_MAJOR(M) ((M) >= SX8_MAJOR1 && (M) <= SX8_MAJOR2) +#define I2O_BLK_MAJOR(M) ((M) >= I2O_MAJOR1 && (M) <= I2O_MAJOR8) +#define CPQARRAY_BLK_MAJOR(M) \ + (((M) >= COMPAQ_SMART2_MAJOR && (M) <= COMPAQ_SMART2_MAJOR7) || \ + (COMPAQ_SMART_MAJOR <= (M) && (M) <= COMPAQ_SMART_MAJOR7)) + +#define VENTOY_FILE_STG1_IMG "boot/core.img.xz" +#define VENTOY_FILE_DISK_IMG "ventoy/ventoy.disk.img.xz" + +extern int g_disk_num; +extern ventoy_disk *g_disk_list; +int ventoy_disk_enumerate_all(void); +int ventoy_disk_init(void); +void ventoy_disk_exit(void); + +#endif /* __VENTOY_DISK_H__ */ + diff --git a/LinuxGUI/Ventoy2Disk/Core/ventoy_json.c b/LinuxGUI/Ventoy2Disk/Core/ventoy_json.c new file mode 100644 index 0000000..8253a1c --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Core/ventoy_json.c @@ -0,0 +1,718 @@ +/****************************************************************************** + * ventoy_json.c + * + * Copyright (c) 2021, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void vtoy_json_free(VTOY_JSON *pstJsonHead) +{ + VTOY_JSON *pstNext = NULL; + + while (NULL != pstJsonHead) + { + pstNext = pstJsonHead->pstNext; + if ((pstJsonHead->enDataType < JSON_TYPE_BUTT) && (NULL != pstJsonHead->pstChild)) + { + vtoy_json_free(pstJsonHead->pstChild); + } + + free(pstJsonHead); + pstJsonHead = pstNext; + } + + return; +} + +static char *vtoy_json_skip(const char *pcData) +{ + while ((NULL != pcData) && ('\0' != *pcData) && (*pcData <= 32)) + { + pcData++; + } + + return (char *)pcData; +} + +VTOY_JSON *vtoy_json_find_item +( + VTOY_JSON *pstJson, + JSON_TYPE enDataType, + const char *szKey +) +{ + while (NULL != pstJson) + { + if ((enDataType == pstJson->enDataType) && + (0 == strcmp(szKey, pstJson->pcName))) + { + return pstJson; + } + pstJson = pstJson->pstNext; + } + + return NULL; +} + +static int vtoy_json_parse_number +( + VTOY_JSON *pstJson, + const char *pcData, + const char **ppcEnd +) +{ + unsigned long Value; + + Value = strtoul(pcData, (char **)ppcEnd, 10); + if (*ppcEnd == pcData) + { + vdebug("Failed to parse json number %s.\n", pcData); + return JSON_FAILED; + } + + pstJson->enDataType = JSON_TYPE_NUMBER; + pstJson->unData.lValue = Value; + + return JSON_SUCCESS; +} + +static int vtoy_json_parse_string +( + char *pcNewStart, + char *pcRawStart, + VTOY_JSON *pstJson, + const char *pcData, + const char **ppcEnd +) +{ + uint32_t uiLen = 0; + const char *pcPos = NULL; + const char *pcTmp = pcData + 1; + + *ppcEnd = pcData; + + if ('\"' != *pcData) + { + return JSON_FAILED; + } + + pcPos = strchr(pcTmp, '\"'); + if ((NULL == pcPos) || (pcPos < pcTmp)) + { + vdebug("Invalid string %s.\n", pcData); + return JSON_FAILED; + } + + *ppcEnd = pcPos + 1; + uiLen = (uint32_t)(unsigned long)(pcPos - pcTmp); + + pstJson->enDataType = JSON_TYPE_STRING; + pstJson->unData.pcStrVal = pcNewStart + (pcTmp - pcRawStart); + pstJson->unData.pcStrVal[uiLen] = '\0'; + + return JSON_SUCCESS; +} + +static int vtoy_json_parse_array +( + char *pcNewStart, + char *pcRawStart, + VTOY_JSON *pstJson, + const char *pcData, + const char **ppcEnd +) +{ + int Ret = JSON_SUCCESS; + VTOY_JSON *pstJsonChild = NULL; + VTOY_JSON *pstJsonItem = NULL; + const char *pcTmp = pcData + 1; + + *ppcEnd = pcData; + pstJson->enDataType = JSON_TYPE_ARRAY; + + if ('[' != *pcData) + { + return JSON_FAILED; + } + + pcTmp = vtoy_json_skip(pcTmp); + + if (']' == *pcTmp) + { + *ppcEnd = pcTmp + 1; + return JSON_SUCCESS; + } + + JSON_NEW_ITEM(pstJson->pstChild, JSON_FAILED); + + Ret = vtoy_json_parse_value(pcNewStart, pcRawStart, pstJson->pstChild, pcTmp, ppcEnd); + if (JSON_SUCCESS != Ret) + { + vdebug("Failed to parse array child.\n"); + return JSON_FAILED; + } + + pstJsonChild = pstJson->pstChild; + pcTmp = vtoy_json_skip(*ppcEnd); + while ((NULL != pcTmp) && (',' == *pcTmp)) + { + JSON_NEW_ITEM(pstJsonItem, JSON_FAILED); + pstJsonChild->pstNext = pstJsonItem; + pstJsonItem->pstPrev = pstJsonChild; + pstJsonChild = pstJsonItem; + + Ret = vtoy_json_parse_value(pcNewStart, pcRawStart, pstJsonChild, vtoy_json_skip(pcTmp + 1), ppcEnd); + if (JSON_SUCCESS != Ret) + { + vdebug("Failed to parse array child.\n"); + return JSON_FAILED; + } + pcTmp = vtoy_json_skip(*ppcEnd); + } + + if ((NULL != pcTmp) && (']' == *pcTmp)) + { + *ppcEnd = pcTmp + 1; + return JSON_SUCCESS; + } + else + { + *ppcEnd = pcTmp; + return JSON_FAILED; + } +} + +static int vtoy_json_parse_object +( + char *pcNewStart, + char *pcRawStart, + VTOY_JSON *pstJson, + const char *pcData, + const char **ppcEnd +) +{ + int Ret = JSON_SUCCESS; + VTOY_JSON *pstJsonChild = NULL; + VTOY_JSON *pstJsonItem = NULL; + const char *pcTmp = pcData + 1; + + *ppcEnd = pcData; + pstJson->enDataType = JSON_TYPE_OBJECT; + + if ('{' != *pcData) + { + return JSON_FAILED; + } + + pcTmp = vtoy_json_skip(pcTmp); + if ('}' == *pcTmp) + { + *ppcEnd = pcTmp + 1; + return JSON_SUCCESS; + } + + JSON_NEW_ITEM(pstJson->pstChild, JSON_FAILED); + + Ret = vtoy_json_parse_string(pcNewStart, pcRawStart, pstJson->pstChild, pcTmp, ppcEnd); + if (JSON_SUCCESS != Ret) + { + vdebug("Failed to parse array child.\n"); + return JSON_FAILED; + } + + pstJsonChild = pstJson->pstChild; + pstJsonChild->pcName = pstJsonChild->unData.pcStrVal; + pstJsonChild->unData.pcStrVal = NULL; + + pcTmp = vtoy_json_skip(*ppcEnd); + if ((NULL == pcTmp) || (':' != *pcTmp)) + { + *ppcEnd = pcTmp; + return JSON_FAILED; + } + + Ret = vtoy_json_parse_value(pcNewStart, pcRawStart, pstJsonChild, vtoy_json_skip(pcTmp + 1), ppcEnd); + if (JSON_SUCCESS != Ret) + { + vdebug("Failed to parse array child.\n"); + return JSON_FAILED; + } + + pcTmp = vtoy_json_skip(*ppcEnd); + while ((NULL != pcTmp) && (',' == *pcTmp)) + { + JSON_NEW_ITEM(pstJsonItem, JSON_FAILED); + pstJsonChild->pstNext = pstJsonItem; + pstJsonItem->pstPrev = pstJsonChild; + pstJsonChild = pstJsonItem; + + Ret = vtoy_json_parse_string(pcNewStart, pcRawStart, pstJsonChild, vtoy_json_skip(pcTmp + 1), ppcEnd); + if (JSON_SUCCESS != Ret) + { + vdebug("Failed to parse array child.\n"); + return JSON_FAILED; + } + + pcTmp = vtoy_json_skip(*ppcEnd); + pstJsonChild->pcName = pstJsonChild->unData.pcStrVal; + pstJsonChild->unData.pcStrVal = NULL; + if ((NULL == pcTmp) || (':' != *pcTmp)) + { + *ppcEnd = pcTmp; + return JSON_FAILED; + } + + Ret = vtoy_json_parse_value(pcNewStart, pcRawStart, pstJsonChild, vtoy_json_skip(pcTmp + 1), ppcEnd); + if (JSON_SUCCESS != Ret) + { + vdebug("Failed to parse array child.\n"); + return JSON_FAILED; + } + + pcTmp = vtoy_json_skip(*ppcEnd); + } + + if ((NULL != pcTmp) && ('}' == *pcTmp)) + { + *ppcEnd = pcTmp + 1; + return JSON_SUCCESS; + } + else + { + *ppcEnd = pcTmp; + return JSON_FAILED; + } +} + +int vtoy_json_parse_value +( + char *pcNewStart, + char *pcRawStart, + VTOY_JSON *pstJson, + const char *pcData, + const char **ppcEnd +) +{ + pcData = vtoy_json_skip(pcData); + + switch (*pcData) + { + case 'n': + { + if (0 == strncmp(pcData, "null", 4)) + { + pstJson->enDataType = JSON_TYPE_NULL; + *ppcEnd = pcData + 4; + return JSON_SUCCESS; + } + break; + } + case 'f': + { + if (0 == strncmp(pcData, "false", 5)) + { + pstJson->enDataType = JSON_TYPE_BOOL; + pstJson->unData.lValue = 0; + *ppcEnd = pcData + 5; + return JSON_SUCCESS; + } + break; + } + case 't': + { + if (0 == strncmp(pcData, "true", 4)) + { + pstJson->enDataType = JSON_TYPE_BOOL; + pstJson->unData.lValue = 1; + *ppcEnd = pcData + 4; + return JSON_SUCCESS; + } + break; + } + case '\"': + { + return vtoy_json_parse_string(pcNewStart, pcRawStart, pstJson, pcData, ppcEnd); + } + case '[': + { + return vtoy_json_parse_array(pcNewStart, pcRawStart, pstJson, pcData, ppcEnd); + } + case '{': + { + return vtoy_json_parse_object(pcNewStart, pcRawStart, pstJson, pcData, ppcEnd); + } + case '-': + { + return vtoy_json_parse_number(pstJson, pcData, ppcEnd); + } + default : + { + if (*pcData >= '0' && *pcData <= '9') + { + return vtoy_json_parse_number(pstJson, pcData, ppcEnd); + } + } + } + + *ppcEnd = pcData; + vdebug("Invalid json data %u.\n", (uint8_t)(*pcData)); + return JSON_FAILED; +} + +VTOY_JSON * vtoy_json_create(void) +{ + VTOY_JSON *pstJson = NULL; + + pstJson = (VTOY_JSON *)zalloc(sizeof(VTOY_JSON)); + if (NULL == pstJson) + { + return NULL; + } + + return pstJson; +} + +int vtoy_json_parse(VTOY_JSON *pstJson, const char *szJsonData) +{ + uint32_t uiMemSize = 0; + int Ret = JSON_SUCCESS; + char *pcNewBuf = NULL; + const char *pcEnd = NULL; + + uiMemSize = strlen(szJsonData) + 1; + pcNewBuf = (char *)malloc(uiMemSize); + if (NULL == pcNewBuf) + { + vdebug("Failed to alloc new buf.\n"); + return JSON_FAILED; + } + memcpy(pcNewBuf, szJsonData, uiMemSize); + pcNewBuf[uiMemSize - 1] = 0; + + Ret = vtoy_json_parse_value(pcNewBuf, (char *)szJsonData, pstJson, szJsonData, &pcEnd); + if (JSON_SUCCESS != Ret) + { + vdebug("Failed to parse json data %s start=%p, end=%p:%s.\n", + szJsonData, szJsonData, pcEnd, pcEnd); + return JSON_FAILED; + } + + return JSON_SUCCESS; +} + +int vtoy_json_scan_parse +( + const VTOY_JSON *pstJson, + uint32_t uiParseNum, + VTOY_JSON_PARSE_S *pstJsonParse +) +{ + uint32_t i = 0; + const VTOY_JSON *pstJsonCur = NULL; + VTOY_JSON_PARSE_S *pstCurParse = NULL; + + for (pstJsonCur = pstJson; NULL != pstJsonCur; pstJsonCur = pstJsonCur->pstNext) + { + if ((JSON_TYPE_OBJECT == pstJsonCur->enDataType) || + (JSON_TYPE_ARRAY == pstJsonCur->enDataType)) + { + continue; + } + + for (i = 0, pstCurParse = NULL; i < uiParseNum; i++) + { + if (0 == strcmp(pstJsonParse[i].pcKey, pstJsonCur->pcName)) + { + pstCurParse = pstJsonParse + i; + break; + } + } + + if (NULL == pstCurParse) + { + continue; + } + + switch (pstJsonCur->enDataType) + { + case JSON_TYPE_NUMBER: + { + if (sizeof(uint32_t) == pstCurParse->uiBufSize) + { + *(uint32_t *)(pstCurParse->pDataBuf) = (uint32_t)pstJsonCur->unData.lValue; + } + else if (sizeof(uint16_t) == pstCurParse->uiBufSize) + { + *(uint16_t *)(pstCurParse->pDataBuf) = (uint16_t)pstJsonCur->unData.lValue; + } + else if (sizeof(uint8_t) == pstCurParse->uiBufSize) + { + *(uint8_t *)(pstCurParse->pDataBuf) = (uint8_t)pstJsonCur->unData.lValue; + } + else if ((pstCurParse->uiBufSize > sizeof(uint64_t))) + { + snprintf((char *)pstCurParse->pDataBuf, pstCurParse->uiBufSize, "%llu", + (unsigned long long)(pstJsonCur->unData.lValue)); + } + else + { + vdebug("Invalid number data buf size %u.\n", pstCurParse->uiBufSize); + } + break; + } + case JSON_TYPE_STRING: + { + strncpy((char *)pstCurParse->pDataBuf, pstJsonCur->unData.pcStrVal, pstCurParse->uiBufSize); + break; + } + case JSON_TYPE_BOOL: + { + *(uint8_t *)(pstCurParse->pDataBuf) = (pstJsonCur->unData.lValue) > 0 ? 1 : 0; + break; + } + default : + { + break; + } + } + } + + return JSON_SUCCESS; +} + +int vtoy_json_scan_array +( + VTOY_JSON *pstJson, + const char *szKey, + VTOY_JSON **ppstArrayItem +) +{ + VTOY_JSON *pstJsonItem = NULL; + + pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_ARRAY, szKey); + if (NULL == pstJsonItem) + { + vdebug("Key %s is not found in json data.\n", szKey); + return JSON_NOT_FOUND; + } + + *ppstArrayItem = pstJsonItem; + + return JSON_SUCCESS; +} + +int vtoy_json_scan_array_ex +( + VTOY_JSON *pstJson, + const char *szKey, + VTOY_JSON **ppstArrayItem +) +{ + VTOY_JSON *pstJsonItem = NULL; + + pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_ARRAY, szKey); + if (NULL == pstJsonItem) + { + vdebug("Key %s is not found in json data.\n", szKey); + return JSON_NOT_FOUND; + } + + *ppstArrayItem = pstJsonItem->pstChild; + + return JSON_SUCCESS; +} + +int vtoy_json_scan_object +( + VTOY_JSON *pstJson, + const char *szKey, + VTOY_JSON **ppstObjectItem +) +{ + VTOY_JSON *pstJsonItem = NULL; + + pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_OBJECT, szKey); + if (NULL == pstJsonItem) + { + vdebug("Key %s is not found in json data.\n", szKey); + return JSON_NOT_FOUND; + } + + *ppstObjectItem = pstJsonItem; + + return JSON_SUCCESS; +} + +int vtoy_json_get_int +( + VTOY_JSON *pstJson, + const char *szKey, + int *piValue +) +{ + VTOY_JSON *pstJsonItem = NULL; + + pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_NUMBER, szKey); + if (NULL == pstJsonItem) + { + vdebug("Key %s is not found in json data.\n", szKey); + return JSON_NOT_FOUND; + } + + *piValue = (int)pstJsonItem->unData.lValue; + + return JSON_SUCCESS; +} + +int vtoy_json_get_uint +( + VTOY_JSON *pstJson, + const char *szKey, + uint32_t *puiValue +) +{ + VTOY_JSON *pstJsonItem = NULL; + + pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_NUMBER, szKey); + if (NULL == pstJsonItem) + { + vdebug("Key %s is not found in json data.\n", szKey); + return JSON_NOT_FOUND; + } + + *puiValue = (uint32_t)pstJsonItem->unData.lValue; + + return JSON_SUCCESS; +} + +int vtoy_json_get_uint64 +( + VTOY_JSON *pstJson, + const char *szKey, + uint64_t *pui64Value +) +{ + VTOY_JSON *pstJsonItem = NULL; + + pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_NUMBER, szKey); + if (NULL == pstJsonItem) + { + vdebug("Key %s is not found in json data.\n", szKey); + return JSON_NOT_FOUND; + } + + *pui64Value = (uint64_t)pstJsonItem->unData.lValue; + + return JSON_SUCCESS; +} + +int vtoy_json_get_bool +( + VTOY_JSON *pstJson, + const char *szKey, + uint8_t *pbValue +) +{ + VTOY_JSON *pstJsonItem = NULL; + + pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_BOOL, szKey); + if (NULL == pstJsonItem) + { + vdebug("Key %s is not found in json data.\n", szKey); + return JSON_NOT_FOUND; + } + + *pbValue = pstJsonItem->unData.lValue > 0 ? 1 : 0; + + return JSON_SUCCESS; +} + +int vtoy_json_get_string +( + VTOY_JSON *pstJson, + const char *szKey, + uint32_t uiBufLen, + char *pcBuf +) +{ + VTOY_JSON *pstJsonItem = NULL; + + pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_STRING, szKey); + if (NULL == pstJsonItem) + { + vdebug("Key %s is not found in json data.\n", szKey); + return JSON_NOT_FOUND; + } + + strncpy(pcBuf, pstJsonItem->unData.pcStrVal, uiBufLen); + + return JSON_SUCCESS; +} + +const char * vtoy_json_get_string_ex(VTOY_JSON *pstJson, const char *szKey) +{ + VTOY_JSON *pstJsonItem = NULL; + + if ((NULL == pstJson) || (NULL == szKey)) + { + return NULL; + } + + pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_STRING, szKey); + if (NULL == pstJsonItem) + { + vdebug("Key %s is not found in json data.\n", szKey); + return NULL; + } + + return pstJsonItem->unData.pcStrVal; +} + +int vtoy_json_destroy(VTOY_JSON *pstJson) +{ + if (NULL == pstJson) + { + return JSON_SUCCESS; + } + + if (NULL != pstJson->pstChild) + { + vtoy_json_free(pstJson->pstChild); + } + + if (NULL != pstJson->pstNext) + { + vtoy_json_free(pstJson->pstNext); + } + + free(pstJson); + + return JSON_SUCCESS; +} + diff --git a/LinuxGUI/Ventoy2Disk/Core/ventoy_json.h b/LinuxGUI/Ventoy2Disk/Core/ventoy_json.h new file mode 100644 index 0000000..32fef4b --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Core/ventoy_json.h @@ -0,0 +1,268 @@ +/****************************************************************************** + * ventoy_json.h + * + * Copyright (c) 2021, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ +#ifndef __VENTOY_JSON_H__ +#define __VENTOY_JSON_H__ + +#define JSON_NEW_ITEM(pstJson, ret) \ +{ \ + (pstJson) = (VTOY_JSON *)zalloc(sizeof(VTOY_JSON)); \ + if (NULL == (pstJson)) \ + { \ + vdebug("Failed to alloc memory for json."); \ + return (ret); \ + } \ +} + +#define ssprintf(curpos, buf, len, fmt, args...) \ + curpos += snprintf(buf + curpos, len - curpos, fmt, ##args) + +#define VTOY_JSON_IS_SKIPABLE(c) (((c) <= 32) ? 1 : 0) + +#define VTOY_JSON_PRINT_PREFIX(uiDepth, args...) \ +{ \ + uint32_t _uiLoop = 0; \ + for (_uiLoop = 0; _uiLoop < (uiDepth); _uiLoop++) \ + { \ + ssprintf(uiCurPos, pcBuf, uiBufLen, " "); \ + } \ + ssprintf(uiCurPos, pcBuf, uiBufLen, ##args); \ +} + +#define VTOY_JSON_SUCCESS_RET "{ \"result\" : \"success\" }" +#define VTOY_JSON_FAILED_RET "{ \"result\" : \"failed\" }" +#define VTOY_JSON_INVALID_RET "{ \"result\" : \"invalidfmt\" }" +#define VTOY_JSON_TOKEN_ERR_RET "{ \"result\" : \"tokenerror\" }" +#define VTOY_JSON_EXIST_RET "{ \"result\" : \"exist\" }" +#define VTOY_JSON_TIMEOUT_RET "{ \"result\" : \"timeout\" }" +#define VTOY_JSON_BUSY_RET "{ \"result\" : \"busy\" }" +#define VTOY_JSON_INUSE_RET "{ \"result\" : \"inuse\" }" +#define VTOY_JSON_NOTFOUND_RET "{ \"result\" : \"notfound\" }" +#define VTOY_JSON_NOTRUNNING_RET "{ \"result\" : \"notrunning\" }" +#define VTOY_JSON_NOT_READY_RET "{ \"result\" : \"notready\" }" +#define VTOY_JSON_NOT_SUPPORT_RET "{ \"result\" : \"notsupport\" }" +#define VTOY_JSON_MBR_2TB_RET "{ \"result\" : \"mbr2tb\" }" +#define VTOY_JSON_4KN_RET "{ \"result\" : \"4kn\" }" +#define VTOY_JSON_INVALID_RSV_RET "{ \"result\" : \"reserve_invalid\" }" +#define VTOY_JSON_FILE_NOT_FOUND_RET "{ \"result\" : \"file_not_found\" }" + +typedef enum tagJSON_TYPE +{ + JSON_TYPE_NUMBER = 0, + JSON_TYPE_STRING, + JSON_TYPE_BOOL, + JSON_TYPE_ARRAY, + JSON_TYPE_OBJECT, + JSON_TYPE_NULL, + JSON_TYPE_BUTT +}JSON_TYPE; + +typedef struct tagVTOY_JSON +{ + struct tagVTOY_JSON *pstPrev; + struct tagVTOY_JSON *pstNext; + struct tagVTOY_JSON *pstChild; + + JSON_TYPE enDataType; + union + { + char *pcStrVal; + int iNumVal; + uint64_t lValue; + }unData; + + char *pcName; +}VTOY_JSON; + +#define VTOY_JSON_FMT_BEGIN(uiCurPos, pcBuf, uiBufLen) \ +{\ + uint32_t __uiCurPos = (uiCurPos);\ + uint32_t __uiBufLen = (uiBufLen);\ + char *__pcBuf = (pcBuf); + +#define VTOY_JSON_FMT_END(uiCurPos) \ + (uiCurPos) = __uiCurPos;\ +} + +#define VTOY_JSON_FMT_OBJ_BEGIN() ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "{") + +#define VTOY_JSON_FMT_OBJ_END() \ +{\ + if (',' == *(__pcBuf + (__uiCurPos - 1)))\ + {\ + __uiCurPos -= 1;\ + }\ + ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "}");\ +} + +#define VTOY_JSON_FMT_OBJ_ENDEX() \ +{\ + if (',' == *(__pcBuf + (__uiCurPos - 1)))\ + {\ + __uiCurPos -= 1;\ + }\ + ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "},");\ +} + +#define VTOY_JSON_FMT_KEY(Key) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":", (Key)) + +#define VTOY_JSON_FMT_ITEM(Item) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\",", (Item)) + +#define VTOY_JSON_FMT_COMA() ssprintf(__uiCurPos, __pcBuf, __uiBufLen, ","); + +#define VTOY_JSON_FMT_APPEND_BEGIN() \ +{ \ + if ('}' == *(__pcBuf + (__uiCurPos - 1)))\ + {\ + __uiCurPos -= 1;\ + }\ + ssprintf(__uiCurPos, __pcBuf, __uiBufLen, ",");\ +} + +#define VTOY_JSON_FMT_APPEND_END() \ +{ \ + ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "}");\ +} + +#define VTOY_JSON_FMT_ARY_BEGIN() ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "[") + +#define VTOY_JSON_FMT_ARY_END() \ +{\ + if (',' == *(__pcBuf + (__uiCurPos - 1)))\ + {\ + __uiCurPos -= 1;\ + }\ + ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "]");\ +} + +#define VTOY_JSON_FMT_ARY_ENDEX() \ +{\ + if (',' == *(__pcBuf + (__uiCurPos - 1)))\ + {\ + __uiCurPos -= 1;\ + }\ + ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "],");\ +} + +#define VTOY_JSON_FMT_UINT64(Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":%llu,", Key, (_ull)Val) + +#define VTOY_JSON_FMT_ULONG(Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":%lu,", Key, Val) +#define VTOY_JSON_FMT_LONG(Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":%ld,", Key, Val) + +#define VTOY_JSON_FMT_UINT(Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":%u,", Key, Val) + +#define VTOY_JSON_FMT_STRINT(Key, Val) \ + ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":\"%u\",", Key, Val) + +#define VTOY_JSON_FMT_STRINT64(Key, Val) \ + ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":\"%llu\",", Key, Val) + +#define VTOY_JSON_FMT_SINT(Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":%d,", Key, Val) + +#define VTOY_JSON_FMT_DUBL(Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":%.1lf,", Key, Val) +#define VTOY_JSON_FMT_DUBL2(Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":%10.02lf,", Key, Val) + +#define VTOY_JSON_FMT_STRN(Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":\"%s\",", Key, Val) + +#define VTOY_JSON_FMT_NULL(Key) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":null,", Key) + +#define VTOY_JSON_FMT_TRUE(Key) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":true,", (Key)) +#define VTOY_JSON_FMT_FALSE(Key) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":false,", (Key)) + +#define VTOY_JSON_FMT_BOOL(Key, Val) \ +{\ + if (0 == (Val))\ + {\ + ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":false,", (Key));\ + }\ + else \ + {\ + ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":true,", (Key));\ + }\ +} + +typedef struct tagVTOY_JSON_PARSE +{ + char *pcKey; + void *pDataBuf; + uint32_t uiBufSize; +}VTOY_JSON_PARSE_S; + +#define JSON_SUCCESS 0 +#define JSON_FAILED 1 +#define JSON_NOT_FOUND 2 + +int vtoy_json_parse_value +( + char *pcNewStart, + char *pcRawStart, + VTOY_JSON *pstJson, + const char *pcData, + const char **ppcEnd +); +VTOY_JSON * vtoy_json_create(void); +int vtoy_json_parse(VTOY_JSON *pstJson, const char *szJsonData); +int vtoy_json_destroy(VTOY_JSON *pstJson); +VTOY_JSON *vtoy_json_find_item +( + VTOY_JSON *pstJson, + JSON_TYPE enDataType, + const char *szKey +); +int vtoy_json_scan_parse +( + const VTOY_JSON *pstJson, + uint32_t uiParseNum, + VTOY_JSON_PARSE_S *pstJsonParse +); +int vtoy_json_get_int +( + VTOY_JSON *pstJson, + const char *szKey, + int *piValue +); +int vtoy_json_get_uint +( + VTOY_JSON *pstJson, + const char *szKey, + uint32_t *puiValue +); +int vtoy_json_get_uint64 +( + VTOY_JSON *pstJson, + const char *szKey, + uint64_t *pui64Value +); +int vtoy_json_get_bool +( + VTOY_JSON *pstJson, + const char *szKey, + uint8_t *pbValue +); +int vtoy_json_get_string +( + VTOY_JSON *pstJson, + const char *szKey, + uint32_t uiBufLen, + char *pcBuf +); +const char * vtoy_json_get_string_ex(VTOY_JSON *pstJson, const char *szKey); + +#endif /* __VENTOY_JSON_H__ */ + diff --git a/LinuxGUI/Ventoy2Disk/Core/ventoy_log.c b/LinuxGUI/Ventoy2Disk/Core/ventoy_log.c new file mode 100644 index 0000000..2df37c2 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Core/ventoy_log.c @@ -0,0 +1,145 @@ +/****************************************************************************** + * ventoy_log.c ---- ventoy log + * + * Copyright (c) 2021, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern char g_log_file[PATH_MAX]; +static int g_ventoy_log_level = VLOG_DEBUG; +static pthread_mutex_t g_log_mutex; + +int ventoy_log_init(void) +{ + pthread_mutex_init(&g_log_mutex, NULL); + return 0; +} + +void ventoy_log_exit(void) +{ + pthread_mutex_destroy(&g_log_mutex); +} + +void ventoy_set_loglevel(int level) +{ + g_ventoy_log_level = level; +} + +void ventoy_syslog_newline(int level, const char *Fmt, ...) +{ + char log[512]; + va_list arg; + time_t stamp; + struct tm ttm; + FILE *fp; + + if (level > g_ventoy_log_level) + { + return; + } + + time(&stamp); + localtime_r(&stamp, &ttm); + + va_start(arg, Fmt); + vsnprintf(log, 512, Fmt, arg); + va_end(arg); + + pthread_mutex_lock(&g_log_mutex); + fp = fopen(g_log_file, "a+"); + if (fp) + { + fprintf(fp, "[%04u/%02u/%02u %02u:%02u:%02u] %s\n", + ttm.tm_year, ttm.tm_mon, ttm.tm_mday, + ttm.tm_hour, ttm.tm_min, ttm.tm_sec, + log); + fclose(fp); + } + pthread_mutex_unlock(&g_log_mutex); +} + +void ventoy_syslog_printf(const char *Fmt, ...) +{ + char log[512]; + va_list arg; + time_t stamp; + struct tm ttm; + FILE *fp; + + time(&stamp); + localtime_r(&stamp, &ttm); + + va_start(arg, Fmt); + vsnprintf(log, 512, Fmt, arg); + va_end(arg); + + pthread_mutex_lock(&g_log_mutex); + fp = fopen(g_log_file, "a+"); + if (fp) + { + fprintf(fp, "[%04u/%02u/%02u %02u:%02u:%02u] %s", + ttm.tm_year, ttm.tm_mon, ttm.tm_mday, + ttm.tm_hour, ttm.tm_min, ttm.tm_sec, + log); + fclose(fp); + } + pthread_mutex_unlock(&g_log_mutex); +} + +void ventoy_syslog(int level, const char *Fmt, ...) +{ + char log[512]; + va_list arg; + time_t stamp; + struct tm ttm; + FILE *fp; + + if (level > g_ventoy_log_level) + { + return; + } + + time(&stamp); + localtime_r(&stamp, &ttm); + + va_start(arg, Fmt); + vsnprintf(log, 512, Fmt, arg); + va_end(arg); + + pthread_mutex_lock(&g_log_mutex); + fp = fopen(g_log_file, "a+"); + if (fp) + { + fprintf(fp, "[%04u/%02u/%02u %02u:%02u:%02u] %s", + ttm.tm_year + 1900, ttm.tm_mon, ttm.tm_mday, + ttm.tm_hour, ttm.tm_min, ttm.tm_sec, + log); + fclose(fp); + } + pthread_mutex_unlock(&g_log_mutex); +} + diff --git a/LinuxGUI/Ventoy2Disk/Core/ventoy_md5.c b/LinuxGUI/Ventoy2Disk/Core/ventoy_md5.c new file mode 100644 index 0000000..ba79d54 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Core/ventoy_md5.c @@ -0,0 +1,167 @@ +/****************************************************************************** + * ventoy_md5.c ---- ventoy md5 + * + * Copyright (c) 2021, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ +#include +#include +#include +#include +#include +#include + +const static uint32_t k[64] = +{ + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 +}; + +const static uint32_t r[] = +{ + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 +}; + +#define LEFTROTATE(x, c) (((x) << (c)) | ((x) >> (32 - (c)))) +#define to_bytes(val, bytes) *((uint32_t *)(bytes)) = (val) + +#define ROTATE_CALC() \ +{\ + temp = d; \ + d = c; \ + c = b; \ + b = b + LEFTROTATE((a + f + k[i] + w[g]), r[i]); \ + a = temp; \ +} + +void ventoy_md5(const void *data, uint32_t len, uint8_t *md5) +{ + uint32_t h0, h1, h2, h3; + uint32_t w[16]; + uint32_t a, b, c, d, i, f, g, temp; + uint32_t offset, mod, delta; + uint8_t postbuf[128] = {0}; + + // Initialize variables - simple count in nibbles: + h0 = 0x67452301; + h1 = 0xefcdab89; + h2 = 0x98badcfe; + h3 = 0x10325476; + + //Pre-processing: + //append "1" bit to message + //append "0" bits until message length in bits ≡ 448 (mod 512) + //append length mod (2^64) to message + + mod = len % 64; + if (mod) + { + memcpy(postbuf, (const uint8_t *)data + len - mod, mod); + } + + postbuf[mod] = 0x80; + if (mod < 56) + { + to_bytes(len * 8, postbuf + 56); + to_bytes(len >> 29, postbuf + 60); + delta = 64; + } + else + { + to_bytes(len * 8, postbuf + 120); + to_bytes(len >> 29, postbuf + 124); + delta = 128; + } + + len -= mod; + + for (offset = 0; offset < len + delta; offset += 64) + { + if (offset < len) + { + memcpy(w, (const uint8_t *)data + offset, 64); + } + else + { + memcpy(w, postbuf + offset - len, 64); + } + + // Initialize hash value for this chunk: + a = h0; + b = h1; + c = h2; + d = h3; + + // Main loop: + for (i = 0; i < 16; i++) + { + f = (b & c) | ((~b) & d); + g = i; + ROTATE_CALC(); + } + + for (i = 16; i < 32; i++) + { + f = (d & b) | ((~d) & c); + g = (5 * i + 1) % 16; + ROTATE_CALC(); + } + + for (i = 32; i < 48; i++) + { + f = b ^ c ^ d; + g = (3 * i + 5) % 16; + ROTATE_CALC(); + } + + for (i = 48; i < 64; i++) + { + f = c ^ (b | (~d)); + g = (7 * i) % 16; + ROTATE_CALC(); + } + + // Add this chunk's hash to result so far: + h0 += a; + h1 += b; + h2 += c; + h3 += d; + } + + //var char md5[16] := h0 append h1 append h2 append h3 //(Output is in little-endian) + to_bytes(h0, md5); + to_bytes(h1, md5 + 4); + to_bytes(h2, md5 + 8); + to_bytes(h3, md5 + 12); +} + diff --git a/LinuxGUI/Ventoy2Disk/Core/ventoy_util.c b/LinuxGUI/Ventoy2Disk/Core/ventoy_util.c new file mode 100644 index 0000000..cbee36a --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Core/ventoy_util.c @@ -0,0 +1,646 @@ +/****************************************************************************** + * ventoy_util.c ---- ventoy util + * Copyright (c) 2021, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +uint8_t g_mbr_template[512]; + +void ventoy_gen_preudo_uuid(void *uuid) +{ + int i; + int fd; + + fd = open("/dev/urandom", O_RDONLY | O_BINARY); + if (fd < 0) + { + srand(time(NULL)); + for (i = 0; i < 8; i++) + { + *((uint16_t *)uuid + i) = (uint16_t)(rand() & 0xFFFF); + } + } + else + { + read(fd, uuid, 16); + close(fd); + } +} + +uint64_t ventoy_get_human_readable_gb(uint64_t SizeBytes) +{ + int i; + int Pow2 = 1; + double Delta; + double GB = SizeBytes * 1.0 / 1000 / 1000 / 1000; + + if ((SizeBytes % SIZE_1GB) == 0) + { + return (uint64_t)(SizeBytes / SIZE_1GB); + } + + for (i = 0; i < 12; i++) + { + if (Pow2 > GB) + { + Delta = (Pow2 - GB) / Pow2; + } + else + { + Delta = (GB - Pow2) / Pow2; + } + + if (Delta < 0.05) + { + return Pow2; + } + + Pow2 <<= 1; + } + + return (uint64_t)GB; +} + + +int ventoy_get_sys_file_line(char *buffer, int buflen, const char *fmt, ...) +{ + int len; + char c; + char path[256]; + va_list arg; + + va_start(arg, fmt); + vsnprintf(path, 256, fmt, arg); + va_end(arg); + + if (access(path, F_OK) >= 0) + { + FILE *fp = fopen(path, "r"); + memset(buffer, 0, buflen); + len = (int)fread(buffer, 1, buflen - 1, fp); + fclose(fp); + + while (len > 0) + { + c = buffer[len - 1]; + if (c == '\r' || c == '\n' || c == ' ' || c == '\t') + { + buffer[len - 1] = 0; + len--; + } + else + { + break; + } + } + + return 0; + } + else + { + vdebug("%s not exist \n", path); + return 1; + } +} + +int ventoy_is_disk_mounted(const char *devpath) +{ + int len; + int mount = 0; + char line[512]; + FILE *fp = NULL; + + fp = fopen("/proc/mounts", "r"); + if (!fp) + { + return 0; + } + + len = (int)strlen(devpath); + while (fgets(line, sizeof(line), fp)) + { + if (strncmp(line, devpath, len) == 0) + { + mount = 1; + vdebug("%s mounted <%s>\n", devpath, line); + goto end; + } + } + +end: + fclose(fp); + return mount; +} + +static int ventoy_mount_path_escape(char *src, char *dst, int len) +{ + int i = 0; + int n = 0; + + dst[len - 1] = 0; + + for (i = 0; i < len - 1; i++) + { + if (src[i] == '\\' && src[i + 1] == '0' && src[i + 2] == '4' && src[i + 3] == '0') + { + dst[n++] = ' '; + i += 3; + } + else + { + dst[n++] = src[i]; + } + + if (src[i] == 0) + { + break; + } + } + + return 0; +} + +int ventoy_try_umount_disk(const char *devpath) +{ + int rc; + int len; + char line[1024]; + char mntpt[1024]; + char *pos1 = NULL; + char *pos2 = NULL; + FILE *fp = NULL; + + fp = fopen("/proc/mounts", "r"); + if (!fp) + { + return 0; + } + + len = (int)strlen(devpath); + while (fgets(line, sizeof(line), fp)) + { + if (strncmp(line, devpath, len) == 0) + { + pos1 = strchr(line, ' '); + if (pos1) + { + pos2 = strchr(pos1 + 1, ' '); + if (pos2) + { + *pos2 = 0; + } + + ventoy_mount_path_escape(pos1 + 1, mntpt, sizeof(mntpt)); + rc = umount(mntpt); + if (rc) + { + vdebug("umount <%s> <%s> [ failed ] error:%d\n", devpath, mntpt, errno); + } + else + { + vdebug("umount <%s> <%s> [ success ]\n", devpath, mntpt); + } + } + } + } + + fclose(fp); + return 0; +} + +int ventoy_read_file_to_buf(const char *FileName, int ExtLen, void **Bufer, int *BufLen) +{ + int FileSize; + FILE *fp = NULL; + void *Data = NULL; + + fp = fopen(FileName, "rb"); + if (fp == NULL) + { + vlog("Failed to open file %s", FileName); + return 1; + } + + fseek(fp, 0, SEEK_END); + FileSize = (int)ftell(fp); + + Data = malloc(FileSize + ExtLen); + if (!Data) + { + fclose(fp); + return 1; + } + + fseek(fp, 0, SEEK_SET); + fread(Data, 1, FileSize, fp); + + fclose(fp); + + *Bufer = Data; + *BufLen = FileSize; + + return 0; +} + +const char * ventoy_get_local_version(void) +{ + int rc; + int FileSize; + char *Pos = NULL; + char *Buf = NULL; + static char LocalVersion[64] = { 0 }; + + if (LocalVersion[0] == 0) + { + rc = ventoy_read_file_to_buf("ventoy/version", 1, (void **)&Buf, &FileSize); + if (rc) + { + return ""; + } + Buf[FileSize] = 0; + + for (Pos = Buf; *Pos; Pos++) + { + if (*Pos == '\r' || *Pos == '\n') + { + *Pos = 0; + break; + } + } + + scnprintf(LocalVersion, "%s", Buf); + free(Buf); + } + + return LocalVersion; +} + +int VentoyGetLocalBootImg(MBR_HEAD *pMBR) +{ + memcpy(pMBR, g_mbr_template, 512); + return 0; +} + +static int VentoyFillProtectMBR(uint64_t DiskSizeBytes, MBR_HEAD *pMBR) +{ + ventoy_guid Guid; + uint32_t DiskSignature; + uint64_t DiskSectorCount; + + VentoyGetLocalBootImg(pMBR); + + ventoy_gen_preudo_uuid(&Guid); + + memcpy(&DiskSignature, &Guid, sizeof(uint32_t)); + + vdebug("Disk signature: 0x%08x\n", DiskSignature); + + memcpy(pMBR->BootCode + 0x1B8, &DiskSignature, 4); + memcpy(pMBR->BootCode + 0x180, &Guid, 16); + + DiskSectorCount = DiskSizeBytes / 512 - 1; + if (DiskSectorCount > 0xFFFFFFFF) + { + DiskSectorCount = 0xFFFFFFFF; + } + + memset(pMBR->PartTbl, 0, sizeof(pMBR->PartTbl)); + + pMBR->PartTbl[0].Active = 0x00; + pMBR->PartTbl[0].FsFlag = 0xee; // EE + + pMBR->PartTbl[0].StartHead = 0; + pMBR->PartTbl[0].StartSector = 1; + pMBR->PartTbl[0].StartCylinder = 0; + pMBR->PartTbl[0].EndHead = 254; + pMBR->PartTbl[0].EndSector = 63; + pMBR->PartTbl[0].EndCylinder = 1023; + + pMBR->PartTbl[0].StartSectorId = 1; + pMBR->PartTbl[0].SectorCount = (uint32_t)DiskSectorCount; + + pMBR->Byte55 = 0x55; + pMBR->ByteAA = 0xAA; + + pMBR->BootCode[92] = 0x22; + + return 0; +} + +static int ventoy_fill_gpt_partname(uint16_t Name[36], const char *asciiName) +{ + int i; + int len; + + memset(Name, 0, 36 * sizeof(uint16_t)); + len = (int)strlen(asciiName); + for (i = 0; i < 36 && i < len; i++) + { + Name[i] = asciiName[i]; + } + + return 0; +} + +int ventoy_fill_gpt(uint64_t size, uint64_t reserve, int align4k, VTOY_GPT_INFO *gpt) +{ + uint64_t ReservedSector = 33; + uint64_t ModSectorCount = 0; + uint64_t Part1SectorCount = 0; + uint64_t DiskSectorCount = size / 512; + VTOY_GPT_HDR *Head = &gpt->Head; + VTOY_GPT_PART_TBL *Table = gpt->PartTbl; + ventoy_guid WindowsDataPartType = { 0xebd0a0a2, 0xb9e5, 0x4433, { 0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7 } }; + //ventoy_guid EspPartType = { 0xc12a7328, 0xf81f, 0x11d2, { 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b } }; + //ventoy_guid BiosGrubPartType = { 0x21686148, 0x6449, 0x6e6f, { 0x74, 0x4e, 0x65, 0x65, 0x64, 0x45, 0x46, 0x49 } }; + + VentoyFillProtectMBR(size, &gpt->MBR); + + if (reserve > 0) + { + ReservedSector += reserve / 512; + } + + Part1SectorCount = DiskSectorCount - ReservedSector - (VTOYEFI_PART_BYTES / 512) - 2048; + + ModSectorCount = (Part1SectorCount % 8); + if (ModSectorCount) + { + vlog("Part1SectorCount:%llu is not aligned by 4KB (%llu)\n", (_ull)Part1SectorCount, (_ull)ModSectorCount); + } + + // check aligned with 4KB + if (align4k) + { + if (ModSectorCount) + { + vdebug("Disk need to align with 4KB %u\n", (uint32_t)ModSectorCount); + Part1SectorCount -= ModSectorCount; + } + else + { + vdebug("no need to align with 4KB\n"); + } + } + + memcpy(Head->Signature, "EFI PART", 8); + Head->Version[2] = 0x01; + Head->Length = 92; + Head->Crc = 0; + Head->EfiStartLBA = 1; + Head->EfiBackupLBA = DiskSectorCount - 1; + Head->PartAreaStartLBA = 34; + Head->PartAreaEndLBA = DiskSectorCount - 34; + ventoy_gen_preudo_uuid(&Head->DiskGuid); + Head->PartTblStartLBA = 2; + Head->PartTblTotNum = 128; + Head->PartTblEntryLen = 128; + + + memcpy(&(Table[0].PartType), &WindowsDataPartType, sizeof(ventoy_guid)); + ventoy_gen_preudo_uuid(&(Table[0].PartGuid)); + Table[0].StartLBA = 2048; + Table[0].LastLBA = 2048 + Part1SectorCount - 1; + Table[0].Attr = 0; + ventoy_fill_gpt_partname(Table[0].Name, "Ventoy"); + + // to fix windows issue + //memcpy(&(Table[1].PartType), &EspPartType, sizeof(GUID)); + memcpy(&(Table[1].PartType), &WindowsDataPartType, sizeof(ventoy_guid)); + ventoy_gen_preudo_uuid(&(Table[1].PartGuid)); + Table[1].StartLBA = Table[0].LastLBA + 1; + Table[1].LastLBA = Table[1].StartLBA + VTOYEFI_PART_BYTES / 512 - 1; + Table[1].Attr = 0x8000000000000000ULL; + ventoy_fill_gpt_partname(Table[1].Name, "VTOYEFI"); + +#if 0 + memcpy(&(Table[2].PartType), &BiosGrubPartType, sizeof(ventoy_guid)); + ventoy_gen_preudo_uuid(&(Table[2].PartGuid)); + Table[2].StartLBA = 34; + Table[2].LastLBA = 2047; + Table[2].Attr = 0; +#endif + + //Update CRC + Head->PartTblCrc = ventoy_crc32(Table, sizeof(gpt->PartTbl)); + Head->Crc = ventoy_crc32(Head, Head->Length); + + return 0; +} + +int VentoyFillMBRLocation(uint64_t DiskSizeInBytes, uint32_t StartSectorId, uint32_t SectorCount, PART_TABLE *Table) +{ + uint8_t Head; + uint8_t Sector; + uint8_t nSector = 63; + uint8_t nHead = 8; + uint32_t Cylinder; + uint32_t EndSectorId; + + while (nHead != 0 && (DiskSizeInBytes / 512 / nSector / nHead) > 1024) + { + nHead = (uint8_t)nHead * 2; + } + + if (nHead == 0) + { + nHead = 255; + } + + Cylinder = StartSectorId / nSector / nHead; + Head = StartSectorId / nSector % nHead; + Sector = StartSectorId % nSector + 1; + + Table->StartHead = Head; + Table->StartSector = Sector; + Table->StartCylinder = Cylinder; + + EndSectorId = StartSectorId + SectorCount - 1; + Cylinder = EndSectorId / nSector / nHead; + Head = EndSectorId / nSector % nHead; + Sector = EndSectorId % nSector + 1; + + Table->EndHead = Head; + Table->EndSector = Sector; + Table->EndCylinder = Cylinder; + + Table->StartSectorId = StartSectorId; + Table->SectorCount = SectorCount; + + return 0; +} + +int ventoy_fill_mbr(uint64_t size, uint64_t reserve, int align4k, MBR_HEAD *pMBR) +{ + ventoy_guid Guid; + uint32_t DiskSignature; + uint32_t DiskSectorCount; + uint32_t PartSectorCount; + uint32_t PartStartSector; + uint32_t ReservedSector; + + VentoyGetLocalBootImg(pMBR); + + ventoy_gen_preudo_uuid(&Guid); + + memcpy(&DiskSignature, &Guid, sizeof(uint32_t)); + + vdebug("Disk signature: 0x%08x\n", DiskSignature); + + memcpy(pMBR->BootCode + 0x1B8, &DiskSignature, 4); + memcpy(pMBR->BootCode + 0x180, &Guid, 16); + + if (size / 512 > 0xFFFFFFFF) + { + DiskSectorCount = 0xFFFFFFFF; + } + else + { + DiskSectorCount = (uint32_t)(size / 512); + } + + if (reserve <= 0) + { + ReservedSector = 0; + } + else + { + ReservedSector = (uint32_t)(reserve / 512); + } + + // check aligned with 4KB + if (align4k) + { + uint64_t sectors = size / 512; + if (sectors % 8) + { + vlog("Disk need to align with 4KB %u\n", (uint32_t)(sectors % 8)); + ReservedSector += (uint32_t)(sectors % 8); + } + else + { + vdebug("no need to align with 4KB\n"); + } + } + + vlog("ReservedSector: %u\n", ReservedSector); + + //Part1 + PartStartSector = VTOYIMG_PART_START_SECTOR; + PartSectorCount = DiskSectorCount - ReservedSector - VTOYEFI_PART_BYTES / 512 - PartStartSector; + VentoyFillMBRLocation(size, PartStartSector, PartSectorCount, pMBR->PartTbl); + + pMBR->PartTbl[0].Active = 0x80; // bootable + pMBR->PartTbl[0].FsFlag = 0x07; // exFAT/NTFS/HPFS + + //Part2 + PartStartSector += PartSectorCount; + PartSectorCount = VTOYEFI_PART_BYTES / 512; + VentoyFillMBRLocation(size, PartStartSector, PartSectorCount, pMBR->PartTbl + 1); + + pMBR->PartTbl[1].Active = 0x00; + pMBR->PartTbl[1].FsFlag = 0xEF; // EFI System Partition + + pMBR->Byte55 = 0x55; + pMBR->ByteAA = 0xAA; + + return 0; +} + +int ventoy_fill_mbr_4k(uint64_t size, uint64_t reserve, int align4k, MBR_HEAD *pMBR) +{ + ventoy_guid Guid; + uint32_t DiskSignature; + uint32_t DiskSectorCount; + uint32_t PartSectorCount; + uint32_t PartStartSector; + uint32_t ReservedSector; + + VentoyGetLocalBootImg(pMBR); + + ventoy_gen_preudo_uuid(&Guid); + + memcpy(&DiskSignature, &Guid, sizeof(uint32_t)); + + vdebug("Disk signature: 0x%08x\n", DiskSignature); + + memcpy(pMBR->BootCode + 0x1B8, &DiskSignature, 4); + memcpy(pMBR->BootCode + 0x180, &Guid, 16); + + if (size / 4096 > 0xFFFFFFFF) + { + DiskSectorCount = 0xFFFFFFFF; + } + else + { + DiskSectorCount = (uint32_t)(size / 4096); + } + + if (reserve <= 0) + { + ReservedSector = 0; + } + else + { + ReservedSector = (uint32_t)(reserve / 4096); + } + + // check aligned with 4KB + vdebug("no need to align with 4KB for 4K native disk\n"); + + vlog("ReservedSector: %u\n", ReservedSector); + + //Part1 + PartStartSector = VTOYIMG_PART_START_SECTOR >> 3; + PartSectorCount = DiskSectorCount - ReservedSector - VTOYEFI_PART_BYTES / 4096 - PartStartSector; + VentoyFillMBRLocation(size, PartStartSector, PartSectorCount, pMBR->PartTbl); + + pMBR->PartTbl[0].Active = 0x80; // bootable + pMBR->PartTbl[0].FsFlag = 0x07; // exFAT/NTFS/HPFS + + //Part2 + PartStartSector += PartSectorCount; + PartSectorCount = VTOYEFI_PART_BYTES / 4096; + VentoyFillMBRLocation(size, PartStartSector, PartSectorCount, pMBR->PartTbl + 1); + + pMBR->PartTbl[1].Active = 0x00; + pMBR->PartTbl[1].FsFlag = 0xEF; // EFI System Partition + + pMBR->Byte55 = 0x55; + pMBR->ByteAA = 0xAA; + + return 0; +} + diff --git a/LinuxGUI/Ventoy2Disk/Core/ventoy_util.h b/LinuxGUI/Ventoy2Disk/Core/ventoy_util.h new file mode 100644 index 0000000..a5e4c8b --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Core/ventoy_util.h @@ -0,0 +1,57 @@ +/****************************************************************************** + * ventoy_util.h + * + * Copyright (c) 2021, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ +#ifndef __VENTOY_UTIL_H__ +#define __VENTOY_UTIL_H__ + +extern char g_log_file[PATH_MAX]; +extern char g_ini_file[PATH_MAX]; + +#define check_free(p) if (p) free(p) +#define vtoy_safe_close_fd(fd) \ +{\ + if ((fd) >= 0) \ + { \ + close(fd); \ + (fd) = -1; \ + }\ +} + +extern uint8_t g_mbr_template[512]; +void ventoy_gen_preudo_uuid(void *uuid); +int ventoy_get_disk_part_name(const char *dev, int part, char *partbuf, int bufsize); +int ventoy_get_sys_file_line(char *buffer, int buflen, const char *fmt, ...); +uint64_t ventoy_get_human_readable_gb(uint64_t SizeBytes); +void ventoy_md5(const void *data, uint32_t len, uint8_t *md5); +int ventoy_is_disk_mounted(const char *devpath); +int ventoy_try_umount_disk(const char *devpath); +int unxz(unsigned char *in, int in_size, + int (*fill)(void *dest, unsigned int size), + int (*flush)(void *src, unsigned int size), + unsigned char *out, int *in_used, + void (*error)(char *x)); +int ventoy_read_file_to_buf(const char *FileName, int ExtLen, void **Bufer, int *BufLen); +const char * ventoy_get_local_version(void); +int ventoy_fill_gpt(uint64_t size, uint64_t reserve, int align4k, VTOY_GPT_INFO *gpt); +int ventoy_fill_mbr(uint64_t size, uint64_t reserve, int align4k, MBR_HEAD *pMBR); +int VentoyGetLocalBootImg(MBR_HEAD *pMBR); +int ventoy_fill_mbr_4k(uint64_t size, uint64_t reserve, int align4k, MBR_HEAD *pMBR); + +#endif /* __VENTOY_UTIL_H__ */ + diff --git a/LinuxGUI/Ventoy2Disk/GTK/refresh_icon_data.c b/LinuxGUI/Ventoy2Disk/GTK/refresh_icon_data.c new file mode 100644 index 0000000..0b678ff --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/GTK/refresh_icon_data.c @@ -0,0 +1,300 @@ +/****************************************************************************** + * refresh_icon_data.c + * + * Copyright (c) 2021, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include +#include + +static unsigned char refresh_icon_hexData[4286] = { + 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x20, 0x20, 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0xA8, 0x10, + 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x27, + 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x0C, 0xA6, 0xBE, + 0x32, 0x2D, 0xA6, 0xBE, 0x32, 0x54, 0xA6, 0xBE, 0x32, 0x72, 0xA6, 0xBE, 0x32, 0x81, 0xA6, 0xBE, + 0x32, 0x81, 0xA6, 0xBE, 0x32, 0x72, 0xA6, 0xBE, 0x32, 0x54, 0xA6, 0xBE, 0x32, 0x2D, 0xA6, 0xBE, + 0x32, 0x0C, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x21, 0xA6, 0xBE, 0x32, 0x72, 0xA6, 0xBE, 0x32, 0xBF, 0xA6, 0xBE, + 0x32, 0xEB, 0xA6, 0xBE, 0x32, 0xFC, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFC, 0xA6, 0xBE, 0x32, 0xEB, 0xA6, 0xBE, + 0x32, 0xBF, 0xA6, 0xBE, 0x32, 0x72, 0xA6, 0xBE, 0x32, 0x21, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x10, 0xA6, 0xBE, + 0x32, 0x71, 0xA6, 0xBE, 0x32, 0xD9, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xDA, 0xA6, 0xBE, 0x32, 0x71, 0xA6, 0xBE, + 0x32, 0x10, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x29, 0xA6, 0xBE, 0x32, 0xB2, 0xA6, 0xBE, + 0x32, 0xFE, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xA5, 0xBD, 0x30, 0xFF, 0xA5, 0xBD, 0x2F, 0xFF, 0xA5, 0xBD, + 0x2F, 0xFF, 0xA5, 0xBD, 0x2F, 0xFF, 0xA5, 0xBE, 0x31, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFE, 0xA6, 0xBE, + 0x32, 0xB2, 0xA6, 0xBE, 0x32, 0x29, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x35, 0xA6, 0xBE, 0x32, 0xCF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA5, 0xBD, 0x30, 0xFF, 0xA5, 0xBE, + 0x31, 0xFF, 0xAC, 0xC3, 0x40, 0xFF, 0xB7, 0xCA, 0x59, 0xFF, 0xBF, 0xD0, 0x6B, 0xFF, 0xC0, 0xD1, + 0x6E, 0xFF, 0xBA, 0xCD, 0x60, 0xFF, 0xAF, 0xC5, 0x48, 0xFF, 0xA7, 0xBF, 0x34, 0xFF, 0xA5, 0xBD, + 0x2F, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xCF, 0xA6, 0xBE, 0x32, 0x35, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x29, 0xA6, 0xBE, 0x32, 0xCF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xB5, 0xC9, 0x54, 0xFF, 0xD4, 0xE0, + 0x9D, 0xFF, 0xED, 0xF2, 0xD6, 0xFF, 0xF9, 0xFB, 0xF1, 0xFF, 0xFD, 0xFD, 0xFA, 0xFF, 0xFD, 0xFE, + 0xFB, 0xFF, 0xFB, 0xFC, 0xF5, 0xFF, 0xF2, 0xF6, 0xE1, 0xFF, 0xDD, 0xE6, 0xB1, 0xFF, 0xBD, 0xCF, + 0x67, 0xFF, 0xA7, 0xBF, 0x35, 0xFF, 0xA5, 0xBE, 0x30, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xCF, 0xA6, 0xBE, 0x32, 0x29, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x10, 0xA6, 0xBE, + 0x32, 0xB2, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x31, 0xFF, 0xA8, 0xC0, 0x37, 0xFF, 0xCB, 0xD9, 0x87, 0xFF, 0xF4, 0xF7, 0xE6, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0xFB, + 0xF4, 0xFF, 0xD9, 0xE4, 0xA8, 0xFF, 0xAF, 0xC4, 0x46, 0xFF, 0xA5, 0xBD, 0x30, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xB2, 0xA6, 0xBE, + 0x32, 0x10, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x71, 0xA6, 0xBE, + 0x32, 0xFE, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xA9, 0xC0, + 0x38, 0xFF, 0xD5, 0xE0, 0x9D, 0xFF, 0xFD, 0xFE, 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, + 0xFD, 0xFF, 0xEE, 0xF3, 0xD9, 0xFF, 0xD9, 0xE3, 0xA8, 0xFF, 0xCC, 0xDA, 0x8A, 0xFF, 0xCA, 0xD8, + 0x85, 0xFF, 0xD3, 0xDF, 0x99, 0xFF, 0xE6, 0xEC, 0xC4, 0xFF, 0xFA, 0xFB, 0xF3, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xED, 0xC7, 0xFF, 0xB1, 0xC6, 0x4C, 0xFF, 0xA5, 0xBD, + 0x30, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFE, 0xA6, 0xBE, + 0x32, 0x71, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x21, 0xA6, 0xBE, 0x32, 0xDA, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xCD, 0xDB, + 0x8C, 0xFF, 0xFD, 0xFE, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xF7, 0xE7, 0xFF, 0xCB, 0xD9, + 0x87, 0xFF, 0xAE, 0xC3, 0x43, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xA4, 0xBD, 0x2F, 0xFF, 0xA4, 0xBD, + 0x2E, 0xFF, 0xA5, 0xBD, 0x2F, 0xFF, 0xA9, 0xC0, 0x38, 0xFF, 0xBD, 0xCF, 0x66, 0xFF, 0xE8, 0xEE, + 0xC9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE4, 0xEB, 0xC1, 0xFF, 0xAD, 0xC3, + 0x41, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xDA, 0xA6, 0xBE, 0x32, 0x21, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBD, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x72, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA5, 0xBD, 0x2F, 0xFF, 0xA4, 0xBC, 0x2D, 0xFF, 0xB8, 0xCB, 0x5C, 0xFF, 0xF6, 0xF9, + 0xEB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0xF5, 0xDF, 0xFF, 0xBA, 0xCD, 0x60, 0xFF, 0xA4, 0xBD, + 0x2E, 0xFF, 0xA5, 0xBE, 0x31, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA5, 0xBD, 0x2F, 0xFF, 0xAE, 0xC4, + 0x44, 0xFF, 0xE2, 0xE9, 0xBB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0xD6, + 0x7E, 0xFF, 0xA5, 0xBD, 0x2F, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0x72, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x0C, 0xA6, 0xBE, 0x32, 0xC0, 0xA6, 0xBE, 0x32, 0xFF, 0xA9, 0xC0, + 0x39, 0xFF, 0xC8, 0xD7, 0x80, 0xFF, 0xD0, 0xDC, 0x92, 0xFF, 0xE7, 0xEE, 0xC8, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE6, 0xED, 0xC5, 0xFF, 0xCC, 0xDA, 0x8A, 0xFF, 0xB0, 0xC5, + 0x49, 0xFF, 0xA5, 0xBE, 0x31, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA5, 0xBD, + 0x30, 0xFF, 0xB0, 0xC6, 0x4A, 0xFF, 0xE3, 0xEA, 0xBE, 0xFF, 0xEA, 0xEF, 0xCE, 0xFF, 0xB8, 0xCB, + 0x5C, 0xFF, 0xA5, 0xBD, 0x30, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xBF, 0xA6, 0xBE, 0x32, 0x0C, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x2E, 0xA6, 0xBE, 0x32, 0xEB, 0xA6, 0xBE, 0x32, 0xFF, 0xA8, 0xC0, + 0x37, 0xFF, 0xE0, 0xE8, 0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0xF6, 0xE3, 0xFF, 0xB3, 0xC7, + 0x4F, 0xFF, 0xA5, 0xBD, 0x30, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xAA, 0xC1, 0x3A, 0xFF, 0xAB, 0xC1, 0x3D, 0xFF, 0xA6, 0xBE, + 0x31, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xEB, 0xA6, 0xBE, 0x32, 0x2D, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x54, 0xA6, 0xBE, 0x32, 0xFC, 0xA6, 0xBE, 0x32, 0xFF, 0xA5, 0xBD, + 0x30, 0xFF, 0xB6, 0xCA, 0x58, 0xFF, 0xF4, 0xF7, 0xE6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xFE, 0xFB, 0xFF, 0xC9, 0xD8, 0x84, 0xFF, 0xA5, 0xBD, + 0x30, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA5, 0xBE, 0x31, 0xFF, 0xA5, 0xBD, 0x2F, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFC, 0xA6, 0xBE, 0x32, 0x54, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x72, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA5, 0xBE, 0x30, 0xFF, 0xCD, 0xDB, 0x8C, 0xFF, 0xFE, 0xFE, 0xFD, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE2, 0xEA, 0xBC, 0xFF, 0xAA, 0xC1, 0x3A, 0xFF, 0xA6, 0xBE, + 0x31, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xAB, 0xC2, 0x3E, 0xFF, 0xBB, 0xCE, 0x63, 0xFF, 0xA7, 0xBF, + 0x35, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0x72, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x81, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xAB, 0xC2, 0x3E, 0xFF, 0xE6, 0xED, 0xC5, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF5, 0xF8, 0xE8, 0xFF, 0xB7, 0xCB, 0x5A, 0xFF, 0xA5, 0xBD, 0x30, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA5, 0xBE, 0x31, 0xFF, 0xCE, 0xDB, 0x8F, 0xFF, 0xF7, 0xF9, 0xEC, 0xFF, 0xBD, 0xCF, + 0x67, 0xFF, 0xA5, 0xBD, 0x2F, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0x81, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x81, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA5, 0xBD, 0x2F, 0xFF, 0xBB, 0xCD, 0x63, 0xFF, 0xF6, 0xF8, + 0xEA, 0xFF, 0xCE, 0xDB, 0x8F, 0xFF, 0xA5, 0xBE, 0x31, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA5, 0xBD, + 0x30, 0xFF, 0xB7, 0xCB, 0x5A, 0xFF, 0xF5, 0xF8, 0xE8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE8, 0xEE, + 0xC9, 0xFF, 0xAC, 0xC2, 0x40, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0x81, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x72, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA7, 0xBF, 0x34, 0xFF, 0xBA, 0xCD, + 0x60, 0xFF, 0xAB, 0xC2, 0x3E, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xAA, 0xC1, + 0x3A, 0xFF, 0xE2, 0xEA, 0xBC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFE, 0xFF, 0xCF, 0xDC, 0x90, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0x72, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x54, 0xA6, 0xBE, 0x32, 0xFC, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA5, 0xBD, + 0x2F, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA5, 0xBD, 0x30, 0xFF, 0xC9, 0xD8, + 0x84, 0xFF, 0xFD, 0xFE, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF5, 0xF8, 0xE9, 0xFF, 0xB8, 0xCB, 0x5B, 0xFF, 0xA5, 0xBD, 0x30, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFC, 0xA6, 0xBE, 0x32, 0x54, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x2E, 0xA6, 0xBE, 0x32, 0xEB, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xA9, 0xC0, + 0x38, 0xFF, 0xA8, 0xBF, 0x37, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA5, 0xBD, 0x30, 0xFF, 0xB2, 0xC7, 0x4F, 0xFF, 0xF2, 0xF6, + 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE2, 0xE9, 0xBB, 0xFF, 0xA9, 0xC0, 0x38, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xEB, 0xA6, 0xBE, 0x32, 0x2D, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x0C, 0xA6, 0xBE, 0x32, 0xC0, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA5, 0xBD, 0x30, 0xFF, 0xB5, 0xC9, 0x54, 0xFF, 0xE4, 0xEB, + 0xC1, 0xFF, 0xDF, 0xE8, 0xB5, 0xFF, 0xAF, 0xC5, 0x47, 0xFF, 0xA5, 0xBD, 0x30, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA5, 0xBE, 0x31, 0xFF, 0xAF, 0xC5, 0x47, 0xFF, 0xCA, 0xD8, + 0x85, 0xFF, 0xE2, 0xE9, 0xBB, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE9, 0xEF, + 0xCD, 0xFF, 0xCE, 0xDB, 0x8F, 0xFF, 0xC7, 0xD6, 0x7E, 0xFF, 0xA9, 0xC0, 0x39, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xBF, 0xA6, 0xBE, 0x32, 0x0C, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBD, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x73, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA5, 0xBD, 0x2F, 0xFF, 0xC6, 0xD6, 0x7C, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xE8, 0xB5, 0xFF, 0xAC, 0xC3, 0x40, 0xFF, 0xA5, 0xBD, + 0x2F, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xA4, 0xBD, 0x2E, 0xFF, 0xB5, 0xC9, + 0x55, 0xFF, 0xED, 0xF2, 0xD6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFB, 0xF1, 0xFF, 0xBC, 0xCE, + 0x65, 0xFF, 0xA4, 0xBC, 0x2C, 0xFF, 0xA5, 0xBD, 0x2F, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0x72, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x21, 0xA6, 0xBE, 0x32, 0xDA, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xAE, 0xC4, 0x44, 0xFF, 0xE6, 0xED, + 0xC6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE4, 0xEB, 0xC1, 0xFF, 0xB9, 0xCC, + 0x5E, 0xFF, 0xA7, 0xBF, 0x35, 0xFF, 0xA5, 0xBD, 0x2F, 0xFF, 0xA4, 0xBD, 0x2E, 0xFF, 0xA4, 0xBD, + 0x2E, 0xFF, 0xA5, 0xBD, 0x2F, 0xFF, 0xAB, 0xC1, 0x3D, 0xFF, 0xC5, 0xD5, 0x79, 0xFF, 0xF1, 0xF5, + 0xDE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xD3, 0xDF, 0x99, 0xFF, 0xA7, 0xBE, + 0x33, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xDA, 0xA6, 0xBE, 0x32, 0x21, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x72, 0xA6, 0xBE, + 0x32, 0xFE, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA5, 0xBD, 0x30, 0xFF, 0xB3, 0xC8, + 0x51, 0xFF, 0xE9, 0xEF, 0xCD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xFA, + 0xEE, 0xFF, 0xE1, 0xE9, 0xBA, 0xFF, 0xCD, 0xDB, 0x8C, 0xFF, 0xC4, 0xD4, 0x78, 0xFF, 0xC6, 0xD6, + 0x7C, 0xFF, 0xD3, 0xDF, 0x9A, 0xFF, 0xE9, 0xEF, 0xCD, 0xFF, 0xFC, 0xFD, 0xF9, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFE, 0xFF, 0xFE, 0xFF, 0xDB, 0xE4, 0xAB, 0xFF, 0xAA, 0xC1, 0x3C, 0xFF, 0xA6, 0xBE, + 0x31, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFE, 0xA6, 0xBE, + 0x32, 0x71, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x10, 0xA6, 0xBE, + 0x32, 0xB3, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA5, 0xBD, + 0x30, 0xFF, 0xB1, 0xC6, 0x4B, 0xFF, 0xDD, 0xE6, 0xB2, 0xFF, 0xFC, 0xFD, 0xF8, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, + 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xFA, + 0xEE, 0xFF, 0xD1, 0xDE, 0x96, 0xFF, 0xAA, 0xC1, 0x3C, 0xFF, 0xA5, 0xBE, 0x31, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xB2, 0xA6, 0xBE, + 0x32, 0x10, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x29, 0xA6, 0xBE, 0x32, 0xCF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA5, 0xBD, 0x30, 0xFF, 0xA9, 0xC0, 0x38, 0xFF, 0xC1, 0xD2, 0x71, 0xFF, 0xE2, 0xEA, + 0xBC, 0xFF, 0xF5, 0xF8, 0xE9, 0xFF, 0xFD, 0xFD, 0xFA, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFE, 0xFF, + 0xFE, 0xFF, 0xFB, 0xFC, 0xF7, 0xFF, 0xF2, 0xF5, 0xE1, 0xFF, 0xDB, 0xE5, 0xAC, 0xFF, 0xB9, 0xCC, + 0x5F, 0xFF, 0xA6, 0xBE, 0x33, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xCF, 0xA6, 0xBE, 0x32, 0x29, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x35, 0xA6, 0xBE, 0x32, 0xCF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xA5, 0xBD, 0x2F, 0xFF, 0xA8, 0xBF, + 0x36, 0xFF, 0xB3, 0xC7, 0x4F, 0xFF, 0xBF, 0xD0, 0x6B, 0xFF, 0xC5, 0xD5, 0x7A, 0xFF, 0xC4, 0xD4, + 0x78, 0xFF, 0xBC, 0xCE, 0x64, 0xFF, 0xB0, 0xC5, 0x48, 0xFF, 0xA6, 0xBE, 0x33, 0xFF, 0xA5, 0xBD, + 0x30, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xCF, 0xA6, 0xBE, 0x32, 0x35, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x29, 0xA6, 0xBE, 0x32, 0xB2, 0xA6, 0xBE, + 0x32, 0xFE, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA5, 0xBD, 0x30, 0xFF, 0xA5, 0xBD, 0x2F, 0xFF, 0xA4, 0xBD, 0x2E, 0xFF, 0xA4, 0xBD, + 0x2E, 0xFF, 0xA5, 0xBD, 0x2F, 0xFF, 0xA5, 0xBE, 0x31, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFE, 0xA6, 0xBE, + 0x32, 0xB3, 0xA6, 0xBE, 0x32, 0x29, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x10, 0xA6, 0xBE, + 0x32, 0x71, 0xA6, 0xBE, 0x32, 0xDA, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xDA, 0xA6, 0xBE, 0x32, 0x72, 0xA6, 0xBE, + 0x32, 0x10, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x21, 0xA6, 0xBE, 0x32, 0x72, 0xA6, 0xBE, 0x32, 0xBF, 0xA6, 0xBE, + 0x32, 0xEB, 0xA6, 0xBE, 0x32, 0xFC, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFC, 0xA6, 0xBE, 0x32, 0xEB, 0xA6, 0xBE, + 0x32, 0xC0, 0xA6, 0xBE, 0x32, 0x73, 0xA6, 0xBE, 0x32, 0x21, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x0C, 0xA6, 0xBE, + 0x32, 0x2D, 0xA6, 0xBE, 0x32, 0x54, 0xA6, 0xBE, 0x32, 0x72, 0xA6, 0xBE, 0x32, 0x81, 0xA6, 0xBE, + 0x32, 0x81, 0xA6, 0xBE, 0x32, 0x72, 0xA6, 0xBE, 0x32, 0x54, 0xA6, 0xBE, 0x32, 0x2E, 0xA6, 0xBE, + 0x32, 0x0C, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBD, 0x31, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, + 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x00, 0x0F, 0xE0, 0x00, + 0x00, 0x07, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, + 0x00, 0x01, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x07, 0xF0, 0x00, + 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x1F, 0xFE, 0x00, 0x00, 0x7F, 0xFF, 0x80, 0x01, 0xFF +}; + +void *get_refresh_icon_raw_data(int *len) +{ + *len = (int)sizeof(refresh_icon_hexData); + return refresh_icon_hexData; +} + diff --git a/LinuxGUI/Ventoy2Disk/GTK/secure_icon_data.c b/LinuxGUI/Ventoy2Disk/GTK/secure_icon_data.c new file mode 100644 index 0000000..d72c847 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/GTK/secure_icon_data.c @@ -0,0 +1,91 @@ +/****************************************************************************** + * secure_icon_data.c + * + * Copyright (c) 2021, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include +#include + +static unsigned char secure_icon_hexData[958] = { + 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x0D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xA8, 0x03, + 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x03, 0x00, 0x00, 0x46, 0x5C, + 0x00, 0x00, 0x46, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8C, + 0xFB, 0x01, 0x00, 0x8C, 0xFB, 0x2E, 0x00, 0x8C, 0xFB, 0x52, 0x00, 0x8C, 0xFB, 0x53, 0x00, 0x8C, + 0xFB, 0x53, 0x00, 0x8C, 0xFB, 0x53, 0x00, 0x8C, 0xFB, 0x53, 0x00, 0x8C, 0xFB, 0x53, 0x00, 0x8C, + 0xFB, 0x53, 0x00, 0x8C, 0xFB, 0x53, 0x00, 0x8C, 0xFB, 0x52, 0x00, 0x8C, 0xFB, 0x2E, 0x00, 0x8C, + 0xFB, 0x01, 0x00, 0x8C, 0xFB, 0x3E, 0x00, 0x8C, 0xFB, 0xDA, 0x00, 0x8C, 0xFB, 0xF8, 0x00, 0x8C, + 0xFB, 0xF7, 0x00, 0x8C, 0xFB, 0xF7, 0x00, 0x8C, 0xFB, 0xF7, 0x00, 0x8C, 0xFB, 0xF7, 0x00, 0x8C, + 0xFB, 0xF7, 0x00, 0x8C, 0xFB, 0xF7, 0x00, 0x8C, 0xFB, 0xF7, 0x00, 0x8C, 0xFB, 0xF8, 0x00, 0x8C, + 0xFB, 0xDA, 0x00, 0x8C, 0xFB, 0x3E, 0x00, 0x8C, 0xFB, 0x78, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0x78, 0x00, 0x8C, 0xFB, 0x7B, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0x7B, 0x00, 0x8C, + 0xFB, 0x7A, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x86, 0xF1, 0xFF, 0x00, 0x7C, 0xDF, 0xFF, 0x00, 0x86, 0xF1, 0xFF, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, + 0xFB, 0x7A, 0x00, 0x8C, 0xFB, 0x7A, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x8C, 0xFC, 0xFF, 0x00, 0x7C, 0xDF, 0xFF, 0x00, 0x6C, 0xC4, 0xFF, 0x00, 0x7C, + 0xDF, 0xFF, 0x00, 0x8C, 0xFC, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0x7A, 0x00, 0x8C, 0xFB, 0x7A, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x87, 0xF2, 0xFF, 0x00, 0x7D, + 0xE1, 0xFF, 0x00, 0x87, 0xF2, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0x7A, 0x00, 0x8C, 0xFB, 0x7B, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x8C, 0xFC, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0x7B, 0x00, 0x8C, + 0xFB, 0x77, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, + 0xFB, 0x77, 0x00, 0x8C, 0xFB, 0x3A, 0x00, 0x8C, 0xFB, 0xD4, 0x01, 0x8B, 0xF9, 0xF7, 0x03, 0x89, + 0xF3, 0xFF, 0x01, 0x8B, 0xF8, 0xF8, 0x00, 0x8C, 0xFB, 0xF4, 0x00, 0x8C, 0xFB, 0xF4, 0x00, 0x8C, + 0xFB, 0xF4, 0x01, 0x8B, 0xF8, 0xF8, 0x03, 0x89, 0xF3, 0xFF, 0x01, 0x8B, 0xF9, 0xF7, 0x00, 0x8C, + 0xFB, 0xD4, 0x00, 0x8C, 0xFB, 0x3A, 0x00, 0x8C, 0xFB, 0x00, 0x00, 0x93, 0xFF, 0x1E, 0x1D, 0x6B, + 0xA9, 0x6B, 0x32, 0x54, 0x6F, 0xF6, 0x22, 0x65, 0x9A, 0x7D, 0x00, 0x90, 0xFF, 0x39, 0x00, 0x8C, + 0xFB, 0x3C, 0x00, 0x90, 0xFF, 0x39, 0x22, 0x65, 0x9A, 0x7D, 0x32, 0x54, 0x6F, 0xF6, 0x1D, 0x6B, + 0xA9, 0x6B, 0x00, 0x93, 0xFF, 0x1E, 0x00, 0x8C, 0xFB, 0x00, 0x00, 0x8C, 0xFB, 0x00, 0x2A, 0x5D, + 0x85, 0x00, 0x46, 0x3D, 0x36, 0x3A, 0x43, 0x41, 0x3F, 0xF3, 0x45, 0x3F, 0x3A, 0x58, 0x26, 0x62, + 0x91, 0x00, 0x00, 0x8D, 0xFD, 0x00, 0x26, 0x62, 0x91, 0x00, 0x45, 0x3F, 0x3A, 0x58, 0x43, 0x41, + 0x3F, 0xF3, 0x46, 0x3D, 0x36, 0x3A, 0x2A, 0x5D, 0x85, 0x00, 0x00, 0x8C, 0xFB, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x42, 0x42, 0x00, 0x42, 0x42, 0x42, 0x27, 0x42, 0x42, 0x42, 0xE9, 0x42, 0x42, + 0x42, 0x94, 0x42, 0x42, 0x42, 0x01, 0x42, 0x42, 0x42, 0x00, 0x42, 0x42, 0x42, 0x01, 0x42, 0x42, + 0x42, 0x94, 0x42, 0x42, 0x42, 0xE9, 0x42, 0x42, 0x42, 0x27, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x00, 0x42, 0x42, 0x42, 0x04, 0x42, 0x42, + 0x42, 0x96, 0x42, 0x42, 0x42, 0xF5, 0x42, 0x42, 0x42, 0x8E, 0x42, 0x42, 0x42, 0x53, 0x42, 0x42, + 0x42, 0x8E, 0x42, 0x42, 0x42, 0xF5, 0x42, 0x42, 0x42, 0x96, 0x42, 0x42, 0x42, 0x04, 0x42, 0x42, + 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x00, 0x42, 0x42, + 0x42, 0x00, 0x42, 0x42, 0x42, 0x16, 0x42, 0x42, 0x42, 0x96, 0x42, 0x42, 0x42, 0xE9, 0x42, 0x42, + 0x42, 0xF3, 0x42, 0x42, 0x42, 0xE9, 0x42, 0x42, 0x42, 0x96, 0x42, 0x42, 0x42, 0x16, 0x42, 0x42, + 0x42, 0x00, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, + 0x42, 0x00, 0x42, 0x42, 0x42, 0x00, 0x42, 0x42, 0x42, 0x00, 0x42, 0x42, 0x42, 0x05, 0x42, 0x42, + 0x42, 0x31, 0x42, 0x42, 0x42, 0x4B, 0x42, 0x42, 0x42, 0x31, 0x42, 0x42, 0x42, 0x05, 0x42, 0x42, + 0x42, 0x00, 0x42, 0x42, 0x42, 0x00, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, + 0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x80, 0x08, 0x00, 0x00 +}; + +void *get_secure_icon_raw_data(int *len) +{ + *len = (int)sizeof(secure_icon_hexData); + return secure_icon_hexData; +} diff --git a/LinuxGUI/Ventoy2Disk/GTK/ventoy_gtk.c b/LinuxGUI/Ventoy2Disk/GTK/ventoy_gtk.c new file mode 100644 index 0000000..bb9215a --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/GTK/ventoy_gtk.c @@ -0,0 +1,1140 @@ +/****************************************************************************** + * ventoy_gtk.c + * + * Copyright (c) 2021, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include "ventoy_gtk.h" + +int g_secure_boot_support = 0; +GtkWidget *g_topWindow = NULL; +GtkWidget *g_partCfgWindow = NULL; +GtkBuilder *g_pXmlBuilder = NULL; +GtkComboBoxText *g_dev_combobox = NULL; +GtkButton *g_refresh_button = NULL; +GtkButton *g_install_button = NULL; +GtkButton *g_update_button = NULL; +GtkMenu *g_lang_menu = NULL;; +GtkCheckMenuItem *g_menu_item_secure_boot = NULL; +GtkCheckMenuItem *g_menu_item_mbr = NULL; +GtkCheckMenuItem *g_menu_item_gpt = NULL; +GtkCheckMenuItem *g_menu_item_show_all = NULL; +GtkLabel *g_device_title = NULL; +GtkLabel *g_label_local_part_style = NULL; +GtkLabel *g_label_dev_part_style = NULL; +GtkLabel *g_label_local_ver = NULL; +GtkLabel *g_label_disk_ver = NULL; +GtkLabel *g_label_status = NULL; +GtkImage *g_image_secure_local = NULL; +GtkImage *g_image_secure_device = NULL; +GtkToggleButton *g_part_align_checkbox = NULL; +GtkToggleButton *g_part_preserve_checkbox = NULL; +GtkEntry *g_part_reserve_space_value = NULL; +GtkComboBoxText *g_part_space_unit_combox = NULL; +GtkProgressBar *g_progress_bar = NULL; +VTOY_JSON *g_languages_json = NULL; +int g_languages_toggled_proc = 0; +int g_dev_changed_proc = 0; +gboolean g_align_part_with_4k = TRUE; +gboolean g_preserve_space_check = FALSE; +int g_preserve_space_unit = 1; +int g_preserve_space_number = 0; +gboolean g_thread_run = FALSE; + +const char *language_string(const char *id) +{ + const char *pName = NULL; + VTOY_JSON *node = NULL; + const char *pCurLang = ventoy_code_get_cur_language(); + + for (node = g_languages_json->pstChild; node; node = node->pstNext) + { + pName = vtoy_json_get_string_ex(node->pstChild, "name"); + if (0 == g_strcmp0(pName, pCurLang)) + { + break; + } + } + + if (NULL == node) + { + return "xxx"; + } + + return vtoy_json_get_string_ex(node->pstChild, id); +} + +int msgbox(GtkMessageType type, GtkButtonsType buttons, const char *strid) +{ + int ret; + GtkWidget *pMsgBox = NULL; + + pMsgBox = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, type, buttons, "%s", language_string(strid)); + + ret = gtk_dialog_run(GTK_DIALOG(pMsgBox)); + gtk_widget_destroy(pMsgBox); + + return ret; +} + + +static void set_item_visible(const char *id, int visible) +{ + GtkWidget *pWidget = NULL; + + pWidget = GTK_WIDGET(gtk_builder_get_object(g_pXmlBuilder, id)); + if (visible) + { + gtk_widget_show(pWidget); + } + else + { + gtk_widget_hide(pWidget); + } +} + +static void init_part_style_menu(void) +{ + int style; + + style = ventoy_code_get_cur_part_style(); + gtk_check_menu_item_set_active(g_menu_item_mbr, (0 == style)); + gtk_check_menu_item_set_active(g_menu_item_gpt, (1 == style)); + gtk_label_set_text(g_label_local_part_style, style ? "GPT" : "MBR"); +} + +static void select_language(const char *lang) +{ + const char *pName = NULL; + const char *pPos = NULL; + const char *pDevice = NULL; + VTOY_JSON *node = NULL; + char device[256]; + + for (node = g_languages_json->pstChild; node; node = node->pstNext) + { + pName = vtoy_json_get_string_ex(node->pstChild, "name"); + if (0 == g_strcmp0(pName, lang)) + { + break; + } + } + + if (NULL == node) + { + return; + } + + pDevice = gtk_label_get_text(g_device_title); + if (pDevice && (pPos = strchr(pDevice, '[')) != NULL) + { + g_snprintf(device, sizeof(device), "%s %s", vtoy_json_get_string_ex(node->pstChild, "STR_DEVICE"), pPos); + gtk_label_set_text(g_device_title, device); + } + else + { + gtk_label_set_text(g_device_title, vtoy_json_get_string_ex(node->pstChild, "STR_DEVICE")); + } + + LANG_LABEL_TEXT("label_local_ver", "STR_LOCAL_VER"); + LANG_LABEL_TEXT("label_device_ver", "STR_DISK_VER"); + + LANG_LABEL_TEXT("label_status", "STR_STATUS"); + + LANG_BUTTON_TEXT("button_install", "STR_INSTALL"); + LANG_BUTTON_TEXT("button_update", "STR_UPDATE"); + + LANG_MENU_ITEM_TEXT("menu_option", "STR_MENU_OPTION"); + LANG_MENU_ITEM_TEXT("menu_item_secure", "STR_MENU_SECURE_BOOT"); + LANG_MENU_ITEM_TEXT("menu_part_style", "STR_MENU_PART_STYLE"); + LANG_MENU_ITEM_TEXT("menu_item_part_cfg", "STR_MENU_PART_CFG"); + LANG_MENU_ITEM_TEXT("menu_item_clear", "STR_MENU_CLEAR"); + LANG_MENU_ITEM_TEXT("menu_item_show_all", "STR_SHOW_ALL_DEV"); + + LANG_BUTTON_TEXT("space_check_btn", "STR_PRESERVE_SPACE"); + LANG_BUTTON_TEXT("space_align_btn", "STR_PART_ALIGN_4KB"); + LANG_BUTTON_TEXT("button_partcfg_ok", "STR_BTN_OK"); + LANG_BUTTON_TEXT("button_partcfg_cancel", "STR_BTN_CANCEL"); + + gtk_window_set_title(GTK_WINDOW(g_partCfgWindow), vtoy_json_get_string_ex(node->pstChild, "STR_MENU_PART_CFG")); + + /* + * refresh screen + */ + + gtk_widget_hide(g_topWindow); + gtk_widget_show(g_topWindow); +} + + +void on_secure_boot_toggled(GtkMenuItem *menuItem, gpointer data) +{ + g_secure_boot_support = 1 - g_secure_boot_support; + + if (g_secure_boot_support) + { + gtk_widget_show((GtkWidget *)g_image_secure_local); + } + else + { + gtk_widget_hide((GtkWidget *)g_image_secure_local); + } +} + +void on_devlist_changed(GtkWidget *widget, gpointer data) +{ + int active; + ventoy_disk *cur = NULL; + char version[512]; + + if (g_dev_changed_proc == 0) + { + return; + } + + gtk_widget_set_sensitive(GTK_WIDGET(g_update_button), FALSE); + + gtk_widget_hide((GtkWidget *)g_image_secure_device); + gtk_label_set_markup(g_label_disk_ver, ""); + gtk_label_set_text(g_label_dev_part_style, ""); + + active = gtk_combo_box_get_active((GtkComboBox *)g_dev_combobox); + if (active < 0 || active >= g_disk_num) + { + vlog("invalid active combox id %d\n", active); + return; + } + + cur = g_disk_list + active; + if (cur->vtoydata.ventoy_valid) + { + if (cur->vtoydata.secure_boot_flag) + { + gtk_widget_show((GtkWidget *)g_image_secure_device); + } + else + { + gtk_widget_hide((GtkWidget *)g_image_secure_device); + } + + if (g_secure_boot_support != cur->vtoydata.secure_boot_flag) + { + gtk_check_menu_item_set_active(g_menu_item_secure_boot, 1 - g_secure_boot_support); + } + + g_snprintf(version, sizeof(version), VTOY_VER_FMT, cur->vtoydata.ventoy_ver); + gtk_label_set_markup(g_label_disk_ver, version); + gtk_label_set_text(g_label_dev_part_style, cur->vtoydata.partition_style ? "GPT" : "MBR"); + + gtk_widget_set_sensitive(GTK_WIDGET(g_update_button), TRUE); + } + else + { + if (!g_secure_boot_support) + { + gtk_check_menu_item_set_active(g_menu_item_secure_boot, 1 - g_secure_boot_support); + } + } +} + + +void on_language_toggled(GtkMenuItem *menuItem, gpointer data) +{ + const char *cur_lang = NULL; + + if (g_languages_toggled_proc == 0) + { + return; + } + + cur_lang = ventoy_code_get_cur_language(); + if (g_strcmp0(cur_lang, (char *)data) != 0) + { + ventoy_code_set_cur_language((char *)data); + select_language((char *)data); + } +} + +void on_part_style_toggled(GtkMenuItem *menuItem, gpointer data) +{ + int style; + + style = ventoy_code_get_cur_part_style(); + ventoy_code_set_cur_part_style(1 - style); + + gtk_label_set_text(g_label_local_part_style, style ? "MBR" : "GPT"); +} + +static ventoy_disk *select_active_dev(const char *select, int *activeid) +{ + int i; + int alldev; + ventoy_disk *cur = NULL; + + alldev = ventoy_code_get_cur_show_all(); + + /* find the match one */ + if (select) + { + for (i = 0; i < g_disk_num; i++) + { + cur = g_disk_list + i; + if (alldev == 0 && cur->type != VTOY_DEVICE_USB) + { + continue; + } + + if (strcmp(cur->disk_name, select) == 0) + { + *activeid = i; + return cur; + } + } + } + + /* find the first one that installed with Ventoy */ + for (i = 0; i < g_disk_num; i++) + { + cur = g_disk_list + i; + if (alldev == 0 && cur->type != VTOY_DEVICE_USB) + { + continue; + } + + if (cur->vtoydata.ventoy_valid) + { + *activeid = i; + return cur; + } + } + + /* find the first USB interface device */ + for (i = 0; i < g_disk_num; i++) + { + cur = g_disk_list + i; + if (alldev == 0 && cur->type != VTOY_DEVICE_USB) + { + continue; + } + + if (cur->type == VTOY_DEVICE_USB) + { + *activeid = i; + return cur; + } + } + + /* use the first one */ + for (i = 0; i < g_disk_num; i++) + { + cur = g_disk_list + i; + if (alldev == 0 && cur->type != VTOY_DEVICE_USB) + { + continue; + } + + *activeid = i; + return cur; + } + + return NULL; +} + +static void fill_dev_list(const char *select) +{ + int i; + int alldev; + int activeid; + int count = 0; + char line[512]; + ventoy_disk *cur = NULL; + ventoy_disk *active = NULL; + GtkListStore *store = NULL; + + g_dev_changed_proc = 0; + + alldev = ventoy_code_get_cur_show_all(); + + vlog("fill_dev_list total disk: %d showall:%d\n", g_disk_num, alldev); + + /* gtk_combo_box_text_remove_all */ + store = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(g_dev_combobox))); + gtk_list_store_clear(store); + + for (i = 0; i < g_disk_num; i++) + { + cur = g_disk_list + i; + + if (alldev == 0 && cur->type != VTOY_DEVICE_USB) + { + continue; + } + + g_snprintf(line, sizeof(line), "%s [%s] %s", cur->disk_name, cur->human_readable_size, cur->disk_model); + gtk_combo_box_text_append_text(g_dev_combobox, line); + count++; + } + + active = select_active_dev(select, &activeid); + if (active) + { + vlog("combox count:%d, active:%s id:%d\n", count, active->disk_name, activeid); + gtk_combo_box_set_active((GtkComboBox *)g_dev_combobox, activeid); + gtk_widget_set_sensitive(GTK_WIDGET(g_install_button), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(g_update_button), active->vtoydata.ventoy_valid); + } + else + { + vlog("combox count:%d, no active id\n", count); + gtk_widget_set_sensitive(GTK_WIDGET(g_install_button), FALSE); + gtk_widget_set_sensitive(GTK_WIDGET(g_update_button), FALSE); + } + + g_dev_changed_proc = 1; + on_devlist_changed(NULL, NULL); +} + + +void on_show_all_toggled(GtkMenuItem *menuItem, gpointer data) +{ + int show_all = ventoy_code_get_cur_show_all(); + + ventoy_code_set_cur_show_all(1 - show_all); + fill_dev_list(NULL); +} + +void on_button_refresh_clicked(GtkWidget *widget, gpointer data) +{ + if (g_thread_run || ventoy_code_is_busy()) + { + msgbox(GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "STR_WAIT_PROCESS"); + return; + } + + ventoy_code_refresh_device(); + fill_dev_list(NULL); +} + +static void set_progress_bar_percent(int percent) +{ + char *pos = NULL; + const char *text = NULL; + char tmp[128]; + + gtk_progress_bar_set_fraction(g_progress_bar, percent * 1.0 / 100); + vlog("set percent %d\n", percent); + + text = language_string("STR_STATUS"); + if (percent == 0) + { + gtk_label_set_text(g_label_status, text); + } + else + { + g_snprintf(tmp, sizeof(tmp), "%s", text); + pos = strchr(tmp, '-'); + if (pos) + { + g_snprintf(pos + 2, sizeof(tmp), "%d%%", percent); + gtk_label_set_text(g_label_status, tmp); + } + } +} + +void on_clear_ventoy(GtkMenuItem *menuItem, gpointer data) +{ + int ret; + int active; + char buf[1024]; + char out[256]; + char disk_name[32]; + ventoy_disk *cur = NULL; + + if (g_thread_run || ventoy_code_is_busy()) + { + msgbox(GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "STR_WAIT_PROCESS"); + return; + } + + active = gtk_combo_box_get_active((GtkComboBox *)g_dev_combobox); + if (active < 0 || active >= g_disk_num) + { + vlog("invalid active combox id %d\n", active); + return; + } + + if (GTK_RESPONSE_OK != msgbox(GTK_MESSAGE_WARNING, GTK_BUTTONS_OK_CANCEL, "STR_INSTALL_TIP")) + { + return; + } + + if (GTK_RESPONSE_OK != msgbox(GTK_MESSAGE_WARNING, GTK_BUTTONS_OK_CANCEL, "STR_INSTALL_TIP2")) + { + return; + } + + gtk_widget_set_sensitive (GTK_WIDGET(g_refresh_button), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET(g_install_button), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET(g_update_button), FALSE); + g_thread_run = TRUE; + + + cur = g_disk_list + active; + g_snprintf(disk_name, sizeof(disk_name), "%s", cur->disk_name); + g_snprintf(buf, sizeof(buf), "{\"method\":\"clean\",\"disk\":\"%s\"}", disk_name); + + out[0] = 0; + ventoy_func_handler(buf, out, sizeof(out)); + vlog("func handler clean <%s>\n", out); + + if (strstr(out, "success")) + { + ret = ventoy_code_get_result(); + ventoy_code_refresh_device(); + cur = NULL; + } + else + { + ret = 1; + } + + if (ret == 0) + { + msgbox(GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "STR_CLEAR_SUCCESS"); + } + else + { + msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "STR_CLEAR_FAILED"); + } + + set_progress_bar_percent(0); + gtk_widget_set_sensitive(GTK_WIDGET(g_refresh_button), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(g_install_button), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(g_update_button), TRUE); + + fill_dev_list(disk_name); + g_thread_run = FALSE; +} + +static int install_proc(ventoy_disk *cur) +{ + int ret = 0; + int pos = 0; + int buflen = 0; + int percent = 0; + char buf[1024]; + char dec[64]; + char out[256]; + char disk_name[32]; + long long space; + + vlog("install_thread ...\n"); + + g_snprintf(disk_name, sizeof(disk_name), "%s", cur->disk_name); + + buflen = sizeof(buf); + VTOY_JSON_FMT_BEGIN(pos, buf, buflen); + VTOY_JSON_FMT_OBJ_BEGIN(); + VTOY_JSON_FMT_STRN("method", "install"); + VTOY_JSON_FMT_STRN("disk", disk_name); + + if (g_preserve_space_check) + { + space = g_preserve_space_number; + if (g_preserve_space_unit == 1) + { + space = space * 1024 * 1024 * 1024LL; + } + else + { + space = space * 1024 * 1024LL; + } + + snprintf(dec, sizeof(dec), "%lld", space); + VTOY_JSON_FMT_STRN("reserve_space", dec); + } + else + { + VTOY_JSON_FMT_STRN("reserve_space", "0"); + } + + VTOY_JSON_FMT_UINT("partstyle", ventoy_code_get_cur_part_style()); + VTOY_JSON_FMT_UINT("secure_boot", g_secure_boot_support); + VTOY_JSON_FMT_UINT("align_4kb", g_align_part_with_4k); + VTOY_JSON_FMT_OBJ_END(); + VTOY_JSON_FMT_END(pos); + + out[0] = 0; + ventoy_func_handler(buf, out, sizeof(out)); + vlog("func handler install <%s>\n", out); + + if (strstr(out, "success")) + { + while (percent != 100) + { + percent = ventoy_code_get_percent(); + set_progress_bar_percent(percent); + GTK_MSG_ITERATION(); + usleep(50 * 1000); + } + + ret = ventoy_code_get_result(); + ventoy_code_refresh_device(); + cur = NULL; + } + else + { + ret = 1; + } + + if (ret) + { + msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "STR_INSTALL_FAILED"); + } + else + { + msgbox(GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "STR_INSTALL_SUCCESS"); + } + + set_progress_bar_percent(0); + gtk_widget_set_sensitive(GTK_WIDGET(g_refresh_button), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(g_install_button), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(g_update_button), TRUE); + + fill_dev_list(disk_name); + g_thread_run = FALSE; + + return 0; +} + +void on_button_install_clicked(GtkWidget *widget, gpointer data) +{ + int active; + long long size; + long long space; + ventoy_disk *cur = NULL; + + if (g_thread_run || ventoy_code_is_busy()) + { + msgbox(GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "STR_WAIT_PROCESS"); + return; + } + + active = gtk_combo_box_get_active((GtkComboBox *)g_dev_combobox); + if (active < 0 || active >= g_disk_num) + { + vlog("invalid active combox id %d\n", active); + return; + } + + cur = g_disk_list + active; + + if (cur->is4kn) + { + msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "STR_4KN_UNSUPPORTED"); + return; + } + + if (ventoy_code_get_cur_part_style() == 0 && cur->size_in_byte > 2199023255552ULL) + { + msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "STR_DISK_2TB_MBR_ERROR"); + return; + } + + if (g_preserve_space_check) + { + space = g_preserve_space_number; + if (g_preserve_space_unit == 1) + { + space = space * 1024; + } + else + { + space = space; + } + + size = cur->size_in_byte / SIZE_1MB; + if (size <= space || (size - space) <= (VTOYEFI_PART_BYTES / SIZE_1MB)) + { + msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "STR_SPACE_VAL_INVALID"); + vlog("reserved space value too big ...\n"); + return; + } + } + + if (GTK_RESPONSE_OK != msgbox(GTK_MESSAGE_WARNING, GTK_BUTTONS_OK_CANCEL, "STR_INSTALL_TIP")) + { + return; + } + + if (GTK_RESPONSE_OK != msgbox(GTK_MESSAGE_WARNING, GTK_BUTTONS_OK_CANCEL, "STR_INSTALL_TIP2")) + { + return; + } + + gtk_widget_set_sensitive (GTK_WIDGET(g_refresh_button), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET(g_install_button), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET(g_update_button), FALSE); + + g_thread_run = TRUE; + + install_proc(cur); +} + + +static int update_proc(ventoy_disk *cur) +{ + int ret = 0; + int percent = 0; + char buf[1024]; + char out[256]; + char disk_name[32]; + + g_snprintf(disk_name, sizeof(disk_name), "%s", cur->disk_name); + g_snprintf(buf, sizeof(buf), "{\"method\":\"update\",\"disk\":\"%s\",\"secure_boot\":%d}", + disk_name, g_secure_boot_support); + + out[0] = 0; + ventoy_func_handler(buf, out, sizeof(out)); + vlog("func handler update <%s>\n", out); + + if (strstr(out, "success")) + { + while (percent != 100) + { + percent = ventoy_code_get_percent(); + set_progress_bar_percent(percent); + GTK_MSG_ITERATION(); + usleep(50 * 1000); + } + + ret = ventoy_code_get_result(); + ventoy_code_refresh_device(); + cur = NULL; + } + else + { + ret = 1; + } + + if (ret) + { + msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "STR_UPDATE_FAILED"); + } + else + { + msgbox(GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "STR_UPDATE_SUCCESS"); + } + + set_progress_bar_percent(0); + gtk_widget_set_sensitive(GTK_WIDGET(g_refresh_button), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(g_install_button), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(g_update_button), TRUE); + + fill_dev_list(disk_name); + g_thread_run = FALSE; + + return 0; +} + + +void on_button_update_clicked(GtkWidget *widget, gpointer data) +{ + int active; + ventoy_disk *cur = NULL; + + if (g_thread_run || ventoy_code_is_busy()) + { + msgbox(GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "STR_WAIT_PROCESS"); + return; + } + + active = gtk_combo_box_get_active((GtkComboBox *)g_dev_combobox); + if (active < 0 || active >= g_disk_num) + { + vlog("invalid active combox id %d\n", active); + return; + } + cur = g_disk_list + active; + + if (cur->vtoydata.ventoy_valid == 0) + { + vlog("invalid ventoy version.\n"); + return; + } + + if (GTK_RESPONSE_OK != msgbox(GTK_MESSAGE_INFO, GTK_BUTTONS_OK_CANCEL, "STR_UPDATE_TIP")) + { + return; + } + + gtk_widget_set_sensitive (GTK_WIDGET(g_refresh_button), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET(g_install_button), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET(g_update_button), FALSE); + + g_thread_run = TRUE; + + update_proc(cur); +} + +static gint lang_compare(gconstpointer a, gconstpointer b) +{ + const char *name1 = (const char *)a; + const char *name2 = (const char *)b; + + if (strncmp(name1, "Chinese Simplified", 18) == 0) + { + return -1; + } + else if (strncmp(name2, "Chinese Simplified", 18) == 0) + { + return 1; + } + else + { + return g_strcmp0(name1, name2); + } +} + +static int load_languages(void) +{ + int size = 0; + char *pBuf = NULL; + char *pCur = NULL; + const char *pCurLang = NULL; + const char *pName = NULL; + VTOY_JSON *json = NULL; + VTOY_JSON *node = NULL; + VTOY_JSON *lang = NULL; + GSList *pGroup = NULL; + GList *pNameNode = NULL; + GList *pNameList = NULL; + GtkRadioMenuItem *pItem = NULL; + + vlog("load_languages ...\n"); + + pCurLang = ventoy_code_get_cur_language(); + if (pCurLang[0] == 0) + { + pName = getenv("LANG"); + if (pName && strncmp(pName, "zh_CN", 5) == 0) + { + ventoy_code_set_cur_language("Chinese Simplified (简体中文)"); + } + else + { + ventoy_code_set_cur_language("English (English)"); + } + pCurLang = ventoy_code_get_cur_language(); + } + + vlog("current language <%s>\n", pCurLang); + + ventoy_read_file_to_buf("./tool/languages.json", 1, (void **)&pBuf, &size); + + json = vtoy_json_create(); + vtoy_json_parse(json, pBuf); + g_languages_json = json; + + for (node = json->pstChild; node; node = node->pstNext) + { + pName = vtoy_json_get_string_ex(node->pstChild, "name"); + if (pName) + { + pNameList = g_list_append(pNameList, (gpointer)pName); + } + + for (lang = node->pstChild; lang; lang = lang->pstNext) + { + if (lang->enDataType == JSON_TYPE_STRING) + { + pCur = lang->unData.pcStrVal; + while (*pCur) + { + if (*pCur == '#') + { + *pCur = '\r'; + } + else if (*pCur == '@') + { + *pCur = '\n'; + } + pCur++; + } + } + } + } + + pNameList = g_list_sort(pNameList, lang_compare); + + for (pNameNode = g_list_first(pNameList); pNameNode; pNameNode = g_list_next(pNameNode)) + { + pName = (char *)(pNameNode->data); + pItem = (GtkRadioMenuItem *)gtk_radio_menu_item_new_with_label(pGroup, pName); + pGroup = gtk_radio_menu_item_get_group(pItem); + + if (strcmp(pCurLang, pName) == 0) + { + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(pItem), TRUE); + } + + g_signal_connect(pItem, "toggled", G_CALLBACK(on_language_toggled), (gpointer)pName); + gtk_widget_show((GtkWidget *)pItem); + gtk_menu_shell_append(GTK_MENU_SHELL(g_lang_menu), (GtkWidget *)pItem); + } + + g_list_free(pNameList); + free(pBuf); + + select_language(pCurLang); + g_languages_toggled_proc = 1; + + return 0; +} + +void on_part_cfg_ok(GtkWidget *widget, gpointer data) +{ + const char *pos = NULL; + const char *input = NULL; + char device[256]; + gboolean checked = gtk_toggle_button_get_active(g_part_preserve_checkbox); + + if (checked) + { + input = gtk_entry_get_text(g_part_reserve_space_value); + if (input == NULL || input[0] == 0) + { + msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "STR_SPACE_VAL_INVALID"); + return; + } + + for (pos = input; *pos; pos++) + { + if (*pos < '0' || *pos > '9') + { + msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "STR_SPACE_VAL_INVALID"); + return; + } + } + + g_preserve_space_unit = gtk_combo_box_get_active((GtkComboBox *)g_part_space_unit_combox); + g_preserve_space_number = (int)strtol(input, NULL, 10); + + g_snprintf(device, sizeof(device), "%s [ -%d%s ]", + language_string("STR_DEVICE"), g_preserve_space_number, + g_preserve_space_unit ? "GB" : "MB"); + gtk_label_set_text(g_device_title, device); + } + else + { + gtk_label_set_text(g_device_title, language_string("STR_DEVICE")); + } + + g_preserve_space_check = checked; + g_align_part_with_4k = gtk_toggle_button_get_active(g_part_align_checkbox); + gtk_widget_hide(g_partCfgWindow); +} + +void on_part_cfg_cancel(GtkWidget *widget, gpointer data) +{ + gtk_widget_hide(g_partCfgWindow); +} + +int on_part_cfg_close(GtkWidget *widget, gpointer data) +{ + gtk_widget_hide(g_partCfgWindow); + return TRUE; +} + +void on_part_config(GtkMenuItem *menuItem, gpointer data) +{ + char value[64]; + + gtk_toggle_button_set_active(g_part_align_checkbox, g_align_part_with_4k); + gtk_toggle_button_set_active(g_part_preserve_checkbox, g_preserve_space_check); + gtk_widget_set_sensitive(GTK_WIDGET(g_part_reserve_space_value), g_preserve_space_check); + gtk_widget_set_sensitive(GTK_WIDGET(g_part_space_unit_combox), g_preserve_space_check); + + if (g_preserve_space_check) + { + g_snprintf(value, sizeof(value), "%d", g_preserve_space_number); + gtk_entry_set_text(g_part_reserve_space_value, value); + gtk_combo_box_set_active((GtkComboBox *)g_part_space_unit_combox, g_preserve_space_unit); + } + + gtk_widget_show_all(g_partCfgWindow); +} + +void on_reserve_space_toggled(GtkMenuItem *menuItem, gpointer data) +{ + gboolean checked = gtk_toggle_button_get_active(g_part_preserve_checkbox); + + gtk_widget_set_sensitive(GTK_WIDGET(g_part_reserve_space_value), checked); + gtk_widget_set_sensitive(GTK_WIDGET(g_part_space_unit_combox), checked); +} + +static void init_part_cfg_window(GtkBuilder *pBuilder) +{ +#if GTK_CHECK_VERSION(3, 0, 0) + GtkWidget *pHeader = NULL; + + pHeader = gtk_header_bar_new(); + gtk_header_bar_set_show_close_button(GTK_HEADER_BAR(pHeader), FALSE); + gtk_window_set_titlebar (GTK_WINDOW(g_partCfgWindow), pHeader); + gtk_window_set_title(GTK_WINDOW(g_partCfgWindow), "Partition Configuration"); +#endif + + gtk_combo_box_set_active((GtkComboBox *)g_part_space_unit_combox, g_preserve_space_unit); + gtk_widget_set_sensitive (GTK_WIDGET(g_part_reserve_space_value), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET(g_part_space_unit_combox), FALSE); + + SIGNAL("space_check_btn", "toggled", on_reserve_space_toggled); + + SIGNAL("button_partcfg_ok", "clicked", on_part_cfg_ok); + SIGNAL("button_partcfg_cancel", "clicked", on_part_cfg_cancel); + SIGNAL("part_cfg_dlg", "delete_event", on_part_cfg_close); +} + +static void add_accelerator(GtkAccelGroup *agMain, void *widget, const char *signal, guint accel_key) +{ + gtk_widget_add_accelerator(GTK_WIDGET(widget), signal, agMain, accel_key, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator(GTK_WIDGET(widget), signal, agMain, accel_key, GDK_SHIFT_MASK | GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE); +} + +void on_init_window(GtkBuilder *pBuilder) +{ + GSList *pGroup = NULL; + GtkAccelGroup *agMain = NULL; + char version[512]; + + vlog("on_init_window ...\n"); + + g_pXmlBuilder = pBuilder; + g_topWindow = BUILDER_ITEM(GtkWidget, "window"); + g_partCfgWindow = BUILDER_ITEM(GtkWidget, "part_cfg_dlg"); + + g_dev_combobox = BUILDER_ITEM(GtkComboBoxText, "combobox_devlist"); + g_refresh_button = BUILDER_ITEM(GtkButton, "button_refresh"); + g_install_button = BUILDER_ITEM(GtkButton, "button_install"); + g_update_button = BUILDER_ITEM(GtkButton, "button_update"); + + g_lang_menu = BUILDER_ITEM(GtkMenu, "submenu_language"); + g_menu_item_secure_boot = BUILDER_ITEM(GtkCheckMenuItem, "menu_item_secure"); + g_menu_item_mbr = BUILDER_ITEM(GtkCheckMenuItem, "menu_item_mbr"); + g_menu_item_gpt = BUILDER_ITEM(GtkCheckMenuItem, "menu_item_gpt"); + g_menu_item_show_all = BUILDER_ITEM(GtkCheckMenuItem, "menu_item_show_all"); + + g_device_title = BUILDER_ITEM(GtkLabel, "label_device"); + g_label_local_part_style = BUILDER_ITEM(GtkLabel, "label_local_part_style"); + g_label_dev_part_style = BUILDER_ITEM(GtkLabel, "label_dev_part_style"); + + g_label_local_ver = BUILDER_ITEM(GtkLabel, "label_local_ver_value"); + g_label_disk_ver = BUILDER_ITEM(GtkLabel, "label_dev_ver_value"); + + g_label_status = BUILDER_ITEM(GtkLabel, "label_status"); + + g_image_secure_local = BUILDER_ITEM(GtkImage, "image_secure_local"); + g_image_secure_device = BUILDER_ITEM(GtkImage, "image_secure_dev"); + + g_part_preserve_checkbox = BUILDER_ITEM(GtkToggleButton, "space_check_btn"); + g_part_align_checkbox = BUILDER_ITEM(GtkToggleButton, "space_align_btn"); + + g_part_reserve_space_value = BUILDER_ITEM(GtkEntry, "entry_reserve_space"); + g_part_space_unit_combox = BUILDER_ITEM(GtkComboBoxText, "comboboxtext_unit"); + + g_progress_bar = BUILDER_ITEM(GtkProgressBar, "progressbar1"); + + init_part_cfg_window(pBuilder); + + /* for gtk2 */ + gtk_frame_set_shadow_type(BUILDER_ITEM(GtkFrame, "frame_dummy1"), GTK_SHADOW_NONE); + gtk_frame_set_shadow_type(BUILDER_ITEM(GtkFrame, "frame_dummy2"), GTK_SHADOW_NONE); + + /* join group */ + pGroup = gtk_radio_menu_item_get_group((GtkRadioMenuItem *)g_menu_item_mbr); + gtk_radio_menu_item_set_group((GtkRadioMenuItem *)g_menu_item_gpt, pGroup); + + gtk_widget_hide((GtkWidget *)g_image_secure_local); + gtk_widget_hide((GtkWidget *)g_image_secure_device); + + g_snprintf(version, sizeof(version), VTOY_VER_FMT, ventoy_get_local_version()); + gtk_label_set_markup(g_label_local_ver, version); + + init_part_style_menu(); + gtk_check_menu_item_set_active(g_menu_item_show_all, ventoy_code_get_cur_show_all()); + + load_languages(); + + SIGNAL("combobox_devlist", "changed", on_devlist_changed); + + SIGNAL("button_refresh", "clicked", on_button_refresh_clicked); + SIGNAL("button_install", "clicked", on_button_install_clicked); + SIGNAL("button_update", "clicked", on_button_update_clicked); + + SIGNAL("menu_item_secure", "toggled", on_secure_boot_toggled); + SIGNAL("menu_item_mbr", "toggled", on_part_style_toggled); + SIGNAL("menu_item_show_all", "toggled", on_show_all_toggled); + + SIGNAL("menu_item_part_cfg", "activate", on_part_config); + SIGNAL("menu_item_clear", "activate", on_clear_ventoy); + + agMain = gtk_accel_group_new(); + gtk_window_add_accel_group(GTK_WINDOW(g_topWindow), agMain); + add_accelerator(agMain, g_dev_combobox, "popup", GDK_KEY_d); + add_accelerator(agMain, g_install_button, "clicked", GDK_KEY_i); + add_accelerator(agMain, g_update_button, "clicked", GDK_KEY_u); + add_accelerator(agMain, g_refresh_button, "clicked", GDK_KEY_r); + + gtk_check_menu_item_set_active(g_menu_item_secure_boot, 1 - g_secure_boot_support); + + fill_dev_list(NULL); + + return; +} + +int on_exit_window(GtkWidget *widget, gpointer data) +{ + vlog("on_exit_window ...\n"); + + if (g_thread_run || ventoy_code_is_busy()) + { + msgbox(GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "STR_WAIT_PROCESS"); + return TRUE; + } + + ventoy_code_save_cfg(); + return FALSE; +} + diff --git a/LinuxGUI/Ventoy2Disk/GTK/ventoy_gtk.h b/LinuxGUI/Ventoy2Disk/GTK/ventoy_gtk.h new file mode 100644 index 0000000..d3c5e5c --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/GTK/ventoy_gtk.h @@ -0,0 +1,70 @@ +/****************************************************************************** + * ventoy_gtk.h + * + * Copyright (c) 2021, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ +#ifndef __VENTOY_GTK_H__ +#define __VENTOY_GTK_H__ + +int ventoy_disk_init(void); +void ventoy_disk_exit(void); +int ventoy_http_init(void); +void ventoy_http_exit(void); +int ventoy_log_init(void); +void ventoy_log_exit(void); +void *get_refresh_icon_raw_data(int *len); +void *get_secure_icon_raw_data(int *len); +void *get_window_icon_raw_data(int *len); +int ventoy_func_handler(const char *jsonstr, char *jsonbuf, int buflen); +const char * ventoy_code_get_cur_language(void); +int ventoy_code_get_cur_part_style(void); +void ventoy_code_set_cur_part_style(int style); +int ventoy_code_get_cur_show_all(void); +void ventoy_code_set_cur_show_all(int show_all); +void ventoy_code_set_cur_language(const char *lang); +void ventoy_code_save_cfg(void); +void on_init_window(GtkBuilder *pBuilder); +int on_exit_window(GtkWidget *widget, gpointer data) ; +void ventoy_code_refresh_device(void); +int ventoy_code_is_busy(void); +int ventoy_code_get_percent(void); +int ventoy_code_get_result(void); +int msgbox(GtkMessageType type, GtkButtonsType buttons, const char *strid); + +#define VTOY_VER_FMT "%s" + +#define LANG_LABEL_TEXT(id, str) \ + gtk_label_set_text(BUILDER_ITEM(GtkLabel, id), vtoy_json_get_string_ex(node->pstChild, str)) + +#define LANG_BUTTON_TEXT(id, str) \ + gtk_button_set_label(BUILDER_ITEM(GtkButton, id), vtoy_json_get_string_ex(node->pstChild, str)) + +#define LANG_MENU_ITEM_TEXT(id, str) \ + gtk_menu_item_set_label(BUILDER_ITEM(GtkMenuItem, id), vtoy_json_get_string_ex(node->pstChild, str)) + +#define LANG_CHKBTN_TEXT(id, str) \ + gtk_check_button_set_label(BUILDER_ITEM(GtkCheckButton, id), vtoy_json_get_string_ex(node->pstChild, str)) + +#define BUILDER_ITEM(type, id) (type *)gtk_builder_get_object(g_pXmlBuilder, id) + +#define SIGNAL(id, act, func) \ + g_signal_connect(gtk_builder_get_object(g_pXmlBuilder, id), act, G_CALLBACK(func), NULL) + +#define GTK_MSG_ITERATION() while (gtk_events_pending ()) gtk_main_iteration() + +#endif /* __VENTOY_GTK_H__ */ + diff --git a/LinuxGUI/Ventoy2Disk/GTK/window_icon_data.c b/LinuxGUI/Ventoy2Disk/GTK/window_icon_data.c new file mode 100644 index 0000000..857be32 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/GTK/window_icon_data.c @@ -0,0 +1,7633 @@ +/****************************************************************************** + * window_icon_data.c + * + * Copyright (c) 2021, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include +#include + +static unsigned char window_icon_hexData[] = +{ + 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x68, 0x05, + 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x28, 0x08, + 0x01, 0x00, 0xCE, 0x05, 0x00, 0x00, 0x48, 0x48, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x88, 0x54, + 0x00, 0x00, 0xF6, 0x0D, 0x01, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x28, 0x42, + 0x00, 0x00, 0x7E, 0x62, 0x01, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xA8, 0x25, + 0x00, 0x00, 0xA6, 0xA4, 0x01, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xA8, 0x10, + 0x00, 0x00, 0x4E, 0xCA, 0x01, 0x00, 0x28, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x5E, 0x0E, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x69, 0x1E, + 0x00, 0x00, 0x6A, 0x23, 0x00, 0x00, 0x6A, 0x32, 0x0B, 0x00, 0x70, 0x37, 0x0F, 0x00, 0x74, 0x3A, + 0x0D, 0x00, 0x6C, 0x37, 0x13, 0x00, 0x7C, 0x41, 0x12, 0x00, 0x7E, 0x45, 0x18, 0x00, 0x78, 0x49, + 0x2A, 0x00, 0x7D, 0x4C, 0x28, 0x00, 0x7D, 0x4F, 0x30, 0x00, 0x80, 0x40, 0x05, 0x00, 0x81, 0x42, + 0x09, 0x00, 0x82, 0x44, 0x0B, 0x00, 0x86, 0x46, 0x0A, 0x00, 0x82, 0x44, 0x0C, 0x00, 0x84, 0x44, + 0x0E, 0x00, 0x88, 0x48, 0x0C, 0x00, 0x8C, 0x4E, 0x0E, 0x00, 0x90, 0x4F, 0x0E, 0x00, 0x84, 0x47, + 0x10, 0x00, 0x85, 0x49, 0x12, 0x00, 0x87, 0x4B, 0x14, 0x00, 0x87, 0x4C, 0x17, 0x00, 0x8A, 0x4C, + 0x13, 0x00, 0x81, 0x47, 0x18, 0x00, 0x87, 0x4D, 0x18, 0x00, 0x88, 0x4D, 0x18, 0x00, 0x84, 0x51, + 0x1F, 0x00, 0x8D, 0x53, 0x1E, 0x00, 0x94, 0x53, 0x13, 0x00, 0x96, 0x56, 0x13, 0x00, 0x91, 0x52, + 0x14, 0x00, 0x98, 0x57, 0x11, 0x00, 0x99, 0x58, 0x13, 0x00, 0x94, 0x5A, 0x1A, 0x00, 0xA1, 0x61, + 0x17, 0x00, 0xA1, 0x62, 0x1A, 0x00, 0xA4, 0x66, 0x1D, 0x00, 0x85, 0x4E, 0x21, 0x00, 0x81, 0x4F, + 0x2B, 0x00, 0x86, 0x50, 0x23, 0x00, 0x85, 0x53, 0x27, 0x00, 0x88, 0x51, 0x21, 0x00, 0x8A, 0x54, + 0x26, 0x00, 0x87, 0x54, 0x2B, 0x00, 0x89, 0x55, 0x2A, 0x00, 0x89, 0x56, 0x2C, 0x00, 0x80, 0x54, + 0x30, 0x00, 0x82, 0x55, 0x36, 0x00, 0x8D, 0x5B, 0x32, 0x00, 0x8A, 0x5A, 0x36, 0x00, 0x89, 0x5B, + 0x3A, 0x00, 0x91, 0x5D, 0x31, 0x00, 0x99, 0x60, 0x2B, 0x00, 0x8D, 0x62, 0x33, 0x00, 0x97, 0x63, + 0x37, 0x00, 0x98, 0x62, 0x30, 0x00, 0x9D, 0x69, 0x32, 0x00, 0x9E, 0x6D, 0x31, 0x00, 0x9A, 0x67, + 0x3A, 0x00, 0xA4, 0x69, 0x28, 0x00, 0xA9, 0x6C, 0x28, 0x00, 0xB1, 0x76, 0x2D, 0x00, 0xA7, 0x6D, + 0x34, 0x00, 0xA5, 0x72, 0x3E, 0x00, 0xB2, 0x78, 0x34, 0x00, 0xD1, 0x55, 0x00, 0x00, 0x94, 0x68, + 0x45, 0x00, 0x9D, 0x6F, 0x48, 0x00, 0x9E, 0x73, 0x4F, 0x00, 0x99, 0x79, 0x50, 0x00, 0xA2, 0x74, + 0x4B, 0x00, 0xA2, 0x76, 0x51, 0x00, 0x9B, 0x7F, 0x64, 0x00, 0xBA, 0x81, 0x3B, 0x00, 0xBF, 0x86, + 0x3B, 0x00, 0xBF, 0x87, 0x3D, 0x00, 0xE6, 0xA6, 0x3E, 0x00, 0xBB, 0x87, 0x4E, 0x00, 0xBB, 0x8B, + 0x49, 0x00, 0xAB, 0x84, 0x50, 0x00, 0xAA, 0x81, 0x5C, 0x00, 0xAD, 0x83, 0x5D, 0x00, 0xB8, 0x91, + 0x62, 0x00, 0xA8, 0x93, 0x73, 0x00, 0xB9, 0x96, 0x79, 0x00, 0xC2, 0x8D, 0x47, 0x00, 0xC2, 0x8F, + 0x4D, 0x00, 0xC9, 0x93, 0x4E, 0x00, 0xCC, 0x97, 0x4D, 0x00, 0xCE, 0x99, 0x50, 0x00, 0xC8, 0x9B, + 0x5F, 0x00, 0xCC, 0x9C, 0x64, 0x00, 0xC5, 0x9B, 0x6A, 0x00, 0xC1, 0x99, 0x6F, 0x00, 0xC7, 0xA4, + 0x6F, 0x00, 0xD2, 0xA2, 0x63, 0x00, 0xD9, 0xA7, 0x64, 0x00, 0xD9, 0xAA, 0x63, 0x00, 0xDC, 0xAC, + 0x65, 0x00, 0xD6, 0xAA, 0x6E, 0x00, 0xDA, 0xAD, 0x74, 0x00, 0xD9, 0xB0, 0x78, 0x00, 0xDC, 0xB2, + 0x7D, 0x00, 0xE6, 0xB9, 0x75, 0x00, 0xEA, 0xBB, 0x76, 0x00, 0xE0, 0xB7, 0x7C, 0x00, 0xE5, 0xBA, + 0x7E, 0x00, 0xEC, 0xBF, 0x78, 0x00, 0xE8, 0xBE, 0x7C, 0x00, 0xB6, 0x99, 0x85, 0x00, 0xB1, 0xA3, + 0x90, 0x00, 0xB7, 0xAB, 0x94, 0x00, 0xBB, 0xB1, 0xA3, 0x00, 0xC2, 0xA7, 0x83, 0x00, 0xC1, 0xA3, + 0x89, 0x00, 0xD3, 0xAD, 0x80, 0x00, 0xD9, 0xB5, 0x82, 0x00, 0xCB, 0xB0, 0x97, 0x00, 0xD5, 0xB6, + 0x95, 0x00, 0xDD, 0xBF, 0x99, 0x00, 0xE4, 0xBE, 0x8B, 0x00, 0xC9, 0xBE, 0xAB, 0x00, 0xC8, 0xBF, + 0xAE, 0x00, 0xD3, 0xBC, 0xA4, 0x00, 0xC5, 0xBF, 0xB4, 0x00, 0xE7, 0xC2, 0x87, 0x00, 0xE5, 0xC1, + 0x8B, 0x00, 0xE6, 0xC3, 0x8F, 0x00, 0xEF, 0xC8, 0x89, 0x00, 0xF0, 0xCB, 0x8B, 0x00, 0xF5, 0xCE, + 0x8C, 0x00, 0xE6, 0xC4, 0x91, 0x00, 0xE7, 0xC4, 0x95, 0x00, 0xEC, 0xC7, 0x90, 0x00, 0xEA, 0xC8, + 0x93, 0x00, 0xE6, 0xC9, 0x9D, 0x00, 0xEB, 0xCB, 0x99, 0x00, 0xEF, 0xCD, 0x99, 0x00, 0xEE, 0xCF, + 0x9C, 0x00, 0xF0, 0xCB, 0x91, 0x00, 0xF2, 0xD1, 0x99, 0x00, 0xF5, 0xD3, 0x98, 0x00, 0xF5, 0xD4, + 0x9A, 0x00, 0xF5, 0xD4, 0x9D, 0x00, 0xD5, 0xC4, 0xAD, 0x00, 0xDF, 0xC7, 0xA9, 0x00, 0xDE, 0xCB, + 0xA9, 0x00, 0xC8, 0xC0, 0xB3, 0x00, 0xC9, 0xC4, 0xB9, 0x00, 0xD0, 0xC5, 0xBC, 0x00, 0xE8, 0xCA, + 0xA1, 0x00, 0xE7, 0xD1, 0xAE, 0x00, 0xEE, 0xD6, 0xAE, 0x00, 0xF5, 0xD6, 0xA0, 0x00, 0xF0, 0xD3, + 0xA5, 0x00, 0xF0, 0xD4, 0xA6, 0x00, 0xF7, 0xD8, 0xA0, 0x00, 0xF9, 0xDB, 0xA7, 0x00, 0xF4, 0xD9, + 0xA9, 0x00, 0xF9, 0xDE, 0xAD, 0x00, 0xF1, 0xD8, 0xB0, 0x00, 0xF5, 0xDB, 0xB0, 0x00, 0xF6, 0xDF, + 0xB6, 0x00, 0xF4, 0xDF, 0xB9, 0x00, 0xF0, 0xDE, 0xBF, 0x00, 0xFB, 0xE1, 0xB3, 0x00, 0xF9, 0xE1, + 0xB6, 0x00, 0xF6, 0xE0, 0xB8, 0x00, 0xF6, 0xE1, 0xBE, 0x00, 0xFC, 0xE5, 0xBC, 0x00, 0xD2, 0xCD, + 0xC2, 0x00, 0xD6, 0xD3, 0xCD, 0x00, 0xD8, 0xD5, 0xCF, 0x00, 0xD7, 0xD6, 0xD5, 0x00, 0xD8, 0xD6, + 0xD2, 0x00, 0xDF, 0xDA, 0xD1, 0x00, 0xDE, 0xDB, 0xD4, 0x00, 0xDF, 0xDD, 0xD8, 0x00, 0xE0, 0xD4, + 0xC1, 0x00, 0xE0, 0xD8, 0xCE, 0x00, 0xE1, 0xDE, 0xDA, 0x00, 0xFA, 0xE5, 0xC1, 0x00, 0xFB, 0xE7, + 0xC4, 0x00, 0xF1, 0xE4, 0xCE, 0x00, 0xE1, 0xE0, 0xDE, 0x00, 0xEF, 0xE7, 0xDA, 0x00, 0xF1, 0xE8, + 0xD8, 0x00, 0xE6, 0xE6, 0xE6, 0x00, 0xE8, 0xE9, 0xE9, 0x00, 0xEE, 0xEE, 0xEC, 0x00, 0xFB, 0xF2, + 0xE1, 0x00, 0xF0, 0xF0, 0xEE, 0x00, 0xEF, 0xF0, 0xF0, 0x00, 0xF2, 0xF1, 0xF0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x0F, 0x0F, 0x0F, 0x0F, 0x13, 0x13, 0x13, 0x13, 0x13, 0x04, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x1A, 0x30, 0x33, 0x33, 0x30, 0x1A, 0x13, 0x0F, 0x13, 0x13, 0x1A, 0x0F, 0x1A, + 0x13, 0x1A, 0x30, 0x0D, 0x0D, 0x0D, 0x0E, 0x35, 0x38, 0x36, 0x1E, 0x13, 0x13, 0x1A, 0x02, 0x73, + 0x4C, 0x2C, 0x09, 0x06, 0x08, 0x0A, 0x1D, 0x2B, 0x31, 0x36, 0x48, 0x49, 0x01, 0x57, 0x7B, 0x00, + 0x36, 0x09, 0x31, 0x4E, 0x30, 0x13, 0x13, 0x16, 0x1C, 0x30, 0x39, 0x4A, 0x78, 0x5A, 0x49, 0x4D, + 0x1D, 0x30, 0x9B, 0xBE, 0x74, 0x3B, 0x16, 0x17, 0x17, 0x17, 0x22, 0x3E, 0x57, 0x40, 0x05, 0x3C, + 0x13, 0x3E, 0xB4, 0xC6, 0xC1, 0x76, 0x4B, 0x27, 0x26, 0x26, 0x26, 0x22, 0x45, 0x81, 0xC4, 0x3E, + 0x22, 0x2A, 0x58, 0xBA, 0xC1, 0xBE, 0x82, 0x59, 0x3E, 0x2A, 0x2A, 0x28, 0x42, 0x62, 0x7C, 0x44, + 0x42, 0x43, 0x43, 0x77, 0xB3, 0x99, 0xB0, 0x9B, 0x75, 0x55, 0x43, 0x43, 0x46, 0x62, 0x97, 0x53, + 0x4F, 0x4F, 0x5B, 0x60, 0x96, 0xB2, 0x7F, 0xB1, 0xB4, 0x7F, 0x54, 0x4F, 0x5B, 0x79, 0x03, 0x61, + 0x5E, 0x5F, 0x69, 0x6C, 0x7A, 0xB8, 0xB4, 0xBA, 0xC3, 0xB4, 0x64, 0x5F, 0x65, 0x7D, 0x6A, 0x6C, + 0x66, 0x66, 0x84, 0x8A, 0x84, 0x8D, 0xBF, 0xC7, 0xC7, 0xC7, 0x98, 0x66, 0x6F, 0x47, 0x8A, 0x9C, + 0x70, 0x6E, 0x8E, 0xA0, 0xA0, 0xA0, 0xA8, 0xA9, 0xBD, 0xC0, 0x83, 0x72, 0x8E, 0x8C, 0x7E, 0x8A, + 0x8E, 0x87, 0x95, 0xA8, 0xAE, 0xAE, 0xA8, 0xA8, 0xAE, 0xA8, 0x88, 0x95, 0x72, 0xFF, 0x9D, 0x6E, + 0x91, 0xA0, 0x95, 0xA5, 0xBC, 0xBC, 0xBC, 0xBC, 0xAB, 0xA4, 0x95, 0x52, 0xAE, 0x9D, 0x00, 0xA8, + 0x88, 0x95, 0xAB, 0xA3, 0xAB, 0xAF, 0xAF, 0xAF, 0xA5, 0xA5, 0x95, 0xAF, 0xA8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x45, 0x0C, 0x01, 0x83, 0x45, 0x0C, 0x01, 0x83, 0x45, + 0x0C, 0x01, 0x83, 0x45, 0x0C, 0x01, 0x83, 0x45, 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x02, 0x83, 0x45, + 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x03, 0x83, 0x45, 0x0C, 0x03, 0x83, 0x45, + 0x0C, 0x03, 0x83, 0x45, 0x0C, 0x03, 0x83, 0x45, 0x0C, 0x03, 0x83, 0x45, 0x0C, 0x04, 0x83, 0x45, + 0x0C, 0x05, 0x83, 0x45, 0x0C, 0x05, 0x83, 0x45, 0x0C, 0x05, 0x83, 0x45, 0x0C, 0x05, 0x83, 0x45, + 0x0C, 0x05, 0x83, 0x45, 0x0C, 0x06, 0x83, 0x45, 0x0C, 0x06, 0x83, 0x45, 0x0C, 0x07, 0x83, 0x45, + 0x0C, 0x07, 0x83, 0x45, 0x0C, 0x08, 0x83, 0x45, 0x0C, 0x09, 0x83, 0x45, 0x0C, 0x09, 0x83, 0x45, + 0x0C, 0x09, 0x83, 0x45, 0x0C, 0x09, 0x83, 0x45, 0x0C, 0x09, 0x83, 0x45, 0x0C, 0x0A, 0x83, 0x45, + 0x0C, 0x0A, 0x83, 0x45, 0x0C, 0x0A, 0x83, 0x45, 0x0C, 0x0A, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, + 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, + 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, + 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, + 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, + 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x0A, 0x83, 0x45, + 0x0C, 0x0A, 0x83, 0x45, 0x0C, 0x0A, 0x83, 0x45, 0x0C, 0x0A, 0x83, 0x45, 0x0C, 0x09, 0x83, 0x45, + 0x0C, 0x09, 0x83, 0x45, 0x0C, 0x08, 0x83, 0x45, 0x0C, 0x09, 0x83, 0x45, 0x0C, 0x08, 0x83, 0x45, + 0x0C, 0x08, 0x83, 0x45, 0x0C, 0x07, 0x83, 0x45, 0x0C, 0x07, 0x83, 0x45, 0x0C, 0x07, 0x83, 0x45, + 0x0C, 0x07, 0x83, 0x45, 0x0C, 0x07, 0x83, 0x45, 0x0C, 0x06, 0x83, 0x45, 0x0C, 0x05, 0x83, 0x45, + 0x0C, 0x05, 0x83, 0x45, 0x0C, 0x04, 0x83, 0x45, 0x0C, 0x04, 0x83, 0x45, 0x0C, 0x03, 0x83, 0x45, + 0x0C, 0x03, 0x83, 0x45, 0x0C, 0x03, 0x83, 0x45, 0x0C, 0x03, 0x83, 0x45, 0x0C, 0x03, 0x83, 0x45, + 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x02, 0x83, 0x45, + 0x0C, 0x01, 0x83, 0x45, 0x0C, 0x01, 0x83, 0x45, 0x0C, 0x01, 0x83, 0x45, 0x0C, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x45, 0x0C, 0x01, 0x83, 0x45, 0x0C, 0x01, 0x83, 0x45, + 0x0C, 0x01, 0x83, 0x45, 0x0C, 0x01, 0x83, 0x45, 0x0C, 0x01, 0x83, 0x45, 0x0C, 0x02, 0x83, 0x45, + 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x03, 0x83, 0x45, 0x0C, 0x03, 0x83, 0x45, + 0x0C, 0x03, 0x83, 0x45, 0x0C, 0x03, 0x83, 0x45, 0x0C, 0x04, 0x83, 0x45, 0x0C, 0x04, 0x83, 0x45, + 0x0C, 0x05, 0x83, 0x45, 0x0C, 0x05, 0x83, 0x45, 0x0C, 0x05, 0x83, 0x45, 0x0C, 0x05, 0x83, 0x45, + 0x0C, 0x06, 0x83, 0x45, 0x0C, 0x06, 0x83, 0x45, 0x0C, 0x07, 0x83, 0x45, 0x0C, 0x07, 0x83, 0x45, + 0x0C, 0x08, 0x83, 0x45, 0x0C, 0x09, 0x83, 0x45, 0x0C, 0x09, 0x83, 0x45, 0x0C, 0x09, 0x83, 0x45, + 0x0C, 0x09, 0x83, 0x45, 0x0C, 0x09, 0x83, 0x45, 0x0C, 0x0A, 0x83, 0x45, 0x0C, 0x0A, 0x83, 0x45, + 0x0C, 0x0A, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x0C, 0x83, 0x45, + 0x0C, 0x0C, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x0C, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, + 0x0C, 0x0C, 0x83, 0x45, 0x0C, 0x0C, 0x83, 0x45, 0x0C, 0x0C, 0x83, 0x45, 0x0C, 0x0C, 0x83, 0x45, + 0x0C, 0x0C, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x0C, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, + 0x0C, 0x0C, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, + 0x0C, 0x0C, 0x83, 0x45, 0x0C, 0x0C, 0x83, 0x45, 0x0C, 0x0C, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, + 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x0A, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x0A, 0x83, 0x45, + 0x0C, 0x0A, 0x83, 0x45, 0x0C, 0x09, 0x83, 0x45, 0x0C, 0x09, 0x83, 0x45, 0x0C, 0x09, 0x83, 0x45, + 0x0C, 0x09, 0x83, 0x45, 0x0C, 0x08, 0x83, 0x45, 0x0C, 0x08, 0x83, 0x45, 0x0C, 0x07, 0x83, 0x45, + 0x0C, 0x08, 0x83, 0x45, 0x0C, 0x07, 0x83, 0x45, 0x0C, 0x07, 0x83, 0x45, 0x0C, 0x06, 0x83, 0x45, + 0x0C, 0x06, 0x83, 0x45, 0x0C, 0x05, 0x83, 0x45, 0x0C, 0x05, 0x83, 0x45, 0x0C, 0x04, 0x83, 0x45, + 0x0C, 0x03, 0x83, 0x45, 0x0C, 0x03, 0x83, 0x45, 0x0C, 0x03, 0x83, 0x45, 0x0C, 0x03, 0x83, 0x45, + 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x02, 0x83, 0x45, + 0x0C, 0x01, 0x83, 0x45, 0x0C, 0x01, 0x83, 0x45, 0x0C, 0x01, 0x83, 0x45, 0x0C, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x45, 0x0C, 0x01, 0x83, 0x45, 0x0C, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x83, 0x45, 0x0C, 0x01, 0x83, 0x45, 0x0C, 0x01, 0x83, 0x45, 0x0C, 0x02, 0x83, 0x45, + 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x03, 0x83, 0x45, 0x0C, 0x04, 0x83, 0x45, + 0x0C, 0x04, 0x83, 0x45, 0x0C, 0x04, 0x83, 0x45, 0x0C, 0x05, 0x83, 0x45, 0x0C, 0x05, 0x83, 0x45, + 0x0C, 0x06, 0x83, 0x45, 0x0C, 0x07, 0x83, 0x45, 0x0C, 0x08, 0x83, 0x45, 0x0C, 0x09, 0x83, 0x45, + 0x0C, 0x09, 0x83, 0x45, 0x0C, 0x09, 0x83, 0x45, 0x0C, 0x0A, 0x83, 0x45, 0x0C, 0x0A, 0x83, 0x45, + 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x0C, 0x83, 0x45, 0x0C, 0x0C, 0x83, 0x45, 0x0C, 0x0D, 0x83, 0x45, + 0x0C, 0x0D, 0x83, 0x45, 0x0C, 0x0E, 0x83, 0x45, 0x0C, 0x0E, 0x83, 0x45, 0x0C, 0x0F, 0x83, 0x45, + 0x0C, 0x0F, 0x83, 0x45, 0x0C, 0x10, 0x83, 0x45, 0x0C, 0x10, 0x83, 0x45, 0x0C, 0x11, 0x83, 0x45, + 0x0C, 0x11, 0x83, 0x45, 0x0C, 0x12, 0x83, 0x45, 0x0C, 0x12, 0x83, 0x45, 0x0C, 0x12, 0x83, 0x45, + 0x0C, 0x12, 0x83, 0x45, 0x0C, 0x12, 0x83, 0x45, 0x0C, 0x12, 0x83, 0x45, 0x0C, 0x13, 0x83, 0x45, + 0x0C, 0x12, 0x83, 0x45, 0x0C, 0x13, 0x83, 0x45, 0x0C, 0x13, 0x83, 0x45, 0x0C, 0x14, 0x83, 0x45, + 0x0C, 0x13, 0x83, 0x45, 0x0C, 0x14, 0x83, 0x45, 0x0C, 0x14, 0x83, 0x45, 0x0C, 0x13, 0x83, 0x45, + 0x0C, 0x12, 0x83, 0x45, 0x0C, 0x12, 0x83, 0x45, 0x0C, 0x12, 0x83, 0x45, 0x0C, 0x12, 0x83, 0x45, + 0x0C, 0x12, 0x83, 0x45, 0x0C, 0x12, 0x83, 0x45, 0x0C, 0x12, 0x83, 0x45, 0x0C, 0x12, 0x83, 0x45, + 0x0C, 0x11, 0x83, 0x45, 0x0C, 0x11, 0x83, 0x45, 0x0C, 0x10, 0x83, 0x45, 0x0C, 0x10, 0x83, 0x45, + 0x0C, 0x10, 0x83, 0x45, 0x0C, 0x0F, 0x83, 0x45, 0x0C, 0x0F, 0x83, 0x45, 0x0C, 0x0F, 0x83, 0x45, + 0x0C, 0x0E, 0x83, 0x45, 0x0C, 0x0E, 0x83, 0x45, 0x0C, 0x0D, 0x83, 0x45, 0x0C, 0x0C, 0x83, 0x45, + 0x0C, 0x0C, 0x83, 0x45, 0x0C, 0x0C, 0x83, 0x45, 0x0C, 0x0C, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, + 0x0C, 0x0A, 0x83, 0x45, 0x0C, 0x09, 0x83, 0x45, 0x0C, 0x09, 0x83, 0x45, 0x0C, 0x08, 0x83, 0x45, + 0x0C, 0x07, 0x83, 0x45, 0x0C, 0x07, 0x83, 0x45, 0x0C, 0x06, 0x83, 0x45, 0x0C, 0x06, 0x83, 0x45, + 0x0C, 0x05, 0x83, 0x45, 0x0C, 0x04, 0x83, 0x45, 0x0C, 0x04, 0x83, 0x45, 0x0C, 0x03, 0x83, 0x45, + 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x03, 0x83, 0x45, + 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x01, 0x83, 0x45, 0x0C, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x45, 0x0C, 0x01, 0x83, 0x45, 0x0C, 0x02, 0x83, 0x45, + 0x0C, 0x01, 0x83, 0x45, 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x03, 0x83, 0x45, + 0x0C, 0x03, 0x83, 0x45, 0x0C, 0x05, 0x83, 0x45, 0x0C, 0x06, 0x83, 0x45, 0x0C, 0x08, 0x83, 0x45, + 0x0C, 0x08, 0x83, 0x45, 0x0C, 0x09, 0x83, 0x45, 0x0C, 0x09, 0x83, 0x45, 0x0C, 0x0A, 0x83, 0x45, + 0x0C, 0x0C, 0x83, 0x45, 0x0C, 0x0D, 0x83, 0x45, 0x0C, 0x0E, 0x83, 0x45, 0x0C, 0x0F, 0x83, 0x45, + 0x0C, 0x10, 0x83, 0x45, 0x0C, 0x10, 0x83, 0x45, 0x0C, 0x11, 0x83, 0x45, 0x0C, 0x12, 0x83, 0x45, + 0x0C, 0x13, 0x83, 0x45, 0x0C, 0x14, 0x83, 0x45, 0x0C, 0x14, 0x83, 0x45, 0x0C, 0x15, 0x83, 0x45, + 0x0C, 0x17, 0x83, 0x45, 0x0C, 0x17, 0x83, 0x45, 0x0C, 0x18, 0x83, 0x45, 0x0C, 0x19, 0x83, 0x45, + 0x0C, 0x19, 0x83, 0x45, 0x0C, 0x1A, 0x82, 0x45, 0x0C, 0x1A, 0x83, 0x45, 0x0C, 0x1B, 0x82, 0x45, + 0x0C, 0x1C, 0x83, 0x45, 0x0C, 0x1C, 0x83, 0x45, 0x0C, 0x1D, 0x83, 0x45, 0x0C, 0x1D, 0x83, 0x45, + 0x0C, 0x1D, 0x83, 0x45, 0x0C, 0x1D, 0x83, 0x45, 0x0C, 0x1E, 0x83, 0x45, 0x0C, 0x1E, 0x83, 0x45, + 0x0C, 0x1E, 0x83, 0x45, 0x0C, 0x1E, 0x83, 0x45, 0x0C, 0x1F, 0x83, 0x45, 0x0C, 0x1F, 0x83, 0x45, + 0x0C, 0x1F, 0x83, 0x45, 0x0C, 0x1F, 0x83, 0x45, 0x0C, 0x1F, 0x83, 0x45, 0x0C, 0x1F, 0x83, 0x45, + 0x0C, 0x1E, 0x83, 0x45, 0x0C, 0x1E, 0x83, 0x45, 0x0C, 0x1E, 0x83, 0x45, 0x0C, 0x1E, 0x83, 0x45, + 0x0C, 0x1D, 0x83, 0x45, 0x0C, 0x1C, 0x82, 0x45, 0x0C, 0x1C, 0x83, 0x45, 0x0C, 0x1C, 0x83, 0x45, + 0x0C, 0x1C, 0x83, 0x45, 0x0C, 0x1B, 0x83, 0x45, 0x0C, 0x1A, 0x83, 0x45, 0x0C, 0x1A, 0x83, 0x45, + 0x0C, 0x19, 0x83, 0x45, 0x0C, 0x18, 0x83, 0x45, 0x0C, 0x18, 0x83, 0x45, 0x0C, 0x17, 0x83, 0x45, + 0x0C, 0x17, 0x83, 0x45, 0x0C, 0x16, 0x83, 0x45, 0x0C, 0x15, 0x83, 0x45, 0x0C, 0x14, 0x83, 0x45, + 0x0C, 0x13, 0x83, 0x45, 0x0C, 0x12, 0x83, 0x45, 0x0C, 0x12, 0x83, 0x45, 0x0C, 0x11, 0x83, 0x45, + 0x0C, 0x10, 0x83, 0x45, 0x0C, 0x0F, 0x83, 0x45, 0x0C, 0x0E, 0x83, 0x45, 0x0C, 0x0E, 0x83, 0x45, + 0x0C, 0x0C, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x0A, 0x83, 0x45, + 0x0C, 0x09, 0x83, 0x45, 0x0C, 0x07, 0x83, 0x45, 0x0C, 0x07, 0x83, 0x45, 0x0C, 0x06, 0x83, 0x45, + 0x0C, 0x04, 0x83, 0x45, 0x0C, 0x04, 0x83, 0x45, 0x0C, 0x04, 0x83, 0x45, 0x0C, 0x04, 0x83, 0x45, + 0x0C, 0x03, 0x83, 0x45, 0x0C, 0x03, 0x83, 0x45, 0x0C, 0x01, 0x83, 0x45, 0x0C, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x45, 0x0C, 0x01, 0x83, 0x45, 0x0C, 0x01, 0x83, 0x45, + 0x0C, 0x01, 0x83, 0x45, 0x0C, 0x01, 0x83, 0x45, 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x02, 0x83, 0x45, + 0x0C, 0x03, 0x83, 0x45, 0x0C, 0x04, 0x83, 0x45, 0x0C, 0x05, 0x83, 0x45, 0x0C, 0x06, 0x83, 0x45, + 0x0C, 0x07, 0x83, 0x45, 0x0C, 0x08, 0x83, 0x45, 0x0C, 0x09, 0x83, 0x45, 0x0C, 0x0A, 0x83, 0x45, + 0x0C, 0x0C, 0x83, 0x45, 0x0C, 0x0D, 0x83, 0x45, 0x0C, 0x0E, 0x83, 0x45, 0x0C, 0x10, 0x83, 0x45, + 0x0C, 0x11, 0x83, 0x45, 0x0C, 0x12, 0x83, 0x45, 0x0C, 0x14, 0x83, 0x45, 0x0C, 0x15, 0x83, 0x45, + 0x0C, 0x16, 0x83, 0x45, 0x0C, 0x17, 0x83, 0x45, 0x0C, 0x18, 0x83, 0x45, 0x0C, 0x19, 0x83, 0x45, + 0x0C, 0x1B, 0x83, 0x45, 0x0C, 0x1C, 0x83, 0x45, 0x0C, 0x1D, 0x83, 0x45, 0x0C, 0x1F, 0x83, 0x45, + 0x0C, 0x20, 0x83, 0x45, 0x0C, 0x20, 0x83, 0x45, 0x0C, 0x20, 0x83, 0x45, 0x0C, 0x21, 0x83, 0x45, + 0x0C, 0x23, 0x83, 0x45, 0x0C, 0x24, 0x83, 0x45, 0x0C, 0x24, 0x83, 0x45, 0x0C, 0x25, 0x83, 0x45, + 0x0C, 0x25, 0x83, 0x45, 0x0C, 0x26, 0x83, 0x45, 0x0C, 0x26, 0x83, 0x45, 0x0C, 0x26, 0x83, 0x45, + 0x0C, 0x27, 0x83, 0x45, 0x0C, 0x27, 0x83, 0x45, 0x0C, 0x29, 0x83, 0x45, 0x0C, 0x29, 0x83, 0x45, + 0x0C, 0x29, 0x83, 0x45, 0x0C, 0x29, 0x83, 0x45, 0x0C, 0x29, 0x83, 0x45, 0x0C, 0x2A, 0x83, 0x45, + 0x0C, 0x29, 0x83, 0x45, 0x0C, 0x29, 0x83, 0x45, 0x0C, 0x2A, 0x83, 0x45, 0x0C, 0x2A, 0x83, 0x45, + 0x0C, 0x2A, 0x83, 0x45, 0x0C, 0x29, 0x83, 0x45, 0x0C, 0x29, 0x83, 0x45, 0x0C, 0x29, 0x83, 0x45, + 0x0C, 0x28, 0x83, 0x45, 0x0C, 0x28, 0x83, 0x45, 0x0C, 0x27, 0x83, 0x45, 0x0C, 0x27, 0x83, 0x45, + 0x0C, 0x27, 0x83, 0x45, 0x0C, 0x26, 0x83, 0x45, 0x0C, 0x25, 0x83, 0x45, 0x0C, 0x24, 0x83, 0x45, + 0x0C, 0x24, 0x83, 0x45, 0x0C, 0x23, 0x83, 0x45, 0x0C, 0x22, 0x83, 0x45, 0x0C, 0x21, 0x83, 0x45, + 0x0C, 0x21, 0x83, 0x45, 0x0C, 0x1F, 0x83, 0x45, 0x0C, 0x1F, 0x83, 0x45, 0x0C, 0x1E, 0x83, 0x45, + 0x0C, 0x1D, 0x83, 0x45, 0x0C, 0x1B, 0x83, 0x45, 0x0C, 0x1A, 0x83, 0x45, 0x0C, 0x19, 0x83, 0x45, + 0x0C, 0x18, 0x83, 0x45, 0x0C, 0x17, 0x83, 0x45, 0x0C, 0x14, 0x83, 0x45, 0x0C, 0x13, 0x83, 0x45, + 0x0C, 0x12, 0x83, 0x45, 0x0C, 0x11, 0x83, 0x45, 0x0C, 0x10, 0x83, 0x45, 0x0C, 0x0F, 0x83, 0x45, + 0x0C, 0x0D, 0x83, 0x45, 0x0C, 0x0C, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x0A, 0x83, 0x45, + 0x0C, 0x08, 0x83, 0x45, 0x0C, 0x07, 0x83, 0x45, 0x0C, 0x06, 0x83, 0x45, 0x0C, 0x06, 0x83, 0x45, + 0x0C, 0x05, 0x83, 0x45, 0x0C, 0x04, 0x83, 0x45, 0x0C, 0x03, 0x83, 0x45, 0x0C, 0x03, 0x83, 0x45, + 0x0C, 0x01, 0x83, 0x45, 0x0C, 0x01, 0x82, 0x45, 0x0C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x45, 0x0C, 0x01, 0x83, 0x45, 0x0C, 0x02, 0x83, 0x45, + 0x0C, 0x01, 0x83, 0x45, 0x0C, 0x02, 0x82, 0x45, 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x03, 0x83, 0x45, + 0x0C, 0x04, 0x83, 0x45, 0x0C, 0x06, 0x83, 0x45, 0x0C, 0x07, 0x83, 0x45, 0x0C, 0x08, 0x83, 0x45, + 0x0C, 0x0A, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x0C, 0x83, 0x45, 0x0C, 0x0D, 0x83, 0x45, + 0x0C, 0x0F, 0x83, 0x45, 0x0C, 0x11, 0x83, 0x45, 0x0C, 0x13, 0x83, 0x45, 0x0C, 0x15, 0x83, 0x45, + 0x0C, 0x17, 0x83, 0x45, 0x0C, 0x18, 0x83, 0x45, 0x0C, 0x1A, 0x83, 0x45, 0x0C, 0x1C, 0x83, 0x45, + 0x0C, 0x1E, 0x83, 0x45, 0x0C, 0x1F, 0x83, 0x45, 0x0C, 0x20, 0x83, 0x45, 0x0C, 0x22, 0x83, 0x45, + 0x0C, 0x23, 0x83, 0x45, 0x0C, 0x25, 0x82, 0x45, 0x0C, 0x27, 0x83, 0x45, 0x0C, 0x28, 0x82, 0x45, + 0x0C, 0x29, 0x83, 0x45, 0x0C, 0x29, 0x83, 0x45, 0x0C, 0x2A, 0x83, 0x45, 0x0C, 0x2B, 0x83, 0x45, + 0x0C, 0x2D, 0x83, 0x45, 0x0C, 0x2E, 0x83, 0x45, 0x0C, 0x2F, 0x83, 0x45, 0x0C, 0x2F, 0x83, 0x45, + 0x0C, 0x2F, 0x83, 0x45, 0x0C, 0x30, 0x83, 0x45, 0x0C, 0x31, 0x83, 0x45, 0x0C, 0x31, 0x83, 0x45, + 0x0C, 0x32, 0x83, 0x45, 0x0C, 0x32, 0x83, 0x45, 0x0C, 0x34, 0x83, 0x45, 0x0C, 0x34, 0x83, 0x45, + 0x0C, 0x34, 0x83, 0x45, 0x0C, 0x33, 0x83, 0x45, 0x0C, 0x34, 0x83, 0x45, 0x0C, 0x33, 0x83, 0x45, + 0x0C, 0x34, 0x83, 0x45, 0x0C, 0x33, 0x83, 0x45, 0x0C, 0x34, 0x83, 0x45, 0x0C, 0x33, 0x83, 0x45, + 0x0C, 0x34, 0x83, 0x45, 0x0C, 0x34, 0x82, 0x45, 0x0C, 0x34, 0x83, 0x45, 0x0C, 0x33, 0x82, 0x45, + 0x0C, 0x33, 0x83, 0x45, 0x0C, 0x32, 0x82, 0x45, 0x0C, 0x32, 0x83, 0x45, 0x0C, 0x31, 0x83, 0x45, + 0x0C, 0x31, 0x83, 0x45, 0x0C, 0x30, 0x83, 0x45, 0x0C, 0x2F, 0x83, 0x45, 0x0C, 0x2E, 0x83, 0x45, + 0x0C, 0x2D, 0x83, 0x45, 0x0C, 0x2D, 0x83, 0x45, 0x0C, 0x2C, 0x83, 0x45, 0x0C, 0x2B, 0x83, 0x45, + 0x0C, 0x2A, 0x83, 0x45, 0x0C, 0x29, 0x83, 0x45, 0x0C, 0x28, 0x83, 0x45, 0x0C, 0x27, 0x83, 0x45, + 0x0C, 0x26, 0x83, 0x45, 0x0C, 0x24, 0x83, 0x45, 0x0C, 0x22, 0x83, 0x45, 0x0C, 0x21, 0x83, 0x45, + 0x0C, 0x20, 0x83, 0x45, 0x0C, 0x1F, 0x83, 0x45, 0x0C, 0x1C, 0x83, 0x45, 0x0C, 0x19, 0x83, 0x45, + 0x0C, 0x18, 0x83, 0x45, 0x0C, 0x16, 0x83, 0x45, 0x0C, 0x15, 0x83, 0x45, 0x0C, 0x14, 0x83, 0x45, + 0x0C, 0x12, 0x83, 0x45, 0x0C, 0x10, 0x83, 0x45, 0x0C, 0x0F, 0x83, 0x45, 0x0C, 0x0D, 0x83, 0x45, + 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x0A, 0x83, 0x45, 0x0C, 0x09, 0x83, 0x45, 0x0C, 0x07, 0x83, 0x45, + 0x0C, 0x06, 0x83, 0x45, 0x0C, 0x05, 0x83, 0x45, 0x0C, 0x04, 0x83, 0x45, 0x0C, 0x03, 0x82, 0x45, + 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x01, 0x82, 0x45, 0x0C, 0x01, 0x82, 0x45, 0x0C, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x45, + 0x0C, 0x01, 0x83, 0x45, 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x03, 0x83, 0x45, + 0x0C, 0x03, 0x83, 0x45, 0x0C, 0x03, 0x83, 0x45, 0x0C, 0x05, 0x83, 0x45, 0x0C, 0x06, 0x83, 0x45, + 0x0C, 0x08, 0x83, 0x45, 0x0C, 0x09, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x0D, 0x83, 0x45, + 0x0C, 0x0F, 0x83, 0x45, 0x0C, 0x11, 0x83, 0x45, 0x0C, 0x13, 0x83, 0x45, 0x0C, 0x15, 0x83, 0x45, + 0x0C, 0x18, 0x83, 0x45, 0x0C, 0x1A, 0x83, 0x45, 0x0C, 0x1C, 0x83, 0x45, 0x0C, 0x1E, 0x83, 0x45, + 0x0C, 0x21, 0x83, 0x45, 0x0C, 0x23, 0x83, 0x45, 0x0C, 0x26, 0x83, 0x45, 0x0C, 0x28, 0x83, 0x45, + 0x0C, 0x2A, 0x83, 0x45, 0x0C, 0x2C, 0x83, 0x45, 0x0C, 0x2E, 0x83, 0x45, 0x0C, 0x30, 0x83, 0x45, + 0x0C, 0x31, 0x83, 0x45, 0x0C, 0x32, 0x83, 0x45, 0x0C, 0x33, 0x83, 0x45, 0x0C, 0x35, 0x83, 0x45, + 0x0C, 0x36, 0x83, 0x45, 0x0C, 0x37, 0x83, 0x45, 0x0C, 0x39, 0x83, 0x45, 0x0C, 0x3A, 0x83, 0x45, + 0x0C, 0x3B, 0x83, 0x45, 0x0C, 0x3C, 0x83, 0x45, 0x0C, 0x3C, 0x83, 0x45, 0x0C, 0x3D, 0x83, 0x45, + 0x0C, 0x3E, 0x83, 0x45, 0x0C, 0x3F, 0x83, 0x45, 0x0C, 0x40, 0x83, 0x45, 0x0C, 0x40, 0x83, 0x45, + 0x0C, 0x41, 0x83, 0x45, 0x0C, 0x41, 0x83, 0x45, 0x0C, 0x43, 0x83, 0x45, 0x0C, 0x43, 0x83, 0x45, + 0x0C, 0x43, 0x83, 0x45, 0x0C, 0x43, 0x83, 0x45, 0x0C, 0x43, 0x83, 0x45, 0x0C, 0x43, 0x83, 0x45, + 0x0C, 0x43, 0x83, 0x45, 0x0C, 0x43, 0x83, 0x45, 0x0C, 0x43, 0x83, 0x45, 0x0C, 0x43, 0x83, 0x45, + 0x0C, 0x43, 0x83, 0x45, 0x0C, 0x43, 0x83, 0x45, 0x0C, 0x43, 0x83, 0x45, 0x0C, 0x43, 0x83, 0x45, + 0x0C, 0x42, 0x83, 0x45, 0x0C, 0x41, 0x83, 0x45, 0x0C, 0x40, 0x83, 0x45, 0x0C, 0x3F, 0x83, 0x45, + 0x0C, 0x3F, 0x83, 0x45, 0x0C, 0x3E, 0x83, 0x45, 0x0C, 0x3D, 0x83, 0x45, 0x0C, 0x3C, 0x83, 0x45, + 0x0C, 0x3B, 0x83, 0x45, 0x0C, 0x3A, 0x83, 0x45, 0x0C, 0x39, 0x83, 0x45, 0x0C, 0x38, 0x83, 0x45, + 0x0C, 0x37, 0x83, 0x45, 0x0C, 0x36, 0x83, 0x45, 0x0C, 0x34, 0x83, 0x45, 0x0C, 0x32, 0x83, 0x45, + 0x0C, 0x31, 0x83, 0x45, 0x0C, 0x30, 0x83, 0x45, 0x0C, 0x2E, 0x83, 0x45, 0x0C, 0x2D, 0x83, 0x45, + 0x0C, 0x2C, 0x83, 0x45, 0x0C, 0x2A, 0x83, 0x45, 0x0C, 0x27, 0x83, 0x45, 0x0C, 0x26, 0x83, 0x45, + 0x0C, 0x24, 0x83, 0x45, 0x0C, 0x22, 0x83, 0x45, 0x0C, 0x1F, 0x83, 0x45, 0x0C, 0x1D, 0x83, 0x45, + 0x0C, 0x1B, 0x83, 0x45, 0x0C, 0x19, 0x83, 0x45, 0x0C, 0x16, 0x83, 0x45, 0x0C, 0x14, 0x83, 0x45, + 0x0C, 0x11, 0x83, 0x45, 0x0C, 0x0F, 0x83, 0x45, 0x0C, 0x0E, 0x83, 0x45, 0x0C, 0x0C, 0x83, 0x45, + 0x0C, 0x09, 0x83, 0x45, 0x0C, 0x08, 0x83, 0x45, 0x0C, 0x06, 0x83, 0x45, 0x0C, 0x04, 0x83, 0x45, + 0x0C, 0x03, 0x83, 0x45, 0x0C, 0x03, 0x82, 0x45, 0x0C, 0x02, 0x82, 0x45, 0x0C, 0x02, 0x82, 0x44, + 0x0C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x45, + 0x0C, 0x01, 0x83, 0x45, 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x03, 0x83, 0x45, + 0x0C, 0x03, 0x83, 0x45, 0x0C, 0x05, 0x83, 0x45, 0x0C, 0x06, 0x83, 0x45, 0x0C, 0x08, 0x83, 0x45, + 0x0C, 0x0A, 0x83, 0x45, 0x0C, 0x0C, 0x83, 0x45, 0x0C, 0x0E, 0x83, 0x45, 0x0C, 0x11, 0x83, 0x45, + 0x0C, 0x15, 0x83, 0x45, 0x0C, 0x18, 0x83, 0x45, 0x0C, 0x1B, 0x83, 0x45, 0x0C, 0x1E, 0x83, 0x45, + 0x0C, 0x20, 0x83, 0x45, 0x0C, 0x23, 0x83, 0x45, 0x0C, 0x26, 0x83, 0x45, 0x0C, 0x29, 0x83, 0x45, + 0x0C, 0x2C, 0x83, 0x45, 0x0C, 0x2F, 0x83, 0x45, 0x0C, 0x31, 0x83, 0x45, 0x0C, 0x33, 0x82, 0x45, + 0x0C, 0x35, 0x83, 0x45, 0x0C, 0x37, 0x82, 0x45, 0x0C, 0x39, 0x83, 0x45, 0x0C, 0x3B, 0x83, 0x45, + 0x0C, 0x3D, 0x83, 0x45, 0x0C, 0x3E, 0x83, 0x45, 0x0C, 0x40, 0x83, 0x45, 0x0C, 0x42, 0x83, 0x45, + 0x0C, 0x44, 0x83, 0x45, 0x0C, 0x45, 0x83, 0x45, 0x0C, 0x46, 0x83, 0x45, 0x0C, 0x48, 0x83, 0x45, + 0x0C, 0x49, 0x83, 0x45, 0x0C, 0x4A, 0x83, 0x45, 0x0C, 0x4B, 0x83, 0x45, 0x0C, 0x4C, 0x83, 0x45, + 0x0C, 0x4D, 0x83, 0x45, 0x0C, 0x4E, 0x82, 0x45, 0x0C, 0x4F, 0x83, 0x45, 0x0C, 0x4F, 0x82, 0x45, + 0x0C, 0x4F, 0x83, 0x45, 0x0C, 0x50, 0x82, 0x45, 0x0C, 0x51, 0x83, 0x45, 0x0C, 0x51, 0x82, 0x45, + 0x0C, 0x51, 0x82, 0x45, 0x0C, 0x51, 0x82, 0x45, 0x0C, 0x51, 0x83, 0x45, 0x0C, 0x51, 0x82, 0x45, + 0x0C, 0x52, 0x83, 0x45, 0x0C, 0x52, 0x82, 0x45, 0x0C, 0x52, 0x83, 0x45, 0x0C, 0x51, 0x82, 0x45, + 0x0C, 0x52, 0x83, 0x45, 0x0C, 0x52, 0x82, 0x45, 0x0C, 0x53, 0x83, 0x45, 0x0C, 0x52, 0x82, 0x45, + 0x0C, 0x52, 0x83, 0x45, 0x0C, 0x50, 0x82, 0x45, 0x0C, 0x50, 0x83, 0x45, 0x0C, 0x4E, 0x82, 0x45, + 0x0C, 0x4E, 0x83, 0x45, 0x0C, 0x4D, 0x82, 0x45, 0x0C, 0x4D, 0x83, 0x45, 0x0C, 0x4B, 0x82, 0x45, + 0x0C, 0x4A, 0x83, 0x45, 0x0C, 0x49, 0x82, 0x45, 0x0C, 0x48, 0x83, 0x45, 0x0C, 0x47, 0x82, 0x45, + 0x0C, 0x46, 0x83, 0x45, 0x0C, 0x45, 0x82, 0x45, 0x0C, 0x43, 0x83, 0x45, 0x0C, 0x40, 0x83, 0x45, + 0x0C, 0x3F, 0x83, 0x45, 0x0C, 0x3D, 0x83, 0x45, 0x0C, 0x3C, 0x83, 0x45, 0x0C, 0x3A, 0x83, 0x45, + 0x0C, 0x39, 0x83, 0x45, 0x0C, 0x36, 0x83, 0x45, 0x0C, 0x34, 0x83, 0x45, 0x0C, 0x31, 0x83, 0x45, + 0x0C, 0x2F, 0x83, 0x45, 0x0C, 0x2D, 0x83, 0x45, 0x0C, 0x2B, 0x83, 0x45, 0x0C, 0x27, 0x83, 0x45, + 0x0C, 0x24, 0x83, 0x45, 0x0C, 0x22, 0x83, 0x45, 0x0C, 0x1F, 0x83, 0x45, 0x0C, 0x1B, 0x83, 0x45, + 0x0C, 0x17, 0x83, 0x45, 0x0C, 0x14, 0x83, 0x45, 0x0C, 0x12, 0x83, 0x45, 0x0C, 0x10, 0x83, 0x45, + 0x0C, 0x0D, 0x83, 0x45, 0x0C, 0x0A, 0x82, 0x45, 0x0C, 0x08, 0x83, 0x45, 0x0C, 0x06, 0x83, 0x45, + 0x0C, 0x04, 0x83, 0x45, 0x0C, 0x03, 0x82, 0x45, 0x0C, 0x03, 0x82, 0x44, 0x0C, 0x02, 0x82, 0x44, + 0x0C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x45, + 0x0C, 0x01, 0x83, 0x45, 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x03, 0x83, 0x45, + 0x0C, 0x05, 0x83, 0x45, 0x0C, 0x07, 0x83, 0x45, 0x0C, 0x09, 0x83, 0x45, 0x0C, 0x0C, 0x83, 0x45, + 0x0C, 0x0E, 0x83, 0x45, 0x0C, 0x11, 0x83, 0x45, 0x0C, 0x15, 0x83, 0x45, 0x0C, 0x19, 0x83, 0x45, + 0x0C, 0x1D, 0x83, 0x45, 0x0C, 0x21, 0x83, 0x45, 0x0C, 0x24, 0x83, 0x45, 0x0C, 0x28, 0x83, 0x45, + 0x0C, 0x2C, 0x83, 0x45, 0x0C, 0x30, 0x83, 0x45, 0x0C, 0x33, 0x83, 0x45, 0x0C, 0x37, 0x83, 0x45, + 0x0C, 0x3A, 0x83, 0x45, 0x0C, 0x3C, 0x83, 0x45, 0x0C, 0x3F, 0x83, 0x45, 0x0C, 0x42, 0x83, 0x45, + 0x0C, 0x44, 0x83, 0x45, 0x0C, 0x46, 0x83, 0x45, 0x0C, 0x49, 0x83, 0x45, 0x0C, 0x4B, 0x83, 0x45, + 0x0C, 0x4D, 0x83, 0x45, 0x0C, 0x4F, 0x83, 0x45, 0x0C, 0x51, 0x83, 0x45, 0x0C, 0x53, 0x83, 0x45, + 0x0C, 0x54, 0x83, 0x45, 0x0C, 0x55, 0x83, 0x45, 0x0D, 0x57, 0x83, 0x45, 0x0C, 0x59, 0x83, 0x45, + 0x0C, 0x59, 0x83, 0x45, 0x0C, 0x5A, 0x83, 0x45, 0x0C, 0x5C, 0x83, 0x45, 0x0C, 0x5D, 0x83, 0x45, + 0x0C, 0x5E, 0x83, 0x45, 0x0C, 0x5F, 0x82, 0x45, 0x0C, 0x5F, 0x83, 0x45, 0x0C, 0x5F, 0x82, 0x45, + 0x0C, 0x60, 0x82, 0x45, 0x0C, 0x60, 0x82, 0x45, 0x0C, 0x61, 0x82, 0x45, 0x0C, 0x61, 0x82, 0x45, + 0x0C, 0x61, 0x82, 0x44, 0x0C, 0x61, 0x82, 0x45, 0x0C, 0x61, 0x82, 0x45, 0x0C, 0x61, 0x82, 0x45, + 0x0C, 0x61, 0x82, 0x45, 0x0C, 0x62, 0x82, 0x45, 0x0C, 0x62, 0x83, 0x45, 0x0C, 0x61, 0x82, 0x45, + 0x0C, 0x61, 0x83, 0x45, 0x0C, 0x61, 0x83, 0x45, 0x0C, 0x62, 0x83, 0x45, 0x0C, 0x62, 0x83, 0x45, + 0x0C, 0x62, 0x83, 0x45, 0x0C, 0x61, 0x83, 0x45, 0x0C, 0x60, 0x83, 0x45, 0x0C, 0x5F, 0x83, 0x45, + 0x0C, 0x5E, 0x83, 0x45, 0x0C, 0x5E, 0x82, 0x45, 0x0C, 0x5D, 0x83, 0x45, 0x0C, 0x5C, 0x82, 0x45, + 0x0C, 0x5B, 0x83, 0x45, 0x0C, 0x5A, 0x82, 0x45, 0x0C, 0x59, 0x83, 0x45, 0x0C, 0x58, 0x82, 0x45, + 0x0C, 0x56, 0x83, 0x45, 0x0C, 0x54, 0x83, 0x45, 0x0C, 0x52, 0x83, 0x45, 0x0C, 0x50, 0x83, 0x45, + 0x0C, 0x4E, 0x83, 0x45, 0x0C, 0x4C, 0x83, 0x45, 0x0C, 0x4A, 0x83, 0x45, 0x0C, 0x48, 0x83, 0x45, + 0x0C, 0x46, 0x83, 0x45, 0x0C, 0x44, 0x83, 0x45, 0x0C, 0x41, 0x83, 0x45, 0x0C, 0x3F, 0x83, 0x45, + 0x0C, 0x3C, 0x83, 0x45, 0x0C, 0x39, 0x83, 0x45, 0x0C, 0x37, 0x83, 0x45, 0x0C, 0x34, 0x83, 0x45, + 0x0C, 0x2F, 0x83, 0x45, 0x0C, 0x2C, 0x83, 0x45, 0x0C, 0x2A, 0x83, 0x45, 0x0C, 0x26, 0x83, 0x45, + 0x0C, 0x21, 0x83, 0x45, 0x0C, 0x1E, 0x83, 0x45, 0x0C, 0x1A, 0x83, 0x45, 0x0C, 0x16, 0x83, 0x45, + 0x0C, 0x12, 0x83, 0x45, 0x0C, 0x0F, 0x83, 0x45, 0x0C, 0x0D, 0x83, 0x45, 0x0C, 0x0A, 0x83, 0x45, + 0x0C, 0x07, 0x83, 0x45, 0x0C, 0x05, 0x83, 0x45, 0x0C, 0x03, 0x82, 0x44, 0x0C, 0x02, 0x81, 0x44, + 0x0B, 0x02, 0x81, 0x44, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x45, + 0x0C, 0x01, 0x83, 0x45, 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x03, 0x83, 0x45, 0x0C, 0x04, 0x83, 0x45, + 0x0C, 0x07, 0x83, 0x45, 0x0C, 0x09, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x0E, 0x83, 0x45, + 0x0C, 0x12, 0x83, 0x45, 0x0C, 0x17, 0x83, 0x45, 0x0C, 0x1C, 0x83, 0x45, 0x0C, 0x21, 0x83, 0x45, + 0x0C, 0x25, 0x83, 0x45, 0x0C, 0x29, 0x83, 0x45, 0x0C, 0x2E, 0x83, 0x45, 0x0C, 0x32, 0x83, 0x45, + 0x0C, 0x37, 0x83, 0x45, 0x0C, 0x3B, 0x82, 0x45, 0x0C, 0x40, 0x83, 0x45, 0x0C, 0x43, 0x82, 0x45, + 0x0C, 0x46, 0x83, 0x45, 0x0C, 0x49, 0x83, 0x45, 0x0C, 0x4D, 0x83, 0x45, 0x0C, 0x4F, 0x83, 0x45, + 0x0C, 0x52, 0x83, 0x45, 0x0C, 0x54, 0x83, 0x45, 0x0C, 0x57, 0x83, 0x45, 0x0C, 0x5A, 0x83, 0x45, + 0x0C, 0x5C, 0x83, 0x45, 0x0C, 0x5E, 0x83, 0x45, 0x0C, 0x60, 0x83, 0x45, 0x0C, 0x62, 0x83, 0x45, + 0x0C, 0x63, 0x83, 0x45, 0x0C, 0x65, 0x82, 0x45, 0x0C, 0x66, 0x83, 0x45, 0x0C, 0x67, 0x82, 0x45, + 0x0C, 0x68, 0x83, 0x45, 0x0C, 0x69, 0x82, 0x45, 0x0C, 0x6B, 0x83, 0x45, 0x0C, 0x6C, 0x82, 0x45, + 0x0C, 0x6D, 0x83, 0x45, 0x0C, 0x6E, 0x83, 0x45, 0x0C, 0x6E, 0x83, 0x45, 0x0C, 0x6F, 0x83, 0x45, + 0x0C, 0x70, 0x83, 0x45, 0x0C, 0x71, 0x82, 0x45, 0x0C, 0x72, 0x83, 0x44, 0x0C, 0x72, 0x82, 0x45, + 0x0C, 0x72, 0x83, 0x44, 0x0C, 0x72, 0x82, 0x45, 0x0C, 0x72, 0x83, 0x44, 0x0C, 0x72, 0x82, 0x45, + 0x0C, 0x73, 0x83, 0x45, 0x0C, 0x73, 0x83, 0x45, 0x0C, 0x73, 0x83, 0x45, 0x0C, 0x73, 0x83, 0x45, + 0x0C, 0x72, 0x83, 0x45, 0x0C, 0x71, 0x83, 0x45, 0x0C, 0x72, 0x83, 0x45, 0x0C, 0x71, 0x83, 0x45, + 0x0C, 0x71, 0x83, 0x45, 0x0C, 0x6F, 0x83, 0x45, 0x0C, 0x6F, 0x83, 0x45, 0x0C, 0x6E, 0x82, 0x45, + 0x0C, 0x6E, 0x83, 0x45, 0x0C, 0x6D, 0x82, 0x45, 0x0C, 0x6C, 0x83, 0x45, 0x0C, 0x6B, 0x82, 0x45, + 0x0C, 0x6A, 0x83, 0x45, 0x0C, 0x69, 0x82, 0x45, 0x0C, 0x68, 0x83, 0x45, 0x0C, 0x67, 0x82, 0x45, + 0x0C, 0x66, 0x83, 0x45, 0x0C, 0x64, 0x82, 0x45, 0x0C, 0x62, 0x83, 0x45, 0x0C, 0x60, 0x82, 0x45, + 0x0C, 0x5E, 0x83, 0x45, 0x0C, 0x5C, 0x82, 0x45, 0x0C, 0x5A, 0x83, 0x45, 0x0C, 0x57, 0x82, 0x45, + 0x0C, 0x56, 0x83, 0x45, 0x0C, 0x53, 0x83, 0x45, 0x0C, 0x51, 0x83, 0x45, 0x0C, 0x4E, 0x83, 0x45, + 0x0C, 0x4B, 0x83, 0x45, 0x0C, 0x48, 0x83, 0x45, 0x0C, 0x45, 0x83, 0x45, 0x0C, 0x41, 0x83, 0x45, + 0x0C, 0x3D, 0x83, 0x45, 0x0C, 0x38, 0x83, 0x45, 0x0C, 0x35, 0x83, 0x45, 0x0C, 0x31, 0x83, 0x45, + 0x0C, 0x2B, 0x83, 0x45, 0x0C, 0x27, 0x83, 0x45, 0x0C, 0x22, 0x83, 0x45, 0x0C, 0x1D, 0x83, 0x45, + 0x0C, 0x18, 0x83, 0x45, 0x0C, 0x13, 0x82, 0x45, 0x0C, 0x10, 0x83, 0x45, 0x0C, 0x0D, 0x83, 0x45, + 0x0C, 0x0A, 0x83, 0x45, 0x0C, 0x07, 0x83, 0x45, 0x0C, 0x04, 0x83, 0x45, 0x0B, 0x03, 0x81, 0x44, + 0x0A, 0x03, 0x82, 0x44, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x43, 0x09, 0x01, 0x82, 0x44, 0x0A, 0x01, 0x83, 0x45, + 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x03, 0x83, 0x45, 0x0C, 0x04, 0x83, 0x45, 0x0C, 0x07, 0x83, 0x45, + 0x0C, 0x09, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x0E, 0x83, 0x45, 0x0C, 0x13, 0x83, 0x45, + 0x0C, 0x18, 0x83, 0x45, 0x0C, 0x1E, 0x83, 0x45, 0x0C, 0x24, 0x83, 0x45, 0x0C, 0x29, 0x83, 0x45, + 0x0C, 0x2F, 0x83, 0x45, 0x0C, 0x35, 0x83, 0x45, 0x0C, 0x3B, 0x83, 0x45, 0x0C, 0x40, 0x83, 0x45, + 0x0C, 0x46, 0x83, 0x45, 0x0C, 0x4A, 0x83, 0x45, 0x0C, 0x4F, 0x83, 0x45, 0x0C, 0x53, 0x83, 0x45, + 0x0C, 0x57, 0x83, 0x45, 0x0C, 0x5A, 0x83, 0x45, 0x0C, 0x5D, 0x83, 0x45, 0x0C, 0x60, 0x83, 0x45, + 0x0C, 0x63, 0x83, 0x45, 0x0C, 0x65, 0x83, 0x45, 0x0C, 0x68, 0x83, 0x45, 0x0C, 0x6A, 0x83, 0x45, + 0x0D, 0x6D, 0x83, 0x45, 0x0C, 0x6F, 0x83, 0x45, 0x0C, 0x71, 0x83, 0x45, 0x0C, 0x73, 0x83, 0x45, + 0x0C, 0x74, 0x83, 0x45, 0x0C, 0x76, 0x82, 0x45, 0x0C, 0x77, 0x82, 0x45, 0x0C, 0x77, 0x82, 0x45, + 0x0C, 0x78, 0x82, 0x45, 0x0C, 0x79, 0x82, 0x45, 0x0D, 0x7A, 0x82, 0x45, 0x0D, 0x7B, 0x83, 0x45, + 0x0D, 0x7D, 0x84, 0x46, 0x0D, 0x7D, 0x84, 0x46, 0x0D, 0x7E, 0x84, 0x46, 0x0C, 0x7F, 0x84, 0x46, + 0x0C, 0x81, 0x83, 0x45, 0x0C, 0x82, 0x83, 0x45, 0x0B, 0x82, 0x83, 0x45, 0x0B, 0x82, 0x83, 0x45, + 0x0B, 0x82, 0x83, 0x45, 0x0B, 0x82, 0x83, 0x45, 0x0B, 0x82, 0x83, 0x44, 0x0B, 0x83, 0x83, 0x44, + 0x0B, 0x83, 0x83, 0x44, 0x0B, 0x83, 0x83, 0x44, 0x0B, 0x83, 0x83, 0x44, 0x0B, 0x82, 0x83, 0x45, + 0x0C, 0x81, 0x84, 0x46, 0x0C, 0x81, 0x84, 0x45, 0x0C, 0x80, 0x84, 0x46, 0x0C, 0x80, 0x83, 0x46, + 0x0D, 0x7F, 0x83, 0x46, 0x0D, 0x7E, 0x83, 0x45, 0x0C, 0x7E, 0x83, 0x45, 0x0D, 0x7D, 0x83, 0x45, + 0x0C, 0x7D, 0x83, 0x45, 0x0D, 0x7C, 0x83, 0x45, 0x0C, 0x7B, 0x83, 0x45, 0x0C, 0x7A, 0x83, 0x45, + 0x0C, 0x7A, 0x83, 0x45, 0x0C, 0x79, 0x83, 0x45, 0x0C, 0x78, 0x83, 0x45, 0x0C, 0x77, 0x83, 0x45, + 0x0C, 0x75, 0x83, 0x45, 0x0C, 0x74, 0x83, 0x45, 0x0C, 0x72, 0x83, 0x45, 0x0C, 0x71, 0x82, 0x45, + 0x0C, 0x6F, 0x83, 0x45, 0x0C, 0x6D, 0x82, 0x45, 0x0C, 0x6A, 0x83, 0x45, 0x0C, 0x68, 0x83, 0x45, + 0x0C, 0x65, 0x83, 0x45, 0x0C, 0x63, 0x83, 0x45, 0x0C, 0x5F, 0x83, 0x45, 0x0C, 0x5D, 0x83, 0x45, + 0x0C, 0x5A, 0x83, 0x45, 0x0C, 0x57, 0x83, 0x45, 0x0C, 0x53, 0x83, 0x45, 0x0C, 0x4F, 0x83, 0x45, + 0x0C, 0x4B, 0x83, 0x45, 0x0C, 0x47, 0x83, 0x45, 0x0C, 0x42, 0x83, 0x45, 0x0C, 0x3D, 0x83, 0x45, + 0x0C, 0x37, 0x83, 0x45, 0x0C, 0x31, 0x83, 0x45, 0x0C, 0x2B, 0x83, 0x45, 0x0C, 0x25, 0x83, 0x45, + 0x0C, 0x1F, 0x83, 0x45, 0x0C, 0x19, 0x83, 0x45, 0x0C, 0x14, 0x83, 0x45, 0x0C, 0x10, 0x83, 0x45, + 0x0C, 0x0D, 0x83, 0x45, 0x0C, 0x0A, 0x83, 0x45, 0x0C, 0x06, 0x82, 0x45, 0x0C, 0x05, 0x81, 0x44, + 0x0A, 0x03, 0x83, 0x45, 0x0D, 0x02, 0x8C, 0x53, 0x21, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x43, 0x09, 0x01, 0x81, 0x43, 0x0A, 0x02, 0x82, 0x45, + 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x03, 0x82, 0x45, 0x0C, 0x05, 0x83, 0x45, 0x0C, 0x08, 0x83, 0x45, + 0x0C, 0x0A, 0x83, 0x45, 0x0C, 0x0D, 0x83, 0x45, 0x0C, 0x12, 0x83, 0x45, 0x0C, 0x18, 0x83, 0x45, + 0x0C, 0x1E, 0x83, 0x45, 0x0C, 0x24, 0x83, 0x45, 0x0C, 0x2A, 0x83, 0x45, 0x0C, 0x31, 0x83, 0x45, + 0x0C, 0x39, 0x83, 0x45, 0x0C, 0x40, 0x83, 0x45, 0x0C, 0x46, 0x83, 0x45, 0x0C, 0x4C, 0x82, 0x45, + 0x0C, 0x52, 0x83, 0x45, 0x0C, 0x57, 0x83, 0x45, 0x0C, 0x5C, 0x83, 0x45, 0x0C, 0x60, 0x83, 0x45, + 0x0C, 0x65, 0x83, 0x45, 0x0C, 0x68, 0x83, 0x45, 0x0C, 0x6C, 0x83, 0x45, 0x0C, 0x6E, 0x83, 0x45, + 0x0C, 0x71, 0x83, 0x45, 0x0C, 0x73, 0x83, 0x45, 0x0C, 0x76, 0x83, 0x45, 0x0C, 0x78, 0x82, 0x45, + 0x0C, 0x7B, 0x83, 0x45, 0x0C, 0x7D, 0x82, 0x45, 0x0C, 0x7F, 0x82, 0x45, 0x0C, 0x81, 0x82, 0x45, + 0x0C, 0x83, 0x83, 0x45, 0x0D, 0x84, 0x82, 0x45, 0x0C, 0x86, 0x83, 0x45, 0x0C, 0x86, 0x83, 0x45, + 0x0C, 0x87, 0x83, 0x45, 0x0C, 0x88, 0x83, 0x45, 0x0C, 0x89, 0x83, 0x45, 0x0C, 0x8A, 0x83, 0x45, + 0x0C, 0x8B, 0x83, 0x45, 0x0C, 0x8C, 0x83, 0x45, 0x0C, 0x8D, 0x83, 0x44, 0x0B, 0x8E, 0x82, 0x45, + 0x0B, 0x8F, 0x83, 0x45, 0x0B, 0x90, 0x83, 0x45, 0x0B, 0x8F, 0x84, 0x45, 0x0B, 0x90, 0x84, 0x45, + 0x0B, 0x8F, 0x84, 0x45, 0x0B, 0x90, 0x84, 0x45, 0x0A, 0x91, 0x84, 0x44, 0x0A, 0x91, 0x84, 0x45, + 0x0B, 0x92, 0x84, 0x44, 0x0A, 0x92, 0x83, 0x45, 0x0B, 0x93, 0x83, 0x44, 0x0A, 0x92, 0x82, 0x45, + 0x0B, 0x93, 0x83, 0x45, 0x0B, 0x92, 0x83, 0x45, 0x0B, 0x92, 0x84, 0x45, 0x0B, 0x91, 0x83, 0x46, + 0x0C, 0x90, 0x84, 0x46, 0x0D, 0x8F, 0x83, 0x45, 0x0C, 0x8F, 0x83, 0x45, 0x0C, 0x8E, 0x83, 0x45, + 0x0C, 0x8D, 0x83, 0x45, 0x0C, 0x8B, 0x83, 0x45, 0x0C, 0x8A, 0x83, 0x45, 0x0C, 0x89, 0x83, 0x45, + 0x0C, 0x89, 0x83, 0x45, 0x0C, 0x87, 0x83, 0x45, 0x0C, 0x87, 0x83, 0x45, 0x0C, 0x85, 0x83, 0x45, + 0x0C, 0x84, 0x83, 0x45, 0x0C, 0x81, 0x83, 0x45, 0x0C, 0x81, 0x83, 0x45, 0x0C, 0x7F, 0x82, 0x45, + 0x0C, 0x7D, 0x83, 0x45, 0x0C, 0x7B, 0x82, 0x45, 0x0C, 0x7A, 0x83, 0x45, 0x0C, 0x78, 0x82, 0x45, + 0x0C, 0x76, 0x83, 0x45, 0x0C, 0x72, 0x82, 0x45, 0x0C, 0x6F, 0x83, 0x45, 0x0C, 0x6C, 0x83, 0x45, + 0x0C, 0x69, 0x83, 0x45, 0x0C, 0x66, 0x83, 0x45, 0x0C, 0x62, 0x83, 0x45, 0x0C, 0x5D, 0x83, 0x45, + 0x0C, 0x59, 0x83, 0x45, 0x0C, 0x54, 0x83, 0x45, 0x0C, 0x4E, 0x83, 0x45, 0x0C, 0x49, 0x83, 0x45, + 0x0C, 0x42, 0x83, 0x45, 0x0C, 0x3B, 0x83, 0x45, 0x0C, 0x34, 0x83, 0x45, 0x0C, 0x2D, 0x83, 0x45, + 0x0C, 0x26, 0x83, 0x45, 0x0C, 0x1F, 0x82, 0x45, 0x0C, 0x19, 0x83, 0x45, 0x0C, 0x14, 0x82, 0x45, + 0x0C, 0x0F, 0x83, 0x45, 0x0C, 0x0B, 0x82, 0x45, 0x0C, 0x08, 0x83, 0x45, 0x0C, 0x06, 0x82, 0x44, + 0x0B, 0x04, 0x84, 0x46, 0x0F, 0x03, 0x8C, 0x53, 0x21, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x43, 0x09, 0x01, 0x81, 0x43, 0x09, 0x02, 0x82, 0x45, + 0x0C, 0x03, 0x83, 0x45, 0x0C, 0x04, 0x82, 0x45, 0x0C, 0x06, 0x83, 0x45, 0x0C, 0x09, 0x83, 0x45, + 0x0C, 0x0C, 0x83, 0x45, 0x0C, 0x10, 0x83, 0x45, 0x0C, 0x17, 0x83, 0x45, 0x0C, 0x1D, 0x83, 0x45, + 0x0C, 0x24, 0x83, 0x45, 0x0C, 0x2A, 0x83, 0x45, 0x0C, 0x33, 0x83, 0x45, 0x0C, 0x3B, 0x83, 0x45, + 0x0C, 0x44, 0x83, 0x45, 0x0C, 0x4B, 0x83, 0x45, 0x0C, 0x53, 0x83, 0x45, 0x0C, 0x59, 0x83, 0x45, + 0x0C, 0x60, 0x83, 0x45, 0x0C, 0x65, 0x83, 0x45, 0x0C, 0x6B, 0x83, 0x45, 0x0C, 0x6F, 0x83, 0x45, + 0x0C, 0x74, 0x83, 0x45, 0x0C, 0x77, 0x83, 0x45, 0x0C, 0x7C, 0x83, 0x45, 0x0C, 0x7F, 0x83, 0x45, + 0x0C, 0x81, 0x83, 0x45, 0x0C, 0x83, 0x83, 0x45, 0x0C, 0x87, 0x83, 0x45, 0x0C, 0x88, 0x82, 0x45, + 0x0C, 0x8A, 0x82, 0x45, 0x0C, 0x8C, 0x82, 0x44, 0x0C, 0x8D, 0x82, 0x45, 0x0C, 0x8E, 0x83, 0x45, + 0x0D, 0x8F, 0x83, 0x45, 0x0C, 0x91, 0x83, 0x45, 0x0C, 0x92, 0x83, 0x45, 0x0B, 0x95, 0x83, 0x45, + 0x0B, 0x96, 0x83, 0x45, 0x0B, 0x98, 0x83, 0x45, 0x0C, 0x99, 0x82, 0x44, 0x0A, 0x99, 0x82, 0x45, + 0x0B, 0x99, 0x81, 0x44, 0x0B, 0x9A, 0x81, 0x42, 0x09, 0x9B, 0x83, 0x45, 0x0B, 0x9C, 0x84, 0x46, + 0x0C, 0x9C, 0x85, 0x48, 0x0F, 0x9E, 0x86, 0x49, 0x10, 0xA1, 0x87, 0x4A, 0x12, 0xA1, 0x86, 0x4A, + 0x13, 0xA2, 0x86, 0x4A, 0x13, 0xA2, 0x87, 0x49, 0x13, 0xA3, 0x86, 0x4A, 0x14, 0xA4, 0x86, 0x49, + 0x13, 0xA4, 0x86, 0x49, 0x13, 0xA2, 0x84, 0x48, 0x12, 0xA1, 0x84, 0x47, 0x11, 0xA0, 0x83, 0x46, + 0x10, 0x9F, 0x82, 0x45, 0x0E, 0xA0, 0x80, 0x43, 0x0B, 0x9F, 0x81, 0x42, 0x0B, 0x9E, 0x82, 0x44, + 0x0C, 0x9D, 0x83, 0x45, 0x0D, 0x9D, 0x83, 0x45, 0x0D, 0x9D, 0x83, 0x44, 0x0C, 0x9C, 0x83, 0x44, + 0x0B, 0x9A, 0x82, 0x43, 0x0A, 0x99, 0x83, 0x45, 0x0B, 0x97, 0x83, 0x45, 0x0B, 0x96, 0x83, 0x45, + 0x0C, 0x96, 0x83, 0x45, 0x0C, 0x95, 0x83, 0x45, 0x0C, 0x94, 0x83, 0x45, 0x0C, 0x93, 0x83, 0x45, + 0x0C, 0x92, 0x83, 0x45, 0x0D, 0x91, 0x83, 0x45, 0x0C, 0x90, 0x83, 0x45, 0x0C, 0x8E, 0x83, 0x45, + 0x0C, 0x8C, 0x83, 0x45, 0x0C, 0x8A, 0x83, 0x45, 0x0C, 0x88, 0x83, 0x45, 0x0C, 0x86, 0x82, 0x45, + 0x0C, 0x85, 0x83, 0x45, 0x0C, 0x82, 0x83, 0x45, 0x0C, 0x7F, 0x83, 0x45, 0x0C, 0x7C, 0x83, 0x45, + 0x0C, 0x78, 0x83, 0x45, 0x0C, 0x75, 0x83, 0x45, 0x0C, 0x70, 0x83, 0x45, 0x0C, 0x6D, 0x83, 0x45, + 0x0C, 0x67, 0x83, 0x45, 0x0C, 0x62, 0x83, 0x45, 0x0C, 0x5B, 0x83, 0x45, 0x0C, 0x55, 0x83, 0x45, + 0x0C, 0x4D, 0x83, 0x45, 0x0C, 0x46, 0x83, 0x45, 0x0C, 0x3D, 0x83, 0x45, 0x0C, 0x36, 0x83, 0x45, + 0x0C, 0x2D, 0x83, 0x45, 0x0C, 0x26, 0x83, 0x45, 0x0C, 0x1E, 0x83, 0x45, 0x0C, 0x18, 0x82, 0x45, + 0x0C, 0x12, 0x82, 0x45, 0x0C, 0x0E, 0x82, 0x45, 0x0C, 0x0A, 0x83, 0x45, 0x0C, 0x07, 0x82, 0x44, + 0x0C, 0x05, 0x82, 0x44, 0x0C, 0x03, 0x81, 0x45, 0x0E, 0x02, 0x85, 0x49, 0x14, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x43, 0x0A, 0x01, 0x82, 0x43, 0x0A, 0x02, 0x82, 0x45, + 0x0C, 0x03, 0x83, 0x45, 0x0C, 0x04, 0x82, 0x45, 0x0C, 0x07, 0x83, 0x45, 0x0C, 0x0A, 0x82, 0x45, + 0x0C, 0x0E, 0x83, 0x45, 0x0C, 0x13, 0x83, 0x45, 0x0C, 0x1A, 0x83, 0x45, 0x0C, 0x21, 0x83, 0x45, + 0x0C, 0x28, 0x83, 0x45, 0x0C, 0x30, 0x83, 0x45, 0x0C, 0x3A, 0x83, 0x45, 0x0C, 0x43, 0x82, 0x45, + 0x0C, 0x4C, 0x83, 0x45, 0x0C, 0x54, 0x82, 0x45, 0x0C, 0x5C, 0x83, 0x45, 0x0C, 0x63, 0x83, 0x45, + 0x0C, 0x6B, 0x83, 0x45, 0x0C, 0x71, 0x83, 0x45, 0x0C, 0x76, 0x83, 0x45, 0x0C, 0x7B, 0x83, 0x45, + 0x0C, 0x7F, 0x83, 0x45, 0x0C, 0x83, 0x83, 0x45, 0x0C, 0x87, 0x83, 0x45, 0x0C, 0x8A, 0x82, 0x45, + 0x0C, 0x8D, 0x82, 0x45, 0x0C, 0x8F, 0x82, 0x45, 0x0C, 0x92, 0x83, 0x45, 0x0C, 0x94, 0x82, 0x45, + 0x0C, 0x96, 0x83, 0x45, 0x0C, 0x98, 0x82, 0x45, 0x0C, 0x9A, 0x83, 0x45, 0x0C, 0x9C, 0x83, 0x46, + 0x0D, 0x9C, 0x83, 0x45, 0x0D, 0x9D, 0x82, 0x45, 0x0C, 0x9E, 0x83, 0x45, 0x0C, 0x9F, 0x82, 0x44, + 0x0B, 0xA1, 0x83, 0x44, 0x0B, 0xA1, 0x82, 0x44, 0x0A, 0xA3, 0x82, 0x46, 0x0C, 0xA6, 0x85, 0x49, + 0x0F, 0xA8, 0x89, 0x4C, 0x14, 0xAA, 0x8D, 0x52, 0x1B, 0xAD, 0x8F, 0x56, 0x22, 0xAE, 0x91, 0x5B, + 0x28, 0xB2, 0x93, 0x5F, 0x30, 0xB6, 0x95, 0x62, 0x36, 0xBA, 0x96, 0x64, 0x3B, 0xBD, 0x97, 0x65, + 0x3C, 0xBF, 0x97, 0x66, 0x3D, 0xC0, 0x96, 0x67, 0x3C, 0xC2, 0x97, 0x68, 0x3C, 0xC0, 0x97, 0x69, + 0x3C, 0xC0, 0x97, 0x68, 0x3C, 0xBE, 0x98, 0x67, 0x3B, 0xBE, 0x97, 0x64, 0x38, 0xBC, 0x96, 0x63, + 0x35, 0xBA, 0x93, 0x5E, 0x2E, 0xB6, 0x8F, 0x59, 0x27, 0xB3, 0x8A, 0x51, 0x1C, 0xAF, 0x88, 0x4B, + 0x15, 0xAC, 0x84, 0x46, 0x10, 0xA9, 0x82, 0x44, 0x0C, 0xA9, 0x82, 0x43, 0x0B, 0xA8, 0x82, 0x43, + 0x0A, 0xA8, 0x83, 0x43, 0x0A, 0xA5, 0x82, 0x44, 0x0C, 0xA4, 0x82, 0x44, 0x0A, 0xA3, 0x83, 0x45, + 0x0B, 0xA2, 0x84, 0x45, 0x0C, 0xA1, 0x84, 0x46, 0x0C, 0xA0, 0x83, 0x45, 0x0C, 0x9E, 0x83, 0x45, + 0x0C, 0x9E, 0x83, 0x45, 0x0C, 0x9C, 0x83, 0x45, 0x0C, 0x9C, 0x83, 0x45, 0x0C, 0x99, 0x82, 0x45, + 0x0C, 0x98, 0x83, 0x45, 0x0C, 0x95, 0x83, 0x45, 0x0C, 0x93, 0x83, 0x45, 0x0C, 0x91, 0x82, 0x45, + 0x0C, 0x8F, 0x83, 0x45, 0x0C, 0x8D, 0x82, 0x45, 0x0C, 0x8B, 0x83, 0x45, 0x0C, 0x87, 0x82, 0x45, + 0x0C, 0x84, 0x83, 0x45, 0x0C, 0x80, 0x82, 0x45, 0x0C, 0x7C, 0x83, 0x45, 0x0C, 0x78, 0x83, 0x45, + 0x0C, 0x73, 0x83, 0x45, 0x0C, 0x6D, 0x83, 0x45, 0x0C, 0x66, 0x83, 0x45, 0x0C, 0x5E, 0x83, 0x45, + 0x0C, 0x56, 0x83, 0x45, 0x0C, 0x4E, 0x83, 0x45, 0x0C, 0x45, 0x83, 0x45, 0x0C, 0x3D, 0x83, 0x45, + 0x0C, 0x33, 0x83, 0x45, 0x0C, 0x2B, 0x82, 0x45, 0x0C, 0x23, 0x83, 0x45, 0x0C, 0x1C, 0x82, 0x45, + 0x0C, 0x15, 0x83, 0x45, 0x0C, 0x10, 0x82, 0x45, 0x0C, 0x0B, 0x82, 0x44, 0x0C, 0x08, 0x82, 0x44, + 0x0C, 0x05, 0x83, 0x45, 0x0D, 0x04, 0x83, 0x45, 0x0D, 0x03, 0x83, 0x46, 0x0D, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x46, 0x0E, 0x01, 0x84, 0x46, 0x0E, 0x03, 0x83, 0x45, + 0x0D, 0x04, 0x83, 0x45, 0x0C, 0x05, 0x83, 0x45, 0x0C, 0x08, 0x83, 0x45, 0x0C, 0x0C, 0x83, 0x45, + 0x0C, 0x10, 0x83, 0x45, 0x0C, 0x16, 0x83, 0x45, 0x0C, 0x1D, 0x83, 0x45, 0x0C, 0x24, 0x83, 0x45, + 0x0C, 0x2E, 0x83, 0x45, 0x0C, 0x36, 0x83, 0x45, 0x0C, 0x40, 0x83, 0x45, 0x0C, 0x49, 0x83, 0x45, + 0x0C, 0x53, 0x83, 0x45, 0x0C, 0x5C, 0x83, 0x45, 0x0C, 0x65, 0x83, 0x45, 0x0C, 0x6D, 0x83, 0x45, + 0x0C, 0x75, 0x83, 0x45, 0x0C, 0x7B, 0x83, 0x45, 0x0D, 0x81, 0x83, 0x45, 0x0C, 0x85, 0x83, 0x45, + 0x0C, 0x8A, 0x83, 0x45, 0x0C, 0x8E, 0x83, 0x45, 0x0C, 0x91, 0x83, 0x45, 0x0C, 0x95, 0x83, 0x45, + 0x0C, 0x97, 0x82, 0x45, 0x0C, 0x9A, 0x82, 0x44, 0x0C, 0x9C, 0x83, 0x45, 0x0C, 0x9E, 0x84, 0x45, + 0x0D, 0xA0, 0x84, 0x45, 0x0C, 0xA3, 0x84, 0x45, 0x0B, 0xA4, 0x83, 0x45, 0x0C, 0xA6, 0x83, 0x46, + 0x0D, 0xA7, 0x83, 0x45, 0x0C, 0xA8, 0x83, 0x44, 0x0C, 0xAA, 0x84, 0x47, 0x0F, 0xAA, 0x88, 0x4B, + 0x14, 0xAC, 0x8B, 0x50, 0x1C, 0xB3, 0x91, 0x59, 0x2A, 0xB9, 0x98, 0x63, 0x39, 0xC0, 0x9D, 0x6A, + 0x42, 0xC7, 0x9E, 0x6F, 0x4C, 0xCC, 0xA0, 0x74, 0x52, 0xD2, 0xA0, 0x77, 0x57, 0xD9, 0x9F, 0x77, + 0x5A, 0xE1, 0x9D, 0x77, 0x5B, 0xE7, 0x9C, 0x76, 0x5A, 0xED, 0x9B, 0x74, 0x5A, 0xF0, 0x9A, 0x74, + 0x5A, 0xF3, 0x9A, 0x74, 0x5A, 0xF3, 0x9B, 0x75, 0x5A, 0xF4, 0x9B, 0x75, 0x5B, 0xF3, 0x9C, 0x77, + 0x5C, 0xF2, 0x9C, 0x77, 0x5C, 0xF2, 0x9D, 0x78, 0x5E, 0xF1, 0x9E, 0x78, 0x5E, 0xEE, 0x9E, 0x78, + 0x5D, 0xE9, 0xA1, 0x78, 0x5C, 0xE2, 0x9F, 0x78, 0x59, 0xDC, 0x9F, 0x76, 0x54, 0xD5, 0x9D, 0x71, + 0x4C, 0xD1, 0x9D, 0x6C, 0x43, 0xCA, 0x98, 0x66, 0x3B, 0xC6, 0x94, 0x5E, 0x2E, 0xBF, 0x8D, 0x54, + 0x22, 0xB8, 0x87, 0x4C, 0x16, 0xB5, 0x84, 0x47, 0x11, 0xAF, 0x83, 0x45, 0x0E, 0xAC, 0x82, 0x45, + 0x0D, 0xAB, 0x83, 0x45, 0x0C, 0xAB, 0x84, 0x45, 0x0C, 0xAA, 0x83, 0x44, 0x0C, 0xA8, 0x84, 0x45, + 0x0C, 0xA7, 0x83, 0x45, 0x0C, 0xA6, 0x83, 0x45, 0x0C, 0xA5, 0x83, 0x45, 0x0C, 0xA3, 0x83, 0x45, + 0x0C, 0xA1, 0x83, 0x45, 0x0D, 0xA0, 0x83, 0x45, 0x0C, 0x9E, 0x83, 0x45, 0x0C, 0x9C, 0x83, 0x45, + 0x0C, 0x9A, 0x83, 0x45, 0x0C, 0x97, 0x83, 0x45, 0x0C, 0x95, 0x83, 0x45, 0x0C, 0x92, 0x82, 0x45, + 0x0C, 0x8E, 0x83, 0x45, 0x0C, 0x8A, 0x83, 0x45, 0x0C, 0x86, 0x83, 0x45, 0x0C, 0x82, 0x83, 0x45, + 0x0C, 0x7D, 0x83, 0x45, 0x0C, 0x77, 0x83, 0x45, 0x0C, 0x6F, 0x83, 0x45, 0x0C, 0x68, 0x83, 0x45, + 0x0C, 0x5E, 0x83, 0x45, 0x0C, 0x56, 0x83, 0x45, 0x0C, 0x4C, 0x83, 0x45, 0x0C, 0x43, 0x83, 0x45, + 0x0C, 0x39, 0x83, 0x45, 0x0C, 0x30, 0x83, 0x45, 0x0C, 0x28, 0x83, 0x45, 0x0C, 0x1F, 0x82, 0x45, + 0x0C, 0x18, 0x82, 0x45, 0x0C, 0x12, 0x82, 0x45, 0x0C, 0x0D, 0x83, 0x45, 0x0C, 0x09, 0x83, 0x45, + 0x0D, 0x06, 0x83, 0x45, 0x0C, 0x04, 0x83, 0x45, 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x47, 0x0F, 0x02, 0x84, 0x46, 0x0E, 0x03, 0x83, 0x45, + 0x0D, 0x04, 0x83, 0x45, 0x0C, 0x05, 0x83, 0x45, 0x0C, 0x08, 0x83, 0x45, 0x0C, 0x0D, 0x82, 0x45, + 0x0C, 0x12, 0x83, 0x45, 0x0C, 0x18, 0x82, 0x45, 0x0C, 0x1F, 0x83, 0x45, 0x0C, 0x27, 0x83, 0x45, + 0x0C, 0x31, 0x83, 0x45, 0x0C, 0x3A, 0x82, 0x45, 0x0C, 0x44, 0x83, 0x45, 0x0C, 0x4E, 0x83, 0x45, + 0x0C, 0x59, 0x83, 0x45, 0x0C, 0x62, 0x83, 0x45, 0x0C, 0x6C, 0x83, 0x45, 0x0C, 0x74, 0x83, 0x45, + 0x0C, 0x7C, 0x83, 0x45, 0x0C, 0x82, 0x83, 0x45, 0x0C, 0x88, 0x83, 0x45, 0x0C, 0x8D, 0x82, 0x45, + 0x0C, 0x92, 0x83, 0x45, 0x0C, 0x95, 0x82, 0x45, 0x0C, 0x99, 0x83, 0x45, 0x0D, 0x9C, 0x82, 0x45, + 0x0C, 0x9F, 0x83, 0x45, 0x0D, 0xA1, 0x83, 0x45, 0x0C, 0xA3, 0x83, 0x45, 0x0C, 0xA5, 0x83, 0x45, + 0x0C, 0xA7, 0x83, 0x44, 0x0B, 0xA9, 0x83, 0x45, 0x0B, 0xAA, 0x84, 0x46, 0x0C, 0xAB, 0x84, 0x47, + 0x0B, 0xAE, 0x8A, 0x4C, 0x13, 0xB2, 0x8E, 0x54, 0x21, 0xB9, 0x95, 0x5F, 0x32, 0xC3, 0x98, 0x69, + 0x42, 0xCD, 0x9E, 0x72, 0x50, 0xD6, 0xA1, 0x78, 0x59, 0xDF, 0xA0, 0x78, 0x5A, 0xE7, 0x9E, 0x77, + 0x59, 0xEF, 0x9B, 0x75, 0x58, 0xF6, 0x99, 0x73, 0x56, 0xFA, 0x98, 0x72, 0x57, 0xFC, 0x99, 0x73, + 0x58, 0xFE, 0x9B, 0x74, 0x59, 0xFF, 0x9B, 0x74, 0x5A, 0xFF, 0x9B, 0x75, 0x5B, 0xFF, 0x9B, 0x75, + 0x5B, 0xFE, 0x9B, 0x74, 0x5B, 0xFF, 0x9A, 0x74, 0x5B, 0xFF, 0x9A, 0x74, 0x5B, 0xFF, 0x99, 0x74, + 0x5B, 0xFF, 0x99, 0x74, 0x5B, 0xFE, 0x99, 0x75, 0x5C, 0xFF, 0x9B, 0x76, 0x5D, 0xFE, 0x9C, 0x77, + 0x5D, 0xFF, 0x9D, 0x77, 0x5D, 0xFD, 0x9D, 0x77, 0x5C, 0xFD, 0x9F, 0x79, 0x5D, 0xFA, 0xA1, 0x7B, + 0x5F, 0xF8, 0xA4, 0x7C, 0x62, 0xF2, 0xA5, 0x7F, 0x63, 0xEE, 0xA5, 0x7D, 0x61, 0xE5, 0xA2, 0x7A, + 0x59, 0xDC, 0x9D, 0x70, 0x4C, 0xD1, 0x97, 0x65, 0x39, 0xCA, 0x8F, 0x57, 0x25, 0xC1, 0x89, 0x4D, + 0x18, 0xB9, 0x84, 0x47, 0x10, 0xB4, 0x83, 0x44, 0x0C, 0xB2, 0x83, 0x43, 0x0B, 0xAE, 0x83, 0x45, + 0x0C, 0xAD, 0x83, 0x45, 0x0B, 0xAC, 0x84, 0x46, 0x0C, 0xAB, 0x84, 0x45, 0x0C, 0xA9, 0x83, 0x45, + 0x0D, 0xA9, 0x83, 0x45, 0x0C, 0xA8, 0x83, 0x45, 0x0C, 0xA7, 0x83, 0x45, 0x0C, 0xA5, 0x82, 0x45, + 0x0C, 0xA2, 0x83, 0x45, 0x0C, 0x9F, 0x83, 0x45, 0x0C, 0x9D, 0x83, 0x45, 0x0C, 0x9A, 0x82, 0x45, + 0x0C, 0x96, 0x83, 0x45, 0x0C, 0x93, 0x82, 0x45, 0x0C, 0x8F, 0x83, 0x45, 0x0C, 0x8B, 0x82, 0x45, + 0x0C, 0x85, 0x83, 0x45, 0x0C, 0x7E, 0x83, 0x45, 0x0C, 0x76, 0x83, 0x45, 0x0C, 0x6E, 0x83, 0x45, + 0x0C, 0x65, 0x83, 0x45, 0x0C, 0x5B, 0x83, 0x45, 0x0C, 0x52, 0x83, 0x45, 0x0C, 0x47, 0x83, 0x45, + 0x0C, 0x3D, 0x83, 0x45, 0x0C, 0x33, 0x83, 0x45, 0x0C, 0x2A, 0x83, 0x45, 0x0C, 0x21, 0x82, 0x45, + 0x0C, 0x19, 0x83, 0x45, 0x0C, 0x13, 0x83, 0x45, 0x0C, 0x0E, 0x83, 0x45, 0x0C, 0x0A, 0x83, 0x45, + 0x0C, 0x06, 0x83, 0x45, 0x0C, 0x04, 0x83, 0x44, 0x0B, 0x03, 0x83, 0x44, 0x0C, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x47, 0x0F, 0x02, 0x84, 0x46, 0x0F, 0x03, 0x83, 0x45, + 0x0D, 0x04, 0x83, 0x45, 0x0C, 0x05, 0x83, 0x45, 0x0C, 0x08, 0x83, 0x45, 0x0C, 0x0C, 0x83, 0x45, + 0x0C, 0x12, 0x83, 0x45, 0x0C, 0x18, 0x83, 0x45, 0x0C, 0x20, 0x83, 0x45, 0x0C, 0x28, 0x83, 0x45, + 0x0C, 0x32, 0x83, 0x45, 0x0C, 0x3C, 0x83, 0x45, 0x0C, 0x47, 0x83, 0x45, 0x0C, 0x51, 0x83, 0x45, + 0x0C, 0x5C, 0x83, 0x45, 0x0C, 0x65, 0x83, 0x45, 0x0D, 0x70, 0x83, 0x45, 0x0C, 0x78, 0x83, 0x45, + 0x0D, 0x80, 0x83, 0x45, 0x0C, 0x86, 0x83, 0x45, 0x0C, 0x8D, 0x83, 0x45, 0x0C, 0x91, 0x83, 0x45, + 0x0C, 0x96, 0x83, 0x45, 0x0C, 0x99, 0x83, 0x44, 0x0C, 0x9D, 0x83, 0x45, 0x0C, 0x9F, 0x83, 0x45, + 0x0D, 0xA2, 0x83, 0x45, 0x0C, 0xA4, 0x83, 0x45, 0x0C, 0xA6, 0x83, 0x45, 0x0C, 0xA9, 0x84, 0x45, + 0x0D, 0xAC, 0x84, 0x45, 0x0E, 0xAE, 0x88, 0x4A, 0x13, 0xB1, 0x8E, 0x54, 0x21, 0xBA, 0x99, 0x62, + 0x37, 0xC4, 0x9E, 0x6F, 0x4C, 0xD0, 0xA2, 0x77, 0x58, 0xDE, 0xA1, 0x7A, 0x5E, 0xE9, 0x9F, 0x78, + 0x5E, 0xF3, 0x9A, 0x75, 0x5B, 0xFA, 0x96, 0x71, 0x57, 0xFD, 0x92, 0x6C, 0x52, 0xFF, 0x8F, 0x68, + 0x4E, 0xFF, 0x8B, 0x65, 0x4A, 0xFF, 0x8A, 0x63, 0x47, 0xFF, 0x87, 0x5F, 0x44, 0xFF, 0x87, 0x5D, + 0x42, 0xFF, 0x85, 0x5B, 0x41, 0xFF, 0x83, 0x5A, 0x3F, 0xFF, 0x82, 0x59, 0x3E, 0xFF, 0x83, 0x57, + 0x3C, 0xFF, 0x82, 0x57, 0x3C, 0xFF, 0x82, 0x56, 0x3B, 0xFF, 0x81, 0x56, 0x3B, 0xFF, 0x82, 0x57, + 0x3D, 0xFF, 0x83, 0x59, 0x3F, 0xFF, 0x84, 0x5B, 0x41, 0xFF, 0x86, 0x5E, 0x43, 0xFF, 0x88, 0x60, + 0x45, 0xFF, 0x8A, 0x62, 0x48, 0xFF, 0x8C, 0x65, 0x4A, 0xFF, 0x8F, 0x69, 0x4E, 0xFF, 0x92, 0x6D, + 0x52, 0xFF, 0x95, 0x70, 0x55, 0xFF, 0x97, 0x72, 0x58, 0xFE, 0x99, 0x74, 0x5A, 0xFD, 0x9B, 0x78, + 0x5E, 0xFA, 0xA0, 0x7B, 0x61, 0xF6, 0xA0, 0x7D, 0x61, 0xEF, 0xA3, 0x7C, 0x5D, 0xE4, 0xA0, 0x78, + 0x54, 0xD8, 0x9C, 0x6C, 0x41, 0xCC, 0x92, 0x5B, 0x2C, 0xC1, 0x89, 0x4D, 0x17, 0xB9, 0x83, 0x45, + 0x0E, 0xB3, 0x84, 0x45, 0x0C, 0xB0, 0x83, 0x45, 0x0C, 0xAE, 0x83, 0x45, 0x0C, 0xAD, 0x84, 0x45, + 0x0D, 0xAC, 0x83, 0x45, 0x0C, 0xAB, 0x84, 0x45, 0x0C, 0xAA, 0x83, 0x45, 0x0D, 0xA9, 0x83, 0x45, + 0x0C, 0xA6, 0x83, 0x45, 0x0D, 0xA4, 0x83, 0x45, 0x0C, 0xA1, 0x83, 0x45, 0x0C, 0x9F, 0x83, 0x45, + 0x0C, 0x9A, 0x83, 0x45, 0x0C, 0x97, 0x82, 0x45, 0x0C, 0x93, 0x83, 0x45, 0x0C, 0x8F, 0x83, 0x45, + 0x0C, 0x88, 0x83, 0x45, 0x0C, 0x82, 0x83, 0x45, 0x0C, 0x7A, 0x83, 0x45, 0x0C, 0x72, 0x83, 0x45, + 0x0C, 0x69, 0x83, 0x45, 0x0C, 0x5F, 0x83, 0x45, 0x0C, 0x55, 0x83, 0x45, 0x0C, 0x4A, 0x83, 0x45, + 0x0C, 0x3F, 0x83, 0x45, 0x0C, 0x35, 0x83, 0x45, 0x0C, 0x2B, 0x83, 0x45, 0x0C, 0x22, 0x82, 0x45, + 0x0C, 0x1B, 0x83, 0x45, 0x0C, 0x14, 0x83, 0x45, 0x0C, 0x0F, 0x83, 0x45, 0x0C, 0x0B, 0x82, 0x45, + 0x0C, 0x06, 0x83, 0x45, 0x0C, 0x04, 0x82, 0x44, 0x0B, 0x02, 0x83, 0x44, 0x0C, 0x01, 0x87, 0x49, + 0x12, 0x01, 0x88, 0x4C, 0x15, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x47, 0x0F, 0x01, 0x83, 0x46, 0x0E, 0x03, 0x83, 0x45, + 0x0D, 0x04, 0x83, 0x45, 0x0C, 0x05, 0x83, 0x45, 0x0C, 0x08, 0x83, 0x45, 0x0C, 0x0C, 0x82, 0x45, + 0x0C, 0x12, 0x83, 0x45, 0x0C, 0x18, 0x82, 0x45, 0x0C, 0x20, 0x83, 0x45, 0x0C, 0x28, 0x82, 0x45, + 0x0C, 0x32, 0x83, 0x45, 0x0C, 0x3C, 0x83, 0x45, 0x0C, 0x47, 0x83, 0x45, 0x0C, 0x51, 0x83, 0x45, + 0x0C, 0x5C, 0x83, 0x45, 0x0C, 0x65, 0x83, 0x45, 0x0C, 0x6F, 0x83, 0x45, 0x0C, 0x78, 0x83, 0x45, + 0x0C, 0x80, 0x83, 0x45, 0x0C, 0x86, 0x82, 0x45, 0x0C, 0x8C, 0x83, 0x45, 0x0C, 0x91, 0x83, 0x45, + 0x0C, 0x95, 0x83, 0x44, 0x0D, 0x99, 0x83, 0x45, 0x0C, 0x9C, 0x83, 0x45, 0x0C, 0xA0, 0x83, 0x45, + 0x0C, 0xA3, 0x83, 0x45, 0x0C, 0xA5, 0x83, 0x46, 0x0C, 0xA8, 0x86, 0x48, 0x0F, 0xAB, 0x88, 0x4D, + 0x14, 0xB1, 0x93, 0x5C, 0x29, 0xBC, 0x9A, 0x6B, 0x42, 0xCB, 0x9F, 0x75, 0x54, 0xDD, 0x9F, 0x79, + 0x59, 0xEB, 0x9C, 0x76, 0x59, 0xF5, 0x96, 0x6F, 0x53, 0xFC, 0x92, 0x6A, 0x4E, 0xFF, 0x8F, 0x66, + 0x4B, 0xFF, 0x8A, 0x60, 0x44, 0xFF, 0x87, 0x5B, 0x40, 0xFF, 0x84, 0x57, 0x3C, 0xFF, 0x80, 0x53, + 0x37, 0xFF, 0x7B, 0x4E, 0x33, 0xFF, 0x77, 0x4A, 0x2F, 0xFF, 0x76, 0x48, 0x2D, 0xFF, 0x74, 0x45, + 0x2C, 0xFF, 0x72, 0x44, 0x2A, 0xFF, 0x71, 0x44, 0x2A, 0xFF, 0x71, 0x43, 0x2A, 0xFF, 0x70, 0x43, + 0x2A, 0xFF, 0x71, 0x43, 0x2B, 0xFF, 0x71, 0x44, 0x2B, 0xFF, 0x71, 0x45, 0x2C, 0xFF, 0x71, 0x45, + 0x2C, 0xFF, 0x72, 0x46, 0x2D, 0xFF, 0x72, 0x47, 0x2D, 0xFF, 0x75, 0x49, 0x2F, 0xFF, 0x76, 0x4A, + 0x31, 0xFF, 0x79, 0x4D, 0x34, 0xFF, 0x7B, 0x50, 0x37, 0xFF, 0x7E, 0x52, 0x3A, 0xFF, 0x81, 0x55, + 0x3D, 0xFF, 0x85, 0x5A, 0x42, 0xFF, 0x88, 0x5E, 0x46, 0xFF, 0x8E, 0x66, 0x4D, 0xFF, 0x92, 0x6B, + 0x52, 0xFF, 0x97, 0x70, 0x57, 0xFF, 0x9A, 0x75, 0x5B, 0xFF, 0x9F, 0x79, 0x5D, 0xFE, 0xA2, 0x7B, + 0x60, 0xFB, 0xA5, 0x7E, 0x62, 0xF2, 0xA4, 0x7D, 0x5F, 0xE5, 0xA0, 0x75, 0x53, 0xD5, 0x97, 0x65, + 0x38, 0xC8, 0x8B, 0x52, 0x1D, 0xBC, 0x85, 0x46, 0x0E, 0xB3, 0x83, 0x43, 0x0B, 0xAF, 0x83, 0x46, + 0x0D, 0xAE, 0x83, 0x45, 0x0C, 0xAD, 0x84, 0x46, 0x0C, 0xAC, 0x84, 0x45, 0x0C, 0xA9, 0x83, 0x45, + 0x0D, 0xA7, 0x83, 0x45, 0x0C, 0xA5, 0x83, 0x45, 0x0C, 0xA3, 0x83, 0x45, 0x0C, 0xA0, 0x83, 0x45, + 0x0C, 0x9C, 0x83, 0x45, 0x0C, 0x98, 0x82, 0x45, 0x0C, 0x94, 0x83, 0x45, 0x0C, 0x8F, 0x83, 0x45, + 0x0C, 0x88, 0x83, 0x45, 0x0C, 0x82, 0x82, 0x45, 0x0C, 0x7A, 0x83, 0x45, 0x0C, 0x73, 0x82, 0x45, + 0x0C, 0x69, 0x83, 0x45, 0x0C, 0x5F, 0x83, 0x45, 0x0C, 0x55, 0x83, 0x45, 0x0C, 0x4A, 0x83, 0x45, + 0x0C, 0x40, 0x83, 0x45, 0x0C, 0x35, 0x83, 0x45, 0x0C, 0x2B, 0x83, 0x45, 0x0C, 0x22, 0x83, 0x45, + 0x0C, 0x1B, 0x83, 0x45, 0x0C, 0x15, 0x82, 0x45, 0x0C, 0x0F, 0x83, 0x45, 0x0C, 0x0B, 0x82, 0x45, + 0x0C, 0x06, 0x83, 0x44, 0x0C, 0x04, 0x82, 0x44, 0x0B, 0x02, 0x83, 0x44, 0x0C, 0x01, 0x87, 0x4A, + 0x12, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x46, 0x0F, 0x02, 0x84, 0x46, 0x0E, 0x03, 0x83, 0x45, + 0x0D, 0x04, 0x83, 0x45, 0x0C, 0x05, 0x83, 0x45, 0x0C, 0x08, 0x83, 0x45, 0x0C, 0x0C, 0x83, 0x45, + 0x0C, 0x12, 0x83, 0x45, 0x0C, 0x17, 0x83, 0x45, 0x0C, 0x1F, 0x83, 0x45, 0x0C, 0x27, 0x83, 0x45, + 0x0C, 0x31, 0x83, 0x45, 0x0C, 0x3A, 0x83, 0x45, 0x0C, 0x45, 0x83, 0x45, 0x0D, 0x4F, 0x83, 0x45, + 0x0D, 0x5A, 0x83, 0x45, 0x0D, 0x63, 0x82, 0x45, 0x0C, 0x6D, 0x83, 0x45, 0x0C, 0x74, 0x83, 0x45, + 0x0C, 0x7D, 0x83, 0x45, 0x0C, 0x83, 0x83, 0x45, 0x0C, 0x89, 0x83, 0x45, 0x0C, 0x8D, 0x84, 0x45, + 0x0C, 0x93, 0x84, 0x45, 0x0C, 0x97, 0x83, 0x45, 0x0C, 0x9A, 0x83, 0x45, 0x0C, 0x9E, 0x84, 0x45, + 0x0D, 0xA0, 0x85, 0x47, 0x11, 0xA3, 0x8F, 0x52, 0x1F, 0xAC, 0x99, 0x64, 0x39, 0xBC, 0xA1, 0x75, + 0x50, 0xD2, 0xA2, 0x7B, 0x5D, 0xE3, 0x9F, 0x78, 0x5C, 0xF3, 0x98, 0x72, 0x56, 0xFA, 0x90, 0x6B, + 0x4F, 0xFD, 0x8B, 0x64, 0x47, 0xFF, 0x86, 0x5C, 0x40, 0xFF, 0x80, 0x55, 0x38, 0xFF, 0x7C, 0x4E, + 0x33, 0xFF, 0x77, 0x49, 0x2E, 0xFF, 0x74, 0x46, 0x2C, 0xFF, 0x71, 0x43, 0x29, 0xFF, 0x70, 0x43, + 0x29, 0xFF, 0x6F, 0x41, 0x27, 0xFF, 0x6F, 0x42, 0x27, 0xFF, 0x6E, 0x41, 0x26, 0xFF, 0x6F, 0x41, + 0x27, 0xFF, 0x6F, 0x42, 0x27, 0xFF, 0x70, 0x42, 0x28, 0xFF, 0x70, 0x42, 0x28, 0xFF, 0x71, 0x43, + 0x29, 0xFF, 0x71, 0x43, 0x29, 0xFF, 0x72, 0x44, 0x2A, 0xFF, 0x72, 0x44, 0x2A, 0xFF, 0x72, 0x46, + 0x2B, 0xFF, 0x72, 0x46, 0x2B, 0xFF, 0x73, 0x47, 0x2C, 0xFF, 0x74, 0x47, 0x2D, 0xFF, 0x75, 0x48, + 0x2E, 0xFF, 0x75, 0x49, 0x2F, 0xFF, 0x76, 0x4B, 0x31, 0xFF, 0x77, 0x4B, 0x32, 0xFF, 0x78, 0x4C, + 0x32, 0xFF, 0x7A, 0x4D, 0x34, 0xFF, 0x7B, 0x4F, 0x35, 0xFF, 0x7D, 0x51, 0x38, 0xFF, 0x81, 0x56, + 0x3C, 0xFF, 0x84, 0x5A, 0x40, 0xFF, 0x88, 0x5F, 0x45, 0xFF, 0x8D, 0x66, 0x4C, 0xFF, 0x91, 0x6C, + 0x52, 0xFF, 0x96, 0x71, 0x56, 0xFE, 0x9C, 0x77, 0x5C, 0xFD, 0xA1, 0x7C, 0x61, 0xF8, 0xA3, 0x7F, + 0x63, 0xEC, 0xA4, 0x7A, 0x59, 0xDA, 0x9C, 0x6D, 0x44, 0xC6, 0x90, 0x57, 0x25, 0xB8, 0x86, 0x48, + 0x11, 0xAF, 0x84, 0x45, 0x0D, 0xA9, 0x84, 0x46, 0x0C, 0xA5, 0x83, 0x45, 0x0D, 0xA3, 0x83, 0x45, + 0x0C, 0xA2, 0x83, 0x44, 0x0C, 0xA0, 0x83, 0x45, 0x0C, 0x9E, 0x83, 0x45, 0x0D, 0x9B, 0x83, 0x45, + 0x0C, 0x97, 0x83, 0x45, 0x0D, 0x93, 0x83, 0x45, 0x0C, 0x8F, 0x83, 0x45, 0x0C, 0x8B, 0x83, 0x45, + 0x0C, 0x84, 0x83, 0x45, 0x0C, 0x7E, 0x83, 0x45, 0x0C, 0x77, 0x83, 0x45, 0x0C, 0x6F, 0x83, 0x45, + 0x0C, 0x66, 0x83, 0x45, 0x0C, 0x5C, 0x83, 0x45, 0x0C, 0x53, 0x83, 0x45, 0x0C, 0x49, 0x83, 0x45, + 0x0C, 0x3F, 0x83, 0x45, 0x0C, 0x34, 0x83, 0x45, 0x0C, 0x2A, 0x83, 0x45, 0x0C, 0x21, 0x83, 0x45, + 0x0C, 0x19, 0x83, 0x45, 0x0C, 0x13, 0x82, 0x45, 0x0C, 0x0E, 0x82, 0x45, 0x0C, 0x0A, 0x82, 0x45, + 0x0C, 0x06, 0x82, 0x44, 0x0C, 0x04, 0x83, 0x44, 0x0B, 0x02, 0x83, 0x44, 0x0B, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x45, 0x0D, 0x01, 0x83, 0x45, 0x0D, 0x02, 0x83, 0x45, + 0x0C, 0x03, 0x83, 0x45, 0x0C, 0x05, 0x83, 0x45, 0x0C, 0x08, 0x83, 0x45, 0x0C, 0x0C, 0x82, 0x45, + 0x0C, 0x10, 0x83, 0x45, 0x0C, 0x16, 0x83, 0x45, 0x0C, 0x1D, 0x83, 0x45, 0x0C, 0x25, 0x83, 0x45, + 0x0C, 0x2E, 0x83, 0x45, 0x0C, 0x37, 0x82, 0x45, 0x0C, 0x41, 0x83, 0x45, 0x0C, 0x4A, 0x83, 0x45, + 0x0C, 0x54, 0x83, 0x45, 0x0C, 0x5D, 0x82, 0x45, 0x0C, 0x66, 0x82, 0x45, 0x0C, 0x6E, 0x82, 0x45, + 0x0C, 0x77, 0x83, 0x44, 0x0C, 0x7C, 0x83, 0x45, 0x0C, 0x82, 0x83, 0x45, 0x0C, 0x85, 0x84, 0x45, + 0x0B, 0x8B, 0x84, 0x45, 0x0C, 0x8F, 0x84, 0x46, 0x0C, 0x92, 0x84, 0x47, 0x0F, 0x97, 0x89, 0x4E, + 0x19, 0xA1, 0x96, 0x60, 0x33, 0xB1, 0x9F, 0x73, 0x4F, 0xCB, 0xA0, 0x79, 0x5A, 0xE5, 0x9B, 0x74, + 0x56, 0xF4, 0x93, 0x6B, 0x4F, 0xFD, 0x8E, 0x64, 0x49, 0xFF, 0x87, 0x5C, 0x41, 0xFF, 0x7E, 0x52, + 0x37, 0xFE, 0x77, 0x49, 0x2E, 0xFF, 0x70, 0x42, 0x27, 0xFF, 0x6F, 0x3F, 0x23, 0xFF, 0x6D, 0x3E, + 0x22, 0xFF, 0x6C, 0x3D, 0x22, 0xFF, 0x6C, 0x3E, 0x23, 0xFF, 0x6C, 0x3E, 0x23, 0xFF, 0x6C, 0x3F, + 0x24, 0xFF, 0x6D, 0x3F, 0x24, 0xFF, 0x6E, 0x40, 0x25, 0xFF, 0x6E, 0x40, 0x25, 0xFF, 0x6F, 0x41, + 0x26, 0xFF, 0x70, 0x42, 0x26, 0xFF, 0x71, 0x43, 0x27, 0xFF, 0x72, 0x43, 0x28, 0xFF, 0x72, 0x44, + 0x29, 0xFF, 0x73, 0x44, 0x29, 0xFF, 0x74, 0x45, 0x2A, 0xFF, 0x74, 0x46, 0x2A, 0xFF, 0x74, 0x46, + 0x2B, 0xFF, 0x74, 0x47, 0x2B, 0xFF, 0x75, 0x48, 0x2C, 0xFF, 0x76, 0x49, 0x2D, 0xFF, 0x76, 0x49, + 0x2E, 0xFF, 0x77, 0x4A, 0x2F, 0xFF, 0x77, 0x4B, 0x30, 0xFF, 0x78, 0x4B, 0x30, 0xFF, 0x78, 0x4B, + 0x31, 0xFF, 0x79, 0x4B, 0x31, 0xFF, 0x78, 0x4C, 0x31, 0xFF, 0x79, 0x4C, 0x32, 0xFF, 0x7A, 0x4D, + 0x34, 0xFF, 0x7C, 0x4F, 0x36, 0xFF, 0x7F, 0x52, 0x38, 0xFF, 0x82, 0x55, 0x3B, 0xFF, 0x86, 0x5B, + 0x41, 0xFF, 0x8C, 0x63, 0x4A, 0xFF, 0x91, 0x69, 0x4F, 0xFF, 0x96, 0x70, 0x55, 0xFF, 0x9E, 0x77, + 0x5B, 0xFF, 0xA4, 0x7D, 0x61, 0xFC, 0xA7, 0x81, 0x65, 0xF1, 0xA7, 0x7E, 0x60, 0xDB, 0x9D, 0x6E, + 0x46, 0xC2, 0x8E, 0x56, 0x23, 0xB0, 0x84, 0x45, 0x0E, 0xA3, 0x82, 0x43, 0x0A, 0x9D, 0x83, 0x45, + 0x0C, 0x9B, 0x83, 0x44, 0x0B, 0x98, 0x84, 0x46, 0x0C, 0x96, 0x83, 0x45, 0x0C, 0x93, 0x83, 0x45, + 0x0D, 0x90, 0x83, 0x45, 0x0C, 0x8D, 0x82, 0x45, 0x0C, 0x89, 0x83, 0x45, 0x0C, 0x84, 0x83, 0x45, + 0x0C, 0x7E, 0x83, 0x45, 0x0C, 0x78, 0x83, 0x45, 0x0C, 0x71, 0x83, 0x45, 0x0C, 0x69, 0x83, 0x45, + 0x0C, 0x5F, 0x83, 0x45, 0x0C, 0x57, 0x82, 0x45, 0x0C, 0x4E, 0x83, 0x45, 0x0C, 0x44, 0x83, 0x45, + 0x0C, 0x3A, 0x83, 0x45, 0x0C, 0x31, 0x82, 0x45, 0x0C, 0x27, 0x83, 0x45, 0x0C, 0x1F, 0x83, 0x45, + 0x0C, 0x17, 0x83, 0x45, 0x0C, 0x12, 0x83, 0x45, 0x0C, 0x0D, 0x82, 0x45, 0x0C, 0x09, 0x82, 0x45, + 0x0C, 0x06, 0x82, 0x44, 0x0D, 0x04, 0x82, 0x44, 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x43, 0x0A, 0x01, 0x81, 0x44, 0x0B, 0x02, 0x82, 0x45, + 0x0C, 0x03, 0x83, 0x45, 0x0C, 0x04, 0x83, 0x45, 0x0C, 0x07, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, + 0x0C, 0x0F, 0x83, 0x45, 0x0C, 0x14, 0x83, 0x45, 0x0C, 0x1B, 0x83, 0x45, 0x0C, 0x22, 0x83, 0x45, + 0x0C, 0x2A, 0x83, 0x45, 0x0D, 0x32, 0x83, 0x45, 0x0D, 0x3B, 0x83, 0x45, 0x0C, 0x44, 0x82, 0x45, + 0x0C, 0x4D, 0x83, 0x45, 0x0C, 0x54, 0x83, 0x45, 0x0D, 0x5D, 0x82, 0x44, 0x0C, 0x65, 0x82, 0x44, + 0x0C, 0x6C, 0x82, 0x44, 0x0C, 0x71, 0x83, 0x45, 0x0B, 0x76, 0x84, 0x45, 0x0B, 0x7B, 0x83, 0x44, + 0x0C, 0x80, 0x82, 0x43, 0x0C, 0x84, 0x8B, 0x4E, 0x1A, 0x8E, 0x99, 0x64, 0x39, 0xA4, 0xA3, 0x77, + 0x53, 0xC5, 0xA2, 0x7A, 0x5D, 0xE0, 0x9A, 0x73, 0x57, 0xF3, 0x93, 0x6B, 0x4E, 0xFB, 0x8B, 0x5F, + 0x42, 0xFE, 0x82, 0x55, 0x38, 0xFF, 0x7A, 0x4C, 0x30, 0xFF, 0x73, 0x45, 0x28, 0xFF, 0x6F, 0x40, + 0x25, 0xFF, 0x6D, 0x3D, 0x21, 0xFF, 0x6C, 0x3C, 0x1F, 0xFF, 0x6C, 0x3C, 0x1F, 0xFF, 0x6C, 0x3C, + 0x1F, 0xFF, 0x6C, 0x3C, 0x1F, 0xFF, 0x6C, 0x3D, 0x20, 0xFF, 0x6D, 0x3E, 0x20, 0xFF, 0x6E, 0x3F, + 0x21, 0xFF, 0x6F, 0x3F, 0x22, 0xFF, 0x6F, 0x40, 0x23, 0xFF, 0x70, 0x41, 0x23, 0xFF, 0x71, 0x42, + 0x24, 0xFF, 0x72, 0x43, 0x25, 0xFF, 0x73, 0x43, 0x26, 0xFF, 0x74, 0x44, 0x26, 0xFF, 0x75, 0x45, + 0x27, 0xFF, 0x75, 0x46, 0x28, 0xFF, 0x76, 0x46, 0x29, 0xFF, 0x76, 0x47, 0x29, 0xFF, 0x76, 0x47, + 0x2A, 0xFF, 0x77, 0x48, 0x2A, 0xFF, 0x77, 0x48, 0x2A, 0xFF, 0x78, 0x49, 0x2B, 0xFF, 0x78, 0x49, + 0x2C, 0xFF, 0x79, 0x4A, 0x2C, 0xFF, 0x79, 0x4A, 0x2D, 0xFF, 0x79, 0x4B, 0x2D, 0xFF, 0x79, 0x4B, + 0x2E, 0xFF, 0x79, 0x4C, 0x2E, 0xFF, 0x79, 0x4C, 0x2F, 0xFF, 0x79, 0x4C, 0x30, 0xFF, 0x79, 0x4C, + 0x31, 0xFF, 0x7A, 0x4C, 0x31, 0xFF, 0x7B, 0x4E, 0x33, 0xFF, 0x7D, 0x4F, 0x34, 0xFF, 0x7E, 0x51, + 0x36, 0xFF, 0x80, 0x53, 0x39, 0xFF, 0x83, 0x58, 0x3D, 0xFF, 0x88, 0x5E, 0x44, 0xFF, 0x8F, 0x66, + 0x4C, 0xFF, 0x95, 0x6D, 0x53, 0xFF, 0x9A, 0x74, 0x5A, 0xFF, 0x9E, 0x79, 0x60, 0xFD, 0xA4, 0x80, + 0x66, 0xEE, 0xA7, 0x7F, 0x60, 0xD4, 0x9E, 0x6F, 0x47, 0xB6, 0x8D, 0x52, 0x1F, 0xA1, 0x84, 0x45, + 0x0D, 0x93, 0x83, 0x44, 0x0A, 0x8C, 0x84, 0x45, 0x0B, 0x88, 0x84, 0x45, 0x0C, 0x86, 0x83, 0x45, + 0x0C, 0x85, 0x83, 0x45, 0x0C, 0x83, 0x83, 0x45, 0x0D, 0x7E, 0x83, 0x45, 0x0D, 0x79, 0x83, 0x45, + 0x0C, 0x74, 0x83, 0x45, 0x0D, 0x6E, 0x83, 0x45, 0x0C, 0x67, 0x83, 0x45, 0x0C, 0x60, 0x83, 0x45, + 0x0C, 0x58, 0x83, 0x45, 0x0C, 0x50, 0x83, 0x45, 0x0C, 0x47, 0x83, 0x45, 0x0C, 0x3E, 0x82, 0x45, + 0x0C, 0x34, 0x83, 0x45, 0x0C, 0x2C, 0x83, 0x45, 0x0C, 0x24, 0x83, 0x45, 0x0C, 0x1C, 0x83, 0x45, + 0x0C, 0x15, 0x83, 0x45, 0x0C, 0x10, 0x83, 0x45, 0x0C, 0x0C, 0x82, 0x45, 0x0C, 0x08, 0x82, 0x45, + 0x0C, 0x05, 0x82, 0x44, 0x0D, 0x03, 0x82, 0x44, 0x0E, 0x02, 0x83, 0x45, 0x0E, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x43, 0x09, 0x01, 0x81, 0x43, 0x0A, 0x02, 0x82, 0x44, + 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x04, 0x83, 0x45, 0x0C, 0x06, 0x83, 0x45, 0x0C, 0x09, 0x83, 0x45, + 0x0C, 0x0C, 0x83, 0x45, 0x0C, 0x11, 0x83, 0x45, 0x0C, 0x17, 0x83, 0x45, 0x0D, 0x1D, 0x83, 0x45, + 0x0D, 0x25, 0x83, 0x45, 0x0D, 0x2C, 0x83, 0x45, 0x0D, 0x34, 0x83, 0x45, 0x0C, 0x3C, 0x82, 0x45, + 0x0B, 0x45, 0x83, 0x45, 0x0C, 0x4C, 0x83, 0x45, 0x0D, 0x53, 0x83, 0x45, 0x0C, 0x5A, 0x83, 0x45, + 0x0C, 0x60, 0x83, 0x45, 0x0D, 0x65, 0x85, 0x47, 0x0D, 0x6B, 0x83, 0x44, 0x0A, 0x71, 0x82, 0x46, + 0x0C, 0x77, 0x91, 0x5C, 0x2A, 0x89, 0xA1, 0x74, 0x4E, 0xAC, 0xA3, 0x7B, 0x5C, 0xD4, 0x9E, 0x74, + 0x57, 0xED, 0x93, 0x68, 0x4C, 0xFA, 0x87, 0x5C, 0x41, 0xFF, 0x7E, 0x51, 0x35, 0xFF, 0x75, 0x46, + 0x2A, 0xFF, 0x6F, 0x40, 0x23, 0xFF, 0x6B, 0x3D, 0x1F, 0xFF, 0x6A, 0x3A, 0x1D, 0xFF, 0x69, 0x3A, + 0x1D, 0xFF, 0x69, 0x39, 0x1D, 0xFF, 0x6A, 0x3A, 0x1D, 0xFF, 0x6B, 0x3A, 0x1D, 0xFF, 0x6C, 0x3B, + 0x1E, 0xFF, 0x6C, 0x3B, 0x1E, 0xFF, 0x6D, 0x3D, 0x1F, 0xFF, 0x6E, 0x3E, 0x1F, 0xFF, 0x6F, 0x3F, + 0x20, 0xFF, 0x70, 0x40, 0x21, 0xFF, 0x71, 0x41, 0x21, 0xFF, 0x72, 0x42, 0x22, 0xFF, 0x73, 0x43, + 0x23, 0xFF, 0x74, 0x44, 0x24, 0xFF, 0x75, 0x44, 0x24, 0xFF, 0x76, 0x45, 0x25, 0xFF, 0x77, 0x46, + 0x26, 0xFF, 0x77, 0x47, 0x27, 0xFF, 0x78, 0x47, 0x28, 0xFF, 0x78, 0x47, 0x28, 0xFF, 0x78, 0x48, + 0x29, 0xFF, 0x79, 0x49, 0x29, 0xFF, 0x79, 0x49, 0x2A, 0xFF, 0x7A, 0x49, 0x2A, 0xFF, 0x7A, 0x4A, + 0x2A, 0xFF, 0x7B, 0x4A, 0x2B, 0xFF, 0x7A, 0x4B, 0x2B, 0xFF, 0x7B, 0x4B, 0x2C, 0xFF, 0x7A, 0x4C, + 0x2C, 0xFF, 0x7B, 0x4C, 0x2D, 0xFF, 0x7B, 0x4C, 0x2E, 0xFF, 0x7B, 0x4C, 0x2F, 0xFF, 0x7B, 0x4D, + 0x2F, 0xFF, 0x7B, 0x4D, 0x30, 0xFF, 0x7C, 0x4E, 0x31, 0xFF, 0x7C, 0x4E, 0x32, 0xFF, 0x7D, 0x4F, + 0x33, 0xFF, 0x7E, 0x50, 0x34, 0xFF, 0x7E, 0x51, 0x35, 0xFF, 0x80, 0x53, 0x38, 0xFF, 0x83, 0x57, + 0x3C, 0xFF, 0x88, 0x5E, 0x43, 0xFF, 0x8E, 0x65, 0x4B, 0xFF, 0x96, 0x6E, 0x54, 0xFF, 0x9E, 0x77, + 0x5D, 0xFF, 0xA4, 0x7E, 0x62, 0xF9, 0xA7, 0x83, 0x65, 0xE6, 0xA8, 0x7F, 0x5E, 0xC5, 0x9A, 0x68, + 0x3A, 0xA1, 0x8A, 0x4F, 0x18, 0x8C, 0x81, 0x42, 0x09, 0x80, 0x82, 0x43, 0x0A, 0x7B, 0x84, 0x46, + 0x0C, 0x79, 0x84, 0x45, 0x0B, 0x76, 0x84, 0x45, 0x0C, 0x72, 0x83, 0x45, 0x0C, 0x6E, 0x83, 0x45, + 0x0D, 0x68, 0x83, 0x45, 0x0C, 0x63, 0x83, 0x45, 0x0C, 0x5C, 0x83, 0x45, 0x0C, 0x55, 0x83, 0x45, + 0x0C, 0x4E, 0x83, 0x45, 0x0C, 0x47, 0x83, 0x45, 0x0C, 0x3E, 0x83, 0x45, 0x0C, 0x36, 0x82, 0x45, + 0x0C, 0x2E, 0x83, 0x45, 0x0C, 0x26, 0x82, 0x45, 0x0C, 0x20, 0x83, 0x45, 0x0C, 0x19, 0x82, 0x45, + 0x0C, 0x13, 0x83, 0x45, 0x0C, 0x0E, 0x83, 0x45, 0x0C, 0x0A, 0x83, 0x45, 0x0C, 0x07, 0x83, 0x45, + 0x0C, 0x04, 0x82, 0x45, 0x0C, 0x03, 0x82, 0x45, 0x0E, 0x02, 0x85, 0x48, 0x12, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x43, 0x09, 0x01, 0x81, 0x43, 0x0A, 0x02, 0x82, 0x45, + 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x03, 0x83, 0x45, 0x0C, 0x05, 0x83, 0x45, 0x0C, 0x08, 0x82, 0x45, + 0x0C, 0x0B, 0x83, 0x45, 0x0D, 0x0F, 0x83, 0x45, 0x0D, 0x14, 0x83, 0x45, 0x0D, 0x19, 0x83, 0x45, + 0x0C, 0x1F, 0x83, 0x45, 0x0C, 0x25, 0x83, 0x45, 0x0C, 0x2B, 0x83, 0x45, 0x0C, 0x32, 0x83, 0x45, + 0x0C, 0x3B, 0x83, 0x45, 0x0C, 0x40, 0x83, 0x44, 0x0B, 0x46, 0x84, 0x45, 0x0B, 0x4D, 0x84, 0x46, + 0x0E, 0x53, 0x83, 0x44, 0x0B, 0x59, 0x84, 0x45, 0x0A, 0x61, 0x8F, 0x57, 0x24, 0x6E, 0xA4, 0x76, + 0x4E, 0x91, 0xA4, 0x7C, 0x5E, 0xBC, 0x9D, 0x75, 0x58, 0xE4, 0x95, 0x6B, 0x4D, 0xF7, 0x89, 0x5D, + 0x3E, 0xFD, 0x7E, 0x50, 0x32, 0xFE, 0x76, 0x46, 0x2B, 0xFF, 0x6E, 0x3E, 0x21, 0xFF, 0x6A, 0x3A, + 0x1D, 0xFF, 0x69, 0x38, 0x1A, 0xFF, 0x68, 0x38, 0x1A, 0xFF, 0x69, 0x38, 0x1A, 0xFF, 0x69, 0x39, + 0x1A, 0xFF, 0x6A, 0x39, 0x1B, 0xFF, 0x6B, 0x3A, 0x1B, 0xFF, 0x6C, 0x3A, 0x1C, 0xFF, 0x6E, 0x3B, + 0x1D, 0xFF, 0x6F, 0x3C, 0x1D, 0xFF, 0x6F, 0x3E, 0x1E, 0xFF, 0x70, 0x3F, 0x1F, 0xFF, 0x72, 0x40, + 0x20, 0xFF, 0x73, 0x41, 0x20, 0xFF, 0x74, 0x42, 0x21, 0xFF, 0x75, 0x43, 0x22, 0xFF, 0x76, 0x45, + 0x23, 0xFF, 0x77, 0x45, 0x24, 0xFF, 0x78, 0x46, 0x24, 0xFF, 0x79, 0x47, 0x25, 0xFF, 0x79, 0x47, + 0x25, 0xFF, 0x7A, 0x48, 0x26, 0xFF, 0x7B, 0x49, 0x27, 0xFF, 0x7B, 0x49, 0x27, 0xFF, 0x7C, 0x4A, + 0x28, 0xFF, 0x7C, 0x4B, 0x28, 0xFF, 0x7C, 0x4B, 0x29, 0xFF, 0x7D, 0x4C, 0x2A, 0xFF, 0x7D, 0x4D, + 0x2A, 0xFF, 0x7E, 0x4D, 0x2B, 0xFF, 0x7D, 0x4D, 0x2B, 0xFF, 0x7E, 0x4D, 0x2C, 0xFF, 0x7E, 0x4E, + 0x2C, 0xFF, 0x7E, 0x4E, 0x2D, 0xFF, 0x7E, 0x4E, 0x2D, 0xFF, 0x7E, 0x4E, 0x2E, 0xFF, 0x7D, 0x4F, + 0x2E, 0xFF, 0x7D, 0x4E, 0x2F, 0xFF, 0x7D, 0x4E, 0x2F, 0xFF, 0x7D, 0x4E, 0x30, 0xFF, 0x7D, 0x4F, + 0x31, 0xFF, 0x7E, 0x4F, 0x31, 0xFF, 0x7E, 0x50, 0x32, 0xFF, 0x7E, 0x51, 0x33, 0xFF, 0x7F, 0x52, + 0x35, 0xFF, 0x80, 0x54, 0x37, 0xFF, 0x83, 0x57, 0x3C, 0xFF, 0x89, 0x5E, 0x44, 0xFF, 0x91, 0x68, + 0x4D, 0xFF, 0x97, 0x6F, 0x53, 0xFE, 0x9D, 0x77, 0x5C, 0xFD, 0xA2, 0x7D, 0x63, 0xF3, 0xA7, 0x83, + 0x67, 0xD5, 0xA7, 0x7D, 0x5A, 0xAD, 0x98, 0x63, 0x36, 0x8A, 0x85, 0x47, 0x10, 0x74, 0x81, 0x42, + 0x09, 0x67, 0x83, 0x44, 0x0B, 0x64, 0x84, 0x45, 0x0B, 0x62, 0x83, 0x44, 0x0C, 0x60, 0x83, 0x45, + 0x0C, 0x5A, 0x83, 0x46, 0x0D, 0x56, 0x83, 0x45, 0x0C, 0x50, 0x84, 0x45, 0x0D, 0x4A, 0x83, 0x45, + 0x0C, 0x43, 0x83, 0x45, 0x0C, 0x3D, 0x83, 0x45, 0x0C, 0x35, 0x83, 0x45, 0x0C, 0x2E, 0x83, 0x45, + 0x0C, 0x27, 0x83, 0x45, 0x0C, 0x20, 0x82, 0x45, 0x0C, 0x1A, 0x83, 0x45, 0x0C, 0x14, 0x82, 0x45, + 0x0C, 0x0F, 0x83, 0x45, 0x0C, 0x0B, 0x83, 0x45, 0x0D, 0x08, 0x83, 0x45, 0x0C, 0x05, 0x82, 0x44, + 0x0A, 0x04, 0x81, 0x44, 0x0B, 0x03, 0x83, 0x48, 0x12, 0x01, 0x8C, 0x53, 0x1E, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x43, 0x09, 0x01, 0x81, 0x44, 0x0A, 0x01, 0x82, 0x45, + 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x02, 0x83, 0x45, 0x0C, 0x04, 0x83, 0x45, 0x0C, 0x07, 0x83, 0x45, + 0x0D, 0x09, 0x83, 0x45, 0x0D, 0x0C, 0x82, 0x45, 0x0D, 0x10, 0x83, 0x45, 0x0D, 0x14, 0x83, 0x45, + 0x0D, 0x19, 0x83, 0x45, 0x0C, 0x1E, 0x82, 0x45, 0x0C, 0x24, 0x84, 0x44, 0x0C, 0x29, 0x84, 0x46, + 0x0D, 0x2F, 0x84, 0x45, 0x0C, 0x34, 0x84, 0x45, 0x0B, 0x3A, 0x83, 0x44, 0x0B, 0x40, 0x7F, 0x40, + 0x05, 0x46, 0x85, 0x47, 0x0F, 0x52, 0x99, 0x69, 0x3E, 0x68, 0xAB, 0x81, 0x62, 0x98, 0xA3, 0x7A, + 0x5B, 0xD4, 0x97, 0x6D, 0x50, 0xF5, 0x8B, 0x60, 0x44, 0xFF, 0x81, 0x54, 0x37, 0xFF, 0x76, 0x46, + 0x29, 0xFF, 0x6F, 0x3E, 0x21, 0xFE, 0x69, 0x39, 0x1C, 0xFF, 0x67, 0x36, 0x18, 0xFF, 0x66, 0x35, + 0x18, 0xFF, 0x67, 0x35, 0x18, 0xFF, 0x67, 0x36, 0x18, 0xFF, 0x68, 0x37, 0x18, 0xFF, 0x69, 0x38, + 0x19, 0xFF, 0x6B, 0x39, 0x1A, 0xFF, 0x6C, 0x3A, 0x1B, 0xFF, 0x6E, 0x3C, 0x1C, 0xFF, 0x70, 0x3D, + 0x1D, 0xFF, 0x72, 0x3E, 0x1D, 0xFF, 0x73, 0x40, 0x1E, 0xFF, 0x74, 0x42, 0x1F, 0xFF, 0x75, 0x43, + 0x20, 0xFF, 0x76, 0x44, 0x21, 0xFF, 0x77, 0x45, 0x21, 0xFF, 0x78, 0x45, 0x22, 0xFF, 0x79, 0x47, + 0x23, 0xFF, 0x7A, 0x48, 0x24, 0xFF, 0x7B, 0x49, 0x24, 0xFF, 0x7C, 0x4A, 0x25, 0xFF, 0x7C, 0x4A, + 0x25, 0xFF, 0x7D, 0x4A, 0x25, 0xFF, 0x7E, 0x4B, 0x27, 0xFF, 0x7F, 0x4C, 0x27, 0xFF, 0x7F, 0x4D, + 0x28, 0xFF, 0x7F, 0x4D, 0x28, 0xFF, 0x7F, 0x4E, 0x29, 0xFF, 0x80, 0x4E, 0x29, 0xFF, 0x80, 0x4F, + 0x2A, 0xFF, 0x81, 0x4F, 0x2B, 0xFF, 0x80, 0x4F, 0x2B, 0xFF, 0x81, 0x4F, 0x2B, 0xFF, 0x81, 0x50, + 0x2C, 0xFF, 0x81, 0x50, 0x2D, 0xFF, 0x81, 0x50, 0x2D, 0xFF, 0x81, 0x50, 0x2D, 0xFF, 0x80, 0x51, + 0x2E, 0xFF, 0x80, 0x50, 0x2E, 0xFF, 0x80, 0x50, 0x2F, 0xFF, 0x7F, 0x4F, 0x2F, 0xFF, 0x7F, 0x4F, + 0x30, 0xFF, 0x7F, 0x4F, 0x30, 0xFF, 0x7F, 0x50, 0x31, 0xFF, 0x7F, 0x51, 0x32, 0xFF, 0x7F, 0x51, + 0x33, 0xFF, 0x7F, 0x52, 0x34, 0xFF, 0x80, 0x52, 0x35, 0xFF, 0x81, 0x55, 0x39, 0xFF, 0x85, 0x59, + 0x3E, 0xFF, 0x8B, 0x62, 0x46, 0xFF, 0x92, 0x6B, 0x4F, 0xFF, 0x9A, 0x73, 0x57, 0xFF, 0xA3, 0x7C, + 0x60, 0xFA, 0xA7, 0x81, 0x65, 0xE6, 0xAA, 0x86, 0x68, 0xBA, 0xA3, 0x76, 0x50, 0x8A, 0x8C, 0x52, + 0x1F, 0x67, 0x83, 0x43, 0x0A, 0x58, 0x82, 0x42, 0x0A, 0x53, 0x83, 0x45, 0x0B, 0x4F, 0x84, 0x46, + 0x0B, 0x4B, 0x83, 0x45, 0x0C, 0x48, 0x83, 0x45, 0x0D, 0x43, 0x83, 0x45, 0x0C, 0x3E, 0x83, 0x45, + 0x0D, 0x38, 0x83, 0x45, 0x0C, 0x31, 0x82, 0x45, 0x0C, 0x2C, 0x83, 0x45, 0x0C, 0x26, 0x83, 0x45, + 0x0C, 0x20, 0x83, 0x45, 0x0C, 0x1A, 0x82, 0x45, 0x0C, 0x15, 0x83, 0x45, 0x0C, 0x11, 0x82, 0x45, + 0x0C, 0x0D, 0x83, 0x45, 0x0C, 0x0A, 0x82, 0x45, 0x0C, 0x07, 0x83, 0x44, 0x0B, 0x05, 0x82, 0x44, + 0x0A, 0x03, 0x81, 0x44, 0x0D, 0x02, 0x8D, 0x55, 0x23, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x45, + 0x0C, 0x01, 0x82, 0x44, 0x0C, 0x02, 0x83, 0x45, 0x0D, 0x04, 0x83, 0x45, 0x0D, 0x05, 0x82, 0x45, + 0x0D, 0x07, 0x82, 0x45, 0x0C, 0x0A, 0x82, 0x45, 0x0C, 0x0C, 0x82, 0x45, 0x0D, 0x10, 0x83, 0x45, + 0x0E, 0x13, 0x83, 0x45, 0x0E, 0x18, 0x82, 0x44, 0x0C, 0x1E, 0x82, 0x44, 0x0B, 0x21, 0x83, 0x44, + 0x0A, 0x24, 0x87, 0x46, 0x0D, 0x2A, 0x83, 0x41, 0x09, 0x31, 0x7C, 0x3D, 0x04, 0x35, 0x91, 0x57, + 0x24, 0x45, 0xAA, 0x80, 0x5C, 0x6A, 0xAC, 0x86, 0x69, 0xAA, 0x9E, 0x75, 0x57, 0xE5, 0x90, 0x66, + 0x48, 0xFC, 0x85, 0x59, 0x3B, 0xFF, 0x7D, 0x4D, 0x2F, 0xFF, 0x71, 0x3F, 0x21, 0xFF, 0x6B, 0x39, + 0x1B, 0xFF, 0x68, 0x36, 0x17, 0xFF, 0x66, 0x34, 0x15, 0xFF, 0x66, 0x34, 0x15, 0xFF, 0x67, 0x34, + 0x15, 0xFF, 0x69, 0x35, 0x16, 0xFF, 0x6A, 0x36, 0x16, 0xFF, 0x6B, 0x36, 0x17, 0xFF, 0x6C, 0x38, + 0x17, 0xFF, 0x6D, 0x39, 0x18, 0xFF, 0x6E, 0x3B, 0x19, 0xFF, 0x6F, 0x3C, 0x1A, 0xFF, 0x71, 0x3E, + 0x1B, 0xFF, 0x73, 0x3F, 0x1C, 0xFF, 0x74, 0x41, 0x1C, 0xFF, 0x76, 0x42, 0x1D, 0xFF, 0x77, 0x43, + 0x1E, 0xFF, 0x79, 0x45, 0x1F, 0xFF, 0x7A, 0x46, 0x21, 0xFF, 0x7B, 0x47, 0x21, 0xFF, 0x7C, 0x48, + 0x22, 0xFF, 0x7D, 0x49, 0x24, 0xFF, 0x7E, 0x4B, 0x25, 0xFF, 0x7F, 0x4C, 0x25, 0xFF, 0x7F, 0x4C, + 0x25, 0xFF, 0x80, 0x4D, 0x26, 0xFF, 0x80, 0x4D, 0x26, 0xFF, 0x81, 0x4D, 0x27, 0xFF, 0x81, 0x4E, + 0x28, 0xFF, 0x82, 0x4E, 0x28, 0xFF, 0x82, 0x4F, 0x29, 0xFF, 0x82, 0x4F, 0x29, 0xFF, 0x82, 0x50, + 0x2A, 0xFF, 0x83, 0x51, 0x2B, 0xFF, 0x83, 0x51, 0x2B, 0xFF, 0x84, 0x51, 0x2C, 0xFF, 0x83, 0x51, + 0x2C, 0xFF, 0x84, 0x51, 0x2D, 0xFF, 0x84, 0x51, 0x2D, 0xFF, 0x83, 0x51, 0x2E, 0xFF, 0x83, 0x52, + 0x2E, 0xFF, 0x82, 0x52, 0x2F, 0xFF, 0x82, 0x52, 0x2F, 0xFF, 0x82, 0x52, 0x2F, 0xFF, 0x81, 0x52, + 0x30, 0xFF, 0x81, 0x51, 0x30, 0xFF, 0x81, 0x51, 0x30, 0xFF, 0x81, 0x51, 0x31, 0xFF, 0x81, 0x51, + 0x31, 0xFF, 0x81, 0x51, 0x32, 0xFF, 0x81, 0x52, 0x33, 0xFF, 0x81, 0x52, 0x34, 0xFF, 0x82, 0x54, + 0x37, 0xFF, 0x84, 0x57, 0x3A, 0xFF, 0x88, 0x5D, 0x40, 0xFF, 0x8F, 0x66, 0x49, 0xFF, 0x98, 0x70, + 0x55, 0xFF, 0x9F, 0x78, 0x5C, 0xFE, 0xA5, 0x80, 0x63, 0xF2, 0xAC, 0x87, 0x6B, 0xCC, 0xAE, 0x87, + 0x66, 0x93, 0x9A, 0x66, 0x3A, 0x62, 0x86, 0x46, 0x0D, 0x47, 0x81, 0x3F, 0x05, 0x3F, 0x84, 0x44, + 0x0B, 0x3B, 0x84, 0x46, 0x0C, 0x38, 0x83, 0x45, 0x0C, 0x36, 0x83, 0x45, 0x0D, 0x32, 0x83, 0x45, + 0x0C, 0x2C, 0x84, 0x46, 0x0D, 0x27, 0x83, 0x45, 0x0C, 0x24, 0x82, 0x45, 0x0C, 0x1F, 0x83, 0x45, + 0x0C, 0x1A, 0x83, 0x45, 0x0C, 0x15, 0x82, 0x45, 0x0C, 0x11, 0x83, 0x45, 0x0C, 0x0D, 0x82, 0x45, + 0x0C, 0x0B, 0x83, 0x45, 0x0C, 0x08, 0x82, 0x45, 0x0C, 0x05, 0x83, 0x45, 0x0C, 0x04, 0x82, 0x45, + 0x0C, 0x02, 0x85, 0x49, 0x12, 0x01, 0xA3, 0x71, 0x44, 0x01, 0x9F, 0x71, 0x4C, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x83, 0x45, 0x0C, 0x01, 0x83, 0x45, 0x0D, 0x03, 0x83, 0x45, 0x0C, 0x04, 0x81, 0x44, + 0x0B, 0x05, 0x82, 0x45, 0x0C, 0x07, 0x82, 0x46, 0x0C, 0x09, 0x83, 0x46, 0x0C, 0x0C, 0x82, 0x45, + 0x0C, 0x0F, 0x83, 0x45, 0x0C, 0x11, 0x84, 0x46, 0x0C, 0x16, 0x84, 0x45, 0x0D, 0x19, 0x86, 0x47, + 0x09, 0x1D, 0x78, 0x37, 0x00, 0x21, 0x7E, 0x42, 0x07, 0x27, 0x9D, 0x6B, 0x3A, 0x3A, 0xB0, 0x8A, + 0x6A, 0x6E, 0xA7, 0x82, 0x67, 0xBC, 0x97, 0x6E, 0x51, 0xED, 0x88, 0x5C, 0x3E, 0xFD, 0x7C, 0x4E, + 0x30, 0xFF, 0x73, 0x42, 0x24, 0xFF, 0x68, 0x35, 0x16, 0xFF, 0x63, 0x2F, 0x10, 0xFF, 0x61, 0x2E, + 0x0F, 0xFF, 0x60, 0x2D, 0x0E, 0xFF, 0x61, 0x2D, 0x0D, 0xFF, 0x63, 0x2E, 0x0D, 0xFF, 0x65, 0x2F, + 0x0E, 0xFF, 0x66, 0x30, 0x0F, 0xFF, 0x68, 0x31, 0x10, 0xFF, 0x6A, 0x32, 0x10, 0xFF, 0x6B, 0x34, + 0x10, 0xFF, 0x6C, 0x36, 0x11, 0xFF, 0x6E, 0x37, 0x12, 0xFF, 0x6F, 0x39, 0x13, 0xFF, 0x71, 0x3B, + 0x14, 0xFF, 0x73, 0x3C, 0x16, 0xFF, 0x74, 0x3E, 0x17, 0xFF, 0x76, 0x3F, 0x18, 0xFF, 0x77, 0x41, + 0x18, 0xFF, 0x79, 0x42, 0x1A, 0xFF, 0x7A, 0x44, 0x1C, 0xFF, 0x7C, 0x46, 0x1E, 0xFF, 0x7C, 0x47, + 0x1E, 0xFF, 0x7D, 0x48, 0x20, 0xFF, 0x7E, 0x4A, 0x22, 0xFF, 0x80, 0x4B, 0x23, 0xFF, 0x80, 0x4D, + 0x24, 0xFF, 0x81, 0x4D, 0x24, 0xFF, 0x81, 0x4E, 0x25, 0xFF, 0x82, 0x4E, 0x26, 0xFF, 0x82, 0x4F, + 0x27, 0xFF, 0x84, 0x4F, 0x28, 0xFF, 0x84, 0x50, 0x29, 0xFF, 0x85, 0x51, 0x29, 0xFF, 0x85, 0x52, + 0x2A, 0xFF, 0x85, 0x52, 0x2A, 0xFF, 0x85, 0x53, 0x2B, 0xFF, 0x86, 0x53, 0x2B, 0xFF, 0x85, 0x53, + 0x2C, 0xFF, 0x86, 0x53, 0x2C, 0xFF, 0x86, 0x53, 0x2D, 0xFF, 0x86, 0x53, 0x2E, 0xFF, 0x85, 0x54, + 0x2E, 0xFF, 0x85, 0x54, 0x2F, 0xFF, 0x85, 0x54, 0x2F, 0xFF, 0x85, 0x54, 0x2F, 0xFF, 0x84, 0x54, + 0x2F, 0xFF, 0x84, 0x54, 0x30, 0xFF, 0x84, 0x53, 0x30, 0xFF, 0x84, 0x52, 0x30, 0xFF, 0x83, 0x52, + 0x31, 0xFF, 0x82, 0x52, 0x31, 0xFF, 0x82, 0x53, 0x32, 0xFF, 0x82, 0x52, 0x33, 0xFF, 0x81, 0x53, + 0x34, 0xFF, 0x82, 0x54, 0x35, 0xFF, 0x82, 0x55, 0x36, 0xFF, 0x84, 0x59, 0x3B, 0xFF, 0x8A, 0x60, + 0x44, 0xFF, 0x95, 0x6D, 0x51, 0xFF, 0x9F, 0x78, 0x5C, 0xFF, 0xA4, 0x7E, 0x62, 0xF7, 0xAB, 0x85, + 0x69, 0xDA, 0xB3, 0x8C, 0x6F, 0x9B, 0xA8, 0x7B, 0x57, 0x58, 0x89, 0x4E, 0x18, 0x39, 0x7A, 0x38, + 0x00, 0x30, 0x82, 0x41, 0x07, 0x2C, 0x84, 0x47, 0x0B, 0x28, 0x84, 0x46, 0x0D, 0x25, 0x83, 0x45, + 0x0C, 0x21, 0x83, 0x44, 0x0C, 0x20, 0x83, 0x45, 0x0C, 0x1C, 0x83, 0x45, 0x0C, 0x17, 0x82, 0x45, + 0x0C, 0x13, 0x83, 0x45, 0x0C, 0x10, 0x82, 0x45, 0x0C, 0x0D, 0x83, 0x45, 0x0C, 0x0B, 0x82, 0x45, + 0x0C, 0x09, 0x83, 0x45, 0x0C, 0x06, 0x82, 0x44, 0x0B, 0x04, 0x83, 0x45, 0x0C, 0x03, 0x82, 0x45, + 0x0C, 0x01, 0x87, 0x49, 0x12, 0x01, 0x9B, 0x69, 0x3A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x48, + 0x10, 0x01, 0x84, 0x47, 0x0F, 0x02, 0x83, 0x44, 0x0C, 0x02, 0x82, 0x44, 0x0A, 0x03, 0x81, 0x44, + 0x0A, 0x03, 0x81, 0x45, 0x0B, 0x04, 0x82, 0x46, 0x0B, 0x06, 0x82, 0x46, 0x0A, 0x08, 0x83, 0x47, + 0x0B, 0x0A, 0x84, 0x47, 0x0A, 0x0C, 0x7F, 0x3F, 0x08, 0x0E, 0x80, 0x3F, 0x04, 0x12, 0x77, 0x36, + 0x00, 0x17, 0x8C, 0x52, 0x1C, 0x1B, 0xB2, 0x89, 0x63, 0x37, 0xB0, 0x8C, 0x6F, 0x79, 0x9F, 0x78, + 0x5D, 0xCB, 0x96, 0x6A, 0x4C, 0xF3, 0x86, 0x58, 0x38, 0xFD, 0x75, 0x45, 0x25, 0xFF, 0x6B, 0x38, + 0x18, 0xFF, 0x63, 0x2E, 0x0D, 0xFF, 0x61, 0x2A, 0x0A, 0xFF, 0x61, 0x2A, 0x09, 0xFF, 0x5F, 0x29, + 0x08, 0xFF, 0x60, 0x2A, 0x07, 0xFF, 0x61, 0x2A, 0x07, 0xFF, 0x63, 0x2A, 0x07, 0xFF, 0x64, 0x2B, + 0x08, 0xFF, 0x65, 0x2C, 0x08, 0xFF, 0x67, 0x2E, 0x09, 0xFF, 0x68, 0x2F, 0x09, 0xFF, 0x6A, 0x31, + 0x09, 0xFF, 0x6B, 0x32, 0x09, 0xFF, 0x6C, 0x33, 0x0A, 0xFF, 0x6D, 0x34, 0x0B, 0xFF, 0x6F, 0x35, + 0x0B, 0xFF, 0x70, 0x36, 0x0C, 0xFF, 0x71, 0x37, 0x0D, 0xFF, 0x72, 0x38, 0x0D, 0xFF, 0x74, 0x3A, + 0x0E, 0xFF, 0x75, 0x3B, 0x0E, 0xFF, 0x76, 0x3C, 0x10, 0xFF, 0x77, 0x3D, 0x11, 0xFF, 0x78, 0x40, + 0x13, 0xFF, 0x7A, 0x41, 0x16, 0xFF, 0x7B, 0x43, 0x18, 0xFF, 0x7D, 0x45, 0x1B, 0xFF, 0x7F, 0x48, + 0x1D, 0xFF, 0x81, 0x4B, 0x20, 0xFF, 0x81, 0x4D, 0x21, 0xFF, 0x83, 0x4E, 0x24, 0xFF, 0x83, 0x4F, + 0x25, 0xFF, 0x85, 0x51, 0x27, 0xFF, 0x86, 0x52, 0x28, 0xFF, 0x88, 0x53, 0x29, 0xFF, 0x87, 0x53, + 0x2A, 0xFF, 0x88, 0x53, 0x2A, 0xFF, 0x88, 0x54, 0x2A, 0xFF, 0x88, 0x54, 0x2B, 0xFF, 0x88, 0x55, + 0x2B, 0xFF, 0x88, 0x55, 0x2C, 0xFF, 0x88, 0x55, 0x2C, 0xFF, 0x88, 0x55, 0x2D, 0xFF, 0x88, 0x55, + 0x2D, 0xFF, 0x88, 0x55, 0x2E, 0xFF, 0x88, 0x55, 0x2E, 0xFF, 0x88, 0x55, 0x2F, 0xFF, 0x88, 0x55, + 0x2F, 0xFF, 0x87, 0x55, 0x30, 0xFF, 0x87, 0x55, 0x30, 0xFF, 0x86, 0x55, 0x31, 0xFF, 0x86, 0x55, + 0x31, 0xFF, 0x85, 0x54, 0x31, 0xFF, 0x84, 0x54, 0x31, 0xFF, 0x83, 0x54, 0x32, 0xFF, 0x83, 0x53, + 0x32, 0xFF, 0x82, 0x53, 0x33, 0xFF, 0x83, 0x54, 0x34, 0xFF, 0x83, 0x54, 0x35, 0xFF, 0x84, 0x56, + 0x39, 0xFF, 0x89, 0x5D, 0x40, 0xFF, 0x92, 0x68, 0x4B, 0xFF, 0x9A, 0x72, 0x56, 0xFF, 0xA2, 0x7C, + 0x62, 0xFC, 0xA8, 0x83, 0x68, 0xE5, 0xAF, 0x8D, 0x71, 0xA5, 0xB5, 0x90, 0x6F, 0x54, 0x98, 0x64, + 0x37, 0x31, 0x76, 0x35, 0x00, 0x24, 0x7E, 0x3F, 0x00, 0x1C, 0x85, 0x47, 0x0B, 0x19, 0x84, 0x47, + 0x0E, 0x19, 0x84, 0x45, 0x0D, 0x18, 0x84, 0x45, 0x0C, 0x14, 0x83, 0x45, 0x0C, 0x10, 0x83, 0x45, + 0x0D, 0x0E, 0x82, 0x44, 0x0C, 0x0C, 0x82, 0x45, 0x0C, 0x09, 0x83, 0x45, 0x0C, 0x07, 0x82, 0x45, + 0x0C, 0x06, 0x82, 0x44, 0x0B, 0x04, 0x81, 0x43, 0x0B, 0x02, 0x81, 0x44, 0x0B, 0x02, 0x83, 0x45, + 0x0D, 0x01, 0x84, 0x48, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x85, 0x49, 0x11, 0x01, 0x83, 0x46, 0x0C, 0x01, 0x83, 0x44, 0x0C, 0x02, 0x83, 0x45, + 0x0C, 0x02, 0x83, 0x46, 0x0D, 0x03, 0x83, 0x48, 0x0C, 0x04, 0x82, 0x44, 0x0C, 0x05, 0x82, 0x44, + 0x0E, 0x06, 0x86, 0x41, 0x0F, 0x08, 0x7C, 0x38, 0x04, 0x0B, 0x73, 0x33, 0x00, 0x0F, 0xA3, 0x6F, + 0x41, 0x13, 0xCA, 0xA5, 0x8A, 0x30, 0xAB, 0x84, 0x68, 0x7E, 0x99, 0x70, 0x54, 0xD5, 0x8F, 0x65, + 0x46, 0xF8, 0x83, 0x55, 0x35, 0xFF, 0x6F, 0x3D, 0x1C, 0xFF, 0x65, 0x30, 0x0F, 0xFF, 0x5F, 0x29, + 0x09, 0xFF, 0x5E, 0x27, 0x06, 0xFF, 0x5E, 0x27, 0x06, 0xFF, 0x60, 0x28, 0x06, 0xFF, 0x60, 0x29, + 0x06, 0xFF, 0x62, 0x2A, 0x05, 0xFF, 0x63, 0x2B, 0x06, 0xFF, 0x65, 0x2B, 0x05, 0xFF, 0x66, 0x2C, + 0x05, 0xFF, 0x67, 0x2D, 0x06, 0xFF, 0x68, 0x2E, 0x06, 0xFF, 0x6A, 0x2F, 0x06, 0xFF, 0x6B, 0x31, + 0x07, 0xFF, 0x6D, 0x32, 0x07, 0xFF, 0x6D, 0x33, 0x07, 0xFF, 0x6F, 0x34, 0x08, 0xFF, 0x70, 0x35, + 0x08, 0xFF, 0x71, 0x36, 0x08, 0xFF, 0x72, 0x37, 0x09, 0xFF, 0x73, 0x38, 0x09, 0xFF, 0x74, 0x39, + 0x09, 0xFF, 0x76, 0x39, 0x0A, 0xFF, 0x76, 0x3A, 0x0A, 0xFF, 0x77, 0x3A, 0x0A, 0xFF, 0x77, 0x3B, + 0x09, 0xFF, 0x78, 0x3B, 0x0A, 0xFF, 0x79, 0x3C, 0x0A, 0xFF, 0x7A, 0x3E, 0x0C, 0xFF, 0x7B, 0x3F, + 0x0D, 0xFF, 0x7D, 0x41, 0x10, 0xFF, 0x7E, 0x43, 0x12, 0xFF, 0x80, 0x45, 0x15, 0xFF, 0x82, 0x49, + 0x19, 0xFF, 0x84, 0x4C, 0x1D, 0xFF, 0x85, 0x4F, 0x20, 0xFF, 0x87, 0x51, 0x24, 0xFF, 0x88, 0x53, + 0x27, 0xFF, 0x89, 0x53, 0x28, 0xFF, 0x89, 0x54, 0x29, 0xFF, 0x8A, 0x55, 0x2A, 0xFF, 0x89, 0x56, + 0x2A, 0xFF, 0x8A, 0x56, 0x2B, 0xFF, 0x8A, 0x57, 0x2B, 0xFF, 0x8B, 0x57, 0x2C, 0xFF, 0x8B, 0x57, + 0x2D, 0xFF, 0x8B, 0x57, 0x2D, 0xFF, 0x8A, 0x57, 0x2E, 0xFF, 0x8A, 0x57, 0x2E, 0xFF, 0x8A, 0x57, + 0x2F, 0xFF, 0x8A, 0x57, 0x30, 0xFF, 0x89, 0x57, 0x30, 0xFF, 0x89, 0x57, 0x30, 0xFF, 0x88, 0x57, + 0x30, 0xFF, 0x88, 0x57, 0x30, 0xFF, 0x86, 0x56, 0x31, 0xFF, 0x86, 0x55, 0x31, 0xFF, 0x85, 0x55, + 0x32, 0xFF, 0x85, 0x54, 0x32, 0xFF, 0x84, 0x55, 0x33, 0xFF, 0x84, 0x55, 0x33, 0xFF, 0x84, 0x54, + 0x34, 0xFF, 0x85, 0x56, 0x37, 0xFF, 0x87, 0x5A, 0x3B, 0xFF, 0x8E, 0x63, 0x45, 0xFF, 0x97, 0x70, + 0x54, 0xFF, 0xA2, 0x7C, 0x60, 0xFD, 0xA8, 0x83, 0x66, 0xEF, 0xAD, 0x8B, 0x6E, 0xB1, 0xBC, 0x9B, + 0x7E, 0x51, 0xAB, 0x7F, 0x57, 0x27, 0x76, 0x35, 0x00, 0x18, 0x7D, 0x37, 0x00, 0x14, 0x85, 0x43, + 0x0D, 0x13, 0x83, 0x43, 0x0C, 0x10, 0x83, 0x46, 0x0C, 0x0D, 0x83, 0x45, 0x0C, 0x0C, 0x83, 0x45, + 0x0D, 0x0B, 0x83, 0x45, 0x0C, 0x09, 0x82, 0x45, 0x0C, 0x07, 0x83, 0x45, 0x0C, 0x05, 0x82, 0x45, + 0x0C, 0x04, 0x82, 0x45, 0x0C, 0x02, 0x81, 0x44, 0x0B, 0x01, 0x82, 0x44, 0x0C, 0x01, 0x83, 0x45, + 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x4A, 0x12, 0x01, 0x84, 0x46, + 0x0E, 0x01, 0x83, 0x45, 0x0C, 0x02, 0x86, 0x4A, 0x0F, 0x02, 0x85, 0x47, 0x14, 0x02, 0x69, 0x1E, + 0x00, 0x03, 0x62, 0x12, 0x00, 0x06, 0x78, 0x32, 0x0B, 0x09, 0xC0, 0x99, 0x6C, 0x0F, 0xD8, 0xB4, + 0x9C, 0x30, 0xA9, 0x83, 0x65, 0x88, 0x93, 0x6A, 0x4E, 0xDD, 0x90, 0x64, 0x44, 0xF8, 0x81, 0x52, + 0x31, 0xFE, 0x6C, 0x39, 0x17, 0xFF, 0x64, 0x2E, 0x0C, 0xFF, 0x62, 0x2A, 0x08, 0xFF, 0x5F, 0x27, + 0x05, 0xFF, 0x60, 0x28, 0x04, 0xFF, 0x61, 0x29, 0x05, 0xFF, 0x62, 0x29, 0x05, 0xFF, 0x63, 0x2B, + 0x06, 0xFF, 0x65, 0x2C, 0x05, 0xFF, 0x67, 0x2E, 0x05, 0xFF, 0x68, 0x2F, 0x06, 0xFF, 0x6A, 0x30, + 0x06, 0xFF, 0x6C, 0x32, 0x07, 0xFF, 0x6D, 0x32, 0x06, 0xFF, 0x6E, 0x33, 0x06, 0xFF, 0x6F, 0x34, + 0x07, 0xFF, 0x71, 0x35, 0x07, 0xFF, 0x72, 0x36, 0x07, 0xFF, 0x73, 0x37, 0x07, 0xFF, 0x74, 0x38, + 0x07, 0xFF, 0x75, 0x39, 0x08, 0xFF, 0x76, 0x3A, 0x08, 0xFF, 0x77, 0x3A, 0x09, 0xFF, 0x77, 0x3A, + 0x09, 0xFF, 0x78, 0x3B, 0x09, 0xFF, 0x79, 0x3C, 0x09, 0xFF, 0x79, 0x3C, 0x09, 0xFF, 0x7A, 0x3C, + 0x09, 0xFF, 0x7B, 0x3D, 0x09, 0xFF, 0x7B, 0x3E, 0x0A, 0xFF, 0x7C, 0x3E, 0x0A, 0xFF, 0x7C, 0x3E, + 0x0A, 0xFF, 0x7C, 0x3E, 0x0A, 0xFF, 0x7C, 0x3F, 0x0B, 0xFF, 0x7D, 0x3F, 0x0C, 0xFF, 0x7D, 0x40, + 0x0D, 0xFF, 0x7D, 0x41, 0x0E, 0xFF, 0x7E, 0x43, 0x11, 0xFF, 0x7F, 0x46, 0x14, 0xFF, 0x82, 0x49, + 0x19, 0xFF, 0x85, 0x4D, 0x1E, 0xFF, 0x87, 0x51, 0x22, 0xFF, 0x8A, 0x55, 0x26, 0xFF, 0x8B, 0x56, + 0x28, 0xFF, 0x8C, 0x58, 0x2A, 0xFF, 0x8D, 0x58, 0x2B, 0xFF, 0x8D, 0x58, 0x2B, 0xFF, 0x8C, 0x58, + 0x2C, 0xFF, 0x8C, 0x58, 0x2C, 0xFF, 0x8C, 0x59, 0x2D, 0xFF, 0x8C, 0x58, 0x2D, 0xFF, 0x8C, 0x58, + 0x2E, 0xFF, 0x8B, 0x58, 0x2E, 0xFF, 0x8B, 0x58, 0x2F, 0xFF, 0x8B, 0x58, 0x2F, 0xFF, 0x8B, 0x58, + 0x2F, 0xFF, 0x8A, 0x58, 0x30, 0xFF, 0x8A, 0x58, 0x30, 0xFF, 0x89, 0x57, 0x31, 0xFF, 0x88, 0x57, + 0x31, 0xFF, 0x87, 0x57, 0x31, 0xFF, 0x87, 0x56, 0x31, 0xFF, 0x86, 0x56, 0x32, 0xFF, 0x85, 0x55, + 0x32, 0xFF, 0x85, 0x55, 0x33, 0xFF, 0x85, 0x56, 0x35, 0xFF, 0x87, 0x59, 0x38, 0xFF, 0x8C, 0x61, + 0x43, 0xFF, 0x97, 0x6E, 0x51, 0xFF, 0xA4, 0x7E, 0x61, 0xFF, 0xAA, 0x85, 0x66, 0xF5, 0xAD, 0x8A, + 0x6D, 0xB7, 0xC1, 0xA2, 0x85, 0x52, 0xBA, 0x98, 0x76, 0x24, 0x7D, 0x3F, 0x18, 0x11, 0x6A, 0x22, + 0x00, 0x0E, 0x73, 0x2E, 0x00, 0x0A, 0x83, 0x48, 0x0F, 0x08, 0x85, 0x47, 0x0E, 0x07, 0x83, 0x44, + 0x0C, 0x06, 0x84, 0x45, 0x0D, 0x05, 0x83, 0x45, 0x0C, 0x04, 0x83, 0x45, 0x0C, 0x03, 0x83, 0x45, + 0x0C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x83, 0x46, 0x0E, 0x01, 0x84, 0x46, 0x0E, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x46, + 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3D, 0x12, 0x01, 0x58, 0x04, + 0x00, 0x02, 0x5D, 0x0E, 0x03, 0x05, 0xC3, 0xA4, 0x85, 0x0A, 0xDF, 0xC6, 0xAC, 0x2D, 0xA1, 0x7A, + 0x5D, 0x88, 0x8D, 0x66, 0x4C, 0xDF, 0x92, 0x66, 0x45, 0xFB, 0x82, 0x51, 0x2E, 0xFF, 0x68, 0x34, + 0x12, 0xFF, 0x61, 0x2B, 0x09, 0xFF, 0x5F, 0x28, 0x06, 0xFF, 0x60, 0x27, 0x06, 0xFF, 0x60, 0x28, + 0x05, 0xFF, 0x62, 0x29, 0x04, 0xFF, 0x63, 0x2A, 0x05, 0xFF, 0x65, 0x2B, 0x05, 0xFF, 0x66, 0x2D, + 0x06, 0xFF, 0x68, 0x2F, 0x06, 0xFF, 0x69, 0x30, 0x06, 0xFF, 0x6B, 0x31, 0x06, 0xFF, 0x6B, 0x32, + 0x06, 0xFF, 0x6D, 0x33, 0x07, 0xFF, 0x6E, 0x34, 0x07, 0xFF, 0x71, 0x35, 0x07, 0xFF, 0x72, 0x36, + 0x07, 0xFF, 0x74, 0x38, 0x08, 0xFF, 0x75, 0x39, 0x08, 0xFF, 0x76, 0x3A, 0x08, 0xFF, 0x77, 0x3B, + 0x08, 0xFF, 0x78, 0x3C, 0x08, 0xFF, 0x79, 0x3C, 0x09, 0xFF, 0x7A, 0x3D, 0x09, 0xFF, 0x7A, 0x3D, + 0x09, 0xFF, 0x7A, 0x3D, 0x09, 0xFF, 0x7B, 0x3E, 0x09, 0xFF, 0x7C, 0x3E, 0x0A, 0xFF, 0x7B, 0x3E, + 0x09, 0xFF, 0x7C, 0x3F, 0x0A, 0xFF, 0x7D, 0x3F, 0x0A, 0xFF, 0x7D, 0x40, 0x0A, 0xFF, 0x7D, 0x40, + 0x0A, 0xFF, 0x7E, 0x40, 0x0A, 0xFF, 0x7E, 0x40, 0x0B, 0xFF, 0x7F, 0x41, 0x0B, 0xFF, 0x7F, 0x41, + 0x0C, 0xFF, 0x80, 0x41, 0x0C, 0xFF, 0x80, 0x41, 0x0B, 0xFF, 0x80, 0x41, 0x0C, 0xFF, 0x80, 0x41, + 0x0B, 0xFF, 0x80, 0x42, 0x0D, 0xFF, 0x81, 0x45, 0x10, 0xFF, 0x83, 0x48, 0x14, 0xFF, 0x87, 0x4E, + 0x1A, 0xFF, 0x89, 0x52, 0x20, 0xFF, 0x8B, 0x55, 0x25, 0xFF, 0x8D, 0x57, 0x29, 0xFF, 0x8D, 0x58, + 0x2A, 0xFF, 0x8D, 0x59, 0x2B, 0xFF, 0x8D, 0x5A, 0x2C, 0xFF, 0x8E, 0x5A, 0x2D, 0xFF, 0x8D, 0x5A, + 0x2D, 0xFF, 0x8D, 0x5A, 0x2D, 0xFF, 0x8D, 0x5A, 0x2E, 0xFF, 0x8D, 0x5A, 0x2E, 0xFF, 0x8D, 0x5A, + 0x2F, 0xFF, 0x8D, 0x59, 0x2F, 0xFF, 0x8C, 0x59, 0x30, 0xFF, 0x8C, 0x59, 0x31, 0xFF, 0x8A, 0x59, + 0x31, 0xFF, 0x89, 0x58, 0x31, 0xFF, 0x89, 0x58, 0x31, 0xFF, 0x88, 0x57, 0x31, 0xFF, 0x87, 0x57, + 0x32, 0xFF, 0x87, 0x56, 0x32, 0xFF, 0x86, 0x56, 0x33, 0xFF, 0x86, 0x57, 0x34, 0xFF, 0x86, 0x58, + 0x37, 0xFF, 0x8A, 0x5E, 0x3F, 0xFF, 0x95, 0x6B, 0x4E, 0xFF, 0xA3, 0x7D, 0x5F, 0xFF, 0xAB, 0x86, + 0x6A, 0xF9, 0xB2, 0x91, 0x76, 0xBA, 0xC2, 0xA6, 0x89, 0x52, 0xC5, 0xA1, 0x82, 0x1D, 0x75, 0x33, + 0x0D, 0x0B, 0x6A, 0x1B, 0x00, 0x08, 0x7E, 0x3E, 0x09, 0x05, 0x83, 0x46, 0x0C, 0x04, 0x83, 0x45, + 0x0B, 0x03, 0x83, 0x44, 0x0C, 0x03, 0x82, 0x44, 0x0C, 0x03, 0x83, 0x45, 0x0C, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8F, 0x5B, + 0x40, 0x01, 0xCF, 0xB4, 0x99, 0x06, 0xD5, 0xB9, 0x9F, 0x29, 0xAB, 0x83, 0x62, 0x88, 0x93, 0x69, + 0x48, 0xE1, 0x94, 0x69, 0x45, 0xFB, 0x81, 0x50, 0x2E, 0xFE, 0x6A, 0x34, 0x11, 0xFF, 0x61, 0x29, + 0x06, 0xFF, 0x62, 0x29, 0x06, 0xFF, 0x61, 0x28, 0x05, 0xFF, 0x61, 0x29, 0x05, 0xFF, 0x63, 0x2A, + 0x06, 0xFF, 0x65, 0x2C, 0x05, 0xFF, 0x67, 0x2D, 0x06, 0xFF, 0x68, 0x2E, 0x06, 0xFF, 0x6A, 0x31, + 0x06, 0xFF, 0x6B, 0x32, 0x07, 0xFF, 0x6B, 0x32, 0x07, 0xFF, 0x6B, 0x33, 0x08, 0xFF, 0x6C, 0x34, + 0x08, 0xFF, 0x6E, 0x35, 0x08, 0xFF, 0x70, 0x36, 0x08, 0xFF, 0x73, 0x38, 0x09, 0xFF, 0x75, 0x39, + 0x08, 0xFF, 0x77, 0x3B, 0x09, 0xFF, 0x78, 0x3B, 0x09, 0xFF, 0x79, 0x3D, 0x0A, 0xFF, 0x7A, 0x3E, + 0x0A, 0xFF, 0x7B, 0x3E, 0x0A, 0xFF, 0x7C, 0x3F, 0x0A, 0xFF, 0x7D, 0x3F, 0x0A, 0xFF, 0x7D, 0x40, + 0x0A, 0xFF, 0x7E, 0x40, 0x0A, 0xFF, 0x7E, 0x40, 0x0A, 0xFF, 0x7E, 0x40, 0x0A, 0xFF, 0x7F, 0x41, + 0x0A, 0xFF, 0x7F, 0x41, 0x0B, 0xFF, 0x7F, 0x41, 0x0B, 0xFF, 0x80, 0x41, 0x0B, 0xFF, 0x80, 0x42, + 0x0B, 0xFF, 0x81, 0x42, 0x0B, 0xFF, 0x81, 0x42, 0x0B, 0xFF, 0x81, 0x42, 0x0B, 0xFF, 0x81, 0x42, + 0x0B, 0xFF, 0x81, 0x42, 0x0A, 0xFF, 0x81, 0x43, 0x0A, 0xFF, 0x82, 0x43, 0x0A, 0xFF, 0x82, 0x43, + 0x0B, 0xFF, 0x82, 0x43, 0x0B, 0xFF, 0x81, 0x43, 0x0C, 0xFF, 0x81, 0x43, 0x0C, 0xFF, 0x81, 0x44, + 0x0D, 0xFF, 0x81, 0x45, 0x0F, 0xFF, 0x83, 0x48, 0x14, 0xFF, 0x86, 0x4D, 0x1A, 0xFF, 0x88, 0x51, + 0x20, 0xFF, 0x8C, 0x56, 0x27, 0xFF, 0x8E, 0x59, 0x2A, 0xFF, 0x8F, 0x5B, 0x2C, 0xFF, 0x8F, 0x5B, + 0x2D, 0xFF, 0x90, 0x5B, 0x2D, 0xFF, 0x8F, 0x5B, 0x2E, 0xFF, 0x8F, 0x5B, 0x2E, 0xFF, 0x8E, 0x5B, + 0x2F, 0xFF, 0x8E, 0x5B, 0x2F, 0xFF, 0x8E, 0x5B, 0x30, 0xFF, 0x8D, 0x5A, 0x30, 0xFF, 0x8D, 0x5A, + 0x31, 0xFF, 0x8C, 0x5A, 0x31, 0xFF, 0x8B, 0x5A, 0x31, 0xFF, 0x8A, 0x59, 0x31, 0xFF, 0x8A, 0x58, + 0x32, 0xFF, 0x89, 0x58, 0x32, 0xFF, 0x87, 0x57, 0x32, 0xFF, 0x87, 0x57, 0x33, 0xFF, 0x87, 0x57, + 0x34, 0xFF, 0x87, 0x58, 0x35, 0xFF, 0x8A, 0x5D, 0x3E, 0xFF, 0x96, 0x6C, 0x4C, 0xFF, 0xA3, 0x7C, + 0x5C, 0xFF, 0xA8, 0x83, 0x68, 0xF8, 0xB1, 0x90, 0x77, 0xB8, 0xBE, 0xA1, 0x88, 0x51, 0xC3, 0xA6, + 0x8A, 0x18, 0x9F, 0x6D, 0x4F, 0x04, 0x90, 0x4A, 0x1E, 0x03, 0x79, 0x39, 0x04, 0x01, 0x7C, 0x3F, + 0x08, 0x01, 0x84, 0x48, 0x0F, 0x02, 0x81, 0x45, 0x0D, 0x02, 0x83, 0x46, 0x0F, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE9, 0xD6, + 0xBF, 0x01, 0xDB, 0xBF, 0xA6, 0x25, 0xA8, 0x81, 0x63, 0x80, 0x96, 0x6D, 0x4E, 0xDE, 0x91, 0x65, + 0x43, 0xFC, 0x80, 0x4E, 0x2A, 0xFF, 0x69, 0x34, 0x11, 0xFF, 0x62, 0x2B, 0x07, 0xFF, 0x61, 0x29, + 0x05, 0xFF, 0x62, 0x29, 0x06, 0xFF, 0x62, 0x2A, 0x05, 0xFF, 0x63, 0x2A, 0x05, 0xFF, 0x65, 0x2D, + 0x06, 0xFF, 0x69, 0x2F, 0x07, 0xFF, 0x69, 0x2F, 0x07, 0xFF, 0x6B, 0x31, 0x07, 0xFF, 0x6B, 0x32, + 0x07, 0xFF, 0x6C, 0x33, 0x07, 0xFF, 0x6B, 0x34, 0x08, 0xFF, 0x6C, 0x34, 0x08, 0xFF, 0x6D, 0x36, + 0x09, 0xFF, 0x6F, 0x36, 0x08, 0xFF, 0x70, 0x38, 0x08, 0xFF, 0x73, 0x39, 0x09, 0xFF, 0x76, 0x3B, + 0x09, 0xFF, 0x78, 0x3C, 0x0A, 0xFF, 0x79, 0x3D, 0x0A, 0xFF, 0x7B, 0x3E, 0x0A, 0xFF, 0x7C, 0x3F, + 0x0A, 0xFF, 0x7E, 0x40, 0x0A, 0xFF, 0x7E, 0x41, 0x0A, 0xFF, 0x7F, 0x41, 0x0A, 0xFF, 0x80, 0x42, + 0x0A, 0xFF, 0x80, 0x42, 0x0A, 0xFF, 0x80, 0x42, 0x0A, 0xFF, 0x81, 0x42, 0x0A, 0xFF, 0x81, 0x43, + 0x0B, 0xFF, 0x81, 0x43, 0x0B, 0xFF, 0x81, 0x43, 0x0B, 0xFF, 0x82, 0x43, 0x0B, 0xFF, 0x82, 0x44, + 0x0B, 0xFF, 0x83, 0x44, 0x0B, 0xFF, 0x83, 0x44, 0x0B, 0xFF, 0x83, 0x44, 0x0B, 0xFF, 0x82, 0x44, + 0x0B, 0xFF, 0x83, 0x44, 0x0B, 0xFF, 0x82, 0x44, 0x0B, 0xFF, 0x83, 0x44, 0x0B, 0xFF, 0x83, 0x44, + 0x0B, 0xFF, 0x83, 0x44, 0x0C, 0xFF, 0x83, 0x44, 0x0C, 0xFF, 0x84, 0x45, 0x0D, 0xFF, 0x83, 0x45, + 0x0D, 0xFF, 0x84, 0x44, 0x0D, 0xFF, 0x84, 0x44, 0x0C, 0xFF, 0x85, 0x45, 0x0D, 0xFF, 0x85, 0x46, + 0x0F, 0xFF, 0x86, 0x48, 0x12, 0xFF, 0x89, 0x4E, 0x19, 0xFF, 0x8C, 0x54, 0x21, 0xFF, 0x8E, 0x58, + 0x27, 0xFF, 0x90, 0x5A, 0x2B, 0xFF, 0x90, 0x5C, 0x2D, 0xFF, 0x90, 0x5B, 0x2E, 0xFF, 0x90, 0x5C, + 0x2E, 0xFF, 0x90, 0x5C, 0x2F, 0xFF, 0x90, 0x5C, 0x30, 0xFF, 0x8F, 0x5C, 0x30, 0xFF, 0x8F, 0x5C, + 0x30, 0xFF, 0x8E, 0x5B, 0x30, 0xFF, 0x8D, 0x5B, 0x31, 0xFF, 0x8C, 0x5A, 0x32, 0xFF, 0x8C, 0x5A, + 0x32, 0xFF, 0x8B, 0x59, 0x32, 0xFF, 0x89, 0x58, 0x32, 0xFF, 0x88, 0x58, 0x32, 0xFF, 0x88, 0x57, + 0x33, 0xFF, 0x88, 0x58, 0x33, 0xFF, 0x88, 0x59, 0x36, 0xFF, 0x8B, 0x5D, 0x3C, 0xFF, 0x96, 0x6C, + 0x4B, 0xFF, 0xA3, 0x7D, 0x5F, 0xFF, 0xA9, 0x86, 0x6A, 0xF7, 0xB3, 0x92, 0x76, 0xAE, 0xBB, 0x9D, + 0x81, 0x49, 0xC8, 0xAA, 0x8F, 0x12, 0xC0, 0xA2, 0x86, 0x01, 0xA7, 0x74, 0x46, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x49, 0x14, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xC2, + 0xB3, 0x1F, 0xB1, 0x86, 0x69, 0x79, 0x99, 0x6D, 0x4A, 0xD9, 0x92, 0x65, 0x43, 0xFB, 0x7F, 0x4D, + 0x29, 0xFF, 0x6B, 0x34, 0x10, 0xFF, 0x63, 0x2B, 0x07, 0xFF, 0x63, 0x2B, 0x06, 0xFF, 0x64, 0x2B, + 0x06, 0xFF, 0x65, 0x2B, 0x06, 0xFF, 0x65, 0x2C, 0x07, 0xFF, 0x67, 0x2D, 0x07, 0xFF, 0x6A, 0x30, + 0x07, 0xFF, 0x6B, 0x32, 0x07, 0xFF, 0x6B, 0x32, 0x08, 0xFF, 0x6C, 0x33, 0x07, 0xFF, 0x6D, 0x34, + 0x08, 0xFF, 0x6D, 0x36, 0x09, 0xFF, 0x6D, 0x37, 0x09, 0xFF, 0x69, 0x35, 0x08, 0xFF, 0x68, 0x35, + 0x08, 0xFF, 0x6B, 0x38, 0x09, 0xFF, 0x6C, 0x37, 0x07, 0xFF, 0x6F, 0x39, 0x08, 0xFF, 0x74, 0x3B, + 0x0A, 0xFF, 0x77, 0x3D, 0x0B, 0xFF, 0x7B, 0x3E, 0x0B, 0xFF, 0x7E, 0x40, 0x0C, 0xFF, 0x80, 0x41, + 0x0B, 0xFF, 0x81, 0x42, 0x0B, 0xFF, 0x81, 0x43, 0x0B, 0xFF, 0x82, 0x43, 0x0B, 0xFF, 0x82, 0x43, + 0x0B, 0xFF, 0x82, 0x43, 0x0B, 0xFF, 0x83, 0x44, 0x0B, 0xFF, 0x83, 0x44, 0x0B, 0xFF, 0x83, 0x44, + 0x0C, 0xFF, 0x83, 0x44, 0x0C, 0xFF, 0x83, 0x45, 0x0C, 0xFF, 0x84, 0x45, 0x0C, 0xFF, 0x84, 0x45, + 0x0C, 0xFF, 0x85, 0x45, 0x0C, 0xFF, 0x85, 0x45, 0x0C, 0xFF, 0x85, 0x45, 0x0C, 0xFF, 0x85, 0x45, + 0x0C, 0xFF, 0x85, 0x45, 0x0C, 0xFF, 0x85, 0x45, 0x0C, 0xFF, 0x85, 0x45, 0x0C, 0xFF, 0x85, 0x45, + 0x0C, 0xFF, 0x85, 0x45, 0x0C, 0xFF, 0x85, 0x45, 0x0C, 0xFF, 0x85, 0x46, 0x0C, 0xFF, 0x85, 0x46, + 0x0D, 0xFF, 0x85, 0x46, 0x0C, 0xFF, 0x84, 0x46, 0x0C, 0xFF, 0x85, 0x46, 0x0C, 0xFF, 0x85, 0x46, + 0x0C, 0xFF, 0x85, 0x46, 0x0D, 0xFF, 0x84, 0x46, 0x0D, 0xFF, 0x84, 0x47, 0x10, 0xFF, 0x86, 0x4B, + 0x16, 0xFF, 0x8A, 0x52, 0x1F, 0xFF, 0x8E, 0x57, 0x25, 0xFF, 0x91, 0x5B, 0x2B, 0xFF, 0x92, 0x5D, + 0x2E, 0xFF, 0x92, 0x5D, 0x2E, 0xFF, 0x91, 0x5D, 0x2F, 0xFF, 0x91, 0x5D, 0x2F, 0xFF, 0x91, 0x5D, + 0x30, 0xFF, 0x90, 0x5C, 0x30, 0xFF, 0x8F, 0x5C, 0x31, 0xFF, 0x8F, 0x5C, 0x31, 0xFF, 0x8E, 0x5B, + 0x31, 0xFF, 0x8D, 0x5B, 0x32, 0xFF, 0x8C, 0x5A, 0x32, 0xFF, 0x8B, 0x59, 0x32, 0xFF, 0x8A, 0x58, + 0x32, 0xFF, 0x89, 0x57, 0x32, 0xFF, 0x89, 0x58, 0x33, 0xFF, 0x89, 0x59, 0x35, 0xFF, 0x8C, 0x5D, + 0x3C, 0xFF, 0x97, 0x6C, 0x4C, 0xFF, 0xA5, 0x7F, 0x62, 0xFF, 0xAB, 0x87, 0x69, 0xF2, 0xB7, 0x96, + 0x7A, 0xA7, 0xC2, 0xA4, 0x8A, 0x46, 0xCA, 0xAF, 0x95, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0xC7, 0xB8, 0x1B, 0xAD, 0x89, + 0x6B, 0x6E, 0x9A, 0x70, 0x4C, 0xD2, 0x93, 0x67, 0x45, 0xFA, 0x7F, 0x4E, 0x2B, 0xFF, 0x6C, 0x35, + 0x12, 0xFF, 0x64, 0x2C, 0x08, 0xFF, 0x63, 0x2A, 0x05, 0xFF, 0x65, 0x2B, 0x06, 0xFF, 0x65, 0x2C, + 0x06, 0xFF, 0x67, 0x2D, 0x06, 0xFF, 0x68, 0x2E, 0x07, 0xFF, 0x6B, 0x30, 0x07, 0xFF, 0x6D, 0x33, + 0x07, 0xFF, 0x6D, 0x33, 0x07, 0xFF, 0x6D, 0x34, 0x07, 0xFF, 0x6D, 0x34, 0x08, 0xFF, 0x6D, 0x35, + 0x08, 0xFF, 0x6C, 0x35, 0x08, 0xFF, 0x6A, 0x36, 0x09, 0xFF, 0x69, 0x39, 0x0D, 0xFF, 0x6A, 0x3D, + 0x12, 0xFF, 0x64, 0x36, 0x0C, 0xFF, 0x63, 0x35, 0x09, 0xFF, 0x6A, 0x3A, 0x09, 0xFF, 0x6F, 0x3B, + 0x09, 0xFF, 0x75, 0x3D, 0x0B, 0xFF, 0x7B, 0x3F, 0x0C, 0xFF, 0x7E, 0x41, 0x0C, 0xFF, 0x81, 0x42, + 0x0B, 0xFF, 0x83, 0x44, 0x0B, 0xFF, 0x84, 0x45, 0x0B, 0xFF, 0x84, 0x45, 0x0B, 0xFF, 0x84, 0x45, + 0x0B, 0xFF, 0x85, 0x45, 0x0B, 0xFF, 0x84, 0x45, 0x0B, 0xFF, 0x85, 0x46, 0x0C, 0xFF, 0x85, 0x46, + 0x0C, 0xFF, 0x85, 0x46, 0x0C, 0xFF, 0x85, 0x46, 0x0C, 0xFF, 0x86, 0x47, 0x0C, 0xFF, 0x86, 0x47, + 0x0C, 0xFF, 0x87, 0x47, 0x0C, 0xFF, 0x86, 0x47, 0x0C, 0xFF, 0x87, 0x47, 0x0C, 0xFF, 0x86, 0x47, + 0x0C, 0xFF, 0x87, 0x47, 0x0C, 0xFF, 0x86, 0x47, 0x0C, 0xFF, 0x87, 0x47, 0x0C, 0xFF, 0x86, 0x47, + 0x0C, 0xFF, 0x87, 0x47, 0x0C, 0xFF, 0x86, 0x47, 0x0C, 0xFF, 0x86, 0x47, 0x0C, 0xFF, 0x86, 0x47, + 0x0C, 0xFF, 0x86, 0x47, 0x0C, 0xFF, 0x86, 0x47, 0x0C, 0xFF, 0x86, 0x47, 0x0C, 0xFF, 0x86, 0x46, + 0x0C, 0xFF, 0x86, 0x47, 0x0D, 0xFF, 0x86, 0x47, 0x0D, 0xFF, 0x87, 0x47, 0x0D, 0xFF, 0x86, 0x46, + 0x0D, 0xFF, 0x86, 0x47, 0x0E, 0xFF, 0x87, 0x4A, 0x12, 0xFF, 0x8B, 0x4F, 0x18, 0xFF, 0x8F, 0x56, + 0x21, 0xFF, 0x92, 0x5A, 0x28, 0xFF, 0x92, 0x5D, 0x2D, 0xFF, 0x93, 0x5D, 0x2F, 0xFF, 0x92, 0x5E, + 0x2F, 0xFF, 0x92, 0x5E, 0x30, 0xFF, 0x92, 0x5E, 0x30, 0xFF, 0x91, 0x5D, 0x30, 0xFF, 0x90, 0x5D, + 0x31, 0xFF, 0x8F, 0x5D, 0x31, 0xFF, 0x8E, 0x5C, 0x32, 0xFF, 0x8D, 0x5B, 0x32, 0xFF, 0x8C, 0x5A, + 0x32, 0xFF, 0x8B, 0x59, 0x32, 0xFF, 0x8A, 0x58, 0x31, 0xFF, 0x8A, 0x58, 0x33, 0xFF, 0x8A, 0x5A, + 0x37, 0xFF, 0x8F, 0x60, 0x3F, 0xFF, 0x98, 0x6D, 0x4E, 0xFE, 0xA7, 0x80, 0x63, 0xFF, 0xAF, 0x8B, + 0x6E, 0xEC, 0xB7, 0x96, 0x7A, 0x98, 0xC7, 0xA9, 0x92, 0x37, 0xD0, 0xBA, 0xA4, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC7, 0xAB, 0x96, 0x0D, 0xB3, 0x93, 0x74, 0x61, 0xA7, 0x82, + 0x61, 0xCB, 0x95, 0x69, 0x46, 0xF8, 0x83, 0x51, 0x2C, 0xFE, 0x6F, 0x38, 0x14, 0xFF, 0x67, 0x2F, + 0x0A, 0xFF, 0x64, 0x2A, 0x05, 0xFF, 0x66, 0x2B, 0x06, 0xFF, 0x68, 0x2C, 0x06, 0xFF, 0x69, 0x2E, + 0x07, 0xFF, 0x6A, 0x2F, 0x07, 0xFF, 0x6D, 0x32, 0x07, 0xFF, 0x6F, 0x34, 0x07, 0xFF, 0x70, 0x35, + 0x08, 0xFF, 0x6F, 0x35, 0x07, 0xFF, 0x6F, 0x35, 0x07, 0xFF, 0x6F, 0x36, 0x08, 0xFF, 0x6D, 0x35, + 0x08, 0xFF, 0x66, 0x32, 0x06, 0xFF, 0x65, 0x37, 0x10, 0xFF, 0x76, 0x4F, 0x29, 0xFF, 0xA1, 0x86, + 0x6D, 0xFF, 0x98, 0x7C, 0x64, 0xFF, 0x71, 0x48, 0x23, 0xFF, 0x66, 0x3C, 0x0E, 0xFF, 0x65, 0x38, + 0x07, 0xFF, 0x6D, 0x3B, 0x0A, 0xFF, 0x77, 0x3F, 0x0A, 0xFF, 0x7C, 0x41, 0x0B, 0xFF, 0x80, 0x43, + 0x0B, 0xFF, 0x83, 0x44, 0x0C, 0xFF, 0x85, 0x46, 0x0C, 0xFF, 0x86, 0x46, 0x0C, 0xFF, 0x87, 0x47, + 0x0C, 0xFF, 0x87, 0x47, 0x0C, 0xFF, 0x87, 0x47, 0x0C, 0xFF, 0x87, 0x47, 0x0C, 0xFF, 0x87, 0x47, + 0x0C, 0xFF, 0x87, 0x47, 0x0C, 0xFF, 0x87, 0x48, 0x0C, 0xFF, 0x88, 0x48, 0x0C, 0xFF, 0x88, 0x48, + 0x0C, 0xFF, 0x88, 0x48, 0x0C, 0xFF, 0x88, 0x48, 0x0C, 0xFF, 0x88, 0x48, 0x0C, 0xFF, 0x88, 0x48, + 0x0C, 0xFF, 0x88, 0x48, 0x0C, 0xFF, 0x88, 0x48, 0x0C, 0xFF, 0x88, 0x48, 0x0C, 0xFF, 0x88, 0x48, + 0x0C, 0xFF, 0x88, 0x48, 0x0C, 0xFF, 0x88, 0x48, 0x0C, 0xFF, 0x88, 0x48, 0x0C, 0xFF, 0x88, 0x48, + 0x0C, 0xFF, 0x88, 0x48, 0x0C, 0xFF, 0x88, 0x49, 0x0C, 0xFF, 0x88, 0x48, 0x0C, 0xFF, 0x87, 0x48, + 0x0C, 0xFF, 0x87, 0x47, 0x0C, 0xFF, 0x87, 0x48, 0x0D, 0xFF, 0x87, 0x48, 0x0C, 0xFF, 0x87, 0x47, + 0x0C, 0xFF, 0x87, 0x47, 0x0C, 0xFF, 0x86, 0x47, 0x0D, 0xFF, 0x87, 0x48, 0x0D, 0xFF, 0x87, 0x4A, + 0x10, 0xFF, 0x89, 0x4E, 0x16, 0xFF, 0x8C, 0x54, 0x1F, 0xFF, 0x91, 0x5B, 0x29, 0xFF, 0x94, 0x5E, + 0x2E, 0xFF, 0x94, 0x5F, 0x2F, 0xFF, 0x93, 0x5F, 0x30, 0xFF, 0x93, 0x5E, 0x30, 0xFF, 0x92, 0x5E, + 0x31, 0xFF, 0x91, 0x5E, 0x31, 0xFF, 0x90, 0x5D, 0x32, 0xFF, 0x90, 0x5D, 0x32, 0xFF, 0x8F, 0x5C, + 0x32, 0xFF, 0x8E, 0x5B, 0x31, 0xFF, 0x8D, 0x5A, 0x32, 0xFF, 0x8C, 0x59, 0x32, 0xFF, 0x8B, 0x59, + 0x33, 0xFF, 0x8C, 0x5B, 0x37, 0xFF, 0x90, 0x61, 0x3F, 0xFF, 0x99, 0x6E, 0x4D, 0xFF, 0xAB, 0x84, + 0x66, 0xFF, 0xB0, 0x8D, 0x6F, 0xE5, 0xB8, 0x97, 0x7C, 0x8D, 0xD4, 0xB9, 0xA4, 0x2C, 0x00, 0x00, + 0x00, 0x00, 0xF1, 0xE3, 0xD7, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xC3, 0xA5, 0x8A, 0x07, 0xC0, 0xA1, 0x85, 0x47, 0xAF, 0x8A, 0x69, 0xB5, 0x9B, 0x71, + 0x4C, 0xF2, 0x85, 0x54, 0x2F, 0xFF, 0x72, 0x3C, 0x16, 0xFF, 0x67, 0x2E, 0x09, 0xFF, 0x66, 0x2C, + 0x06, 0xFF, 0x66, 0x2B, 0x06, 0xFF, 0x68, 0x2D, 0x06, 0xFF, 0x6A, 0x2E, 0x07, 0xFF, 0x6B, 0x30, + 0x07, 0xFF, 0x6E, 0x32, 0x08, 0xFF, 0x70, 0x35, 0x07, 0xFF, 0x70, 0x35, 0x07, 0xFF, 0x71, 0x36, + 0x08, 0xFF, 0x70, 0x37, 0x08, 0xFF, 0x6E, 0x37, 0x07, 0xFF, 0x69, 0x35, 0x07, 0xFF, 0x62, 0x33, + 0x07, 0xFF, 0x63, 0x3A, 0x12, 0xFF, 0x7A, 0x5D, 0x36, 0xFF, 0xB2, 0xA1, 0x8C, 0xFF, 0xE6, 0xDB, + 0xD5, 0xFF, 0xE0, 0xD6, 0xCE, 0xFF, 0xAD, 0x9C, 0x8B, 0xFF, 0x81, 0x60, 0x3D, 0xFF, 0x67, 0x3F, + 0x15, 0xFF, 0x65, 0x3A, 0x0B, 0xFF, 0x70, 0x3E, 0x09, 0xFF, 0x76, 0x3F, 0x09, 0xFF, 0x7C, 0x42, + 0x0A, 0xFF, 0x81, 0x44, 0x0B, 0xFF, 0x84, 0x46, 0x0C, 0xFF, 0x87, 0x48, 0x0C, 0xFF, 0x88, 0x49, + 0x0D, 0xFF, 0x89, 0x48, 0x0D, 0xFF, 0x88, 0x48, 0x0D, 0xFF, 0x89, 0x48, 0x0D, 0xFF, 0x88, 0x49, + 0x0C, 0xFF, 0x89, 0x49, 0x0C, 0xFF, 0x89, 0x49, 0x0C, 0xFF, 0x8A, 0x4A, 0x0C, 0xFF, 0x89, 0x4A, + 0x0C, 0xFF, 0x89, 0x4A, 0x0C, 0xFF, 0x89, 0x4A, 0x0C, 0xFF, 0x8A, 0x4A, 0x0C, 0xFF, 0x89, 0x4A, + 0x0C, 0xFF, 0x8A, 0x4A, 0x0C, 0xFF, 0x89, 0x49, 0x0C, 0xFF, 0x89, 0x4A, 0x0C, 0xFF, 0x89, 0x4A, + 0x0C, 0xFF, 0x8A, 0x4A, 0x0C, 0xFF, 0x89, 0x4A, 0x0C, 0xFF, 0x8A, 0x4A, 0x0C, 0xFF, 0x89, 0x4A, + 0x0C, 0xFF, 0x8A, 0x4A, 0x0D, 0xFF, 0x89, 0x4A, 0x0D, 0xFF, 0x89, 0x49, 0x0C, 0xFF, 0x88, 0x49, + 0x0C, 0xFF, 0x88, 0x48, 0x0C, 0xFF, 0x88, 0x48, 0x0C, 0xFF, 0x88, 0x48, 0x0C, 0xFF, 0x88, 0x48, + 0x0C, 0xFF, 0x88, 0x48, 0x0D, 0xFF, 0x88, 0x48, 0x0D, 0xFF, 0x89, 0x49, 0x0D, 0xFF, 0x88, 0x48, + 0x0D, 0xFF, 0x89, 0x49, 0x0E, 0xFF, 0x89, 0x4A, 0x0F, 0xFF, 0x8B, 0x4E, 0x14, 0xFF, 0x8F, 0x55, + 0x1F, 0xFF, 0x93, 0x5C, 0x29, 0xFF, 0x94, 0x5E, 0x2E, 0xFF, 0x94, 0x5E, 0x2F, 0xFF, 0x94, 0x5F, + 0x30, 0xFF, 0x93, 0x5F, 0x31, 0xFF, 0x93, 0x5F, 0x31, 0xFF, 0x92, 0x5E, 0x31, 0xFF, 0x91, 0x5D, + 0x31, 0xFF, 0x90, 0x5C, 0x31, 0xFF, 0x8F, 0x5C, 0x32, 0xFF, 0x8E, 0x5B, 0x32, 0xFF, 0x8D, 0x5A, + 0x32, 0xFF, 0x8C, 0x5A, 0x33, 0xFF, 0x8E, 0x5E, 0x39, 0xFF, 0x91, 0x63, 0x40, 0xFF, 0x9A, 0x71, + 0x50, 0xFF, 0xAD, 0x86, 0x67, 0xFF, 0xB4, 0x90, 0x72, 0xDB, 0xBE, 0x9E, 0x85, 0x78, 0xD9, 0xC4, + 0xB6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xCA, 0xAE, 0x92, 0x33, 0xB9, 0x97, 0x79, 0x9D, 0x9D, 0x73, 0x4F, 0xE9, 0x8B, 0x5A, + 0x35, 0xFD, 0x77, 0x41, 0x1A, 0xFF, 0x6C, 0x33, 0x0D, 0xFF, 0x67, 0x2D, 0x07, 0xFF, 0x68, 0x2D, + 0x07, 0xFF, 0x69, 0x2D, 0x07, 0xFF, 0x6B, 0x2F, 0x07, 0xFF, 0x6C, 0x31, 0x07, 0xFF, 0x6F, 0x33, + 0x08, 0xFF, 0x71, 0x35, 0x08, 0xFF, 0x71, 0x37, 0x08, 0xFF, 0x71, 0x37, 0x08, 0xFF, 0x70, 0x38, + 0x07, 0xFF, 0x70, 0x39, 0x08, 0xFF, 0x6A, 0x35, 0x07, 0xFF, 0x65, 0x36, 0x0A, 0xFF, 0x6E, 0x48, + 0x22, 0xFF, 0x98, 0x7F, 0x68, 0xFF, 0xB4, 0xA6, 0x98, 0xFF, 0xA1, 0x96, 0x86, 0xFF, 0xC7, 0xC0, + 0xB5, 0xFF, 0xEF, 0xEB, 0xE8, 0xFF, 0xED, 0xE6, 0xE2, 0xFF, 0xBF, 0xB1, 0xA5, 0xFF, 0x90, 0x6F, + 0x54, 0xFF, 0x6D, 0x48, 0x20, 0xFF, 0x67, 0x3D, 0x0E, 0xFF, 0x6D, 0x3E, 0x0C, 0xFF, 0x75, 0x41, + 0x0B, 0xFF, 0x7C, 0x43, 0x0B, 0xFF, 0x82, 0x46, 0x0C, 0xFF, 0x86, 0x48, 0x0D, 0xFF, 0x88, 0x49, + 0x0D, 0xFF, 0x89, 0x49, 0x0E, 0xFF, 0x8A, 0x49, 0x0D, 0xFF, 0x8A, 0x4A, 0x0E, 0xFF, 0x89, 0x4A, + 0x0D, 0xFF, 0x8A, 0x4A, 0x0D, 0xFF, 0x8A, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8A, 0x4B, + 0x0D, 0xFF, 0x8A, 0x4B, 0x0D, 0xFF, 0x8A, 0x4B, 0x0D, 0xFF, 0x8A, 0x4B, 0x0D, 0xFF, 0x8A, 0x4B, + 0x0D, 0xFF, 0x8A, 0x4B, 0x0D, 0xFF, 0x8A, 0x4B, 0x0D, 0xFF, 0x8A, 0x4B, 0x0D, 0xFF, 0x8A, 0x4B, + 0x0D, 0xFF, 0x8A, 0x4B, 0x0D, 0xFF, 0x8A, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8A, 0x4B, + 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8A, 0x4B, 0x0D, 0xFF, 0x8A, 0x4B, 0x0D, 0xFF, 0x8A, 0x4B, + 0x0D, 0xFF, 0x8A, 0x4A, 0x0D, 0xFF, 0x8A, 0x4A, 0x0D, 0xFF, 0x8A, 0x49, 0x0D, 0xFF, 0x89, 0x49, + 0x0D, 0xFF, 0x89, 0x49, 0x0D, 0xFF, 0x89, 0x4A, 0x0D, 0xFF, 0x89, 0x49, 0x0D, 0xFF, 0x89, 0x49, + 0x0D, 0xFF, 0x89, 0x49, 0x0D, 0xFF, 0x89, 0x49, 0x0D, 0xFF, 0x89, 0x4A, 0x0E, 0xFF, 0x88, 0x4A, + 0x10, 0xFF, 0x8A, 0x4E, 0x16, 0xFF, 0x8E, 0x56, 0x1F, 0xFF, 0x93, 0x5D, 0x2A, 0xFF, 0x96, 0x5F, + 0x2E, 0xFF, 0x96, 0x60, 0x2F, 0xFF, 0x94, 0x5F, 0x30, 0xFF, 0x94, 0x5F, 0x30, 0xFF, 0x93, 0x5F, + 0x31, 0xFF, 0x91, 0x5E, 0x31, 0xFF, 0x91, 0x5D, 0x32, 0xFF, 0x90, 0x5D, 0x32, 0xFF, 0x8F, 0x5B, + 0x32, 0xFF, 0x8D, 0x5A, 0x32, 0xFF, 0x8E, 0x5C, 0x34, 0xFF, 0x8F, 0x5F, 0x3A, 0xFF, 0x93, 0x65, + 0x43, 0xFF, 0x9E, 0x75, 0x53, 0xFF, 0xAF, 0x89, 0x69, 0xFE, 0xB9, 0x97, 0x7A, 0xCA, 0xC2, 0xA7, + 0x90, 0x62, 0xCE, 0xB6, 0xA1, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCB, 0xAE, + 0x97, 0x1C, 0xC1, 0xA0, 0x83, 0x7E, 0xA0, 0x78, 0x57, 0xDC, 0x8E, 0x5F, 0x3A, 0xFC, 0x79, 0x44, + 0x1D, 0xFF, 0x6D, 0x34, 0x0F, 0xFF, 0x69, 0x2F, 0x08, 0xFF, 0x68, 0x2D, 0x08, 0xFF, 0x6A, 0x2E, + 0x07, 0xFF, 0x6B, 0x30, 0x07, 0xFF, 0x6D, 0x32, 0x07, 0xFF, 0x70, 0x34, 0x08, 0xFF, 0x72, 0x36, + 0x08, 0xFF, 0x72, 0x36, 0x08, 0xFF, 0x72, 0x38, 0x09, 0xFF, 0x71, 0x39, 0x08, 0xFF, 0x6F, 0x39, + 0x07, 0xFF, 0x68, 0x37, 0x07, 0xFF, 0x62, 0x38, 0x09, 0xFF, 0x72, 0x52, 0x2C, 0xFF, 0xAC, 0x9C, + 0x8B, 0xFF, 0xD9, 0xD5, 0xD1, 0xFF, 0xDC, 0xDC, 0xD9, 0xFF, 0xC6, 0xBD, 0xB6, 0xFF, 0x96, 0x8E, + 0x7F, 0xFF, 0xA6, 0xA0, 0x94, 0xFF, 0xD7, 0xD5, 0xCD, 0xFF, 0xEC, 0xEA, 0xE2, 0xFF, 0xD2, 0xC8, + 0xBD, 0xFF, 0x9C, 0x85, 0x6E, 0xFF, 0x71, 0x4F, 0x2B, 0xFF, 0x68, 0x40, 0x14, 0xFF, 0x6F, 0x3F, + 0x10, 0xFF, 0x74, 0x3F, 0x0B, 0xFF, 0x7B, 0x44, 0x0C, 0xFF, 0x81, 0x46, 0x0D, 0xFF, 0x86, 0x49, + 0x0D, 0xFF, 0x89, 0x4A, 0x0E, 0xFF, 0x89, 0x4A, 0x0E, 0xFF, 0x8A, 0x4A, 0x0E, 0xFF, 0x8A, 0x4B, + 0x0E, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, + 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, + 0x0D, 0xFF, 0x8C, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8C, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, + 0x0D, 0xFF, 0x8C, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, + 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8C, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, + 0x0D, 0xFF, 0x8C, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4A, 0x0D, 0xFF, 0x8B, 0x4B, + 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8A, 0x4B, 0x0D, 0xFF, 0x8A, 0x4A, 0x0D, 0xFF, 0x89, 0x4A, + 0x0D, 0xFF, 0x8A, 0x4A, 0x0D, 0xFF, 0x8A, 0x4A, 0x0D, 0xFF, 0x8B, 0x4B, 0x0E, 0xFF, 0x8A, 0x4A, + 0x0E, 0xFF, 0x8A, 0x4A, 0x0E, 0xFF, 0x8B, 0x4C, 0x10, 0xFF, 0x8D, 0x51, 0x16, 0xFF, 0x91, 0x59, + 0x22, 0xFF, 0x95, 0x5E, 0x2A, 0xFF, 0x95, 0x60, 0x2E, 0xFF, 0x95, 0x5F, 0x30, 0xFF, 0x94, 0x5F, + 0x31, 0xFF, 0x93, 0x5F, 0x31, 0xFF, 0x93, 0x5F, 0x32, 0xFF, 0x92, 0x5E, 0x31, 0xFF, 0x91, 0x5D, + 0x32, 0xFF, 0x8F, 0x5C, 0x32, 0xFF, 0x8E, 0x5B, 0x32, 0xFF, 0x8F, 0x5D, 0x35, 0xFF, 0x92, 0x61, + 0x3C, 0xFF, 0x95, 0x68, 0x44, 0xFF, 0xA2, 0x7A, 0x59, 0xFF, 0xB0, 0x8B, 0x6D, 0xF2, 0xBA, 0x99, + 0x7F, 0xB2, 0xC6, 0xAA, 0x91, 0x42, 0xCD, 0xB4, 0x9D, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDD, 0xC5, 0xB0, 0x0E, 0xC0, 0xA1, + 0x87, 0x57, 0xA5, 0x7E, 0x5C, 0xC6, 0x95, 0x68, 0x44, 0xF9, 0x80, 0x4C, 0x25, 0xFF, 0x72, 0x38, + 0x11, 0xFF, 0x6C, 0x30, 0x09, 0xFF, 0x6B, 0x2F, 0x08, 0xFF, 0x6B, 0x2F, 0x07, 0xFF, 0x6D, 0x31, + 0x07, 0xFF, 0x6E, 0x32, 0x07, 0xFF, 0x71, 0x35, 0x08, 0xFF, 0x73, 0x37, 0x08, 0xFF, 0x74, 0x38, + 0x08, 0xFF, 0x73, 0x39, 0x08, 0xFF, 0x72, 0x3A, 0x08, 0xFF, 0x70, 0x3A, 0x08, 0xFF, 0x68, 0x37, + 0x07, 0xFF, 0x64, 0x39, 0x0D, 0xFF, 0x75, 0x55, 0x30, 0xFF, 0xB0, 0x9F, 0x91, 0xFF, 0xDF, 0xDB, + 0xDA, 0xFF, 0xE5, 0xE4, 0xE1, 0xFF, 0xE2, 0xE2, 0xDF, 0xFF, 0xE2, 0xE1, 0xE0, 0xFF, 0xD3, 0xCB, + 0xC3, 0xFF, 0x90, 0x86, 0x74, 0xFF, 0x9D, 0x92, 0x83, 0xFF, 0xCD, 0xC9, 0xBD, 0xFF, 0xE5, 0xE1, + 0xD9, 0xFF, 0xDF, 0xD9, 0xD1, 0xFF, 0xB4, 0xA1, 0x90, 0xFF, 0x7F, 0x60, 0x3C, 0xFF, 0x71, 0x49, + 0x1C, 0xFF, 0x70, 0x42, 0x12, 0xFF, 0x72, 0x40, 0x0C, 0xFF, 0x79, 0x44, 0x0E, 0xFF, 0x80, 0x47, + 0x0D, 0xFF, 0x85, 0x49, 0x0E, 0xFF, 0x88, 0x4A, 0x0E, 0xFF, 0x8A, 0x4A, 0x0E, 0xFF, 0x8A, 0x4B, + 0x0E, 0xFF, 0x8B, 0x4B, 0x0E, 0xFF, 0x8B, 0x4C, 0x0D, 0xFF, 0x8C, 0x4C, 0x0D, 0xFF, 0x8C, 0x4C, + 0x0D, 0xFF, 0x8C, 0x4C, 0x0D, 0xFF, 0x8B, 0x4C, 0x0D, 0xFF, 0x8B, 0x4C, 0x0D, 0xFF, 0x8C, 0x4C, + 0x0D, 0xFF, 0x8C, 0x4C, 0x0D, 0xFF, 0x8C, 0x4C, 0x0D, 0xFF, 0x8C, 0x4C, 0x0D, 0xFF, 0x8C, 0x4C, + 0x0D, 0xFF, 0x8C, 0x4C, 0x0D, 0xFF, 0x8C, 0x4C, 0x0D, 0xFF, 0x8C, 0x4C, 0x0D, 0xFF, 0x8C, 0x4C, + 0x0D, 0xFF, 0x8C, 0x4C, 0x0D, 0xFF, 0x8C, 0x4C, 0x0D, 0xFF, 0x8C, 0x4C, 0x0D, 0xFF, 0x8C, 0x4C, + 0x0D, 0xFF, 0x8C, 0x4C, 0x0D, 0xFF, 0x8C, 0x4C, 0x0D, 0xFF, 0x8C, 0x4C, 0x0D, 0xFF, 0x8C, 0x4C, + 0x0D, 0xFF, 0x8C, 0x4C, 0x0D, 0xFF, 0x8C, 0x4C, 0x0D, 0xFF, 0x8C, 0x4C, 0x0D, 0xFF, 0x8B, 0x4C, + 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, + 0x0E, 0xFF, 0x8A, 0x4B, 0x0D, 0xFF, 0x8A, 0x4A, 0x0D, 0xFF, 0x8A, 0x4A, 0x0D, 0xFF, 0x8A, 0x4C, + 0x11, 0xFF, 0x8C, 0x52, 0x1A, 0xFF, 0x91, 0x59, 0x24, 0xFF, 0x96, 0x5F, 0x2D, 0xFF, 0x96, 0x61, + 0x2F, 0xFF, 0x96, 0x61, 0x30, 0xFF, 0x94, 0x60, 0x31, 0xFF, 0x93, 0x5F, 0x31, 0xFF, 0x92, 0x5E, + 0x32, 0xFF, 0x92, 0x5E, 0x32, 0xFF, 0x90, 0x5C, 0x31, 0xFF, 0x8F, 0x5C, 0x32, 0xFF, 0x90, 0x5E, + 0x36, 0xFF, 0x93, 0x63, 0x3B, 0xFF, 0x99, 0x6E, 0x4A, 0xFF, 0xA7, 0x7E, 0x5C, 0xFF, 0xB3, 0x8F, + 0x71, 0xE7, 0xC2, 0xA2, 0x88, 0x8E, 0xCC, 0xB3, 0x9B, 0x28, 0xCE, 0xB5, 0x9E, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD1, 0xB8, 0xA3, 0x3A, 0xAE, 0x8C, + 0x6D, 0x9C, 0x9B, 0x6F, 0x4A, 0xF3, 0x88, 0x57, 0x30, 0xFF, 0x76, 0x3E, 0x17, 0xFF, 0x6D, 0x32, + 0x0B, 0xFF, 0x6B, 0x2F, 0x08, 0xFF, 0x6B, 0x30, 0x07, 0xFF, 0x6D, 0x31, 0x07, 0xFF, 0x6E, 0x32, + 0x07, 0xFF, 0x72, 0x35, 0x08, 0xFF, 0x74, 0x37, 0x08, 0xFF, 0x75, 0x38, 0x08, 0xFF, 0x75, 0x39, + 0x08, 0xFF, 0x75, 0x3B, 0x08, 0xFF, 0x71, 0x3B, 0x07, 0xFF, 0x6A, 0x38, 0x06, 0xFF, 0x68, 0x3B, + 0x0A, 0xFF, 0x75, 0x54, 0x2F, 0xFF, 0xAC, 0x9D, 0x8D, 0xFF, 0xE3, 0xDF, 0xDA, 0xFF, 0xE3, 0xE2, + 0xE1, 0xFF, 0xE3, 0xE1, 0xE0, 0xFF, 0xE0, 0xE0, 0xDF, 0xFF, 0xE0, 0xE2, 0xE2, 0xFF, 0xE3, 0xE5, + 0xE3, 0xFF, 0xCE, 0xC9, 0xBF, 0xFF, 0x97, 0x8A, 0x77, 0xFF, 0x90, 0x83, 0x6F, 0xFF, 0xC1, 0xB9, + 0xAA, 0xFF, 0xE0, 0xDB, 0xD4, 0xFF, 0xDE, 0xD9, 0xD3, 0xFF, 0xC3, 0xB7, 0xAA, 0xFF, 0x8E, 0x72, + 0x52, 0xFF, 0x75, 0x4D, 0x21, 0xFF, 0x71, 0x44, 0x14, 0xFF, 0x72, 0x41, 0x0E, 0xFF, 0x78, 0x44, + 0x0C, 0xFF, 0x7F, 0x46, 0x0C, 0xFF, 0x84, 0x49, 0x0D, 0xFF, 0x89, 0x4A, 0x0D, 0xFF, 0x89, 0x4B, + 0x0E, 0xFF, 0x8B, 0x4C, 0x0D, 0xFF, 0x8C, 0x4C, 0x0E, 0xFF, 0x8D, 0x4C, 0x0D, 0xFF, 0x8D, 0x4C, + 0x0D, 0xFF, 0x8D, 0x4C, 0x0D, 0xFF, 0x8C, 0x4C, 0x0D, 0xFF, 0x8C, 0x4C, 0x0D, 0xFF, 0x8C, 0x4C, + 0x0D, 0xFF, 0x8D, 0x4C, 0x0D, 0xFF, 0x8D, 0x4C, 0x0D, 0xFF, 0x8D, 0x4C, 0x0D, 0xFF, 0x8D, 0x4C, + 0x0D, 0xFF, 0x8D, 0x4C, 0x0D, 0xFF, 0x8D, 0x4C, 0x0D, 0xFF, 0x8D, 0x4C, 0x0E, 0xFF, 0x8C, 0x4C, + 0x0D, 0xFF, 0x8C, 0x4C, 0x0D, 0xFF, 0x8D, 0x4C, 0x0D, 0xFF, 0x8D, 0x4C, 0x0E, 0xFF, 0x8D, 0x4C, + 0x0D, 0xFF, 0x8D, 0x4C, 0x0D, 0xFF, 0x8D, 0x4C, 0x0D, 0xFF, 0x8D, 0x4C, 0x0D, 0xFF, 0x8D, 0x4C, + 0x0E, 0xFF, 0x8D, 0x4C, 0x0E, 0xFF, 0x8D, 0x4C, 0x0D, 0xFF, 0x8D, 0x4C, 0x0D, 0xFF, 0x8C, 0x4D, + 0x0E, 0xFF, 0x8C, 0x4C, 0x0D, 0xFF, 0x8C, 0x4C, 0x0D, 0xFF, 0x8C, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, + 0x0D, 0xFF, 0x8B, 0x4C, 0x0E, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8C, 0x4B, 0x0D, 0xFF, 0x8C, 0x4B, + 0x0E, 0xFF, 0x8C, 0x4B, 0x0F, 0xFF, 0x8D, 0x4F, 0x13, 0xFF, 0x91, 0x56, 0x1C, 0xFF, 0x95, 0x5D, + 0x27, 0xFF, 0x97, 0x60, 0x2D, 0xFF, 0x96, 0x61, 0x30, 0xFF, 0x95, 0x61, 0x31, 0xFF, 0x94, 0x60, + 0x32, 0xFF, 0x93, 0x5F, 0x31, 0xFF, 0x92, 0x5E, 0x31, 0xFF, 0x91, 0x5D, 0x32, 0xFF, 0x90, 0x5D, + 0x32, 0xFF, 0x92, 0x5F, 0x36, 0xFF, 0x95, 0x66, 0x3F, 0xFF, 0xA0, 0x75, 0x50, 0xFF, 0xAC, 0x85, + 0x64, 0xFE, 0xBA, 0x96, 0x78, 0xD1, 0xCA, 0xAC, 0x93, 0x63, 0xCF, 0xB6, 0xA0, 0x15, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0xA5, 0x8B, 0x16, 0xBE, 0x9E, 0x81, 0x7A, 0xA6, 0x7D, + 0x5C, 0xDB, 0x91, 0x61, 0x39, 0xFF, 0x7E, 0x47, 0x1F, 0xFF, 0x71, 0x35, 0x0E, 0xFF, 0x6D, 0x31, + 0x09, 0xFF, 0x6D, 0x31, 0x07, 0xFF, 0x6E, 0x32, 0x08, 0xFF, 0x70, 0x33, 0x08, 0xFF, 0x73, 0x36, + 0x09, 0xFF, 0x75, 0x38, 0x09, 0xFF, 0x76, 0x39, 0x09, 0xFF, 0x76, 0x3A, 0x08, 0xFF, 0x75, 0x3B, + 0x08, 0xFF, 0x74, 0x3B, 0x09, 0xFF, 0x6C, 0x39, 0x08, 0xFF, 0x6A, 0x3C, 0x0E, 0xFF, 0x73, 0x51, + 0x2B, 0xFF, 0xAC, 0x9B, 0x8A, 0xFF, 0xE1, 0xDD, 0xDA, 0xFF, 0xE6, 0xE5, 0xE3, 0xFF, 0xE3, 0xE3, + 0xE2, 0xFF, 0xE3, 0xE2, 0xE3, 0xFF, 0xE2, 0xE3, 0xE3, 0xFF, 0xE2, 0xE3, 0xE3, 0xFF, 0xE4, 0xE5, + 0xE7, 0xFF, 0xE4, 0xE4, 0xE4, 0xFF, 0xD6, 0xD3, 0xCC, 0xFF, 0xA0, 0x97, 0x87, 0xFF, 0x84, 0x77, + 0x62, 0xFF, 0xA4, 0x9A, 0x88, 0xFF, 0xD5, 0xD0, 0xC6, 0xFF, 0xDF, 0xDC, 0xD8, 0xFF, 0xD1, 0xCB, + 0xC1, 0xFF, 0xA0, 0x89, 0x70, 0xFF, 0x7C, 0x56, 0x2B, 0xFF, 0x70, 0x45, 0x14, 0xFF, 0x70, 0x42, + 0x0C, 0xFF, 0x77, 0x45, 0x0E, 0xFF, 0x7F, 0x48, 0x0D, 0xFF, 0x84, 0x49, 0x0D, 0xFF, 0x88, 0x4B, + 0x0E, 0xFF, 0x8B, 0x4C, 0x0E, 0xFF, 0x8C, 0x4D, 0x0D, 0xFF, 0x8D, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, + 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8D, 0x4D, 0x0E, 0xFF, 0x8D, 0x4C, 0x0E, 0xFF, 0x8D, 0x4C, + 0x0D, 0xFF, 0x8D, 0x4C, 0x0D, 0xFF, 0x8D, 0x4D, 0x0E, 0xFF, 0x8D, 0x4D, 0x0E, 0xFF, 0x8D, 0x4C, + 0x0E, 0xFF, 0x8D, 0x4D, 0x0E, 0xFF, 0x8D, 0x4C, 0x0E, 0xFF, 0x8D, 0x4D, 0x0E, 0xFF, 0x8D, 0x4D, + 0x0E, 0xFF, 0x8D, 0x4D, 0x0E, 0xFF, 0x8D, 0x4D, 0x0E, 0xFF, 0x8D, 0x4D, 0x0E, 0xFF, 0x8D, 0x4D, + 0x0E, 0xFF, 0x8D, 0x4D, 0x0E, 0xFF, 0x8D, 0x4D, 0x0E, 0xFF, 0x8D, 0x4D, 0x0E, 0xFF, 0x8D, 0x4D, + 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8D, 0x4D, 0x0E, 0xFF, 0x8D, 0x4D, 0x0E, 0xFF, 0x8D, 0x4E, + 0x0E, 0xFF, 0x8D, 0x4D, 0x0E, 0xFF, 0x8D, 0x4D, 0x0D, 0xFF, 0x8D, 0x4C, 0x0D, 0xFF, 0x8D, 0x4C, + 0x0E, 0xFF, 0x8D, 0x4D, 0x0E, 0xFF, 0x8D, 0x4D, 0x0D, 0xFF, 0x8D, 0x4C, 0x0D, 0xFF, 0x8D, 0x4C, + 0x0E, 0xFF, 0x8C, 0x4C, 0x0D, 0xFF, 0x8C, 0x4C, 0x0E, 0xFF, 0x8C, 0x4D, 0x10, 0xFF, 0x8D, 0x51, + 0x16, 0xFF, 0x92, 0x58, 0x22, 0xFF, 0x96, 0x60, 0x2B, 0xFF, 0x98, 0x62, 0x2F, 0xFF, 0x96, 0x61, + 0x30, 0xFF, 0x95, 0x60, 0x31, 0xFF, 0x94, 0x5F, 0x32, 0xFF, 0x93, 0x5F, 0x32, 0xFF, 0x92, 0x5E, + 0x32, 0xFF, 0x92, 0x5E, 0x33, 0xFF, 0x93, 0x62, 0x37, 0xFF, 0x9A, 0x6B, 0x44, 0xFF, 0xA6, 0x7C, + 0x59, 0xFF, 0xB2, 0x8B, 0x6B, 0xF8, 0xBC, 0x99, 0x7D, 0xAE, 0xCB, 0xAE, 0x96, 0x3B, 0xE3, 0xD2, + 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xC2, 0xA3, 0x85, 0x05, 0xBA, 0x99, 0x7D, 0x47, 0xAC, 0x86, 0x65, 0xBD, 0x96, 0x69, + 0x45, 0xF9, 0x86, 0x52, 0x2A, 0xFF, 0x75, 0x3C, 0x14, 0xFF, 0x6D, 0x32, 0x0A, 0xFF, 0x6D, 0x31, + 0x07, 0xFF, 0x6E, 0x31, 0x07, 0xFF, 0x70, 0x33, 0x08, 0xFF, 0x73, 0x36, 0x09, 0xFF, 0x75, 0x38, + 0x09, 0xFF, 0x76, 0x39, 0x09, 0xFF, 0x77, 0x3A, 0x09, 0xFF, 0x77, 0x3B, 0x08, 0xFF, 0x75, 0x3C, + 0x08, 0xFF, 0x6F, 0x3A, 0x08, 0xFF, 0x6B, 0x3B, 0x0A, 0xFF, 0x72, 0x4F, 0x27, 0xFF, 0xA8, 0x96, + 0x83, 0xFF, 0xE4, 0xE0, 0xDA, 0xFF, 0xE6, 0xE6, 0xE4, 0xFF, 0xE5, 0xE4, 0xE3, 0xFF, 0xE4, 0xE4, + 0xE4, 0xFF, 0xE3, 0xE4, 0xE4, 0xFF, 0xE3, 0xE4, 0xE4, 0xFF, 0xE4, 0xE4, 0xE5, 0xFF, 0xE6, 0xE6, + 0xE7, 0xFF, 0xE7, 0xE7, 0xE8, 0xFF, 0xE7, 0xE7, 0xE7, 0xFF, 0xDC, 0xDB, 0xD5, 0xFF, 0xAA, 0xA1, + 0x92, 0xFF, 0x85, 0x76, 0x60, 0xFF, 0x95, 0x88, 0x72, 0xFF, 0xC2, 0xBC, 0xB0, 0xFF, 0xE1, 0xDE, + 0xD9, 0xFF, 0xDC, 0xD8, 0xD1, 0xFF, 0xAF, 0x9D, 0x8B, 0xFF, 0x83, 0x62, 0x3C, 0xFF, 0x73, 0x4A, + 0x1D, 0xFF, 0x6F, 0x43, 0x11, 0xFF, 0x77, 0x45, 0x0D, 0xFF, 0x7E, 0x46, 0x0D, 0xFF, 0x83, 0x49, + 0x0D, 0xFF, 0x88, 0x4B, 0x0D, 0xFF, 0x8B, 0x4C, 0x0D, 0xFF, 0x8D, 0x4D, 0x0E, 0xFF, 0x8E, 0x4E, + 0x0F, 0xFF, 0x8F, 0x4E, 0x0F, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, + 0x0D, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, + 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, + 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, + 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, + 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4E, + 0x0E, 0xFF, 0x8E, 0x4E, 0x0E, 0xFF, 0x8E, 0x4E, 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, + 0x0E, 0xFF, 0x8E, 0x4E, 0x0E, 0xFF, 0x8E, 0x4E, 0x0D, 0xFF, 0x8E, 0x4D, 0x0D, 0xFF, 0x8D, 0x4D, + 0x0D, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8D, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8D, 0x4C, + 0x0E, 0xFF, 0x8E, 0x4E, 0x12, 0xFF, 0x91, 0x56, 0x1C, 0xFF, 0x97, 0x5E, 0x27, 0xFF, 0x98, 0x62, + 0x2E, 0xFF, 0x97, 0x61, 0x30, 0xFF, 0x95, 0x61, 0x31, 0xFF, 0x94, 0x60, 0x31, 0xFF, 0x94, 0x5F, + 0x31, 0xFF, 0x93, 0x5F, 0x32, 0xFF, 0x93, 0x60, 0x34, 0xFF, 0x95, 0x64, 0x3A, 0xFF, 0x9E, 0x72, + 0x4D, 0xFF, 0xAC, 0x83, 0x61, 0xFF, 0xB6, 0x90, 0x72, 0xE8, 0xC6, 0xA4, 0x8B, 0x7C, 0xE0, 0xCE, + 0xBD, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xCE, 0xB3, 0x99, 0x22, 0xB8, 0x94, 0x76, 0x8D, 0x9F, 0x74, 0x4F, 0xE7, 0x8D, 0x5B, + 0x34, 0xFF, 0x7C, 0x44, 0x1A, 0xFF, 0x71, 0x36, 0x0D, 0xFF, 0x6F, 0x32, 0x08, 0xFF, 0x70, 0x33, + 0x08, 0xFF, 0x71, 0x34, 0x08, 0xFF, 0x73, 0x36, 0x09, 0xFF, 0x75, 0x38, 0x09, 0xFF, 0x77, 0x3A, + 0x09, 0xFF, 0x78, 0x3C, 0x09, 0xFF, 0x78, 0x3D, 0x09, 0xFF, 0x76, 0x3D, 0x09, 0xFF, 0x72, 0x3B, + 0x07, 0xFF, 0x6D, 0x3D, 0x0D, 0xFF, 0x6F, 0x48, 0x22, 0xFF, 0xA3, 0x90, 0x7B, 0xFF, 0xE1, 0xDD, + 0xD8, 0xFF, 0xE8, 0xE9, 0xE5, 0xFF, 0xE5, 0xE6, 0xE5, 0xFF, 0xE6, 0xE6, 0xE6, 0xFF, 0xE4, 0xE6, + 0xE6, 0xFF, 0xE5, 0xE5, 0xE6, 0xFF, 0xE5, 0xE5, 0xE5, 0xFF, 0xE5, 0xE5, 0xE5, 0xFF, 0xE5, 0xE6, + 0xE6, 0xFF, 0xE5, 0xE6, 0xE6, 0xFF, 0xE5, 0xE5, 0xE6, 0xFF, 0xE8, 0xE8, 0xE9, 0xFF, 0xE3, 0xE2, + 0xDF, 0xFF, 0xB3, 0xAB, 0xA0, 0xFF, 0x81, 0x75, 0x5C, 0xFF, 0x85, 0x78, 0x5F, 0xFF, 0xAF, 0xA7, + 0x99, 0xFF, 0xDE, 0xDB, 0xD7, 0xFF, 0xE3, 0xDF, 0xDA, 0xFF, 0xC6, 0xBA, 0xAC, 0xFF, 0x8E, 0x71, + 0x51, 0xFF, 0x73, 0x4E, 0x21, 0xFF, 0x70, 0x46, 0x12, 0xFF, 0x75, 0x47, 0x10, 0xFF, 0x7B, 0x47, + 0x0D, 0xFF, 0x81, 0x48, 0x0D, 0xFF, 0x87, 0x4B, 0x0D, 0xFF, 0x8B, 0x4D, 0x0E, 0xFF, 0x8D, 0x4E, + 0x0E, 0xFF, 0x8F, 0x4F, 0x0F, 0xFF, 0x8F, 0x4E, 0x0F, 0xFF, 0x8F, 0x4E, 0x0F, 0xFF, 0x8F, 0x4E, + 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x8F, 0x4E, + 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x8F, 0x4E, + 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x8F, 0x4E, + 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x8F, 0x4E, + 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x8F, 0x4F, + 0x0E, 0xFF, 0x8F, 0x4F, 0x0E, 0xFF, 0x8F, 0x4F, 0x0E, 0xFF, 0x8F, 0x4F, 0x0E, 0xFF, 0x8F, 0x4E, + 0x0E, 0xFF, 0x8F, 0x4F, 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x8F, 0x4F, 0x0E, 0xFF, 0x8F, 0x4E, + 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x8E, 0x4E, 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, + 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8D, 0x4D, 0x10, 0xFF, 0x8E, 0x51, 0x16, 0xFF, 0x93, 0x5B, + 0x22, 0xFF, 0x97, 0x61, 0x2D, 0xFF, 0x97, 0x62, 0x2F, 0xFF, 0x96, 0x62, 0x30, 0xFF, 0x95, 0x60, + 0x30, 0xFF, 0x94, 0x60, 0x31, 0xFF, 0x93, 0x60, 0x32, 0xFF, 0x94, 0x61, 0x35, 0xFF, 0x98, 0x68, + 0x3F, 0xFF, 0xA3, 0x78, 0x52, 0xFF, 0xB3, 0x8D, 0x6B, 0xFB, 0xBF, 0x9B, 0x7E, 0xC2, 0xCA, 0xB0, + 0x97, 0x4F, 0xD0, 0xBA, 0xA3, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCF, 0xB2, + 0x97, 0x07, 0xCA, 0xAD, 0x94, 0x5C, 0xAE, 0x88, 0x68, 0xC6, 0x96, 0x67, 0x40, 0xFD, 0x82, 0x4D, + 0x24, 0xFF, 0x75, 0x3A, 0x11, 0xFF, 0x70, 0x34, 0x0A, 0xFF, 0x70, 0x33, 0x08, 0xFF, 0x71, 0x34, + 0x07, 0xFF, 0x73, 0x36, 0x08, 0xFF, 0x75, 0x37, 0x09, 0xFF, 0x78, 0x3A, 0x09, 0xFF, 0x7A, 0x3D, + 0x0A, 0xFF, 0x7A, 0x3D, 0x09, 0xFF, 0x78, 0x3F, 0x09, 0xFF, 0x76, 0x3E, 0x09, 0xFF, 0x71, 0x3C, + 0x09, 0xFF, 0x6D, 0x46, 0x19, 0xFF, 0x96, 0x7F, 0x65, 0xFF, 0xDD, 0xD9, 0xD1, 0xFF, 0xE6, 0xE6, + 0xE5, 0xFF, 0xE5, 0xE4, 0xE3, 0xFF, 0xE5, 0xE6, 0xE5, 0xFF, 0xE6, 0xE6, 0xE7, 0xFF, 0xE5, 0xE7, + 0xE7, 0xFF, 0xE6, 0xE7, 0xE7, 0xFF, 0xE7, 0xE7, 0xE7, 0xFF, 0xE8, 0xE7, 0xE8, 0xFF, 0xE7, 0xE7, + 0xE8, 0xFF, 0xE7, 0xE7, 0xE8, 0xFF, 0xE7, 0xE8, 0xE9, 0xFF, 0xE9, 0xE8, 0xE8, 0xFF, 0xEB, 0xE9, + 0xEA, 0xFF, 0xE5, 0xE5, 0xE3, 0xFF, 0xBB, 0xB7, 0xAA, 0xFF, 0x85, 0x79, 0x60, 0xFF, 0x84, 0x72, + 0x58, 0xFF, 0x99, 0x8C, 0x7B, 0xFF, 0xCF, 0xC8, 0xC2, 0xFF, 0xE4, 0xE0, 0xDC, 0xFF, 0xD2, 0xC9, + 0xC0, 0xFF, 0x99, 0x85, 0x6D, 0xFF, 0x74, 0x52, 0x2B, 0xFF, 0x6F, 0x47, 0x16, 0xFF, 0x75, 0x45, + 0x10, 0xFF, 0x79, 0x44, 0x0C, 0xFF, 0x7F, 0x48, 0x0D, 0xFF, 0x86, 0x4A, 0x0E, 0xFF, 0x8A, 0x4D, + 0x0E, 0xFF, 0x8E, 0x4F, 0x0F, 0xFF, 0x8F, 0x4F, 0x0F, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x90, 0x4F, + 0x0E, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x90, 0x4F, + 0x0E, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x90, 0x4F, + 0x0E, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x90, 0x4F, + 0x0E, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x90, 0x4F, + 0x0E, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x90, 0x4F, + 0x0E, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x90, 0x4F, + 0x0E, 0xFF, 0x90, 0x4F, 0x0F, 0xFF, 0x90, 0x4F, 0x0F, 0xFF, 0x91, 0x50, 0x0F, 0xFF, 0x90, 0x50, + 0x0E, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x8F, 0x4F, 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x8F, 0x4E, + 0x0E, 0xFF, 0x8F, 0x4E, 0x0F, 0xFF, 0x8E, 0x4E, 0x0F, 0xFF, 0x8E, 0x4E, 0x0F, 0xFF, 0x90, 0x51, + 0x13, 0xFF, 0x94, 0x59, 0x1F, 0xFF, 0x96, 0x5F, 0x29, 0xFF, 0x97, 0x61, 0x2D, 0xFF, 0x96, 0x61, + 0x2F, 0xFF, 0x95, 0x60, 0x30, 0xFF, 0x95, 0x60, 0x31, 0xFF, 0x95, 0x61, 0x33, 0xFF, 0x97, 0x65, + 0x39, 0xFF, 0x9C, 0x6E, 0x44, 0xFF, 0xA9, 0x81, 0x5D, 0xFF, 0xB8, 0x93, 0x72, 0xE8, 0xC0, 0x9E, + 0x82, 0x8D, 0xCA, 0xB1, 0x96, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC8, 0xA8, + 0x8B, 0x22, 0xBA, 0x98, 0x7A, 0x9A, 0xA3, 0x78, 0x55, 0xEC, 0x8E, 0x5A, 0x30, 0xFF, 0x7C, 0x42, + 0x18, 0xFF, 0x74, 0x37, 0x0C, 0xFF, 0x72, 0x35, 0x09, 0xFF, 0x72, 0x34, 0x08, 0xFF, 0x75, 0x37, + 0x08, 0xFF, 0x77, 0x39, 0x08, 0xFF, 0x79, 0x3A, 0x09, 0xFF, 0x7B, 0x3D, 0x0A, 0xFF, 0x7C, 0x3F, + 0x0A, 0xFF, 0x7C, 0x40, 0x0A, 0xFF, 0x7B, 0x42, 0x0B, 0xFF, 0x75, 0x40, 0x0C, 0xFF, 0x6F, 0x43, + 0x16, 0xFF, 0x8D, 0x74, 0x57, 0xFF, 0xD4, 0xCD, 0xC2, 0xFF, 0xE5, 0xE5, 0xE1, 0xFF, 0xE3, 0xE4, + 0xE3, 0xFF, 0xE4, 0xE4, 0xE5, 0xFF, 0xE4, 0xE5, 0xE5, 0xFF, 0xE6, 0xE6, 0xE7, 0xFF, 0xE7, 0xE8, + 0xE8, 0xFF, 0xE8, 0xE8, 0xE8, 0xFF, 0xE9, 0xE9, 0xE9, 0xFF, 0xEA, 0xE9, 0xE9, 0xFF, 0xE9, 0xE8, + 0xE8, 0xFF, 0xE9, 0xE9, 0xE9, 0xFF, 0xE7, 0xE8, 0xE9, 0xFF, 0xE8, 0xE9, 0xE9, 0xFF, 0xE9, 0xE9, + 0xE9, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xE8, 0xE9, 0xE8, 0xFF, 0xC4, 0xC1, 0xBA, 0xFF, 0x90, 0x83, + 0x72, 0xFF, 0x7F, 0x6C, 0x52, 0xFF, 0x87, 0x78, 0x61, 0xFF, 0xBC, 0xB5, 0xA6, 0xFF, 0xE1, 0xDC, + 0xD6, 0xFF, 0xDE, 0xD9, 0xD2, 0xFF, 0xB0, 0xA0, 0x8E, 0xFF, 0x81, 0x64, 0x3F, 0xFF, 0x74, 0x4E, + 0x1C, 0xFF, 0x74, 0x47, 0x11, 0xFF, 0x76, 0x45, 0x0D, 0xFF, 0x7D, 0x47, 0x0E, 0xFF, 0x84, 0x4B, + 0x0E, 0xFF, 0x8A, 0x4E, 0x0F, 0xFF, 0x8E, 0x4F, 0x0E, 0xFF, 0x90, 0x50, 0x0F, 0xFF, 0x90, 0x50, + 0x0F, 0xFF, 0x91, 0x50, 0x0F, 0xFF, 0x91, 0x50, 0x0F, 0xFF, 0x91, 0x50, 0x0F, 0xFF, 0x91, 0x50, + 0x0E, 0xFF, 0x91, 0x50, 0x0E, 0xFF, 0x91, 0x50, 0x0E, 0xFF, 0x91, 0x50, 0x0E, 0xFF, 0x91, 0x50, + 0x0E, 0xFF, 0x91, 0x50, 0x0E, 0xFF, 0x91, 0x50, 0x0E, 0xFF, 0x91, 0x50, 0x0E, 0xFF, 0x91, 0x50, + 0x0F, 0xFF, 0x91, 0x50, 0x0F, 0xFF, 0x91, 0x50, 0x0F, 0xFF, 0x91, 0x50, 0x0F, 0xFF, 0x91, 0x50, + 0x0F, 0xFF, 0x91, 0x51, 0x0F, 0xFF, 0x91, 0x50, 0x0F, 0xFF, 0x91, 0x51, 0x0F, 0xFF, 0x91, 0x50, + 0x0F, 0xFF, 0x91, 0x50, 0x0F, 0xFF, 0x91, 0x50, 0x0F, 0xFF, 0x91, 0x50, 0x0F, 0xFF, 0x91, 0x50, + 0x0F, 0xFF, 0x91, 0x51, 0x0F, 0xFF, 0x91, 0x51, 0x0F, 0xFF, 0x91, 0x51, 0x0F, 0xFF, 0x91, 0x50, + 0x0E, 0xFF, 0x91, 0x51, 0x0E, 0xFF, 0x91, 0x50, 0x0F, 0xFF, 0x91, 0x50, 0x0F, 0xFF, 0x90, 0x50, + 0x0F, 0xFF, 0x90, 0x4F, 0x0F, 0xFF, 0x8F, 0x4F, 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x8F, 0x4E, + 0x0F, 0xFF, 0x8F, 0x4F, 0x12, 0xFF, 0x91, 0x55, 0x1B, 0xFF, 0x95, 0x5D, 0x27, 0xFF, 0x98, 0x61, + 0x2D, 0xFF, 0x98, 0x62, 0x2F, 0xFF, 0x96, 0x61, 0x30, 0xFF, 0x95, 0x61, 0x31, 0xFF, 0x96, 0x62, + 0x34, 0xFF, 0x99, 0x67, 0x3B, 0xFF, 0xA2, 0x77, 0x4F, 0xFF, 0xB3, 0x8B, 0x67, 0xFD, 0xBE, 0x9B, + 0x7A, 0xC5, 0xCA, 0xAC, 0x93, 0x54, 0xD9, 0xC6, 0xB1, 0x07, 0xE0, 0xCE, 0xBD, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0xA3, 0x84, 0x06, 0xB7, 0x96, + 0x78, 0x55, 0xAF, 0x87, 0x65, 0xCC, 0x98, 0x69, 0x41, 0xFD, 0x87, 0x4E, 0x22, 0xFF, 0x78, 0x3C, + 0x11, 0xFF, 0x73, 0x36, 0x0A, 0xFF, 0x72, 0x35, 0x08, 0xFF, 0x74, 0x36, 0x08, 0xFF, 0x76, 0x39, + 0x08, 0xFF, 0x7A, 0x3B, 0x09, 0xFF, 0x7C, 0x3E, 0x0A, 0xFF, 0x7E, 0x3F, 0x0A, 0xFF, 0x7D, 0x41, + 0x0A, 0xFF, 0x7D, 0x42, 0x0A, 0xFF, 0x7B, 0x44, 0x0D, 0xFF, 0x73, 0x42, 0x0F, 0xFF, 0x88, 0x65, + 0x41, 0xFF, 0xCE, 0xC4, 0xB3, 0xFF, 0xE4, 0xE2, 0xDF, 0xFF, 0xE6, 0xE4, 0xE4, 0xFF, 0xE5, 0xE6, + 0xE5, 0xFF, 0xE4, 0xE5, 0xE5, 0xFF, 0xE4, 0xE6, 0xE6, 0xFF, 0xE6, 0xE6, 0xE7, 0xFF, 0xE7, 0xE8, + 0xE8, 0xFF, 0xE9, 0xE9, 0xE9, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xEB, 0xEA, 0xEA, 0xFF, 0xEB, 0xEA, + 0xEA, 0xFF, 0xEA, 0xEA, 0xEB, 0xFF, 0xEA, 0xEB, 0xEB, 0xFF, 0xEA, 0xEB, 0xEB, 0xFF, 0xEA, 0xEA, + 0xEB, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xED, 0xEE, 0xEE, 0xFF, 0xE8, 0xEA, 0xE9, 0xFF, 0xCA, 0xC9, + 0xC3, 0xFF, 0x97, 0x8D, 0x7D, 0xFF, 0x82, 0x6F, 0x56, 0xFF, 0x7C, 0x6B, 0x51, 0xFF, 0xAE, 0xA3, + 0x91, 0xFF, 0xDE, 0xD9, 0xD4, 0xFF, 0xDD, 0xD8, 0xD5, 0xFF, 0xBB, 0xB0, 0xA5, 0xFF, 0x8C, 0x72, + 0x51, 0xFF, 0x78, 0x53, 0x23, 0xFF, 0x74, 0x48, 0x14, 0xFF, 0x75, 0x45, 0x0F, 0xFF, 0x7C, 0x47, + 0x0D, 0xFF, 0x84, 0x4A, 0x0E, 0xFF, 0x8A, 0x4E, 0x0E, 0xFF, 0x8F, 0x50, 0x0E, 0xFF, 0x8F, 0x51, + 0x0F, 0xFF, 0x91, 0x51, 0x0F, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x93, 0x51, 0x0F, 0xFF, 0x92, 0x51, + 0x0E, 0xFF, 0x92, 0x51, 0x0E, 0xFF, 0x92, 0x51, 0x0E, 0xFF, 0x92, 0x51, 0x0E, 0xFF, 0x92, 0x51, + 0x0E, 0xFF, 0x92, 0x51, 0x0E, 0xFF, 0x92, 0x51, 0x0E, 0xFF, 0x92, 0x51, 0x0E, 0xFF, 0x92, 0x51, + 0x0F, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x92, 0x51, + 0x0F, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x92, 0x51, + 0x0F, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x92, 0x51, + 0x0F, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x92, 0x51, + 0x0F, 0xFF, 0x92, 0x52, 0x0F, 0xFF, 0x92, 0x52, 0x0F, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x91, 0x51, + 0x0F, 0xFF, 0x91, 0x50, 0x0F, 0xFF, 0x90, 0x50, 0x0E, 0xFF, 0x91, 0x50, 0x0F, 0xFF, 0x90, 0x4F, + 0x0E, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x8E, 0x4E, 0x10, 0xFF, 0x91, 0x53, 0x18, 0xFF, 0x95, 0x5B, + 0x24, 0xFF, 0x98, 0x60, 0x2B, 0xFF, 0x98, 0x61, 0x2E, 0xFF, 0x97, 0x62, 0x31, 0xFF, 0x96, 0x62, + 0x32, 0xFF, 0x99, 0x65, 0x37, 0xFF, 0x9F, 0x6E, 0x44, 0xFF, 0xAC, 0x82, 0x5C, 0xFF, 0xB9, 0x94, + 0x72, 0xEC, 0xCB, 0xA9, 0x8E, 0x8C, 0xDC, 0xC5, 0xB2, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCD, 0xB1, 0x9A, 0x20, 0xB5, 0x92, + 0x72, 0x94, 0xA6, 0x78, 0x50, 0xEA, 0x92, 0x5C, 0x34, 0xFF, 0x7F, 0x44, 0x17, 0xFF, 0x76, 0x38, + 0x0C, 0xFF, 0x74, 0x36, 0x09, 0xFF, 0x75, 0x37, 0x09, 0xFF, 0x77, 0x38, 0x09, 0xFF, 0x79, 0x3B, + 0x09, 0xFF, 0x7C, 0x3E, 0x0A, 0xFF, 0x7F, 0x40, 0x0A, 0xFF, 0x81, 0x41, 0x0A, 0xFF, 0x7F, 0x43, + 0x0A, 0xFF, 0x7F, 0x44, 0x0D, 0xFF, 0x78, 0x41, 0x0E, 0xFF, 0x83, 0x59, 0x2D, 0xFF, 0xC3, 0xB5, + 0xA2, 0xFF, 0xE3, 0xE2, 0xDD, 0xFF, 0xE7, 0xE7, 0xE8, 0xFF, 0xE8, 0xE8, 0xE8, 0xFF, 0xE5, 0xE6, + 0xE7, 0xFF, 0xE5, 0xE6, 0xE6, 0xFF, 0xE5, 0xE6, 0xE6, 0xFF, 0xE6, 0xE6, 0xE6, 0xFF, 0xE6, 0xE7, + 0xE7, 0xFF, 0xE8, 0xE9, 0xE9, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xEB, 0xEC, 0xEB, 0xFF, 0xEB, 0xEC, + 0xEC, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xEB, 0xEC, 0xEC, 0xFF, 0xEB, 0xEC, 0xEC, 0xFF, 0xEA, 0xEB, + 0xEC, 0xFF, 0xEB, 0xEC, 0xEC, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xED, 0xEE, 0xEE, 0xFF, 0xEC, 0xEE, + 0xEE, 0xFF, 0xD3, 0xD1, 0xCE, 0xFF, 0xA1, 0x96, 0x87, 0xFF, 0x7F, 0x6B, 0x51, 0xFF, 0x73, 0x61, + 0x44, 0xFF, 0x93, 0x87, 0x73, 0xFF, 0xD0, 0xC9, 0xC3, 0xFF, 0xDF, 0xDB, 0xD9, 0xFF, 0xC9, 0xC1, + 0xBA, 0xFF, 0xA0, 0x8A, 0x72, 0xFF, 0x7F, 0x5D, 0x2F, 0xFF, 0x72, 0x4A, 0x16, 0xFF, 0x72, 0x45, + 0x0E, 0xFF, 0x79, 0x48, 0x0F, 0xFF, 0x83, 0x4B, 0x0E, 0xFF, 0x8A, 0x4E, 0x0E, 0xFF, 0x8E, 0x50, + 0x0F, 0xFF, 0x90, 0x51, 0x0F, 0xFF, 0x92, 0x52, 0x0F, 0xFF, 0x93, 0x52, 0x10, 0xFF, 0x93, 0x52, + 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x52, + 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x52, + 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x52, + 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x53, 0x0F, 0xFF, 0x93, 0x53, + 0x0F, 0xFF, 0x93, 0x53, 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x53, 0x0F, 0xFF, 0x93, 0x53, + 0x0F, 0xFF, 0x93, 0x53, 0x0F, 0xFF, 0x93, 0x53, 0x0F, 0xFF, 0x93, 0x53, 0x0F, 0xFF, 0x93, 0x53, + 0x0F, 0xFF, 0x93, 0x53, 0x0F, 0xFF, 0x93, 0x53, 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x92, 0x52, + 0x0F, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x91, 0x51, + 0x0E, 0xFF, 0x91, 0x50, 0x0E, 0xFF, 0x90, 0x4F, 0x0F, 0xFF, 0x8F, 0x4F, 0x10, 0xFF, 0x90, 0x52, + 0x16, 0xFF, 0x94, 0x59, 0x20, 0xFF, 0x98, 0x60, 0x2A, 0xFF, 0x9A, 0x63, 0x2F, 0xFF, 0x97, 0x62, + 0x31, 0xFF, 0x99, 0x64, 0x35, 0xFF, 0x9D, 0x69, 0x3D, 0xFF, 0xA4, 0x78, 0x50, 0xFF, 0xB3, 0x8C, + 0x68, 0xFC, 0xC5, 0xA1, 0x83, 0xC2, 0xD8, 0xBD, 0xA5, 0x4F, 0xDD, 0xC6, 0xAD, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0xC5, 0xAE, 0x05, 0xD6, 0xBE, 0xA7, 0x4E, 0xB2, 0x8E, + 0x6D, 0xC0, 0x9B, 0x69, 0x3E, 0xFB, 0x87, 0x4F, 0x25, 0xFF, 0x79, 0x3C, 0x10, 0xFF, 0x75, 0x37, + 0x0B, 0xFF, 0x76, 0x37, 0x08, 0xFF, 0x77, 0x38, 0x08, 0xFF, 0x79, 0x3B, 0x09, 0xFF, 0x7B, 0x3E, + 0x09, 0xFF, 0x7F, 0x40, 0x0A, 0xFF, 0x82, 0x42, 0x0B, 0xFF, 0x84, 0x44, 0x0B, 0xFF, 0x84, 0x47, + 0x0D, 0xFF, 0x81, 0x48, 0x0D, 0xFF, 0x83, 0x55, 0x25, 0xFF, 0xBF, 0xA8, 0x8D, 0xFF, 0xDF, 0xDD, + 0xD6, 0xFF, 0xE9, 0xE8, 0xE7, 0xFF, 0xE9, 0xEA, 0xEB, 0xFF, 0xE8, 0xE8, 0xE9, 0xFF, 0xE6, 0xE7, + 0xE8, 0xFF, 0xE6, 0xE7, 0xE7, 0xFF, 0xE6, 0xE7, 0xE6, 0xFF, 0xE7, 0xE7, 0xE7, 0xFF, 0xE7, 0xE8, + 0xE8, 0xFF, 0xE8, 0xE9, 0xE9, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xEC, 0xED, + 0xEC, 0xFF, 0xED, 0xED, 0xED, 0xFF, 0xED, 0xED, 0xED, 0xFF, 0xEC, 0xED, 0xED, 0xFF, 0xEC, 0xED, + 0xEE, 0xFF, 0xEC, 0xED, 0xEE, 0xFF, 0xEB, 0xED, 0xEE, 0xFF, 0xEC, 0xED, 0xED, 0xFF, 0xED, 0xEE, + 0xEE, 0xFF, 0xEC, 0xEE, 0xEF, 0xFF, 0xDB, 0xDD, 0xD9, 0xFF, 0xA6, 0xA0, 0x91, 0xFF, 0x7F, 0x6B, + 0x52, 0xFF, 0x71, 0x5D, 0x41, 0xFF, 0x8B, 0x7D, 0x67, 0xFF, 0xC2, 0xBA, 0xB1, 0xFF, 0xDE, 0xDA, + 0xD8, 0xFF, 0xD3, 0xCE, 0xCA, 0xFF, 0xAA, 0x98, 0x87, 0xFF, 0x85, 0x66, 0x3F, 0xFF, 0x76, 0x4F, + 0x20, 0xFF, 0x71, 0x46, 0x12, 0xFF, 0x79, 0x48, 0x0F, 0xFF, 0x81, 0x4A, 0x0E, 0xFF, 0x87, 0x4E, + 0x0F, 0xFF, 0x8D, 0x50, 0x0F, 0xFF, 0x8F, 0x51, 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x94, 0x53, + 0x10, 0xFF, 0x94, 0x53, 0x10, 0xFF, 0x94, 0x53, 0x10, 0xFF, 0x94, 0x53, 0x10, 0xFF, 0x94, 0x53, + 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x53, + 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x53, + 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x53, + 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x53, + 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x53, + 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x93, 0x53, + 0x0F, 0xFF, 0x93, 0x53, 0x0F, 0xFF, 0x93, 0x53, 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x92, 0x52, + 0x0E, 0xFF, 0x92, 0x51, 0x0E, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x91, 0x50, 0x0F, 0xFF, 0x8F, 0x4F, + 0x0F, 0xFF, 0x91, 0x52, 0x14, 0xFF, 0x94, 0x59, 0x1F, 0xFF, 0x98, 0x5F, 0x28, 0xFF, 0x98, 0x62, + 0x2E, 0xFF, 0x99, 0x64, 0x32, 0xFF, 0x9D, 0x68, 0x3A, 0xFF, 0x9F, 0x6F, 0x45, 0xFF, 0xAD, 0x83, + 0x5D, 0xFF, 0xBB, 0x97, 0x75, 0xE7, 0xC8, 0xA7, 0x8D, 0x83, 0xC5, 0xAA, 0x8C, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD3, 0xB7, 0x9C, 0x18, 0xCB, 0xAC, 0x90, 0x7E, 0xA9, 0x80, + 0x5C, 0xE1, 0x93, 0x5E, 0x31, 0xFF, 0x81, 0x45, 0x19, 0xFF, 0x79, 0x3A, 0x0D, 0xFF, 0x76, 0x38, + 0x09, 0xFF, 0x77, 0x38, 0x08, 0xFF, 0x79, 0x3B, 0x08, 0xFF, 0x7C, 0x3E, 0x09, 0xFF, 0x7F, 0x40, + 0x0A, 0xFF, 0x82, 0x42, 0x0B, 0xFF, 0x84, 0x44, 0x0B, 0xFF, 0x86, 0x46, 0x0C, 0xFF, 0x8A, 0x4B, + 0x11, 0xFF, 0x82, 0x47, 0x09, 0xFF, 0x92, 0x68, 0x35, 0xFF, 0xD4, 0xC3, 0xB9, 0xFF, 0xE8, 0xE6, + 0xE2, 0xFF, 0xEB, 0xEA, 0xE9, 0xFF, 0xEB, 0xEC, 0xED, 0xFF, 0xE9, 0xEA, 0xEB, 0xFF, 0xE9, 0xE9, + 0xEA, 0xFF, 0xE8, 0xE9, 0xE8, 0xFF, 0xE9, 0xE9, 0xE9, 0xFF, 0xE9, 0xE9, 0xE9, 0xFF, 0xE8, 0xE9, + 0xE8, 0xFF, 0xE9, 0xE9, 0xE9, 0xFF, 0xE9, 0xEA, 0xE9, 0xFF, 0xEB, 0xEB, 0xEA, 0xFF, 0xEC, 0xED, + 0xEC, 0xFF, 0xED, 0xEE, 0xED, 0xFF, 0xED, 0xEE, 0xEE, 0xFF, 0xED, 0xEE, 0xEE, 0xFF, 0xED, 0xEE, + 0xEE, 0xFF, 0xED, 0xEE, 0xEE, 0xFF, 0xEC, 0xEE, 0xEE, 0xFF, 0xED, 0xED, 0xEE, 0xFF, 0xED, 0xEE, + 0xEE, 0xFF, 0xED, 0xEF, 0xEF, 0xFF, 0xED, 0xF0, 0xF0, 0xFF, 0xE2, 0xE6, 0xE3, 0xFF, 0xB5, 0xAF, + 0xA6, 0xFF, 0x82, 0x70, 0x59, 0xFF, 0x6E, 0x5D, 0x40, 0xFF, 0x79, 0x6A, 0x50, 0xFF, 0xB1, 0xA7, + 0x96, 0xFF, 0xDD, 0xDA, 0xD7, 0xFF, 0xDB, 0xD8, 0xD5, 0xFF, 0xBC, 0xB0, 0xA3, 0xFF, 0x90, 0x75, + 0x54, 0xFF, 0x76, 0x53, 0x25, 0xFF, 0x72, 0x49, 0x14, 0xFF, 0x77, 0x4A, 0x13, 0xFF, 0x7F, 0x4B, + 0x10, 0xFF, 0x86, 0x4D, 0x0F, 0xFF, 0x8C, 0x50, 0x10, 0xFF, 0x91, 0x53, 0x10, 0xFF, 0x94, 0x54, + 0x10, 0xFF, 0x95, 0x54, 0x11, 0xFF, 0x95, 0x54, 0x11, 0xFF, 0x95, 0x54, 0x11, 0xFF, 0x95, 0x54, + 0x11, 0xFF, 0x95, 0x54, 0x10, 0xFF, 0x95, 0x54, 0x10, 0xFF, 0x95, 0x54, 0x10, 0xFF, 0x95, 0x54, + 0x10, 0xFF, 0x95, 0x54, 0x10, 0xFF, 0x95, 0x54, 0x10, 0xFF, 0x95, 0x54, 0x10, 0xFF, 0x95, 0x54, + 0x10, 0xFF, 0x95, 0x54, 0x10, 0xFF, 0x95, 0x54, 0x0F, 0xFF, 0x95, 0x54, 0x0F, 0xFF, 0x95, 0x54, + 0x0F, 0xFF, 0x95, 0x53, 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x54, 0x0F, 0xFF, 0x94, 0x53, + 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x54, 0x0F, 0xFF, 0x94, 0x54, + 0x0F, 0xFF, 0x94, 0x54, 0x0F, 0xFF, 0x94, 0x54, 0x0F, 0xFF, 0x94, 0x54, 0x0F, 0xFF, 0x94, 0x54, + 0x0F, 0xFF, 0x94, 0x54, 0x0F, 0xFF, 0x94, 0x54, 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x53, + 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x92, 0x52, 0x0F, 0xFF, 0x91, 0x50, + 0x0E, 0xFF, 0x90, 0x50, 0x0F, 0xFF, 0x90, 0x52, 0x13, 0xFF, 0x92, 0x57, 0x1B, 0xFF, 0x97, 0x5E, + 0x27, 0xFF, 0x9A, 0x63, 0x2E, 0xFF, 0x9C, 0x66, 0x34, 0xFF, 0x9D, 0x6A, 0x3D, 0xFF, 0xAA, 0x7E, + 0x56, 0xFF, 0xB9, 0x91, 0x6B, 0xFC, 0xBC, 0x95, 0x76, 0xB8, 0xCC, 0xB0, 0x91, 0x3D, 0xF9, 0xFF, + 0xFB, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xC9, 0xB1, 0x97, 0x02, 0xC0, 0xA3, 0x86, 0x35, 0xBA, 0x93, 0x70, 0xAF, 0xA0, 0x71, + 0x49, 0xF5, 0x90, 0x56, 0x28, 0xFF, 0x80, 0x42, 0x15, 0xFF, 0x79, 0x3A, 0x0C, 0xFF, 0x78, 0x39, + 0x08, 0xFF, 0x79, 0x3A, 0x08, 0xFF, 0x7B, 0x3D, 0x09, 0xFF, 0x7E, 0x40, 0x09, 0xFF, 0x81, 0x42, + 0x0B, 0xFF, 0x84, 0x44, 0x0C, 0xFF, 0x86, 0x47, 0x0C, 0xFF, 0x88, 0x48, 0x0C, 0xFF, 0x8B, 0x4C, + 0x0F, 0xFF, 0x8C, 0x4D, 0x11, 0xFF, 0x84, 0x4F, 0x10, 0xFF, 0xAA, 0x8F, 0x6E, 0xFF, 0xE1, 0xDF, + 0xDA, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xEB, 0xEC, 0xED, 0xFF, 0xEB, 0xEC, 0xED, 0xFF, 0xEA, 0xEB, + 0xEB, 0xFF, 0xEA, 0xEB, 0xEB, 0xFF, 0xEA, 0xEB, 0xEB, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xEA, 0xEB, + 0xEA, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xEC, 0xEC, + 0xEB, 0xFF, 0xED, 0xED, 0xED, 0xFF, 0xED, 0xEE, 0xEE, 0xFF, 0xEE, 0xEF, 0xEE, 0xFF, 0xEE, 0xEF, + 0xEF, 0xFF, 0xEE, 0xEE, 0xEF, 0xFF, 0xEE, 0xEF, 0xEF, 0xFF, 0xEE, 0xEF, 0xF0, 0xFF, 0xEE, 0xEF, + 0xEF, 0xFF, 0xEE, 0xEF, 0xF0, 0xFF, 0xEE, 0xF0, 0xF0, 0xFF, 0xEE, 0xF1, 0xF1, 0xFF, 0xEB, 0xED, + 0xED, 0xFF, 0xC3, 0xC1, 0xBA, 0xFF, 0x85, 0x75, 0x5F, 0xFF, 0x71, 0x5F, 0x3F, 0xFF, 0x7C, 0x6C, + 0x49, 0xFF, 0x9E, 0x92, 0x7D, 0xFF, 0xD2, 0xCD, 0xC9, 0xFF, 0xDF, 0xDC, 0xDB, 0xFF, 0xCB, 0xC2, + 0xBB, 0xFF, 0x9C, 0x88, 0x70, 0xFF, 0x7A, 0x59, 0x31, 0xFF, 0x73, 0x4C, 0x19, 0xFF, 0x78, 0x49, + 0x13, 0xFF, 0x7D, 0x49, 0x10, 0xFF, 0x85, 0x4E, 0x11, 0xFF, 0x8C, 0x50, 0x11, 0xFF, 0x91, 0x53, + 0x11, 0xFF, 0x95, 0x55, 0x12, 0xFF, 0x96, 0x56, 0x12, 0xFF, 0x96, 0x55, 0x12, 0xFF, 0x96, 0x55, + 0x12, 0xFF, 0x96, 0x55, 0x11, 0xFF, 0x96, 0x55, 0x11, 0xFF, 0x96, 0x55, 0x11, 0xFF, 0x96, 0x56, + 0x11, 0xFF, 0x96, 0x56, 0x11, 0xFF, 0x96, 0x56, 0x11, 0xFF, 0x96, 0x56, 0x11, 0xFF, 0x96, 0x56, + 0x11, 0xFF, 0x96, 0x56, 0x10, 0xFF, 0x96, 0x55, 0x10, 0xFF, 0x96, 0x55, 0x10, 0xFF, 0x96, 0x55, + 0x10, 0xFF, 0x96, 0x54, 0x10, 0xFF, 0x95, 0x54, 0x0F, 0xFF, 0x95, 0x54, 0x0F, 0xFF, 0x95, 0x54, + 0x0F, 0xFF, 0x95, 0x54, 0x0F, 0xFF, 0x95, 0x54, 0x0F, 0xFF, 0x95, 0x54, 0x0F, 0xFF, 0x95, 0x54, + 0x0F, 0xFF, 0x95, 0x54, 0x0F, 0xFF, 0x95, 0x54, 0x0F, 0xFF, 0x96, 0x55, 0x0F, 0xFF, 0x95, 0x55, + 0x0F, 0xFF, 0x96, 0x55, 0x0F, 0xFF, 0x95, 0x55, 0x0F, 0xFF, 0x96, 0x55, 0x0F, 0xFF, 0x95, 0x55, + 0x0F, 0xFF, 0x95, 0x54, 0x0F, 0xFF, 0x94, 0x54, 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x92, 0x52, + 0x0F, 0xFF, 0x91, 0x50, 0x0E, 0xFF, 0x8F, 0x50, 0x0E, 0xFF, 0x91, 0x53, 0x12, 0xFF, 0x93, 0x58, + 0x1C, 0xFF, 0x98, 0x5F, 0x26, 0xFF, 0x9B, 0x64, 0x2E, 0xFF, 0x9C, 0x68, 0x36, 0xFF, 0xA4, 0x76, + 0x4B, 0xFF, 0xB2, 0x89, 0x61, 0xFF, 0xB6, 0x8C, 0x6A, 0xDE, 0xE2, 0xC7, 0xAD, 0x69, 0xFE, 0xFF, + 0xFF, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xF4, 0xE8, 0xDB, 0x0A, 0xC3, 0xA1, 0x84, 0x62, 0xB0, 0x81, 0x58, 0xD8, 0x9A, 0x66, + 0x3D, 0xFD, 0x8B, 0x4F, 0x20, 0xFF, 0x7D, 0x3E, 0x0F, 0xFF, 0x7A, 0x3A, 0x0A, 0xFF, 0x7B, 0x3B, + 0x09, 0xFF, 0x7C, 0x3D, 0x09, 0xFF, 0x7F, 0x40, 0x0A, 0xFF, 0x81, 0x42, 0x0A, 0xFF, 0x83, 0x44, + 0x0C, 0xFF, 0x86, 0x47, 0x0C, 0xFF, 0x88, 0x49, 0x0D, 0xFF, 0x8A, 0x4B, 0x0E, 0xFF, 0x8B, 0x4C, + 0x0E, 0xFF, 0x8A, 0x4D, 0x0F, 0xFF, 0x8A, 0x51, 0x13, 0xFF, 0x8A, 0x5B, 0x20, 0xFF, 0xB6, 0x9F, + 0x84, 0xFF, 0xE8, 0xE4, 0xE0, 0xFF, 0xEE, 0xED, 0xEE, 0xFF, 0xED, 0xEE, 0xEE, 0xFF, 0xEB, 0xED, + 0xED, 0xFF, 0xEB, 0xED, 0xED, 0xFF, 0xEB, 0xED, 0xED, 0xFF, 0xEC, 0xED, 0xEC, 0xFF, 0xEC, 0xED, + 0xEC, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xEC, 0xEC, + 0xEC, 0xFF, 0xEC, 0xED, 0xEC, 0xFF, 0xED, 0xEE, 0xEE, 0xFF, 0xEE, 0xEF, 0xEF, 0xFF, 0xEE, 0xEF, + 0xEF, 0xFF, 0xEE, 0xEF, 0xEF, 0xFF, 0xEE, 0xEF, 0xF0, 0xFF, 0xEF, 0xF0, 0xF0, 0xFF, 0xEF, 0xEF, + 0xEF, 0xFF, 0xEF, 0xEF, 0xEF, 0xFF, 0xEF, 0xF1, 0xF0, 0xFF, 0xED, 0xF0, 0xF0, 0xFF, 0xEF, 0xF1, + 0xF2, 0xFF, 0xED, 0xEF, 0xF0, 0xFF, 0xCE, 0xCD, 0xC9, 0xFF, 0x8E, 0x81, 0x6F, 0xFF, 0x75, 0x64, + 0x44, 0xFF, 0x77, 0x65, 0x42, 0xFF, 0x8F, 0x80, 0x67, 0xFF, 0xC9, 0xC5, 0xBB, 0xFF, 0xE2, 0xDF, + 0xDE, 0xFF, 0xD8, 0xD3, 0xCD, 0xFF, 0xB0, 0xA2, 0x8F, 0xFF, 0x85, 0x6A, 0x46, 0xFF, 0x79, 0x54, + 0x23, 0xFF, 0x78, 0x4C, 0x18, 0xFF, 0x7C, 0x4C, 0x12, 0xFF, 0x83, 0x4E, 0x12, 0xFF, 0x8B, 0x51, + 0x12, 0xFF, 0x91, 0x55, 0x13, 0xFF, 0x95, 0x56, 0x13, 0xFF, 0x96, 0x57, 0x13, 0xFF, 0x97, 0x57, + 0x13, 0xFF, 0x97, 0x58, 0x13, 0xFF, 0x98, 0x58, 0x13, 0xFF, 0x98, 0x58, 0x13, 0xFF, 0x98, 0x58, + 0x13, 0xFF, 0x98, 0x58, 0x12, 0xFF, 0x98, 0x58, 0x12, 0xFF, 0x98, 0x58, 0x12, 0xFF, 0x98, 0x58, + 0x12, 0xFF, 0x98, 0x58, 0x12, 0xFF, 0x98, 0x57, 0x12, 0xFF, 0x98, 0x57, 0x12, 0xFF, 0x98, 0x57, + 0x12, 0xFF, 0x98, 0x57, 0x11, 0xFF, 0x97, 0x56, 0x11, 0xFF, 0x97, 0x56, 0x10, 0xFF, 0x97, 0x56, + 0x10, 0xFF, 0x97, 0x56, 0x10, 0xFF, 0x97, 0x55, 0x10, 0xFF, 0x97, 0x55, 0x10, 0xFF, 0x96, 0x55, + 0x10, 0xFF, 0x96, 0x55, 0x10, 0xFF, 0x97, 0x55, 0x10, 0xFF, 0x97, 0x56, 0x10, 0xFF, 0x97, 0x56, + 0x10, 0xFF, 0x97, 0x57, 0x10, 0xFF, 0x97, 0x56, 0x10, 0xFF, 0x97, 0x56, 0x10, 0xFF, 0x96, 0x56, + 0x10, 0xFF, 0x96, 0x55, 0x10, 0xFF, 0x95, 0x55, 0x10, 0xFF, 0x95, 0x54, 0x10, 0xFF, 0x94, 0x54, + 0x10, 0xFF, 0x93, 0x53, 0x0F, 0xFF, 0x92, 0x51, 0x0E, 0xFF, 0x91, 0x51, 0x0F, 0xFF, 0x91, 0x53, + 0x13, 0xFF, 0x94, 0x57, 0x1A, 0xFF, 0x98, 0x5E, 0x26, 0xFF, 0x9C, 0x66, 0x32, 0xFF, 0xA0, 0x6F, + 0x40, 0xFF, 0xAE, 0x83, 0x59, 0xFF, 0xB6, 0x8A, 0x66, 0xF1, 0xD6, 0xBD, 0xA0, 0x9B, 0xE3, 0xCF, + 0xBB, 0x26, 0xDC, 0xC7, 0xB0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xF3, 0xEA, 0x1F, 0xC9, 0xA6, 0x88, 0x8D, 0xA9, 0x77, 0x4C, 0xF1, 0x92, 0x5D, + 0x32, 0xFF, 0x86, 0x48, 0x18, 0xFF, 0x7B, 0x3C, 0x0C, 0xFF, 0x7C, 0x3C, 0x0A, 0xFF, 0x7D, 0x3C, + 0x09, 0xFF, 0x7F, 0x3F, 0x09, 0xFF, 0x81, 0x42, 0x0A, 0xFF, 0x84, 0x44, 0x0B, 0xFF, 0x86, 0x47, + 0x0C, 0xFF, 0x89, 0x49, 0x0D, 0xFF, 0x8B, 0x4B, 0x0E, 0xFF, 0x8D, 0x4D, 0x0F, 0xFF, 0x8E, 0x4E, + 0x0E, 0xFF, 0x8E, 0x4F, 0x0F, 0xFF, 0x8F, 0x51, 0x11, 0xFF, 0x8D, 0x53, 0x13, 0xFF, 0x94, 0x68, + 0x2D, 0xFF, 0xCA, 0xB3, 0x9C, 0xFF, 0xED, 0xE9, 0xE5, 0xFF, 0xEF, 0xEE, 0xEF, 0xFF, 0xED, 0xED, + 0xEE, 0xFF, 0xEC, 0xEE, 0xEE, 0xFF, 0xED, 0xEE, 0xEE, 0xFF, 0xED, 0xEE, 0xEE, 0xFF, 0xED, 0xEE, + 0xED, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xED, 0xEE, 0xED, 0xFF, 0xEC, 0xED, 0xED, 0xFF, 0xED, 0xED, + 0xED, 0xFF, 0xED, 0xEE, 0xED, 0xFF, 0xED, 0xEE, 0xEE, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEE, 0xEF, + 0xEF, 0xFF, 0xEF, 0xF0, 0xF0, 0xFF, 0xF0, 0xF1, 0xF1, 0xFF, 0xF0, 0xF1, 0xF1, 0xFF, 0xF0, 0xF1, + 0xF1, 0xFF, 0xF0, 0xF1, 0xF1, 0xFF, 0xF0, 0xF2, 0xF1, 0xFF, 0xF0, 0xF1, 0xF2, 0xFF, 0xF0, 0xF2, + 0xF3, 0xFF, 0xF2, 0xF3, 0xF4, 0xFF, 0xF1, 0xF2, 0xF4, 0xFF, 0xD9, 0xD8, 0xD4, 0xFF, 0x95, 0x8A, + 0x73, 0xFF, 0x78, 0x66, 0x44, 0xFF, 0x7E, 0x6A, 0x46, 0xFF, 0x85, 0x73, 0x55, 0xFF, 0xBB, 0xB2, + 0xA2, 0xFF, 0xE2, 0xDF, 0xDC, 0xFF, 0xDF, 0xDA, 0xD7, 0xFF, 0xBC, 0xB2, 0xA4, 0xFF, 0x8F, 0x77, + 0x56, 0xFF, 0x7D, 0x5A, 0x2C, 0xFF, 0x78, 0x4E, 0x1A, 0xFF, 0x7A, 0x4B, 0x14, 0xFF, 0x82, 0x4E, + 0x12, 0xFF, 0x8B, 0x51, 0x13, 0xFF, 0x91, 0x56, 0x13, 0xFF, 0x96, 0x58, 0x13, 0xFF, 0x97, 0x59, + 0x14, 0xFF, 0x98, 0x59, 0x13, 0xFF, 0x99, 0x5A, 0x14, 0xFF, 0x9A, 0x59, 0x14, 0xFF, 0x99, 0x59, + 0x14, 0xFF, 0x9A, 0x59, 0x13, 0xFF, 0x99, 0x5A, 0x13, 0xFF, 0x9A, 0x5A, 0x13, 0xFF, 0x99, 0x5A, + 0x14, 0xFF, 0x9A, 0x59, 0x14, 0xFF, 0x99, 0x59, 0x13, 0xFF, 0x9A, 0x59, 0x13, 0xFF, 0x99, 0x59, + 0x13, 0xFF, 0x99, 0x59, 0x13, 0xFF, 0x98, 0x58, 0x12, 0xFF, 0x99, 0x58, 0x12, 0xFF, 0x98, 0x58, + 0x11, 0xFF, 0x99, 0x58, 0x11, 0xFF, 0x98, 0x57, 0x11, 0xFF, 0x98, 0x56, 0x10, 0xFF, 0x97, 0x56, + 0x10, 0xFF, 0x98, 0x56, 0x10, 0xFF, 0x98, 0x56, 0x10, 0xFF, 0x98, 0x56, 0x10, 0xFF, 0x98, 0x57, + 0x10, 0xFF, 0x98, 0x57, 0x10, 0xFF, 0x98, 0x57, 0x10, 0xFF, 0x98, 0x57, 0x10, 0xFF, 0x97, 0x57, + 0x10, 0xFF, 0x97, 0x56, 0x10, 0xFF, 0x96, 0x56, 0x10, 0xFF, 0x96, 0x55, 0x10, 0xFF, 0x95, 0x55, + 0x10, 0xFF, 0x95, 0x54, 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x93, 0x51, 0x0E, 0xFF, 0x91, 0x51, + 0x0E, 0xFF, 0x92, 0x53, 0x12, 0xFF, 0x94, 0x57, 0x1B, 0xFF, 0x9A, 0x60, 0x29, 0xFF, 0x9F, 0x6B, + 0x39, 0xFF, 0xA8, 0x79, 0x4C, 0xFF, 0xB3, 0x87, 0x62, 0xFC, 0xBB, 0x9C, 0x7A, 0xC2, 0xCA, 0xAB, + 0x8E, 0x49, 0xD1, 0xBB, 0xA0, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD3, 0xC1, + 0xB0, 0x03, 0xDB, 0xC5, 0xB0, 0x3A, 0xBB, 0x96, 0x76, 0xBA, 0xA4, 0x72, 0x44, 0xF9, 0x8F, 0x56, + 0x26, 0xFF, 0x82, 0x44, 0x12, 0xFF, 0x7C, 0x3C, 0x0B, 0xFF, 0x7E, 0x3D, 0x0A, 0xFF, 0x80, 0x3E, + 0x0A, 0xFF, 0x82, 0x41, 0x09, 0xFF, 0x85, 0x44, 0x0A, 0xFF, 0x87, 0x46, 0x0B, 0xFF, 0x89, 0x49, + 0x0D, 0xFF, 0x8C, 0x4B, 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x90, 0x4F, 0x0F, 0xFF, 0x92, 0x51, + 0x0F, 0xFF, 0x92, 0x53, 0x10, 0xFF, 0x92, 0x53, 0x10, 0xFF, 0x90, 0x53, 0x11, 0xFF, 0x89, 0x56, + 0x18, 0xFF, 0x9E, 0x76, 0x42, 0xFF, 0xD8, 0xC8, 0xB9, 0xFF, 0xF2, 0xED, 0xE8, 0xFF, 0xEE, 0xED, + 0xEC, 0xFF, 0xED, 0xEE, 0xEE, 0xFF, 0xEC, 0xEE, 0xEF, 0xFF, 0xEC, 0xEE, 0xEE, 0xFF, 0xED, 0xEE, + 0xEE, 0xFF, 0xEE, 0xEF, 0xEE, 0xFF, 0xEE, 0xEF, 0xEF, 0xFF, 0xEE, 0xEF, 0xEF, 0xFF, 0xEE, 0xEE, + 0xEE, 0xFF, 0xED, 0xEE, 0xEE, 0xFF, 0xED, 0xEE, 0xEE, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEE, 0xEF, + 0xEF, 0xFF, 0xEF, 0xF0, 0xF0, 0xFF, 0xF0, 0xF1, 0xF1, 0xFF, 0xF1, 0xF2, 0xF2, 0xFF, 0xF1, 0xF2, + 0xF2, 0xFF, 0xF1, 0xF2, 0xF2, 0xFF, 0xF1, 0xF2, 0xF2, 0xFF, 0xF1, 0xF2, 0xF2, 0xFF, 0xF1, 0xF2, + 0xF2, 0xFF, 0xF0, 0xF2, 0xF2, 0xFF, 0xF1, 0xF2, 0xF3, 0xFF, 0xF2, 0xF3, 0xF5, 0xFF, 0xE5, 0xE5, + 0xE2, 0xFF, 0xA4, 0x9D, 0x8D, 0xFF, 0x7B, 0x6A, 0x4C, 0xFF, 0x7A, 0x64, 0x42, 0xFF, 0x7A, 0x65, + 0x45, 0xFF, 0xAA, 0x9D, 0x89, 0xFF, 0xDB, 0xD7, 0xD4, 0xFF, 0xE5, 0xE2, 0xE0, 0xFF, 0xCC, 0xC7, + 0xBD, 0xFF, 0xA5, 0x92, 0x7A, 0xFF, 0x84, 0x64, 0x38, 0xFF, 0x79, 0x52, 0x1E, 0xFF, 0x79, 0x4D, + 0x15, 0xFF, 0x7F, 0x4F, 0x14, 0xFF, 0x8A, 0x54, 0x13, 0xFF, 0x92, 0x57, 0x14, 0xFF, 0x96, 0x59, + 0x14, 0xFF, 0x98, 0x5A, 0x15, 0xFF, 0x9A, 0x5A, 0x14, 0xFF, 0x9B, 0x5B, 0x15, 0xFF, 0x9B, 0x5B, + 0x15, 0xFF, 0x9B, 0x5B, 0x15, 0xFF, 0x9B, 0x5B, 0x15, 0xFF, 0x9B, 0x5B, 0x15, 0xFF, 0x9B, 0x5B, + 0x15, 0xFF, 0x9B, 0x5B, 0x15, 0xFF, 0x9B, 0x5B, 0x15, 0xFF, 0x9B, 0x5B, 0x15, 0xFF, 0x9B, 0x5B, + 0x14, 0xFF, 0x9B, 0x5B, 0x14, 0xFF, 0x9B, 0x5B, 0x14, 0xFF, 0x9B, 0x5B, 0x14, 0xFF, 0x9B, 0x5A, + 0x14, 0xFF, 0x9B, 0x5A, 0x14, 0xFF, 0x9A, 0x5A, 0x13, 0xFF, 0x9A, 0x59, 0x12, 0xFF, 0x99, 0x58, + 0x12, 0xFF, 0x99, 0x57, 0x11, 0xFF, 0x99, 0x57, 0x10, 0xFF, 0x99, 0x57, 0x10, 0xFF, 0x99, 0x57, + 0x10, 0xFF, 0x99, 0x58, 0x10, 0xFF, 0x99, 0x58, 0x10, 0xFF, 0x99, 0x58, 0x10, 0xFF, 0x99, 0x57, + 0x10, 0xFF, 0x99, 0x57, 0x10, 0xFF, 0x98, 0x57, 0x10, 0xFF, 0x98, 0x57, 0x10, 0xFF, 0x97, 0x57, + 0x10, 0xFF, 0x97, 0x56, 0x10, 0xFF, 0x96, 0x55, 0x0F, 0xFF, 0x95, 0x53, 0x0F, 0xFF, 0x93, 0x52, + 0x0E, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x92, 0x52, 0x12, 0xFF, 0x95, 0x57, 0x1B, 0xFF, 0x9D, 0x64, + 0x2F, 0xFF, 0xA4, 0x72, 0x43, 0xFF, 0xB0, 0x81, 0x57, 0xFF, 0xC6, 0xA2, 0x80, 0xDD, 0xC7, 0xA7, + 0x8B, 0x74, 0xD8, 0xBB, 0x9F, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDA, 0xC1, + 0xA4, 0x0A, 0xC6, 0xA7, 0x88, 0x5E, 0xB1, 0x87, 0x64, 0xD6, 0xA0, 0x6A, 0x39, 0xFC, 0x8D, 0x51, + 0x20, 0xFF, 0x7E, 0x3F, 0x0F, 0xFF, 0x7D, 0x3D, 0x0A, 0xFF, 0x7F, 0x3D, 0x0A, 0xFF, 0x81, 0x40, + 0x0A, 0xFF, 0x84, 0x43, 0x0A, 0xFF, 0x86, 0x46, 0x0B, 0xFF, 0x89, 0x48, 0x0C, 0xFF, 0x8B, 0x4B, + 0x0D, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x90, 0x4F, 0x0F, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x93, 0x53, + 0x0F, 0xFF, 0x94, 0x54, 0x10, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x54, 0x0E, 0xFF, 0x8C, 0x53, + 0x0F, 0xFF, 0x8F, 0x5B, 0x1B, 0xFF, 0xA7, 0x87, 0x5D, 0xFF, 0xE2, 0xD8, 0xCE, 0xFF, 0xF0, 0xEE, + 0xEC, 0xFF, 0xEE, 0xEE, 0xEF, 0xFF, 0xEC, 0xEE, 0xEF, 0xFF, 0xED, 0xEE, 0xEF, 0xFF, 0xED, 0xEF, + 0xEF, 0xFF, 0xEE, 0xEF, 0xEE, 0xFF, 0xEE, 0xEF, 0xEF, 0xFF, 0xEF, 0xEF, 0xEF, 0xFF, 0xEE, 0xEF, + 0xEF, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xED, 0xEE, 0xEE, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEE, 0xEF, + 0xEE, 0xFF, 0xEE, 0xEF, 0xEF, 0xFF, 0xF0, 0xF0, 0xF0, 0xFF, 0xF1, 0xF1, 0xF1, 0xFF, 0xF1, 0xF2, + 0xF2, 0xFF, 0xF2, 0xF2, 0xF2, 0xFF, 0xF2, 0xF2, 0xF2, 0xFF, 0xF2, 0xF2, 0xF2, 0xFF, 0xF1, 0xF2, + 0xF3, 0xFF, 0xF1, 0xF2, 0xF3, 0xFF, 0xF2, 0xF2, 0xF4, 0xFF, 0xF3, 0xF3, 0xF3, 0xFF, 0xF3, 0xF2, + 0xF5, 0xFF, 0xE8, 0xE9, 0xE8, 0xFF, 0xB4, 0xB0, 0xA4, 0xFF, 0x83, 0x75, 0x5A, 0xFF, 0x7A, 0x66, + 0x45, 0xFF, 0x76, 0x62, 0x3F, 0xFF, 0x9E, 0x91, 0x7B, 0xFF, 0xD9, 0xD4, 0xCF, 0xFF, 0xE4, 0xE1, + 0xE0, 0xFF, 0xD8, 0xD3, 0xCE, 0xFF, 0xAE, 0xA0, 0x8E, 0xFF, 0x8A, 0x6E, 0x49, 0xFF, 0x7B, 0x56, + 0x27, 0xFF, 0x76, 0x4D, 0x18, 0xFF, 0x7E, 0x50, 0x14, 0xFF, 0x88, 0x53, 0x14, 0xFF, 0x8F, 0x57, + 0x15, 0xFF, 0x95, 0x59, 0x15, 0xFF, 0x99, 0x5B, 0x15, 0xFF, 0x9B, 0x5B, 0x16, 0xFF, 0x9C, 0x5C, + 0x16, 0xFF, 0x9C, 0x5C, 0x16, 0xFF, 0x9C, 0x5C, 0x16, 0xFF, 0x9C, 0x5C, 0x16, 0xFF, 0x9C, 0x5C, + 0x16, 0xFF, 0x9C, 0x5C, 0x16, 0xFF, 0x9C, 0x5D, 0x16, 0xFF, 0x9D, 0x5D, 0x16, 0xFF, 0x9C, 0x5C, + 0x16, 0xFF, 0x9C, 0x5C, 0x16, 0xFF, 0x9C, 0x5D, 0x16, 0xFF, 0x9D, 0x5C, 0x16, 0xFF, 0x9C, 0x5C, + 0x16, 0xFF, 0x9C, 0x5C, 0x16, 0xFF, 0x9C, 0x5C, 0x15, 0xFF, 0x9C, 0x5C, 0x14, 0xFF, 0x9B, 0x5B, + 0x14, 0xFF, 0x9B, 0x59, 0x13, 0xFF, 0x9A, 0x59, 0x11, 0xFF, 0x9A, 0x58, 0x11, 0xFF, 0x9A, 0x58, + 0x11, 0xFF, 0x9A, 0x58, 0x11, 0xFF, 0x9A, 0x58, 0x10, 0xFF, 0x9A, 0x58, 0x10, 0xFF, 0x9A, 0x58, + 0x10, 0xFF, 0x9A, 0x58, 0x10, 0xFF, 0x99, 0x58, 0x10, 0xFF, 0x99, 0x58, 0x10, 0xFF, 0x98, 0x58, + 0x10, 0xFF, 0x98, 0x57, 0x10, 0xFF, 0x97, 0x56, 0x10, 0xFF, 0x97, 0x55, 0x0F, 0xFF, 0x95, 0x53, + 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x92, 0x52, 0x0F, 0xFF, 0x93, 0x53, 0x12, 0xFF, 0x99, 0x5C, + 0x22, 0xFF, 0xA1, 0x6C, 0x3B, 0xFF, 0xA7, 0x78, 0x4E, 0xFF, 0xC2, 0x9C, 0x76, 0xF3, 0xD4, 0xB1, + 0x8E, 0x9A, 0xD5, 0xBA, 0xA3, 0x2C, 0xA7, 0x96, 0x7E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD2, 0xB7, + 0x97, 0x18, 0xC8, 0xA9, 0x8A, 0x84, 0xA8, 0x7C, 0x56, 0xE9, 0x9B, 0x63, 0x33, 0xFD, 0x88, 0x4B, + 0x1A, 0xFF, 0x80, 0x40, 0x0D, 0xFF, 0x80, 0x3E, 0x0A, 0xFF, 0x81, 0x3F, 0x0A, 0xFF, 0x83, 0x43, + 0x0A, 0xFF, 0x86, 0x46, 0x0B, 0xFF, 0x88, 0x49, 0x0C, 0xFF, 0x8A, 0x4B, 0x0D, 0xFF, 0x8D, 0x4D, + 0x0E, 0xFF, 0x8F, 0x4F, 0x0E, 0xFF, 0x91, 0x51, 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x95, 0x54, + 0x10, 0xFF, 0x96, 0x56, 0x10, 0xFF, 0x96, 0x56, 0x0F, 0xFF, 0x97, 0x57, 0x10, 0xFF, 0x94, 0x56, + 0x0F, 0xFF, 0x90, 0x56, 0x12, 0xFF, 0x92, 0x62, 0x27, 0xFF, 0xB6, 0x9B, 0x7D, 0xFF, 0xE8, 0xE2, + 0xD5, 0xFF, 0xF3, 0xF0, 0xEF, 0xFF, 0xED, 0xEE, 0xEE, 0xFF, 0xEC, 0xEE, 0xEE, 0xFF, 0xEC, 0xEE, + 0xEE, 0xFF, 0xED, 0xEE, 0xEE, 0xFF, 0xED, 0xEE, 0xEE, 0xFF, 0xEE, 0xEF, 0xEF, 0xFF, 0xEE, 0xEE, + 0xEE, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xED, 0xEE, + 0xEE, 0xFF, 0xED, 0xEE, 0xEE, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEF, 0xF0, 0xF0, 0xFF, 0xF0, 0xF1, + 0xF1, 0xFF, 0xF1, 0xF2, 0xF2, 0xFF, 0xF1, 0xF1, 0xF1, 0xFF, 0xF1, 0xF1, 0xF1, 0xFF, 0xF1, 0xF2, + 0xF2, 0xFF, 0xF1, 0xF1, 0xF1, 0xFF, 0xF0, 0xF2, 0xF2, 0xFF, 0xF0, 0xF1, 0xF2, 0xFF, 0xF1, 0xF1, + 0xF2, 0xFF, 0xF1, 0xF2, 0xF4, 0xFF, 0xEB, 0xED, 0xEE, 0xFF, 0xC3, 0xBF, 0xB8, 0xFF, 0x92, 0x83, + 0x68, 0xFF, 0x7D, 0x68, 0x44, 0xFF, 0x71, 0x5C, 0x38, 0xFF, 0x8C, 0x7D, 0x63, 0xFF, 0xCF, 0xCA, + 0xBF, 0xFF, 0xE5, 0xE4, 0xE2, 0xFF, 0xDD, 0xDB, 0xD7, 0xFF, 0xC1, 0xB7, 0xAC, 0xFF, 0x96, 0x7E, + 0x60, 0xFF, 0x7B, 0x5B, 0x2D, 0xFF, 0x77, 0x51, 0x1B, 0xFF, 0x7D, 0x52, 0x19, 0xFF, 0x87, 0x54, + 0x16, 0xFF, 0x8F, 0x57, 0x15, 0xFF, 0x95, 0x5A, 0x17, 0xFF, 0x99, 0x5C, 0x18, 0xFF, 0x9C, 0x5D, + 0x17, 0xFF, 0x9D, 0x5E, 0x18, 0xFF, 0x9D, 0x5E, 0x18, 0xFF, 0x9E, 0x5E, 0x18, 0xFF, 0x9E, 0x5E, + 0x18, 0xFF, 0x9E, 0x5E, 0x18, 0xFF, 0x9E, 0x5E, 0x18, 0xFF, 0x9E, 0x5E, 0x18, 0xFF, 0x9E, 0x5E, + 0x18, 0xFF, 0x9E, 0x5E, 0x18, 0xFF, 0x9E, 0x5E, 0x18, 0xFF, 0x9E, 0x5E, 0x18, 0xFF, 0x9E, 0x5E, + 0x18, 0xFF, 0x9E, 0x5E, 0x18, 0xFF, 0x9E, 0x5E, 0x17, 0xFF, 0x9E, 0x5E, 0x17, 0xFF, 0x9E, 0x5E, + 0x17, 0xFF, 0x9D, 0x5D, 0x16, 0xFF, 0x9D, 0x5D, 0x15, 0xFF, 0x9C, 0x5C, 0x14, 0xFF, 0x9C, 0x5B, + 0x13, 0xFF, 0x9B, 0x5A, 0x12, 0xFF, 0x9B, 0x59, 0x11, 0xFF, 0x9B, 0x59, 0x11, 0xFF, 0x9B, 0x59, + 0x11, 0xFF, 0x9A, 0x5A, 0x11, 0xFF, 0x9A, 0x59, 0x11, 0xFF, 0x9A, 0x59, 0x11, 0xFF, 0x9A, 0x59, + 0x11, 0xFF, 0x99, 0x58, 0x11, 0xFF, 0x98, 0x57, 0x10, 0xFF, 0x98, 0x57, 0x10, 0xFF, 0x96, 0x55, + 0x10, 0xFF, 0x95, 0x55, 0x10, 0xFF, 0x93, 0x53, 0x0F, 0xFF, 0x92, 0x52, 0x0F, 0xFF, 0x94, 0x55, + 0x15, 0xFF, 0x9C, 0x63, 0x2B, 0xFF, 0xA3, 0x75, 0x47, 0xFF, 0xC2, 0x99, 0x70, 0xFF, 0xD8, 0xB4, + 0x89, 0xBC, 0xB9, 0xA4, 0x8B, 0x41, 0x00, 0x24, 0x4C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC9, 0xAC, + 0x8E, 0x2C, 0xC0, 0x97, 0x73, 0xA9, 0xA4, 0x74, 0x49, 0xF6, 0x96, 0x5C, 0x2B, 0xFE, 0x87, 0x49, + 0x18, 0xFF, 0x81, 0x41, 0x0D, 0xFF, 0x81, 0x40, 0x0A, 0xFF, 0x83, 0x42, 0x0A, 0xFF, 0x86, 0x45, + 0x0A, 0xFF, 0x88, 0x48, 0x0B, 0xFF, 0x8A, 0x4B, 0x0D, 0xFF, 0x8D, 0x4D, 0x0E, 0xFF, 0x8F, 0x4F, + 0x0E, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x93, 0x53, 0x0F, 0xFF, 0x96, 0x55, 0x10, 0xFF, 0x97, 0x56, + 0x10, 0xFF, 0x98, 0x57, 0x10, 0xFF, 0x99, 0x58, 0x11, 0xFF, 0x9A, 0x59, 0x11, 0xFF, 0x99, 0x5A, + 0x13, 0xFF, 0x99, 0x5B, 0x15, 0xFF, 0x92, 0x5C, 0x19, 0xFF, 0x9C, 0x71, 0x38, 0xFF, 0xC1, 0xAE, + 0x94, 0xFF, 0xE9, 0xE7, 0xDE, 0xFF, 0xED, 0xEE, 0xEF, 0xFF, 0xEC, 0xEE, 0xEE, 0xFF, 0xEB, 0xED, + 0xEE, 0xFF, 0xEC, 0xED, 0xEE, 0xFF, 0xEC, 0xEE, 0xED, 0xFF, 0xED, 0xED, 0xED, 0xFF, 0xED, 0xEE, + 0xED, 0xFF, 0xED, 0xED, 0xEE, 0xFF, 0xED, 0xEE, 0xEE, 0xFF, 0xED, 0xEE, 0xED, 0xFF, 0xEC, 0xED, + 0xED, 0xFF, 0xEC, 0xED, 0xED, 0xFF, 0xEC, 0xED, 0xED, 0xFF, 0xED, 0xED, 0xED, 0xFF, 0xEE, 0xEF, + 0xEF, 0xFF, 0xEF, 0xEF, 0xEF, 0xFF, 0xEF, 0xF0, 0xF0, 0xFF, 0xF0, 0xF1, 0xF1, 0xFF, 0xF0, 0xF1, + 0xF1, 0xFF, 0xF0, 0xF1, 0xF1, 0xFF, 0xF0, 0xF1, 0xF1, 0xFF, 0xF0, 0xF0, 0xF2, 0xFF, 0xEF, 0xF0, + 0xF2, 0xFF, 0xF0, 0xF0, 0xF1, 0xFF, 0xEF, 0xF0, 0xF2, 0xFF, 0xEA, 0xEC, 0xED, 0xFF, 0xD0, 0xD0, + 0xCB, 0xFF, 0x99, 0x8F, 0x78, 0xFF, 0x7C, 0x67, 0x45, 0xFF, 0x74, 0x5E, 0x38, 0xFF, 0x8C, 0x78, + 0x5A, 0xFF, 0xC6, 0xBC, 0xAE, 0xFF, 0xE2, 0xE2, 0xDF, 0xFF, 0xE0, 0xE0, 0xDF, 0xFF, 0xCC, 0xC5, + 0xBC, 0xFF, 0xA1, 0x8F, 0x77, 0xFF, 0x7F, 0x62, 0x39, 0xFF, 0x78, 0x53, 0x21, 0xFF, 0x7E, 0x52, + 0x1A, 0xFF, 0x85, 0x53, 0x17, 0xFF, 0x8E, 0x58, 0x18, 0xFF, 0x95, 0x5A, 0x19, 0xFF, 0x99, 0x5D, + 0x18, 0xFF, 0x9D, 0x5F, 0x19, 0xFF, 0x9E, 0x60, 0x1A, 0xFF, 0x9F, 0x60, 0x1A, 0xFF, 0x9F, 0x60, + 0x1A, 0xFF, 0xA0, 0x60, 0x1A, 0xFF, 0x9F, 0x60, 0x1A, 0xFF, 0xA0, 0x60, 0x1A, 0xFF, 0x9F, 0x60, + 0x1A, 0xFF, 0x9F, 0x60, 0x1A, 0xFF, 0x9F, 0x60, 0x1A, 0xFF, 0x9F, 0x60, 0x1A, 0xFF, 0x9F, 0x60, + 0x19, 0xFF, 0x9F, 0x60, 0x19, 0xFF, 0x9F, 0x60, 0x19, 0xFF, 0xA0, 0x60, 0x19, 0xFF, 0x9F, 0x60, + 0x19, 0xFF, 0xA0, 0x60, 0x19, 0xFF, 0x9F, 0x60, 0x18, 0xFF, 0x9F, 0x5F, 0x17, 0xFF, 0x9E, 0x5E, + 0x17, 0xFF, 0x9E, 0x5C, 0x15, 0xFF, 0x9C, 0x5B, 0x13, 0xFF, 0x9C, 0x5A, 0x12, 0xFF, 0x9B, 0x5A, + 0x11, 0xFF, 0x9C, 0x5B, 0x11, 0xFF, 0x9B, 0x5A, 0x11, 0xFF, 0x9B, 0x5A, 0x11, 0xFF, 0x9B, 0x5A, + 0x11, 0xFF, 0x9B, 0x59, 0x11, 0xFF, 0x99, 0x59, 0x10, 0xFF, 0x99, 0x58, 0x10, 0xFF, 0x98, 0x57, + 0x10, 0xFF, 0x97, 0x56, 0x10, 0xFF, 0x95, 0x54, 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x93, 0x52, + 0x0F, 0xFF, 0x98, 0x5A, 0x1B, 0xFF, 0xA2, 0x71, 0x3D, 0xFF, 0xB9, 0x8C, 0x61, 0xFF, 0xD4, 0xAC, + 0x81, 0xD9, 0xA8, 0x92, 0x71, 0x62, 0x03, 0x26, 0x4C, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFD, 0x03, 0xCE, 0xB1, + 0x94, 0x45, 0xB3, 0x83, 0x56, 0xCB, 0xA2, 0x6E, 0x40, 0xFD, 0x93, 0x5A, 0x29, 0xFF, 0x85, 0x46, + 0x14, 0xFF, 0x82, 0x41, 0x0C, 0xFF, 0x83, 0x42, 0x0A, 0xFF, 0x85, 0x44, 0x0A, 0xFF, 0x88, 0x47, + 0x0B, 0xFF, 0x8A, 0x4A, 0x0C, 0xFF, 0x8D, 0x4D, 0x0E, 0xFF, 0x8F, 0x4F, 0x0E, 0xFF, 0x92, 0x51, + 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x96, 0x55, 0x10, 0xFF, 0x98, 0x57, 0x10, 0xFF, 0x99, 0x58, + 0x11, 0xFF, 0x9A, 0x59, 0x11, 0xFF, 0x9C, 0x5B, 0x13, 0xFF, 0x9D, 0x5D, 0x15, 0xFF, 0x9D, 0x5F, + 0x17, 0xFF, 0x9D, 0x5F, 0x19, 0xFF, 0x99, 0x5D, 0x17, 0xFF, 0x97, 0x63, 0x20, 0xFF, 0xA3, 0x7A, + 0x48, 0xFF, 0xCD, 0xBF, 0xAD, 0xFF, 0xE8, 0xE8, 0xE2, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEB, 0xEC, + 0xEC, 0xFF, 0xEA, 0xEB, 0xEB, 0xFF, 0xE9, 0xEB, 0xEB, 0xFF, 0xEA, 0xEB, 0xEB, 0xFF, 0xEB, 0xEC, + 0xEC, 0xFF, 0xEB, 0xEC, 0xEC, 0xFF, 0xEB, 0xEC, 0xEC, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xEC, 0xED, + 0xED, 0xFF, 0xEC, 0xED, 0xED, 0xFF, 0xEB, 0xEC, 0xEC, 0xFF, 0xEB, 0xEC, 0xEC, 0xFF, 0xEB, 0xEC, + 0xEC, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xED, 0xEE, 0xEE, 0xFF, 0xEE, 0xEF, 0xEF, 0xFF, 0xEF, 0xF0, + 0xF0, 0xFF, 0xEF, 0xF0, 0xF0, 0xFF, 0xEF, 0xF0, 0xF0, 0xFF, 0xEF, 0xF0, 0xF0, 0xFF, 0xEE, 0xF0, + 0xF0, 0xFF, 0xEE, 0xEF, 0xF0, 0xFF, 0xEF, 0xF0, 0xF1, 0xFF, 0xF0, 0xF1, 0xF1, 0xFF, 0xED, 0xEF, + 0xEF, 0xFF, 0xDA, 0xDA, 0xD7, 0xFF, 0xA9, 0xA0, 0x90, 0xFF, 0x80, 0x6D, 0x4B, 0xFF, 0x73, 0x60, + 0x39, 0xFF, 0x82, 0x6F, 0x4E, 0xFF, 0xB6, 0xAA, 0x96, 0xFF, 0xDF, 0xE0, 0xDB, 0xFF, 0xE1, 0xE2, + 0xE1, 0xFF, 0xD7, 0xD4, 0xCC, 0xFF, 0xB4, 0xA8, 0x93, 0xFF, 0x89, 0x71, 0x4A, 0xFF, 0x7C, 0x5B, + 0x2A, 0xFF, 0x7E, 0x56, 0x20, 0xFF, 0x84, 0x56, 0x1A, 0xFF, 0x8C, 0x58, 0x19, 0xFF, 0x94, 0x5C, + 0x1A, 0xFF, 0x9B, 0x5F, 0x1B, 0xFF, 0x9E, 0x60, 0x1A, 0xFF, 0x9F, 0x61, 0x1B, 0xFF, 0xA0, 0x61, + 0x1B, 0xFF, 0xA0, 0x61, 0x1B, 0xFF, 0xA1, 0x62, 0x1C, 0xFF, 0xA1, 0x62, 0x1C, 0xFF, 0xA1, 0x62, + 0x1C, 0xFF, 0xA1, 0x62, 0x1B, 0xFF, 0xA1, 0x62, 0x1B, 0xFF, 0xA1, 0x62, 0x1B, 0xFF, 0xA1, 0x62, + 0x1B, 0xFF, 0xA1, 0x62, 0x1B, 0xFF, 0xA1, 0x62, 0x1B, 0xFF, 0xA1, 0x62, 0x1B, 0xFF, 0xA1, 0x62, + 0x1B, 0xFF, 0xA1, 0x62, 0x1B, 0xFF, 0xA1, 0x62, 0x1B, 0xFF, 0xA1, 0x62, 0x1B, 0xFF, 0xA1, 0x62, + 0x1A, 0xFF, 0xA1, 0x61, 0x19, 0xFF, 0xA0, 0x60, 0x18, 0xFF, 0x9F, 0x5E, 0x16, 0xFF, 0x9E, 0x5D, + 0x13, 0xFF, 0x9D, 0x5C, 0x12, 0xFF, 0x9D, 0x5B, 0x11, 0xFF, 0x9D, 0x5B, 0x11, 0xFF, 0x9C, 0x5B, + 0x11, 0xFF, 0x9C, 0x5B, 0x11, 0xFF, 0x9B, 0x5B, 0x11, 0xFF, 0x9B, 0x5A, 0x11, 0xFF, 0x99, 0x58, + 0x10, 0xFF, 0x99, 0x58, 0x10, 0xFF, 0x97, 0x56, 0x0F, 0xFF, 0x96, 0x55, 0x0F, 0xFF, 0x94, 0x54, + 0x0F, 0xFF, 0x94, 0x55, 0x13, 0xFF, 0x9F, 0x67, 0x2D, 0xFF, 0xB3, 0x85, 0x56, 0xFF, 0xC5, 0x9F, + 0x75, 0xEC, 0xC5, 0xA7, 0x87, 0x7F, 0xC6, 0xB3, 0xA0, 0x1B, 0xA8, 0xA0, 0x96, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0xFF, 0x0B, 0xD7, 0xB8, + 0x9D, 0x5D, 0xAB, 0x7C, 0x4C, 0xE4, 0x9D, 0x69, 0x39, 0xFF, 0x92, 0x56, 0x25, 0xFF, 0x84, 0x44, + 0x10, 0xFF, 0x84, 0x43, 0x0C, 0xFF, 0x85, 0x43, 0x0A, 0xFF, 0x88, 0x47, 0x0B, 0xFF, 0x8A, 0x49, + 0x0C, 0xFF, 0x8D, 0x4C, 0x0C, 0xFF, 0x8F, 0x4F, 0x0E, 0xFF, 0x92, 0x51, 0x0E, 0xFF, 0x93, 0x53, + 0x0F, 0xFF, 0x96, 0x55, 0x0F, 0xFF, 0x98, 0x57, 0x10, 0xFF, 0x9A, 0x59, 0x11, 0xFF, 0x9B, 0x5A, + 0x12, 0xFF, 0x9D, 0x5C, 0x14, 0xFF, 0x9E, 0x5F, 0x17, 0xFF, 0xA0, 0x61, 0x19, 0xFF, 0xA2, 0x63, + 0x1B, 0xFF, 0xA2, 0x64, 0x1C, 0xFF, 0x9F, 0x62, 0x1B, 0xFF, 0x9C, 0x61, 0x1D, 0xFF, 0x9A, 0x66, + 0x27, 0xFF, 0xAC, 0x89, 0x5C, 0xFF, 0xD3, 0xCB, 0xBC, 0xFF, 0xE8, 0xE8, 0xE5, 0xFF, 0xE9, 0xEA, + 0xEB, 0xFF, 0xE8, 0xEA, 0xEA, 0xFF, 0xE8, 0xE9, 0xE9, 0xFF, 0xE8, 0xE9, 0xE9, 0xFF, 0xE9, 0xEA, + 0xEA, 0xFF, 0xE9, 0xEA, 0xEA, 0xFF, 0xE9, 0xEA, 0xEA, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xEA, 0xEB, + 0xEB, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xEA, 0xEB, 0xEB, 0xFF, 0xEA, 0xEB, 0xEA, 0xFF, 0xEA, 0xEB, + 0xEA, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xEA, 0xEB, 0xEB, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xED, 0xEE, + 0xEE, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEE, 0xEF, 0xEF, 0xFF, 0xEE, 0xEF, 0xEF, 0xFF, 0xEE, 0xEF, + 0xEF, 0xFF, 0xEE, 0xEE, 0xEF, 0xFF, 0xEE, 0xEF, 0xEF, 0xFF, 0xED, 0xEE, 0xEF, 0xFF, 0xEE, 0xEE, + 0xEF, 0xFF, 0xED, 0xEE, 0xEF, 0xFF, 0xE6, 0xE6, 0xE5, 0xFF, 0xBA, 0xB4, 0xA7, 0xFF, 0x81, 0x70, + 0x4E, 0xFF, 0x73, 0x5E, 0x36, 0xFF, 0x84, 0x70, 0x4B, 0xFF, 0xAA, 0x9C, 0x84, 0xFF, 0xD9, 0xD7, + 0xD0, 0xFF, 0xE5, 0xE6, 0xE5, 0xFF, 0xDF, 0xDB, 0xD8, 0xFF, 0xBF, 0xB6, 0xA7, 0xFF, 0x91, 0x7B, + 0x5A, 0xFF, 0x7F, 0x5F, 0x31, 0xFF, 0x7E, 0x56, 0x21, 0xFF, 0x83, 0x55, 0x1C, 0xFF, 0x8C, 0x58, + 0x1A, 0xFF, 0x95, 0x5C, 0x1C, 0xFF, 0x9A, 0x60, 0x1B, 0xFF, 0x9F, 0x62, 0x1B, 0xFF, 0xA0, 0x63, + 0x1C, 0xFF, 0xA1, 0x63, 0x1C, 0xFF, 0xA2, 0x64, 0x1D, 0xFF, 0xA3, 0x64, 0x1D, 0xFF, 0xA2, 0x64, + 0x1C, 0xFF, 0xA3, 0x63, 0x1C, 0xFF, 0xA2, 0x64, 0x1C, 0xFF, 0xA2, 0x64, 0x1B, 0xFF, 0xA2, 0x64, + 0x1C, 0xFF, 0xA3, 0x64, 0x1C, 0xFF, 0xA2, 0x64, 0x1C, 0xFF, 0xA3, 0x64, 0x1D, 0xFF, 0xA2, 0x63, + 0x1C, 0xFF, 0xA2, 0x63, 0x1D, 0xFF, 0xA2, 0x64, 0x1C, 0xFF, 0xA3, 0x64, 0x1C, 0xFF, 0xA2, 0x64, + 0x1C, 0xFF, 0xA3, 0x64, 0x1C, 0xFF, 0xA2, 0x63, 0x1B, 0xFF, 0xA2, 0x62, 0x1A, 0xFF, 0xA1, 0x61, + 0x18, 0xFF, 0xA0, 0x5E, 0x15, 0xFF, 0x9E, 0x5D, 0x12, 0xFF, 0x9E, 0x5C, 0x12, 0xFF, 0x9D, 0x5C, + 0x11, 0xFF, 0x9D, 0x5C, 0x11, 0xFF, 0x9C, 0x5C, 0x11, 0xFF, 0x9C, 0x5B, 0x11, 0xFF, 0x9B, 0x5A, + 0x10, 0xFF, 0x9A, 0x59, 0x10, 0xFF, 0x99, 0x58, 0x0F, 0xFF, 0x98, 0x57, 0x0F, 0xFF, 0x96, 0x56, + 0x10, 0xFF, 0x95, 0x56, 0x12, 0xFF, 0x9B, 0x5E, 0x1E, 0xFF, 0xAC, 0x7B, 0x49, 0xFF, 0xB8, 0x90, + 0x65, 0xF6, 0xC9, 0xAC, 0x8B, 0x9F, 0xDB, 0xC3, 0xA7, 0x29, 0xDB, 0xC2, 0xA9, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEE, 0xE0, 0xD4, 0x15, 0xCC, 0xAC, + 0x8D, 0x7C, 0xAD, 0x7D, 0x4D, 0xED, 0x9C, 0x66, 0x34, 0xFF, 0x8F, 0x51, 0x1C, 0xFF, 0x85, 0x44, + 0x0F, 0xFF, 0x86, 0x44, 0x0C, 0xFF, 0x88, 0x46, 0x0B, 0xFF, 0x8A, 0x49, 0x0B, 0xFF, 0x8C, 0x4C, + 0x0D, 0xFF, 0x8F, 0x4E, 0x0D, 0xFF, 0x91, 0x50, 0x0E, 0xFF, 0x94, 0x52, 0x0E, 0xFF, 0x96, 0x54, + 0x0F, 0xFF, 0x98, 0x56, 0x10, 0xFF, 0x9A, 0x59, 0x12, 0xFF, 0x9C, 0x5C, 0x15, 0xFF, 0x9F, 0x60, + 0x18, 0xFF, 0xA1, 0x62, 0x1A, 0xFF, 0xA2, 0x64, 0x1C, 0xFF, 0xA3, 0x65, 0x1D, 0xFF, 0xA4, 0x65, + 0x1E, 0xFF, 0xA3, 0x65, 0x1E, 0xFF, 0xA2, 0x65, 0x1E, 0xFF, 0x9F, 0x63, 0x1E, 0xFF, 0x9B, 0x62, + 0x1E, 0xFF, 0x9B, 0x69, 0x2A, 0xFF, 0xB5, 0x95, 0x6E, 0xFF, 0xD9, 0xD3, 0xCA, 0xFF, 0xE8, 0xE8, + 0xE6, 0xFF, 0xE8, 0xE9, 0xE9, 0xFF, 0xE7, 0xE9, 0xE9, 0xFF, 0xE6, 0xE8, 0xE8, 0xFF, 0xE6, 0xE7, + 0xE7, 0xFF, 0xE6, 0xE7, 0xE7, 0xFF, 0xE7, 0xE8, 0xE8, 0xFF, 0xE7, 0xE8, 0xE8, 0xFF, 0xE7, 0xE8, + 0xE8, 0xFF, 0xE8, 0xE9, 0xE9, 0xFF, 0xE8, 0xE9, 0xE9, 0xFF, 0xE9, 0xE9, 0xE9, 0xFF, 0xE8, 0xE9, + 0xE9, 0xFF, 0xE8, 0xE9, 0xE9, 0xFF, 0xE8, 0xE9, 0xE9, 0xFF, 0xE9, 0xE9, 0xE9, 0xFF, 0xE9, 0xEA, + 0xE9, 0xFF, 0xEA, 0xEB, 0xEB, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xED, 0xED, 0xED, 0xFF, 0xEC, 0xED, + 0xEE, 0xFF, 0xED, 0xEE, 0xEE, 0xFF, 0xEC, 0xEE, 0xEE, 0xFF, 0xEC, 0xED, 0xED, 0xFF, 0xEC, 0xED, + 0xED, 0xFF, 0xEB, 0xEC, 0xEC, 0xFF, 0xEA, 0xEC, 0xEC, 0xFF, 0xE8, 0xE9, 0xE9, 0xFF, 0xC8, 0xC5, + 0xBC, 0xFF, 0x89, 0x7B, 0x5F, 0xFF, 0x73, 0x61, 0x3B, 0xFF, 0x7D, 0x68, 0x43, 0xFF, 0x9B, 0x8A, + 0x6F, 0xFF, 0xD2, 0xCF, 0xC1, 0xFF, 0xE5, 0xE4, 0xE4, 0xFF, 0xE2, 0xE0, 0xDE, 0xFF, 0xCF, 0xCB, + 0xC0, 0xFF, 0xA2, 0x92, 0x7A, 0xFF, 0x87, 0x69, 0x3E, 0xFF, 0x7F, 0x5A, 0x26, 0xFF, 0x81, 0x57, + 0x1E, 0xFF, 0x89, 0x59, 0x1D, 0xFF, 0x93, 0x5E, 0x1D, 0xFF, 0x9B, 0x61, 0x1D, 0xFF, 0x9F, 0x63, + 0x1D, 0xFF, 0xA1, 0x64, 0x1D, 0xFF, 0xA2, 0x65, 0x1D, 0xFF, 0xA4, 0x65, 0x1E, 0xFF, 0xA4, 0x65, + 0x1E, 0xFF, 0xA4, 0x65, 0x1D, 0xFF, 0xA4, 0x65, 0x1D, 0xFF, 0xA4, 0x65, 0x1D, 0xFF, 0xA4, 0x65, + 0x1D, 0xFF, 0xA4, 0x65, 0x1D, 0xFF, 0xA4, 0x65, 0x1D, 0xFF, 0xA4, 0x65, 0x1E, 0xFF, 0xA4, 0x65, + 0x1E, 0xFF, 0xA4, 0x65, 0x1E, 0xFF, 0xA4, 0x65, 0x1E, 0xFF, 0xA4, 0x65, 0x1E, 0xFF, 0xA4, 0x65, + 0x1E, 0xFF, 0xA4, 0x65, 0x1E, 0xFF, 0xA4, 0x65, 0x1E, 0xFF, 0xA4, 0x65, 0x1E, 0xFF, 0xA4, 0x65, + 0x1D, 0xFF, 0xA3, 0x64, 0x1B, 0xFF, 0xA2, 0x62, 0x17, 0xFF, 0xA0, 0x60, 0x15, 0xFF, 0x9F, 0x5E, + 0x13, 0xFF, 0x9F, 0x5D, 0x13, 0xFF, 0x9E, 0x5D, 0x12, 0xFF, 0x9E, 0x5C, 0x12, 0xFF, 0x9D, 0x5C, + 0x11, 0xFF, 0x9C, 0x5B, 0x10, 0xFF, 0x9B, 0x5A, 0x11, 0xFF, 0x9A, 0x58, 0x11, 0xFF, 0x97, 0x56, + 0x0F, 0xFF, 0x96, 0x56, 0x11, 0xFF, 0x9A, 0x5C, 0x1B, 0xFF, 0xA9, 0x71, 0x3A, 0xFF, 0xB6, 0x87, + 0x58, 0xFB, 0xCC, 0xB0, 0x8B, 0xBB, 0xE0, 0xC6, 0xAC, 0x3A, 0xDF, 0xCA, 0xB2, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xC9, 0xAF, 0x25, 0xC8, 0xA6, + 0x81, 0x97, 0xAA, 0x78, 0x45, 0xF4, 0x9B, 0x61, 0x2F, 0xFF, 0x8C, 0x4D, 0x18, 0xFF, 0x87, 0x45, + 0x0F, 0xFF, 0x88, 0x45, 0x0C, 0xFF, 0x8A, 0x47, 0x0B, 0xFF, 0x8C, 0x4B, 0x0C, 0xFF, 0x8E, 0x4E, + 0x0D, 0xFF, 0x91, 0x50, 0x0E, 0xFF, 0x93, 0x52, 0x0E, 0xFF, 0x96, 0x54, 0x0F, 0xFF, 0x98, 0x56, + 0x10, 0xFF, 0x9A, 0x59, 0x12, 0xFF, 0x9D, 0x5D, 0x16, 0xFF, 0xA0, 0x61, 0x1A, 0xFF, 0xA2, 0x64, + 0x1D, 0xFF, 0xA4, 0x66, 0x1F, 0xFF, 0xA4, 0x67, 0x1F, 0xFF, 0xA5, 0x67, 0x20, 0xFF, 0xA5, 0x67, + 0x20, 0xFF, 0xA5, 0x67, 0x20, 0xFF, 0xA5, 0x66, 0x1F, 0xFF, 0xA3, 0x66, 0x1F, 0xFF, 0x9F, 0x65, + 0x1D, 0xFF, 0x9B, 0x62, 0x1F, 0xFF, 0xA1, 0x72, 0x33, 0xFF, 0xBC, 0xA4, 0x86, 0xFF, 0xE0, 0xDC, + 0xD6, 0xFF, 0xE7, 0xE7, 0xE7, 0xFF, 0xE7, 0xE7, 0xE7, 0xFF, 0xE5, 0xE7, 0xE7, 0xFF, 0xE4, 0xE5, + 0xE5, 0xFF, 0xE4, 0xE5, 0xE5, 0xFF, 0xE5, 0xE6, 0xE6, 0xFF, 0xE5, 0xE6, 0xE6, 0xFF, 0xE5, 0xE6, + 0xE5, 0xFF, 0xE5, 0xE6, 0xE6, 0xFF, 0xE6, 0xE7, 0xE7, 0xFF, 0xE7, 0xE7, 0xE7, 0xFF, 0xE7, 0xE7, + 0xE7, 0xFF, 0xE7, 0xE7, 0xE7, 0xFF, 0xE7, 0xE8, 0xE7, 0xFF, 0xE6, 0xE7, 0xE7, 0xFF, 0xE6, 0xE7, + 0xE6, 0xFF, 0xE7, 0xE7, 0xE7, 0xFF, 0xE8, 0xE9, 0xE9, 0xFF, 0xE9, 0xEA, 0xEA, 0xFF, 0xEA, 0xEB, + 0xEB, 0xFF, 0xEB, 0xEC, 0xEC, 0xFF, 0xEB, 0xEC, 0xEC, 0xFF, 0xEB, 0xEC, 0xEC, 0xFF, 0xEB, 0xEC, + 0xEC, 0xFF, 0xEA, 0xEB, 0xEC, 0xFF, 0xEA, 0xEB, 0xEC, 0xFF, 0xEB, 0xEB, 0xED, 0xFF, 0xEB, 0xEA, + 0xEC, 0xFF, 0xD6, 0xD3, 0xCE, 0xFF, 0x93, 0x87, 0x6C, 0xFF, 0x7A, 0x66, 0x3F, 0xFF, 0x82, 0x6D, + 0x45, 0xFF, 0x92, 0x7F, 0x5E, 0xFF, 0xC7, 0xC0, 0xB0, 0xFF, 0xE6, 0xE3, 0xE2, 0xFF, 0xE4, 0xE0, + 0xE1, 0xFF, 0xD7, 0xD3, 0xCC, 0xFF, 0xB0, 0xA4, 0x90, 0xFF, 0x8E, 0x74, 0x4E, 0xFF, 0x80, 0x5D, + 0x2D, 0xFF, 0x7F, 0x57, 0x20, 0xFF, 0x87, 0x5A, 0x1E, 0xFF, 0x91, 0x5D, 0x1E, 0xFF, 0x98, 0x61, + 0x1E, 0xFF, 0x9E, 0x63, 0x1E, 0xFF, 0xA1, 0x66, 0x1E, 0xFF, 0xA4, 0x66, 0x1E, 0xFF, 0xA5, 0x67, + 0x1F, 0xFF, 0xA6, 0x66, 0x1F, 0xFF, 0xA5, 0x66, 0x1F, 0xFF, 0xA6, 0x66, 0x1F, 0xFF, 0xA5, 0x67, + 0x1F, 0xFF, 0xA6, 0x67, 0x1F, 0xFF, 0xA5, 0x67, 0x1F, 0xFF, 0xA5, 0x67, 0x1F, 0xFF, 0xA5, 0x67, + 0x1F, 0xFF, 0xA6, 0x67, 0x1F, 0xFF, 0xA5, 0x67, 0x1F, 0xFF, 0xA5, 0x67, 0x1F, 0xFF, 0xA5, 0x67, + 0x1F, 0xFF, 0xA6, 0x67, 0x20, 0xFF, 0xA5, 0x67, 0x1F, 0xFF, 0xA5, 0x67, 0x20, 0xFF, 0xA5, 0x67, + 0x20, 0xFF, 0xA6, 0x67, 0x1F, 0xFF, 0xA5, 0x66, 0x1D, 0xFF, 0xA4, 0x64, 0x1A, 0xFF, 0xA2, 0x62, + 0x17, 0xFF, 0xA1, 0x5F, 0x14, 0xFF, 0x9F, 0x5E, 0x13, 0xFF, 0xA0, 0x5D, 0x12, 0xFF, 0x9E, 0x5D, + 0x11, 0xFF, 0x9E, 0x5C, 0x11, 0xFF, 0x9C, 0x5B, 0x11, 0xFF, 0x9B, 0x59, 0x11, 0xFF, 0x99, 0x57, + 0x0F, 0xFF, 0x97, 0x56, 0x0F, 0xFF, 0x98, 0x5A, 0x17, 0xFF, 0xA7, 0x6C, 0x31, 0xFF, 0xB4, 0x80, + 0x4D, 0xFD, 0xC8, 0xAA, 0x85, 0xCC, 0xDD, 0xC8, 0xB0, 0x50, 0xE0, 0xCA, 0xB4, 0x0A, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xC9, 0xB0, 0x03, 0xDB, 0xC1, 0xA5, 0x2F, 0xC0, 0x9E, + 0x7A, 0xB0, 0xAA, 0x75, 0x40, 0xF8, 0x9A, 0x5F, 0x2C, 0xFF, 0x8D, 0x4D, 0x17, 0xFF, 0x88, 0x46, + 0x0D, 0xFF, 0x8A, 0x47, 0x0B, 0xFF, 0x8C, 0x49, 0x0C, 0xFF, 0x8E, 0x4D, 0x0D, 0xFF, 0x90, 0x4F, + 0x0E, 0xFF, 0x92, 0x51, 0x0E, 0xFF, 0x96, 0x54, 0x0F, 0xFF, 0x99, 0x57, 0x11, 0xFF, 0x9B, 0x5A, + 0x14, 0xFF, 0x9F, 0x5F, 0x19, 0xFF, 0xA2, 0x64, 0x1D, 0xFF, 0xA4, 0x66, 0x1F, 0xFF, 0xA5, 0x68, + 0x21, 0xFF, 0xA6, 0x68, 0x21, 0xFF, 0xA7, 0x69, 0x22, 0xFF, 0xA7, 0x69, 0x22, 0xFF, 0xA7, 0x69, + 0x22, 0xFF, 0xA7, 0x69, 0x21, 0xFF, 0xA7, 0x69, 0x21, 0xFF, 0xA6, 0x68, 0x21, 0xFF, 0xA3, 0x67, + 0x20, 0xFF, 0xA0, 0x66, 0x20, 0xFF, 0x9A, 0x64, 0x22, 0xFF, 0xA2, 0x7A, 0x41, 0xFF, 0xC3, 0xB1, + 0x9A, 0xFF, 0xDE, 0xDD, 0xD9, 0xFF, 0xE6, 0xE5, 0xE4, 0xFF, 0xE4, 0xE5, 0xE6, 0xFF, 0xE3, 0xE5, + 0xE4, 0xFF, 0xE2, 0xE4, 0xE4, 0xFF, 0xE2, 0xE3, 0xE3, 0xFF, 0xE2, 0xE3, 0xE3, 0xFF, 0xE2, 0xE3, + 0xE3, 0xFF, 0xE2, 0xE3, 0xE3, 0xFF, 0xE2, 0xE3, 0xE3, 0xFF, 0xE3, 0xE4, 0xE4, 0xFF, 0xE3, 0xE4, + 0xE4, 0xFF, 0xE4, 0xE5, 0xE5, 0xFF, 0xE4, 0xE5, 0xE5, 0xFF, 0xE4, 0xE4, 0xE4, 0xFF, 0xE4, 0xE4, + 0xE4, 0xFF, 0xE4, 0xE4, 0xE4, 0xFF, 0xE4, 0xE5, 0xE5, 0xFF, 0xE5, 0xE6, 0xE6, 0xFF, 0xE6, 0xE7, + 0xE7, 0xFF, 0xE7, 0xE9, 0xE9, 0xFF, 0xE8, 0xEA, 0xEA, 0xFF, 0xE9, 0xEA, 0xEA, 0xFF, 0xE9, 0xEA, + 0xEB, 0xFF, 0xE9, 0xEA, 0xEA, 0xFF, 0xE9, 0xEA, 0xEB, 0xFF, 0xE8, 0xE9, 0xEA, 0xFF, 0xE8, 0xE9, + 0xE9, 0xFF, 0xEA, 0xE9, 0xEB, 0xFF, 0xDF, 0xDE, 0xD9, 0xFF, 0xA3, 0x99, 0x86, 0xFF, 0x7C, 0x6A, + 0x48, 0xFF, 0x7E, 0x6A, 0x43, 0xFF, 0x85, 0x71, 0x4E, 0xFF, 0xBC, 0xB1, 0x9D, 0xFF, 0xE1, 0xDE, + 0xDA, 0xFF, 0xE7, 0xE4, 0xE3, 0xFF, 0xDA, 0xD8, 0xD4, 0xFF, 0xC2, 0xBA, 0xAE, 0xFF, 0x9B, 0x84, + 0x64, 0xFF, 0x82, 0x63, 0x33, 0xFF, 0x7F, 0x5A, 0x23, 0xFF, 0x85, 0x5C, 0x21, 0xFF, 0x90, 0x5E, + 0x1F, 0xFF, 0x98, 0x61, 0x1E, 0xFF, 0x9E, 0x65, 0x1F, 0xFF, 0xA2, 0x67, 0x20, 0xFF, 0xA5, 0x68, + 0x20, 0xFF, 0xA7, 0x68, 0x21, 0xFF, 0xA7, 0x69, 0x21, 0xFF, 0xA7, 0x69, 0x21, 0xFF, 0xA7, 0x69, + 0x21, 0xFF, 0xA7, 0x69, 0x21, 0xFF, 0xA7, 0x69, 0x21, 0xFF, 0xA7, 0x69, 0x21, 0xFF, 0xA7, 0x69, + 0x21, 0xFF, 0xA7, 0x69, 0x21, 0xFF, 0xA7, 0x69, 0x21, 0xFF, 0xA7, 0x69, 0x21, 0xFF, 0xA7, 0x69, + 0x21, 0xFF, 0xA7, 0x69, 0x21, 0xFF, 0xA7, 0x69, 0x21, 0xFF, 0xA7, 0x69, 0x22, 0xFF, 0xA7, 0x69, + 0x21, 0xFF, 0xA7, 0x69, 0x21, 0xFF, 0xA7, 0x69, 0x21, 0xFF, 0xA7, 0x68, 0x20, 0xFF, 0xA6, 0x68, + 0x1E, 0xFF, 0xA4, 0x65, 0x1A, 0xFF, 0xA2, 0x62, 0x16, 0xFF, 0xA1, 0x5F, 0x13, 0xFF, 0x9F, 0x5E, + 0x12, 0xFF, 0x9F, 0x5C, 0x11, 0xFF, 0x9E, 0x5B, 0x11, 0xFF, 0x9D, 0x5B, 0x11, 0xFF, 0x9B, 0x59, + 0x10, 0xFF, 0x99, 0x58, 0x10, 0xFF, 0x98, 0x59, 0x15, 0xFF, 0xA7, 0x6B, 0x2E, 0xFF, 0xB2, 0x7B, + 0x46, 0xFF, 0xC5, 0xA4, 0x7B, 0xD9, 0xDC, 0xC5, 0xAB, 0x69, 0xDF, 0xC9, 0xB0, 0x11, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD9, 0xC3, 0xA8, 0x04, 0xD7, 0xBD, 0xA2, 0x3D, 0xBC, 0x9A, + 0x74, 0xC4, 0xA8, 0x71, 0x3A, 0xFD, 0x98, 0x5C, 0x28, 0xFF, 0x8D, 0x4C, 0x15, 0xFF, 0x8A, 0x48, + 0x0D, 0xFF, 0x8B, 0x48, 0x0B, 0xFF, 0x8D, 0x4B, 0x0C, 0xFF, 0x90, 0x4E, 0x0D, 0xFF, 0x92, 0x51, + 0x0E, 0xFF, 0x95, 0x53, 0x0F, 0xFF, 0x99, 0x57, 0x12, 0xFF, 0x9C, 0x5B, 0x15, 0xFF, 0xA0, 0x61, + 0x1B, 0xFF, 0xA3, 0x65, 0x1F, 0xFF, 0xA5, 0x68, 0x21, 0xFF, 0xA7, 0x69, 0x22, 0xFF, 0xA7, 0x6A, + 0x22, 0xFF, 0xA8, 0x6A, 0x23, 0xFF, 0xA8, 0x6B, 0x23, 0xFF, 0xA9, 0x6B, 0x23, 0xFF, 0xA9, 0x6B, + 0x23, 0xFF, 0xA9, 0x6B, 0x23, 0xFF, 0xA9, 0x6B, 0x23, 0xFF, 0xA8, 0x6B, 0x22, 0xFF, 0xA7, 0x6A, + 0x22, 0xFF, 0xA5, 0x69, 0x21, 0xFF, 0x9F, 0x67, 0x20, 0xFF, 0x9C, 0x69, 0x25, 0xFF, 0xAA, 0x83, + 0x4D, 0xFF, 0xC9, 0xBC, 0xAD, 0xFF, 0xE1, 0xE0, 0xDE, 0xFF, 0xE3, 0xE4, 0xE5, 0xFF, 0xE2, 0xE3, + 0xE3, 0xFF, 0xE1, 0xE3, 0xE3, 0xFF, 0xE0, 0xE1, 0xE1, 0xFF, 0xE0, 0xE1, 0xE1, 0xFF, 0xE0, 0xE1, + 0xE1, 0xFF, 0xE0, 0xE1, 0xE1, 0xFF, 0xE0, 0xE1, 0xE1, 0xFF, 0xE0, 0xE1, 0xE1, 0xFF, 0xE1, 0xE2, + 0xE2, 0xFF, 0xE1, 0xE2, 0xE2, 0xFF, 0xE1, 0xE2, 0xE2, 0xFF, 0xE1, 0xE2, 0xE2, 0xFF, 0xE1, 0xE2, + 0xE2, 0xFF, 0xE1, 0xE1, 0xE2, 0xFF, 0xE0, 0xE1, 0xE1, 0xFF, 0xE1, 0xE3, 0xE2, 0xFF, 0xE2, 0xE4, + 0xE4, 0xFF, 0xE4, 0xE5, 0xE5, 0xFF, 0xE6, 0xE8, 0xE7, 0xFF, 0xE6, 0xE8, 0xE8, 0xFF, 0xE7, 0xE8, + 0xE8, 0xFF, 0xE7, 0xE8, 0xE9, 0xFF, 0xE8, 0xE9, 0xE9, 0xFF, 0xE8, 0xE8, 0xEA, 0xFF, 0xE8, 0xE8, + 0xE8, 0xFF, 0xE8, 0xE7, 0xE8, 0xFF, 0xEB, 0xE8, 0xEB, 0xFF, 0xE2, 0xE0, 0xDE, 0xFF, 0xB1, 0xA9, + 0x96, 0xFF, 0x83, 0x72, 0x50, 0xFF, 0x7F, 0x69, 0x42, 0xFF, 0x83, 0x6E, 0x48, 0xFF, 0xB0, 0xA5, + 0x8F, 0xFF, 0xDD, 0xD9, 0xD5, 0xFF, 0xE2, 0xE1, 0xE1, 0xFF, 0xDC, 0xDB, 0xD9, 0xFF, 0xCC, 0xC5, + 0xBB, 0xFF, 0xA4, 0x92, 0x76, 0xFF, 0x85, 0x69, 0x3D, 0xFF, 0x7E, 0x5C, 0x27, 0xFF, 0x86, 0x5C, + 0x22, 0xFF, 0x8E, 0x5D, 0x1F, 0xFF, 0x97, 0x62, 0x21, 0xFF, 0x9E, 0x65, 0x22, 0xFF, 0xA4, 0x69, + 0x21, 0xFF, 0xA7, 0x6A, 0x22, 0xFF, 0xA8, 0x6B, 0x22, 0xFF, 0xA9, 0x6B, 0x23, 0xFF, 0xA8, 0x6B, + 0x23, 0xFF, 0xA9, 0x6B, 0x23, 0xFF, 0xA8, 0x6B, 0x23, 0xFF, 0xA8, 0x6B, 0x23, 0xFF, 0xA8, 0x6B, + 0x22, 0xFF, 0xA9, 0x6B, 0x22, 0xFF, 0xA8, 0x6B, 0x23, 0xFF, 0xA9, 0x6B, 0x23, 0xFF, 0xA8, 0x6B, + 0x22, 0xFF, 0xA9, 0x6B, 0x23, 0xFF, 0xA9, 0x6B, 0x23, 0xFF, 0xA9, 0x6B, 0x23, 0xFF, 0xA8, 0x6B, + 0x23, 0xFF, 0xA8, 0x6B, 0x23, 0xFF, 0xA8, 0x6B, 0x23, 0xFF, 0xA9, 0x6B, 0x23, 0xFF, 0xA9, 0x6B, + 0x22, 0xFF, 0xA8, 0x6A, 0x21, 0xFF, 0xA7, 0x67, 0x1C, 0xFF, 0xA4, 0x63, 0x17, 0xFF, 0xA1, 0x60, + 0x14, 0xFF, 0xA0, 0x5E, 0x12, 0xFF, 0x9F, 0x5C, 0x11, 0xFF, 0x9E, 0x5C, 0x11, 0xFF, 0x9C, 0x5A, + 0x10, 0xFF, 0x9B, 0x5A, 0x10, 0xFF, 0x9C, 0x5D, 0x15, 0xFF, 0xA3, 0x66, 0x28, 0xFF, 0xB2, 0x7A, + 0x42, 0xFF, 0xC4, 0x9F, 0x76, 0xE4, 0xDA, 0xC0, 0xA4, 0x82, 0xDD, 0xC4, 0xAA, 0x17, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD7, 0xBE, 0xA3, 0x06, 0xD5, 0xBA, 0x9D, 0x4F, 0xBC, 0x98, + 0x70, 0xD8, 0xA7, 0x6E, 0x38, 0xFD, 0x96, 0x58, 0x23, 0xFF, 0x8E, 0x4D, 0x14, 0xFF, 0x8C, 0x49, + 0x0E, 0xFF, 0x8D, 0x49, 0x0B, 0xFF, 0x90, 0x4D, 0x0D, 0xFF, 0x92, 0x51, 0x0E, 0xFF, 0x94, 0x53, + 0x0F, 0xFF, 0x99, 0x58, 0x13, 0xFF, 0x9D, 0x5D, 0x18, 0xFF, 0xA1, 0x62, 0x1D, 0xFF, 0xA4, 0x67, + 0x21, 0xFF, 0xA6, 0x69, 0x23, 0xFF, 0xA8, 0x6A, 0x24, 0xFF, 0xA9, 0x6C, 0x24, 0xFF, 0xAA, 0x6D, + 0x25, 0xFF, 0xAA, 0x6D, 0x25, 0xFF, 0xAA, 0x6D, 0x25, 0xFF, 0xAA, 0x6D, 0x25, 0xFF, 0xAB, 0x6D, + 0x25, 0xFF, 0xAB, 0x6D, 0x25, 0xFF, 0xAB, 0x6D, 0x24, 0xFF, 0xAA, 0x6D, 0x24, 0xFF, 0xAA, 0x6D, + 0x24, 0xFF, 0xA9, 0x6D, 0x24, 0xFF, 0xA6, 0x6B, 0x23, 0xFF, 0xA0, 0x68, 0x22, 0xFF, 0x9C, 0x6C, + 0x2A, 0xFF, 0xAD, 0x8E, 0x63, 0xFF, 0xD0, 0xC7, 0xBB, 0xFF, 0xE1, 0xE0, 0xDC, 0xFF, 0xE0, 0xE0, + 0xE0, 0xFF, 0xDF, 0xE1, 0xE0, 0xFF, 0xDE, 0xE0, 0xE0, 0xFF, 0xDE, 0xDF, 0xDF, 0xFF, 0xDE, 0xDF, + 0xDF, 0xFF, 0xDE, 0xDF, 0xDF, 0xFF, 0xDE, 0xDF, 0xDF, 0xFF, 0xDE, 0xDF, 0xDF, 0xFF, 0xDE, 0xDF, + 0xDF, 0xFF, 0xDE, 0xDF, 0xDF, 0xFF, 0xDE, 0xDF, 0xDF, 0xFF, 0xDE, 0xDF, 0xE0, 0xFF, 0xDE, 0xDF, + 0xE0, 0xFF, 0xDE, 0xDF, 0xDF, 0xFF, 0xDE, 0xDF, 0xDF, 0xFF, 0xDF, 0xE0, 0xE0, 0xFF, 0xE0, 0xE1, + 0xE1, 0xFF, 0xE1, 0xE2, 0xE1, 0xFF, 0xE2, 0xE3, 0xE2, 0xFF, 0xE4, 0xE6, 0xE5, 0xFF, 0xE3, 0xE6, + 0xE6, 0xFF, 0xE4, 0xE6, 0xE6, 0xFF, 0xE6, 0xE7, 0xE7, 0xFF, 0xE6, 0xE7, 0xE7, 0xFF, 0xE6, 0xE7, + 0xE7, 0xFF, 0xE6, 0xE7, 0xE7, 0xFF, 0xE6, 0xE6, 0xE7, 0xFF, 0xE8, 0xE7, 0xEA, 0xFF, 0xE4, 0xE4, + 0xE4, 0xFF, 0xBF, 0xB9, 0xAE, 0xFF, 0x8F, 0x7D, 0x5C, 0xFF, 0x82, 0x6B, 0x42, 0xFF, 0x7D, 0x68, + 0x41, 0xFF, 0xA1, 0x94, 0x7A, 0xFF, 0xD7, 0xD3, 0xCB, 0xFF, 0xE2, 0xE1, 0xE1, 0xFF, 0xDD, 0xDD, + 0xDC, 0xFF, 0xD3, 0xCF, 0xC9, 0xFF, 0xB5, 0xA7, 0x91, 0xFF, 0x8E, 0x76, 0x4F, 0xFF, 0x81, 0x62, + 0x2F, 0xFF, 0x85, 0x5F, 0x27, 0xFF, 0x8E, 0x60, 0x23, 0xFF, 0x96, 0x63, 0x22, 0xFF, 0x9F, 0x68, + 0x23, 0xFF, 0xA5, 0x6C, 0x24, 0xFF, 0xA8, 0x6C, 0x24, 0xFF, 0xA9, 0x6C, 0x24, 0xFF, 0xAA, 0x6D, + 0x24, 0xFF, 0xAA, 0x6D, 0x25, 0xFF, 0xAA, 0x6D, 0x25, 0xFF, 0xAA, 0x6D, 0x24, 0xFF, 0xAA, 0x6D, + 0x24, 0xFF, 0xAA, 0x6D, 0x24, 0xFF, 0xAA, 0x6D, 0x24, 0xFF, 0xAB, 0x6D, 0x24, 0xFF, 0xAB, 0x6D, + 0x24, 0xFF, 0xAB, 0x6D, 0x24, 0xFF, 0xAB, 0x6D, 0x24, 0xFF, 0xAB, 0x6D, 0x24, 0xFF, 0xAA, 0x6D, + 0x24, 0xFF, 0xAA, 0x6D, 0x25, 0xFF, 0xAA, 0x6D, 0x24, 0xFF, 0xAB, 0x6D, 0x25, 0xFF, 0xAA, 0x6E, + 0x25, 0xFF, 0xAA, 0x6D, 0x25, 0xFF, 0xAA, 0x6C, 0x23, 0xFF, 0xA9, 0x6A, 0x20, 0xFF, 0xA6, 0x66, + 0x1A, 0xFF, 0xA3, 0x62, 0x15, 0xFF, 0xA1, 0x5F, 0x12, 0xFF, 0xA0, 0x5E, 0x11, 0xFF, 0x9F, 0x5D, + 0x11, 0xFF, 0x9D, 0x5C, 0x12, 0xFF, 0x9E, 0x5F, 0x17, 0xFF, 0xA3, 0x66, 0x23, 0xFF, 0xAF, 0x77, + 0x3D, 0xFF, 0xC3, 0x9D, 0x72, 0xEA, 0xD6, 0xB9, 0x99, 0x95, 0xD9, 0xBF, 0xA1, 0x1E, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD7, 0xBD, 0xA1, 0x0A, 0xD6, 0xBA, 0x9C, 0x62, 0xBB, 0x95, + 0x6B, 0xDE, 0xA4, 0x69, 0x33, 0xFD, 0x96, 0x57, 0x1F, 0xFF, 0x8E, 0x4D, 0x13, 0xFF, 0x8E, 0x4B, + 0x0D, 0xFF, 0x8F, 0x4B, 0x0C, 0xFF, 0x92, 0x4F, 0x0D, 0xFF, 0x94, 0x52, 0x0F, 0xFF, 0x98, 0x58, + 0x13, 0xFF, 0x9D, 0x5D, 0x19, 0xFF, 0xA2, 0x63, 0x1F, 0xFF, 0xA5, 0x68, 0x23, 0xFF, 0xA6, 0x6A, + 0x25, 0xFF, 0xA9, 0x6C, 0x25, 0xFF, 0xA9, 0x6C, 0x25, 0xFF, 0xAB, 0x6D, 0x26, 0xFF, 0xAB, 0x6F, + 0x26, 0xFF, 0xAC, 0x6F, 0x26, 0xFF, 0xAB, 0x6F, 0x26, 0xFF, 0xAC, 0x6F, 0x26, 0xFF, 0xAC, 0x6F, + 0x26, 0xFF, 0xAD, 0x6F, 0x26, 0xFF, 0xAC, 0x6F, 0x26, 0xFF, 0xAD, 0x6F, 0x26, 0xFF, 0xAC, 0x6F, + 0x26, 0xFF, 0xAB, 0x6F, 0x26, 0xFF, 0xAA, 0x6D, 0x25, 0xFF, 0xA8, 0x6C, 0x25, 0xFF, 0xA1, 0x6A, + 0x25, 0xFF, 0xA1, 0x73, 0x32, 0xFF, 0xB2, 0x97, 0x71, 0xFF, 0xD4, 0xCD, 0xC5, 0xFF, 0xDF, 0xDF, + 0xDE, 0xFF, 0xDF, 0xE0, 0xE1, 0xFF, 0xDC, 0xDD, 0xDE, 0xFF, 0xDC, 0xDE, 0xDE, 0xFF, 0xDC, 0xDD, + 0xDD, 0xFF, 0xDC, 0xDD, 0xDD, 0xFF, 0xDC, 0xDD, 0xDD, 0xFF, 0xDC, 0xDD, 0xDD, 0xFF, 0xDC, 0xDD, + 0xDD, 0xFF, 0xDC, 0xDD, 0xDD, 0xFF, 0xDB, 0xDD, 0xDE, 0xFF, 0xDC, 0xDD, 0xDE, 0xFF, 0xDC, 0xDE, + 0xDE, 0xFF, 0xDC, 0xDD, 0xDD, 0xFF, 0xDC, 0xDD, 0xDD, 0xFF, 0xDC, 0xDD, 0xDD, 0xFF, 0xDF, 0xDF, + 0xDF, 0xFF, 0xDF, 0xDE, 0xDC, 0xFF, 0xDE, 0xDE, 0xDD, 0xFF, 0xE2, 0xE3, 0xE2, 0xFF, 0xE0, 0xE1, + 0xE1, 0xFF, 0xE1, 0xE3, 0xE3, 0xFF, 0xE2, 0xE3, 0xE4, 0xFF, 0xE3, 0xE4, 0xE5, 0xFF, 0xE5, 0xE6, + 0xE6, 0xFF, 0xE6, 0xE6, 0xE7, 0xFF, 0xE5, 0xE6, 0xE6, 0xFF, 0xE4, 0xE4, 0xE5, 0xFF, 0xE5, 0xE4, + 0xE7, 0xFF, 0xE2, 0xE3, 0xE3, 0xFF, 0xCB, 0xC9, 0xC1, 0xFF, 0x97, 0x8A, 0x6B, 0xFF, 0x7F, 0x6A, + 0x43, 0xFF, 0x7C, 0x67, 0x3E, 0xFF, 0x9A, 0x8A, 0x6C, 0xFF, 0xD2, 0xCA, 0xC0, 0xFF, 0xE0, 0xE0, + 0xDE, 0xFF, 0xDE, 0xDE, 0xDF, 0xFF, 0xD8, 0xD4, 0xD1, 0xFF, 0xBF, 0xB5, 0xA5, 0xFF, 0x94, 0x7F, + 0x5D, 0xFF, 0x82, 0x65, 0x36, 0xFF, 0x86, 0x5F, 0x2A, 0xFF, 0x8D, 0x60, 0x25, 0xFF, 0x95, 0x64, + 0x24, 0xFF, 0x9E, 0x68, 0x25, 0xFF, 0xA4, 0x6C, 0x25, 0xFF, 0xA9, 0x6E, 0x25, 0xFF, 0xAA, 0x6E, + 0x26, 0xFF, 0xAB, 0x6F, 0x25, 0xFF, 0xAB, 0x6F, 0x26, 0xFF, 0xAC, 0x6F, 0x26, 0xFF, 0xAB, 0x6F, + 0x25, 0xFF, 0xAC, 0x6E, 0x26, 0xFF, 0xAC, 0x6F, 0x26, 0xFF, 0xAD, 0x6F, 0x26, 0xFF, 0xAC, 0x6F, + 0x26, 0xFF, 0xAD, 0x6F, 0x26, 0xFF, 0xAC, 0x6F, 0x26, 0xFF, 0xAC, 0x6F, 0x26, 0xFF, 0xAB, 0x6F, + 0x26, 0xFF, 0xAC, 0x6F, 0x26, 0xFF, 0xAC, 0x6F, 0x26, 0xFF, 0xAD, 0x6F, 0x26, 0xFF, 0xAC, 0x6F, + 0x27, 0xFF, 0xAC, 0x6F, 0x27, 0xFF, 0xAC, 0x6F, 0x26, 0xFF, 0xAC, 0x6E, 0x26, 0xFF, 0xAA, 0x6C, + 0x22, 0xFF, 0xA7, 0x67, 0x1C, 0xFF, 0xA4, 0x63, 0x16, 0xFF, 0xA2, 0x60, 0x13, 0xFF, 0xA0, 0x5E, + 0x12, 0xFF, 0x9F, 0x5D, 0x12, 0xFF, 0x9F, 0x5F, 0x16, 0xFF, 0xA5, 0x67, 0x21, 0xFF, 0xAF, 0x77, + 0x38, 0xFF, 0xC2, 0x9A, 0x6F, 0xF3, 0xD3, 0xB5, 0x93, 0xA4, 0xD6, 0xB9, 0x9A, 0x24, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD7, 0xBE, 0xA1, 0x0E, 0xD7, 0xBC, 0x9D, 0x72, 0xBB, 0x96, + 0x6B, 0xE3, 0xA3, 0x67, 0x30, 0xFE, 0x97, 0x57, 0x1D, 0xFF, 0x90, 0x4F, 0x13, 0xFF, 0x90, 0x4C, + 0x0D, 0xFF, 0x91, 0x4D, 0x0C, 0xFF, 0x94, 0x50, 0x0E, 0xFF, 0x98, 0x57, 0x14, 0xFF, 0x9E, 0x5F, + 0x1C, 0xFF, 0xA2, 0x65, 0x22, 0xFF, 0xA5, 0x69, 0x25, 0xFF, 0xA7, 0x6B, 0x26, 0xFF, 0xA9, 0x6D, + 0x27, 0xFF, 0xAA, 0x6E, 0x27, 0xFF, 0xAB, 0x6E, 0x27, 0xFF, 0xAD, 0x6F, 0x28, 0xFF, 0xAD, 0x71, + 0x28, 0xFF, 0xAE, 0x71, 0x28, 0xFF, 0xAE, 0x71, 0x28, 0xFF, 0xAE, 0x71, 0x28, 0xFF, 0xAE, 0x71, + 0x28, 0xFF, 0xAE, 0x71, 0x28, 0xFF, 0xAE, 0x71, 0x28, 0xFF, 0xAE, 0x71, 0x28, 0xFF, 0xAE, 0x71, + 0x28, 0xFF, 0xAD, 0x71, 0x28, 0xFF, 0xAC, 0x70, 0x28, 0xFF, 0xAB, 0x70, 0x28, 0xFF, 0xA8, 0x6E, + 0x26, 0xFF, 0xA3, 0x6D, 0x28, 0xFF, 0xA1, 0x76, 0x3B, 0xFF, 0xB9, 0xA4, 0x88, 0xFF, 0xD5, 0xD0, + 0xC7, 0xFF, 0xDF, 0xDD, 0xDD, 0xFF, 0xDB, 0xDC, 0xDD, 0xFF, 0xD9, 0xDB, 0xDB, 0xFF, 0xD9, 0xDB, + 0xDB, 0xFF, 0xDA, 0xDB, 0xDB, 0xFF, 0xDA, 0xDB, 0xDB, 0xFF, 0xDA, 0xDB, 0xDB, 0xFF, 0xDA, 0xDB, + 0xDB, 0xFF, 0xDA, 0xDB, 0xDB, 0xFF, 0xDA, 0xDB, 0xDC, 0xFF, 0xDB, 0xDC, 0xDD, 0xFF, 0xDA, 0xDC, + 0xDD, 0xFF, 0xDA, 0xDB, 0xDB, 0xFF, 0xDA, 0xDA, 0xDA, 0xFF, 0xDB, 0xDB, 0xDA, 0xFF, 0xD4, 0xD0, + 0xCB, 0xFF, 0xC9, 0xC0, 0xB0, 0xFF, 0xC8, 0xC1, 0xAF, 0xFF, 0xD7, 0xD8, 0xD0, 0xFF, 0xDC, 0xDD, + 0xDD, 0xFF, 0xE1, 0xE1, 0xE1, 0xFF, 0xDF, 0xE1, 0xE1, 0xFF, 0xE1, 0xE2, 0xE2, 0xFF, 0xE2, 0xE3, + 0xE4, 0xFF, 0xE4, 0xE5, 0xE5, 0xFF, 0xE5, 0xE6, 0xE6, 0xFF, 0xE5, 0xE5, 0xE6, 0xFF, 0xE4, 0xE4, + 0xE5, 0xFF, 0xE4, 0xE4, 0xE5, 0xFF, 0xE2, 0xE3, 0xE4, 0xFF, 0xD4, 0xD3, 0xCE, 0xFF, 0xA5, 0x99, + 0x7F, 0xFF, 0x81, 0x6D, 0x43, 0xFF, 0x7B, 0x69, 0x3E, 0xFF, 0x92, 0x81, 0x62, 0xFF, 0xC8, 0xBF, + 0xB0, 0xFF, 0xDA, 0xD9, 0xD5, 0xFF, 0xD9, 0xD9, 0xDA, 0xFF, 0xDA, 0xD8, 0xD7, 0xFF, 0xCC, 0xC7, + 0xBB, 0xFF, 0xA4, 0x95, 0x7B, 0xFF, 0x88, 0x6C, 0x42, 0xFF, 0x84, 0x61, 0x2D, 0xFF, 0x8B, 0x62, + 0x26, 0xFF, 0x93, 0x64, 0x25, 0xFF, 0x9E, 0x6A, 0x26, 0xFF, 0xA6, 0x6E, 0x27, 0xFF, 0xA9, 0x6F, + 0x27, 0xFF, 0xAB, 0x6F, 0x27, 0xFF, 0xAC, 0x71, 0x27, 0xFF, 0xAD, 0x71, 0x28, 0xFF, 0xAD, 0x71, + 0x28, 0xFF, 0xAE, 0x71, 0x28, 0xFF, 0xAE, 0x71, 0x28, 0xFF, 0xAE, 0x71, 0x28, 0xFF, 0xAE, 0x71, + 0x28, 0xFF, 0xAE, 0x71, 0x28, 0xFF, 0xAE, 0x71, 0x28, 0xFF, 0xAE, 0x71, 0x28, 0xFF, 0xAE, 0x71, + 0x28, 0xFF, 0xAE, 0x71, 0x28, 0xFF, 0xAE, 0x71, 0x28, 0xFF, 0xAE, 0x71, 0x28, 0xFF, 0xAE, 0x71, + 0x28, 0xFF, 0xAE, 0x71, 0x29, 0xFF, 0xAE, 0x71, 0x28, 0xFF, 0xAE, 0x71, 0x28, 0xFF, 0xAD, 0x70, + 0x27, 0xFF, 0xAC, 0x6E, 0x25, 0xFF, 0xA9, 0x69, 0x1E, 0xFF, 0xA5, 0x63, 0x17, 0xFF, 0xA2, 0x60, + 0x12, 0xFF, 0xA1, 0x5F, 0x12, 0xFF, 0xA0, 0x61, 0x15, 0xFF, 0xA5, 0x67, 0x20, 0xFF, 0xAF, 0x77, + 0x33, 0xFF, 0xC0, 0x99, 0x6E, 0xF8, 0xD5, 0xB5, 0x93, 0xB6, 0xD5, 0xB7, 0x96, 0x28, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD7, 0xBE, 0xA0, 0x12, 0xD7, 0xBD, 0x9E, 0x7F, 0xBB, 0x95, + 0x69, 0xE4, 0xA2, 0x64, 0x2C, 0xFD, 0x97, 0x57, 0x1C, 0xFF, 0x92, 0x50, 0x13, 0xFF, 0x92, 0x4E, + 0x0D, 0xFF, 0x93, 0x4F, 0x0E, 0xFF, 0x97, 0x55, 0x13, 0xFF, 0x9D, 0x5E, 0x1C, 0xFF, 0xA2, 0x65, + 0x23, 0xFF, 0xA6, 0x6A, 0x27, 0xFF, 0xA7, 0x6C, 0x28, 0xFF, 0xAA, 0x6E, 0x28, 0xFF, 0xAB, 0x6E, + 0x29, 0xFF, 0xAC, 0x6F, 0x29, 0xFF, 0xAD, 0x70, 0x29, 0xFF, 0xAE, 0x71, 0x29, 0xFF, 0xAF, 0x73, + 0x2A, 0xFF, 0xB0, 0x73, 0x2A, 0xFF, 0xAF, 0x73, 0x2A, 0xFF, 0xB0, 0x73, 0x2A, 0xFF, 0xAF, 0x73, + 0x2A, 0xFF, 0xB0, 0x73, 0x2A, 0xFF, 0xAF, 0x73, 0x2A, 0xFF, 0xB0, 0x73, 0x2A, 0xFF, 0xAF, 0x73, + 0x2A, 0xFF, 0xAF, 0x73, 0x2A, 0xFF, 0xAF, 0x73, 0x2A, 0xFF, 0xAE, 0x72, 0x29, 0xFF, 0xAD, 0x71, + 0x29, 0xFF, 0xAA, 0x70, 0x29, 0xFF, 0xA4, 0x70, 0x2D, 0xFF, 0xA7, 0x81, 0x4A, 0xFF, 0xBD, 0xAD, + 0x96, 0xFF, 0xD4, 0xD1, 0xCD, 0xFF, 0xDB, 0xDB, 0xDC, 0xFF, 0xDA, 0xDB, 0xDC, 0xFF, 0xD7, 0xD9, + 0xD9, 0xFF, 0xD8, 0xD9, 0xD9, 0xFF, 0xD8, 0xD9, 0xD9, 0xFF, 0xD9, 0xD9, 0xD9, 0xFF, 0xD9, 0xDA, + 0xD9, 0xFF, 0xD9, 0xDA, 0xDA, 0xFF, 0xDA, 0xDB, 0xDB, 0xFF, 0xDB, 0xDC, 0xDC, 0xFF, 0xDA, 0xDB, + 0xDC, 0xFF, 0xD9, 0xDA, 0xDA, 0xFF, 0xD9, 0xDA, 0xD9, 0xFF, 0xD0, 0xCA, 0xBF, 0xFF, 0xA4, 0x93, + 0x76, 0xFF, 0x94, 0x7C, 0x52, 0xFF, 0x96, 0x7C, 0x4F, 0xFF, 0xBD, 0xAF, 0x96, 0xFF, 0xDB, 0xD9, + 0xD3, 0xFF, 0xDE, 0xDD, 0xDD, 0xFF, 0xDD, 0xDE, 0xE0, 0xFF, 0xDF, 0xE0, 0xE0, 0xFF, 0xE0, 0xE1, + 0xE2, 0xFF, 0xE1, 0xE3, 0xE3, 0xFF, 0xE3, 0xE5, 0xE5, 0xFF, 0xE4, 0xE5, 0xE6, 0xFF, 0xE2, 0xE4, + 0xE5, 0xFF, 0xE2, 0xE3, 0xE4, 0xFF, 0xE2, 0xE3, 0xE3, 0xFF, 0xE1, 0xE3, 0xE3, 0xFF, 0xDC, 0xDC, + 0xDB, 0xFF, 0xB4, 0xAC, 0x98, 0xFF, 0x84, 0x71, 0x4B, 0xFF, 0x7D, 0x69, 0x3E, 0xFF, 0x95, 0x83, + 0x61, 0xFF, 0xC3, 0xB9, 0xA6, 0xFF, 0xD8, 0xD6, 0xD2, 0xFF, 0xDB, 0xDA, 0xDB, 0xFF, 0xDB, 0xD8, + 0xD8, 0xFF, 0xD2, 0xCD, 0xC7, 0xFF, 0xB2, 0xA6, 0x8F, 0xFF, 0x8F, 0x78, 0x51, 0xFF, 0x84, 0x64, + 0x32, 0xFF, 0x88, 0x61, 0x28, 0xFF, 0x92, 0x65, 0x27, 0xFF, 0x9D, 0x69, 0x28, 0xFF, 0xA4, 0x6D, + 0x28, 0xFF, 0xA9, 0x6F, 0x28, 0xFF, 0xAC, 0x72, 0x29, 0xFF, 0xAE, 0x72, 0x2A, 0xFF, 0xAF, 0x73, + 0x2A, 0xFF, 0xB0, 0x73, 0x2A, 0xFF, 0xAF, 0x73, 0x2A, 0xFF, 0xAF, 0x73, 0x2A, 0xFF, 0xAF, 0x73, + 0x29, 0xFF, 0xB0, 0x73, 0x2A, 0xFF, 0xAF, 0x73, 0x2A, 0xFF, 0xB0, 0x73, 0x2A, 0xFF, 0xAF, 0x73, + 0x29, 0xFF, 0xB0, 0x73, 0x2A, 0xFF, 0xAF, 0x73, 0x2A, 0xFF, 0xB0, 0x73, 0x2A, 0xFF, 0xAF, 0x73, + 0x2A, 0xFF, 0xB0, 0x73, 0x2A, 0xFF, 0xAF, 0x73, 0x2A, 0xFF, 0xB0, 0x73, 0x2A, 0xFF, 0xAF, 0x73, + 0x2A, 0xFF, 0xAF, 0x72, 0x2A, 0xFF, 0xAE, 0x70, 0x27, 0xFF, 0xAA, 0x6A, 0x1F, 0xFF, 0xA4, 0x62, + 0x15, 0xFF, 0xA3, 0x60, 0x14, 0xFF, 0xA2, 0x62, 0x16, 0xFF, 0xA6, 0x67, 0x1E, 0xFF, 0xB1, 0x77, + 0x30, 0xFF, 0xBF, 0x97, 0x6A, 0xFF, 0xD5, 0xB5, 0x92, 0xC5, 0xD6, 0xB7, 0x95, 0x29, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD7, 0xBD, 0xA0, 0x15, 0xD7, 0xBC, 0x9E, 0x87, 0xBE, 0x95, + 0x69, 0xE8, 0xA2, 0x64, 0x2B, 0xFF, 0x97, 0x56, 0x1A, 0xFF, 0x93, 0x50, 0x12, 0xFF, 0x94, 0x50, + 0x10, 0xFF, 0x97, 0x54, 0x13, 0xFF, 0x9E, 0x5F, 0x1E, 0xFF, 0xA2, 0x66, 0x25, 0xFF, 0xA6, 0x6A, + 0x28, 0xFF, 0xA8, 0x6D, 0x29, 0xFF, 0xAA, 0x6E, 0x2A, 0xFF, 0xAB, 0x70, 0x2A, 0xFF, 0xAD, 0x71, + 0x2A, 0xFF, 0xAE, 0x72, 0x2B, 0xFF, 0xAF, 0x73, 0x2B, 0xFF, 0xB0, 0x74, 0x2B, 0xFF, 0xB1, 0x75, + 0x2B, 0xFF, 0xB1, 0x75, 0x2B, 0xFF, 0xB1, 0x75, 0x2B, 0xFF, 0xB1, 0x75, 0x2B, 0xFF, 0xB1, 0x75, + 0x2B, 0xFF, 0xB1, 0x75, 0x2B, 0xFF, 0xB1, 0x75, 0x2C, 0xFF, 0xB1, 0x75, 0x2C, 0xFF, 0xB1, 0x75, + 0x2C, 0xFF, 0xB1, 0x75, 0x2B, 0xFF, 0xB1, 0x75, 0x2B, 0xFF, 0xB0, 0x75, 0x2B, 0xFF, 0xAF, 0x74, + 0x2B, 0xFF, 0xAD, 0x73, 0x2C, 0xFF, 0xAA, 0x71, 0x2B, 0xFF, 0xA4, 0x72, 0x2F, 0xFF, 0xA9, 0x86, + 0x54, 0xFF, 0xC3, 0xB6, 0xA6, 0xFF, 0xD3, 0xD3, 0xCE, 0xFF, 0xD9, 0xD8, 0xD9, 0xFF, 0xD7, 0xD7, + 0xD8, 0xFF, 0xD6, 0xD7, 0xD8, 0xFF, 0xD6, 0xD7, 0xD7, 0xFF, 0xD7, 0xD8, 0xD8, 0xFF, 0xD8, 0xD9, + 0xD9, 0xFF, 0xD9, 0xD9, 0xDA, 0xFF, 0xD9, 0xDA, 0xDB, 0xFF, 0xDA, 0xDB, 0xDC, 0xFF, 0xD8, 0xDA, + 0xDB, 0xFF, 0xD8, 0xDA, 0xDA, 0xFF, 0xD7, 0xD9, 0xD8, 0xFF, 0xB3, 0xA8, 0x95, 0xFF, 0x8B, 0x74, + 0x4D, 0xFF, 0x8A, 0x6F, 0x44, 0xFF, 0x8B, 0x6E, 0x40, 0xFF, 0xA6, 0x8C, 0x60, 0xFF, 0xD6, 0xCF, + 0xC5, 0xFF, 0xDB, 0xDA, 0xD9, 0xFF, 0xDC, 0xDD, 0xDE, 0xFF, 0xDF, 0xDF, 0xE0, 0xFF, 0xDE, 0xDF, + 0xE0, 0xFF, 0xE0, 0xE1, 0xE1, 0xFF, 0xE3, 0xE3, 0xE4, 0xFF, 0xE3, 0xE4, 0xE5, 0xFF, 0xE2, 0xE3, + 0xE4, 0xFF, 0xE1, 0xE2, 0xE3, 0xFF, 0xE1, 0xE3, 0xE4, 0xFF, 0xE1, 0xE3, 0xE2, 0xFF, 0xE0, 0xE2, + 0xE1, 0xFF, 0xE0, 0xE1, 0xDF, 0xFF, 0xC1, 0xBB, 0xAE, 0xFF, 0x8C, 0x7C, 0x5A, 0xFF, 0x7F, 0x6F, + 0x47, 0xFF, 0x92, 0x82, 0x60, 0xFF, 0xB9, 0xAD, 0x98, 0xFF, 0xD5, 0xD4, 0xCC, 0xFF, 0xDA, 0xD9, + 0xDA, 0xFF, 0xDC, 0xDB, 0xDB, 0xFF, 0xD7, 0xD5, 0xD0, 0xFF, 0xC0, 0xB8, 0xA9, 0xFF, 0x9B, 0x85, + 0x64, 0xFF, 0x87, 0x69, 0x39, 0xFF, 0x89, 0x64, 0x2C, 0xFF, 0x91, 0x66, 0x2A, 0xFF, 0x9C, 0x6B, + 0x29, 0xFF, 0xA4, 0x6E, 0x29, 0xFF, 0xA9, 0x71, 0x2B, 0xFF, 0xAC, 0x73, 0x2B, 0xFF, 0xAF, 0x74, + 0x2B, 0xFF, 0xB1, 0x74, 0x2B, 0xFF, 0xB1, 0x74, 0x2B, 0xFF, 0xB1, 0x74, 0x2B, 0xFF, 0xB1, 0x75, + 0x2B, 0xFF, 0xB1, 0x75, 0x2B, 0xFF, 0xB1, 0x75, 0x2B, 0xFF, 0xB1, 0x75, 0x2B, 0xFF, 0xB1, 0x75, + 0x2B, 0xFF, 0xB1, 0x75, 0x2B, 0xFF, 0xB1, 0x75, 0x2B, 0xFF, 0xB1, 0x75, 0x2B, 0xFF, 0xB1, 0x75, + 0x2B, 0xFF, 0xB1, 0x75, 0x2B, 0xFF, 0xB1, 0x75, 0x2B, 0xFF, 0xB1, 0x75, 0x2C, 0xFF, 0xB1, 0x75, + 0x2C, 0xFF, 0xB1, 0x75, 0x2C, 0xFF, 0xB0, 0x74, 0x2C, 0xFF, 0xAE, 0x71, 0x28, 0xFF, 0xAA, 0x6A, + 0x20, 0xFF, 0xA5, 0x63, 0x17, 0xFF, 0xA3, 0x63, 0x17, 0xFF, 0xA5, 0x66, 0x1D, 0xFF, 0xB2, 0x75, + 0x2E, 0xFF, 0xC1, 0x97, 0x69, 0xFF, 0xD4, 0xB4, 0x91, 0xD7, 0xD5, 0xB6, 0x94, 0x27, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0xBE, 0xA0, 0x19, 0xD8, 0xBC, 0x9D, 0x8F, 0xBF, 0x95, + 0x66, 0xEA, 0xA2, 0x63, 0x29, 0xFE, 0x98, 0x56, 0x1A, 0xFF, 0x95, 0x52, 0x14, 0xFF, 0x98, 0x54, + 0x14, 0xFF, 0x9C, 0x5C, 0x1C, 0xFF, 0xA3, 0x66, 0x26, 0xFF, 0xA6, 0x6B, 0x2A, 0xFF, 0xA8, 0x6D, + 0x2B, 0xFF, 0xAB, 0x6F, 0x2B, 0xFF, 0xAC, 0x70, 0x2B, 0xFF, 0xAD, 0x71, 0x2C, 0xFF, 0xAF, 0x73, + 0x2C, 0xFF, 0xB0, 0x74, 0x2C, 0xFF, 0xB1, 0x75, 0x2D, 0xFF, 0xB2, 0x76, 0x2D, 0xFF, 0xB2, 0x77, + 0x2D, 0xFF, 0xB3, 0x77, 0x2D, 0xFF, 0xB2, 0x77, 0x2D, 0xFF, 0xB3, 0x77, 0x2D, 0xFF, 0xB2, 0x77, + 0x2D, 0xFF, 0xB3, 0x77, 0x2D, 0xFF, 0xB2, 0x77, 0x2D, 0xFF, 0xB3, 0x77, 0x2D, 0xFF, 0xB2, 0x77, + 0x2D, 0xFF, 0xB3, 0x77, 0x2D, 0xFF, 0xB2, 0x77, 0x2D, 0xFF, 0xB2, 0x77, 0x2D, 0xFF, 0xB2, 0x77, + 0x2D, 0xFF, 0xB1, 0x76, 0x2D, 0xFF, 0xAF, 0x75, 0x2C, 0xFF, 0xAB, 0x73, 0x2D, 0xFF, 0xA6, 0x75, + 0x33, 0xFF, 0xAF, 0x8F, 0x61, 0xFF, 0xC6, 0xBE, 0xB0, 0xFF, 0xD4, 0xD3, 0xCF, 0xFF, 0xD5, 0xD5, + 0xD6, 0xFF, 0xD5, 0xD6, 0xD7, 0xFF, 0xD5, 0xD6, 0xD6, 0xFF, 0xD6, 0xD7, 0xD7, 0xFF, 0xD7, 0xD8, + 0xD8, 0xFF, 0xD8, 0xD9, 0xD9, 0xFF, 0xD9, 0xDA, 0xDA, 0xFF, 0xD9, 0xDA, 0xDA, 0xFF, 0xD9, 0xDA, + 0xDA, 0xFF, 0xD9, 0xDB, 0xDB, 0xFF, 0xD7, 0xD9, 0xD5, 0xFF, 0xAB, 0xA1, 0x8A, 0xFF, 0x84, 0x6F, + 0x44, 0xFF, 0x8A, 0x6F, 0x42, 0xFF, 0x84, 0x68, 0x3B, 0xFF, 0x9A, 0x7C, 0x4C, 0xFF, 0xCF, 0xC3, + 0xB3, 0xFF, 0xDB, 0xDA, 0xD7, 0xFF, 0xDC, 0xDB, 0xDC, 0xFF, 0xDD, 0xDE, 0xE0, 0xFF, 0xDE, 0xDF, + 0xDF, 0xFF, 0xDE, 0xE0, 0xDF, 0xFF, 0xE1, 0xE3, 0xE2, 0xFF, 0xE3, 0xE3, 0xE4, 0xFF, 0xE1, 0xE2, + 0xE4, 0xFF, 0xE2, 0xE2, 0xE4, 0xFF, 0xE1, 0xE3, 0xE3, 0xFF, 0xE1, 0xE2, 0xE2, 0xFF, 0xE0, 0xE1, + 0xE0, 0xFF, 0xDF, 0xE1, 0xE2, 0xFF, 0xE0, 0xE1, 0xE2, 0xFF, 0xD0, 0xCC, 0xC5, 0xFF, 0x98, 0x8B, + 0x6D, 0xFF, 0x87, 0x76, 0x4F, 0xFF, 0x93, 0x82, 0x60, 0xFF, 0xB6, 0xA8, 0x91, 0xFF, 0xD1, 0xCE, + 0xC6, 0xFF, 0xDB, 0xDB, 0xDA, 0xFF, 0xDC, 0xDA, 0xDA, 0xFF, 0xD8, 0xD8, 0xD5, 0xFF, 0xCA, 0xC4, + 0xB8, 0xFF, 0xA4, 0x93, 0x76, 0xFF, 0x8A, 0x6F, 0x42, 0xFF, 0x87, 0x65, 0x2F, 0xFF, 0x91, 0x68, + 0x2C, 0xFF, 0x9B, 0x6B, 0x2A, 0xFF, 0xA2, 0x6F, 0x2B, 0xFF, 0xA9, 0x72, 0x2C, 0xFF, 0xAE, 0x75, + 0x2C, 0xFF, 0xB1, 0x76, 0x2C, 0xFF, 0xB2, 0x77, 0x2D, 0xFF, 0xB2, 0x76, 0x2D, 0xFF, 0xB2, 0x76, + 0x2D, 0xFF, 0xB2, 0x76, 0x2D, 0xFF, 0xB2, 0x77, 0x2D, 0xFF, 0xB2, 0x77, 0x2D, 0xFF, 0xB2, 0x77, + 0x2D, 0xFF, 0xB3, 0x77, 0x2D, 0xFF, 0xB2, 0x77, 0x2D, 0xFF, 0xB3, 0x77, 0x2D, 0xFF, 0xB2, 0x77, + 0x2D, 0xFF, 0xB3, 0x77, 0x2D, 0xFF, 0xB2, 0x77, 0x2D, 0xFF, 0xB3, 0x77, 0x2D, 0xFF, 0xB2, 0x77, + 0x2E, 0xFF, 0xB3, 0x77, 0x2E, 0xFF, 0xB2, 0x76, 0x2E, 0xFF, 0xB1, 0x75, 0x2D, 0xFF, 0xAF, 0x73, + 0x2A, 0xFF, 0xAB, 0x6C, 0x21, 0xFF, 0xA7, 0x67, 0x1C, 0xFF, 0xA7, 0x67, 0x1D, 0xFF, 0xAF, 0x72, + 0x2C, 0xFF, 0xC2, 0x98, 0x67, 0xFF, 0xD4, 0xB5, 0x91, 0xE4, 0xD6, 0xB6, 0x93, 0x23, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0xBE, 0x9F, 0x19, 0xD9, 0xBD, 0x9E, 0x94, 0xBF, 0x93, + 0x63, 0xED, 0xA3, 0x64, 0x29, 0xFF, 0x9B, 0x59, 0x1C, 0xFF, 0x98, 0x56, 0x18, 0xFF, 0x9D, 0x5D, + 0x1F, 0xFF, 0xA1, 0x65, 0x27, 0xFF, 0xA5, 0x6A, 0x2B, 0xFF, 0xA8, 0x6D, 0x2C, 0xFF, 0xAB, 0x6F, + 0x2C, 0xFF, 0xAD, 0x71, 0x2D, 0xFF, 0xAE, 0x72, 0x2D, 0xFF, 0xAF, 0x73, 0x2D, 0xFF, 0xB0, 0x75, + 0x2E, 0xFF, 0xB1, 0x76, 0x2E, 0xFF, 0xB2, 0x77, 0x2F, 0xFF, 0xB3, 0x78, 0x2F, 0xFF, 0xB4, 0x79, + 0x2F, 0xFF, 0xB4, 0x79, 0x2F, 0xFF, 0xB4, 0x79, 0x2F, 0xFF, 0xB4, 0x79, 0x2F, 0xFF, 0xB4, 0x79, + 0x2F, 0xFF, 0xB4, 0x79, 0x2F, 0xFF, 0xB4, 0x79, 0x2F, 0xFF, 0xB4, 0x79, 0x2F, 0xFF, 0xB4, 0x79, + 0x2F, 0xFF, 0xB4, 0x79, 0x2F, 0xFF, 0xB4, 0x79, 0x2F, 0xFF, 0xB4, 0x79, 0x2F, 0xFF, 0xB4, 0x79, + 0x2F, 0xFF, 0xB3, 0x79, 0x2E, 0xFF, 0xB1, 0x78, 0x2E, 0xFF, 0xB0, 0x77, 0x30, 0xFF, 0xAA, 0x75, + 0x2E, 0xFF, 0xA7, 0x78, 0x35, 0xFF, 0xB1, 0x95, 0x70, 0xFF, 0xCB, 0xC5, 0xBC, 0xFF, 0xD5, 0xD6, + 0xD3, 0xFF, 0xD6, 0xD6, 0xD6, 0xFF, 0xD5, 0xD7, 0xD7, 0xFF, 0xD5, 0xD7, 0xD7, 0xFF, 0xD6, 0xD7, + 0xD7, 0xFF, 0xD6, 0xD7, 0xD7, 0xFF, 0xD7, 0xD8, 0xD8, 0xFF, 0xD7, 0xD8, 0xD8, 0xFF, 0xD7, 0xD8, + 0xD8, 0xFF, 0xD6, 0xD7, 0xD7, 0xFF, 0xD8, 0xD8, 0xD5, 0xFF, 0xCB, 0xC5, 0xB7, 0xFF, 0x99, 0x89, + 0x64, 0xFF, 0x85, 0x70, 0x43, 0xFF, 0x86, 0x6E, 0x41, 0xFF, 0x9A, 0x81, 0x5A, 0xFF, 0xC3, 0xB2, + 0x97, 0xFF, 0xD9, 0xD8, 0xD4, 0xFF, 0xDE, 0xDF, 0xE1, 0xFF, 0xDD, 0xDD, 0xD7, 0xFF, 0xDC, 0xDD, + 0xD8, 0xFF, 0xDD, 0xDB, 0xD5, 0xFF, 0xE1, 0xE0, 0xD9, 0xFF, 0xE2, 0xE2, 0xE1, 0xFF, 0xE2, 0xE3, + 0xE3, 0xFF, 0xE2, 0xE2, 0xDF, 0xFF, 0xE2, 0xE3, 0xE1, 0xFF, 0xE1, 0xE2, 0xE2, 0xFF, 0xE1, 0xE3, + 0xE3, 0xFF, 0xE0, 0xE2, 0xE2, 0xFF, 0xDE, 0xE0, 0xE0, 0xFF, 0xE1, 0xE0, 0xE0, 0xFF, 0xD3, 0xD1, + 0xCB, 0xFF, 0xA6, 0x9B, 0x85, 0xFF, 0x89, 0x7A, 0x58, 0xFF, 0x8F, 0x7E, 0x5E, 0xFF, 0xA7, 0x99, + 0x80, 0xFF, 0xD0, 0xCC, 0xC0, 0xFF, 0xDC, 0xDA, 0xD9, 0xFF, 0xDC, 0xDC, 0xDB, 0xFF, 0xDA, 0xDA, + 0xD8, 0xFF, 0xD1, 0xCE, 0xC8, 0xFF, 0xB3, 0xA5, 0x8F, 0xFF, 0x91, 0x79, 0x4E, 0xFF, 0x8A, 0x6A, + 0x34, 0xFF, 0x90, 0x6A, 0x2F, 0xFF, 0x99, 0x6C, 0x2C, 0xFF, 0xA2, 0x70, 0x2D, 0xFF, 0xAA, 0x74, + 0x2E, 0xFF, 0xB0, 0x77, 0x2F, 0xFF, 0xB2, 0x78, 0x2F, 0xFF, 0xB3, 0x78, 0x2F, 0xFF, 0xB4, 0x79, + 0x2F, 0xFF, 0xB4, 0x79, 0x2F, 0xFF, 0xB4, 0x79, 0x2F, 0xFF, 0xB4, 0x79, 0x2F, 0xFF, 0xB4, 0x79, + 0x2F, 0xFF, 0xB4, 0x79, 0x2F, 0xFF, 0xB4, 0x79, 0x2F, 0xFF, 0xB4, 0x79, 0x2F, 0xFF, 0xB4, 0x79, + 0x2F, 0xFF, 0xB4, 0x79, 0x2F, 0xFF, 0xB4, 0x79, 0x2F, 0xFF, 0xB4, 0x79, 0x2F, 0xFF, 0xB4, 0x79, + 0x30, 0xFF, 0xB4, 0x79, 0x30, 0xFF, 0xB3, 0x78, 0x2F, 0xFF, 0xB2, 0x77, 0x2F, 0xFF, 0xB2, 0x77, + 0x2F, 0xFF, 0xB0, 0x74, 0x2B, 0xFF, 0xAC, 0x6E, 0x25, 0xFF, 0xAC, 0x6D, 0x24, 0xFF, 0xB0, 0x73, + 0x2E, 0xFF, 0xC2, 0x98, 0x66, 0xFF, 0xD5, 0xB5, 0x90, 0xEF, 0xD6, 0xB7, 0x92, 0x21, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD9, 0xBE, 0x9F, 0x1A, 0xD9, 0xBC, 0x9C, 0x96, 0xBF, 0x92, + 0x60, 0xED, 0xA4, 0x67, 0x2B, 0xFF, 0x9E, 0x5E, 0x21, 0xFF, 0x9C, 0x5C, 0x20, 0xFF, 0xA2, 0x65, + 0x28, 0xFF, 0xA5, 0x6A, 0x2C, 0xFF, 0xA7, 0x6C, 0x2D, 0xFF, 0xAB, 0x6F, 0x2E, 0xFF, 0xAC, 0x71, + 0x2E, 0xFF, 0xAF, 0x73, 0x2E, 0xFF, 0xB0, 0x74, 0x2F, 0xFF, 0xB1, 0x76, 0x2F, 0xFF, 0xB2, 0x77, + 0x30, 0xFF, 0xB3, 0x78, 0x30, 0xFF, 0xB4, 0x79, 0x31, 0xFF, 0xB5, 0x7A, 0x31, 0xFF, 0xB5, 0x7B, + 0x31, 0xFF, 0xB5, 0x7B, 0x31, 0xFF, 0xB5, 0x7B, 0x31, 0xFF, 0xB6, 0x7B, 0x31, 0xFF, 0xB5, 0x7B, + 0x31, 0xFF, 0xB6, 0x7B, 0x31, 0xFF, 0xB5, 0x7B, 0x31, 0xFF, 0xB6, 0x7B, 0x31, 0xFF, 0xB5, 0x7B, + 0x31, 0xFF, 0xB6, 0x7B, 0x31, 0xFF, 0xB5, 0x7B, 0x31, 0xFF, 0xB6, 0x7B, 0x31, 0xFF, 0xB5, 0x7B, + 0x31, 0xFF, 0xB5, 0x7B, 0x30, 0xFF, 0xB4, 0x7A, 0x30, 0xFF, 0xB3, 0x7A, 0x31, 0xFF, 0xAF, 0x78, + 0x30, 0xFF, 0xAD, 0x78, 0x32, 0xFF, 0xAB, 0x82, 0x45, 0xFF, 0xBA, 0xA5, 0x8B, 0xFF, 0xD1, 0xCD, + 0xC6, 0xFF, 0xD6, 0xD7, 0xD5, 0xFF, 0xD6, 0xD7, 0xD6, 0xFF, 0xD5, 0xD7, 0xD7, 0xFF, 0xD5, 0xD7, + 0xD6, 0xFF, 0xD6, 0xD7, 0xD7, 0xFF, 0xD6, 0xD7, 0xD7, 0xFF, 0xD6, 0xD7, 0xD7, 0xFF, 0xD7, 0xD7, + 0xD7, 0xFF, 0xD5, 0xD6, 0xD6, 0xFF, 0xD6, 0xD5, 0xD7, 0xFF, 0xDB, 0xDA, 0xDB, 0xFF, 0xCB, 0xC6, + 0xC2, 0xFF, 0xBC, 0xB8, 0xAE, 0xFF, 0xB8, 0xB4, 0x9F, 0xFF, 0xB6, 0xAC, 0x8E, 0xFF, 0xAD, 0x9D, + 0x77, 0xFF, 0xB5, 0xAB, 0x97, 0xFF, 0xC6, 0xBC, 0xA6, 0xFF, 0xC4, 0xB6, 0x96, 0xFF, 0xBA, 0xAB, + 0x8D, 0xFF, 0xB8, 0xA7, 0x91, 0xFF, 0xB7, 0xA6, 0x8F, 0xFF, 0xC1, 0xB4, 0xA2, 0xFF, 0xD2, 0xCC, + 0xC2, 0xFF, 0xDD, 0xDC, 0xD1, 0xFF, 0xDE, 0xDE, 0xD7, 0xFF, 0xE2, 0xE1, 0xDF, 0xFF, 0xE3, 0xE3, + 0xE2, 0xFF, 0xE2, 0xE3, 0xE4, 0xFF, 0xDF, 0xE0, 0xE0, 0xFF, 0xDF, 0xDF, 0xE0, 0xFF, 0xE0, 0xDF, + 0xE0, 0xFF, 0xDA, 0xD8, 0xD2, 0xFF, 0xB3, 0xA9, 0x94, 0xFF, 0x93, 0x84, 0x63, 0xFF, 0x91, 0x81, + 0x5F, 0xFF, 0xA5, 0x97, 0x7B, 0xFF, 0xCD, 0xC8, 0xBC, 0xFF, 0xDC, 0xDB, 0xDA, 0xFF, 0xDB, 0xDD, + 0xDC, 0xFF, 0xD8, 0xD9, 0xD9, 0xFF, 0xD4, 0xD1, 0xCC, 0xFF, 0xBC, 0xB1, 0xA0, 0xFF, 0x98, 0x82, + 0x5B, 0xFF, 0x8B, 0x6C, 0x3A, 0xFF, 0x8F, 0x6A, 0x31, 0xFF, 0x98, 0x6C, 0x2E, 0xFF, 0xA2, 0x71, + 0x2F, 0xFF, 0xAA, 0x75, 0x30, 0xFF, 0xB0, 0x79, 0x31, 0xFF, 0xB4, 0x7A, 0x31, 0xFF, 0xB5, 0x7B, + 0x31, 0xFF, 0xB6, 0x7A, 0x31, 0xFF, 0xB5, 0x7A, 0x31, 0xFF, 0xB6, 0x7A, 0x31, 0xFF, 0xB5, 0x7B, + 0x31, 0xFF, 0xB6, 0x7B, 0x31, 0xFF, 0xB5, 0x7B, 0x31, 0xFF, 0xB6, 0x7B, 0x31, 0xFF, 0xB5, 0x7B, + 0x31, 0xFF, 0xB6, 0x7B, 0x31, 0xFF, 0xB5, 0x7B, 0x31, 0xFF, 0xB6, 0x7B, 0x31, 0xFF, 0xB5, 0x7B, + 0x31, 0xFF, 0xB6, 0x7B, 0x31, 0xFF, 0xB4, 0x7A, 0x31, 0xFF, 0xB4, 0x79, 0x30, 0xFF, 0xB3, 0x78, + 0x30, 0xFF, 0xB2, 0x77, 0x2F, 0xFF, 0xB0, 0x74, 0x2C, 0xFF, 0xAF, 0x73, 0x2C, 0xFF, 0xB0, 0x75, + 0x31, 0xFF, 0xC3, 0x9B, 0x67, 0xFF, 0xD5, 0xB5, 0x90, 0xF2, 0xD6, 0xB7, 0x92, 0x1F, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD9, 0xBE, 0x9F, 0x19, 0xD9, 0xBC, 0x9C, 0x95, 0xBD, 0x8F, + 0x5E, 0xEE, 0xA6, 0x6E, 0x34, 0xFF, 0xA3, 0x67, 0x2C, 0xFF, 0xA3, 0x66, 0x2C, 0xFF, 0xA6, 0x6A, + 0x2E, 0xFF, 0xA8, 0x6D, 0x2F, 0xFF, 0xAA, 0x6F, 0x2F, 0xFF, 0xAC, 0x72, 0x30, 0xFF, 0xAF, 0x74, + 0x31, 0xFF, 0xB0, 0x75, 0x31, 0xFF, 0xB2, 0x77, 0x32, 0xFF, 0xB3, 0x78, 0x32, 0xFF, 0xB4, 0x7A, + 0x32, 0xFF, 0xB5, 0x7B, 0x32, 0xFF, 0xB6, 0x7C, 0x33, 0xFF, 0xB7, 0x7C, 0x33, 0xFF, 0xB7, 0x7D, + 0x33, 0xFF, 0xB7, 0x7D, 0x33, 0xFF, 0xB7, 0x7D, 0x33, 0xFF, 0xB8, 0x7D, 0x33, 0xFF, 0xB7, 0x7D, + 0x33, 0xFF, 0xB8, 0x7D, 0x33, 0xFF, 0xB7, 0x7D, 0x33, 0xFF, 0xB8, 0x7D, 0x33, 0xFF, 0xB8, 0x7D, + 0x33, 0xFF, 0xB8, 0x7D, 0x33, 0xFF, 0xB8, 0x7D, 0x33, 0xFF, 0xB8, 0x7D, 0x33, 0xFF, 0xB7, 0x7D, + 0x33, 0xFF, 0xB7, 0x7D, 0x33, 0xFF, 0xB7, 0x7D, 0x33, 0xFF, 0xB6, 0x7D, 0x32, 0xFF, 0xB4, 0x7C, + 0x33, 0xFF, 0xB4, 0x7F, 0x3A, 0xFF, 0xB2, 0x83, 0x3F, 0xFF, 0xB3, 0x93, 0x63, 0xFF, 0xC2, 0xB3, + 0x9D, 0xFF, 0xD3, 0xD2, 0xCD, 0xFF, 0xD7, 0xD7, 0xD5, 0xFF, 0xD5, 0xD7, 0xD7, 0xFF, 0xD4, 0xD7, + 0xD7, 0xFF, 0xD5, 0xD7, 0xD7, 0xFF, 0xD5, 0xD7, 0xD7, 0xFF, 0xD6, 0xD7, 0xD7, 0xFF, 0xD6, 0xD7, + 0xD7, 0xFF, 0xD6, 0xD7, 0xD7, 0xFF, 0xD5, 0xD6, 0xD6, 0xFF, 0xD6, 0xD7, 0xD5, 0xFF, 0xD5, 0xD6, + 0xD4, 0xFF, 0xD9, 0xDA, 0xD9, 0xFF, 0xD9, 0xD9, 0xD8, 0xFF, 0xD1, 0xCE, 0xC3, 0xFF, 0xB1, 0x9F, + 0x7F, 0xFF, 0x9F, 0x89, 0x66, 0xFF, 0xA9, 0x98, 0x73, 0xFF, 0xB0, 0xA0, 0x80, 0xFF, 0xB7, 0xAA, + 0x8D, 0xFF, 0xC9, 0xC2, 0xAC, 0xFF, 0xBB, 0xAF, 0x96, 0xFF, 0xA9, 0x94, 0x73, 0xFF, 0xA1, 0x8B, + 0x69, 0xFF, 0xA6, 0x91, 0x70, 0xFF, 0xB2, 0xA5, 0x8B, 0xFF, 0xCC, 0xC7, 0xB9, 0xFF, 0xE4, 0xE2, + 0xE2, 0xFF, 0xE3, 0xE3, 0xE5, 0xFF, 0xE0, 0xE1, 0xE1, 0xFF, 0xDF, 0xE0, 0xE0, 0xFF, 0xDF, 0xDF, + 0xE0, 0xFF, 0xE0, 0xDF, 0xDF, 0xFF, 0xDB, 0xDB, 0xD6, 0xFF, 0xBA, 0xB4, 0xA4, 0xFF, 0x9A, 0x8D, + 0x6F, 0xFF, 0x92, 0x82, 0x61, 0xFF, 0x9C, 0x8D, 0x6F, 0xFF, 0xC7, 0xC1, 0xB1, 0xFF, 0xDD, 0xDD, + 0xDA, 0xFF, 0xDC, 0xDC, 0xDD, 0xFF, 0xDA, 0xDA, 0xDA, 0xFF, 0xD9, 0xD7, 0xD5, 0xFF, 0xCD, 0xC5, + 0xB8, 0xFF, 0xA5, 0x92, 0x70, 0xFF, 0x8F, 0x72, 0x42, 0xFF, 0x8E, 0x6B, 0x34, 0xFF, 0x98, 0x6D, + 0x2F, 0xFF, 0xA1, 0x71, 0x2F, 0xFF, 0xAB, 0x77, 0x32, 0xFF, 0xB2, 0x7B, 0x33, 0xFF, 0xB5, 0x7C, + 0x33, 0xFF, 0xB6, 0x7C, 0x33, 0xFF, 0xB7, 0x7C, 0x33, 0xFF, 0xB7, 0x7D, 0x33, 0xFF, 0xB8, 0x7D, + 0x33, 0xFF, 0xB8, 0x7D, 0x33, 0xFF, 0xB7, 0x7D, 0x33, 0xFF, 0xB8, 0x7D, 0x33, 0xFF, 0xB7, 0x7D, + 0x33, 0xFF, 0xB8, 0x7D, 0x33, 0xFF, 0xB8, 0x7D, 0x33, 0xFF, 0xB8, 0x7D, 0x33, 0xFF, 0xB7, 0x7D, + 0x33, 0xFF, 0xB7, 0x7D, 0x33, 0xFF, 0xB6, 0x7C, 0x33, 0xFF, 0xB6, 0x7B, 0x33, 0xFF, 0xB5, 0x7B, + 0x32, 0xFF, 0xB4, 0x7A, 0x32, 0xFF, 0xB3, 0x79, 0x32, 0xFF, 0xB5, 0x7C, 0x37, 0xFF, 0xB5, 0x7F, + 0x3C, 0xFF, 0xC6, 0x9E, 0x6B, 0xFF, 0xD5, 0xB5, 0x90, 0xF2, 0xD7, 0xB8, 0x94, 0x1F, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDB, 0xC0, 0xA1, 0x15, 0xDA, 0xBD, 0x9D, 0x93, 0xBF, 0x93, + 0x62, 0xED, 0xAD, 0x76, 0x3E, 0xFF, 0xAA, 0x70, 0x38, 0xFF, 0xA8, 0x6C, 0x32, 0xFF, 0xA8, 0x6D, + 0x31, 0xFF, 0xAB, 0x6F, 0x30, 0xFF, 0xAC, 0x72, 0x31, 0xFF, 0xAF, 0x74, 0x32, 0xFF, 0xB0, 0x76, + 0x33, 0xFF, 0xB2, 0x78, 0x33, 0xFF, 0xB4, 0x79, 0x34, 0xFF, 0xB5, 0x7B, 0x34, 0xFF, 0xB6, 0x7C, + 0x34, 0xFF, 0xB7, 0x7D, 0x34, 0xFF, 0xB8, 0x7E, 0x35, 0xFF, 0xB9, 0x7E, 0x35, 0xFF, 0xB8, 0x7E, + 0x35, 0xFF, 0xB9, 0x7F, 0x35, 0xFF, 0xB9, 0x7F, 0x35, 0xFF, 0xB9, 0x7F, 0x35, 0xFF, 0xB9, 0x7F, + 0x35, 0xFF, 0xBA, 0x7F, 0x35, 0xFF, 0xB9, 0x7F, 0x35, 0xFF, 0xBA, 0x7F, 0x35, 0xFF, 0xB9, 0x7F, + 0x35, 0xFF, 0xBA, 0x7F, 0x35, 0xFF, 0xB9, 0x7F, 0x35, 0xFF, 0xB9, 0x7F, 0x35, 0xFF, 0xB8, 0x7F, + 0x35, 0xFF, 0xB9, 0x7F, 0x35, 0xFF, 0xB9, 0x80, 0x35, 0xFF, 0xB9, 0x81, 0x38, 0xFF, 0xBC, 0x86, + 0x40, 0xFF, 0xBE, 0x8B, 0x49, 0xFF, 0xBB, 0x8C, 0x4B, 0xFF, 0xB6, 0x8D, 0x50, 0xFF, 0xBA, 0x9A, + 0x6B, 0xFF, 0xCA, 0xBD, 0xAD, 0xFF, 0xD6, 0xD6, 0xD3, 0xFF, 0xD7, 0xD8, 0xD8, 0xFF, 0xD6, 0xD7, + 0xD8, 0xFF, 0xD6, 0xD8, 0xD8, 0xFF, 0xD6, 0xD8, 0xD7, 0xFF, 0xD6, 0xD8, 0xD8, 0xFF, 0xD7, 0xD8, + 0xD8, 0xFF, 0xD7, 0xD8, 0xD8, 0xFF, 0xD7, 0xD9, 0xD8, 0xFF, 0xD8, 0xD9, 0xD9, 0xFF, 0xD7, 0xD9, + 0xD8, 0xFF, 0xD8, 0xDA, 0xD9, 0xFF, 0xDA, 0xDB, 0xDC, 0xFF, 0xDA, 0xDA, 0xD7, 0xFF, 0xC1, 0xB9, + 0xA5, 0xFF, 0x9F, 0x8A, 0x64, 0xFF, 0xA3, 0x91, 0x69, 0xFF, 0xC3, 0xB3, 0x98, 0xFF, 0xDE, 0xD6, + 0xC8, 0xFF, 0xE1, 0xE2, 0xE0, 0xFF, 0xD9, 0xD8, 0xD2, 0xFF, 0xB2, 0xA4, 0x84, 0xFF, 0x9C, 0x88, + 0x63, 0xFF, 0x98, 0x83, 0x5E, 0xFF, 0x95, 0x81, 0x59, 0xFF, 0xA8, 0x9A, 0x7E, 0xFF, 0xD4, 0xD1, + 0xCC, 0xFF, 0xDF, 0xE0, 0xE1, 0xFF, 0xDE, 0xE0, 0xE0, 0xFF, 0xDF, 0xE0, 0xE0, 0xFF, 0xDF, 0xE0, + 0xE0, 0xFF, 0xE0, 0xDF, 0xE0, 0xFF, 0xE1, 0xE0, 0xE2, 0xFF, 0xDE, 0xDD, 0xDA, 0xFF, 0xC1, 0xBD, + 0xAE, 0xFF, 0x9F, 0x94, 0x77, 0xFF, 0x97, 0x86, 0x65, 0xFF, 0x9D, 0x8D, 0x6D, 0xFF, 0xC1, 0xBB, + 0xAC, 0xFF, 0xDE, 0xDD, 0xDB, 0xFF, 0xDB, 0xDC, 0xDD, 0xFF, 0xD9, 0xD9, 0xDA, 0xFF, 0xDC, 0xDA, + 0xD9, 0xFF, 0xD3, 0xCD, 0xC4, 0xFF, 0xAB, 0x9D, 0x80, 0xFF, 0x90, 0x77, 0x4B, 0xFF, 0x8F, 0x6C, + 0x37, 0xFF, 0x98, 0x6E, 0x31, 0xFF, 0xA4, 0x74, 0x33, 0xFF, 0xAE, 0x79, 0x35, 0xFF, 0xB4, 0x7D, + 0x35, 0xFF, 0xB7, 0x7E, 0x35, 0xFF, 0xB8, 0x7E, 0x34, 0xFF, 0xB9, 0x7E, 0x35, 0xFF, 0xB9, 0x7E, + 0x35, 0xFF, 0xBA, 0x7E, 0x35, 0xFF, 0xB9, 0x7F, 0x35, 0xFF, 0xB9, 0x7F, 0x35, 0xFF, 0xB9, 0x7F, + 0x35, 0xFF, 0xBA, 0x7F, 0x35, 0xFF, 0xB9, 0x7F, 0x35, 0xFF, 0xB9, 0x7F, 0x35, 0xFF, 0xB8, 0x7F, + 0x35, 0xFF, 0xB9, 0x7E, 0x35, 0xFF, 0xB8, 0x7E, 0x35, 0xFF, 0xB8, 0x7D, 0x34, 0xFF, 0xB7, 0x7D, + 0x34, 0xFF, 0xB6, 0x7C, 0x34, 0xFF, 0xB6, 0x7D, 0x36, 0xFF, 0xB8, 0x80, 0x3E, 0xFF, 0xBB, 0x86, + 0x45, 0xFF, 0xC9, 0xA2, 0x72, 0xFF, 0xD6, 0xB7, 0x93, 0xE9, 0xD9, 0xBA, 0x96, 0x1F, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0xC2, 0xA4, 0x15, 0xDC, 0xBE, 0x9E, 0x8C, 0xC3, 0x9A, + 0x6C, 0xEB, 0xB5, 0x80, 0x48, 0xFF, 0xAE, 0x76, 0x3D, 0xFF, 0xAB, 0x70, 0x36, 0xFF, 0xAA, 0x70, + 0x33, 0xFF, 0xAD, 0x72, 0x32, 0xFF, 0xAE, 0x74, 0x34, 0xFF, 0xB0, 0x77, 0x35, 0xFF, 0xB3, 0x79, + 0x35, 0xFF, 0xB4, 0x7A, 0x35, 0xFF, 0xB6, 0x7C, 0x36, 0xFF, 0xB7, 0x7D, 0x36, 0xFF, 0xB7, 0x7E, + 0x36, 0xFF, 0xB8, 0x7F, 0x36, 0xFF, 0xB9, 0x80, 0x37, 0xFF, 0xBA, 0x80, 0x37, 0xFF, 0xBA, 0x81, + 0x37, 0xFF, 0xBB, 0x81, 0x37, 0xFF, 0xBA, 0x81, 0x37, 0xFF, 0xBA, 0x81, 0x37, 0xFF, 0xBB, 0x81, + 0x37, 0xFF, 0xBB, 0x81, 0x37, 0xFF, 0xBB, 0x81, 0x37, 0xFF, 0xBB, 0x81, 0x37, 0xFF, 0xBB, 0x81, + 0x37, 0xFF, 0xBB, 0x81, 0x37, 0xFF, 0xBA, 0x81, 0x37, 0xFF, 0xBA, 0x81, 0x37, 0xFF, 0xBB, 0x81, + 0x37, 0xFF, 0xBB, 0x82, 0x38, 0xFF, 0xBC, 0x84, 0x3C, 0xFF, 0xBF, 0x8A, 0x46, 0xFF, 0xC3, 0x91, + 0x4F, 0xFF, 0xC2, 0x91, 0x52, 0xFF, 0xC1, 0x91, 0x52, 0xFF, 0xBD, 0x90, 0x52, 0xFF, 0xB7, 0x90, + 0x56, 0xFF, 0xBE, 0xA1, 0x7A, 0xFF, 0xD0, 0xC7, 0xBB, 0xFF, 0xD9, 0xD7, 0xD3, 0xFF, 0xD8, 0xD8, + 0xD8, 0xFF, 0xD8, 0xD9, 0xD9, 0xFF, 0xD8, 0xDA, 0xDA, 0xFF, 0xD8, 0xDA, 0xDA, 0xFF, 0xD9, 0xDA, + 0xDA, 0xFF, 0xDA, 0xDB, 0xDB, 0xFF, 0xDA, 0xDA, 0xDA, 0xFF, 0xDA, 0xDA, 0xDA, 0xFF, 0xD8, 0xDA, + 0xD9, 0xFF, 0xD8, 0xD9, 0xDA, 0xFF, 0xDA, 0xDB, 0xDC, 0xFF, 0xDD, 0xDD, 0xDD, 0xFF, 0xCE, 0xCE, + 0xC4, 0xFF, 0xAB, 0x9D, 0x80, 0xFF, 0x9E, 0x8C, 0x6B, 0xFF, 0xAF, 0x9F, 0x82, 0xFF, 0xDB, 0xD2, + 0xC5, 0xFF, 0xE5, 0xE1, 0xE1, 0xFF, 0xE5, 0xE4, 0xE2, 0xFF, 0xCA, 0xC6, 0xB5, 0xFF, 0xA2, 0x93, + 0x6F, 0xFF, 0x99, 0x87, 0x5B, 0xFF, 0x8E, 0x7C, 0x55, 0xFF, 0xAA, 0x9D, 0x84, 0xFF, 0xD6, 0xD4, + 0xCE, 0xFF, 0xDB, 0xDC, 0xDC, 0xFF, 0xDC, 0xDE, 0xDE, 0xFF, 0xDF, 0xDF, 0xE0, 0xFF, 0xDF, 0xE0, + 0xE0, 0xFF, 0xDF, 0xE0, 0xE0, 0xFF, 0xDF, 0xE0, 0xE0, 0xFF, 0xE1, 0xE1, 0xE1, 0xFF, 0xDF, 0xE0, + 0xDE, 0xFF, 0xC9, 0xC6, 0xBC, 0xFF, 0xA8, 0x9C, 0x81, 0xFF, 0x9A, 0x8A, 0x69, 0xFF, 0x99, 0x8B, + 0x6C, 0xFF, 0xBE, 0xB6, 0xA4, 0xFF, 0xDE, 0xDD, 0xD9, 0xFF, 0xDD, 0xDC, 0xDC, 0xFF, 0xDA, 0xDA, + 0xD9, 0xFF, 0xDC, 0xDB, 0xD9, 0xFF, 0xDA, 0xD6, 0xCD, 0xFF, 0xBB, 0xAF, 0x98, 0xFF, 0x9A, 0x80, + 0x55, 0xFF, 0x95, 0x72, 0x3C, 0xFF, 0x9F, 0x75, 0x36, 0xFF, 0xA8, 0x78, 0x35, 0xFF, 0xB1, 0x7C, + 0x36, 0xFF, 0xB7, 0x7F, 0x36, 0xFF, 0xB9, 0x81, 0x37, 0xFF, 0xBA, 0x81, 0x37, 0xFF, 0xBA, 0x81, + 0x37, 0xFF, 0xBB, 0x81, 0x37, 0xFF, 0xBB, 0x81, 0x37, 0xFF, 0xBB, 0x81, 0x37, 0xFF, 0xBB, 0x81, + 0x37, 0xFF, 0xBB, 0x81, 0x37, 0xFF, 0xBA, 0x81, 0x37, 0xFF, 0xBA, 0x81, 0x37, 0xFF, 0xBA, 0x81, + 0x37, 0xFF, 0xBB, 0x81, 0x37, 0xFF, 0xBA, 0x80, 0x37, 0xFF, 0xB9, 0x7F, 0x36, 0xFF, 0xB8, 0x7F, + 0x36, 0xFF, 0xB8, 0x7F, 0x36, 0xFF, 0xB7, 0x7E, 0x38, 0xFF, 0xB9, 0x83, 0x41, 0xFF, 0xBF, 0x8C, + 0x4B, 0xFF, 0xCC, 0xA7, 0x7B, 0xFF, 0xDA, 0xBB, 0x98, 0xE1, 0xDB, 0xBD, 0x9A, 0x1F, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDD, 0xC2, 0xA4, 0x11, 0xDF, 0xC1, 0xA1, 0x84, 0xC9, 0xA2, + 0x75, 0xE6, 0xB8, 0x85, 0x4F, 0xFF, 0xB2, 0x7B, 0x41, 0xFF, 0xAD, 0x73, 0x38, 0xFF, 0xAC, 0x72, + 0x34, 0xFF, 0xAF, 0x74, 0x34, 0xFF, 0xB0, 0x76, 0x35, 0xFF, 0xB3, 0x79, 0x36, 0xFF, 0xB4, 0x7B, + 0x37, 0xFF, 0xB6, 0x7D, 0x37, 0xFF, 0xB8, 0x7E, 0x38, 0xFF, 0xB9, 0x7F, 0x38, 0xFF, 0xB9, 0x80, + 0x38, 0xFF, 0xBA, 0x81, 0x38, 0xFF, 0xBB, 0x82, 0x39, 0xFF, 0xBC, 0x82, 0x39, 0xFF, 0xBC, 0x83, + 0x39, 0xFF, 0xBC, 0x83, 0x39, 0xFF, 0xBB, 0x83, 0x39, 0xFF, 0xBB, 0x83, 0x39, 0xFF, 0xBC, 0x83, + 0x39, 0xFF, 0xBC, 0x83, 0x39, 0xFF, 0xBC, 0x83, 0x39, 0xFF, 0xBC, 0x83, 0x39, 0xFF, 0xBC, 0x83, + 0x39, 0xFF, 0xBC, 0x83, 0x39, 0xFF, 0xBB, 0x83, 0x39, 0xFF, 0xBC, 0x83, 0x39, 0xFF, 0xBD, 0x84, + 0x3A, 0xFF, 0xBE, 0x87, 0x3E, 0xFF, 0xC2, 0x8D, 0x48, 0xFF, 0xC5, 0x93, 0x53, 0xFF, 0xC6, 0x95, + 0x56, 0xFF, 0xC5, 0x94, 0x56, 0xFF, 0xC5, 0x94, 0x56, 0xFF, 0xC3, 0x93, 0x56, 0xFF, 0xBC, 0x91, + 0x55, 0xFF, 0xBC, 0x94, 0x5E, 0xFF, 0xC2, 0xAA, 0x87, 0xFF, 0xD6, 0xCE, 0xC5, 0xFF, 0xDB, 0xDA, + 0xD8, 0xFF, 0xDB, 0xDA, 0xDB, 0xFF, 0xDA, 0xDB, 0xDC, 0xFF, 0xDA, 0xDC, 0xDC, 0xFF, 0xDB, 0xDD, + 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDD, 0xFF, 0xDB, 0xDC, 0xDC, 0xFF, 0xDB, 0xDC, + 0xDC, 0xFF, 0xDA, 0xDB, 0xDC, 0xFF, 0xDA, 0xDB, 0xDC, 0xFF, 0xDD, 0xDD, 0xDE, 0xFF, 0xD1, 0xD1, + 0xCC, 0xFF, 0xB4, 0xAA, 0x8E, 0xFF, 0xBD, 0xB1, 0x97, 0xFF, 0xA7, 0x98, 0x79, 0xFF, 0xC0, 0xB3, + 0x9D, 0xFF, 0xDB, 0xD6, 0xD0, 0xFF, 0xE4, 0xE4, 0xE6, 0xFF, 0xDC, 0xDB, 0xDB, 0xFF, 0xB7, 0xAF, + 0x9E, 0xFF, 0x9D, 0x8F, 0x71, 0xFF, 0xA4, 0x9A, 0x83, 0xFF, 0xCC, 0xCB, 0xBF, 0xFF, 0xDA, 0xDB, + 0xDB, 0xFF, 0xDB, 0xDB, 0xDB, 0xFF, 0xDA, 0xDB, 0xDD, 0xFF, 0xDC, 0xDD, 0xDE, 0xFF, 0xDE, 0xDF, + 0xDF, 0xFF, 0xDF, 0xE0, 0xE1, 0xFF, 0xDF, 0xE0, 0xE0, 0xFF, 0xDF, 0xE0, 0xE0, 0xFF, 0xE1, 0xE2, + 0xE3, 0xFF, 0xDF, 0xE1, 0xE0, 0xFF, 0xD2, 0xD1, 0xCA, 0xFF, 0xAF, 0xA7, 0x8F, 0xFF, 0x9D, 0x8E, + 0x6E, 0xFF, 0x9B, 0x8C, 0x6C, 0xFF, 0xBA, 0xB3, 0xA2, 0xFF, 0xDD, 0xDC, 0xD6, 0xFF, 0xDB, 0xDB, + 0xDB, 0xFF, 0xDB, 0xDB, 0xDB, 0xFF, 0xDE, 0xDB, 0xDD, 0xFF, 0xDB, 0xD7, 0xD1, 0xFF, 0xC3, 0xB8, + 0xA1, 0xFF, 0x9C, 0x84, 0x5B, 0xFF, 0x9B, 0x76, 0x3E, 0xFF, 0xA4, 0x77, 0x37, 0xFF, 0xAF, 0x7C, + 0x36, 0xFF, 0xB7, 0x7F, 0x38, 0xFF, 0xBA, 0x82, 0x38, 0xFF, 0xBC, 0x82, 0x39, 0xFF, 0xBC, 0x82, + 0x38, 0xFF, 0xBC, 0x82, 0x39, 0xFF, 0xBC, 0x83, 0x39, 0xFF, 0xBC, 0x83, 0x39, 0xFF, 0xBC, 0x83, + 0x39, 0xFF, 0xBC, 0x83, 0x39, 0xFF, 0xBB, 0x83, 0x39, 0xFF, 0xBC, 0x83, 0x39, 0xFF, 0xBC, 0x83, + 0x39, 0xFF, 0xBC, 0x83, 0x39, 0xFF, 0xBB, 0x82, 0x39, 0xFF, 0xBB, 0x81, 0x38, 0xFF, 0xBA, 0x81, + 0x38, 0xFF, 0xB9, 0x80, 0x38, 0xFF, 0xB8, 0x80, 0x3B, 0xFF, 0xBC, 0x86, 0x44, 0xFF, 0xC1, 0x90, + 0x51, 0xFF, 0xD0, 0xAD, 0x82, 0xFF, 0xDB, 0xBD, 0x9A, 0xD1, 0xDD, 0xBF, 0x9D, 0x1E, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDD, 0xC4, 0xA5, 0x10, 0xDE, 0xC2, 0xA2, 0x77, 0xCA, 0xA6, + 0x7B, 0xE4, 0xBA, 0x89, 0x52, 0xFF, 0xB4, 0x7E, 0x45, 0xFF, 0xB0, 0x76, 0x3B, 0xFF, 0xAF, 0x74, + 0x37, 0xFF, 0xB1, 0x76, 0x36, 0xFF, 0xB3, 0x78, 0x37, 0xFF, 0xB4, 0x7B, 0x38, 0xFF, 0xB6, 0x7D, + 0x39, 0xFF, 0xB8, 0x7F, 0x3A, 0xFF, 0xB9, 0x80, 0x3A, 0xFF, 0xBA, 0x81, 0x3A, 0xFF, 0xBB, 0x82, + 0x3A, 0xFF, 0xBC, 0x83, 0x3A, 0xFF, 0xBC, 0x84, 0x3B, 0xFF, 0xBD, 0x84, 0x3B, 0xFF, 0xBE, 0x85, + 0x3B, 0xFF, 0xBE, 0x85, 0x3B, 0xFF, 0xBD, 0x85, 0x3B, 0xFF, 0xBD, 0x85, 0x3B, 0xFF, 0xBD, 0x85, + 0x3B, 0xFF, 0xBD, 0x85, 0x3B, 0xFF, 0xBD, 0x85, 0x3B, 0xFF, 0xBD, 0x85, 0x3B, 0xFF, 0xBD, 0x85, + 0x3B, 0xFF, 0xBD, 0x85, 0x3B, 0xFF, 0xBE, 0x85, 0x3B, 0xFF, 0xBE, 0x85, 0x3C, 0xFF, 0xBF, 0x88, + 0x40, 0xFF, 0xC4, 0x8F, 0x4C, 0xFF, 0xC6, 0x95, 0x56, 0xFF, 0xC7, 0x97, 0x5A, 0xFF, 0xC7, 0x98, + 0x5A, 0xFF, 0xC7, 0x99, 0x5A, 0xFF, 0xC7, 0x98, 0x5A, 0xFF, 0xC6, 0x97, 0x5A, 0xFF, 0xC4, 0x96, + 0x59, 0xFF, 0xC0, 0x95, 0x5A, 0xFF, 0xBB, 0x98, 0x65, 0xFF, 0xC6, 0xB0, 0x95, 0xFF, 0xD9, 0xD3, + 0xCA, 0xFF, 0xE0, 0xDD, 0xDB, 0xFF, 0xDC, 0xDD, 0xDD, 0xFF, 0xDC, 0xDD, 0xDD, 0xFF, 0xDB, 0xDE, + 0xDE, 0xFF, 0xDD, 0xDE, 0xDE, 0xFF, 0xDD, 0xDE, 0xDF, 0xFF, 0xDE, 0xDE, 0xDF, 0xFF, 0xDD, 0xDE, + 0xDE, 0xFF, 0xDD, 0xDE, 0xDF, 0xFF, 0xDD, 0xDE, 0xDE, 0xFF, 0xE1, 0xE0, 0xE0, 0xFF, 0xCD, 0xCB, + 0xC5, 0xFF, 0xB1, 0xAA, 0x91, 0xFF, 0xDE, 0xDB, 0xCE, 0xFF, 0xC5, 0xBC, 0xA5, 0xFF, 0xA7, 0x9B, + 0x7E, 0xFF, 0xBE, 0xB4, 0x9F, 0xFF, 0xDD, 0xDA, 0xD3, 0xFF, 0xE4, 0xE4, 0xE5, 0xFF, 0xDB, 0xDC, + 0xDB, 0xFF, 0xD4, 0xD0, 0xC9, 0xFF, 0xD6, 0xD5, 0xCE, 0xFF, 0xDD, 0xDF, 0xDD, 0xFF, 0xDB, 0xDC, + 0xDB, 0xFF, 0xD9, 0xDA, 0xDA, 0xFF, 0xD8, 0xDA, 0xDA, 0xFF, 0xDA, 0xDA, 0xDB, 0xFF, 0xDC, 0xDD, + 0xDD, 0xFF, 0xDE, 0xDF, 0xDF, 0xFF, 0xDF, 0xE1, 0xE1, 0xFF, 0xE0, 0xE1, 0xE1, 0xFF, 0xE0, 0xE2, + 0xE2, 0xFF, 0xE2, 0xE3, 0xE2, 0xFF, 0xE1, 0xE3, 0xE2, 0xFF, 0xD9, 0xD9, 0xD5, 0xFF, 0xBC, 0xB6, + 0xA2, 0xFF, 0xA1, 0x94, 0x74, 0xFF, 0x9B, 0x90, 0x71, 0xFF, 0xB9, 0xB3, 0x9E, 0xFF, 0xDC, 0xD9, + 0xD3, 0xFF, 0xDF, 0xDD, 0xDD, 0xFF, 0xDC, 0xDB, 0xDC, 0xFF, 0xDF, 0xDD, 0xDE, 0xFF, 0xE1, 0xDD, + 0xD5, 0xFF, 0xC7, 0xBA, 0xA5, 0xFF, 0xA1, 0x84, 0x55, 0xFF, 0xA1, 0x77, 0x36, 0xFF, 0xAE, 0x7D, + 0x38, 0xFF, 0xB7, 0x81, 0x3B, 0xFF, 0xBB, 0x83, 0x3B, 0xFF, 0xBD, 0x84, 0x3B, 0xFF, 0xBD, 0x84, + 0x3B, 0xFF, 0xBD, 0x85, 0x3B, 0xFF, 0xBD, 0x85, 0x3B, 0xFF, 0xBD, 0x85, 0x3B, 0xFF, 0xBD, 0x85, + 0x3B, 0xFF, 0xBD, 0x85, 0x3B, 0xFF, 0xBC, 0x85, 0x3B, 0xFF, 0xBD, 0x85, 0x3B, 0xFF, 0xBE, 0x85, + 0x3B, 0xFF, 0xBE, 0x85, 0x3B, 0xFF, 0xBD, 0x85, 0x3B, 0xFF, 0xBC, 0x84, 0x3A, 0xFF, 0xBC, 0x83, + 0x3A, 0xFF, 0xBB, 0x83, 0x3A, 0xFF, 0xBA, 0x83, 0x3D, 0xFF, 0xBE, 0x89, 0x46, 0xFF, 0xC4, 0x93, + 0x55, 0xFF, 0xD2, 0xAF, 0x84, 0xFD, 0xDB, 0xBE, 0x9B, 0xC1, 0xDE, 0xC1, 0x9F, 0x1E, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDD, 0xC4, 0xA5, 0x09, 0xDF, 0xC3, 0xA3, 0x68, 0xCE, 0xAA, + 0x80, 0xDE, 0xBD, 0x8C, 0x54, 0xFE, 0xB8, 0x82, 0x49, 0xFF, 0xB2, 0x79, 0x3D, 0xFF, 0xB0, 0x76, + 0x38, 0xFF, 0xB3, 0x78, 0x38, 0xFF, 0xB4, 0x7A, 0x39, 0xFF, 0xB6, 0x7D, 0x3A, 0xFF, 0xB7, 0x7F, + 0x3B, 0xFF, 0xB9, 0x81, 0x3B, 0xFF, 0xBA, 0x82, 0x3C, 0xFF, 0xBC, 0x83, 0x3C, 0xFF, 0xBD, 0x84, + 0x3C, 0xFF, 0xBE, 0x85, 0x3C, 0xFF, 0xBE, 0x86, 0x3D, 0xFF, 0xBF, 0x86, 0x3D, 0xFF, 0xBF, 0x87, + 0x3D, 0xFF, 0xBF, 0x87, 0x3D, 0xFF, 0xBE, 0x87, 0x3D, 0xFF, 0xBF, 0x87, 0x3D, 0xFF, 0xBE, 0x87, + 0x3D, 0xFF, 0xBF, 0x87, 0x3D, 0xFF, 0xBE, 0x87, 0x3D, 0xFF, 0xBE, 0x87, 0x3D, 0xFF, 0xBE, 0x87, + 0x3D, 0xFF, 0xBF, 0x87, 0x3D, 0xFF, 0xBF, 0x87, 0x3D, 0xFF, 0xC0, 0x8A, 0x42, 0xFF, 0xC5, 0x91, + 0x4D, 0xFF, 0xC7, 0x98, 0x59, 0xFF, 0xC9, 0x9A, 0x5D, 0xFF, 0xCA, 0x9B, 0x5D, 0xFF, 0xC9, 0x9B, + 0x5D, 0xFF, 0xC9, 0x9B, 0x5D, 0xFF, 0xC9, 0x9B, 0x5D, 0xFF, 0xC9, 0x9A, 0x5D, 0xFF, 0xC8, 0x9A, + 0x5D, 0xFF, 0xC6, 0x99, 0x5E, 0xFF, 0xC0, 0x98, 0x5F, 0xFF, 0xBF, 0x9D, 0x6E, 0xFF, 0xCA, 0xB9, + 0x9E, 0xFF, 0xDD, 0xD8, 0xD2, 0xFF, 0xDF, 0xDE, 0xDE, 0xFF, 0xDE, 0xDF, 0xE0, 0xFF, 0xDD, 0xDF, + 0xE0, 0xFF, 0xDF, 0xE0, 0xE0, 0xFF, 0xE0, 0xE1, 0xE1, 0xFF, 0xE0, 0xE0, 0xE1, 0xFF, 0xDF, 0xE0, + 0xE1, 0xFF, 0xDF, 0xE0, 0xE0, 0xFF, 0xDF, 0xE0, 0xE0, 0xFF, 0xE3, 0xE3, 0xE1, 0xFF, 0xC8, 0xC5, + 0xBD, 0xFF, 0xBC, 0xB5, 0x9F, 0xFF, 0xE6, 0xE4, 0xE1, 0xFF, 0xE0, 0xDD, 0xD4, 0xFF, 0xBC, 0xB4, + 0x9F, 0xFF, 0xAC, 0xA0, 0x81, 0xFF, 0xB9, 0xAD, 0x94, 0xFF, 0xDB, 0xD6, 0xCE, 0xFF, 0xE2, 0xE1, + 0xE1, 0xFF, 0xE2, 0xE1, 0xE0, 0xFF, 0xDD, 0xDE, 0xDD, 0xFF, 0xDC, 0xDD, 0xDD, 0xFF, 0xDB, 0xDC, + 0xDC, 0xFF, 0xDA, 0xDB, 0xDB, 0xFF, 0xDA, 0xDA, 0xDB, 0xFF, 0xD9, 0xDA, 0xDA, 0xFF, 0xDA, 0xDB, + 0xDB, 0xFF, 0xDC, 0xDD, 0xDE, 0xFF, 0xDE, 0xE0, 0xE0, 0xFF, 0xE0, 0xE1, 0xE2, 0xFF, 0xE0, 0xE2, + 0xE2, 0xFF, 0xE1, 0xE2, 0xE2, 0xFF, 0xE2, 0xE3, 0xE2, 0xFF, 0xE1, 0xE3, 0xE3, 0xFF, 0xDF, 0xDF, + 0xDE, 0xFF, 0xC9, 0xC4, 0xB6, 0xFF, 0xA4, 0x98, 0x7C, 0xFF, 0x99, 0x8E, 0x6E, 0xFF, 0xB9, 0xB3, + 0xA0, 0xFF, 0xDC, 0xDA, 0xD4, 0xFF, 0xDD, 0xDD, 0xDD, 0xFF, 0xDE, 0xDE, 0xE0, 0xFF, 0xE2, 0xE0, + 0xDF, 0xFF, 0xDE, 0xD7, 0xCE, 0xFF, 0xB0, 0x99, 0x75, 0xFF, 0xA5, 0x7A, 0x3C, 0xFF, 0xB1, 0x7F, + 0x3D, 0xFF, 0xB8, 0x82, 0x3D, 0xFF, 0xBC, 0x84, 0x3C, 0xFF, 0xBF, 0x86, 0x3C, 0xFF, 0xBF, 0x86, + 0x3D, 0xFF, 0xBF, 0x86, 0x3D, 0xFF, 0xBE, 0x87, 0x3D, 0xFF, 0xBE, 0x87, 0x3D, 0xFF, 0xBE, 0x87, + 0x3D, 0xFF, 0xBF, 0x87, 0x3D, 0xFF, 0xBE, 0x87, 0x3D, 0xFF, 0xBF, 0x87, 0x3D, 0xFF, 0xBF, 0x87, + 0x3D, 0xFF, 0xBF, 0x87, 0x3D, 0xFF, 0xBE, 0x87, 0x3D, 0xFF, 0xBE, 0x86, 0x3C, 0xFF, 0xBD, 0x85, + 0x3B, 0xFF, 0xBD, 0x84, 0x3C, 0xFF, 0xBC, 0x85, 0x3F, 0xFF, 0xC1, 0x8D, 0x4B, 0xFF, 0xC7, 0x98, + 0x5B, 0xFF, 0xD3, 0xB2, 0x88, 0xF9, 0xDC, 0xC0, 0x9D, 0xB2, 0xDF, 0xC4, 0xA3, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xC5, 0xA6, 0x06, 0xDF, 0xC3, 0xA3, 0x55, 0xD1, 0xAD, + 0x83, 0xD8, 0xC0, 0x90, 0x58, 0xFF, 0xBB, 0x86, 0x4D, 0xFF, 0xB5, 0x7C, 0x41, 0xFF, 0xB3, 0x79, + 0x3B, 0xFF, 0xB5, 0x7A, 0x3A, 0xFF, 0xB6, 0x7C, 0x3B, 0xFF, 0xB7, 0x7F, 0x3C, 0xFF, 0xBA, 0x81, + 0x3D, 0xFF, 0xBB, 0x83, 0x3D, 0xFF, 0xBC, 0x84, 0x3D, 0xFF, 0xBD, 0x85, 0x3E, 0xFF, 0xBE, 0x86, + 0x3E, 0xFF, 0xBF, 0x87, 0x3F, 0xFF, 0xBF, 0x88, 0x3F, 0xFF, 0xC0, 0x89, 0x3F, 0xFF, 0xC0, 0x89, + 0x3F, 0xFF, 0xC1, 0x89, 0x3F, 0xFF, 0xC1, 0x89, 0x3F, 0xFF, 0xC1, 0x89, 0x3F, 0xFF, 0xC0, 0x89, + 0x3F, 0xFF, 0xC1, 0x89, 0x3F, 0xFF, 0xC0, 0x89, 0x3F, 0xFF, 0xC1, 0x89, 0x3F, 0xFF, 0xC1, 0x89, + 0x3F, 0xFF, 0xC1, 0x89, 0x3F, 0xFF, 0xC1, 0x8B, 0x42, 0xFF, 0xC5, 0x92, 0x4E, 0xFF, 0xCA, 0x9B, + 0x5C, 0xFF, 0xCA, 0x9D, 0x62, 0xFF, 0xCB, 0x9E, 0x61, 0xFF, 0xCC, 0x9E, 0x61, 0xFF, 0xCB, 0x9E, + 0x61, 0xFF, 0xCC, 0x9E, 0x61, 0xFF, 0xCB, 0x9E, 0x61, 0xFF, 0xCB, 0x9E, 0x61, 0xFF, 0xCA, 0x9D, + 0x60, 0xFF, 0xCA, 0x9D, 0x61, 0xFF, 0xC8, 0x9C, 0x60, 0xFF, 0xC3, 0x9B, 0x63, 0xFF, 0xC0, 0xA2, + 0x74, 0xFF, 0xD0, 0xC0, 0xAB, 0xFF, 0xDF, 0xDC, 0xD6, 0xFF, 0xE4, 0xE2, 0xE3, 0xFF, 0xE1, 0xE1, + 0xE2, 0xFF, 0xE1, 0xE2, 0xE2, 0xFF, 0xE1, 0xE2, 0xE3, 0xFF, 0xE1, 0xE2, 0xE2, 0xFF, 0xE1, 0xE2, + 0xE3, 0xFF, 0xE2, 0xE2, 0xE2, 0xFF, 0xE1, 0xE1, 0xDF, 0xFF, 0xE3, 0xE2, 0xE0, 0xFF, 0xC9, 0xC5, + 0xB9, 0xFF, 0xBE, 0xB8, 0xA1, 0xFF, 0xE4, 0xE4, 0xE0, 0xFF, 0xE8, 0xE5, 0xE4, 0xFF, 0xE0, 0xDE, + 0xD8, 0xFF, 0xBB, 0xB4, 0xA3, 0xFF, 0xA8, 0x9D, 0x7F, 0xFF, 0xB6, 0xAA, 0x92, 0xFF, 0xDA, 0xD6, + 0xCE, 0xFF, 0xE1, 0xE0, 0xE1, 0xFF, 0xDE, 0xDE, 0xDD, 0xFF, 0xDE, 0xDE, 0xDE, 0xFF, 0xDD, 0xDD, + 0xDE, 0xFF, 0xDC, 0xDD, 0xDD, 0xFF, 0xDB, 0xDC, 0xDD, 0xFF, 0xDB, 0xDC, 0xDC, 0xFF, 0xDA, 0xDB, + 0xDA, 0xFF, 0xDB, 0xDB, 0xDC, 0xFF, 0xDD, 0xDE, 0xDE, 0xFF, 0xDF, 0xE0, 0xE0, 0xFF, 0xE0, 0xE2, + 0xE1, 0xFF, 0xE1, 0xE2, 0xE2, 0xFF, 0xE3, 0xE4, 0xE3, 0xFF, 0xE3, 0xE4, 0xE3, 0xFF, 0xE2, 0xE4, + 0xE3, 0xFF, 0xE3, 0xE3, 0xE1, 0xFF, 0xD2, 0xCE, 0xC4, 0xFF, 0xAD, 0xA3, 0x8A, 0xFF, 0x9A, 0x92, + 0x75, 0xFF, 0xB9, 0xB4, 0xA0, 0xFF, 0xDC, 0xD9, 0xD5, 0xFF, 0xE1, 0xE0, 0xDF, 0xFF, 0xE1, 0xE0, + 0xDE, 0xFF, 0xE1, 0xDC, 0xD7, 0xFF, 0xB8, 0xA5, 0x82, 0xFF, 0xA9, 0x7C, 0x3F, 0xFF, 0xB4, 0x82, + 0x40, 0xFF, 0xB9, 0x84, 0x3F, 0xFF, 0xBE, 0x87, 0x3E, 0xFF, 0xC1, 0x88, 0x3F, 0xFF, 0xC1, 0x89, + 0x3F, 0xFF, 0xC1, 0x89, 0x3F, 0xFF, 0xC0, 0x89, 0x3F, 0xFF, 0xC0, 0x89, 0x3F, 0xFF, 0xC0, 0x89, + 0x3F, 0xFF, 0xC1, 0x89, 0x3F, 0xFF, 0xC0, 0x89, 0x3F, 0xFF, 0xC1, 0x89, 0x3F, 0xFF, 0xC1, 0x89, + 0x3F, 0xFF, 0xC1, 0x89, 0x3F, 0xFF, 0xC0, 0x89, 0x3F, 0xFF, 0xBF, 0x88, 0x3E, 0xFF, 0xBF, 0x87, + 0x3D, 0xFF, 0xBF, 0x87, 0x3E, 0xFF, 0xBE, 0x88, 0x42, 0xFF, 0xC3, 0x91, 0x50, 0xFF, 0xC9, 0x9C, + 0x60, 0xFF, 0xD5, 0xB5, 0x8B, 0xF3, 0xDE, 0xC5, 0xA2, 0xA0, 0xE2, 0xC9, 0xA9, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xC6, 0xA7, 0x05, 0xDE, 0xC2, 0xA2, 0x40, 0xD3, 0xAF, + 0x84, 0xCC, 0xC4, 0x95, 0x60, 0xFC, 0xBE, 0x8A, 0x52, 0xFF, 0xB8, 0x80, 0x44, 0xFF, 0xB5, 0x7C, + 0x3D, 0xFF, 0xB6, 0x7C, 0x3C, 0xFF, 0xB7, 0x7E, 0x3D, 0xFF, 0xBA, 0x81, 0x3E, 0xFF, 0xBB, 0x83, + 0x3F, 0xFF, 0xBD, 0x85, 0x3F, 0xFF, 0xBE, 0x86, 0x3F, 0xFF, 0xBF, 0x87, 0x3F, 0xFF, 0xC0, 0x88, + 0x40, 0xFF, 0xC1, 0x89, 0x40, 0xFF, 0xC1, 0x8A, 0x41, 0xFF, 0xC2, 0x8B, 0x41, 0xFF, 0xC2, 0x8B, + 0x41, 0xFF, 0xC3, 0x8B, 0x41, 0xFF, 0xC2, 0x8B, 0x41, 0xFF, 0xC3, 0x8B, 0x41, 0xFF, 0xC2, 0x8A, + 0x41, 0xFF, 0xC2, 0x8A, 0x40, 0xFF, 0xC2, 0x8B, 0x40, 0xFF, 0xC2, 0x8B, 0x41, 0xFF, 0xC3, 0x8B, + 0x41, 0xFF, 0xC3, 0x8C, 0x43, 0xFF, 0xC6, 0x92, 0x4C, 0xFF, 0xCA, 0x9B, 0x5B, 0xFF, 0xCC, 0xA0, + 0x64, 0xFF, 0xCD, 0xA1, 0x65, 0xFF, 0xCD, 0xA0, 0x65, 0xFF, 0xCE, 0xA0, 0x64, 0xFF, 0xCD, 0xA0, + 0x64, 0xFF, 0xCE, 0xA1, 0x64, 0xFF, 0xCD, 0xA0, 0x64, 0xFF, 0xCD, 0xA0, 0x64, 0xFF, 0xCD, 0xA0, + 0x64, 0xFF, 0xCC, 0xA0, 0x63, 0xFF, 0xCC, 0xA0, 0x63, 0xFF, 0xC9, 0x9E, 0x64, 0xFF, 0xC3, 0x9D, + 0x68, 0xFF, 0xC5, 0xA8, 0x7E, 0xFF, 0xD4, 0xC8, 0xB6, 0xFF, 0xE2, 0xE0, 0xDB, 0xFF, 0xE3, 0xE3, + 0xE3, 0xFF, 0xE2, 0xE3, 0xE4, 0xFF, 0xE2, 0xE4, 0xE4, 0xFF, 0xE3, 0xE4, 0xE4, 0xFF, 0xE3, 0xE4, + 0xE5, 0xFF, 0xE3, 0xE4, 0xE4, 0xFF, 0xE3, 0xE3, 0xE2, 0xFF, 0xE4, 0xE3, 0xE2, 0xFF, 0xCE, 0xCA, + 0xBE, 0xFF, 0xBE, 0xB6, 0x9C, 0xFF, 0xDD, 0xDB, 0xD5, 0xFF, 0xE4, 0xE2, 0xE2, 0xFF, 0xE7, 0xE5, + 0xE5, 0xFF, 0xDD, 0xDB, 0xD6, 0xFF, 0xBF, 0xB7, 0xA1, 0xFF, 0xB1, 0xA3, 0x85, 0xFF, 0xBE, 0xB4, + 0x9E, 0xFF, 0xDA, 0xD5, 0xCD, 0xFF, 0xDE, 0xDC, 0xDB, 0xFF, 0xDB, 0xDA, 0xD9, 0xFF, 0xDB, 0xDB, + 0xDA, 0xFF, 0xDE, 0xDE, 0xDD, 0xFF, 0xDD, 0xDE, 0xDD, 0xFF, 0xDD, 0xDE, 0xDE, 0xFF, 0xDD, 0xDE, + 0xDD, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDD, 0xDD, 0xFF, 0xDD, 0xDE, 0xDF, 0xFF, 0xDF, 0xE0, + 0xE0, 0xFF, 0xE1, 0xE2, 0xE2, 0xFF, 0xE3, 0xE3, 0xE4, 0xFF, 0xE3, 0xE4, 0xE4, 0xFF, 0xE3, 0xE4, + 0xE4, 0xFF, 0xE3, 0xE4, 0xE5, 0xFF, 0xE4, 0xE3, 0xE3, 0xFF, 0xDD, 0xD9, 0xD3, 0xFF, 0xB3, 0xAC, + 0x96, 0xFF, 0x9E, 0x94, 0x76, 0xFF, 0xBB, 0xB3, 0x9F, 0xFF, 0xDD, 0xDA, 0xD3, 0xFF, 0xE4, 0xE2, + 0xDE, 0xFF, 0xE4, 0xDF, 0xD9, 0xFF, 0xBC, 0xA7, 0x81, 0xFF, 0xAC, 0x7D, 0x40, 0xFF, 0xB7, 0x85, + 0x43, 0xFF, 0xBB, 0x86, 0x40, 0xFF, 0xBF, 0x89, 0x40, 0xFF, 0xC2, 0x8B, 0x41, 0xFF, 0xC2, 0x8B, + 0x41, 0xFF, 0xC2, 0x8B, 0x41, 0xFF, 0xC2, 0x8B, 0x41, 0xFF, 0xC2, 0x8B, 0x41, 0xFF, 0xC2, 0x8B, + 0x41, 0xFF, 0xC2, 0x8B, 0x41, 0xFF, 0xC2, 0x8B, 0x41, 0xFF, 0xC3, 0x8B, 0x41, 0xFF, 0xC2, 0x8B, + 0x41, 0xFF, 0xC2, 0x8B, 0x41, 0xFF, 0xC1, 0x8A, 0x40, 0xFF, 0xC1, 0x8A, 0x40, 0xFF, 0xC1, 0x89, + 0x3F, 0xFF, 0xC0, 0x89, 0x41, 0xFF, 0xBF, 0x8A, 0x44, 0xFF, 0xC7, 0x95, 0x57, 0xFF, 0xCB, 0x9F, + 0x66, 0xFF, 0xD7, 0xB8, 0x8F, 0xEB, 0xE2, 0xCA, 0xAA, 0x8B, 0xE5, 0xCD, 0xAF, 0x11, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE2, 0xC8, 0xAA, 0x04, 0xDF, 0xC2, 0x9E, 0x2E, 0xD4, 0xB1, + 0x88, 0xB6, 0xC6, 0x9A, 0x67, 0xFA, 0xC1, 0x8F, 0x57, 0xFF, 0xBA, 0x83, 0x48, 0xFF, 0xB7, 0x7F, + 0x40, 0xFF, 0xB8, 0x7F, 0x3E, 0xFF, 0xBA, 0x80, 0x3F, 0xFF, 0xBB, 0x83, 0x40, 0xFF, 0xBD, 0x85, + 0x41, 0xFF, 0xBE, 0x87, 0x41, 0xFF, 0xC0, 0x88, 0x42, 0xFF, 0xC1, 0x8A, 0x42, 0xFF, 0xC1, 0x8A, + 0x42, 0xFF, 0xC2, 0x8B, 0x42, 0xFF, 0xC2, 0x8C, 0x43, 0xFF, 0xC3, 0x8D, 0x43, 0xFF, 0xC3, 0x8D, + 0x43, 0xFF, 0xC4, 0x8D, 0x43, 0xFF, 0xC4, 0x8D, 0x43, 0xFF, 0xC4, 0x8D, 0x43, 0xFF, 0xC4, 0x8D, + 0x43, 0xFF, 0xC4, 0x8D, 0x43, 0xFF, 0xC4, 0x8D, 0x43, 0xFF, 0xC4, 0x8D, 0x43, 0xFF, 0xC4, 0x8E, + 0x43, 0xFF, 0xC7, 0x91, 0x4B, 0xFF, 0xCB, 0x9C, 0x5B, 0xFF, 0xCD, 0xA1, 0x65, 0xFF, 0xCE, 0xA2, + 0x68, 0xFF, 0xCF, 0xA3, 0x68, 0xFF, 0xCF, 0xA3, 0x68, 0xFF, 0xCF, 0xA3, 0x68, 0xFF, 0xCF, 0xA3, + 0x68, 0xFF, 0xCF, 0xA3, 0x68, 0xFF, 0xCF, 0xA3, 0x68, 0xFF, 0xCF, 0xA3, 0x68, 0xFF, 0xCF, 0xA3, + 0x67, 0xFF, 0xCF, 0xA3, 0x67, 0xFF, 0xCE, 0xA2, 0x67, 0xFF, 0xCC, 0xA1, 0x67, 0xFF, 0xC9, 0xA1, + 0x67, 0xFF, 0xC5, 0xA0, 0x6C, 0xFF, 0xC7, 0xAD, 0x85, 0xFF, 0xD9, 0xCF, 0xC1, 0xFF, 0xE4, 0xE3, + 0xDF, 0xFF, 0xE6, 0xE6, 0xE7, 0xFF, 0xE5, 0xE6, 0xE6, 0xFF, 0xE5, 0xE6, 0xE6, 0xFF, 0xE4, 0xE6, + 0xE7, 0xFF, 0xE5, 0xE6, 0xE6, 0xFF, 0xE5, 0xE6, 0xE5, 0xFF, 0xE7, 0xE5, 0xE4, 0xFF, 0xD1, 0xCC, + 0xC4, 0xFF, 0xBA, 0xAC, 0x8F, 0xFF, 0xC6, 0xBC, 0xA6, 0xFF, 0xD4, 0xCE, 0xBF, 0xFF, 0xDB, 0xD8, + 0xD6, 0xFF, 0xE3, 0xE3, 0xE2, 0xFF, 0xDF, 0xDF, 0xD6, 0xFF, 0xC3, 0xB8, 0xA2, 0xFF, 0xB6, 0xAB, + 0x8E, 0xFF, 0xBE, 0xB3, 0x9B, 0xFF, 0xCB, 0xC1, 0xB2, 0xFF, 0xCC, 0xC6, 0xBA, 0xFF, 0xD0, 0xCE, + 0xC5, 0xFF, 0xDA, 0xDB, 0xD7, 0xFF, 0xDD, 0xDF, 0xDF, 0xFF, 0xDE, 0xE0, 0xE0, 0xFF, 0xDF, 0xE0, + 0xE0, 0xFF, 0xDF, 0xDF, 0xE0, 0xFF, 0xDD, 0xDE, 0xDE, 0xFF, 0xDD, 0xDE, 0xDE, 0xFF, 0xDD, 0xDE, + 0xDE, 0xFF, 0xDF, 0xE0, 0xE0, 0xFF, 0xE2, 0xE3, 0xE3, 0xFF, 0xE4, 0xE4, 0xE4, 0xFF, 0xE4, 0xE5, + 0xE5, 0xFF, 0xE4, 0xE5, 0xE5, 0xFF, 0xE3, 0xE5, 0xE5, 0xFF, 0xE5, 0xE5, 0xE5, 0xFF, 0xE0, 0xDF, + 0xD9, 0xFF, 0xC1, 0xBB, 0xA9, 0xFF, 0xA6, 0x9C, 0x7F, 0xFF, 0xBD, 0xB4, 0x9D, 0xFF, 0xE1, 0xDC, + 0xD2, 0xFF, 0xE5, 0xDC, 0xD0, 0xFF, 0xB9, 0x9F, 0x74, 0xFF, 0xB1, 0x83, 0x43, 0xFF, 0xBB, 0x89, + 0x44, 0xFF, 0xBE, 0x8A, 0x43, 0xFF, 0xC2, 0x8C, 0x43, 0xFF, 0xC4, 0x8D, 0x43, 0xFF, 0xC3, 0x8D, + 0x43, 0xFF, 0xC4, 0x8D, 0x43, 0xFF, 0xC4, 0x8D, 0x43, 0xFF, 0xC4, 0x8D, 0x43, 0xFF, 0xC4, 0x8D, + 0x43, 0xFF, 0xC4, 0x8D, 0x43, 0xFF, 0xC4, 0x8D, 0x43, 0xFF, 0xC4, 0x8D, 0x43, 0xFF, 0xC4, 0x8D, + 0x43, 0xFF, 0xC4, 0x8D, 0x43, 0xFF, 0xC3, 0x8C, 0x43, 0xFF, 0xC3, 0x8B, 0x42, 0xFF, 0xC2, 0x8A, + 0x41, 0xFF, 0xC1, 0x8B, 0x43, 0xFF, 0xC1, 0x8D, 0x48, 0xFF, 0xCA, 0x99, 0x5C, 0xFF, 0xCE, 0xA4, + 0x6B, 0xFF, 0xDA, 0xBA, 0x93, 0xE1, 0xE5, 0xCF, 0xB2, 0x72, 0xE8, 0xD2, 0xB5, 0x0D, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE9, 0xD2, 0xB6, 0x04, 0xE6, 0xCC, 0xAF, 0x23, 0xD9, 0xB9, + 0x92, 0x9D, 0xCA, 0xA1, 0x6F, 0xF4, 0xC4, 0x94, 0x5D, 0xFF, 0xBC, 0x87, 0x4C, 0xFF, 0xB9, 0x81, + 0x43, 0xFF, 0xBA, 0x81, 0x41, 0xFF, 0xBB, 0x82, 0x40, 0xFF, 0xBD, 0x85, 0x42, 0xFF, 0xBE, 0x87, + 0x42, 0xFF, 0xC0, 0x89, 0x43, 0xFF, 0xC2, 0x8A, 0x44, 0xFF, 0xC3, 0x8B, 0x44, 0xFF, 0xC3, 0x8C, + 0x44, 0xFF, 0xC3, 0x8D, 0x44, 0xFF, 0xC4, 0x8E, 0x45, 0xFF, 0xC5, 0x8F, 0x45, 0xFF, 0xC5, 0x8F, + 0x45, 0xFF, 0xC5, 0x8F, 0x45, 0xFF, 0xC5, 0x8F, 0x45, 0xFF, 0xC5, 0x8E, 0x45, 0xFF, 0xC5, 0x8E, + 0x45, 0xFF, 0xC5, 0x8F, 0x45, 0xFF, 0xC5, 0x8F, 0x45, 0xFF, 0xC6, 0x8F, 0x45, 0xFF, 0xC6, 0x90, + 0x48, 0xFF, 0xCA, 0x98, 0x56, 0xFF, 0xCF, 0xA2, 0x66, 0xFF, 0xD0, 0xA5, 0x6A, 0xFF, 0xCF, 0xA5, + 0x6A, 0xFF, 0xD0, 0xA5, 0x6A, 0xFF, 0xD0, 0xA5, 0x6B, 0xFF, 0xD0, 0xA5, 0x6B, 0xFF, 0xD0, 0xA5, + 0x6B, 0xFF, 0xD0, 0xA5, 0x6B, 0xFF, 0xD0, 0xA5, 0x6A, 0xFF, 0xD0, 0xA5, 0x6B, 0xFF, 0xD0, 0xA5, + 0x6B, 0xFF, 0xD0, 0xA5, 0x6A, 0xFF, 0xD0, 0xA5, 0x6A, 0xFF, 0xCF, 0xA4, 0x6A, 0xFF, 0xCE, 0xA5, + 0x6A, 0xFF, 0xCB, 0xA3, 0x6B, 0xFF, 0xC6, 0xA3, 0x71, 0xFF, 0xCD, 0xB5, 0x91, 0xFF, 0xDD, 0xD7, + 0xCB, 0xFF, 0xE6, 0xE6, 0xE3, 0xFF, 0xE7, 0xE8, 0xE7, 0xFF, 0xE6, 0xE8, 0xE8, 0xFF, 0xE6, 0xE8, + 0xE8, 0xFF, 0xE6, 0xE7, 0xE7, 0xFF, 0xE7, 0xE8, 0xE8, 0xFF, 0xE9, 0xE8, 0xE6, 0xFF, 0xCC, 0xC7, + 0xBE, 0xFF, 0xAF, 0x9F, 0x7F, 0xFF, 0xAD, 0x9A, 0x75, 0xFF, 0xB2, 0xA0, 0x7B, 0xFF, 0xBF, 0xB3, + 0x9B, 0xFF, 0xDF, 0xD9, 0xD0, 0xFF, 0xE7, 0xE7, 0xE5, 0xFF, 0xD6, 0xD0, 0xC3, 0xFF, 0xBA, 0xAC, + 0x91, 0xFF, 0xB0, 0xA0, 0x7D, 0xFF, 0xB0, 0x9F, 0x77, 0xFF, 0xB5, 0xA5, 0x81, 0xFF, 0xC1, 0xB5, + 0x9D, 0xFF, 0xD8, 0xD3, 0xCA, 0xFF, 0xDE, 0xDE, 0xDF, 0xFF, 0xDE, 0xE0, 0xE0, 0xFF, 0xDF, 0xE1, + 0xE2, 0xFF, 0xE0, 0xE1, 0xE2, 0xFF, 0xE0, 0xE1, 0xE1, 0xFF, 0xDF, 0xDF, 0xE0, 0xFF, 0xDE, 0xDF, + 0xDF, 0xFF, 0xDE, 0xDF, 0xE0, 0xFF, 0xE1, 0xE2, 0xE2, 0xFF, 0xE3, 0xE3, 0xE4, 0xFF, 0xE4, 0xE5, + 0xE6, 0xFF, 0xE5, 0xE6, 0xE6, 0xFF, 0xE5, 0xE7, 0xE7, 0xFF, 0xE5, 0xE7, 0xE7, 0xFF, 0xE8, 0xE9, + 0xE8, 0xFF, 0xE5, 0xE3, 0xDE, 0xFF, 0xCE, 0xC8, 0xB7, 0xFF, 0xB9, 0xAD, 0x91, 0xFF, 0xC4, 0xBC, + 0xA3, 0xFF, 0xD9, 0xCA, 0xAD, 0xFF, 0xB6, 0x94, 0x5E, 0xFF, 0xB6, 0x86, 0x43, 0xFF, 0xBC, 0x8B, + 0x44, 0xFF, 0xC0, 0x8C, 0x44, 0xFF, 0xC3, 0x8E, 0x45, 0xFF, 0xC5, 0x8F, 0x45, 0xFF, 0xC5, 0x8F, + 0x45, 0xFF, 0xC5, 0x8F, 0x45, 0xFF, 0xC5, 0x8F, 0x45, 0xFF, 0xC5, 0x8F, 0x45, 0xFF, 0xC5, 0x8F, + 0x45, 0xFF, 0xC5, 0x8F, 0x45, 0xFF, 0xC5, 0x8F, 0x45, 0xFF, 0xC5, 0x8F, 0x45, 0xFF, 0xC5, 0x8F, + 0x45, 0xFF, 0xC5, 0x8E, 0x45, 0xFF, 0xC4, 0x8E, 0x44, 0xFF, 0xC4, 0x8D, 0x44, 0xFF, 0xC3, 0x8D, + 0x43, 0xFF, 0xC3, 0x8D, 0x45, 0xFF, 0xC4, 0x91, 0x4B, 0xFF, 0xCB, 0x9C, 0x63, 0xFF, 0xD0, 0xA8, + 0x72, 0xFF, 0xDD, 0xBE, 0x98, 0xD5, 0xE8, 0xD2, 0xB7, 0x58, 0xEA, 0xD3, 0xB8, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEF, 0xE4, 0xD8, 0x02, 0xF9, 0xEE, 0xE1, 0x15, 0xE1, 0xC1, + 0x9D, 0x86, 0xCE, 0xA5, 0x74, 0xED, 0xC6, 0x98, 0x64, 0xFE, 0xBF, 0x8B, 0x51, 0xFF, 0xBB, 0x84, + 0x46, 0xFF, 0xBC, 0x84, 0x44, 0xFF, 0xBD, 0x85, 0x44, 0xFF, 0xBF, 0x87, 0x44, 0xFF, 0xC1, 0x8A, + 0x45, 0xFF, 0xC2, 0x8B, 0x46, 0xFF, 0xC3, 0x8C, 0x46, 0xFF, 0xC4, 0x8D, 0x46, 0xFF, 0xC4, 0x8E, + 0x47, 0xFF, 0xC5, 0x8F, 0x47, 0xFF, 0xC6, 0x90, 0x48, 0xFF, 0xC7, 0x91, 0x48, 0xFF, 0xC6, 0x91, + 0x48, 0xFF, 0xC7, 0x91, 0x48, 0xFF, 0xC7, 0x91, 0x48, 0xFF, 0xC7, 0x91, 0x48, 0xFF, 0xC7, 0x91, + 0x48, 0xFF, 0xC7, 0x91, 0x47, 0xFF, 0xC6, 0x91, 0x47, 0xFF, 0xC8, 0x92, 0x48, 0xFF, 0xC8, 0x96, + 0x51, 0xFF, 0xCF, 0xA2, 0x65, 0xFF, 0xD1, 0xA8, 0x6D, 0xFF, 0xD2, 0xA9, 0x6F, 0xFF, 0xD1, 0xA8, + 0x6E, 0xFF, 0xD2, 0xA8, 0x6E, 0xFF, 0xD1, 0xA8, 0x6E, 0xFF, 0xD2, 0xA8, 0x6E, 0xFF, 0xD2, 0xA8, + 0x6E, 0xFF, 0xD2, 0xA8, 0x6E, 0xFF, 0xD2, 0xA8, 0x6E, 0xFF, 0xD2, 0xA8, 0x6E, 0xFF, 0xD1, 0xA8, + 0x6E, 0xFF, 0xD2, 0xA8, 0x6E, 0xFF, 0xD2, 0xA8, 0x6E, 0xFF, 0xD2, 0xA8, 0x6E, 0xFF, 0xD1, 0xA8, + 0x6E, 0xFF, 0xCF, 0xA7, 0x6E, 0xFF, 0xCB, 0xA5, 0x6E, 0xFF, 0xC8, 0xA7, 0x74, 0xFF, 0xCE, 0xBA, + 0x9A, 0xFF, 0xE0, 0xDB, 0xD3, 0xFF, 0xE8, 0xE8, 0xE5, 0xFF, 0xE9, 0xE9, 0xE9, 0xFF, 0xE7, 0xEA, + 0xEA, 0xFF, 0xE7, 0xE9, 0xEA, 0xFF, 0xE8, 0xEA, 0xEA, 0xFF, 0xEA, 0xEA, 0xE7, 0xFF, 0xCA, 0xC6, + 0xB6, 0xFF, 0x9F, 0x91, 0x6C, 0xFF, 0xA6, 0x95, 0x6A, 0xFF, 0xA9, 0x98, 0x6F, 0xFF, 0xAA, 0x9C, + 0x7D, 0xFF, 0xD2, 0xCC, 0xBF, 0xFF, 0xE5, 0xE4, 0xE1, 0xFF, 0xDA, 0xD8, 0xD0, 0xFF, 0xB7, 0xAA, + 0x91, 0xFF, 0xA8, 0x96, 0x6F, 0xFF, 0xA7, 0x95, 0x6B, 0xFF, 0xAB, 0x98, 0x70, 0xFF, 0xB6, 0xA8, + 0x8B, 0xFF, 0xD6, 0xCF, 0xC6, 0xFF, 0xE1, 0xDF, 0xE0, 0xFF, 0xDF, 0xE0, 0xE2, 0xFF, 0xDF, 0xE1, + 0xE2, 0xFF, 0xE1, 0xE1, 0xE2, 0xFF, 0xE1, 0xE2, 0xE3, 0xFF, 0xE1, 0xE2, 0xE2, 0xFF, 0xE0, 0xE1, + 0xE1, 0xFF, 0xE0, 0xE1, 0xE1, 0xFF, 0xE0, 0xE1, 0xE1, 0xFF, 0xE2, 0xE2, 0xE2, 0xFF, 0xE4, 0xE5, + 0xE5, 0xFF, 0xE5, 0xE6, 0xE6, 0xFF, 0xE6, 0xE7, 0xE7, 0xFF, 0xE7, 0xE8, 0xE9, 0xFF, 0xE6, 0xE7, + 0xE8, 0xFF, 0xE8, 0xE8, 0xE9, 0xFF, 0xE7, 0xE5, 0xE1, 0xFF, 0xDC, 0xD6, 0xCD, 0xFF, 0xC7, 0xBD, + 0xA0, 0xFF, 0xC1, 0xA7, 0x7C, 0xFF, 0xB5, 0x8D, 0x52, 0xFF, 0xB6, 0x87, 0x43, 0xFF, 0xBE, 0x8D, + 0x45, 0xFF, 0xC3, 0x8F, 0x47, 0xFF, 0xC5, 0x90, 0x47, 0xFF, 0xC7, 0x91, 0x48, 0xFF, 0xC7, 0x91, + 0x48, 0xFF, 0xC7, 0x91, 0x48, 0xFF, 0xC7, 0x91, 0x48, 0xFF, 0xC7, 0x91, 0x48, 0xFF, 0xC6, 0x91, + 0x48, 0xFF, 0xC7, 0x91, 0x48, 0xFF, 0xC6, 0x91, 0x48, 0xFF, 0xC7, 0x91, 0x48, 0xFF, 0xC7, 0x91, + 0x48, 0xFF, 0xC6, 0x91, 0x48, 0xFF, 0xC6, 0x91, 0x48, 0xFF, 0xC6, 0x90, 0x47, 0xFF, 0xC5, 0x8F, + 0x46, 0xFF, 0xC5, 0x90, 0x48, 0xFF, 0xC7, 0x95, 0x51, 0xFF, 0xCE, 0xA1, 0x69, 0xFF, 0xD5, 0xAE, + 0x79, 0xFE, 0xE2, 0xC4, 0x9D, 0xBD, 0xEC, 0xD3, 0xB9, 0x3C, 0xE9, 0xD3, 0xB9, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF7, 0xE9, 0xD8, 0x0E, 0xD9, 0xB8, + 0x8E, 0x65, 0xD0, 0xA8, 0x77, 0xE0, 0xCA, 0x9E, 0x6A, 0xFE, 0xC3, 0x8F, 0x57, 0xFF, 0xBE, 0x87, + 0x49, 0xFF, 0xBF, 0x86, 0x46, 0xFF, 0xBF, 0x87, 0x46, 0xFF, 0xC1, 0x8A, 0x46, 0xFF, 0xC2, 0x8C, + 0x47, 0xFF, 0xC4, 0x8E, 0x48, 0xFF, 0xC5, 0x8E, 0x48, 0xFF, 0xC5, 0x8F, 0x48, 0xFF, 0xC6, 0x90, + 0x49, 0xFF, 0xC7, 0x92, 0x49, 0xFF, 0xC8, 0x92, 0x4A, 0xFF, 0xC9, 0x93, 0x4A, 0xFF, 0xC8, 0x93, + 0x4A, 0xFF, 0xC9, 0x93, 0x4A, 0xFF, 0xC8, 0x93, 0x4A, 0xFF, 0xC8, 0x93, 0x4A, 0xFF, 0xC8, 0x93, + 0x49, 0xFF, 0xC9, 0x93, 0x49, 0xFF, 0xC8, 0x93, 0x49, 0xFF, 0xC9, 0x95, 0x4E, 0xFF, 0xCD, 0x9F, + 0x5D, 0xFF, 0xD2, 0xA8, 0x6D, 0xFF, 0xD3, 0xAB, 0x72, 0xFF, 0xD4, 0xAB, 0x72, 0xFF, 0xD3, 0xAB, + 0x71, 0xFF, 0xD4, 0xAA, 0x71, 0xFF, 0xD3, 0xAA, 0x71, 0xFF, 0xD3, 0xAA, 0x71, 0xFF, 0xD3, 0xAA, + 0x71, 0xFF, 0xD3, 0xAA, 0x71, 0xFF, 0xD3, 0xAA, 0x71, 0xFF, 0xD3, 0xAA, 0x71, 0xFF, 0xD3, 0xAA, + 0x71, 0xFF, 0xD3, 0xAA, 0x71, 0xFF, 0xD3, 0xAB, 0x71, 0xFF, 0xD4, 0xAB, 0x71, 0xFF, 0xD4, 0xAB, + 0x71, 0xFF, 0xD2, 0xAA, 0x71, 0xFF, 0xCF, 0xA9, 0x70, 0xFF, 0xCD, 0xA7, 0x71, 0xFF, 0xCB, 0xAB, + 0x7B, 0xFF, 0xD3, 0xC1, 0xA7, 0xFF, 0xE3, 0xE0, 0xDA, 0xFF, 0xE9, 0xEA, 0xE8, 0xFF, 0xEA, 0xEB, + 0xEA, 0xFF, 0xE9, 0xEB, 0xEB, 0xFF, 0xE9, 0xEB, 0xEA, 0xFF, 0xE7, 0xE8, 0xE7, 0xFF, 0xD1, 0xD0, + 0xC4, 0xFF, 0xA4, 0x9A, 0x7A, 0xFF, 0xA3, 0x95, 0x6F, 0xFF, 0xA4, 0x94, 0x73, 0xFF, 0xB4, 0xAA, + 0x96, 0xFF, 0xDC, 0xDA, 0xD2, 0xFF, 0xE5, 0xE5, 0xE4, 0xFF, 0xDC, 0xDC, 0xD8, 0xFF, 0xBD, 0xB9, + 0xA7, 0xFF, 0xA3, 0x94, 0x71, 0xFF, 0xA3, 0x8F, 0x6A, 0xFF, 0xA6, 0x95, 0x6E, 0xFF, 0xA9, 0x9D, + 0x7C, 0xFF, 0xD4, 0xD0, 0xC7, 0xFF, 0xE2, 0xE1, 0xE1, 0xFF, 0xE0, 0xE1, 0xE2, 0xFF, 0xE0, 0xE2, + 0xE2, 0xFF, 0xE1, 0xE2, 0xE2, 0xFF, 0xE2, 0xE4, 0xE3, 0xFF, 0xE3, 0xE4, 0xE4, 0xFF, 0xE3, 0xE4, + 0xE4, 0xFF, 0xE2, 0xE3, 0xE3, 0xFF, 0xE1, 0xE2, 0xE2, 0xFF, 0xE2, 0xE3, 0xE3, 0xFF, 0xE4, 0xE4, + 0xE5, 0xFF, 0xE5, 0xE5, 0xE6, 0xFF, 0xE6, 0xE7, 0xE8, 0xFF, 0xE7, 0xE8, 0xE9, 0xFF, 0xE6, 0xE8, + 0xEA, 0xFF, 0xE7, 0xE8, 0xEA, 0xFF, 0xEB, 0xEA, 0xEA, 0xFF, 0xE1, 0xDF, 0xD9, 0xFF, 0xC5, 0xB9, + 0x9C, 0xFF, 0xB6, 0x99, 0x66, 0xFF, 0xB3, 0x8E, 0x53, 0xFF, 0xB5, 0x89, 0x44, 0xFF, 0xBE, 0x8E, + 0x47, 0xFF, 0xC3, 0x90, 0x49, 0xFF, 0xC5, 0x92, 0x49, 0xFF, 0xC7, 0x93, 0x4A, 0xFF, 0xC8, 0x93, + 0x4A, 0xFF, 0xC9, 0x93, 0x4A, 0xFF, 0xC8, 0x93, 0x4A, 0xFF, 0xC8, 0x93, 0x4A, 0xFF, 0xC8, 0x93, + 0x4A, 0xFF, 0xC9, 0x93, 0x4A, 0xFF, 0xC8, 0x93, 0x4A, 0xFF, 0xC9, 0x93, 0x4A, 0xFF, 0xC8, 0x93, + 0x4A, 0xFF, 0xC8, 0x93, 0x4A, 0xFF, 0xC7, 0x93, 0x49, 0xFF, 0xC8, 0x92, 0x49, 0xFF, 0xC7, 0x92, + 0x49, 0xFF, 0xC7, 0x93, 0x4C, 0xFF, 0xC9, 0x99, 0x57, 0xFF, 0xD2, 0xA7, 0x70, 0xFF, 0xD9, 0xB3, + 0x80, 0xF8, 0xDF, 0xC4, 0x9F, 0xA2, 0xE4, 0xCE, 0xB5, 0x2C, 0xE1, 0xD0, 0xB8, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xC0, 0x9A, 0x05, 0xD9, 0xB8, + 0x8B, 0x47, 0xD6, 0xB0, 0x82, 0xD0, 0xCE, 0xA4, 0x70, 0xFD, 0xC7, 0x95, 0x5D, 0xFF, 0xC2, 0x8C, + 0x4F, 0xFF, 0xC2, 0x8A, 0x4A, 0xFF, 0xC1, 0x8A, 0x48, 0xFF, 0xC3, 0x8C, 0x48, 0xFF, 0xC4, 0x8E, + 0x49, 0xFF, 0xC5, 0x90, 0x4A, 0xFF, 0xC6, 0x91, 0x4B, 0xFF, 0xC7, 0x92, 0x4B, 0xFF, 0xC8, 0x93, + 0x4B, 0xFF, 0xC9, 0x94, 0x4C, 0xFF, 0xCA, 0x95, 0x4C, 0xFF, 0xCB, 0x95, 0x4C, 0xFF, 0xCA, 0x95, + 0x4C, 0xFF, 0xCB, 0x96, 0x4C, 0xFF, 0xCA, 0x95, 0x4C, 0xFF, 0xCB, 0x95, 0x4C, 0xFF, 0xCA, 0x96, + 0x4C, 0xFF, 0xCB, 0x96, 0x4C, 0xFF, 0xCA, 0x96, 0x4D, 0xFF, 0xCD, 0x9C, 0x57, 0xFF, 0xD3, 0xA8, + 0x6B, 0xFF, 0xD5, 0xAD, 0x74, 0xFF, 0xD5, 0xAD, 0x75, 0xFF, 0xD5, 0xAE, 0x75, 0xFF, 0xD5, 0xAE, + 0x75, 0xFF, 0xD5, 0xAE, 0x75, 0xFF, 0xD5, 0xAD, 0x75, 0xFF, 0xD6, 0xAE, 0x75, 0xFF, 0xD5, 0xAE, + 0x75, 0xFF, 0xD6, 0xAE, 0x75, 0xFF, 0xD5, 0xAE, 0x75, 0xFF, 0xD6, 0xAE, 0x75, 0xFF, 0xD5, 0xAE, + 0x75, 0xFF, 0xD6, 0xAE, 0x75, 0xFF, 0xD5, 0xAD, 0x75, 0xFF, 0xD5, 0xAE, 0x75, 0xFF, 0xD5, 0xAD, + 0x75, 0xFF, 0xD5, 0xAD, 0x75, 0xFF, 0xD3, 0xAD, 0x74, 0xFF, 0xD1, 0xAA, 0x74, 0xFF, 0xCD, 0xAA, + 0x76, 0xFF, 0xCE, 0xAF, 0x82, 0xFF, 0xD7, 0xC7, 0xB1, 0xFF, 0xE6, 0xE4, 0xDF, 0xFF, 0xEC, 0xEC, + 0xEA, 0xFF, 0xEB, 0xEC, 0xEC, 0xFF, 0xEA, 0xEC, 0xEC, 0xFF, 0xEA, 0xEA, 0xEC, 0xFF, 0xE6, 0xE7, + 0xE5, 0xFF, 0xC9, 0xC5, 0xB6, 0xFF, 0xBC, 0xB3, 0x9D, 0xFF, 0xC4, 0xBC, 0xAC, 0xFF, 0xDD, 0xDB, + 0xD0, 0xFF, 0xE3, 0xE4, 0xE2, 0xFF, 0xE3, 0xE3, 0xE3, 0xFF, 0xE1, 0xE0, 0xE0, 0xFF, 0xD5, 0xD5, + 0xCC, 0xFF, 0xB9, 0xB3, 0x9D, 0xFF, 0xB1, 0xA5, 0x87, 0xFF, 0xAF, 0xA2, 0x81, 0xFF, 0xA5, 0x9B, + 0x7B, 0xFF, 0xD3, 0xCF, 0xC6, 0xFF, 0xE2, 0xE2, 0xE3, 0xFF, 0xE2, 0xE3, 0xE3, 0xFF, 0xE2, 0xE3, + 0xE3, 0xFF, 0xE3, 0xE3, 0xE4, 0xFF, 0xE3, 0xE4, 0xE4, 0xFF, 0xE4, 0xE5, 0xE5, 0xFF, 0xE4, 0xE5, + 0xE5, 0xFF, 0xE5, 0xE5, 0xE6, 0xFF, 0xE4, 0xE5, 0xE5, 0xFF, 0xE4, 0xE5, 0xE5, 0xFF, 0xE4, 0xE4, + 0xE4, 0xFF, 0xE4, 0xE5, 0xE5, 0xFF, 0xE5, 0xE7, 0xE7, 0xFF, 0xE7, 0xE8, 0xE9, 0xFF, 0xE7, 0xE8, + 0xEA, 0xFF, 0xE9, 0xEA, 0xEB, 0xFF, 0xE9, 0xE9, 0xE6, 0xFF, 0xD4, 0xD1, 0xC2, 0xFF, 0xBB, 0xAE, + 0x8A, 0xFF, 0xBC, 0xA6, 0x7A, 0xFF, 0xB3, 0x94, 0x5E, 0xFF, 0xB2, 0x89, 0x49, 0xFF, 0xBA, 0x8D, + 0x47, 0xFF, 0xC1, 0x91, 0x49, 0xFF, 0xC4, 0x92, 0x4A, 0xFF, 0xC7, 0x93, 0x4C, 0xFF, 0xC9, 0x95, + 0x4C, 0xFF, 0xCA, 0x95, 0x4C, 0xFF, 0xCA, 0x95, 0x4C, 0xFF, 0xCA, 0x96, 0x4C, 0xFF, 0xCA, 0x96, + 0x4C, 0xFF, 0xCB, 0x96, 0x4C, 0xFF, 0xCA, 0x96, 0x4C, 0xFF, 0xCB, 0x96, 0x4C, 0xFF, 0xCA, 0x96, + 0x4C, 0xFF, 0xCA, 0x95, 0x4C, 0xFF, 0xC9, 0x95, 0x4C, 0xFF, 0xCA, 0x95, 0x4B, 0xFF, 0xC9, 0x94, + 0x4C, 0xFF, 0xCA, 0x96, 0x50, 0xFF, 0xCC, 0x9E, 0x5D, 0xFF, 0xD5, 0xAD, 0x77, 0xFF, 0xDC, 0xB8, + 0x86, 0xEE, 0xD7, 0xBC, 0x9A, 0x86, 0xC6, 0xBC, 0xAF, 0x1C, 0xD3, 0xC8, 0xB9, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD5, 0xB6, 0x8C, 0x02, 0xDE, 0xBF, + 0x97, 0x2C, 0xDC, 0xB9, 0x90, 0xB4, 0xD3, 0xAA, 0x77, 0xF6, 0xCC, 0x9C, 0x63, 0xFF, 0xC6, 0x91, + 0x55, 0xFF, 0xC4, 0x8C, 0x4D, 0xFF, 0xC3, 0x8C, 0x4A, 0xFF, 0xC5, 0x8D, 0x4A, 0xFF, 0xC5, 0x8F, + 0x4B, 0xFF, 0xC7, 0x92, 0x4C, 0xFF, 0xC8, 0x93, 0x4D, 0xFF, 0xC9, 0x94, 0x4D, 0xFF, 0xCA, 0x95, + 0x4D, 0xFF, 0xCB, 0x96, 0x4D, 0xFF, 0xCC, 0x97, 0x4E, 0xFF, 0xCC, 0x97, 0x4E, 0xFF, 0xCC, 0x98, + 0x4E, 0xFF, 0xCD, 0x98, 0x4E, 0xFF, 0xCC, 0x97, 0x4D, 0xFF, 0xCC, 0x97, 0x4D, 0xFF, 0xCC, 0x98, + 0x4D, 0xFF, 0xCD, 0x98, 0x4E, 0xFF, 0xCC, 0x99, 0x51, 0xFF, 0xD2, 0xA3, 0x62, 0xFF, 0xD6, 0xAE, + 0x75, 0xFF, 0xD8, 0xB0, 0x78, 0xFF, 0xD7, 0xB0, 0x78, 0xFF, 0xD7, 0xB0, 0x78, 0xFF, 0xD7, 0xB0, + 0x78, 0xFF, 0xD8, 0xB0, 0x78, 0xFF, 0xD7, 0xB0, 0x78, 0xFF, 0xD7, 0xB0, 0x78, 0xFF, 0xD7, 0xB0, + 0x77, 0xFF, 0xD7, 0xB0, 0x78, 0xFF, 0xD7, 0xB0, 0x78, 0xFF, 0xD8, 0xB0, 0x78, 0xFF, 0xD7, 0xB0, + 0x78, 0xFF, 0xD8, 0xB0, 0x78, 0xFF, 0xD7, 0xB0, 0x78, 0xFF, 0xD7, 0xB0, 0x78, 0xFF, 0xD7, 0xB0, + 0x78, 0xFF, 0xD7, 0xB0, 0x78, 0xFF, 0xD7, 0xAF, 0x78, 0xFF, 0xD5, 0xAE, 0x77, 0xFF, 0xD1, 0xAD, + 0x77, 0xFF, 0xD1, 0xAD, 0x7B, 0xFF, 0xD3, 0xB5, 0x89, 0xFF, 0xDB, 0xCE, 0xBC, 0xFF, 0xE9, 0xE8, + 0xE4, 0xFF, 0xED, 0xED, 0xED, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xEB, 0xEC, 0xED, 0xFF, 0xED, 0xED, + 0xED, 0xFF, 0xEA, 0xE8, 0xE7, 0xFF, 0xE5, 0xE4, 0xE2, 0xFF, 0xE4, 0xE3, 0xE3, 0xFF, 0xE7, 0xE8, + 0xE7, 0xFF, 0xE6, 0xE7, 0xE8, 0xFF, 0xE7, 0xE7, 0xE8, 0xFF, 0xE7, 0xE6, 0xE7, 0xFF, 0xE5, 0xE5, + 0xE4, 0xFF, 0xDD, 0xDC, 0xD8, 0xFF, 0xD4, 0xD3, 0xCD, 0xFF, 0xCF, 0xCC, 0xC2, 0xFF, 0xBD, 0xBA, + 0xA9, 0xFF, 0xD7, 0xD7, 0xD1, 0xFF, 0xE3, 0xE4, 0xE5, 0xFF, 0xE4, 0xE5, 0xE5, 0xFF, 0xE4, 0xE5, + 0xE5, 0xFF, 0xE4, 0xE5, 0xE5, 0xFF, 0xE5, 0xE6, 0xE6, 0xFF, 0xE5, 0xE6, 0xE6, 0xFF, 0xE6, 0xE6, + 0xE7, 0xFF, 0xE6, 0xE7, 0xE7, 0xFF, 0xE6, 0xE7, 0xE7, 0xFF, 0xE6, 0xE6, 0xE7, 0xFF, 0xE5, 0xE6, + 0xE6, 0xFF, 0xE5, 0xE6, 0xE6, 0xFF, 0xE6, 0xE7, 0xE8, 0xFF, 0xE7, 0xE8, 0xE9, 0xFF, 0xE9, 0xEA, + 0xEB, 0xFF, 0xEB, 0xEC, 0xEC, 0xFF, 0xEB, 0xEC, 0xE7, 0xFF, 0xCD, 0xC7, 0xB7, 0xFF, 0xB3, 0xA7, + 0x88, 0xFF, 0xC5, 0xB3, 0x8F, 0xFF, 0xC2, 0xAA, 0x7C, 0xFF, 0xB4, 0x91, 0x5A, 0xFF, 0xB5, 0x8D, + 0x4D, 0xFF, 0xBB, 0x8F, 0x4A, 0xFF, 0xC1, 0x92, 0x4B, 0xFF, 0xC5, 0x93, 0x4C, 0xFF, 0xC8, 0x96, + 0x4D, 0xFF, 0xCA, 0x97, 0x4D, 0xFF, 0xCB, 0x97, 0x4E, 0xFF, 0xCC, 0x98, 0x4E, 0xFF, 0xCC, 0x98, + 0x4E, 0xFF, 0xCC, 0x98, 0x4E, 0xFF, 0xCC, 0x98, 0x4E, 0xFF, 0xCD, 0x98, 0x4E, 0xFF, 0xCC, 0x98, + 0x4E, 0xFF, 0xCC, 0x97, 0x4E, 0xFF, 0xCB, 0x97, 0x4D, 0xFF, 0xCC, 0x97, 0x4E, 0xFF, 0xCB, 0x96, + 0x4F, 0xFF, 0xCC, 0x9A, 0x55, 0xFF, 0xCF, 0xA3, 0x64, 0xFF, 0xDA, 0xB2, 0x7F, 0xFD, 0xE0, 0xBE, + 0x8F, 0xDE, 0xDE, 0xC2, 0x9C, 0x64, 0xC3, 0xB6, 0xA5, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE5, 0xC9, + 0xA5, 0x1A, 0xE1, 0xC1, 0x9B, 0x8E, 0xD5, 0xAF, 0x7D, 0xEA, 0xCE, 0xA2, 0x6A, 0xFF, 0xCA, 0x97, + 0x5C, 0xFF, 0xC6, 0x90, 0x51, 0xFF, 0xC5, 0x8E, 0x4D, 0xFF, 0xC7, 0x90, 0x4D, 0xFF, 0xC8, 0x92, + 0x4D, 0xFF, 0xC9, 0x94, 0x4F, 0xFF, 0xCA, 0x95, 0x4F, 0xFF, 0xCB, 0x96, 0x4F, 0xFF, 0xCC, 0x97, + 0x4F, 0xFF, 0xCD, 0x98, 0x50, 0xFF, 0xCD, 0x99, 0x50, 0xFF, 0xCE, 0x9A, 0x50, 0xFF, 0xCE, 0x9A, + 0x50, 0xFF, 0xCF, 0x9A, 0x50, 0xFF, 0xCE, 0x9A, 0x50, 0xFF, 0xCE, 0x9A, 0x4F, 0xFF, 0xCE, 0x9A, + 0x4F, 0xFF, 0xCF, 0x9B, 0x51, 0xFF, 0xCF, 0x9F, 0x57, 0xFF, 0xD6, 0xAB, 0x6F, 0xFF, 0xD9, 0xB2, + 0x7A, 0xFF, 0xDA, 0xB3, 0x7C, 0xFF, 0xDA, 0xB3, 0x7B, 0xFF, 0xDA, 0xB3, 0x7B, 0xFF, 0xD9, 0xB3, + 0x7B, 0xFF, 0xDA, 0xB3, 0x7B, 0xFF, 0xD9, 0xB3, 0x7B, 0xFF, 0xDA, 0xB3, 0x7B, 0xFF, 0xD9, 0xB3, + 0x7B, 0xFF, 0xDA, 0xB3, 0x7B, 0xFF, 0xD9, 0xB3, 0x7B, 0xFF, 0xDA, 0xB3, 0x7B, 0xFF, 0xD9, 0xB3, + 0x7B, 0xFF, 0xDA, 0xB3, 0x7B, 0xFF, 0xD9, 0xB3, 0x7B, 0xFF, 0xDA, 0xB3, 0x7B, 0xFF, 0xD9, 0xB3, + 0x7B, 0xFF, 0xD9, 0xB3, 0x7B, 0xFF, 0xDA, 0xB2, 0x7B, 0xFF, 0xD9, 0xB2, 0x7B, 0xFF, 0xD6, 0xB1, + 0x7A, 0xFF, 0xD3, 0xAF, 0x7B, 0xFF, 0xD0, 0xAF, 0x7E, 0xFF, 0xD1, 0xB7, 0x8E, 0xFF, 0xDA, 0xD2, + 0xC1, 0xFF, 0xEC, 0xEA, 0xE7, 0xFF, 0xEE, 0xEE, 0xED, 0xFF, 0xED, 0xEE, 0xEE, 0xFF, 0xEC, 0xED, + 0xEE, 0xFF, 0xED, 0xEF, 0xEE, 0xFF, 0xEB, 0xEC, 0xEC, 0xFF, 0xEC, 0xEC, 0xED, 0xFF, 0xEA, 0xEB, + 0xEB, 0xFF, 0xEA, 0xEB, 0xEB, 0xFF, 0xEA, 0xEB, 0xEC, 0xFF, 0xE9, 0xEA, 0xEA, 0xFF, 0xE9, 0xEA, + 0xEA, 0xFF, 0xE8, 0xE8, 0xE8, 0xFF, 0xE5, 0xE5, 0xE5, 0xFF, 0xE3, 0xE2, 0xE1, 0xFF, 0xDD, 0xDE, + 0xDA, 0xFF, 0xE1, 0xE4, 0xE2, 0xFF, 0xE5, 0xE6, 0xE7, 0xFF, 0xE6, 0xE7, 0xE8, 0xFF, 0xE6, 0xE8, + 0xE8, 0xFF, 0xE6, 0xE7, 0xE7, 0xFF, 0xE5, 0xE6, 0xE6, 0xFF, 0xE6, 0xE7, 0xE7, 0xFF, 0xE6, 0xE7, + 0xE7, 0xFF, 0xE7, 0xE8, 0xE8, 0xFF, 0xE7, 0xE8, 0xE8, 0xFF, 0xE8, 0xE8, 0xE9, 0xFF, 0xE6, 0xE8, + 0xE7, 0xFF, 0xE7, 0xE7, 0xE7, 0xFF, 0xE8, 0xE8, 0xE9, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xEB, 0xEC, + 0xEC, 0xFF, 0xEE, 0xEE, 0xED, 0xFF, 0xF0, 0xF0, 0xEC, 0xFF, 0xD6, 0xD3, 0xC5, 0xFF, 0xB5, 0xAC, + 0x91, 0xFF, 0xC5, 0xB9, 0x9B, 0xFF, 0xCE, 0xC0, 0x9F, 0xFF, 0xBF, 0xA9, 0x81, 0xFF, 0xB3, 0x92, + 0x5B, 0xFF, 0xB3, 0x8D, 0x4E, 0xFF, 0xB8, 0x8F, 0x4B, 0xFF, 0xBF, 0x92, 0x4D, 0xFF, 0xC5, 0x95, + 0x4E, 0xFF, 0xC9, 0x98, 0x4F, 0xFF, 0xCB, 0x99, 0x50, 0xFF, 0xCD, 0x99, 0x50, 0xFF, 0xCD, 0x99, + 0x50, 0xFF, 0xCE, 0x9A, 0x50, 0xFF, 0xCE, 0x9A, 0x50, 0xFF, 0xCF, 0x9A, 0x50, 0xFF, 0xCF, 0x9A, + 0x50, 0xFF, 0xCE, 0x9A, 0x50, 0xFF, 0xCE, 0x99, 0x4F, 0xFF, 0xCE, 0x99, 0x50, 0xFF, 0xCC, 0x99, + 0x52, 0xFF, 0xCF, 0x9F, 0x5A, 0xFF, 0xD4, 0xA9, 0x6C, 0xFF, 0xDD, 0xB8, 0x88, 0xFC, 0xE0, 0xC1, + 0x98, 0xCA, 0xDE, 0xC3, 0x9F, 0x43, 0xDE, 0xC2, 0x9F, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE9, 0xCC, + 0xA9, 0x0E, 0xE2, 0xC3, 0x9D, 0x64, 0xD8, 0xB4, 0x83, 0xD9, 0xD2, 0xA8, 0x71, 0xFF, 0xCE, 0x9D, + 0x62, 0xFE, 0xC8, 0x94, 0x55, 0xFF, 0xC7, 0x91, 0x4F, 0xFF, 0xC9, 0x92, 0x4E, 0xFF, 0xC9, 0x93, + 0x4F, 0xFF, 0xCB, 0x96, 0x50, 0xFF, 0xCB, 0x97, 0x50, 0xFF, 0xCD, 0x98, 0x51, 0xFF, 0xCE, 0x99, + 0x51, 0xFF, 0xCF, 0x9A, 0x51, 0xFF, 0xCF, 0x9B, 0x52, 0xFF, 0xD0, 0x9C, 0x52, 0xFF, 0xD0, 0x9C, + 0x52, 0xFF, 0xD0, 0x9C, 0x52, 0xFF, 0xCF, 0x9C, 0x51, 0xFF, 0xD0, 0x9C, 0x51, 0xFF, 0xD0, 0x9C, + 0x52, 0xFF, 0xD1, 0x9D, 0x54, 0xFF, 0xD2, 0xA4, 0x5E, 0xFF, 0xD9, 0xB1, 0x77, 0xFF, 0xDB, 0xB5, + 0x7E, 0xFF, 0xDB, 0xB6, 0x7F, 0xFF, 0xDB, 0xB5, 0x7E, 0xFF, 0xDC, 0xB5, 0x7E, 0xFF, 0xDB, 0xB5, + 0x7E, 0xFF, 0xDB, 0xB5, 0x7E, 0xFF, 0xDB, 0xB5, 0x7D, 0xFF, 0xDB, 0xB5, 0x7E, 0xFF, 0xDB, 0xB5, + 0x7D, 0xFF, 0xDB, 0xB5, 0x7D, 0xFF, 0xDB, 0xB5, 0x7D, 0xFF, 0xDB, 0xB5, 0x7D, 0xFF, 0xDB, 0xB5, + 0x7D, 0xFF, 0xDB, 0xB5, 0x7E, 0xFF, 0xDB, 0xB5, 0x7D, 0xFF, 0xDB, 0xB5, 0x7E, 0xFF, 0xDB, 0xB5, + 0x7E, 0xFF, 0xDB, 0xB5, 0x7E, 0xFF, 0xDB, 0xB5, 0x7E, 0xFF, 0xDB, 0xB5, 0x7D, 0xFF, 0xDA, 0xB4, + 0x7E, 0xFF, 0xD8, 0xB3, 0x7D, 0xFF, 0xD4, 0xB2, 0x7D, 0xFF, 0xD4, 0xB3, 0x82, 0xFF, 0xD6, 0xBC, + 0x93, 0xFF, 0xE1, 0xD6, 0xC8, 0xFF, 0xED, 0xED, 0xE9, 0xFF, 0xEE, 0xED, 0xED, 0xFF, 0xED, 0xEE, + 0xEF, 0xFF, 0xED, 0xEE, 0xEF, 0xFF, 0xEE, 0xEF, 0xEE, 0xFF, 0xEE, 0xEF, 0xEF, 0xFF, 0xED, 0xEF, + 0xEF, 0xFF, 0xED, 0xED, 0xEE, 0xFF, 0xEB, 0xED, 0xED, 0xFF, 0xEB, 0xEC, 0xEC, 0xFF, 0xEB, 0xEC, + 0xEC, 0xFF, 0xEA, 0xEB, 0xEB, 0xFF, 0xEA, 0xEB, 0xE9, 0xFF, 0xE9, 0xE9, 0xE9, 0xFF, 0xE7, 0xE8, + 0xE8, 0xFF, 0xE7, 0xE8, 0xE9, 0xFF, 0xE8, 0xE9, 0xE9, 0xFF, 0xE8, 0xE9, 0xE9, 0xFF, 0xE8, 0xE9, + 0xE9, 0xFF, 0xE8, 0xE9, 0xE9, 0xFF, 0xE7, 0xE8, 0xE8, 0xFF, 0xE7, 0xE8, 0xE8, 0xFF, 0xE8, 0xE8, + 0xE9, 0xFF, 0xE8, 0xE9, 0xE9, 0xFF, 0xE8, 0xE9, 0xE9, 0xFF, 0xE9, 0xE9, 0xE9, 0xFF, 0xE9, 0xE9, + 0xE9, 0xFF, 0xE9, 0xE9, 0xE9, 0xFF, 0xE9, 0xE9, 0xEA, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xED, 0xED, + 0xEC, 0xFF, 0xEE, 0xEF, 0xED, 0xFF, 0xF0, 0xF0, 0xEF, 0xFF, 0xED, 0xEC, 0xE9, 0xFF, 0xD3, 0xCF, + 0xBF, 0xFF, 0xBF, 0xB7, 0x9F, 0xFF, 0xC9, 0xBF, 0xA5, 0xFF, 0xD1, 0xC5, 0xA9, 0xFF, 0xC1, 0xB0, + 0x8A, 0xFF, 0xB2, 0x96, 0x62, 0xFF, 0xB0, 0x8C, 0x51, 0xFF, 0xB8, 0x90, 0x4F, 0xFF, 0xC1, 0x95, + 0x4F, 0xFF, 0xC8, 0x98, 0x50, 0xFF, 0xCB, 0x9A, 0x51, 0xFF, 0xCE, 0x9B, 0x52, 0xFF, 0xCF, 0x9C, + 0x52, 0xFF, 0xD0, 0x9C, 0x52, 0xFF, 0xD0, 0x9C, 0x52, 0xFF, 0xD1, 0x9C, 0x52, 0xFF, 0xD0, 0x9B, + 0x51, 0xFF, 0xD0, 0x9B, 0x51, 0xFF, 0xD0, 0x9B, 0x51, 0xFF, 0xCF, 0x9B, 0x53, 0xFF, 0xCF, 0x9C, + 0x56, 0xFF, 0xD2, 0xA3, 0x61, 0xFF, 0xD8, 0xAF, 0x75, 0xFF, 0xDD, 0xBB, 0x8E, 0xF9, 0xDE, 0xC1, + 0x9B, 0xA4, 0xDC, 0xC2, 0xA1, 0x29, 0xDB, 0xC3, 0xA0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0xC7, + 0xA1, 0x05, 0xE0, 0xBF, 0x97, 0x3F, 0xD9, 0xB8, 0x8A, 0xBE, 0xD6, 0xAD, 0x78, 0xFD, 0xD1, 0xA2, + 0x68, 0xFE, 0xCC, 0x98, 0x5B, 0xFF, 0xC9, 0x94, 0x53, 0xFF, 0xCA, 0x94, 0x51, 0xFF, 0xCB, 0x96, + 0x51, 0xFF, 0xCC, 0x97, 0x51, 0xFF, 0xCD, 0x99, 0x52, 0xFF, 0xCE, 0x9A, 0x53, 0xFF, 0xCF, 0x9B, + 0x53, 0xFF, 0xD0, 0x9D, 0x54, 0xFF, 0xD0, 0x9D, 0x54, 0xFF, 0xD1, 0x9E, 0x54, 0xFF, 0xD1, 0x9E, + 0x54, 0xFF, 0xD2, 0x9F, 0x54, 0xFF, 0xD1, 0x9F, 0x54, 0xFF, 0xD2, 0x9E, 0x54, 0xFF, 0xD1, 0x9E, + 0x53, 0xFF, 0xD3, 0xA1, 0x57, 0xFF, 0xD6, 0xAC, 0x69, 0xFF, 0xDC, 0xB6, 0x7E, 0xFF, 0xDC, 0xB8, + 0x82, 0xFF, 0xDD, 0xB8, 0x82, 0xFF, 0xDC, 0xB8, 0x81, 0xFF, 0xDD, 0xB8, 0x81, 0xFF, 0xDC, 0xB8, + 0x81, 0xFF, 0xDD, 0xB8, 0x81, 0xFF, 0xDD, 0xB8, 0x81, 0xFF, 0xDD, 0xB8, 0x81, 0xFF, 0xDD, 0xB8, + 0x81, 0xFF, 0xDD, 0xB8, 0x81, 0xFF, 0xDC, 0xB8, 0x81, 0xFF, 0xDD, 0xB8, 0x81, 0xFF, 0xDD, 0xB8, + 0x81, 0xFF, 0xDD, 0xB8, 0x81, 0xFF, 0xDD, 0xB8, 0x81, 0xFF, 0xDD, 0xB8, 0x81, 0xFF, 0xDC, 0xB8, + 0x81, 0xFF, 0xDD, 0xB8, 0x81, 0xFF, 0xDC, 0xB8, 0x81, 0xFF, 0xDD, 0xB8, 0x81, 0xFF, 0xDC, 0xB7, + 0x81, 0xFF, 0xDC, 0xB7, 0x81, 0xFF, 0xD9, 0xB6, 0x80, 0xFF, 0xD6, 0xB4, 0x80, 0xFF, 0xD3, 0xB4, + 0x85, 0xFF, 0xD6, 0xBE, 0x9B, 0xFF, 0xE2, 0xDB, 0xCF, 0xFF, 0xED, 0xED, 0xEB, 0xFF, 0xEF, 0xEF, + 0xF0, 0xFF, 0xF0, 0xF1, 0xF1, 0xFF, 0xEF, 0xF0, 0xF1, 0xFF, 0xEF, 0xF0, 0xF1, 0xFF, 0xEF, 0xF0, + 0xF1, 0xFF, 0xEF, 0xF0, 0xF0, 0xFF, 0xEE, 0xEF, 0xEF, 0xFF, 0xED, 0xEE, 0xEE, 0xFF, 0xEC, 0xED, + 0xED, 0xFF, 0xEC, 0xEC, 0xED, 0xFF, 0xEB, 0xEC, 0xEC, 0xFF, 0xEA, 0xEB, 0xEB, 0xFF, 0xE9, 0xEA, + 0xEA, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xEA, 0xEB, 0xEB, 0xFF, 0xEA, 0xEA, 0xEB, 0xFF, 0xE9, 0xEA, + 0xEA, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xE9, 0xEA, 0xEA, 0xFF, 0xE8, 0xE9, + 0xEA, 0xFF, 0xE9, 0xEA, 0xEA, 0xFF, 0xE9, 0xEA, 0xEA, 0xFF, 0xEA, 0xEA, 0xEB, 0xFF, 0xEB, 0xEB, + 0xEB, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xEA, 0xEA, 0xE9, 0xFF, 0xEA, 0xEA, 0xE8, 0xFF, 0xEA, 0xEA, + 0xE8, 0xFF, 0xEB, 0xEC, 0xEA, 0xFF, 0xEC, 0xEE, 0xEC, 0xFF, 0xED, 0xEE, 0xEE, 0xFF, 0xF1, 0xF1, + 0xEE, 0xFF, 0xE3, 0xE0, 0xD5, 0xFF, 0xC5, 0xC0, 0xAB, 0xFF, 0xCD, 0xC6, 0xAF, 0xFF, 0xD8, 0xCF, + 0xB8, 0xFF, 0xCC, 0xBE, 0xA0, 0xFF, 0xB8, 0x9D, 0x6D, 0xFF, 0xB5, 0x91, 0x58, 0xFF, 0xBD, 0x94, + 0x53, 0xFF, 0xC4, 0x98, 0x51, 0xFF, 0xCB, 0x9B, 0x53, 0xFF, 0xCE, 0x9D, 0x54, 0xFF, 0xD0, 0x9E, + 0x54, 0xFF, 0xD1, 0x9E, 0x54, 0xFF, 0xD2, 0x9E, 0x54, 0xFF, 0xD2, 0x9E, 0x54, 0xFF, 0xD2, 0x9E, + 0x53, 0xFF, 0xD2, 0x9D, 0x53, 0xFF, 0xD1, 0x9D, 0x53, 0xFF, 0xD1, 0x9E, 0x55, 0xFF, 0xD2, 0xA0, + 0x5B, 0xFF, 0xD6, 0xA8, 0x69, 0xFF, 0xDD, 0xB6, 0x7F, 0xFF, 0xDF, 0xC0, 0x94, 0xE9, 0xD9, 0xC0, + 0x9F, 0x77, 0xD9, 0xC2, 0xA2, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEF, 0xE0, + 0xCB, 0x02, 0xF1, 0xDF, 0xC4, 0x23, 0xE0, 0xC2, 0x98, 0x95, 0xD6, 0xB0, 0x7C, 0xF2, 0xD4, 0xA7, + 0x6E, 0xFF, 0xD0, 0x9D, 0x60, 0xFF, 0xCB, 0x97, 0x56, 0xFF, 0xCC, 0x96, 0x53, 0xFF, 0xCC, 0x98, + 0x53, 0xFF, 0xCE, 0x99, 0x53, 0xFF, 0xCE, 0x9B, 0x53, 0xFF, 0xD0, 0x9C, 0x54, 0xFF, 0xD1, 0x9D, + 0x55, 0xFF, 0xD2, 0x9E, 0x56, 0xFF, 0xD2, 0x9F, 0x56, 0xFF, 0xD3, 0xA0, 0x56, 0xFF, 0xD3, 0xA0, + 0x56, 0xFF, 0xD3, 0xA1, 0x56, 0xFF, 0xD3, 0xA1, 0x56, 0xFF, 0xD4, 0xA1, 0x56, 0xFF, 0xD3, 0xA1, + 0x56, 0xFF, 0xD5, 0xA4, 0x5C, 0xFF, 0xDA, 0xB1, 0x73, 0xFF, 0xDE, 0xB9, 0x83, 0xFF, 0xDE, 0xBB, + 0x85, 0xFF, 0xDE, 0xBB, 0x84, 0xFF, 0xDE, 0xBA, 0x84, 0xFF, 0xDE, 0xBA, 0x84, 0xFF, 0xDE, 0xBA, + 0x83, 0xFF, 0xDE, 0xBA, 0x83, 0xFF, 0xDE, 0xBA, 0x83, 0xFF, 0xDE, 0xBA, 0x84, 0xFF, 0xDE, 0xBA, + 0x83, 0xFF, 0xDE, 0xBA, 0x83, 0xFF, 0xDE, 0xBA, 0x83, 0xFF, 0xDE, 0xBA, 0x83, 0xFF, 0xDE, 0xBA, + 0x83, 0xFF, 0xDE, 0xBA, 0x83, 0xFF, 0xDE, 0xBA, 0x83, 0xFF, 0xDE, 0xBA, 0x84, 0xFF, 0xDE, 0xBA, + 0x83, 0xFF, 0xDE, 0xBA, 0x84, 0xFF, 0xDE, 0xBA, 0x83, 0xFF, 0xDE, 0xBA, 0x83, 0xFF, 0xDE, 0xBA, + 0x84, 0xFF, 0xDE, 0xBA, 0x83, 0xFF, 0xDE, 0xBA, 0x84, 0xFF, 0xDB, 0xB8, 0x83, 0xFF, 0xD7, 0xB7, + 0x83, 0xFF, 0xDA, 0xB9, 0x8B, 0xFF, 0xDB, 0xC4, 0xA0, 0xFF, 0xE7, 0xE0, 0xD6, 0xFF, 0xEE, 0xEE, + 0xEC, 0xFF, 0xF1, 0xF1, 0xF1, 0xFF, 0xF0, 0xF1, 0xF2, 0xFF, 0xF0, 0xF1, 0xF1, 0xFF, 0xF0, 0xF2, + 0xF1, 0xFF, 0xF0, 0xF1, 0xF1, 0xFF, 0xEF, 0xF0, 0xF0, 0xFF, 0xEF, 0xF0, 0xF0, 0xFF, 0xEE, 0xEF, + 0xEF, 0xFF, 0xED, 0xEE, 0xEE, 0xFF, 0xED, 0xED, 0xEE, 0xFF, 0xEC, 0xEC, 0xED, 0xFF, 0xEC, 0xEC, + 0xEC, 0xFF, 0xEB, 0xEC, 0xEB, 0xFF, 0xEB, 0xEC, 0xEC, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xEB, 0xEC, + 0xEC, 0xFF, 0xEB, 0xEC, 0xEC, 0xFF, 0xEB, 0xEC, 0xEC, 0xFF, 0xEB, 0xEC, 0xEC, 0xFF, 0xEA, 0xEB, + 0xEB, 0xFF, 0xEA, 0xEB, 0xEB, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xEB, 0xEC, 0xEC, 0xFF, 0xED, 0xED, + 0xED, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xE6, 0xE6, 0xE2, 0xFF, 0xE3, 0xE3, 0xDF, 0xFF, 0xE9, 0xEA, + 0xE7, 0xFF, 0xED, 0xED, 0xEC, 0xFF, 0xEC, 0xEE, 0xED, 0xFF, 0xEC, 0xED, 0xED, 0xFF, 0xF0, 0xF0, + 0xF1, 0xFF, 0xF3, 0xF2, 0xF1, 0xFF, 0xE4, 0xE2, 0xD8, 0xFF, 0xC9, 0xC5, 0xB4, 0xFF, 0xD1, 0xCA, + 0xB9, 0xFF, 0xD9, 0xD2, 0xBD, 0xFF, 0xD3, 0xC7, 0xAB, 0xFF, 0xBA, 0xA1, 0x74, 0xFF, 0xB7, 0x92, + 0x58, 0xFF, 0xC1, 0x97, 0x53, 0xFF, 0xCA, 0x9C, 0x53, 0xFF, 0xCF, 0x9F, 0x55, 0xFF, 0xD1, 0xA0, + 0x56, 0xFF, 0xD3, 0xA1, 0x56, 0xFF, 0xD3, 0xA1, 0x56, 0xFF, 0xD3, 0xA0, 0x56, 0xFF, 0xD3, 0x9F, + 0x55, 0xFF, 0xD3, 0x9F, 0x55, 0xFF, 0xD2, 0xA0, 0x56, 0xFF, 0xD3, 0xA1, 0x59, 0xFF, 0xD3, 0xA4, + 0x61, 0xFF, 0xDA, 0xAF, 0x74, 0xFF, 0xE3, 0xBC, 0x86, 0xFC, 0xDE, 0xC3, 0x9A, 0xCE, 0xD7, 0xC1, + 0xA5, 0x50, 0xD7, 0xC2, 0xA5, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFD, 0xFF, 0x0B, 0xE9, 0xCE, 0xA9, 0x67, 0xD6, 0xB1, 0x7C, 0xDC, 0xD8, 0xAE, + 0x7A, 0xFF, 0xD3, 0xA3, 0x68, 0xFF, 0xCE, 0x9A, 0x5B, 0xFF, 0xCF, 0x9A, 0x57, 0xFF, 0xCE, 0x9A, + 0x55, 0xFF, 0xD0, 0x9B, 0x55, 0xFF, 0xD1, 0x9D, 0x56, 0xFF, 0xD2, 0x9E, 0x57, 0xFF, 0xD2, 0xA0, + 0x58, 0xFF, 0xD3, 0xA1, 0x58, 0xFF, 0xD3, 0xA1, 0x58, 0xFF, 0xD4, 0xA2, 0x58, 0xFF, 0xD4, 0xA3, + 0x58, 0xFF, 0xD4, 0xA3, 0x58, 0xFF, 0xD4, 0xA3, 0x58, 0xFF, 0xD5, 0xA3, 0x58, 0xFF, 0xD5, 0xA3, + 0x59, 0xFF, 0xD8, 0xA7, 0x61, 0xFF, 0xDD, 0xB6, 0x7B, 0xFF, 0xE0, 0xBD, 0x87, 0xFF, 0xDF, 0xBD, + 0x88, 0xFF, 0xE0, 0xBD, 0x88, 0xFF, 0xDF, 0xBD, 0x87, 0xFF, 0xE0, 0xBD, 0x87, 0xFF, 0xDF, 0xBD, + 0x87, 0xFF, 0xE0, 0xBD, 0x87, 0xFF, 0xDF, 0xBD, 0x87, 0xFF, 0xE0, 0xBD, 0x87, 0xFF, 0xDF, 0xBD, + 0x87, 0xFF, 0xE0, 0xBD, 0x87, 0xFF, 0xDF, 0xBD, 0x87, 0xFF, 0xE0, 0xBD, 0x87, 0xFF, 0xDF, 0xBD, + 0x87, 0xFF, 0xE0, 0xBD, 0x87, 0xFF, 0xDF, 0xBD, 0x87, 0xFF, 0xE0, 0xBD, 0x87, 0xFF, 0xDF, 0xBD, + 0x87, 0xFF, 0xE0, 0xBD, 0x87, 0xFF, 0xDF, 0xBD, 0x87, 0xFF, 0xE0, 0xBD, 0x87, 0xFF, 0xDF, 0xBD, + 0x86, 0xFF, 0xE0, 0xBD, 0x87, 0xFF, 0xE0, 0xBC, 0x86, 0xFF, 0xDF, 0xBC, 0x87, 0xFF, 0xDC, 0xBA, + 0x85, 0xFF, 0xDA, 0xB9, 0x86, 0xFF, 0xD8, 0xBB, 0x8E, 0xFF, 0xDB, 0xC7, 0xA8, 0xFF, 0xE6, 0xE1, + 0xD7, 0xFF, 0xF2, 0xEF, 0xEC, 0xFF, 0xF1, 0xF1, 0xF1, 0xFF, 0xF1, 0xF2, 0xF2, 0xFF, 0xF0, 0xF2, + 0xF2, 0xFF, 0xF1, 0xF2, 0xF2, 0xFF, 0xF0, 0xF1, 0xF2, 0xFF, 0xF0, 0xF1, 0xF1, 0xFF, 0xEF, 0xF0, + 0xF0, 0xFF, 0xEF, 0xEF, 0xEF, 0xFF, 0xEE, 0xEF, 0xEF, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEC, 0xED, + 0xED, 0xFF, 0xED, 0xED, 0xED, 0xFF, 0xED, 0xED, 0xED, 0xFF, 0xED, 0xEE, 0xEE, 0xFF, 0xED, 0xEE, + 0xEE, 0xFF, 0xED, 0xED, 0xEE, 0xFF, 0xEC, 0xED, 0xED, 0xFF, 0xED, 0xEE, 0xEE, 0xFF, 0xEC, 0xED, + 0xED, 0xFF, 0xED, 0xED, 0xED, 0xFF, 0xED, 0xED, 0xED, 0xFF, 0xED, 0xED, 0xEE, 0xFF, 0xEC, 0xED, + 0xEB, 0xFF, 0xE4, 0xE5, 0xE0, 0xFF, 0xE2, 0xE3, 0xDD, 0xFF, 0xEA, 0xEB, 0xE9, 0xFF, 0xEF, 0xF0, + 0xF0, 0xFF, 0xF0, 0xF1, 0xF1, 0xFF, 0xEE, 0xEF, 0xEF, 0xFF, 0xED, 0xEE, 0xEE, 0xFF, 0xED, 0xEE, + 0xEE, 0xFF, 0xEF, 0xEF, 0xF0, 0xFF, 0xF2, 0xF3, 0xF2, 0xFF, 0xEA, 0xE8, 0xE2, 0xFF, 0xD6, 0xD0, + 0xC2, 0xFF, 0xD3, 0xCC, 0xBA, 0xFF, 0xDE, 0xD7, 0xC3, 0xFF, 0xD7, 0xCA, 0xAF, 0xFF, 0xBC, 0xA0, + 0x6E, 0xFF, 0xBE, 0x97, 0x54, 0xFF, 0xC9, 0x9C, 0x55, 0xFF, 0xCF, 0xA0, 0x58, 0xFF, 0xD2, 0xA2, + 0x58, 0xFF, 0xD4, 0xA2, 0x58, 0xFF, 0xD4, 0xA2, 0x58, 0xFF, 0xD4, 0xA2, 0x58, 0xFF, 0xD4, 0xA2, + 0x58, 0xFF, 0xD4, 0xA2, 0x58, 0xFF, 0xD4, 0xA2, 0x58, 0xFF, 0xD5, 0xA4, 0x5D, 0xFF, 0xD7, 0xAA, + 0x69, 0xFF, 0xDE, 0xB6, 0x7E, 0xFF, 0xE7, 0xC1, 0x8B, 0xF5, 0xE0, 0xC5, 0xA1, 0xA7, 0xD5, 0xC3, + 0xAE, 0x2C, 0xD5, 0xC3, 0xAC, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFA, 0xFA, 0xFE, 0x02, 0xE5, 0xCA, 0x9F, 0x39, 0xD9, 0xB5, 0x80, 0xB8, 0xDA, 0xB3, + 0x80, 0xF8, 0xD8, 0xAA, 0x72, 0xFF, 0xD2, 0x9F, 0x61, 0xFF, 0xD1, 0x9C, 0x5A, 0xFF, 0xD0, 0x9C, + 0x57, 0xFF, 0xD2, 0x9D, 0x57, 0xFF, 0xD2, 0x9F, 0x58, 0xFF, 0xD4, 0xA0, 0x59, 0xFF, 0xD4, 0xA1, + 0x5A, 0xFF, 0xD4, 0xA2, 0x5A, 0xFF, 0xD5, 0xA3, 0x5A, 0xFF, 0xD6, 0xA4, 0x5A, 0xFF, 0xD6, 0xA4, + 0x5A, 0xFF, 0xD7, 0xA5, 0x5A, 0xFF, 0xD6, 0xA5, 0x5A, 0xFF, 0xD7, 0xA5, 0x5A, 0xFF, 0xD6, 0xA5, + 0x5C, 0xFF, 0xDA, 0xAB, 0x67, 0xFF, 0xDF, 0xBA, 0x82, 0xFF, 0xE2, 0xBF, 0x8A, 0xFF, 0xE1, 0xBF, + 0x8B, 0xFF, 0xE1, 0xBF, 0x8B, 0xFF, 0xE1, 0xBF, 0x8A, 0xFF, 0xE1, 0xBF, 0x8A, 0xFF, 0xE1, 0xBF, + 0x8A, 0xFF, 0xE1, 0xBF, 0x8A, 0xFF, 0xE1, 0xBF, 0x8A, 0xFF, 0xE1, 0xBF, 0x8A, 0xFF, 0xE1, 0xBF, + 0x8A, 0xFF, 0xE1, 0xBF, 0x8A, 0xFF, 0xE1, 0xBF, 0x8A, 0xFF, 0xE1, 0xBF, 0x8A, 0xFF, 0xE1, 0xBF, + 0x8A, 0xFF, 0xE1, 0xBF, 0x8A, 0xFF, 0xE1, 0xBF, 0x8A, 0xFF, 0xE1, 0xBF, 0x8A, 0xFF, 0xE1, 0xBF, + 0x8A, 0xFF, 0xE2, 0xBF, 0x8A, 0xFF, 0xE1, 0xBF, 0x8A, 0xFF, 0xE1, 0xBF, 0x8A, 0xFF, 0xE1, 0xBF, + 0x8A, 0xFF, 0xE1, 0xBF, 0x8A, 0xFF, 0xE1, 0xBF, 0x8A, 0xFF, 0xE1, 0xBE, 0x89, 0xFF, 0xE1, 0xBE, + 0x89, 0xFF, 0xDF, 0xBD, 0x89, 0xFF, 0xD9, 0xBB, 0x8A, 0xFF, 0xD9, 0xBE, 0x91, 0xFF, 0xDC, 0xCC, + 0xAD, 0xFF, 0xEA, 0xE4, 0xDC, 0xFF, 0xF1, 0xF0, 0xEE, 0xFF, 0xF2, 0xF2, 0xF2, 0xFF, 0xF2, 0xF3, + 0xF3, 0xFF, 0xF1, 0xF3, 0xF3, 0xFF, 0xF1, 0xF2, 0xF2, 0xFF, 0xF1, 0xF2, 0xF2, 0xFF, 0xF0, 0xF2, + 0xF2, 0xFF, 0xF0, 0xF1, 0xF1, 0xFF, 0xEF, 0xF0, 0xF0, 0xFF, 0xEF, 0xEF, 0xF0, 0xFF, 0xEE, 0xEF, + 0xEF, 0xFF, 0xEE, 0xEF, 0xEF, 0xFF, 0xEE, 0xEF, 0xEF, 0xFF, 0xEE, 0xEF, 0xEF, 0xFF, 0xEE, 0xEF, + 0xEF, 0xFF, 0xEE, 0xEF, 0xEF, 0xFF, 0xEE, 0xEF, 0xEF, 0xFF, 0xEE, 0xEF, 0xEF, 0xFF, 0xEE, 0xEF, + 0xEF, 0xFF, 0xEE, 0xEF, 0xEF, 0xFF, 0xEE, 0xEF, 0xEF, 0xFF, 0xED, 0xEE, 0xEC, 0xFF, 0xE6, 0xE6, + 0xE0, 0xFF, 0xE2, 0xE3, 0xDE, 0xFF, 0xEE, 0xEF, 0xED, 0xFF, 0xF0, 0xF0, 0xF0, 0xFF, 0xF0, 0xF0, + 0xF1, 0xFF, 0xF0, 0xF0, 0xF0, 0xFF, 0xEF, 0xF0, 0xEF, 0xFF, 0xEE, 0xEF, 0xEF, 0xFF, 0xEE, 0xEF, + 0xF0, 0xFF, 0xF0, 0xF0, 0xF1, 0xFF, 0xF5, 0xF5, 0xF6, 0xFF, 0xF3, 0xF3, 0xF3, 0xFF, 0xE8, 0xE7, + 0xE1, 0xFF, 0xDC, 0xDA, 0xD1, 0xFF, 0xE4, 0xE1, 0xD7, 0xFF, 0xEA, 0xE1, 0xD3, 0xFF, 0xC8, 0xB1, + 0x8A, 0xFF, 0xC1, 0x9A, 0x57, 0xFF, 0xCA, 0x9F, 0x59, 0xFF, 0xD0, 0xA1, 0x5A, 0xFF, 0xD4, 0xA3, + 0x5A, 0xFF, 0xD6, 0xA4, 0x5A, 0xFF, 0xD6, 0xA4, 0x59, 0xFF, 0xD6, 0xA4, 0x59, 0xFF, 0xD6, 0xA4, + 0x59, 0xFF, 0xD7, 0xA5, 0x5A, 0xFF, 0xD6, 0xA4, 0x5C, 0xFF, 0xD6, 0xA7, 0x62, 0xFF, 0xD9, 0xAF, + 0x70, 0xFF, 0xE2, 0xBB, 0x86, 0xFE, 0xE8, 0xC7, 0x93, 0xE3, 0xE0, 0xC6, 0xA5, 0x75, 0xDA, 0xC5, + 0xAD, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE1, 0xC5, 0x96, 0x19, 0xE4, 0xC2, 0x91, 0x8C, 0xDC, 0xB6, + 0x83, 0xE5, 0xDB, 0xB0, 0x79, 0xFF, 0xD6, 0xA6, 0x69, 0xFF, 0xD3, 0xA0, 0x5F, 0xFF, 0xD2, 0x9F, + 0x5B, 0xFF, 0xD3, 0x9F, 0x5A, 0xFF, 0xD4, 0xA0, 0x5B, 0xFF, 0xD5, 0xA2, 0x5B, 0xFF, 0xD5, 0xA3, + 0x5C, 0xFF, 0xD6, 0xA4, 0x5D, 0xFF, 0xD7, 0xA5, 0x5D, 0xFF, 0xD8, 0xA6, 0x5D, 0xFF, 0xD8, 0xA7, + 0x5D, 0xFF, 0xD9, 0xA7, 0x5D, 0xFF, 0xD9, 0xA7, 0x5C, 0xFF, 0xD9, 0xA7, 0x5C, 0xFF, 0xD8, 0xA8, + 0x5F, 0xFF, 0xDC, 0xB0, 0x6C, 0xFF, 0xE1, 0xBE, 0x87, 0xFF, 0xE3, 0xC2, 0x8E, 0xFF, 0xE3, 0xC1, + 0x8E, 0xFF, 0xE4, 0xC1, 0x8E, 0xFF, 0xE3, 0xC1, 0x8E, 0xFF, 0xE3, 0xC1, 0x8E, 0xFF, 0xE3, 0xC1, + 0x8E, 0xFF, 0xE3, 0xC1, 0x8E, 0xFF, 0xE3, 0xC1, 0x8E, 0xFF, 0xE3, 0xC1, 0x8E, 0xFF, 0xE3, 0xC1, + 0x8E, 0xFF, 0xE3, 0xC1, 0x8E, 0xFF, 0xE3, 0xC1, 0x8E, 0xFF, 0xE3, 0xC1, 0x8E, 0xFF, 0xE3, 0xC1, + 0x8E, 0xFF, 0xE3, 0xC1, 0x8E, 0xFF, 0xE3, 0xC1, 0x8D, 0xFF, 0xE3, 0xC1, 0x8E, 0xFF, 0xE3, 0xC1, + 0x8E, 0xFF, 0xE3, 0xC1, 0x8E, 0xFF, 0xE3, 0xC1, 0x8D, 0xFF, 0xE4, 0xC1, 0x8E, 0xFF, 0xE3, 0xC1, + 0x8D, 0xFF, 0xE3, 0xC1, 0x8D, 0xFF, 0xE3, 0xC1, 0x8D, 0xFF, 0xE3, 0xC1, 0x8D, 0xFF, 0xE2, 0xC0, + 0x8D, 0xFF, 0xE2, 0xC0, 0x8D, 0xFF, 0xDF, 0xBF, 0x8D, 0xFF, 0xDB, 0xBE, 0x8D, 0xFF, 0xD8, 0xC1, + 0x95, 0xFF, 0xDF, 0xCF, 0xB4, 0xFF, 0xE9, 0xE5, 0xDE, 0xFF, 0xF3, 0xF1, 0xEF, 0xFF, 0xF2, 0xF3, + 0xF3, 0xFF, 0xF2, 0xF4, 0xF4, 0xFF, 0xF1, 0xF3, 0xF3, 0xFF, 0xF1, 0xF3, 0xF3, 0xFF, 0xF2, 0xF3, + 0xF3, 0xFF, 0xF2, 0xF2, 0xF2, 0xFF, 0xF1, 0xF2, 0xF1, 0xFF, 0xF1, 0xF1, 0xF1, 0xFF, 0xF0, 0xF1, + 0xF1, 0xFF, 0xF0, 0xF0, 0xF0, 0xFF, 0xEF, 0xF0, 0xEF, 0xFF, 0xEF, 0xF0, 0xF0, 0xFF, 0xEF, 0xF0, + 0xF0, 0xFF, 0xF0, 0xF0, 0xF1, 0xFF, 0xEF, 0xF0, 0xF1, 0xFF, 0xF0, 0xF1, 0xF1, 0xFF, 0xF0, 0xF1, + 0xF1, 0xFF, 0xF0, 0xF0, 0xF1, 0xFF, 0xED, 0xEE, 0xED, 0xFF, 0xE6, 0xE7, 0xE2, 0xFF, 0xE5, 0xE6, + 0xE1, 0xFF, 0xEF, 0xEF, 0xEE, 0xFF, 0xF1, 0xF2, 0xF2, 0xFF, 0xF0, 0xF1, 0xF1, 0xFF, 0xEF, 0xF0, + 0xF1, 0xFF, 0xF0, 0xF1, 0xF1, 0xFF, 0xF0, 0xF1, 0xF0, 0xFF, 0xF1, 0xF2, 0xF2, 0xFF, 0xED, 0xED, + 0xEA, 0xFF, 0xEA, 0xE9, 0xE4, 0xFF, 0xF1, 0xF1, 0xF0, 0xFF, 0xF4, 0xF3, 0xF3, 0xFF, 0xF0, 0xF1, + 0xF0, 0xFF, 0xEC, 0xEB, 0xE8, 0xFF, 0xEA, 0xE7, 0xE0, 0xFF, 0xEA, 0xE1, 0xD4, 0xFF, 0xCA, 0xB3, + 0x88, 0xFF, 0xC5, 0x9E, 0x5B, 0xFF, 0xCD, 0xA1, 0x5B, 0xFF, 0xD3, 0xA4, 0x5D, 0xFF, 0xD6, 0xA6, + 0x5D, 0xFF, 0xD8, 0xA6, 0x5C, 0xFF, 0xD8, 0xA6, 0x5C, 0xFF, 0xD8, 0xA7, 0x5C, 0xFF, 0xD8, 0xA7, + 0x5C, 0xFF, 0xD9, 0xA7, 0x5D, 0xFF, 0xD8, 0xA8, 0x60, 0xFF, 0xD8, 0xAC, 0x68, 0xFF, 0xDC, 0xB5, + 0x77, 0xFF, 0xE3, 0xC1, 0x8E, 0xFB, 0xE6, 0xCB, 0x9E, 0xC5, 0xE3, 0xCB, 0xA8, 0x42, 0xE1, 0xC7, + 0xAB, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEE, 0xD7, 0xB8, 0x09, 0xEC, 0xD1, 0xB0, 0x58, 0xE0, 0xBD, + 0x8D, 0xC3, 0xDE, 0xB5, 0x7F, 0xFD, 0xDB, 0xAE, 0x73, 0xFF, 0xD5, 0xA4, 0x65, 0xFF, 0xD3, 0xA1, + 0x5E, 0xFF, 0xD5, 0xA1, 0x5D, 0xFF, 0xD5, 0xA2, 0x5C, 0xFF, 0xD6, 0xA3, 0x5D, 0xFF, 0xD7, 0xA5, + 0x5E, 0xFF, 0xD8, 0xA6, 0x5E, 0xFF, 0xD8, 0xA7, 0x5F, 0xFF, 0xDA, 0xA8, 0x5F, 0xFF, 0xDA, 0xA8, + 0x5F, 0xFF, 0xDA, 0xA9, 0x5E, 0xFF, 0xDA, 0xA9, 0x5E, 0xFF, 0xDB, 0xA9, 0x5E, 0xFF, 0xDA, 0xAA, + 0x61, 0xFF, 0xDE, 0xB4, 0x72, 0xFF, 0xE3, 0xC1, 0x8C, 0xFF, 0xE6, 0xC4, 0x91, 0xFF, 0xE5, 0xC3, + 0x90, 0xFF, 0xE5, 0xC3, 0x91, 0xFF, 0xE5, 0xC3, 0x91, 0xFF, 0xE5, 0xC3, 0x91, 0xFF, 0xE5, 0xC3, + 0x91, 0xFF, 0xE5, 0xC3, 0x91, 0xFF, 0xE5, 0xC3, 0x90, 0xFF, 0xE5, 0xC3, 0x90, 0xFF, 0xE5, 0xC3, + 0x90, 0xFF, 0xE5, 0xC3, 0x90, 0xFF, 0xE5, 0xC3, 0x90, 0xFF, 0xE5, 0xC3, 0x90, 0xFF, 0xE5, 0xC3, + 0x90, 0xFF, 0xE5, 0xC3, 0x90, 0xFF, 0xE5, 0xC3, 0x90, 0xFF, 0xE5, 0xC3, 0x90, 0xFF, 0xE5, 0xC3, + 0x90, 0xFF, 0xE5, 0xC3, 0x90, 0xFF, 0xE5, 0xC3, 0x90, 0xFF, 0xE5, 0xC3, 0x90, 0xFF, 0xE5, 0xC3, + 0x90, 0xFF, 0xE5, 0xC3, 0x90, 0xFF, 0xE5, 0xC3, 0x90, 0xFF, 0xE5, 0xC3, 0x90, 0xFF, 0xE5, 0xC3, + 0x91, 0xFF, 0xE4, 0xC3, 0x90, 0xFF, 0xE3, 0xC3, 0x90, 0xFF, 0xE1, 0xC1, 0x90, 0xFF, 0xDB, 0xC0, + 0x90, 0xFF, 0xDD, 0xC3, 0x99, 0xFF, 0xE1, 0xD2, 0xB7, 0xFF, 0xED, 0xE8, 0xE0, 0xFF, 0xF3, 0xF3, + 0xF1, 0xFF, 0xF3, 0xF4, 0xF4, 0xFF, 0xF3, 0xF4, 0xF5, 0xFF, 0xF2, 0xF4, 0xF4, 0xFF, 0xF3, 0xF4, + 0xF4, 0xFF, 0xF3, 0xF4, 0xF4, 0xFF, 0xF2, 0xF3, 0xF3, 0xFF, 0xF2, 0xF2, 0xF2, 0xFF, 0xF1, 0xF2, + 0xF2, 0xFF, 0xF1, 0xF1, 0xF1, 0xFF, 0xF0, 0xF1, 0xF1, 0xFF, 0xF0, 0xF1, 0xF1, 0xFF, 0xF1, 0xF2, + 0xF1, 0xFF, 0xF1, 0xF2, 0xF2, 0xFF, 0xF1, 0xF2, 0xF3, 0xFF, 0xF1, 0xF1, 0xF2, 0xFF, 0xF1, 0xF2, + 0xF3, 0xFF, 0xEE, 0xEF, 0xEF, 0xFF, 0xE8, 0xE8, 0xE4, 0xFF, 0xE8, 0xE8, 0xE4, 0xFF, 0xF0, 0xF1, + 0xEF, 0xFF, 0xF2, 0xF3, 0xF2, 0xFF, 0xF2, 0xF2, 0xF2, 0xFF, 0xF2, 0xF2, 0xF2, 0xFF, 0xF1, 0xF2, + 0xF2, 0xFF, 0xF1, 0xF2, 0xF2, 0xFF, 0xF1, 0xF2, 0xF2, 0xFF, 0xF2, 0xF2, 0xEF, 0xFF, 0xE1, 0xDF, + 0xCD, 0xFF, 0xC8, 0xC3, 0xB0, 0xFF, 0xE6, 0xE5, 0xDB, 0xFF, 0xF2, 0xF1, 0xED, 0xFF, 0xF1, 0xF2, + 0xF1, 0xFF, 0xF0, 0xF1, 0xF0, 0xFF, 0xEF, 0xEC, 0xE5, 0xFF, 0xE4, 0xD6, 0xC1, 0xFF, 0xC6, 0xA9, + 0x75, 0xFF, 0xCA, 0xA1, 0x5C, 0xFF, 0xD1, 0xA5, 0x5E, 0xFF, 0xD5, 0xA6, 0x5F, 0xFF, 0xD8, 0xA8, + 0x5F, 0xFF, 0xDA, 0xA8, 0x5E, 0xFF, 0xDA, 0xA8, 0x5E, 0xFF, 0xDB, 0xA9, 0x5E, 0xFF, 0xDA, 0xA9, + 0x5E, 0xFF, 0xDA, 0xA9, 0x60, 0xFF, 0xDA, 0xAB, 0x64, 0xFF, 0xDE, 0xB2, 0x73, 0xFF, 0xE2, 0xBD, + 0x87, 0xFE, 0xE7, 0xC5, 0x97, 0xF1, 0xE9, 0xCD, 0xA4, 0x8F, 0xE8, 0xCE, 0xA8, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEF, 0xDE, 0xC9, 0x01, 0xE9, 0xD4, 0xBA, 0x28, 0xE5, 0xC3, + 0x94, 0x99, 0xE0, 0xBA, 0x86, 0xF0, 0xDE, 0xB4, 0x7B, 0xFF, 0xD9, 0xAA, 0x6E, 0xFF, 0xD6, 0xA5, + 0x63, 0xFF, 0xD7, 0xA4, 0x60, 0xFF, 0xD7, 0xA4, 0x5F, 0xFF, 0xD8, 0xA5, 0x5F, 0xFF, 0xD8, 0xA7, + 0x60, 0xFF, 0xD9, 0xA9, 0x61, 0xFF, 0xD9, 0xAA, 0x61, 0xFF, 0xDA, 0xAA, 0x61, 0xFF, 0xDA, 0xAB, + 0x61, 0xFF, 0xDB, 0xAB, 0x61, 0xFF, 0xDC, 0xAB, 0x60, 0xFF, 0xDC, 0xAB, 0x60, 0xFF, 0xDB, 0xAC, + 0x63, 0xFF, 0xDF, 0xB6, 0x76, 0xFF, 0xE5, 0xC4, 0x91, 0xFF, 0xE7, 0xC6, 0x94, 0xFF, 0xE7, 0xC6, + 0x94, 0xFF, 0xE7, 0xC6, 0x94, 0xFF, 0xE6, 0xC6, 0x94, 0xFF, 0xE7, 0xC6, 0x94, 0xFF, 0xE6, 0xC6, + 0x94, 0xFF, 0xE7, 0xC6, 0x94, 0xFF, 0xE6, 0xC6, 0x94, 0xFF, 0xE7, 0xC6, 0x94, 0xFF, 0xE6, 0xC6, + 0x94, 0xFF, 0xE7, 0xC6, 0x94, 0xFF, 0xE6, 0xC6, 0x94, 0xFF, 0xE7, 0xC6, 0x94, 0xFF, 0xE6, 0xC6, + 0x94, 0xFF, 0xE7, 0xC6, 0x94, 0xFF, 0xE6, 0xC6, 0x94, 0xFF, 0xE7, 0xC6, 0x94, 0xFF, 0xE6, 0xC6, + 0x94, 0xFF, 0xE7, 0xC6, 0x94, 0xFF, 0xE6, 0xC6, 0x94, 0xFF, 0xE7, 0xC6, 0x94, 0xFF, 0xE6, 0xC6, + 0x94, 0xFF, 0xE7, 0xC6, 0x94, 0xFF, 0xE6, 0xC6, 0x94, 0xFF, 0xE7, 0xC6, 0x94, 0xFF, 0xE6, 0xC6, + 0x94, 0xFF, 0xE6, 0xC6, 0x94, 0xFF, 0xE5, 0xC5, 0x93, 0xFF, 0xE5, 0xC5, 0x94, 0xFF, 0xE2, 0xC3, + 0x92, 0xFF, 0xDE, 0xC2, 0x92, 0xFF, 0xDC, 0xC6, 0x9C, 0xFF, 0xE4, 0xD3, 0xBA, 0xFF, 0xEC, 0xE9, + 0xE0, 0xFF, 0xF5, 0xF4, 0xF1, 0xFF, 0xF4, 0xF5, 0xF5, 0xFF, 0xF4, 0xF5, 0xF5, 0xFF, 0xF3, 0xF5, + 0xF5, 0xFF, 0xF3, 0xF5, 0xF5, 0xFF, 0xF3, 0xF4, 0xF4, 0xFF, 0xF3, 0xF3, 0xF3, 0xFF, 0xF2, 0xF3, + 0xF3, 0xFF, 0xF2, 0xF2, 0xF3, 0xFF, 0xF1, 0xF2, 0xF2, 0xFF, 0xF1, 0xF2, 0xF3, 0xFF, 0xF1, 0xF2, + 0xF2, 0xFF, 0xF2, 0xF3, 0xF2, 0xFF, 0xF2, 0xF3, 0xF3, 0xFF, 0xF3, 0xF3, 0xF3, 0xFF, 0xF0, 0xF1, + 0xF1, 0xFF, 0xEC, 0xED, 0xEA, 0xFF, 0xED, 0xEE, 0xEA, 0xFF, 0xF2, 0xF3, 0xF2, 0xFF, 0xF2, 0xF3, + 0xF2, 0xFF, 0xF2, 0xF3, 0xF3, 0xFF, 0xF2, 0xF3, 0xF3, 0xFF, 0xF2, 0xF3, 0xF3, 0xFF, 0xF1, 0xF2, + 0xF3, 0xFF, 0xF2, 0xF3, 0xF3, 0xFF, 0xF2, 0xF3, 0xF1, 0xFF, 0xE5, 0xE3, 0xD7, 0xFF, 0xBA, 0xB4, + 0x9D, 0xFF, 0xC6, 0xC2, 0xAF, 0xFF, 0xEF, 0xEE, 0xE6, 0xFF, 0xF3, 0xF3, 0xF3, 0xFF, 0xF4, 0xF4, + 0xF4, 0xFF, 0xF2, 0xF1, 0xF0, 0xFF, 0xF0, 0xE7, 0xDB, 0xFF, 0xD3, 0xBE, 0x96, 0xFF, 0xC6, 0xA3, + 0x67, 0xFF, 0xCF, 0xA5, 0x60, 0xFF, 0xD5, 0xA9, 0x62, 0xFF, 0xD9, 0xAA, 0x61, 0xFF, 0xDB, 0xAA, + 0x61, 0xFF, 0xDC, 0xAA, 0x60, 0xFF, 0xDC, 0xAB, 0x61, 0xFF, 0xDC, 0xAB, 0x61, 0xFF, 0xDB, 0xAB, + 0x61, 0xFF, 0xDB, 0xAC, 0x65, 0xFF, 0xDD, 0xAF, 0x6C, 0xFF, 0xE2, 0xBA, 0x80, 0xFF, 0xE7, 0xC5, + 0x92, 0xFE, 0xEE, 0xCA, 0x9D, 0xD3, 0xF1, 0xCF, 0xA5, 0x55, 0xE9, 0xD3, 0xA4, 0x0D, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE2, 0xCC, 0xAE, 0x0E, 0xE3, 0xC3, + 0x96, 0x5C, 0xE2, 0xBE, 0x8C, 0xD2, 0xE1, 0xB9, 0x83, 0xFE, 0xDD, 0xB1, 0x76, 0xFF, 0xD9, 0xA9, + 0x68, 0xFF, 0xD9, 0xA7, 0x62, 0xFF, 0xD9, 0xA6, 0x61, 0xFF, 0xD9, 0xA7, 0x61, 0xFF, 0xD9, 0xA9, + 0x61, 0xFF, 0xDA, 0xAA, 0x62, 0xFF, 0xDB, 0xAB, 0x63, 0xFF, 0xDC, 0xAC, 0x63, 0xFF, 0xDC, 0xAC, + 0x63, 0xFF, 0xDD, 0xAD, 0x63, 0xFF, 0xDD, 0xAD, 0x63, 0xFF, 0xDD, 0xAD, 0x62, 0xFF, 0xDD, 0xAF, + 0x65, 0xFF, 0xE1, 0xB8, 0x79, 0xFF, 0xE7, 0xC6, 0x93, 0xFF, 0xE9, 0xC8, 0x97, 0xFF, 0xE8, 0xC8, + 0x96, 0xFF, 0xE8, 0xC8, 0x96, 0xFF, 0xE8, 0xC8, 0x96, 0xFF, 0xE8, 0xC8, 0x96, 0xFF, 0xE8, 0xC8, + 0x96, 0xFF, 0xE8, 0xC8, 0x96, 0xFF, 0xE8, 0xC8, 0x96, 0xFF, 0xE8, 0xC8, 0x96, 0xFF, 0xE8, 0xC8, + 0x96, 0xFF, 0xE8, 0xC8, 0x96, 0xFF, 0xE8, 0xC8, 0x96, 0xFF, 0xE8, 0xC8, 0x96, 0xFF, 0xE8, 0xC8, + 0x96, 0xFF, 0xE8, 0xC8, 0x96, 0xFF, 0xE8, 0xC8, 0x96, 0xFF, 0xE8, 0xC8, 0x96, 0xFF, 0xE8, 0xC8, + 0x96, 0xFF, 0xE8, 0xC8, 0x96, 0xFF, 0xE8, 0xC8, 0x96, 0xFF, 0xE8, 0xC8, 0x96, 0xFF, 0xE8, 0xC8, + 0x96, 0xFF, 0xE8, 0xC8, 0x96, 0xFF, 0xE8, 0xC8, 0x96, 0xFF, 0xE8, 0xC8, 0x96, 0xFF, 0xE8, 0xC8, + 0x96, 0xFF, 0xE8, 0xC8, 0x96, 0xFF, 0xE8, 0xC8, 0x96, 0xFF, 0xE7, 0xC7, 0x96, 0xFF, 0xE6, 0xC7, + 0x95, 0xFF, 0xE4, 0xC5, 0x95, 0xFF, 0xDF, 0xC4, 0x96, 0xFF, 0xE2, 0xC9, 0xA0, 0xFF, 0xE5, 0xD6, + 0xBC, 0xFF, 0xF0, 0xEA, 0xE2, 0xFF, 0xF5, 0xF4, 0xF3, 0xFF, 0xF5, 0xF5, 0xF5, 0xFF, 0xF5, 0xF6, + 0xF6, 0xFF, 0xF4, 0xF5, 0xF6, 0xFF, 0xF4, 0xF5, 0xF5, 0xFF, 0xF4, 0xF5, 0xF5, 0xFF, 0xF3, 0xF4, + 0xF4, 0xFF, 0xF3, 0xF4, 0xF4, 0xFF, 0xF3, 0xF4, 0xF4, 0xFF, 0xF3, 0xF4, 0xF4, 0xFF, 0xF2, 0xF4, + 0xF4, 0xFF, 0xF3, 0xF3, 0xF3, 0xFF, 0xF4, 0xF4, 0xF3, 0xFF, 0xF3, 0xF3, 0xF2, 0xFF, 0xF1, 0xF2, + 0xF0, 0xFF, 0xF0, 0xF1, 0xEF, 0xFF, 0xF3, 0xF4, 0xF3, 0xFF, 0xF5, 0xF5, 0xF5, 0xFF, 0xF4, 0xF4, + 0xF4, 0xFF, 0xF4, 0xF4, 0xF4, 0xFF, 0xF3, 0xF4, 0xF4, 0xFF, 0xF3, 0xF3, 0xF3, 0xFF, 0xF2, 0xF4, + 0xF4, 0xFF, 0xF3, 0xF5, 0xF5, 0xFF, 0xEE, 0xEF, 0xEA, 0xFF, 0xCE, 0xCB, 0xBB, 0xFF, 0xBD, 0xB8, + 0xA5, 0xFF, 0xE3, 0xE0, 0xD3, 0xFF, 0xF5, 0xF4, 0xF2, 0xFF, 0xF5, 0xF5, 0xF5, 0xFF, 0xF5, 0xF5, + 0xF3, 0xFF, 0xF0, 0xEA, 0xE3, 0xFF, 0xD9, 0xC9, 0xAA, 0xFF, 0xC7, 0xA8, 0x72, 0xFF, 0xCC, 0xA5, + 0x62, 0xFF, 0xD4, 0xA9, 0x63, 0xFF, 0xD8, 0xAB, 0x63, 0xFF, 0xDC, 0xAC, 0x62, 0xFF, 0xDC, 0xAC, + 0x62, 0xFF, 0xDD, 0xAD, 0x62, 0xFF, 0xDD, 0xAC, 0x62, 0xFF, 0xDD, 0xAC, 0x63, 0xFF, 0xDC, 0xAD, + 0x64, 0xFF, 0xDD, 0xAF, 0x6A, 0xFF, 0xDE, 0xB3, 0x74, 0xFF, 0xE7, 0xC4, 0x8E, 0xFF, 0xEC, 0xCB, + 0x97, 0xF4, 0xEB, 0xCB, 0xA1, 0x9A, 0xE2, 0xCA, 0xA7, 0x27, 0xC0, 0xC5, 0xB6, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE2, 0xC8, 0xA2, 0x01, 0xE1, 0xC5, + 0x9C, 0x29, 0xE5, 0xC2, 0x93, 0xA2, 0xE3, 0xBE, 0x8A, 0xF0, 0xE1, 0xB7, 0x7F, 0xFF, 0xDC, 0xAF, + 0x70, 0xFF, 0xDA, 0xAA, 0x67, 0xFF, 0xDA, 0xA9, 0x63, 0xFF, 0xDB, 0xA9, 0x63, 0xFF, 0xDB, 0xAA, + 0x63, 0xFF, 0xDC, 0xAC, 0x64, 0xFF, 0xDC, 0xAC, 0x64, 0xFF, 0xDD, 0xAD, 0x65, 0xFF, 0xDD, 0xAE, + 0x65, 0xFF, 0xDE, 0xAE, 0x65, 0xFF, 0xDE, 0xAE, 0x64, 0xFF, 0xDE, 0xAF, 0x64, 0xFF, 0xDF, 0xB1, + 0x66, 0xFF, 0xE2, 0xBA, 0x7A, 0xFF, 0xE8, 0xC8, 0x95, 0xFF, 0xEA, 0xCA, 0x99, 0xFF, 0xE9, 0xCA, + 0x99, 0xFF, 0xE9, 0xCA, 0x99, 0xFF, 0xE9, 0xCA, 0x99, 0xFF, 0xE9, 0xCA, 0x99, 0xFF, 0xE9, 0xCA, + 0x99, 0xFF, 0xE9, 0xCA, 0x99, 0xFF, 0xE9, 0xCA, 0x99, 0xFF, 0xE9, 0xCA, 0x99, 0xFF, 0xE9, 0xCA, + 0x99, 0xFF, 0xE9, 0xCA, 0x99, 0xFF, 0xE9, 0xCA, 0x99, 0xFF, 0xE9, 0xCA, 0x99, 0xFF, 0xE9, 0xCA, + 0x99, 0xFF, 0xE9, 0xCA, 0x99, 0xFF, 0xE9, 0xCA, 0x99, 0xFF, 0xE9, 0xCA, 0x99, 0xFF, 0xE9, 0xCA, + 0x99, 0xFF, 0xE9, 0xCA, 0x99, 0xFF, 0xE9, 0xCA, 0x99, 0xFF, 0xE9, 0xCA, 0x99, 0xFF, 0xE9, 0xCA, + 0x99, 0xFF, 0xE9, 0xCA, 0x99, 0xFF, 0xE9, 0xCA, 0x99, 0xFF, 0xE9, 0xCA, 0x99, 0xFF, 0xE9, 0xCA, + 0x99, 0xFF, 0xE9, 0xCA, 0x99, 0xFF, 0xE8, 0xCA, 0x99, 0xFF, 0xE9, 0xCA, 0x99, 0xFF, 0xE8, 0xC9, + 0x98, 0xFF, 0xE8, 0xC9, 0x99, 0xFF, 0xE5, 0xC8, 0x98, 0xFF, 0xE3, 0xC7, 0x99, 0xFF, 0xE0, 0xCA, + 0xA2, 0xFF, 0xE5, 0xD5, 0xBC, 0xFF, 0xED, 0xE9, 0xE1, 0xFF, 0xF6, 0xF5, 0xF2, 0xFF, 0xF6, 0xF6, + 0xF6, 0xFF, 0xF6, 0xF6, 0xF7, 0xFF, 0xF5, 0xF6, 0xF7, 0xFF, 0xF5, 0xF6, 0xF7, 0xFF, 0xF5, 0xF6, + 0xF6, 0xFF, 0xF5, 0xF6, 0xF6, 0xFF, 0xF4, 0xF5, 0xF6, 0xFF, 0xF5, 0xF5, 0xF5, 0xFF, 0xF3, 0xF4, + 0xF5, 0xFF, 0xF5, 0xF5, 0xF4, 0xFF, 0xF6, 0xF6, 0xF3, 0xFF, 0xF5, 0xF5, 0xF3, 0xFF, 0xF3, 0xF5, + 0xF4, 0xFF, 0xF4, 0xF5, 0xF4, 0xFF, 0xF4, 0xF5, 0xF5, 0xFF, 0xF5, 0xF5, 0xF5, 0xFF, 0xF4, 0xF5, + 0xF5, 0xFF, 0xF5, 0xF5, 0xF6, 0xFF, 0xF3, 0xF4, 0xF5, 0xFF, 0xF4, 0xF5, 0xF5, 0xFF, 0xF5, 0xF6, + 0xF5, 0xFF, 0xF3, 0xF4, 0xF5, 0xFF, 0xEF, 0xF0, 0xED, 0xFF, 0xE3, 0xE3, 0xDA, 0xFF, 0xE5, 0xE3, + 0xDB, 0xFF, 0xF8, 0xF8, 0xF4, 0xFF, 0xF8, 0xF9, 0xF8, 0xFF, 0xF6, 0xF6, 0xF6, 0xFF, 0xF5, 0xEE, + 0xE6, 0xFF, 0xDC, 0xCB, 0xAC, 0xFF, 0xC9, 0xAC, 0x78, 0xFF, 0xCC, 0xA6, 0x63, 0xFF, 0xD3, 0xAA, + 0x64, 0xFF, 0xD9, 0xAD, 0x64, 0xFF, 0xDC, 0xAF, 0x65, 0xFF, 0xDE, 0xAF, 0x65, 0xFF, 0xDF, 0xAF, + 0x64, 0xFF, 0xDF, 0xAF, 0x65, 0xFF, 0xDE, 0xAF, 0x65, 0xFF, 0xDF, 0xAF, 0x66, 0xFF, 0xE0, 0xB1, + 0x69, 0xFF, 0xE1, 0xB3, 0x71, 0xFF, 0xDE, 0xBA, 0x82, 0xFF, 0xEA, 0xCA, 0x97, 0xFE, 0xF1, 0xCE, + 0x98, 0xD6, 0xE5, 0xCA, 0xA9, 0x5A, 0x49, 0xAC, 0xFD, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xC7, + 0xA3, 0x10, 0xE3, 0xC4, 0x9A, 0x61, 0xE5, 0xC2, 0x8F, 0xCE, 0xE5, 0xBD, 0x87, 0xFF, 0xE1, 0xB5, + 0x7A, 0xFF, 0xDD, 0xAE, 0x6D, 0xFF, 0xDB, 0xAB, 0x66, 0xFF, 0xDD, 0xAB, 0x65, 0xFF, 0xDC, 0xAC, + 0x65, 0xFF, 0xDD, 0xAD, 0x65, 0xFF, 0xDD, 0xAE, 0x66, 0xFF, 0xDE, 0xAF, 0x67, 0xFF, 0xDE, 0xAF, + 0x67, 0xFF, 0xDF, 0xB0, 0x67, 0xFF, 0xDF, 0xB0, 0x66, 0xFF, 0xE0, 0xB0, 0x66, 0xFF, 0xE1, 0xB2, + 0x68, 0xFF, 0xE4, 0xBB, 0x7C, 0xFF, 0xE9, 0xCA, 0x96, 0xFF, 0xEA, 0xCC, 0x9B, 0xFF, 0xEA, 0xCB, + 0x9C, 0xFF, 0xEA, 0xCB, 0x9C, 0xFF, 0xEA, 0xCB, 0x9B, 0xFF, 0xEA, 0xCC, 0x9B, 0xFF, 0xEA, 0xCC, + 0x9B, 0xFF, 0xEA, 0xCC, 0x9B, 0xFF, 0xEA, 0xCC, 0x9B, 0xFF, 0xEA, 0xCC, 0x9B, 0xFF, 0xEA, 0xCB, + 0x9B, 0xFF, 0xEA, 0xCB, 0x9B, 0xFF, 0xEA, 0xCC, 0x9B, 0xFF, 0xEA, 0xCB, 0x9B, 0xFF, 0xEA, 0xCC, + 0x9B, 0xFF, 0xEA, 0xCB, 0x9B, 0xFF, 0xEA, 0xCC, 0x9B, 0xFF, 0xEA, 0xCC, 0x9B, 0xFF, 0xEA, 0xCC, + 0x9B, 0xFF, 0xEA, 0xCB, 0x9B, 0xFF, 0xEA, 0xCC, 0x9B, 0xFF, 0xEA, 0xCB, 0x9B, 0xFF, 0xEA, 0xCC, + 0x9B, 0xFF, 0xEA, 0xCC, 0x9B, 0xFF, 0xEA, 0xCC, 0x9B, 0xFF, 0xEA, 0xCC, 0x9B, 0xFF, 0xEA, 0xCC, + 0x9B, 0xFF, 0xEA, 0xCC, 0x9B, 0xFF, 0xE9, 0xCC, 0x9B, 0xFF, 0xEA, 0xCC, 0x9B, 0xFF, 0xEA, 0xCC, + 0x9C, 0xFF, 0xEA, 0xCB, 0x9B, 0xFF, 0xE9, 0xCB, 0x9B, 0xFF, 0xE6, 0xC9, 0x9B, 0xFF, 0xE2, 0xC9, + 0x9D, 0xFF, 0xE5, 0xCC, 0xA6, 0xFF, 0xE6, 0xD6, 0xBC, 0xFF, 0xF0, 0xE9, 0xE0, 0xFF, 0xF6, 0xF5, + 0xF3, 0xFF, 0xF7, 0xF7, 0xF7, 0xFF, 0xF7, 0xF7, 0xF8, 0xFF, 0xF6, 0xF8, 0xF8, 0xFF, 0xF6, 0xF8, + 0xF8, 0xFF, 0xF6, 0xF7, 0xF8, 0xFF, 0xF5, 0xF6, 0xF7, 0xFF, 0xF5, 0xF5, 0xF7, 0xFF, 0xF4, 0xF4, + 0xF4, 0xFF, 0xF1, 0xEF, 0xE8, 0xFF, 0xF1, 0xEF, 0xE9, 0xFF, 0xF7, 0xF6, 0xF4, 0xFF, 0xF6, 0xF7, + 0xF6, 0xFF, 0xF6, 0xF7, 0xF7, 0xFF, 0xF5, 0xF7, 0xF7, 0xFF, 0xF6, 0xF7, 0xF7, 0xFF, 0xF6, 0xF7, + 0xF7, 0xFF, 0xF6, 0xF6, 0xF6, 0xFF, 0xF4, 0xF6, 0xF6, 0xFF, 0xF5, 0xF6, 0xF6, 0xFF, 0xF7, 0xF7, + 0xF7, 0xFF, 0xF7, 0xF8, 0xF8, 0xFF, 0xF8, 0xF9, 0xF9, 0xFF, 0xF6, 0xF7, 0xF7, 0xFF, 0xF7, 0xF8, + 0xF7, 0xFF, 0xF9, 0xFA, 0xFA, 0xFF, 0xF9, 0xFB, 0xFA, 0xFF, 0xF5, 0xF2, 0xEC, 0xFF, 0xE1, 0xD4, + 0xBB, 0xFF, 0xCC, 0xB0, 0x7D, 0xFF, 0xCC, 0xA7, 0x68, 0xFF, 0xD1, 0xA9, 0x62, 0xFF, 0xD7, 0xAD, + 0x65, 0xFF, 0xDD, 0xAF, 0x66, 0xFF, 0xDF, 0xB1, 0x67, 0xFF, 0xE0, 0xB1, 0x67, 0xFF, 0xE0, 0xB1, + 0x66, 0xFF, 0xE0, 0xB1, 0x67, 0xFF, 0xDF, 0xB0, 0x67, 0xFF, 0xE1, 0xB1, 0x69, 0xFF, 0xE3, 0xB4, + 0x6D, 0xFF, 0xE0, 0xB8, 0x78, 0xFF, 0xE3, 0xC4, 0x8E, 0xFF, 0xEF, 0xCA, 0x98, 0xF5, 0xF2, 0xD0, + 0xA3, 0x9A, 0xDA, 0xCB, 0xAF, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xCA, + 0xAF, 0x01, 0xE0, 0xC8, 0xA8, 0x2A, 0xE5, 0xC5, 0x95, 0x97, 0xE5, 0xC1, 0x8E, 0xEE, 0xE3, 0xBB, + 0x83, 0xFF, 0xE0, 0xB3, 0x75, 0xFF, 0xDE, 0xAE, 0x6C, 0xFF, 0xDE, 0xAD, 0x69, 0xFF, 0xDE, 0xAD, + 0x67, 0xFF, 0xDE, 0xAE, 0x67, 0xFF, 0xDF, 0xAF, 0x68, 0xFF, 0xE0, 0xB1, 0x68, 0xFF, 0xE0, 0xB1, + 0x69, 0xFF, 0xE1, 0xB2, 0x69, 0xFF, 0xE1, 0xB2, 0x68, 0xFF, 0xE1, 0xB2, 0x68, 0xFF, 0xE2, 0xB3, + 0x6A, 0xFF, 0xE5, 0xBB, 0x7A, 0xFF, 0xE9, 0xCA, 0x97, 0xFF, 0xEA, 0xCD, 0x9E, 0xFF, 0xEB, 0xCD, + 0x9F, 0xFF, 0xEB, 0xCD, 0x9F, 0xFF, 0xEB, 0xCD, 0x9F, 0xFF, 0xEB, 0xCD, 0x9F, 0xFF, 0xEA, 0xCD, + 0x9F, 0xFF, 0xEB, 0xCD, 0x9F, 0xFF, 0xEA, 0xCD, 0x9F, 0xFF, 0xEB, 0xCD, 0x9F, 0xFF, 0xEA, 0xCD, + 0x9F, 0xFF, 0xEB, 0xCD, 0x9F, 0xFF, 0xEA, 0xCD, 0x9F, 0xFF, 0xEB, 0xCD, 0x9F, 0xFF, 0xEA, 0xCD, + 0x9F, 0xFF, 0xEB, 0xCD, 0x9F, 0xFF, 0xEA, 0xCD, 0x9F, 0xFF, 0xEB, 0xCD, 0x9F, 0xFF, 0xEA, 0xCD, + 0x9F, 0xFF, 0xEB, 0xCD, 0x9F, 0xFF, 0xEA, 0xCD, 0x9F, 0xFF, 0xEB, 0xCD, 0x9F, 0xFF, 0xEA, 0xCD, + 0x9F, 0xFF, 0xEB, 0xCD, 0x9F, 0xFF, 0xEB, 0xCD, 0x9F, 0xFF, 0xEB, 0xCD, 0x9F, 0xFF, 0xEA, 0xCD, + 0x9F, 0xFF, 0xEB, 0xCD, 0x9F, 0xFF, 0xEA, 0xCD, 0x9F, 0xFF, 0xEB, 0xCD, 0x9F, 0xFF, 0xEA, 0xCD, + 0x9F, 0xFF, 0xEB, 0xCD, 0x9F, 0xFF, 0xEA, 0xCC, 0x9E, 0xFF, 0xEA, 0xCC, 0x9F, 0xFF, 0xE8, 0xCC, + 0x9E, 0xFF, 0xE6, 0xCB, 0x9F, 0xFF, 0xE3, 0xCD, 0xA6, 0xFF, 0xE5, 0xD5, 0xB8, 0xFF, 0xEC, 0xE8, + 0xDC, 0xFF, 0xF6, 0xF5, 0xF1, 0xFF, 0xF8, 0xF8, 0xF8, 0xFF, 0xF8, 0xF9, 0xF9, 0xFF, 0xF6, 0xF8, + 0xF8, 0xFF, 0xF6, 0xF7, 0xF8, 0xFF, 0xF6, 0xF6, 0xF7, 0xFF, 0xF5, 0xF4, 0xF2, 0xFF, 0xEC, 0xE5, + 0xD6, 0xFF, 0xE2, 0xD7, 0xC0, 0xFF, 0xE2, 0xD9, 0xC5, 0xFF, 0xEF, 0xEC, 0xE3, 0xFF, 0xF8, 0xF7, + 0xF6, 0xFF, 0xF9, 0xF9, 0xF9, 0xFF, 0xF6, 0xF7, 0xF8, 0xFF, 0xF6, 0xF8, 0xF9, 0xFF, 0xF8, 0xF9, + 0xFA, 0xFF, 0xF8, 0xF9, 0xF9, 0xFF, 0xF7, 0xF8, 0xF8, 0xFF, 0xFA, 0xFA, 0xF7, 0xFF, 0xF8, 0xF9, + 0xF7, 0xFF, 0xF8, 0xFA, 0xF9, 0xFF, 0xF9, 0xFC, 0xFC, 0xFF, 0xF7, 0xF9, 0xFB, 0xFF, 0xF7, 0xF9, + 0xFA, 0xFF, 0xF8, 0xF9, 0xF9, 0xFF, 0xF9, 0xF6, 0xF2, 0xFF, 0xE8, 0xDF, 0xCE, 0xFF, 0xD4, 0xBE, + 0x95, 0xFF, 0xD1, 0xAD, 0x6F, 0xFF, 0xD6, 0xAD, 0x68, 0xFF, 0xDA, 0xAF, 0x66, 0xFF, 0xDE, 0xB2, + 0x67, 0xFF, 0xE1, 0xB3, 0x69, 0xFF, 0xE1, 0xB2, 0x68, 0xFF, 0xE2, 0xB3, 0x68, 0xFF, 0xE1, 0xB3, + 0x68, 0xFF, 0xE1, 0xB3, 0x69, 0xFF, 0xE1, 0xB2, 0x69, 0xFF, 0xE3, 0xB4, 0x6D, 0xFF, 0xE4, 0xBA, + 0x76, 0xFF, 0xE3, 0xBF, 0x84, 0xFF, 0xE8, 0xC9, 0x98, 0xFD, 0xEE, 0xCC, 0xA1, 0xD0, 0xEC, 0xD2, + 0xAF, 0x59, 0xE5, 0xD0, 0xB7, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xE0, 0xCB, 0xB1, 0x0D, 0xE6, 0xC9, 0x9D, 0x52, 0xE9, 0xC6, 0x93, 0xC7, 0xE7, 0xC1, + 0x8D, 0xFB, 0xE3, 0xB9, 0x81, 0xFF, 0xE0, 0xB3, 0x74, 0xFF, 0xE0, 0xB0, 0x6C, 0xFF, 0xDF, 0xAF, + 0x69, 0xFF, 0xDF, 0xB0, 0x69, 0xFF, 0xE0, 0xB1, 0x69, 0xFF, 0xE1, 0xB2, 0x6A, 0xFF, 0xE1, 0xB3, + 0x6A, 0xFF, 0xE2, 0xB4, 0x6B, 0xFF, 0xE2, 0xB4, 0x6A, 0xFF, 0xE3, 0xB4, 0x6B, 0xFF, 0xE4, 0xB5, + 0x6C, 0xFF, 0xE6, 0xBB, 0x79, 0xFF, 0xEA, 0xCA, 0x96, 0xFF, 0xEC, 0xCF, 0xA0, 0xFF, 0xEC, 0xCF, + 0xA1, 0xFF, 0xEC, 0xCF, 0xA1, 0xFF, 0xEC, 0xCF, 0xA1, 0xFF, 0xEC, 0xCF, 0xA1, 0xFF, 0xEC, 0xCF, + 0xA1, 0xFF, 0xEC, 0xCF, 0xA1, 0xFF, 0xEC, 0xCF, 0xA1, 0xFF, 0xEC, 0xCF, 0xA1, 0xFF, 0xEC, 0xCF, + 0xA1, 0xFF, 0xEC, 0xCF, 0xA1, 0xFF, 0xEC, 0xCF, 0xA1, 0xFF, 0xEC, 0xCF, 0xA1, 0xFF, 0xEC, 0xCF, + 0xA1, 0xFF, 0xEC, 0xCF, 0xA1, 0xFF, 0xEC, 0xCF, 0xA1, 0xFF, 0xEC, 0xCF, 0xA1, 0xFF, 0xEC, 0xCF, + 0xA1, 0xFF, 0xEC, 0xCF, 0xA1, 0xFF, 0xEC, 0xCF, 0xA1, 0xFF, 0xEC, 0xCF, 0xA1, 0xFF, 0xEC, 0xCF, + 0xA1, 0xFF, 0xEC, 0xCF, 0xA1, 0xFF, 0xEC, 0xCF, 0xA1, 0xFF, 0xEC, 0xCF, 0xA1, 0xFF, 0xEC, 0xCF, + 0xA1, 0xFF, 0xEC, 0xCF, 0xA1, 0xFF, 0xEC, 0xCF, 0xA1, 0xFF, 0xEC, 0xCF, 0xA1, 0xFF, 0xEC, 0xCF, + 0xA1, 0xFF, 0xEC, 0xCF, 0xA1, 0xFF, 0xEC, 0xCF, 0xA2, 0xFF, 0xEC, 0xCF, 0xA1, 0xFF, 0xEB, 0xCF, + 0xA1, 0xFF, 0xE9, 0xCD, 0xA0, 0xFF, 0xE6, 0xCD, 0xA1, 0xFF, 0xE7, 0xCE, 0xA6, 0xFF, 0xE8, 0xD6, + 0xB5, 0xFF, 0xEE, 0xE6, 0xD6, 0xFF, 0xF6, 0xF4, 0xEF, 0xFF, 0xF9, 0xF9, 0xF7, 0xFF, 0xF6, 0xF7, + 0xF6, 0xFF, 0xF7, 0xF8, 0xF9, 0xFF, 0xF6, 0xF7, 0xF6, 0xFF, 0xEA, 0xE0, 0xCD, 0xFF, 0xE1, 0xD0, + 0xAC, 0xFF, 0xDF, 0xCB, 0xA6, 0xFF, 0xE1, 0xCD, 0xA9, 0xFF, 0xE8, 0xD9, 0xBD, 0xFF, 0xF3, 0xEE, + 0xE3, 0xFF, 0xFA, 0xF9, 0xF6, 0xFF, 0xF8, 0xFA, 0xF9, 0xFF, 0xF8, 0xF9, 0xF9, 0xFF, 0xF8, 0xF9, + 0xFA, 0xFF, 0xFA, 0xFB, 0xFA, 0xFF, 0xF6, 0xF6, 0xF3, 0xFF, 0xE8, 0xE6, 0xDB, 0xFF, 0xE4, 0xE2, + 0xD7, 0xFF, 0xF2, 0xF1, 0xEB, 0xFF, 0xF8, 0xF9, 0xF9, 0xFF, 0xF7, 0xF9, 0xFA, 0xFF, 0xF8, 0xF9, + 0xF9, 0xFF, 0xF6, 0xF4, 0xEF, 0xFF, 0xEC, 0xE5, 0xD4, 0xFF, 0xDE, 0xCC, 0xAA, 0xFF, 0xD6, 0xB8, + 0x83, 0xFF, 0xD8, 0xB1, 0x6C, 0xFF, 0xDC, 0xB2, 0x6A, 0xFF, 0xDF, 0xB2, 0x69, 0xFF, 0xE1, 0xB4, + 0x6A, 0xFF, 0xE3, 0xB5, 0x6B, 0xFF, 0xE3, 0xB5, 0x6A, 0xFF, 0xE3, 0xB5, 0x6A, 0xFF, 0xE2, 0xB4, + 0x6A, 0xFF, 0xE2, 0xB5, 0x6B, 0xFF, 0xE2, 0xB4, 0x6C, 0xFF, 0xE4, 0xB8, 0x74, 0xFF, 0xE6, 0xC0, + 0x81, 0xFF, 0xE7, 0xC5, 0x8F, 0xFE, 0xEA, 0xCC, 0x9D, 0xE7, 0xEC, 0xD0, 0xA6, 0x8F, 0xEA, 0xD3, + 0xAE, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xDE, 0xCB, 0xB0, 0x01, 0xE3, 0xC8, 0xA3, 0x1E, 0xEC, 0xC9, 0x94, 0x88, 0xE7, 0xC5, + 0x93, 0xE2, 0xE7, 0xC1, 0x8A, 0xFF, 0xE4, 0xB9, 0x7D, 0xFF, 0xE2, 0xB5, 0x72, 0xFF, 0xE1, 0xB2, + 0x6D, 0xFF, 0xE1, 0xB2, 0x6C, 0xFF, 0xE1, 0xB2, 0x6C, 0xFF, 0xE2, 0xB4, 0x6C, 0xFF, 0xE2, 0xB5, + 0x6D, 0xFF, 0xE3, 0xB5, 0x6D, 0xFF, 0xE4, 0xB6, 0x6D, 0xFF, 0xE4, 0xB6, 0x6D, 0xFF, 0xE5, 0xB7, + 0x6E, 0xFF, 0xE6, 0xBC, 0x77, 0xFF, 0xEA, 0xC9, 0x92, 0xFF, 0xEE, 0xD1, 0xA2, 0xFF, 0xEE, 0xD1, + 0xA4, 0xFF, 0xEE, 0xD1, 0xA4, 0xFF, 0xEE, 0xD1, 0xA4, 0xFF, 0xEE, 0xD1, 0xA4, 0xFF, 0xED, 0xD1, + 0xA4, 0xFF, 0xEE, 0xD1, 0xA4, 0xFF, 0xED, 0xD1, 0xA4, 0xFF, 0xEE, 0xD1, 0xA4, 0xFF, 0xED, 0xD1, + 0xA4, 0xFF, 0xEE, 0xD1, 0xA4, 0xFF, 0xED, 0xD1, 0xA4, 0xFF, 0xEE, 0xD1, 0xA4, 0xFF, 0xED, 0xD1, + 0xA4, 0xFF, 0xEE, 0xD1, 0xA4, 0xFF, 0xED, 0xD1, 0xA4, 0xFF, 0xEE, 0xD1, 0xA4, 0xFF, 0xED, 0xD1, + 0xA4, 0xFF, 0xEE, 0xD1, 0xA4, 0xFF, 0xED, 0xD1, 0xA4, 0xFF, 0xEE, 0xD1, 0xA4, 0xFF, 0xED, 0xD1, + 0xA4, 0xFF, 0xEE, 0xD1, 0xA4, 0xFF, 0xED, 0xD1, 0xA4, 0xFF, 0xEE, 0xD1, 0xA4, 0xFF, 0xED, 0xD1, + 0xA4, 0xFF, 0xEE, 0xD1, 0xA4, 0xFF, 0xED, 0xD1, 0xA4, 0xFF, 0xEE, 0xD1, 0xA4, 0xFF, 0xED, 0xD1, + 0xA4, 0xFF, 0xEE, 0xD1, 0xA4, 0xFF, 0xED, 0xD1, 0xA4, 0xFF, 0xEE, 0xD1, 0xA4, 0xFF, 0xED, 0xD0, + 0xA4, 0xFF, 0xED, 0xD0, 0xA3, 0xFF, 0xEA, 0xCF, 0xA2, 0xFF, 0xE8, 0xCE, 0xA3, 0xFF, 0xE7, 0xCF, + 0xA6, 0xFF, 0xE7, 0xD3, 0xAE, 0xFF, 0xE9, 0xDE, 0xC8, 0xFF, 0xF1, 0xEC, 0xE4, 0xFF, 0xF6, 0xF5, + 0xF2, 0xFF, 0xF7, 0xF4, 0xED, 0xFF, 0xEC, 0xE1, 0xCD, 0xFF, 0xE5, 0xD1, 0xAD, 0xFF, 0xE4, 0xCD, + 0xA5, 0xFF, 0xE4, 0xCE, 0xA4, 0xFF, 0xE4, 0xCC, 0xA1, 0xFF, 0xE5, 0xCF, 0xA9, 0xFF, 0xE9, 0xDB, + 0xBE, 0xFF, 0xF4, 0xEC, 0xDF, 0xFF, 0xFA, 0xFA, 0xF5, 0xFF, 0xFB, 0xFB, 0xFA, 0xFF, 0xF9, 0xFA, + 0xFA, 0xFF, 0xF8, 0xF8, 0xF7, 0xFF, 0xE6, 0xE5, 0xDA, 0xFF, 0xC7, 0xC4, 0xB2, 0xFF, 0xD3, 0xD1, + 0xC1, 0xFF, 0xF0, 0xEF, 0xE8, 0xFF, 0xF9, 0xFB, 0xFA, 0xFF, 0xF7, 0xF9, 0xFB, 0xFF, 0xF9, 0xF5, + 0xF1, 0xFF, 0xF0, 0xE7, 0xD6, 0xFF, 0xE2, 0xD1, 0xB5, 0xFF, 0xE1, 0xC7, 0x9D, 0xFF, 0xDC, 0xBB, + 0x82, 0xFF, 0xE0, 0xB6, 0x6F, 0xFF, 0xE2, 0xB6, 0x6C, 0xFF, 0xE3, 0xB5, 0x6C, 0xFF, 0xE3, 0xB7, + 0x6D, 0xFF, 0xE4, 0xB7, 0x6D, 0xFF, 0xE4, 0xB7, 0x6D, 0xFF, 0xE4, 0xB7, 0x6D, 0xFF, 0xE4, 0xB6, + 0x6D, 0xFF, 0xE4, 0xB7, 0x6F, 0xFF, 0xE4, 0xB9, 0x73, 0xFF, 0xE6, 0xBE, 0x7F, 0xFF, 0xE9, 0xC6, + 0x8C, 0xFF, 0xEC, 0xCC, 0x99, 0xF6, 0xED, 0xD1, 0xA5, 0xBA, 0xEB, 0xD1, 0xAA, 0x49, 0xE7, 0xD2, + 0xAE, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE1, 0xCC, 0xAC, 0x06, 0xE8, 0xCD, 0xA1, 0x40, 0xEA, 0xCB, + 0x95, 0xAD, 0xEB, 0xC4, 0x91, 0xF5, 0xE9, 0xC0, 0x87, 0xFF, 0xE5, 0xB9, 0x7C, 0xFF, 0xE2, 0xB5, + 0x72, 0xFF, 0xE2, 0xB4, 0x6E, 0xFF, 0xE2, 0xB4, 0x6D, 0xFF, 0xE3, 0xB5, 0x6E, 0xFF, 0xE3, 0xB6, + 0x6E, 0xFF, 0xE4, 0xB7, 0x6F, 0xFF, 0xE5, 0xB7, 0x6F, 0xFF, 0xE5, 0xB8, 0x6F, 0xFF, 0xE5, 0xB7, + 0x6F, 0xFF, 0xE8, 0xBB, 0x75, 0xFF, 0xEB, 0xC7, 0x8D, 0xFF, 0xEF, 0xD2, 0xA2, 0xFF, 0xF0, 0xD3, + 0xA6, 0xFF, 0xEF, 0xD3, 0xA7, 0xFF, 0xEF, 0xD3, 0xA7, 0xFF, 0xEF, 0xD3, 0xA6, 0xFF, 0xEF, 0xD3, + 0xA6, 0xFF, 0xEF, 0xD3, 0xA6, 0xFF, 0xEF, 0xD3, 0xA6, 0xFF, 0xEF, 0xD3, 0xA6, 0xFF, 0xEF, 0xD3, + 0xA6, 0xFF, 0xEF, 0xD3, 0xA6, 0xFF, 0xEF, 0xD3, 0xA6, 0xFF, 0xEF, 0xD3, 0xA6, 0xFF, 0xEF, 0xD3, + 0xA6, 0xFF, 0xEF, 0xD3, 0xA6, 0xFF, 0xEF, 0xD3, 0xA6, 0xFF, 0xEF, 0xD3, 0xA6, 0xFF, 0xEF, 0xD3, + 0xA6, 0xFF, 0xEF, 0xD3, 0xA6, 0xFF, 0xEF, 0xD3, 0xA6, 0xFF, 0xEF, 0xD3, 0xA6, 0xFF, 0xEF, 0xD3, + 0xA6, 0xFF, 0xEF, 0xD3, 0xA6, 0xFF, 0xEF, 0xD3, 0xA6, 0xFF, 0xEF, 0xD3, 0xA6, 0xFF, 0xEF, 0xD3, + 0xA6, 0xFF, 0xEF, 0xD3, 0xA6, 0xFF, 0xEF, 0xD3, 0xA6, 0xFF, 0xEF, 0xD3, 0xA6, 0xFF, 0xEF, 0xD3, + 0xA6, 0xFF, 0xEF, 0xD3, 0xA6, 0xFF, 0xEF, 0xD3, 0xA6, 0xFF, 0xEF, 0xD3, 0xA6, 0xFF, 0xEF, 0xD3, + 0xA7, 0xFF, 0xEF, 0xD3, 0xA6, 0xFF, 0xEE, 0xD2, 0xA5, 0xFF, 0xED, 0xD1, 0xA5, 0xFF, 0xEC, 0xD2, + 0xA5, 0xFF, 0xED, 0xD2, 0xA7, 0xFF, 0xE9, 0xD1, 0xAC, 0xFF, 0xEB, 0xD8, 0xB9, 0xFF, 0xEF, 0xDD, + 0xC2, 0xFF, 0xED, 0xD9, 0xBA, 0xFF, 0xE6, 0xD1, 0xAB, 0xFF, 0xE6, 0xCE, 0xA6, 0xFF, 0xE8, 0xCF, + 0xA5, 0xFF, 0xE9, 0xD0, 0xA5, 0xFF, 0xE9, 0xD0, 0xA5, 0xFF, 0xE9, 0xD0, 0xA7, 0xFF, 0xE6, 0xD2, + 0xAE, 0xFF, 0xEC, 0xDA, 0xBC, 0xFF, 0xF4, 0xEC, 0xDE, 0xFF, 0xFA, 0xF9, 0xF5, 0xFF, 0xFA, 0xFA, + 0xFA, 0xFF, 0xF7, 0xF7, 0xF7, 0xFF, 0xE7, 0xE6, 0xDB, 0xFF, 0xD9, 0xD7, 0xC5, 0xFF, 0xE6, 0xE4, + 0xD9, 0xFF, 0xF6, 0xF8, 0xF4, 0xFF, 0xF8, 0xFA, 0xFC, 0xFF, 0xF7, 0xF6, 0xF6, 0xFF, 0xF1, 0xE9, + 0xD9, 0xFF, 0xE7, 0xD7, 0xB8, 0xFF, 0xE3, 0xCD, 0xA8, 0xFF, 0xE5, 0xC8, 0x99, 0xFF, 0xE0, 0xBB, + 0x7E, 0xFF, 0xE4, 0xB8, 0x70, 0xFF, 0xE4, 0xB8, 0x6F, 0xFF, 0xE5, 0xB8, 0x6E, 0xFF, 0xE6, 0xB9, + 0x6F, 0xFF, 0xE6, 0xB9, 0x6F, 0xFF, 0xE5, 0xB8, 0x6F, 0xFF, 0xE5, 0xB8, 0x70, 0xFF, 0xE5, 0xB8, + 0x70, 0xFF, 0xE5, 0xBA, 0x74, 0xFF, 0xE7, 0xBE, 0x7C, 0xFF, 0xE8, 0xC3, 0x88, 0xFF, 0xED, 0xCA, + 0x94, 0xFE, 0xEE, 0xCF, 0xA0, 0xD9, 0xEC, 0xD3, 0xAE, 0x76, 0xEA, 0xD4, 0xB0, 0x19, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCD, 0xD9, 0xE4, 0x0D, 0xEE, 0xCB, + 0x9C, 0x62, 0xEB, 0xC9, 0x92, 0xD3, 0xEA, 0xC5, 0x8E, 0xFF, 0xE8, 0xC0, 0x88, 0xFF, 0xE4, 0xBA, + 0x7A, 0xFF, 0xE3, 0xB6, 0x72, 0xFF, 0xE4, 0xB6, 0x70, 0xFF, 0xE5, 0xB6, 0x70, 0xFF, 0xE4, 0xB7, + 0x70, 0xFF, 0xE5, 0xB8, 0x70, 0xFF, 0xE5, 0xB9, 0x71, 0xFF, 0xE6, 0xB9, 0x71, 0xFF, 0xE6, 0xB8, + 0x70, 0xFF, 0xE7, 0xBA, 0x74, 0xFF, 0xEA, 0xC4, 0x86, 0xFF, 0xF0, 0xD3, 0xA2, 0xFF, 0xF0, 0xD4, + 0xA8, 0xFF, 0xF0, 0xD5, 0xA9, 0xFF, 0xF0, 0xD5, 0xA9, 0xFF, 0xF0, 0xD5, 0xA9, 0xFF, 0xF0, 0xD5, + 0xA9, 0xFF, 0xF0, 0xD5, 0xA9, 0xFF, 0xF0, 0xD5, 0xA9, 0xFF, 0xF0, 0xD5, 0xA9, 0xFF, 0xF0, 0xD5, + 0xA9, 0xFF, 0xF0, 0xD5, 0xA9, 0xFF, 0xF0, 0xD5, 0xA9, 0xFF, 0xF0, 0xD5, 0xA9, 0xFF, 0xF0, 0xD5, + 0xA9, 0xFF, 0xF0, 0xD5, 0xA9, 0xFF, 0xF0, 0xD5, 0xA9, 0xFF, 0xF0, 0xD5, 0xA9, 0xFF, 0xF0, 0xD5, + 0xA9, 0xFF, 0xF0, 0xD5, 0xA9, 0xFF, 0xF0, 0xD5, 0xA9, 0xFF, 0xF0, 0xD5, 0xA9, 0xFF, 0xF0, 0xD5, + 0xA9, 0xFF, 0xF0, 0xD5, 0xA9, 0xFF, 0xF0, 0xD5, 0xA9, 0xFF, 0xF0, 0xD5, 0xA9, 0xFF, 0xF0, 0xD5, + 0xA9, 0xFF, 0xF0, 0xD5, 0xA9, 0xFF, 0xF0, 0xD5, 0xA9, 0xFF, 0xF0, 0xD5, 0xA9, 0xFF, 0xF0, 0xD5, + 0xA9, 0xFF, 0xF0, 0xD5, 0xA9, 0xFF, 0xF0, 0xD5, 0xA9, 0xFF, 0xF0, 0xD5, 0xA9, 0xFF, 0xF0, 0xD5, + 0xA9, 0xFF, 0xF0, 0xD5, 0xA9, 0xFF, 0xF0, 0xD5, 0xA8, 0xFF, 0xEF, 0xD5, 0xA8, 0xFF, 0xEE, 0xD4, + 0xA7, 0xFF, 0xEE, 0xD3, 0xA9, 0xFF, 0xED, 0xD2, 0xA9, 0xFF, 0xED, 0xD3, 0xA9, 0xFF, 0xEC, 0xD4, + 0xAC, 0xFF, 0xEB, 0xD3, 0xAB, 0xFF, 0xEC, 0xD3, 0xA9, 0xFF, 0xED, 0xD2, 0xA9, 0xFF, 0xED, 0xD3, + 0xA7, 0xFF, 0xEE, 0xD4, 0xA8, 0xFF, 0xEE, 0xD3, 0xA8, 0xFF, 0xED, 0xD3, 0xA8, 0xFF, 0xEA, 0xD2, + 0xA9, 0xFF, 0xE8, 0xD2, 0xAB, 0xFF, 0xEA, 0xD9, 0xB9, 0xFF, 0xF4, 0xEB, 0xDB, 0xFF, 0xFB, 0xF9, + 0xF4, 0xFF, 0xFB, 0xFA, 0xF8, 0xFF, 0xF6, 0xF6, 0xF2, 0xFF, 0xF5, 0xF5, 0xF1, 0xFF, 0xF7, 0xF9, + 0xF5, 0xFF, 0xF9, 0xFB, 0xFC, 0xFF, 0xF9, 0xF8, 0xF9, 0xFF, 0xF3, 0xEC, 0xE0, 0xFF, 0xE5, 0xD6, + 0xBA, 0xFF, 0xE5, 0xD0, 0xAC, 0xFF, 0xE7, 0xD1, 0xAB, 0xFF, 0xE8, 0xC8, 0x94, 0xFF, 0xE3, 0xBB, + 0x78, 0xFF, 0xE6, 0xBA, 0x72, 0xFF, 0xE6, 0xBA, 0x71, 0xFF, 0xE7, 0xBA, 0x70, 0xFF, 0xE7, 0xBA, + 0x71, 0xFF, 0xE7, 0xBA, 0x70, 0xFF, 0xE6, 0xBA, 0x71, 0xFF, 0xE7, 0xBA, 0x72, 0xFF, 0xE7, 0xBB, + 0x73, 0xFF, 0xE8, 0xBE, 0x7A, 0xFF, 0xEA, 0xC4, 0x87, 0xFF, 0xEC, 0xC9, 0x92, 0xFF, 0xEE, 0xCF, + 0x9C, 0xEE, 0xEF, 0xD4, 0xA8, 0x9C, 0xEB, 0xD6, 0xBA, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8, 0xCD, + 0xA8, 0x25, 0xEE, 0xCC, 0x99, 0x89, 0xEB, 0xC8, 0x93, 0xE6, 0xEA, 0xC5, 0x8F, 0xFF, 0xE8, 0xC0, + 0x85, 0xFF, 0xE6, 0xBA, 0x7A, 0xFF, 0xE5, 0xB8, 0x73, 0xFF, 0xE6, 0xB8, 0x72, 0xFF, 0xE6, 0xB8, + 0x71, 0xFF, 0xE6, 0xB9, 0x71, 0xFF, 0xE6, 0xBA, 0x72, 0xFF, 0xE7, 0xBA, 0x72, 0xFF, 0xE6, 0xBA, + 0x72, 0xFF, 0xE8, 0xBB, 0x74, 0xFF, 0xEB, 0xC2, 0x81, 0xFF, 0xEE, 0xCF, 0x9E, 0xFF, 0xF0, 0xD5, + 0xA9, 0xFF, 0xF1, 0xD6, 0xAB, 0xFF, 0xF1, 0xD7, 0xAB, 0xFF, 0xF1, 0xD6, 0xAB, 0xFF, 0xF1, 0xD6, + 0xAB, 0xFF, 0xF1, 0xD6, 0xAB, 0xFF, 0xF1, 0xD6, 0xAB, 0xFF, 0xF1, 0xD6, 0xAB, 0xFF, 0xF0, 0xD7, + 0xAB, 0xFF, 0xF1, 0xD7, 0xAB, 0xFF, 0xF1, 0xD7, 0xAB, 0xFF, 0xF1, 0xD7, 0xAB, 0xFF, 0xF1, 0xD7, + 0xAB, 0xFF, 0xF1, 0xD7, 0xAB, 0xFF, 0xF1, 0xD7, 0xAB, 0xFF, 0xF1, 0xD7, 0xAB, 0xFF, 0xF1, 0xD7, + 0xAB, 0xFF, 0xF1, 0xD7, 0xAB, 0xFF, 0xF1, 0xD7, 0xAB, 0xFF, 0xF1, 0xD7, 0xAB, 0xFF, 0xF1, 0xD7, + 0xAB, 0xFF, 0xF1, 0xD7, 0xAB, 0xFF, 0xF1, 0xD7, 0xAB, 0xFF, 0xF1, 0xD7, 0xAB, 0xFF, 0xF1, 0xD7, + 0xAB, 0xFF, 0xF1, 0xD7, 0xAB, 0xFF, 0xF1, 0xD7, 0xAB, 0xFF, 0xF1, 0xD7, 0xAB, 0xFF, 0xF1, 0xD7, + 0xAB, 0xFF, 0xF1, 0xD7, 0xAB, 0xFF, 0xF1, 0xD7, 0xAB, 0xFF, 0xF1, 0xD6, 0xAB, 0xFF, 0xF1, 0xD7, + 0xAB, 0xFF, 0xF1, 0xD7, 0xAB, 0xFF, 0xF1, 0xD7, 0xAB, 0xFF, 0xF1, 0xD6, 0xAA, 0xFF, 0xF0, 0xD6, + 0xAA, 0xFF, 0xF0, 0xD5, 0xAA, 0xFF, 0xEF, 0xD5, 0xAA, 0xFF, 0xEF, 0xD4, 0xAB, 0xFF, 0xED, 0xD4, + 0xAB, 0xFF, 0xEE, 0xD5, 0xAB, 0xFF, 0xEE, 0xD5, 0xAB, 0xFF, 0xF0, 0xD6, 0xAB, 0xFF, 0xF0, 0xD6, + 0xAA, 0xFF, 0xF1, 0xD6, 0xAA, 0xFF, 0xF0, 0xD6, 0xAA, 0xFF, 0xEF, 0xD5, 0xAB, 0xFF, 0xEE, 0xD5, + 0xAB, 0xFF, 0xEB, 0xD4, 0xAA, 0xFF, 0xE7, 0xD2, 0xAC, 0xFF, 0xEA, 0xD8, 0xB7, 0xFF, 0xF3, 0xEB, + 0xD7, 0xFF, 0xFB, 0xFA, 0xF3, 0xFF, 0xF9, 0xFA, 0xF9, 0xFF, 0xFA, 0xFA, 0xF9, 0xFF, 0xFA, 0xFB, + 0xFA, 0xFF, 0xFC, 0xFC, 0xFB, 0xFF, 0xF6, 0xF1, 0xE5, 0xFF, 0xE9, 0xDA, 0xBB, 0xFF, 0xE3, 0xD0, + 0xAC, 0xFF, 0xE7, 0xD2, 0xAB, 0xFF, 0xE8, 0xD1, 0xA8, 0xFF, 0xEB, 0xC7, 0x8B, 0xFF, 0xE7, 0xBD, + 0x76, 0xFF, 0xE7, 0xBC, 0x74, 0xFF, 0xE8, 0xBC, 0x73, 0xFF, 0xE8, 0xBC, 0x72, 0xFF, 0xE8, 0xBB, + 0x72, 0xFF, 0xE8, 0xBB, 0x72, 0xFF, 0xE7, 0xBB, 0x73, 0xFF, 0xE9, 0xBC, 0x75, 0xFF, 0xE9, 0xBE, + 0x78, 0xFF, 0xE9, 0xC3, 0x82, 0xFF, 0xEC, 0xCA, 0x90, 0xFF, 0xED, 0xCE, 0x9C, 0xF8, 0xEF, 0xD2, + 0xA5, 0xBB, 0xEF, 0xD6, 0xAE, 0x54, 0xEC, 0xD7, 0xBB, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0xD2, + 0xB6, 0x06, 0xF1, 0xD4, 0xAA, 0x3C, 0xEE, 0xCD, 0x9A, 0xA6, 0xEC, 0xC9, 0x93, 0xF2, 0xEC, 0xC6, + 0x8F, 0xFF, 0xEA, 0xC2, 0x87, 0xFF, 0xE7, 0xBC, 0x7B, 0xFF, 0xE6, 0xBA, 0x75, 0xFF, 0xE7, 0xBA, + 0x74, 0xFF, 0xE7, 0xBA, 0x74, 0xFF, 0xE7, 0xBB, 0x74, 0xFF, 0xE8, 0xBC, 0x74, 0xFF, 0xE8, 0xBC, + 0x73, 0xFF, 0xE8, 0xBC, 0x74, 0xFF, 0xEC, 0xC1, 0x7D, 0xFF, 0xED, 0xCB, 0x96, 0xFF, 0xF0, 0xD5, + 0xAA, 0xFF, 0xF2, 0xD7, 0xAD, 0xFF, 0xF1, 0xD8, 0xAD, 0xFF, 0xF1, 0xD8, 0xAE, 0xFF, 0xF1, 0xD7, + 0xAD, 0xFF, 0xF1, 0xD7, 0xAD, 0xFF, 0xF1, 0xD7, 0xAD, 0xFF, 0xF1, 0xD7, 0xAD, 0xFF, 0xF1, 0xD8, + 0xAD, 0xFF, 0xF1, 0xD8, 0xAD, 0xFF, 0xF1, 0xD8, 0xAD, 0xFF, 0xF1, 0xD8, 0xAD, 0xFF, 0xF1, 0xD8, + 0xAD, 0xFF, 0xF1, 0xD8, 0xAD, 0xFF, 0xF1, 0xD8, 0xAD, 0xFF, 0xF1, 0xD8, 0xAD, 0xFF, 0xF1, 0xD8, + 0xAD, 0xFF, 0xF1, 0xD8, 0xAD, 0xFF, 0xF1, 0xD8, 0xAD, 0xFF, 0xF1, 0xD8, 0xAD, 0xFF, 0xF1, 0xD8, + 0xAD, 0xFF, 0xF1, 0xD8, 0xAD, 0xFF, 0xF1, 0xD8, 0xAD, 0xFF, 0xF1, 0xD8, 0xAD, 0xFF, 0xF1, 0xD8, + 0xAD, 0xFF, 0xF1, 0xD8, 0xAD, 0xFF, 0xF1, 0xD8, 0xAD, 0xFF, 0xF1, 0xD8, 0xAD, 0xFF, 0xF1, 0xD8, + 0xAD, 0xFF, 0xF1, 0xD8, 0xAD, 0xFF, 0xF1, 0xD8, 0xAD, 0xFF, 0xF1, 0xD8, 0xAD, 0xFF, 0xF1, 0xD7, + 0xAD, 0xFF, 0xF1, 0xD7, 0xAD, 0xFF, 0xF1, 0xD8, 0xAD, 0xFF, 0xF1, 0xD8, 0xAD, 0xFF, 0xF1, 0xD8, + 0xAD, 0xFF, 0xF1, 0xD8, 0xAD, 0xFF, 0xF0, 0xD7, 0xAD, 0xFF, 0xF1, 0xD7, 0xAD, 0xFF, 0xF0, 0xD6, + 0xAD, 0xFF, 0xF0, 0xD7, 0xAD, 0xFF, 0xF0, 0xD7, 0xAD, 0xFF, 0xF1, 0xD8, 0xAD, 0xFF, 0xF1, 0xD8, + 0xAD, 0xFF, 0xF1, 0xD8, 0xAD, 0xFF, 0xF1, 0xD8, 0xAD, 0xFF, 0xF1, 0xD8, 0xAD, 0xFF, 0xF0, 0xD7, + 0xAC, 0xFF, 0xEF, 0xD6, 0xAC, 0xFF, 0xEC, 0xD5, 0xAC, 0xFF, 0xEA, 0xD4, 0xAD, 0xFF, 0xE9, 0xD7, + 0xB6, 0xFF, 0xF2, 0xE9, 0xD3, 0xFF, 0xF8, 0xF7, 0xF2, 0xFF, 0xFB, 0xFA, 0xF8, 0xFF, 0xFB, 0xF9, + 0xF7, 0xFF, 0xF7, 0xF3, 0xE9, 0xFF, 0xEA, 0xDD, 0xC2, 0xFF, 0xE8, 0xD4, 0xAF, 0xFF, 0xE8, 0xD3, + 0xAC, 0xFF, 0xEC, 0xD5, 0xAE, 0xFF, 0xEA, 0xD2, 0xA3, 0xFF, 0xEE, 0xC6, 0x82, 0xFF, 0xE8, 0xBE, + 0x76, 0xFF, 0xE9, 0xBD, 0x75, 0xFF, 0xE9, 0xBD, 0x75, 0xFF, 0xE9, 0xBD, 0x74, 0xFF, 0xE8, 0xBD, + 0x74, 0xFF, 0xE8, 0xBD, 0x75, 0xFF, 0xE9, 0xBD, 0x76, 0xFF, 0xEB, 0xBF, 0x79, 0xFF, 0xE9, 0xC3, + 0x82, 0xFF, 0xEC, 0xCA, 0x8E, 0xFF, 0xEE, 0xD0, 0x9A, 0xFF, 0xEF, 0xD4, 0xA5, 0xD4, 0xEE, 0xD5, + 0xAE, 0x6F, 0xEE, 0xD7, 0xB4, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xEE, 0xD4, 0xAD, 0x12, 0xEF, 0xD1, 0xA7, 0x56, 0xEF, 0xCD, 0x9B, 0xC0, 0xEE, 0xCA, + 0x94, 0xF9, 0xED, 0xC7, 0x8E, 0xFF, 0xEB, 0xC2, 0x85, 0xFF, 0xE9, 0xBD, 0x7C, 0xFF, 0xE7, 0xBB, + 0x77, 0xFF, 0xE8, 0xBC, 0x76, 0xFF, 0xE8, 0xBC, 0x75, 0xFF, 0xE9, 0xBC, 0x75, 0xFF, 0xE9, 0xBD, + 0x75, 0xFF, 0xE9, 0xBD, 0x75, 0xFF, 0xEA, 0xBF, 0x7A, 0xFF, 0xEE, 0xC9, 0x8C, 0xFF, 0xF1, 0xD4, + 0xA8, 0xFF, 0xF3, 0xD8, 0xAF, 0xFF, 0xF2, 0xD9, 0xB0, 0xFF, 0xF2, 0xD9, 0xB0, 0xFF, 0xF2, 0xD9, + 0xAF, 0xFF, 0xF2, 0xD8, 0xAF, 0xFF, 0xF2, 0xD9, 0xAF, 0xFF, 0xF2, 0xD9, 0xAF, 0xFF, 0xF2, 0xD9, + 0xAF, 0xFF, 0xF2, 0xD9, 0xAF, 0xFF, 0xF2, 0xDA, 0xAF, 0xFF, 0xF2, 0xD9, 0xAF, 0xFF, 0xF2, 0xDA, + 0xAF, 0xFF, 0xF2, 0xD9, 0xAF, 0xFF, 0xF2, 0xDA, 0xAF, 0xFF, 0xF2, 0xD9, 0xAF, 0xFF, 0xF2, 0xDA, + 0xAF, 0xFF, 0xF2, 0xD9, 0xAF, 0xFF, 0xF2, 0xDA, 0xAF, 0xFF, 0xF2, 0xD9, 0xAF, 0xFF, 0xF2, 0xDA, + 0xAF, 0xFF, 0xF2, 0xD9, 0xAF, 0xFF, 0xF2, 0xDA, 0xAF, 0xFF, 0xF2, 0xD9, 0xAF, 0xFF, 0xF2, 0xDA, + 0xAF, 0xFF, 0xF2, 0xD9, 0xAF, 0xFF, 0xF2, 0xDA, 0xAF, 0xFF, 0xF2, 0xD9, 0xAF, 0xFF, 0xF2, 0xDA, + 0xAF, 0xFF, 0xF2, 0xD9, 0xAF, 0xFF, 0xF2, 0xDA, 0xAF, 0xFF, 0xF2, 0xD9, 0xAF, 0xFF, 0xF2, 0xD9, + 0xAF, 0xFF, 0xF2, 0xD9, 0xAF, 0xFF, 0xF2, 0xD9, 0xAF, 0xFF, 0xF2, 0xD9, 0xAF, 0xFF, 0xF2, 0xD9, + 0xAF, 0xFF, 0xF2, 0xD9, 0xAF, 0xFF, 0xF1, 0xD9, 0xAF, 0xFF, 0xF2, 0xD9, 0xAF, 0xFF, 0xF2, 0xD9, + 0xAF, 0xFF, 0xF2, 0xD9, 0xAF, 0xFF, 0xF2, 0xDA, 0xAF, 0xFF, 0xF2, 0xDA, 0xB0, 0xFF, 0xF2, 0xDA, + 0xB0, 0xFF, 0xF2, 0xDA, 0xB0, 0xFF, 0xF2, 0xDA, 0xAF, 0xFF, 0xF2, 0xD9, 0xAF, 0xFF, 0xF2, 0xD9, + 0xAF, 0xFF, 0xF1, 0xD8, 0xAF, 0xFF, 0xF0, 0xD8, 0xAF, 0xFF, 0xEF, 0xD8, 0xAF, 0xFF, 0xEC, 0xD6, + 0xAF, 0xFF, 0xEC, 0xD8, 0xB5, 0xFF, 0xF1, 0xE6, 0xD1, 0xFF, 0xF8, 0xF1, 0xE6, 0xFF, 0xF8, 0xF2, + 0xE4, 0xFF, 0xEF, 0xE2, 0xC9, 0xFF, 0xE9, 0xD7, 0xB3, 0xFF, 0xEA, 0xD6, 0xAF, 0xFF, 0xEC, 0xD6, + 0xAD, 0xFF, 0xF1, 0xD9, 0xAF, 0xFF, 0xEC, 0xCF, 0x9A, 0xFF, 0xEE, 0xC2, 0x7C, 0xFF, 0xE9, 0xBF, + 0x77, 0xFF, 0xEA, 0xBE, 0x76, 0xFF, 0xEA, 0xBF, 0x76, 0xFF, 0xEA, 0xBE, 0x76, 0xFF, 0xE9, 0xBE, + 0x76, 0xFF, 0xEA, 0xBF, 0x78, 0xFF, 0xEB, 0xC0, 0x7A, 0xFF, 0xEB, 0xC3, 0x82, 0xFF, 0xEC, 0xC9, + 0x90, 0xFF, 0xEF, 0xCE, 0x9A, 0xFE, 0xEF, 0xD3, 0xA1, 0xE2, 0xF1, 0xD7, 0xA9, 0x89, 0xEC, 0xD6, + 0xB7, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEC, 0xD4, 0xAC, 0x1B, 0xED, 0xD1, 0xA7, 0x6E, 0xEE, 0xCD, + 0x9B, 0xD1, 0xEE, 0xCA, 0x93, 0xFF, 0xED, 0xC8, 0x8E, 0xFF, 0xEC, 0xC4, 0x87, 0xFF, 0xE9, 0xBF, + 0x7D, 0xFF, 0xE9, 0xBE, 0x79, 0xFF, 0xE9, 0xBE, 0x78, 0xFF, 0xEA, 0xBE, 0x77, 0xFF, 0xEA, 0xBE, + 0x77, 0xFF, 0xEA, 0xBF, 0x77, 0xFF, 0xEB, 0xC0, 0x79, 0xFF, 0xEE, 0xC5, 0x82, 0xFF, 0xF1, 0xD1, + 0x9E, 0xFF, 0xF3, 0xD9, 0xB0, 0xFF, 0xF4, 0xDA, 0xB2, 0xFF, 0xF3, 0xDA, 0xB2, 0xFF, 0xF3, 0xDA, + 0xB2, 0xFF, 0xF3, 0xDA, 0xB2, 0xFF, 0xF3, 0xDB, 0xB2, 0xFF, 0xF3, 0xDB, 0xB2, 0xFF, 0xF3, 0xDB, + 0xB2, 0xFF, 0xF3, 0xDB, 0xB2, 0xFF, 0xF3, 0xDB, 0xB2, 0xFF, 0xF3, 0xDB, 0xB2, 0xFF, 0xF3, 0xDB, + 0xB2, 0xFF, 0xF3, 0xDB, 0xB2, 0xFF, 0xF3, 0xDB, 0xB2, 0xFF, 0xF3, 0xDB, 0xB2, 0xFF, 0xF3, 0xDB, + 0xB2, 0xFF, 0xF3, 0xDB, 0xB2, 0xFF, 0xF3, 0xDB, 0xB2, 0xFF, 0xF3, 0xDB, 0xB2, 0xFF, 0xF3, 0xDB, + 0xB2, 0xFF, 0xF3, 0xDB, 0xB2, 0xFF, 0xF3, 0xDB, 0xB2, 0xFF, 0xF3, 0xDB, 0xB2, 0xFF, 0xF3, 0xDB, + 0xB2, 0xFF, 0xF3, 0xDB, 0xB2, 0xFF, 0xF3, 0xDB, 0xB2, 0xFF, 0xF3, 0xDB, 0xB2, 0xFF, 0xF3, 0xDB, + 0xB2, 0xFF, 0xF3, 0xDB, 0xB2, 0xFF, 0xF3, 0xDB, 0xB2, 0xFF, 0xF3, 0xDB, 0xB2, 0xFF, 0xF3, 0xDB, + 0xB2, 0xFF, 0xF3, 0xDB, 0xB2, 0xFF, 0xF3, 0xDB, 0xB2, 0xFF, 0xF3, 0xDB, 0xB2, 0xFF, 0xF3, 0xDA, + 0xB2, 0xFF, 0xF3, 0xDA, 0xB2, 0xFF, 0xF3, 0xDB, 0xB2, 0xFF, 0xF3, 0xDB, 0xB2, 0xFF, 0xF3, 0xDB, + 0xB2, 0xFF, 0xF3, 0xDB, 0xB2, 0xFF, 0xF3, 0xDB, 0xB2, 0xFF, 0xF3, 0xDB, 0xB2, 0xFF, 0xF3, 0xDB, + 0xB2, 0xFF, 0xF3, 0xDB, 0xB2, 0xFF, 0xF3, 0xDB, 0xB2, 0xFF, 0xF3, 0xDB, 0xB1, 0xFF, 0xF3, 0xDB, + 0xB2, 0xFF, 0xF3, 0xDB, 0xB2, 0xFF, 0xF2, 0xDA, 0xB2, 0xFF, 0xF1, 0xD9, 0xB1, 0xFF, 0xF1, 0xDA, + 0xB1, 0xFF, 0xEF, 0xD8, 0xB2, 0xFF, 0xEC, 0xDA, 0xB6, 0xFF, 0xF0, 0xE1, 0xC4, 0xFF, 0xF0, 0xE1, + 0xC4, 0xFF, 0xED, 0xDB, 0xB6, 0xFF, 0xEF, 0xDA, 0xB2, 0xFF, 0xF0, 0xDA, 0xB1, 0xFF, 0xF0, 0xD8, + 0xAF, 0xFF, 0xF3, 0xD9, 0xAB, 0xFF, 0xED, 0xCA, 0x8E, 0xFF, 0xEB, 0xC0, 0x7A, 0xFF, 0xEA, 0xBF, + 0x78, 0xFF, 0xEB, 0xC0, 0x78, 0xFF, 0xEB, 0xC0, 0x78, 0xFF, 0xEA, 0xC0, 0x79, 0xFF, 0xEA, 0xC0, + 0x7A, 0xFF, 0xEB, 0xC2, 0x7D, 0xFF, 0xEC, 0xC5, 0x83, 0xFF, 0xED, 0xCA, 0x91, 0xFF, 0xF1, 0xD2, + 0x9D, 0xFF, 0xF3, 0xD5, 0xA4, 0xEA, 0xF4, 0xD5, 0xA3, 0xA0, 0xF2, 0xD7, 0xA8, 0x3B, 0xE8, 0xD9, + 0xBF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xED, 0xD4, 0xAA, 0x25, 0xF0, 0xD2, + 0xA3, 0x7E, 0xF0, 0xCF, 0x9B, 0xD8, 0xEF, 0xCC, 0x95, 0xFD, 0xEE, 0xC8, 0x8E, 0xFF, 0xEC, 0xC4, + 0x85, 0xFF, 0xEB, 0xC0, 0x7E, 0xFF, 0xEA, 0xBF, 0x7A, 0xFF, 0xEB, 0xBF, 0x79, 0xFF, 0xEB, 0xBF, + 0x79, 0xFF, 0xEB, 0xC0, 0x78, 0xFF, 0xEB, 0xC0, 0x79, 0xFF, 0xEE, 0xC3, 0x7D, 0xFF, 0xF1, 0xCD, + 0x8F, 0xFF, 0xF2, 0xD8, 0xAC, 0xFF, 0xF4, 0xDC, 0xB4, 0xFF, 0xF4, 0xDC, 0xB4, 0xFF, 0xF4, 0xDC, + 0xB4, 0xFF, 0xF4, 0xDC, 0xB4, 0xFF, 0xF4, 0xDC, 0xB4, 0xFF, 0xF4, 0xDD, 0xB4, 0xFF, 0xF4, 0xDD, + 0xB4, 0xFF, 0xF4, 0xDD, 0xB4, 0xFF, 0xF4, 0xDD, 0xB4, 0xFF, 0xF4, 0xDD, 0xB4, 0xFF, 0xF4, 0xDD, + 0xB4, 0xFF, 0xF4, 0xDD, 0xB4, 0xFF, 0xF4, 0xDD, 0xB4, 0xFF, 0xF4, 0xDD, 0xB4, 0xFF, 0xF4, 0xDD, + 0xB4, 0xFF, 0xF4, 0xDD, 0xB4, 0xFF, 0xF4, 0xDD, 0xB4, 0xFF, 0xF4, 0xDD, 0xB4, 0xFF, 0xF4, 0xDD, + 0xB4, 0xFF, 0xF4, 0xDD, 0xB4, 0xFF, 0xF4, 0xDD, 0xB4, 0xFF, 0xF4, 0xDD, 0xB4, 0xFF, 0xF4, 0xDD, + 0xB4, 0xFF, 0xF4, 0xDD, 0xB4, 0xFF, 0xF4, 0xDD, 0xB4, 0xFF, 0xF4, 0xDD, 0xB4, 0xFF, 0xF4, 0xDD, + 0xB4, 0xFF, 0xF4, 0xDD, 0xB4, 0xFF, 0xF4, 0xDD, 0xB4, 0xFF, 0xF4, 0xDD, 0xB4, 0xFF, 0xF4, 0xDD, + 0xB4, 0xFF, 0xF4, 0xDD, 0xB4, 0xFF, 0xF4, 0xDD, 0xB4, 0xFF, 0xF4, 0xDC, 0xB4, 0xFF, 0xF4, 0xDC, + 0xB4, 0xFF, 0xF4, 0xDC, 0xB4, 0xFF, 0xF4, 0xDD, 0xB4, 0xFF, 0xF4, 0xDD, 0xB4, 0xFF, 0xF4, 0xDD, + 0xB4, 0xFF, 0xF4, 0xDD, 0xB4, 0xFF, 0xF4, 0xDD, 0xB4, 0xFF, 0xF4, 0xDD, 0xB4, 0xFF, 0xF4, 0xDC, + 0xB4, 0xFF, 0xF4, 0xDC, 0xB4, 0xFF, 0xF4, 0xDD, 0xB4, 0xFF, 0xF4, 0xDD, 0xB4, 0xFF, 0xF4, 0xDD, + 0xB4, 0xFF, 0xF4, 0xDD, 0xB4, 0xFF, 0xF4, 0xDC, 0xB4, 0xFF, 0xF4, 0xDC, 0xB4, 0xFF, 0xF3, 0xDC, + 0xB3, 0xFF, 0xF2, 0xDA, 0xB3, 0xFF, 0xEF, 0xDA, 0xB4, 0xFF, 0xF1, 0xDC, 0xB7, 0xFF, 0xF0, 0xDC, + 0xB8, 0xFF, 0xF0, 0xDB, 0xB5, 0xFF, 0xF2, 0xDC, 0xB5, 0xFF, 0xF3, 0xDC, 0xB3, 0xFF, 0xF3, 0xDB, + 0xB1, 0xFF, 0xF3, 0xD5, 0xA1, 0xFF, 0xEC, 0xC6, 0x83, 0xFF, 0xEA, 0xC0, 0x79, 0xFF, 0xEC, 0xC2, + 0x7A, 0xFF, 0xED, 0xC1, 0x7A, 0xFF, 0xEC, 0xC2, 0x7A, 0xFF, 0xEC, 0xC2, 0x7C, 0xFF, 0xEC, 0xC3, + 0x7D, 0xFF, 0xEC, 0xC5, 0x84, 0xFF, 0xEF, 0xCB, 0x8F, 0xFF, 0xF0, 0xD0, 0x9D, 0xFF, 0xF3, 0xD4, + 0xA2, 0xEE, 0xF3, 0xD6, 0xA6, 0xB2, 0xF1, 0xD8, 0xB0, 0x4A, 0xE9, 0xDB, 0xC1, 0x0A, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF1, 0xD5, + 0xA8, 0x2C, 0xF2, 0xD4, 0xA5, 0x89, 0xEF, 0xCF, 0x9C, 0xDE, 0xEE, 0xCC, 0x94, 0xFF, 0xEE, 0xCA, + 0x8F, 0xFF, 0xED, 0xC6, 0x88, 0xFF, 0xEC, 0xC2, 0x7F, 0xFF, 0xEC, 0xC1, 0x7C, 0xFF, 0xEC, 0xC1, + 0x7B, 0xFF, 0xEC, 0xC1, 0x7A, 0xFF, 0xEC, 0xC1, 0x7A, 0xFF, 0xED, 0xC2, 0x7C, 0xFF, 0xF1, 0xC8, + 0x83, 0xFF, 0xF2, 0xD3, 0xA2, 0xFF, 0xF4, 0xDC, 0xB3, 0xFF, 0xF6, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, + 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, + 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, + 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, + 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, + 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, + 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, + 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, + 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, + 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, + 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, + 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, + 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF4, 0xDE, + 0xB6, 0xFF, 0xF4, 0xDD, 0xB6, 0xFF, 0xF3, 0xDD, 0xB6, 0xFF, 0xF3, 0xDD, 0xB7, 0xFF, 0xF3, 0xDD, + 0xB7, 0xFF, 0xF3, 0xDD, 0xB7, 0xFF, 0xF3, 0xDD, 0xB6, 0xFF, 0xF4, 0xDC, 0xB4, 0xFF, 0xF3, 0xDA, + 0xAC, 0xFF, 0xF1, 0xCD, 0x90, 0xFF, 0xEC, 0xC4, 0x7E, 0xFF, 0xEC, 0xC3, 0x7B, 0xFF, 0xED, 0xC3, + 0x7B, 0xFF, 0xED, 0xC3, 0x7C, 0xFF, 0xED, 0xC4, 0x7D, 0xFF, 0xEE, 0xC5, 0x7F, 0xFF, 0xEF, 0xC8, + 0x84, 0xFF, 0xF1, 0xCC, 0x90, 0xFF, 0xF2, 0xD2, 0x9E, 0xFF, 0xF2, 0xD5, 0xA4, 0xF1, 0xF5, 0xD5, + 0xA1, 0xB9, 0xF5, 0xDA, 0xAC, 0x55, 0xD2, 0xE5, 0xF8, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF1, 0xD5, + 0xA7, 0x01, 0xF2, 0xD6, 0xA8, 0x32, 0xF1, 0xD4, 0xA3, 0x94, 0xF1, 0xD1, 0x9D, 0xE0, 0xF0, 0xCE, + 0x98, 0xFE, 0xEF, 0xCB, 0x91, 0xFF, 0xEE, 0xC7, 0x88, 0xFF, 0xED, 0xC3, 0x81, 0xFF, 0xEC, 0xC2, + 0x7D, 0xFF, 0xED, 0xC2, 0x7C, 0xFF, 0xED, 0xC2, 0x7C, 0xFF, 0xEE, 0xC2, 0x7C, 0xFF, 0xEF, 0xC4, + 0x7E, 0xFF, 0xF2, 0xCD, 0x90, 0xFF, 0xF4, 0xD9, 0xAE, 0xFF, 0xF7, 0xDE, 0xB6, 0xFF, 0xF7, 0xDF, + 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, + 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, + 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, + 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, + 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, + 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, + 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, + 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, + 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, + 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, + 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDF, + 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xE0, 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF5, 0xDF, + 0xB8, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF5, 0xDF, 0xB8, 0xFF, 0xF5, 0xDF, 0xB8, 0xFF, 0xF5, 0xDF, + 0xB9, 0xFF, 0xF6, 0xDF, 0xB9, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF5, 0xDD, 0xB3, 0xFF, 0xF2, 0xD5, + 0x9F, 0xFF, 0xEF, 0xC7, 0x83, 0xFF, 0xEE, 0xC5, 0x7D, 0xFF, 0xEE, 0xC4, 0x7D, 0xFF, 0xEE, 0xC5, + 0x7D, 0xFF, 0xEE, 0xC5, 0x7F, 0xFF, 0xEE, 0xC6, 0x80, 0xFF, 0xF0, 0xC8, 0x85, 0xFF, 0xF3, 0xCD, + 0x8F, 0xFF, 0xF2, 0xD2, 0x9D, 0xFF, 0xF3, 0xD6, 0xA5, 0xF4, 0xF6, 0xD7, 0xA6, 0xC2, 0xF4, 0xD6, + 0xA6, 0x62, 0xED, 0xDC, 0xC6, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xF1, 0xD4, 0xA5, 0x01, 0xF1, 0xD6, 0xA8, 0x3B, 0xF2, 0xD5, 0xA7, 0x9B, 0xF1, 0xD2, + 0x9F, 0xE5, 0xF0, 0xCF, 0x98, 0xFF, 0xF1, 0xCD, 0x92, 0xFF, 0xF1, 0xCA, 0x8B, 0xFF, 0xEE, 0xC6, + 0x83, 0xFF, 0xEE, 0xC4, 0x80, 0xFF, 0xEE, 0xC4, 0x7F, 0xFF, 0xEE, 0xC4, 0x7F, 0xFF, 0xEF, 0xC5, + 0x7F, 0xFF, 0xF1, 0xC7, 0x84, 0xFF, 0xF3, 0xD2, 0x9B, 0xFF, 0xF6, 0xDC, 0xB5, 0xFF, 0xF8, 0xE0, + 0xBA, 0xFF, 0xF7, 0xE1, 0xBB, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, 0xBB, 0xFF, 0xF6, 0xE0, + 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, + 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, + 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, + 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, + 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, + 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, + 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, + 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, + 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, + 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, + 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, + 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, 0xBA, 0xFF, 0xF6, 0xE0, 0xBB, 0xFF, 0xF5, 0xE0, + 0xBA, 0xFF, 0xF6, 0xE0, 0xB9, 0xFF, 0xF7, 0xE0, 0xB8, 0xFF, 0xF4, 0xD9, 0xA9, 0xFF, 0xF3, 0xCE, + 0x8F, 0xFF, 0xEF, 0xC7, 0x81, 0xFF, 0xEE, 0xC6, 0x7E, 0xFF, 0xEF, 0xC6, 0x7F, 0xFF, 0xEF, 0xC7, + 0x80, 0xFF, 0xF0, 0xC8, 0x83, 0xFF, 0xF1, 0xCA, 0x87, 0xFF, 0xF3, 0xCE, 0x92, 0xFF, 0xF3, 0xD4, + 0x9E, 0xFF, 0xF5, 0xD8, 0xA6, 0xF9, 0xF5, 0xD7, 0xA4, 0xC6, 0xF5, 0xD7, 0xA6, 0x6A, 0xE7, 0xE0, + 0xCB, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF1, 0xD6, 0xA9, 0x04, 0xF3, 0xD7, 0xA9, 0x3E, 0xF3, 0xD6, + 0xA6, 0xA0, 0xF3, 0xD3, 0xA0, 0xE3, 0xF2, 0xD1, 0x9A, 0xFE, 0xF2, 0xCE, 0x94, 0xFF, 0xF1, 0xCB, + 0x8C, 0xFF, 0xEF, 0xC7, 0x86, 0xFF, 0xEE, 0xC5, 0x82, 0xFF, 0xEF, 0xC6, 0x80, 0xFF, 0xF0, 0xC6, + 0x80, 0xFF, 0xF1, 0xC7, 0x82, 0xFF, 0xF3, 0xCB, 0x88, 0xFF, 0xF3, 0xD7, 0xA6, 0xFF, 0xF7, 0xE0, + 0xBA, 0xFF, 0xF8, 0xE1, 0xBC, 0xFF, 0xF7, 0xE1, 0xBC, 0xFF, 0xF7, 0xE1, 0xBC, 0xFF, 0xF7, 0xE2, + 0xBC, 0xFF, 0xF7, 0xE1, 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, + 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, + 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, + 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, + 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, + 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, + 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, + 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, + 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, + 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, + 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, + 0xBC, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, 0xBD, 0xFF, 0xF7, 0xE2, 0xBD, 0xFF, 0xF7, 0xE2, + 0xBC, 0xFF, 0xF7, 0xE2, 0xBA, 0xFF, 0xF6, 0xDD, 0xB1, 0xFF, 0xF4, 0xD2, 0x98, 0xFF, 0xF2, 0xCB, + 0x85, 0xFF, 0xEF, 0xC8, 0x81, 0xFF, 0xEF, 0xC8, 0x80, 0xFF, 0xF0, 0xC8, 0x83, 0xFF, 0xF0, 0xC9, + 0x85, 0xFF, 0xF2, 0xCB, 0x8A, 0xFF, 0xF3, 0xD0, 0x95, 0xFF, 0xF2, 0xD3, 0x9F, 0xFF, 0xF4, 0xD8, + 0xA6, 0xF7, 0xF6, 0xD9, 0xA7, 0xCD, 0xF3, 0xD7, 0xAC, 0x6D, 0xEE, 0xDE, 0xC7, 0x1E, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF2, 0xD6, 0xA7, 0x02, 0xF3, 0xD7, + 0xA9, 0x3D, 0xF4, 0xD7, 0xA8, 0x99, 0xF2, 0xD4, 0xA1, 0xE2, 0xF2, 0xD1, 0x9A, 0xFE, 0xF2, 0xD0, + 0x96, 0xFF, 0xF3, 0xCE, 0x91, 0xFF, 0xF0, 0xCA, 0x89, 0xFF, 0xEF, 0xC8, 0x84, 0xFF, 0xF0, 0xC7, + 0x82, 0xFF, 0xF0, 0xC7, 0x83, 0xFF, 0xF1, 0xC9, 0x85, 0xFF, 0xF3, 0xCF, 0x90, 0xFF, 0xF5, 0xDB, + 0xAE, 0xFF, 0xF9, 0xE2, 0xBB, 0xFF, 0xF8, 0xE2, 0xBE, 0xFF, 0xF8, 0xE3, 0xBE, 0xFF, 0xF7, 0xE3, + 0xBE, 0xFF, 0xF7, 0xE3, 0xBE, 0xFF, 0xF7, 0xE3, 0xBE, 0xFF, 0xF8, 0xE3, 0xBD, 0xFF, 0xF7, 0xE3, + 0xBD, 0xFF, 0xF8, 0xE3, 0xBD, 0xFF, 0xF7, 0xE3, 0xBD, 0xFF, 0xF7, 0xE3, 0xBD, 0xFF, 0xF7, 0xE3, + 0xBD, 0xFF, 0xF7, 0xE3, 0xBD, 0xFF, 0xF7, 0xE3, 0xBD, 0xFF, 0xF8, 0xE3, 0xBD, 0xFF, 0xF7, 0xE3, + 0xBD, 0xFF, 0xF8, 0xE3, 0xBD, 0xFF, 0xF7, 0xE3, 0xBD, 0xFF, 0xF8, 0xE3, 0xBD, 0xFF, 0xF7, 0xE3, + 0xBD, 0xFF, 0xF8, 0xE3, 0xBD, 0xFF, 0xF7, 0xE3, 0xBD, 0xFF, 0xF8, 0xE3, 0xBD, 0xFF, 0xF7, 0xE3, + 0xBD, 0xFF, 0xF8, 0xE3, 0xBD, 0xFF, 0xF7, 0xE3, 0xBD, 0xFF, 0xF8, 0xE3, 0xBD, 0xFF, 0xF7, 0xE3, + 0xBD, 0xFF, 0xF8, 0xE3, 0xBD, 0xFF, 0xF7, 0xE3, 0xBD, 0xFF, 0xF8, 0xE3, 0xBD, 0xFF, 0xF7, 0xE3, + 0xBD, 0xFF, 0xF8, 0xE3, 0xBD, 0xFF, 0xF7, 0xE3, 0xBD, 0xFF, 0xF8, 0xE3, 0xBD, 0xFF, 0xF7, 0xE3, + 0xBD, 0xFF, 0xF8, 0xE3, 0xBD, 0xFF, 0xF7, 0xE3, 0xBD, 0xFF, 0xF8, 0xE3, 0xBD, 0xFF, 0xF7, 0xE3, + 0xBD, 0xFF, 0xF8, 0xE3, 0xBD, 0xFF, 0xF7, 0xE3, 0xBD, 0xFF, 0xF8, 0xE3, 0xBD, 0xFF, 0xF7, 0xE3, + 0xBD, 0xFF, 0xF8, 0xE3, 0xBD, 0xFF, 0xF7, 0xE3, 0xBD, 0xFF, 0xF8, 0xE3, 0xBE, 0xFF, 0xF7, 0xE3, + 0xBD, 0xFF, 0xF7, 0xE3, 0xBE, 0xFF, 0xF7, 0xE3, 0xBE, 0xFF, 0xF8, 0xE3, 0xBE, 0xFF, 0xF8, 0xE2, + 0xBC, 0xFF, 0xF7, 0xDF, 0xB4, 0xFF, 0xF5, 0xD5, 0xA0, 0xFF, 0xF2, 0xCC, 0x8A, 0xFF, 0xF1, 0xCA, + 0x83, 0xFF, 0xF1, 0xC9, 0x83, 0xFF, 0xF0, 0xCA, 0x84, 0xFF, 0xF2, 0xCC, 0x88, 0xFF, 0xF4, 0xCE, + 0x8F, 0xFF, 0xF4, 0xD1, 0x99, 0xFF, 0xF5, 0xD6, 0xA2, 0xFF, 0xF6, 0xD8, 0xA5, 0xF5, 0xF8, 0xD9, + 0xA3, 0xC2, 0xF6, 0xD9, 0xA7, 0x6A, 0xEA, 0xDD, 0xCE, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF3, 0xD8, + 0xAA, 0x02, 0xF4, 0xD9, 0xAB, 0x36, 0xF3, 0xD8, 0xA8, 0x8F, 0xF3, 0xD5, 0xA2, 0xDA, 0xF3, 0xD4, + 0x9D, 0xFB, 0xF4, 0xD2, 0x99, 0xFF, 0xF3, 0xD0, 0x94, 0xFF, 0xF1, 0xCB, 0x8C, 0xFF, 0xF0, 0xC9, + 0x86, 0xFF, 0xF1, 0xC8, 0x84, 0xFF, 0xF0, 0xC9, 0x83, 0xFF, 0xF4, 0xCB, 0x87, 0xFF, 0xF6, 0xD3, + 0x96, 0xFF, 0xF7, 0xDE, 0xB2, 0xFF, 0xF8, 0xE4, 0xBE, 0xFF, 0xF9, 0xE4, 0xC0, 0xFF, 0xF8, 0xE4, + 0xC0, 0xFF, 0xF8, 0xE4, 0xC0, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, + 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, + 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, + 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, + 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, + 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, + 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, + 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, + 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, + 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, + 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, + 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF8, 0xE3, 0xBE, 0xFF, 0xF8, 0xE1, + 0xB8, 0xFF, 0xF6, 0xD8, 0xA6, 0xFF, 0xF4, 0xCF, 0x8E, 0xFF, 0xF1, 0xCB, 0x85, 0xFF, 0xF2, 0xCB, + 0x84, 0xFF, 0xF1, 0xCB, 0x86, 0xFF, 0xF3, 0xCE, 0x8A, 0xFF, 0xF4, 0xD0, 0x91, 0xFF, 0xF6, 0xD3, + 0x9A, 0xFF, 0xF4, 0xD5, 0xA2, 0xFE, 0xF5, 0xD7, 0xA8, 0xED, 0xF7, 0xDB, 0xA9, 0xBB, 0xF6, 0xDB, + 0xAD, 0x60, 0xED, 0xDE, 0xC8, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF3, 0xDB, 0xAF, 0x2F, 0xF4, 0xD9, 0xAD, 0x7E, 0xF4, 0xD6, + 0xA4, 0xCF, 0xF4, 0xD5, 0x9F, 0xF9, 0xF4, 0xD4, 0x9D, 0xFF, 0xF4, 0xD1, 0x99, 0xFF, 0xF2, 0xCD, + 0x8F, 0xFF, 0xF2, 0xCB, 0x89, 0xFF, 0xF2, 0xCA, 0x87, 0xFF, 0xF2, 0xCA, 0x87, 0xFF, 0xF4, 0xCD, + 0x8A, 0xFF, 0xF6, 0xD3, 0x98, 0xFF, 0xF5, 0xDE, 0xB2, 0xFF, 0xF9, 0xE4, 0xBE, 0xFF, 0xF9, 0xE5, + 0xC1, 0xFF, 0xF9, 0xE5, 0xC1, 0xFF, 0xF8, 0xE5, 0xC1, 0xFF, 0xF8, 0xE5, 0xC0, 0xFF, 0xF8, 0xE5, + 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF8, 0xE4, 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF8, 0xE4, + 0xC0, 0xFF, 0xF8, 0xE4, 0xC0, 0xFF, 0xF8, 0xE4, 0xC0, 0xFF, 0xF8, 0xE4, 0xC0, 0xFF, 0xF8, 0xE4, + 0xC0, 0xFF, 0xF8, 0xE4, 0xC0, 0xFF, 0xF8, 0xE4, 0xC0, 0xFF, 0xF8, 0xE4, 0xC0, 0xFF, 0xF8, 0xE4, + 0xC0, 0xFF, 0xF8, 0xE4, 0xC0, 0xFF, 0xF8, 0xE4, 0xC0, 0xFF, 0xF8, 0xE4, 0xC0, 0xFF, 0xF8, 0xE4, + 0xC0, 0xFF, 0xF8, 0xE4, 0xC0, 0xFF, 0xF8, 0xE4, 0xC0, 0xFF, 0xF8, 0xE4, 0xC0, 0xFF, 0xF8, 0xE4, + 0xC0, 0xFF, 0xF8, 0xE4, 0xC0, 0xFF, 0xF8, 0xE4, 0xC0, 0xFF, 0xF8, 0xE4, 0xC0, 0xFF, 0xF8, 0xE4, + 0xC0, 0xFF, 0xF8, 0xE4, 0xC0, 0xFF, 0xF8, 0xE4, 0xC0, 0xFF, 0xF8, 0xE4, 0xC0, 0xFF, 0xF8, 0xE4, + 0xC0, 0xFF, 0xF8, 0xE4, 0xC0, 0xFF, 0xF8, 0xE4, 0xC0, 0xFF, 0xF8, 0xE4, 0xC0, 0xFF, 0xF8, 0xE5, + 0xC0, 0xFF, 0xF8, 0xE5, 0xC0, 0xFF, 0xF8, 0xE5, 0xC0, 0xFF, 0xF8, 0xE5, 0xC0, 0xFF, 0xF8, 0xE4, + 0xC0, 0xFF, 0xF9, 0xE5, 0xC1, 0xFF, 0xF8, 0xE4, 0xC0, 0xFF, 0xF8, 0xE5, 0xC0, 0xFF, 0xF8, 0xE5, + 0xC0, 0xFF, 0xF8, 0xE5, 0xC0, 0xFF, 0xF9, 0xE4, 0xBF, 0xFF, 0xF8, 0xE1, 0xB9, 0xFF, 0xF7, 0xD9, + 0xA7, 0xFF, 0xF4, 0xD0, 0x92, 0xFF, 0xF3, 0xCC, 0x88, 0xFF, 0xF3, 0xCB, 0x87, 0xFF, 0xF2, 0xCC, + 0x89, 0xFF, 0xF4, 0xCF, 0x8F, 0xFF, 0xF5, 0xD2, 0x97, 0xFF, 0xF6, 0xD5, 0x9F, 0xFF, 0xF5, 0xD7, + 0xA4, 0xFE, 0xF5, 0xD9, 0xA9, 0xE6, 0xF4, 0xD8, 0xA8, 0xA6, 0xF8, 0xDD, 0xB1, 0x54, 0xE7, 0xEA, + 0xEA, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF4, 0xDC, 0xB1, 0x24, 0xF3, 0xD9, + 0xAC, 0x68, 0xF4, 0xD7, 0xA5, 0xC2, 0xF5, 0xD6, 0xA2, 0xF4, 0xF6, 0xD5, 0x9F, 0xFF, 0xF6, 0xD3, + 0x9B, 0xFF, 0xF4, 0xD0, 0x94, 0xFF, 0xF4, 0xCD, 0x8E, 0xFF, 0xF3, 0xCC, 0x8A, 0xFF, 0xF2, 0xCC, + 0x89, 0xFF, 0xF5, 0xCD, 0x8C, 0xFF, 0xF7, 0xD4, 0x99, 0xFF, 0xF8, 0xDE, 0xB3, 0xFF, 0xF9, 0xE5, + 0xC0, 0xFF, 0xFA, 0xE6, 0xC2, 0xFF, 0xF9, 0xE6, 0xC2, 0xFF, 0xF9, 0xE5, 0xC2, 0xFF, 0xF9, 0xE5, + 0xC2, 0xFF, 0xF9, 0xE5, 0xC2, 0xFF, 0xF9, 0xE5, 0xC2, 0xFF, 0xF9, 0xE5, 0xC2, 0xFF, 0xF9, 0xE5, + 0xC2, 0xFF, 0xF9, 0xE5, 0xC2, 0xFF, 0xF9, 0xE5, 0xC2, 0xFF, 0xF9, 0xE5, 0xC2, 0xFF, 0xF9, 0xE5, + 0xC2, 0xFF, 0xF9, 0xE5, 0xC2, 0xFF, 0xF9, 0xE5, 0xC2, 0xFF, 0xF9, 0xE5, 0xC2, 0xFF, 0xF9, 0xE5, + 0xC2, 0xFF, 0xF9, 0xE5, 0xC2, 0xFF, 0xF9, 0xE5, 0xC2, 0xFF, 0xF9, 0xE5, 0xC2, 0xFF, 0xF9, 0xE5, + 0xC2, 0xFF, 0xF9, 0xE5, 0xC2, 0xFF, 0xF9, 0xE5, 0xC2, 0xFF, 0xF9, 0xE5, 0xC2, 0xFF, 0xF9, 0xE5, + 0xC2, 0xFF, 0xF9, 0xE5, 0xC2, 0xFF, 0xF9, 0xE5, 0xC2, 0xFF, 0xF9, 0xE5, 0xC2, 0xFF, 0xF9, 0xE5, + 0xC2, 0xFF, 0xF9, 0xE5, 0xC2, 0xFF, 0xF9, 0xE5, 0xC2, 0xFF, 0xF9, 0xE5, 0xC2, 0xFF, 0xF9, 0xE5, + 0xC2, 0xFF, 0xF9, 0xE5, 0xC2, 0xFF, 0xF9, 0xE5, 0xC2, 0xFF, 0xF9, 0xE5, 0xC2, 0xFF, 0xF9, 0xE5, + 0xC2, 0xFF, 0xF9, 0xE5, 0xC2, 0xFF, 0xF9, 0xE5, 0xC2, 0xFF, 0xF9, 0xE5, 0xC2, 0xFF, 0xF9, 0xE5, + 0xC2, 0xFF, 0xF9, 0xE5, 0xC2, 0xFF, 0xF9, 0xE5, 0xC2, 0xFF, 0xF9, 0xE5, 0xC2, 0xFF, 0xF9, 0xE5, + 0xC2, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE2, 0xBA, 0xFF, 0xF8, 0xDB, 0xA8, 0xFF, 0xF5, 0xD1, + 0x92, 0xFF, 0xF3, 0xCE, 0x8B, 0xFF, 0xF4, 0xCD, 0x89, 0xFF, 0xF4, 0xCE, 0x8D, 0xFF, 0xF5, 0xD1, + 0x94, 0xFF, 0xF6, 0xD4, 0x9B, 0xFF, 0xF6, 0xD7, 0xA0, 0xFF, 0xF6, 0xD9, 0xA6, 0xFB, 0xF7, 0xDB, + 0xAA, 0xD8, 0xF8, 0xDC, 0xAD, 0x94, 0xF4, 0xDA, 0xB0, 0x3F, 0xF5, 0xDF, 0xC3, 0x0E, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF2, 0xDC, + 0xB3, 0x1A, 0xF4, 0xDB, 0xB1, 0x50, 0xF4, 0xD8, 0xA7, 0xA0, 0xF6, 0xD7, 0xA2, 0xE4, 0xF7, 0xD7, + 0xA1, 0xFE, 0xF6, 0xD6, 0x9E, 0xFF, 0xF4, 0xD2, 0x99, 0xFF, 0xF4, 0xD0, 0x94, 0xFF, 0xF4, 0xCE, + 0x8E, 0xFF, 0xF3, 0xCD, 0x8C, 0xFF, 0xF4, 0xCE, 0x8E, 0xFF, 0xF5, 0xD3, 0x98, 0xFF, 0xF6, 0xDD, + 0xB1, 0xFF, 0xFA, 0xE6, 0xC0, 0xFF, 0xFB, 0xE6, 0xC4, 0xFF, 0xFB, 0xE6, 0xC4, 0xFF, 0xFA, 0xE6, + 0xC4, 0xFF, 0xFA, 0xE6, 0xC4, 0xFF, 0xFA, 0xE6, 0xC4, 0xFF, 0xFA, 0xE7, 0xC4, 0xFF, 0xFA, 0xE6, + 0xC4, 0xFF, 0xFB, 0xE7, 0xC4, 0xFF, 0xFA, 0xE6, 0xC4, 0xFF, 0xFA, 0xE6, 0xC4, 0xFF, 0xFA, 0xE6, + 0xC4, 0xFF, 0xFA, 0xE6, 0xC4, 0xFF, 0xFA, 0xE6, 0xC4, 0xFF, 0xFA, 0xE6, 0xC4, 0xFF, 0xFA, 0xE6, + 0xC4, 0xFF, 0xFA, 0xE6, 0xC4, 0xFF, 0xFA, 0xE6, 0xC4, 0xFF, 0xFA, 0xE6, 0xC4, 0xFF, 0xFA, 0xE6, + 0xC4, 0xFF, 0xFA, 0xE6, 0xC4, 0xFF, 0xFA, 0xE6, 0xC4, 0xFF, 0xFA, 0xE6, 0xC4, 0xFF, 0xFA, 0xE6, + 0xC4, 0xFF, 0xFA, 0xE6, 0xC4, 0xFF, 0xFA, 0xE6, 0xC4, 0xFF, 0xFA, 0xE6, 0xC4, 0xFF, 0xFA, 0xE6, + 0xC4, 0xFF, 0xFA, 0xE6, 0xC4, 0xFF, 0xFA, 0xE6, 0xC4, 0xFF, 0xFA, 0xE6, 0xC4, 0xFF, 0xFA, 0xE6, + 0xC4, 0xFF, 0xFA, 0xE6, 0xC4, 0xFF, 0xFA, 0xE6, 0xC4, 0xFF, 0xFA, 0xE6, 0xC4, 0xFF, 0xFA, 0xE6, + 0xC4, 0xFF, 0xFA, 0xE6, 0xC4, 0xFF, 0xFA, 0xE6, 0xC4, 0xFF, 0xFA, 0xE6, 0xC4, 0xFF, 0xFA, 0xE6, + 0xC4, 0xFF, 0xFA, 0xE6, 0xC4, 0xFF, 0xF9, 0xE6, 0xC4, 0xFF, 0xF9, 0xE6, 0xC4, 0xFF, 0xF9, 0xE6, + 0xC3, 0xFF, 0xF9, 0xE1, 0xB9, 0xFF, 0xF8, 0xD9, 0xA4, 0xFF, 0xF5, 0xD1, 0x92, 0xFF, 0xF3, 0xCF, + 0x8B, 0xFF, 0xF4, 0xCF, 0x8D, 0xFF, 0xF5, 0xD1, 0x92, 0xFF, 0xF6, 0xD4, 0x9A, 0xFF, 0xF6, 0xD7, + 0x9F, 0xFF, 0xF6, 0xD8, 0xA3, 0xFF, 0xF7, 0xDA, 0xA6, 0xF3, 0xF8, 0xDC, 0xAB, 0xC3, 0xF8, 0xDE, + 0xB0, 0x7C, 0xF9, 0xE0, 0xB6, 0x2D, 0xF3, 0xDF, 0xBD, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xF1, 0xDB, 0xB9, 0x0E, 0xF2, 0xD9, 0xB0, 0x3C, 0xF5, 0xD8, 0xA8, 0x7E, 0xF7, 0xDA, + 0xA5, 0xCB, 0xF8, 0xD9, 0xA3, 0xF6, 0xF7, 0xD7, 0xA0, 0xFF, 0xF6, 0xD5, 0x9D, 0xFF, 0xF6, 0xD3, + 0x98, 0xFF, 0xF5, 0xD1, 0x92, 0xFF, 0xF4, 0xD0, 0x90, 0xFF, 0xF6, 0xD0, 0x90, 0xFF, 0xF7, 0xD3, + 0x98, 0xFF, 0xF9, 0xDB, 0xAC, 0xFF, 0xF9, 0xE3, 0xBD, 0xFF, 0xFB, 0xE6, 0xC5, 0xFF, 0xFB, 0xE7, + 0xC6, 0xFF, 0xFB, 0xE7, 0xC6, 0xFF, 0xFB, 0xE7, 0xC6, 0xFF, 0xFB, 0xE7, 0xC6, 0xFF, 0xFB, 0xE8, + 0xC6, 0xFF, 0xFB, 0xE7, 0xC6, 0xFF, 0xFB, 0xE8, 0xC6, 0xFF, 0xFB, 0xE7, 0xC6, 0xFF, 0xFB, 0xE8, + 0xC6, 0xFF, 0xFB, 0xE7, 0xC6, 0xFF, 0xFB, 0xE8, 0xC6, 0xFF, 0xFB, 0xE7, 0xC6, 0xFF, 0xFB, 0xE8, + 0xC6, 0xFF, 0xFB, 0xE7, 0xC6, 0xFF, 0xFB, 0xE8, 0xC6, 0xFF, 0xFB, 0xE7, 0xC6, 0xFF, 0xFB, 0xE8, + 0xC6, 0xFF, 0xFB, 0xE7, 0xC6, 0xFF, 0xFB, 0xE8, 0xC6, 0xFF, 0xFB, 0xE7, 0xC6, 0xFF, 0xFB, 0xE8, + 0xC6, 0xFF, 0xFB, 0xE7, 0xC6, 0xFF, 0xFB, 0xE8, 0xC6, 0xFF, 0xFB, 0xE7, 0xC6, 0xFF, 0xFB, 0xE8, + 0xC6, 0xFF, 0xFB, 0xE7, 0xC6, 0xFF, 0xFB, 0xE8, 0xC6, 0xFF, 0xFB, 0xE7, 0xC6, 0xFF, 0xFB, 0xE8, + 0xC6, 0xFF, 0xFB, 0xE8, 0xC6, 0xFF, 0xFB, 0xE8, 0xC6, 0xFF, 0xFB, 0xE8, 0xC6, 0xFF, 0xFB, 0xE8, + 0xC6, 0xFF, 0xFB, 0xE8, 0xC6, 0xFF, 0xFB, 0xE8, 0xC6, 0xFF, 0xFB, 0xE7, 0xC6, 0xFF, 0xFB, 0xE7, + 0xC5, 0xFF, 0xFB, 0xE6, 0xC5, 0xFF, 0xFA, 0xE6, 0xC6, 0xFF, 0xFB, 0xE6, 0xC2, 0xFF, 0xFA, 0xE0, + 0xB5, 0xFF, 0xF8, 0xD9, 0xA1, 0xFF, 0xF5, 0xD3, 0x93, 0xFF, 0xF3, 0xD1, 0x90, 0xFF, 0xF5, 0xD1, + 0x90, 0xFF, 0xF5, 0xD3, 0x96, 0xFF, 0xF7, 0xD7, 0x9E, 0xFF, 0xF8, 0xD9, 0xA2, 0xFF, 0xF8, 0xDA, + 0xA4, 0xFC, 0xF7, 0xDC, 0xAB, 0xE5, 0xF6, 0xDC, 0xB0, 0xA4, 0xF6, 0xDD, 0xB2, 0x5C, 0xF7, 0xE0, + 0xB5, 0x1C, 0xF8, 0xE0, 0xB7, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0xD9, 0xC7, 0x04, 0xE8, 0xD7, 0xC3, 0x21, 0xF6, 0xDB, + 0xAA, 0x5B, 0xF7, 0xDA, 0xA6, 0xA1, 0xF7, 0xD8, 0xA5, 0xDE, 0xF6, 0xD7, 0xA3, 0xFA, 0xF7, 0xD7, + 0xA1, 0xFF, 0xF8, 0xD7, 0x9E, 0xFF, 0xF7, 0xD5, 0x99, 0xFF, 0xF6, 0xD3, 0x95, 0xFF, 0xF5, 0xD2, + 0x93, 0xFF, 0xF6, 0xD3, 0x96, 0xFF, 0xF7, 0xD9, 0xA4, 0xFF, 0xF9, 0xE1, 0xB7, 0xFF, 0xFB, 0xE6, + 0xC4, 0xFF, 0xFC, 0xE9, 0xC8, 0xFF, 0xFB, 0xE8, 0xC8, 0xFF, 0xFB, 0xE8, 0xC8, 0xFF, 0xFB, 0xE8, + 0xC8, 0xFF, 0xFB, 0xE8, 0xC8, 0xFF, 0xFB, 0xE8, 0xC8, 0xFF, 0xFC, 0xE9, 0xC8, 0xFF, 0xFC, 0xE9, + 0xC7, 0xFF, 0xFC, 0xE9, 0xC7, 0xFF, 0xFC, 0xE9, 0xC7, 0xFF, 0xFC, 0xE9, 0xC7, 0xFF, 0xFC, 0xE9, + 0xC7, 0xFF, 0xFC, 0xE9, 0xC7, 0xFF, 0xFB, 0xE9, 0xC7, 0xFF, 0xFC, 0xE9, 0xC7, 0xFF, 0xFB, 0xE8, + 0xC7, 0xFF, 0xFC, 0xE8, 0xC7, 0xFF, 0xFB, 0xE8, 0xC7, 0xFF, 0xFC, 0xE8, 0xC7, 0xFF, 0xFB, 0xE8, + 0xC7, 0xFF, 0xFC, 0xE8, 0xC7, 0xFF, 0xFB, 0xE8, 0xC7, 0xFF, 0xFC, 0xE8, 0xC7, 0xFF, 0xFB, 0xE8, + 0xC7, 0xFF, 0xFC, 0xE8, 0xC7, 0xFF, 0xFB, 0xE9, 0xC7, 0xFF, 0xFC, 0xE9, 0xC7, 0xFF, 0xFB, 0xE8, + 0xC7, 0xFF, 0xFC, 0xE8, 0xC7, 0xFF, 0xFB, 0xE8, 0xC7, 0xFF, 0xFC, 0xE9, 0xC8, 0xFF, 0xFB, 0xE8, + 0xC8, 0xFF, 0xFC, 0xE9, 0xC8, 0xFF, 0xFB, 0xE9, 0xC8, 0xFF, 0xFB, 0xE8, 0xC8, 0xFF, 0xFB, 0xE7, + 0xC7, 0xFF, 0xFC, 0xE7, 0xC6, 0xFF, 0xFA, 0xE5, 0xBE, 0xFF, 0xF9, 0xDE, 0xAD, 0xFF, 0xF8, 0xD8, + 0x9C, 0xFF, 0xF7, 0xD5, 0x96, 0xFF, 0xF5, 0xD4, 0x94, 0xFF, 0xF6, 0xD5, 0x99, 0xFF, 0xF6, 0xD7, + 0x9E, 0xFF, 0xF6, 0xD8, 0xA4, 0xFF, 0xF8, 0xDA, 0xA6, 0xFD, 0xF9, 0xDB, 0xA8, 0xEF, 0xF7, 0xDB, + 0xAA, 0xC5, 0xF8, 0xDE, 0xB3, 0x80, 0xF7, 0xE4, 0xC4, 0x3F, 0xF6, 0xE4, 0xC5, 0x0F, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE7, 0xD8, 0xC8, 0x01, 0xF1, 0xD8, + 0xB2, 0x10, 0xF5, 0xD9, 0xAC, 0x34, 0xF5, 0xDA, 0xAA, 0x72, 0xF6, 0xDA, 0xA9, 0xC0, 0xF7, 0xDB, + 0xA7, 0xF0, 0xF8, 0xDA, 0xA4, 0xFF, 0xF9, 0xD9, 0xA2, 0xFF, 0xF9, 0xD8, 0x9F, 0xFF, 0xF8, 0xD6, + 0x9A, 0xFF, 0xF7, 0xD4, 0x97, 0xFF, 0xF6, 0xD3, 0x98, 0xFF, 0xF8, 0xD6, 0x9E, 0xFF, 0xFB, 0xDD, + 0xB0, 0xFF, 0xFD, 0xE5, 0xC0, 0xFF, 0xFC, 0xE8, 0xC8, 0xFF, 0xFC, 0xE8, 0xC9, 0xFF, 0xFB, 0xE8, + 0xC9, 0xFF, 0xFC, 0xE9, 0xC9, 0xFF, 0xFC, 0xEA, 0xC9, 0xFF, 0xFC, 0xE9, 0xC9, 0xFF, 0xFC, 0xEA, + 0xC9, 0xFF, 0xFC, 0xE9, 0xC9, 0xFF, 0xFC, 0xE9, 0xC9, 0xFF, 0xFC, 0xE9, 0xC9, 0xFF, 0xFC, 0xE9, + 0xC9, 0xFF, 0xFC, 0xE9, 0xC9, 0xFF, 0xFC, 0xE9, 0xC9, 0xFF, 0xFC, 0xE9, 0xC9, 0xFF, 0xFC, 0xE9, + 0xC9, 0xFF, 0xFC, 0xE9, 0xC9, 0xFF, 0xFC, 0xE9, 0xC9, 0xFF, 0xFC, 0xE9, 0xC9, 0xFF, 0xFC, 0xE9, + 0xC9, 0xFF, 0xFC, 0xE9, 0xC9, 0xFF, 0xFC, 0xE9, 0xC9, 0xFF, 0xFC, 0xE9, 0xC9, 0xFF, 0xFC, 0xE9, + 0xC9, 0xFF, 0xFC, 0xE9, 0xC9, 0xFF, 0xFC, 0xE9, 0xC9, 0xFF, 0xFC, 0xE9, 0xC9, 0xFF, 0xFC, 0xE9, + 0xC9, 0xFF, 0xFC, 0xE9, 0xC9, 0xFF, 0xFB, 0xE9, 0xC9, 0xFF, 0xFC, 0xE9, 0xC9, 0xFF, 0xFC, 0xE9, + 0xC9, 0xFF, 0xFD, 0xE9, 0xC9, 0xFF, 0xFC, 0xE9, 0xCA, 0xFF, 0xFC, 0xE8, 0xC8, 0xFF, 0xFC, 0xE6, + 0xC3, 0xFF, 0xFC, 0xE2, 0xB7, 0xFF, 0xFA, 0xDC, 0xA5, 0xFF, 0xF7, 0xD7, 0x9C, 0xFF, 0xF6, 0xD6, + 0x97, 0xFF, 0xF7, 0xD6, 0x99, 0xFF, 0xF8, 0xD8, 0x9E, 0xFF, 0xFA, 0xDA, 0xA2, 0xFF, 0xF9, 0xDC, + 0xA6, 0xFF, 0xF9, 0xDC, 0xA9, 0xFB, 0xF9, 0xDC, 0xAA, 0xD7, 0xFA, 0xDD, 0xAE, 0x97, 0xF8, 0xDE, + 0xB0, 0x4F, 0xF8, 0xE0, 0xB5, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF2, 0xDC, 0xB7, 0x18, 0xF3, 0xDC, 0xB4, 0x46, 0xF6, 0xDC, + 0xAC, 0x8C, 0xF7, 0xDC, 0xA9, 0xC8, 0xF7, 0xDB, 0xA7, 0xF1, 0xF9, 0xDA, 0xA5, 0xFE, 0xF9, 0xDA, + 0xA3, 0xFF, 0xF8, 0xD8, 0xA0, 0xFF, 0xF7, 0xD7, 0x9E, 0xFF, 0xF7, 0xD6, 0x9C, 0xFF, 0xF7, 0xD6, + 0x9D, 0xFF, 0xF8, 0xD9, 0xA4, 0xFF, 0xF9, 0xE0, 0xB3, 0xFF, 0xFB, 0xE6, 0xC3, 0xFF, 0xFB, 0xE9, + 0xC8, 0xFF, 0xFB, 0xEA, 0xC9, 0xFF, 0xFC, 0xEA, 0xCB, 0xFF, 0xFC, 0xEA, 0xCB, 0xFF, 0xFB, 0xE9, + 0xCB, 0xFF, 0xFC, 0xE9, 0xCB, 0xFF, 0xFB, 0xE9, 0xCB, 0xFF, 0xFB, 0xE9, 0xCB, 0xFF, 0xFB, 0xEA, + 0xCB, 0xFF, 0xFC, 0xEA, 0xCB, 0xFF, 0xFC, 0xEA, 0xCB, 0xFF, 0xFC, 0xEA, 0xCB, 0xFF, 0xFC, 0xEA, + 0xCB, 0xFF, 0xFC, 0xEA, 0xCB, 0xFF, 0xFC, 0xEA, 0xCA, 0xFF, 0xFC, 0xEA, 0xCA, 0xFF, 0xFC, 0xEA, + 0xCA, 0xFF, 0xFC, 0xEA, 0xCB, 0xFF, 0xFC, 0xEA, 0xCB, 0xFF, 0xFC, 0xEA, 0xCB, 0xFF, 0xFC, 0xEA, + 0xCB, 0xFF, 0xFC, 0xEA, 0xCB, 0xFF, 0xFB, 0xE9, 0xCB, 0xFF, 0xFC, 0xE9, 0xCB, 0xFF, 0xFB, 0xE9, + 0xCB, 0xFF, 0xFB, 0xE9, 0xCB, 0xFF, 0xFB, 0xEA, 0xCA, 0xFF, 0xFB, 0xE9, 0xCA, 0xFF, 0xFB, 0xE9, + 0xCA, 0xFF, 0xFD, 0xE9, 0xC9, 0xFF, 0xFC, 0xE8, 0xC5, 0xFF, 0xFB, 0xE4, 0xBA, 0xFF, 0xFA, 0xDD, + 0xAB, 0xFF, 0xF9, 0xD9, 0xA0, 0xFF, 0xF7, 0xD7, 0x9D, 0xFF, 0xF7, 0xD8, 0x9E, 0xFF, 0xF6, 0xD8, + 0xA0, 0xFF, 0xF7, 0xD9, 0xA6, 0xFF, 0xF9, 0xDB, 0xA7, 0xFE, 0xFA, 0xDC, 0xA9, 0xF9, 0xF9, 0xDD, + 0xA9, 0xE2, 0xF9, 0xDD, 0xAC, 0xAD, 0xFA, 0xE0, 0xB4, 0x69, 0xFA, 0xE0, 0xB7, 0x2B, 0xF8, 0xE0, + 0xB5, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF2, 0xDC, 0xB7, 0x08, 0xF4, 0xDB, + 0xAF, 0x23, 0xF7, 0xDC, 0xAD, 0x4F, 0xF8, 0xDD, 0xAC, 0x8D, 0xF8, 0xDD, 0xAB, 0xCC, 0xF9, 0xDC, + 0xA9, 0xF2, 0xF9, 0xDB, 0xA6, 0xFD, 0xF9, 0xDA, 0xA4, 0xFF, 0xF9, 0xD9, 0xA3, 0xFF, 0xF8, 0xD9, + 0xA1, 0xFF, 0xF9, 0xD8, 0x9F, 0xFF, 0xF9, 0xD8, 0xA1, 0xFF, 0xF9, 0xDB, 0xA7, 0xFF, 0xFB, 0xE0, + 0xB5, 0xFF, 0xFC, 0xE5, 0xBF, 0xFF, 0xFB, 0xE9, 0xC7, 0xFF, 0xFC, 0xEA, 0xCC, 0xFF, 0xFC, 0xEA, + 0xCC, 0xFF, 0xFC, 0xEA, 0xCC, 0xFF, 0xFB, 0xEA, 0xCC, 0xFF, 0xFC, 0xEA, 0xCC, 0xFF, 0xFB, 0xEA, + 0xCC, 0xFF, 0xFC, 0xEA, 0xCD, 0xFF, 0xFC, 0xEB, 0xCD, 0xFF, 0xFC, 0xEB, 0xCD, 0xFF, 0xFC, 0xEB, + 0xCD, 0xFF, 0xFC, 0xEA, 0xCC, 0xFF, 0xFC, 0xEA, 0xCC, 0xFF, 0xFC, 0xEA, 0xCC, 0xFF, 0xFC, 0xEA, + 0xCC, 0xFF, 0xFC, 0xEA, 0xCC, 0xFF, 0xFC, 0xEA, 0xCC, 0xFF, 0xFC, 0xEA, 0xCC, 0xFF, 0xFC, 0xEA, + 0xCC, 0xFF, 0xFC, 0xEA, 0xCC, 0xFF, 0xFC, 0xEA, 0xCC, 0xFF, 0xFC, 0xEA, 0xCB, 0xFF, 0xFC, 0xEA, + 0xCB, 0xFF, 0xFC, 0xEA, 0xCB, 0xFF, 0xFB, 0xEA, 0xCB, 0xFF, 0xFC, 0xE9, 0xCA, 0xFF, 0xFD, 0xE7, + 0xC3, 0xFF, 0xFC, 0xE2, 0xB8, 0xFF, 0xFB, 0xDF, 0xAE, 0xFF, 0xFB, 0xDB, 0xA6, 0xFF, 0xF8, 0xD9, + 0xA1, 0xFF, 0xF6, 0xD8, 0xA0, 0xFF, 0xF6, 0xD8, 0xA2, 0xFF, 0xF9, 0xDA, 0xA2, 0xFF, 0xFA, 0xDB, + 0xA6, 0xFF, 0xFA, 0xDD, 0xAA, 0xFC, 0xF9, 0xDC, 0xA9, 0xE0, 0xFB, 0xDD, 0xB0, 0xAF, 0xF8, 0xDD, + 0xB4, 0x71, 0xF6, 0xDF, 0xB5, 0x3B, 0xF7, 0xE5, 0xBD, 0x11, 0xF7, 0xE2, 0xBB, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xF6, 0xDC, 0xB0, 0x05, 0xF6, 0xDE, 0xB5, 0x23, 0xF6, 0xDD, 0xB4, 0x51, 0xF7, 0xDD, + 0xAE, 0x8B, 0xF8, 0xDD, 0xAA, 0xBD, 0xF8, 0xDC, 0xA9, 0xE3, 0xF8, 0xDA, 0xA6, 0xF6, 0xF8, 0xDA, + 0xA4, 0xFF, 0xF8, 0xDA, 0xA4, 0xFF, 0xF9, 0xDA, 0xA4, 0xFF, 0xF9, 0xDA, 0xA4, 0xFF, 0xF9, 0xDB, + 0xA5, 0xFF, 0xFA, 0xDC, 0xA9, 0xFF, 0xF9, 0xE0, 0xB1, 0xFF, 0xF9, 0xE4, 0xBB, 0xFF, 0xF9, 0xE6, + 0xC5, 0xFF, 0xFB, 0xE9, 0xCA, 0xFF, 0xFB, 0xEA, 0xCB, 0xFF, 0xFC, 0xEB, 0xCC, 0xFF, 0xFC, 0xEB, + 0xCD, 0xFF, 0xFC, 0xEB, 0xCD, 0xFF, 0xFC, 0xEB, 0xCD, 0xFF, 0xFC, 0xEB, 0xCD, 0xFF, 0xFC, 0xEB, + 0xCD, 0xFF, 0xFC, 0xEB, 0xCD, 0xFF, 0xFC, 0xEB, 0xCD, 0xFF, 0xFC, 0xEB, 0xCD, 0xFF, 0xFC, 0xEB, + 0xCD, 0xFF, 0xFC, 0xEB, 0xCD, 0xFF, 0xFC, 0xEC, 0xCD, 0xFF, 0xFC, 0xEB, 0xCC, 0xFF, 0xFC, 0xEA, + 0xCB, 0xFF, 0xFC, 0xEB, 0xCB, 0xFF, 0xFC, 0xEA, 0xCA, 0xFF, 0xFC, 0xEA, 0xCA, 0xFF, 0xFC, 0xEA, + 0xCB, 0xFF, 0xFC, 0xE9, 0xC7, 0xFF, 0xFB, 0xE7, 0xC1, 0xFF, 0xFD, 0xE4, 0xB7, 0xFF, 0xFB, 0xE0, + 0xAE, 0xFF, 0xF8, 0xDC, 0xA7, 0xFF, 0xF8, 0xDA, 0xA5, 0xFF, 0xFA, 0xDB, 0xA6, 0xFF, 0xF9, 0xDB, + 0xA5, 0xFF, 0xF9, 0xDB, 0xA7, 0xFD, 0xF7, 0xDB, 0xA6, 0xF9, 0xF8, 0xDC, 0xAB, 0xF2, 0xFC, 0xDC, + 0xA7, 0xDD, 0xFD, 0xDC, 0xA7, 0xA9, 0xFB, 0xDB, 0xAB, 0x6E, 0xF7, 0xDD, 0xC0, 0x3A, 0xE6, 0xE4, + 0xDD, 0x16, 0xE8, 0xE6, 0xDB, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF5, 0xDE, 0xB7, 0x01, 0xF5, 0xDD, 0xB6, 0x0B, 0xF6, 0xDD, + 0xB1, 0x22, 0xF7, 0xDD, 0xAE, 0x46, 0xF8, 0xDD, 0xAE, 0x77, 0xF8, 0xDE, 0xAE, 0xA8, 0xF9, 0xDE, + 0xAE, 0xCE, 0xFA, 0xDD, 0xAA, 0xED, 0xFB, 0xDD, 0xA8, 0xFD, 0xFA, 0xDC, 0xA7, 0xFF, 0xF9, 0xDC, + 0xA8, 0xFF, 0xFB, 0xDC, 0xA8, 0xFF, 0xFB, 0xDC, 0xA8, 0xFF, 0xFB, 0xDD, 0xA9, 0xFF, 0xFB, 0xDF, + 0xAE, 0xFF, 0xFB, 0xE1, 0xB4, 0xFF, 0xFC, 0xE4, 0xBA, 0xFF, 0xFD, 0xE7, 0xC0, 0xFF, 0xFC, 0xE9, + 0xC6, 0xFF, 0xFC, 0xEA, 0xCA, 0xFF, 0xFC, 0xEB, 0xCA, 0xFF, 0xFC, 0xEB, 0xCB, 0xFF, 0xFC, 0xEB, + 0xCB, 0xFF, 0xFC, 0xEA, 0xCC, 0xFF, 0xFC, 0xEA, 0xCD, 0xFF, 0xFC, 0xEA, 0xCD, 0xFF, 0xFC, 0xEA, + 0xCC, 0xFF, 0xFC, 0xEA, 0xCC, 0xFF, 0xFD, 0xEB, 0xCC, 0xFF, 0xFD, 0xEB, 0xCB, 0xFF, 0xFD, 0xEB, + 0xC9, 0xFF, 0xFD, 0xE9, 0xC7, 0xFF, 0xFE, 0xE9, 0xC4, 0xFF, 0xFD, 0xE7, 0xC0, 0xFF, 0xFB, 0xE3, + 0xB8, 0xFF, 0xFA, 0xDF, 0xB0, 0xFF, 0xFA, 0xDF, 0xAC, 0xFF, 0xFA, 0xDC, 0xA8, 0xFF, 0xF7, 0xDB, + 0xA9, 0xFF, 0xF9, 0xDC, 0xA8, 0xFF, 0xFA, 0xDC, 0xA7, 0xFF, 0xFC, 0xDE, 0xA9, 0xFD, 0xFB, 0xDE, + 0xAA, 0xF2, 0xFB, 0xDE, 0xAD, 0xE1, 0xFD, 0xDF, 0xAF, 0xBC, 0xF9, 0xE1, 0xB5, 0x92, 0xF2, 0xDD, + 0xBB, 0x5A, 0xF3, 0xDE, 0xB2, 0x2D, 0xF2, 0xE0, 0xB0, 0x13, 0xF2, 0xE0, 0xC6, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xF6, 0xDD, 0xB2, 0x03, 0xF4, 0xDF, 0xBA, 0x14, 0xF5, 0xE1, 0xBD, 0x33, 0xF9, 0xE3, + 0xB9, 0x5E, 0xFB, 0xE3, 0xB5, 0x8A, 0xFB, 0xDF, 0xB0, 0xB4, 0xFA, 0xDD, 0xAC, 0xD0, 0xFA, 0xDD, + 0xAB, 0xE8, 0xFA, 0xDD, 0xAB, 0xF4, 0xFA, 0xDD, 0xAB, 0xFB, 0xFB, 0xDD, 0xAB, 0xFF, 0xFA, 0xDD, + 0xAA, 0xFF, 0xFB, 0xDE, 0xAB, 0xFF, 0xFA, 0xDE, 0xAC, 0xFF, 0xFB, 0xE0, 0xAF, 0xFF, 0xFB, 0xE2, + 0xB2, 0xFF, 0xFC, 0xE3, 0xB7, 0xFF, 0xFA, 0xE4, 0xB9, 0xFF, 0xFA, 0xE5, 0xBC, 0xFF, 0xFA, 0xE6, + 0xBF, 0xFF, 0xFB, 0xE7, 0xC2, 0xFF, 0xFA, 0xE7, 0xC2, 0xFF, 0xFA, 0xE7, 0xC2, 0xFF, 0xFA, 0xE7, + 0xC1, 0xFF, 0xFB, 0xE7, 0xC0, 0xFF, 0xFA, 0xE5, 0xBE, 0xFF, 0xFA, 0xE4, 0xBC, 0xFF, 0xF9, 0xE2, + 0xB8, 0xFF, 0xF9, 0xE1, 0xB5, 0xFF, 0xFA, 0xE1, 0xB3, 0xFF, 0xFA, 0xE0, 0xB0, 0xFF, 0xF9, 0xDE, + 0xAC, 0xFF, 0xFB, 0xDF, 0xAC, 0xFE, 0xFB, 0xDF, 0xAC, 0xFD, 0xFA, 0xDE, 0xAD, 0xF8, 0xF9, 0xDE, + 0xAE, 0xF3, 0xFB, 0xDE, 0xAC, 0xEA, 0xFA, 0xDC, 0xA8, 0xDC, 0xF9, 0xDD, 0xAA, 0xC2, 0xF9, 0xDF, + 0xB2, 0x9E, 0xFC, 0xE2, 0xB9, 0x6D, 0xFD, 0xE1, 0xB9, 0x44, 0xF7, 0xE3, 0xC1, 0x23, 0xAC, 0xE5, + 0xFF, 0x0A, 0xA2, 0xE6, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF6, 0xE2, 0xBE, 0x02, 0xF8, 0xE3, + 0xBD, 0x0B, 0xFB, 0xE4, 0xB9, 0x19, 0xFA, 0xE2, 0xB5, 0x35, 0xFB, 0xE1, 0xB4, 0x56, 0xFC, 0xE1, + 0xB3, 0x76, 0xFB, 0xE1, 0xB2, 0x97, 0xFB, 0xE0, 0xAF, 0xBA, 0xFB, 0xDF, 0xAD, 0xCF, 0xFB, 0xDF, + 0xAD, 0xE0, 0xFB, 0xDF, 0xAE, 0xEE, 0xFA, 0xDF, 0xAE, 0xF6, 0xFA, 0xDF, 0xAD, 0xFE, 0xFA, 0xDF, + 0xAE, 0xFF, 0xFA, 0xDF, 0xAE, 0xFF, 0xFB, 0xDF, 0xAF, 0xFF, 0xFB, 0xDF, 0xB0, 0xFF, 0xFB, 0xE0, + 0xAF, 0xFF, 0xFA, 0xDF, 0xAF, 0xFF, 0xFA, 0xDF, 0xAF, 0xFF, 0xFA, 0xDF, 0xAF, 0xFF, 0xF9, 0xDF, + 0xAE, 0xFF, 0xFA, 0xDE, 0xAD, 0xFF, 0xFA, 0xDF, 0xAF, 0xFF, 0xFB, 0xE0, 0xAF, 0xFF, 0xFC, 0xE1, + 0xAF, 0xFF, 0xFC, 0xE1, 0xAF, 0xFE, 0xFC, 0xE0, 0xAD, 0xFC, 0xFC, 0xE0, 0xAD, 0xF8, 0xFB, 0xE0, + 0xAD, 0xF1, 0xFB, 0xDF, 0xAD, 0xE6, 0xFC, 0xE0, 0xAF, 0xDB, 0xFC, 0xE1, 0xB1, 0xCD, 0xFB, 0xE0, + 0xB1, 0xAE, 0xFD, 0xE3, 0xB7, 0x8F, 0xFF, 0xE4, 0xBA, 0x69, 0xF8, 0xE1, 0xB7, 0x42, 0xF9, 0xE4, + 0xBD, 0x26, 0xFE, 0xE5, 0xBF, 0x12, 0xF5, 0xE2, 0xBB, 0x05, 0xEC, 0xE5, 0xC5, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF7, 0xE2, + 0xBA, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFB, 0xE3, 0xB9, 0x04, 0xFC, 0xEB, + 0xC9, 0x16, 0xFC, 0xE9, 0xC7, 0x2B, 0xFB, 0xE2, 0xB6, 0x3E, 0xFB, 0xE1, 0xB2, 0x58, 0xFB, 0xE1, + 0xB3, 0x74, 0xFB, 0xE0, 0xB2, 0x90, 0xFA, 0xE0, 0xB0, 0xA4, 0xFA, 0xE0, 0xAF, 0xBB, 0xFA, 0xDF, + 0xAD, 0xD3, 0xF9, 0xDF, 0xAD, 0xE0, 0xF9, 0xDE, 0xAD, 0xEC, 0xF9, 0xDD, 0xAC, 0xF7, 0xF9, 0xDE, + 0xAD, 0xFB, 0xFA, 0xDE, 0xAD, 0xFF, 0xF9, 0xDD, 0xAB, 0xFF, 0xFA, 0xDE, 0xAD, 0xFF, 0xF9, 0xDE, + 0xAC, 0xFF, 0xF9, 0xDF, 0xAD, 0xFF, 0xFA, 0xDE, 0xAD, 0xFE, 0xF9, 0xDE, 0xAA, 0xF2, 0xF8, 0xDC, + 0xA7, 0xE7, 0xF8, 0xDC, 0xA8, 0xD5, 0xF9, 0xDE, 0xAB, 0xC4, 0xFC, 0xE0, 0xAF, 0xAD, 0xFC, 0xE1, + 0xB2, 0x99, 0xFB, 0xE1, 0xB4, 0x7E, 0xFB, 0xE2, 0xB6, 0x67, 0xFB, 0xE2, 0xB7, 0x4A, 0xFA, 0xE2, + 0xB9, 0x31, 0xFD, 0xE9, 0xC8, 0x1D, 0xFA, 0xFE, 0xFF, 0x0D, 0xFE, 0xFF, 0xFF, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFC, 0xE9, 0xC7, 0x01, 0xFB, 0xE4, 0xBA, 0x03, 0xFC, 0xE3, 0xB6, 0x0A, 0xFC, 0xE2, + 0xB5, 0x12, 0xFB, 0xE1, 0xB3, 0x18, 0xFA, 0xE0, 0xB1, 0x22, 0xFB, 0xE0, 0xB0, 0x2C, 0xFA, 0xE0, + 0xAF, 0x33, 0xFB, 0xE1, 0xB1, 0x3E, 0xFA, 0xE1, 0xB3, 0x45, 0xFA, 0xE1, 0xB3, 0x4A, 0xFA, 0xE2, + 0xB3, 0x50, 0xFB, 0xE2, 0xB3, 0x53, 0xFC, 0xE2, 0xB5, 0x56, 0xFC, 0xE2, 0xB4, 0x55, 0xFB, 0xE2, + 0xB4, 0x51, 0xFB, 0xE2, 0xB3, 0x4B, 0xF9, 0xE0, 0xB1, 0x47, 0xFA, 0xE1, 0xB2, 0x47, 0xFA, 0xE0, + 0xB5, 0x43, 0xFA, 0xE2, 0xB6, 0x3D, 0xF9, 0xE1, 0xB3, 0x32, 0xFB, 0xE1, 0xB3, 0x28, 0xFA, 0xE2, + 0xB4, 0x20, 0xFB, 0xE2, 0xB6, 0x17, 0xFB, 0xE3, 0xB8, 0x0C, 0xFC, 0xE4, 0xBC, 0x08, 0xFB, 0xE6, + 0xC1, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEB, 0xCA, 0x03, 0xFF, 0xED, 0xCB, 0x07, 0xFE, 0xE9, + 0xC1, 0x06, 0xFD, 0xE6, 0xBC, 0x07, 0xFC, 0xE5, 0xBB, 0x08, 0xFD, 0xE6, 0xBC, 0x08, 0xFD, 0xE8, + 0xBF, 0x07, 0xFE, 0xE9, 0xC1, 0x07, 0xFB, 0xE8, 0xC0, 0x06, 0xFF, 0xF1, 0xD2, 0x06, 0xFF, 0xFF, + 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0xF0, 0xCF, 0x01, 0xFB, 0xE4, 0xB6, 0x01, 0xFC, 0xE3, + 0xB5, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xEC, 0xD0, 0x04, 0xFF, 0xED, 0xD2, 0x08, 0xFE, 0xEB, + 0xC7, 0x0A, 0xFD, 0xE7, 0xBF, 0x0B, 0xFC, 0xE6, 0xBD, 0x0C, 0xFC, 0xE7, 0xBE, 0x0D, 0xFC, 0xE9, + 0xC1, 0x0C, 0xFE, 0xE9, 0xC3, 0x0B, 0xFC, 0xE9, 0xC2, 0x09, 0xFB, 0xF0, 0xD7, 0x06, 0xFF, 0xFF, + 0xFF, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x13, 0xFF, 0xFF, 0xFF, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x7F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x80, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x1F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x01, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x28, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x90, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x54, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x44, 0x0C, 0x01, 0x82, 0x44, 0x0C, 0x01, 0x82, 0x44, + 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x03, 0x82, 0x44, + 0x0C, 0x03, 0x82, 0x44, 0x0C, 0x04, 0x82, 0x44, 0x0C, 0x05, 0x82, 0x44, 0x0C, 0x05, 0x82, 0x44, + 0x0C, 0x06, 0x82, 0x44, 0x0C, 0x07, 0x82, 0x44, 0x0C, 0x07, 0x82, 0x44, 0x0C, 0x08, 0x82, 0x44, + 0x0C, 0x08, 0x82, 0x44, 0x0C, 0x09, 0x82, 0x44, 0x0C, 0x0A, 0x82, 0x44, 0x0C, 0x0A, 0x82, 0x44, + 0x0C, 0x0A, 0x82, 0x44, 0x0C, 0x0A, 0x82, 0x44, 0x0C, 0x0B, 0x82, 0x44, 0x0C, 0x0B, 0x82, 0x44, + 0x0C, 0x0B, 0x82, 0x44, 0x0C, 0x0B, 0x82, 0x44, 0x0C, 0x0B, 0x82, 0x44, 0x0C, 0x0B, 0x82, 0x44, + 0x0C, 0x0B, 0x82, 0x44, 0x0C, 0x0B, 0x82, 0x44, 0x0C, 0x0A, 0x82, 0x44, 0x0C, 0x0A, 0x82, 0x44, + 0x0C, 0x0A, 0x82, 0x44, 0x0C, 0x09, 0x82, 0x44, 0x0C, 0x09, 0x82, 0x44, 0x0C, 0x08, 0x82, 0x44, + 0x0C, 0x07, 0x82, 0x44, 0x0C, 0x07, 0x82, 0x44, 0x0C, 0x07, 0x82, 0x44, 0x0C, 0x06, 0x82, 0x44, + 0x0C, 0x05, 0x82, 0x44, 0x0C, 0x05, 0x82, 0x44, 0x0C, 0x04, 0x82, 0x44, 0x0C, 0x03, 0x82, 0x44, + 0x0C, 0x03, 0x82, 0x44, 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x01, 0x82, 0x44, + 0x0C, 0x01, 0x82, 0x44, 0x0C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x44, + 0x0C, 0x01, 0x82, 0x44, 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x03, 0x82, 0x44, + 0x0C, 0x04, 0x82, 0x44, 0x0C, 0x05, 0x82, 0x44, 0x0C, 0x06, 0x82, 0x44, 0x0C, 0x07, 0x82, 0x44, + 0x0C, 0x09, 0x82, 0x44, 0x0C, 0x0A, 0x82, 0x44, 0x0C, 0x0B, 0x82, 0x44, 0x0C, 0x0C, 0x82, 0x44, + 0x0C, 0x0D, 0x82, 0x44, 0x0C, 0x0E, 0x82, 0x44, 0x0C, 0x0F, 0x82, 0x44, 0x0C, 0x10, 0x82, 0x44, + 0x0C, 0x11, 0x82, 0x44, 0x0C, 0x12, 0x82, 0x44, 0x0C, 0x13, 0x82, 0x44, 0x0C, 0x14, 0x82, 0x44, + 0x0C, 0x14, 0x82, 0x44, 0x0C, 0x14, 0x82, 0x44, 0x0C, 0x15, 0x82, 0x44, 0x0C, 0x15, 0x82, 0x44, + 0x0C, 0x16, 0x82, 0x44, 0x0C, 0x16, 0x82, 0x44, 0x0C, 0x16, 0x82, 0x44, 0x0C, 0x15, 0x82, 0x44, + 0x0C, 0x15, 0x82, 0x44, 0x0C, 0x15, 0x82, 0x44, 0x0C, 0x14, 0x82, 0x44, 0x0C, 0x14, 0x82, 0x44, + 0x0C, 0x13, 0x82, 0x44, 0x0C, 0x12, 0x82, 0x44, 0x0C, 0x11, 0x82, 0x44, 0x0C, 0x11, 0x82, 0x44, + 0x0C, 0x10, 0x82, 0x44, 0x0C, 0x0F, 0x82, 0x44, 0x0C, 0x0E, 0x82, 0x44, 0x0C, 0x0D, 0x82, 0x44, + 0x0C, 0x0C, 0x82, 0x44, 0x0C, 0x0A, 0x82, 0x44, 0x0C, 0x09, 0x82, 0x44, 0x0C, 0x08, 0x82, 0x44, + 0x0C, 0x07, 0x82, 0x44, 0x0C, 0x06, 0x82, 0x44, 0x0C, 0x04, 0x82, 0x44, 0x0C, 0x03, 0x82, 0x44, + 0x0C, 0x03, 0x82, 0x44, 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x01, 0x82, 0x44, 0x0C, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x44, 0x0C, 0x01, 0x82, 0x44, 0x0C, 0x02, 0x82, 0x44, + 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x04, 0x82, 0x44, 0x0C, 0x06, 0x82, 0x44, 0x0C, 0x08, 0x82, 0x44, + 0x0C, 0x09, 0x82, 0x44, 0x0C, 0x0B, 0x82, 0x44, 0x0C, 0x0E, 0x82, 0x44, 0x0C, 0x10, 0x82, 0x44, + 0x0C, 0x12, 0x82, 0x44, 0x0C, 0x14, 0x82, 0x44, 0x0C, 0x16, 0x82, 0x44, 0x0C, 0x18, 0x82, 0x44, + 0x0C, 0x1B, 0x82, 0x44, 0x0C, 0x1D, 0x82, 0x44, 0x0C, 0x1E, 0x82, 0x44, 0x0C, 0x1F, 0x82, 0x44, + 0x0C, 0x21, 0x82, 0x44, 0x0C, 0x22, 0x82, 0x44, 0x0C, 0x23, 0x82, 0x44, 0x0C, 0x25, 0x82, 0x44, + 0x0C, 0x25, 0x82, 0x44, 0x0C, 0x26, 0x82, 0x44, 0x0C, 0x27, 0x82, 0x44, 0x0C, 0x27, 0x82, 0x44, + 0x0C, 0x27, 0x82, 0x44, 0x0C, 0x28, 0x82, 0x44, 0x0C, 0x28, 0x82, 0x44, 0x0C, 0x27, 0x82, 0x44, + 0x0C, 0x27, 0x82, 0x44, 0x0C, 0x26, 0x82, 0x44, 0x0C, 0x26, 0x82, 0x44, 0x0C, 0x25, 0x82, 0x44, + 0x0C, 0x24, 0x82, 0x44, 0x0C, 0x23, 0x82, 0x44, 0x0C, 0x22, 0x82, 0x44, 0x0C, 0x21, 0x82, 0x44, + 0x0C, 0x1F, 0x82, 0x44, 0x0C, 0x1D, 0x82, 0x44, 0x0C, 0x1C, 0x82, 0x44, 0x0C, 0x1A, 0x82, 0x44, + 0x0C, 0x18, 0x82, 0x44, 0x0C, 0x16, 0x82, 0x44, 0x0C, 0x13, 0x82, 0x44, 0x0C, 0x11, 0x82, 0x44, + 0x0C, 0x0F, 0x82, 0x44, 0x0C, 0x0D, 0x82, 0x44, 0x0C, 0x0B, 0x82, 0x44, 0x0C, 0x08, 0x82, 0x44, + 0x0C, 0x06, 0x82, 0x44, 0x0C, 0x05, 0x82, 0x44, 0x0C, 0x03, 0x82, 0x44, 0x0C, 0x02, 0x82, 0x44, + 0x0C, 0x01, 0x82, 0x44, 0x0C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x82, 0x44, 0x0C, 0x01, 0x82, 0x44, 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x04, 0x82, 0x44, + 0x0C, 0x06, 0x82, 0x44, 0x0C, 0x09, 0x82, 0x44, 0x0C, 0x0C, 0x82, 0x44, 0x0C, 0x10, 0x82, 0x44, + 0x0C, 0x13, 0x82, 0x44, 0x0C, 0x17, 0x82, 0x44, 0x0C, 0x1B, 0x82, 0x44, 0x0C, 0x1E, 0x82, 0x44, + 0x0C, 0x22, 0x82, 0x44, 0x0C, 0x25, 0x82, 0x44, 0x0C, 0x28, 0x82, 0x44, 0x0C, 0x2B, 0x82, 0x44, + 0x0C, 0x2E, 0x82, 0x44, 0x0C, 0x31, 0x82, 0x44, 0x0C, 0x33, 0x82, 0x44, 0x0C, 0x34, 0x82, 0x44, + 0x0C, 0x37, 0x82, 0x44, 0x0C, 0x39, 0x82, 0x44, 0x0C, 0x3A, 0x82, 0x44, 0x0C, 0x3B, 0x82, 0x44, + 0x0C, 0x3C, 0x82, 0x44, 0x0C, 0x3D, 0x82, 0x44, 0x0C, 0x3F, 0x82, 0x44, 0x0C, 0x3F, 0x82, 0x44, + 0x0C, 0x3F, 0x82, 0x44, 0x0C, 0x3F, 0x82, 0x44, 0x0C, 0x3F, 0x82, 0x44, 0x0C, 0x3F, 0x82, 0x44, + 0x0C, 0x3F, 0x82, 0x44, 0x0C, 0x3E, 0x82, 0x44, 0x0C, 0x3D, 0x82, 0x44, 0x0C, 0x3C, 0x82, 0x44, + 0x0C, 0x3B, 0x82, 0x44, 0x0C, 0x39, 0x82, 0x44, 0x0C, 0x38, 0x82, 0x44, 0x0C, 0x36, 0x82, 0x44, + 0x0C, 0x34, 0x82, 0x44, 0x0C, 0x32, 0x82, 0x44, 0x0C, 0x2F, 0x82, 0x44, 0x0C, 0x2D, 0x82, 0x44, + 0x0C, 0x2A, 0x82, 0x44, 0x0C, 0x27, 0x82, 0x44, 0x0C, 0x23, 0x82, 0x44, 0x0C, 0x20, 0x82, 0x44, + 0x0C, 0x1D, 0x82, 0x44, 0x0C, 0x19, 0x82, 0x44, 0x0C, 0x15, 0x82, 0x44, 0x0C, 0x11, 0x82, 0x44, + 0x0C, 0x0E, 0x82, 0x44, 0x0C, 0x0A, 0x82, 0x44, 0x0C, 0x07, 0x82, 0x44, 0x0C, 0x05, 0x82, 0x44, + 0x0C, 0x03, 0x82, 0x44, 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x44, + 0x0C, 0x01, 0x82, 0x44, 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x04, 0x82, 0x44, 0x0C, 0x07, 0x82, 0x44, + 0x0C, 0x0B, 0x82, 0x44, 0x0C, 0x11, 0x82, 0x44, 0x0C, 0x16, 0x82, 0x44, 0x0C, 0x1C, 0x82, 0x44, + 0x0C, 0x22, 0x82, 0x44, 0x0C, 0x28, 0x82, 0x44, 0x0C, 0x2D, 0x82, 0x44, 0x0C, 0x32, 0x82, 0x44, + 0x0C, 0x37, 0x82, 0x44, 0x0C, 0x3C, 0x82, 0x44, 0x0C, 0x40, 0x82, 0x44, 0x0C, 0x43, 0x82, 0x44, + 0x0C, 0x46, 0x82, 0x44, 0x0C, 0x49, 0x82, 0x44, 0x0C, 0x4C, 0x82, 0x44, 0x0C, 0x4F, 0x82, 0x44, + 0x0C, 0x51, 0x82, 0x44, 0x0C, 0x53, 0x82, 0x44, 0x0C, 0x55, 0x82, 0x44, 0x0C, 0x56, 0x82, 0x44, + 0x0C, 0x57, 0x82, 0x44, 0x0C, 0x59, 0x82, 0x44, 0x0C, 0x5A, 0x82, 0x44, 0x0C, 0x5A, 0x82, 0x44, + 0x0C, 0x5A, 0x82, 0x44, 0x0C, 0x5A, 0x82, 0x44, 0x0C, 0x5A, 0x82, 0x44, 0x0C, 0x5A, 0x82, 0x44, + 0x0C, 0x5A, 0x82, 0x44, 0x0C, 0x5A, 0x82, 0x44, 0x0C, 0x58, 0x82, 0x44, 0x0C, 0x57, 0x82, 0x44, + 0x0C, 0x56, 0x82, 0x44, 0x0C, 0x54, 0x82, 0x44, 0x0C, 0x52, 0x82, 0x44, 0x0C, 0x50, 0x82, 0x44, + 0x0C, 0x4E, 0x82, 0x44, 0x0C, 0x4B, 0x82, 0x44, 0x0C, 0x48, 0x82, 0x44, 0x0C, 0x45, 0x82, 0x44, + 0x0C, 0x42, 0x82, 0x44, 0x0C, 0x3E, 0x82, 0x44, 0x0C, 0x39, 0x82, 0x44, 0x0C, 0x35, 0x82, 0x44, + 0x0C, 0x30, 0x82, 0x44, 0x0C, 0x2B, 0x82, 0x44, 0x0C, 0x25, 0x82, 0x44, 0x0C, 0x1F, 0x82, 0x44, + 0x0C, 0x19, 0x82, 0x44, 0x0C, 0x14, 0x82, 0x44, 0x0C, 0x0E, 0x82, 0x44, 0x0C, 0x09, 0x82, 0x44, + 0x0C, 0x06, 0x82, 0x44, 0x0C, 0x03, 0x81, 0x43, 0x0B, 0x02, 0x81, 0x42, 0x0B, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x44, 0x0C, 0x01, 0x82, 0x44, + 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x04, 0x82, 0x44, 0x0C, 0x08, 0x82, 0x44, 0x0C, 0x0D, 0x82, 0x44, + 0x0C, 0x13, 0x82, 0x44, 0x0C, 0x1B, 0x82, 0x44, 0x0C, 0x24, 0x82, 0x44, 0x0C, 0x2D, 0x82, 0x44, + 0x0C, 0x36, 0x82, 0x44, 0x0C, 0x3E, 0x82, 0x44, 0x0C, 0x45, 0x82, 0x44, 0x0C, 0x4B, 0x82, 0x44, + 0x0C, 0x51, 0x82, 0x44, 0x0C, 0x56, 0x82, 0x44, 0x0C, 0x5B, 0x82, 0x44, 0x0C, 0x5F, 0x82, 0x44, + 0x0C, 0x62, 0x82, 0x44, 0x0C, 0x66, 0x82, 0x44, 0x0C, 0x69, 0x82, 0x44, 0x0C, 0x6B, 0x82, 0x44, + 0x0C, 0x6D, 0x82, 0x44, 0x0C, 0x6F, 0x82, 0x44, 0x0C, 0x72, 0x82, 0x44, 0x0C, 0x73, 0x82, 0x44, + 0x0C, 0x74, 0x82, 0x44, 0x0C, 0x76, 0x82, 0x44, 0x0C, 0x76, 0x82, 0x44, 0x0C, 0x77, 0x82, 0x44, + 0x0C, 0x77, 0x82, 0x44, 0x0C, 0x77, 0x82, 0x44, 0x0C, 0x77, 0x82, 0x44, 0x0C, 0x77, 0x82, 0x44, + 0x0C, 0x76, 0x82, 0x44, 0x0C, 0x76, 0x82, 0x44, 0x0C, 0x75, 0x82, 0x44, 0x0C, 0x74, 0x82, 0x44, + 0x0C, 0x72, 0x82, 0x44, 0x0C, 0x70, 0x82, 0x44, 0x0C, 0x6E, 0x82, 0x44, 0x0C, 0x6D, 0x82, 0x44, + 0x0C, 0x6A, 0x82, 0x44, 0x0C, 0x67, 0x82, 0x44, 0x0C, 0x64, 0x82, 0x44, 0x0C, 0x60, 0x82, 0x44, + 0x0C, 0x5D, 0x82, 0x44, 0x0C, 0x58, 0x82, 0x44, 0x0C, 0x53, 0x82, 0x44, 0x0C, 0x4E, 0x82, 0x44, + 0x0C, 0x48, 0x82, 0x44, 0x0C, 0x42, 0x82, 0x44, 0x0C, 0x3A, 0x82, 0x44, 0x0C, 0x32, 0x82, 0x44, + 0x0C, 0x29, 0x82, 0x44, 0x0C, 0x20, 0x82, 0x44, 0x0C, 0x17, 0x82, 0x44, 0x0C, 0x10, 0x82, 0x44, + 0x0C, 0x0A, 0x82, 0x44, 0x0C, 0x05, 0x81, 0x43, 0x0B, 0x03, 0x85, 0x48, 0x12, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x42, 0x09, 0x01, 0x82, 0x44, + 0x0C, 0x03, 0x82, 0x44, 0x0C, 0x06, 0x82, 0x44, 0x0C, 0x0B, 0x82, 0x44, 0x0C, 0x13, 0x82, 0x44, + 0x0C, 0x1D, 0x82, 0x44, 0x0C, 0x28, 0x82, 0x44, 0x0C, 0x34, 0x82, 0x44, 0x0C, 0x41, 0x82, 0x44, + 0x0C, 0x4C, 0x82, 0x44, 0x0C, 0x56, 0x82, 0x44, 0x0C, 0x5F, 0x82, 0x44, 0x0C, 0x66, 0x82, 0x44, + 0x0C, 0x6C, 0x82, 0x44, 0x0C, 0x72, 0x82, 0x44, 0x0C, 0x76, 0x82, 0x44, 0x0C, 0x7B, 0x82, 0x44, + 0x0C, 0x7E, 0x82, 0x44, 0x0C, 0x82, 0x82, 0x44, 0x0C, 0x84, 0x82, 0x44, 0x0C, 0x87, 0x82, 0x44, + 0x0C, 0x89, 0x82, 0x44, 0x0C, 0x8B, 0x82, 0x44, 0x0B, 0x8D, 0x81, 0x43, 0x0B, 0x8D, 0x81, 0x43, + 0x0A, 0x8E, 0x81, 0x42, 0x09, 0x8F, 0x81, 0x42, 0x09, 0x90, 0x80, 0x41, 0x08, 0x90, 0x80, 0x41, + 0x08, 0x90, 0x80, 0x41, 0x08, 0x90, 0x81, 0x41, 0x08, 0x91, 0x81, 0x42, 0x09, 0x90, 0x81, 0x42, + 0x0A, 0x90, 0x81, 0x43, 0x0B, 0x90, 0x82, 0x43, 0x0B, 0x8F, 0x82, 0x44, 0x0C, 0x8E, 0x82, 0x44, + 0x0C, 0x8D, 0x82, 0x44, 0x0C, 0x8C, 0x82, 0x44, 0x0C, 0x8A, 0x82, 0x44, 0x0C, 0x88, 0x82, 0x44, + 0x0C, 0x86, 0x82, 0x44, 0x0C, 0x83, 0x82, 0x44, 0x0C, 0x80, 0x82, 0x44, 0x0C, 0x7D, 0x82, 0x44, + 0x0C, 0x78, 0x82, 0x44, 0x0C, 0x74, 0x82, 0x44, 0x0C, 0x6F, 0x82, 0x44, 0x0C, 0x69, 0x82, 0x44, + 0x0C, 0x62, 0x82, 0x44, 0x0C, 0x5B, 0x82, 0x44, 0x0C, 0x52, 0x82, 0x44, 0x0C, 0x47, 0x82, 0x44, + 0x0C, 0x3B, 0x82, 0x44, 0x0C, 0x2E, 0x82, 0x44, 0x0C, 0x22, 0x82, 0x44, 0x0C, 0x17, 0x82, 0x44, + 0x0C, 0x0F, 0x82, 0x44, 0x0C, 0x08, 0x82, 0x44, 0x0C, 0x04, 0x82, 0x43, 0x0C, 0x02, 0x9A, 0x68, + 0x3B, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x42, 0x0A, 0x01, 0x82, 0x44, + 0x0C, 0x04, 0x82, 0x44, 0x0C, 0x08, 0x82, 0x44, 0x0C, 0x0F, 0x82, 0x44, 0x0C, 0x19, 0x82, 0x44, + 0x0C, 0x26, 0x82, 0x44, 0x0C, 0x35, 0x82, 0x44, 0x0C, 0x44, 0x82, 0x44, 0x0C, 0x53, 0x82, 0x44, + 0x0C, 0x61, 0x82, 0x44, 0x0C, 0x6D, 0x82, 0x44, 0x0C, 0x77, 0x82, 0x44, 0x0C, 0x7E, 0x82, 0x44, + 0x0C, 0x85, 0x82, 0x44, 0x0C, 0x8A, 0x82, 0x44, 0x0C, 0x8F, 0x82, 0x44, 0x0C, 0x93, 0x82, 0x44, + 0x0C, 0x97, 0x82, 0x44, 0x0C, 0x9A, 0x82, 0x44, 0x0C, 0x9C, 0x81, 0x43, 0x0B, 0x9D, 0x81, 0x42, + 0x09, 0x9E, 0x81, 0x43, 0x0A, 0xA0, 0x84, 0x46, 0x0E, 0xA3, 0x87, 0x4C, 0x15, 0xA8, 0x8B, 0x52, + 0x1F, 0xAD, 0x90, 0x5B, 0x2B, 0xB5, 0x93, 0x5F, 0x32, 0xBA, 0x94, 0x61, 0x34, 0xBD, 0x94, 0x61, + 0x34, 0xBF, 0x94, 0x61, 0x34, 0xBE, 0x94, 0x60, 0x33, 0xBC, 0x92, 0x5D, 0x2E, 0xB8, 0x8D, 0x55, + 0x23, 0xB1, 0x89, 0x4E, 0x19, 0xAB, 0x85, 0x47, 0x11, 0xA7, 0x82, 0x44, 0x0B, 0xA4, 0x81, 0x42, + 0x09, 0xA2, 0x81, 0x43, 0x0A, 0xA1, 0x82, 0x44, 0x0B, 0xA0, 0x82, 0x44, 0x0C, 0x9F, 0x82, 0x44, + 0x0C, 0x9D, 0x82, 0x44, 0x0C, 0x9B, 0x82, 0x44, 0x0C, 0x98, 0x82, 0x44, 0x0C, 0x95, 0x82, 0x44, + 0x0C, 0x91, 0x82, 0x44, 0x0C, 0x8D, 0x82, 0x44, 0x0C, 0x88, 0x82, 0x44, 0x0C, 0x82, 0x82, 0x44, + 0x0C, 0x7B, 0x82, 0x44, 0x0C, 0x72, 0x82, 0x44, 0x0C, 0x67, 0x82, 0x44, 0x0C, 0x5B, 0x82, 0x44, + 0x0C, 0x4C, 0x82, 0x44, 0x0C, 0x3D, 0x82, 0x44, 0x0C, 0x2D, 0x82, 0x44, 0x0C, 0x1F, 0x82, 0x44, + 0x0C, 0x14, 0x82, 0x44, 0x0C, 0x0B, 0x82, 0x44, 0x0C, 0x06, 0x81, 0x43, 0x0B, 0x03, 0x89, 0x4E, + 0x1B, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x62, 0x32, 0x01, 0x81, 0x43, 0x0B, 0x02, 0x82, 0x44, + 0x0C, 0x04, 0x82, 0x44, 0x0C, 0x09, 0x82, 0x44, 0x0C, 0x12, 0x82, 0x44, 0x0C, 0x1E, 0x82, 0x44, + 0x0C, 0x2D, 0x82, 0x44, 0x0C, 0x3E, 0x82, 0x44, 0x0C, 0x50, 0x82, 0x44, 0x0C, 0x61, 0x82, 0x44, + 0x0C, 0x71, 0x82, 0x44, 0x0C, 0x7D, 0x82, 0x44, 0x0C, 0x88, 0x82, 0x44, 0x0C, 0x8F, 0x82, 0x44, + 0x0C, 0x96, 0x82, 0x44, 0x0C, 0x9C, 0x82, 0x44, 0x0C, 0xA0, 0x82, 0x44, 0x0C, 0xA4, 0x82, 0x43, + 0x0B, 0xA7, 0x81, 0x42, 0x09, 0xA8, 0x83, 0x45, 0x0D, 0xAB, 0x89, 0x4F, 0x1A, 0xB3, 0x92, 0x5E, + 0x2F, 0xC1, 0x9A, 0x6C, 0x44, 0xD1, 0x9F, 0x74, 0x51, 0xDF, 0x9E, 0x75, 0x56, 0xE8, 0x9D, 0x76, + 0x59, 0xF1, 0x9C, 0x76, 0x5A, 0xF8, 0x9B, 0x75, 0x5A, 0xFB, 0x9A, 0x74, 0x5A, 0xFD, 0x99, 0x74, + 0x5A, 0xFD, 0x9A, 0x75, 0x5B, 0xFD, 0x9C, 0x76, 0x5C, 0xFC, 0x9E, 0x79, 0x5E, 0xF9, 0x9F, 0x79, + 0x5D, 0xF4, 0xA0, 0x79, 0x5A, 0xEC, 0xA0, 0x77, 0x57, 0xE4, 0x9E, 0x72, 0x4D, 0xD8, 0x96, 0x65, + 0x39, 0xC9, 0x8C, 0x55, 0x22, 0xBB, 0x85, 0x48, 0x11, 0xB1, 0x81, 0x42, 0x0A, 0xAD, 0x81, 0x43, + 0x0A, 0xAC, 0x82, 0x44, 0x0C, 0xAB, 0x82, 0x44, 0x0C, 0xA8, 0x82, 0x44, 0x0C, 0xA6, 0x82, 0x44, + 0x0C, 0xA2, 0x82, 0x44, 0x0C, 0x9E, 0x82, 0x44, 0x0C, 0x99, 0x82, 0x44, 0x0C, 0x94, 0x82, 0x44, + 0x0C, 0x8C, 0x82, 0x44, 0x0C, 0x83, 0x82, 0x44, 0x0C, 0x78, 0x82, 0x44, 0x0C, 0x69, 0x82, 0x44, + 0x0C, 0x59, 0x82, 0x44, 0x0C, 0x47, 0x82, 0x44, 0x0C, 0x35, 0x82, 0x44, 0x0C, 0x25, 0x82, 0x44, + 0x0C, 0x17, 0x82, 0x44, 0x0C, 0x0D, 0x82, 0x44, 0x0C, 0x07, 0x82, 0x44, 0x0C, 0x03, 0x83, 0x46, + 0x0E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x62, 0x33, 0x01, 0x81, 0x43, 0x0B, 0x02, 0x82, 0x44, + 0x0C, 0x04, 0x82, 0x44, 0x0C, 0x0A, 0x82, 0x44, 0x0C, 0x13, 0x82, 0x44, 0x0C, 0x20, 0x82, 0x44, + 0x0C, 0x30, 0x82, 0x44, 0x0C, 0x42, 0x82, 0x44, 0x0C, 0x55, 0x82, 0x44, 0x0C, 0x67, 0x82, 0x44, + 0x0C, 0x77, 0x82, 0x44, 0x0C, 0x84, 0x82, 0x44, 0x0C, 0x8F, 0x82, 0x44, 0x0C, 0x97, 0x82, 0x44, + 0x0C, 0x9E, 0x82, 0x44, 0x0C, 0xA3, 0x81, 0x43, 0x0B, 0xA6, 0x81, 0x42, 0x0A, 0xA8, 0x87, 0x4C, + 0x15, 0xB1, 0x94, 0x60, 0x32, 0xC4, 0x9D, 0x71, 0x4C, 0xDB, 0x9E, 0x76, 0x57, 0xEE, 0x99, 0x72, + 0x56, 0xFA, 0x90, 0x68, 0x4D, 0xFE, 0x89, 0x60, 0x45, 0xFF, 0x83, 0x59, 0x3F, 0xFF, 0x7F, 0x54, + 0x3A, 0xFF, 0x7C, 0x50, 0x36, 0xFF, 0x7A, 0x4E, 0x34, 0xFF, 0x79, 0x4D, 0x34, 0xFF, 0x79, 0x4D, + 0x34, 0xFF, 0x7B, 0x4F, 0x35, 0xFF, 0x7C, 0x51, 0x37, 0xFF, 0x7F, 0x55, 0x3B, 0xFF, 0x83, 0x59, + 0x40, 0xFF, 0x88, 0x5F, 0x46, 0xFF, 0x8E, 0x67, 0x4D, 0xFF, 0x95, 0x6F, 0x55, 0xFF, 0x9D, 0x77, + 0x5D, 0xFC, 0xA2, 0x7C, 0x60, 0xF5, 0xA1, 0x78, 0x56, 0xE5, 0x99, 0x69, 0x3F, 0xD0, 0x8B, 0x53, + 0x1F, 0xBB, 0x82, 0x44, 0x0C, 0xB0, 0x81, 0x42, 0x0A, 0xAD, 0x82, 0x44, 0x0C, 0xAC, 0x82, 0x44, + 0x0C, 0xA9, 0x82, 0x44, 0x0C, 0xA5, 0x82, 0x44, 0x0C, 0xA0, 0x82, 0x44, 0x0C, 0x9B, 0x82, 0x44, + 0x0C, 0x94, 0x82, 0x44, 0x0C, 0x8A, 0x82, 0x44, 0x0C, 0x7F, 0x82, 0x44, 0x0C, 0x70, 0x82, 0x44, + 0x0C, 0x5E, 0x82, 0x44, 0x0C, 0x4C, 0x82, 0x44, 0x0C, 0x39, 0x82, 0x44, 0x0C, 0x28, 0x82, 0x44, + 0x0C, 0x19, 0x82, 0x44, 0x0C, 0x0E, 0x82, 0x44, 0x0C, 0x07, 0x82, 0x44, 0x0C, 0x03, 0x83, 0x44, + 0x0D, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x62, 0x33, 0x01, 0x81, 0x43, 0x0B, 0x02, 0x82, 0x44, + 0x0C, 0x04, 0x82, 0x44, 0x0C, 0x09, 0x82, 0x44, 0x0C, 0x12, 0x82, 0x44, 0x0C, 0x1F, 0x82, 0x44, + 0x0C, 0x2E, 0x82, 0x44, 0x0C, 0x3F, 0x82, 0x44, 0x0C, 0x51, 0x82, 0x44, 0x0C, 0x63, 0x82, 0x44, + 0x0C, 0x73, 0x82, 0x44, 0x0C, 0x80, 0x82, 0x44, 0x0C, 0x8A, 0x82, 0x44, 0x0C, 0x92, 0x81, 0x43, + 0x0B, 0x98, 0x81, 0x43, 0x0A, 0x9B, 0x8A, 0x50, 0x1C, 0xA9, 0x99, 0x69, 0x40, 0xC8, 0x9F, 0x76, + 0x56, 0xE8, 0x97, 0x70, 0x53, 0xFA, 0x8B, 0x61, 0x45, 0xFF, 0x7E, 0x53, 0x37, 0xFF, 0x76, 0x48, + 0x2D, 0xFF, 0x71, 0x43, 0x28, 0xFF, 0x6F, 0x41, 0x26, 0xFF, 0x6E, 0x40, 0x25, 0xFF, 0x6E, 0x40, + 0x25, 0xFF, 0x6F, 0x40, 0x26, 0xFF, 0x70, 0x41, 0x26, 0xFF, 0x71, 0x42, 0x27, 0xFF, 0x71, 0x43, + 0x28, 0xFF, 0x72, 0x44, 0x29, 0xFF, 0x73, 0x46, 0x2A, 0xFF, 0x74, 0x47, 0x2C, 0xFF, 0x75, 0x49, + 0x2E, 0xFF, 0x76, 0x4A, 0x2F, 0xFF, 0x78, 0x4C, 0x32, 0xFF, 0x7B, 0x50, 0x35, 0xFF, 0x81, 0x56, + 0x3C, 0xFF, 0x88, 0x5F, 0x45, 0xFF, 0x93, 0x6B, 0x51, 0xFF, 0x9D, 0x78, 0x5D, 0xFD, 0xA4, 0x7E, + 0x61, 0xF1, 0x9F, 0x73, 0x4F, 0xD9, 0x90, 0x5A, 0x2A, 0xBA, 0x83, 0x45, 0x0D, 0xA7, 0x81, 0x42, + 0x0A, 0xA3, 0x82, 0x44, 0x0C, 0xA0, 0x82, 0x44, 0x0C, 0x9C, 0x82, 0x44, 0x0C, 0x96, 0x82, 0x44, + 0x0C, 0x8F, 0x82, 0x44, 0x0C, 0x85, 0x82, 0x44, 0x0C, 0x7A, 0x82, 0x44, 0x0C, 0x6B, 0x82, 0x44, + 0x0C, 0x5B, 0x82, 0x44, 0x0C, 0x49, 0x82, 0x44, 0x0C, 0x37, 0x82, 0x44, 0x0C, 0x26, 0x82, 0x44, + 0x0C, 0x18, 0x82, 0x44, 0x0C, 0x0E, 0x82, 0x44, 0x0C, 0x07, 0x82, 0x44, 0x0C, 0x03, 0x83, 0x45, + 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x42, 0x0A, 0x02, 0x82, 0x44, + 0x0C, 0x04, 0x82, 0x44, 0x0C, 0x08, 0x82, 0x44, 0x0C, 0x0F, 0x82, 0x44, 0x0C, 0x1A, 0x82, 0x44, + 0x0C, 0x27, 0x82, 0x44, 0x0C, 0x37, 0x82, 0x44, 0x0C, 0x47, 0x82, 0x44, 0x0C, 0x56, 0x82, 0x44, + 0x0C, 0x65, 0x82, 0x44, 0x0C, 0x70, 0x82, 0x44, 0x0C, 0x7A, 0x81, 0x42, 0x09, 0x7F, 0x88, 0x4C, + 0x16, 0x8E, 0x9B, 0x6B, 0x42, 0xB9, 0x9F, 0x76, 0x57, 0xE7, 0x93, 0x6A, 0x4D, 0xFC, 0x81, 0x55, + 0x38, 0xFF, 0x74, 0x45, 0x29, 0xFF, 0x6D, 0x3D, 0x21, 0xFF, 0x6A, 0x3A, 0x1F, 0xFF, 0x6A, 0x3A, + 0x1E, 0xFF, 0x6B, 0x3B, 0x1F, 0xFF, 0x6D, 0x3C, 0x20, 0xFF, 0x6E, 0x3E, 0x21, 0xFF, 0x6F, 0x40, + 0x22, 0xFF, 0x71, 0x41, 0x23, 0xFF, 0x73, 0x43, 0x25, 0xFF, 0x74, 0x44, 0x26, 0xFF, 0x75, 0x45, + 0x27, 0xFF, 0x76, 0x46, 0x28, 0xFF, 0x76, 0x47, 0x29, 0xFF, 0x77, 0x48, 0x2A, 0xFF, 0x77, 0x49, + 0x2B, 0xFF, 0x78, 0x49, 0x2C, 0xFF, 0x78, 0x4A, 0x2D, 0xFF, 0x78, 0x4B, 0x2E, 0xFF, 0x78, 0x4B, + 0x2F, 0xFF, 0x7A, 0x4D, 0x31, 0xFF, 0x7D, 0x50, 0x35, 0xFF, 0x83, 0x58, 0x3C, 0xFF, 0x8D, 0x64, + 0x49, 0xFF, 0x9A, 0x74, 0x5A, 0xFF, 0xA5, 0x7F, 0x63, 0xF4, 0xA2, 0x77, 0x53, 0xD2, 0x8E, 0x57, + 0x25, 0xA4, 0x81, 0x43, 0x0A, 0x8E, 0x81, 0x43, 0x0B, 0x8B, 0x82, 0x44, 0x0C, 0x86, 0x82, 0x44, + 0x0C, 0x7F, 0x82, 0x44, 0x0C, 0x76, 0x82, 0x44, 0x0C, 0x6B, 0x82, 0x44, 0x0C, 0x5E, 0x82, 0x44, + 0x0C, 0x4F, 0x82, 0x44, 0x0C, 0x3F, 0x82, 0x44, 0x0C, 0x2F, 0x82, 0x44, 0x0C, 0x21, 0x82, 0x44, + 0x0C, 0x14, 0x82, 0x44, 0x0C, 0x0C, 0x82, 0x44, 0x0C, 0x06, 0x82, 0x43, 0x0B, 0x03, 0x86, 0x4A, + 0x15, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x42, 0x09, 0x01, 0x82, 0x44, + 0x0C, 0x03, 0x82, 0x44, 0x0C, 0x06, 0x82, 0x44, 0x0C, 0x0C, 0x82, 0x44, 0x0C, 0x14, 0x82, 0x44, + 0x0C, 0x1E, 0x82, 0x44, 0x0C, 0x2A, 0x82, 0x44, 0x0C, 0x37, 0x82, 0x44, 0x0C, 0x44, 0x82, 0x44, + 0x0C, 0x50, 0x81, 0x43, 0x0A, 0x5A, 0x83, 0x46, 0x0E, 0x62, 0x97, 0x65, 0x38, 0x8D, 0xA1, 0x77, + 0x56, 0xD3, 0x94, 0x6A, 0x4D, 0xFA, 0x7E, 0x50, 0x33, 0xFF, 0x6F, 0x3F, 0x22, 0xFF, 0x69, 0x38, + 0x1B, 0xFF, 0x67, 0x36, 0x19, 0xFF, 0x68, 0x37, 0x19, 0xFF, 0x6A, 0x38, 0x1A, 0xFF, 0x6C, 0x3A, + 0x1C, 0xFF, 0x6E, 0x3D, 0x1D, 0xFF, 0x71, 0x3F, 0x1F, 0xFF, 0x72, 0x41, 0x20, 0xFF, 0x74, 0x42, + 0x21, 0xFF, 0x76, 0x44, 0x22, 0xFF, 0x77, 0x46, 0x24, 0xFF, 0x78, 0x47, 0x25, 0xFF, 0x79, 0x48, + 0x26, 0xFF, 0x7A, 0x49, 0x27, 0xFF, 0x7B, 0x4A, 0x28, 0xFF, 0x7C, 0x4B, 0x29, 0xFF, 0x7C, 0x4C, + 0x2A, 0xFF, 0x7C, 0x4C, 0x2B, 0xFF, 0x7D, 0x4D, 0x2C, 0xFF, 0x7C, 0x4D, 0x2D, 0xFF, 0x7C, 0x4D, + 0x2E, 0xFF, 0x7C, 0x4D, 0x2F, 0xFF, 0x7B, 0x4D, 0x2F, 0xFF, 0x7C, 0x4E, 0x31, 0xFF, 0x7D, 0x50, + 0x34, 0xFF, 0x82, 0x56, 0x3A, 0xFF, 0x8D, 0x63, 0x47, 0xFF, 0x9C, 0x76, 0x5B, 0xFF, 0xA6, 0x81, + 0x64, 0xE9, 0x9F, 0x72, 0x4A, 0xAF, 0x89, 0x4F, 0x19, 0x7B, 0x81, 0x42, 0x09, 0x6C, 0x82, 0x44, + 0x0C, 0x67, 0x82, 0x44, 0x0C, 0x5F, 0x82, 0x44, 0x0C, 0x56, 0x82, 0x44, 0x0C, 0x4B, 0x82, 0x44, + 0x0C, 0x3E, 0x82, 0x44, 0x0C, 0x31, 0x82, 0x44, 0x0C, 0x24, 0x82, 0x44, 0x0C, 0x19, 0x82, 0x44, + 0x0C, 0x10, 0x82, 0x44, 0x0C, 0x09, 0x82, 0x44, 0x0C, 0x05, 0x81, 0x43, 0x0B, 0x02, 0x94, 0x60, + 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x44, 0x0B, 0x01, 0x82, 0x44, + 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x04, 0x82, 0x44, 0x0C, 0x08, 0x82, 0x44, 0x0C, 0x0E, 0x82, 0x44, + 0x0C, 0x15, 0x82, 0x44, 0x0C, 0x1E, 0x82, 0x44, 0x0C, 0x27, 0x82, 0x44, 0x0C, 0x31, 0x80, 0x41, + 0x08, 0x37, 0x8E, 0x56, 0x23, 0x4C, 0xA4, 0x7A, 0x57, 0x9E, 0x9C, 0x74, 0x56, 0xEC, 0x84, 0x57, + 0x38, 0xFF, 0x70, 0x3F, 0x21, 0xFF, 0x68, 0x36, 0x18, 0xFF, 0x66, 0x34, 0x15, 0xFF, 0x67, 0x35, + 0x16, 0xFF, 0x69, 0x37, 0x17, 0xFF, 0x6C, 0x39, 0x19, 0xFF, 0x6E, 0x3B, 0x1A, 0xFF, 0x71, 0x3E, + 0x1B, 0xFF, 0x73, 0x40, 0x1D, 0xFF, 0x75, 0x42, 0x1E, 0xFF, 0x77, 0x44, 0x20, 0xFF, 0x79, 0x45, + 0x21, 0xFF, 0x7A, 0x47, 0x22, 0xFF, 0x7C, 0x49, 0x23, 0xFF, 0x7D, 0x4A, 0x24, 0xFF, 0x7E, 0x4B, + 0x25, 0xFF, 0x7F, 0x4C, 0x26, 0xFF, 0x80, 0x4D, 0x27, 0xFF, 0x81, 0x4E, 0x28, 0xFF, 0x81, 0x4F, + 0x29, 0xFF, 0x81, 0x4F, 0x2A, 0xFF, 0x81, 0x50, 0x2B, 0xFF, 0x81, 0x50, 0x2C, 0xFF, 0x81, 0x50, + 0x2D, 0xFF, 0x81, 0x50, 0x2E, 0xFF, 0x80, 0x50, 0x2E, 0xFF, 0x7F, 0x50, 0x2F, 0xFF, 0x7E, 0x50, + 0x30, 0xFF, 0x7E, 0x50, 0x31, 0xFF, 0x80, 0x52, 0x35, 0xFF, 0x85, 0x5A, 0x3C, 0xFF, 0x92, 0x6A, + 0x4D, 0xFF, 0xA3, 0x7E, 0x62, 0xFA, 0xAA, 0x84, 0x64, 0xC8, 0x98, 0x66, 0x38, 0x72, 0x81, 0x42, + 0x09, 0x4B, 0x82, 0x43, 0x0B, 0x47, 0x82, 0x44, 0x0C, 0x3F, 0x82, 0x44, 0x0C, 0x36, 0x82, 0x44, + 0x0C, 0x2C, 0x82, 0x44, 0x0C, 0x23, 0x82, 0x44, 0x0C, 0x19, 0x82, 0x44, 0x0C, 0x11, 0x82, 0x44, + 0x0C, 0x0B, 0x82, 0x44, 0x0C, 0x06, 0x82, 0x44, 0x0B, 0x03, 0x85, 0x49, 0x13, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x45, + 0x0E, 0x01, 0x82, 0x44, 0x0C, 0x03, 0x82, 0x44, 0x0C, 0x05, 0x82, 0x44, 0x0C, 0x08, 0x82, 0x44, + 0x0C, 0x0D, 0x82, 0x44, 0x0C, 0x13, 0x82, 0x44, 0x0B, 0x19, 0x7D, 0x3C, 0x01, 0x1B, 0x9F, 0x70, + 0x46, 0x41, 0xA6, 0x7F, 0x60, 0xB4, 0x90, 0x65, 0x46, 0xF9, 0x75, 0x44, 0x24, 0xFF, 0x66, 0x32, + 0x13, 0xFF, 0x61, 0x2C, 0x0E, 0xFF, 0x61, 0x2B, 0x0C, 0xFF, 0x63, 0x2D, 0x0C, 0xFF, 0x65, 0x2E, + 0x0C, 0xFF, 0x68, 0x30, 0x0D, 0xFF, 0x6A, 0x32, 0x0E, 0xFF, 0x6D, 0x35, 0x0F, 0xFF, 0x6F, 0x38, + 0x11, 0xFF, 0x72, 0x3A, 0x13, 0xFF, 0x75, 0x3D, 0x14, 0xFF, 0x77, 0x40, 0x16, 0xFF, 0x7A, 0x43, + 0x19, 0xFF, 0x7D, 0x46, 0x1C, 0xFF, 0x7F, 0x49, 0x20, 0xFF, 0x81, 0x4C, 0x22, 0xFF, 0x83, 0x4E, + 0x24, 0xFF, 0x84, 0x4F, 0x26, 0xFF, 0x85, 0x50, 0x27, 0xFF, 0x85, 0x51, 0x29, 0xFF, 0x86, 0x51, + 0x29, 0xFF, 0x86, 0x52, 0x2A, 0xFF, 0x86, 0x52, 0x2B, 0xFF, 0x86, 0x53, 0x2C, 0xFF, 0x86, 0x53, + 0x2D, 0xFF, 0x85, 0x53, 0x2E, 0xFF, 0x85, 0x53, 0x2E, 0xFF, 0x84, 0x53, 0x2F, 0xFF, 0x83, 0x53, + 0x30, 0xFF, 0x82, 0x52, 0x30, 0xFF, 0x81, 0x52, 0x31, 0xFF, 0x80, 0x52, 0x33, 0xFF, 0x83, 0x55, + 0x37, 0xFF, 0x8C, 0x60, 0x43, 0xFF, 0x9C, 0x75, 0x59, 0xFF, 0xAB, 0x88, 0x6B, 0xDE, 0xA7, 0x7D, + 0x58, 0x72, 0x83, 0x45, 0x0D, 0x2D, 0x81, 0x42, 0x0A, 0x28, 0x82, 0x44, 0x0C, 0x23, 0x82, 0x44, + 0x0C, 0x1C, 0x82, 0x44, 0x0C, 0x16, 0x82, 0x44, 0x0C, 0x10, 0x82, 0x44, 0x0C, 0x0A, 0x82, 0x44, + 0x0C, 0x06, 0x82, 0x44, 0x0C, 0x03, 0x81, 0x43, 0x0A, 0x02, 0x94, 0x5F, 0x2E, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x4A, + 0x13, 0x01, 0x81, 0x43, 0x0B, 0x01, 0x82, 0x44, 0x0B, 0x02, 0x82, 0x44, 0x0C, 0x04, 0x82, 0x44, + 0x0C, 0x07, 0x81, 0x42, 0x0A, 0x0A, 0x77, 0x31, 0x00, 0x09, 0xB0, 0x8A, 0x69, 0x3F, 0xA4, 0x7D, + 0x5E, 0xC8, 0x85, 0x57, 0x36, 0xFF, 0x6A, 0x35, 0x14, 0xFF, 0x5F, 0x29, 0x09, 0xFF, 0x5D, 0x26, + 0x05, 0xFF, 0x5F, 0x27, 0x05, 0xFF, 0x62, 0x29, 0x05, 0xFF, 0x64, 0x2B, 0x05, 0xFF, 0x67, 0x2D, + 0x06, 0xFF, 0x69, 0x2F, 0x06, 0xFF, 0x6B, 0x30, 0x07, 0xFF, 0x6D, 0x32, 0x07, 0xFF, 0x70, 0x34, + 0x07, 0xFF, 0x72, 0x35, 0x08, 0xFF, 0x73, 0x37, 0x08, 0xFF, 0x75, 0x38, 0x09, 0xFF, 0x76, 0x39, + 0x0A, 0xFF, 0x78, 0x3B, 0x0B, 0xFF, 0x79, 0x3D, 0x0D, 0xFF, 0x7B, 0x40, 0x10, 0xFF, 0x7E, 0x43, + 0x13, 0xFF, 0x81, 0x48, 0x18, 0xFF, 0x84, 0x4C, 0x1E, 0xFF, 0x87, 0x50, 0x23, 0xFF, 0x89, 0x53, + 0x27, 0xFF, 0x8A, 0x55, 0x29, 0xFF, 0x8A, 0x56, 0x2A, 0xFF, 0x8A, 0x56, 0x2B, 0xFF, 0x8A, 0x56, + 0x2C, 0xFF, 0x8A, 0x56, 0x2D, 0xFF, 0x89, 0x56, 0x2D, 0xFF, 0x89, 0x56, 0x2E, 0xFF, 0x88, 0x56, + 0x2F, 0xFF, 0x87, 0x55, 0x2F, 0xFF, 0x85, 0x55, 0x30, 0xFF, 0x84, 0x54, 0x31, 0xFF, 0x83, 0x53, + 0x31, 0xFF, 0x83, 0x55, 0x34, 0xFF, 0x89, 0x5C, 0x3D, 0xFF, 0x97, 0x6F, 0x51, 0xFF, 0xAB, 0x86, + 0x6A, 0xEA, 0xB1, 0x8D, 0x6E, 0x78, 0x8E, 0x56, 0x23, 0x1A, 0x7F, 0x3F, 0x05, 0x12, 0x82, 0x44, + 0x0C, 0x10, 0x82, 0x44, 0x0C, 0x0C, 0x82, 0x44, 0x0C, 0x09, 0x82, 0x44, 0x0C, 0x05, 0x82, 0x44, + 0x0C, 0x03, 0x81, 0x43, 0x0B, 0x02, 0x80, 0x41, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x8B, 0x51, 0x1D, 0x01, 0x85, 0x48, 0x11, 0x01, 0x82, 0x44, 0x0C, 0x02, 0x7E, 0x3D, + 0x03, 0x03, 0x5C, 0x09, 0x00, 0x02, 0xB7, 0x95, 0x77, 0x3E, 0xA3, 0x7B, 0x5C, 0xD0, 0x81, 0x50, + 0x2D, 0xFF, 0x67, 0x31, 0x0F, 0xFF, 0x5F, 0x28, 0x07, 0xFF, 0x5F, 0x28, 0x05, 0xFF, 0x62, 0x2A, + 0x05, 0xFF, 0x65, 0x2C, 0x06, 0xFF, 0x67, 0x2E, 0x06, 0xFF, 0x6A, 0x30, 0x07, 0xFF, 0x6D, 0x32, + 0x07, 0xFF, 0x70, 0x34, 0x08, 0xFF, 0x72, 0x36, 0x08, 0xFF, 0x74, 0x38, 0x08, 0xFF, 0x76, 0x39, + 0x09, 0xFF, 0x78, 0x3B, 0x09, 0xFF, 0x79, 0x3C, 0x09, 0xFF, 0x7A, 0x3C, 0x09, 0xFF, 0x7B, 0x3D, + 0x0A, 0xFF, 0x7B, 0x3E, 0x09, 0xFF, 0x7C, 0x3E, 0x09, 0xFF, 0x7C, 0x3E, 0x09, 0xFF, 0x7C, 0x3E, + 0x09, 0xFF, 0x7D, 0x3E, 0x0A, 0xFF, 0x7E, 0x40, 0x0B, 0xFF, 0x7F, 0x42, 0x0E, 0xFF, 0x82, 0x46, + 0x13, 0xFF, 0x85, 0x4B, 0x19, 0xFF, 0x89, 0x51, 0x20, 0xFF, 0x8C, 0x56, 0x27, 0xFF, 0x8D, 0x58, + 0x2B, 0xFF, 0x8E, 0x59, 0x2C, 0xFF, 0x8D, 0x59, 0x2C, 0xFF, 0x8D, 0x59, 0x2D, 0xFF, 0x8C, 0x59, + 0x2E, 0xFF, 0x8B, 0x58, 0x2F, 0xFF, 0x8A, 0x58, 0x2F, 0xFF, 0x89, 0x57, 0x30, 0xFF, 0x87, 0x56, + 0x30, 0xFF, 0x85, 0x55, 0x31, 0xFF, 0x84, 0x55, 0x33, 0xFF, 0x88, 0x5A, 0x39, 0xFF, 0x95, 0x6B, + 0x4C, 0xFF, 0xAA, 0x86, 0x6A, 0xF2, 0xB6, 0x95, 0x79, 0x7C, 0x9D, 0x6D, 0x41, 0x0F, 0x78, 0x34, + 0x00, 0x06, 0x82, 0x44, 0x0D, 0x06, 0x82, 0x44, 0x0C, 0x04, 0x82, 0x43, 0x0B, 0x02, 0x82, 0x44, + 0x0D, 0x01, 0x86, 0x49, 0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xBB, 0x9A, 0x7E, 0x37, 0xA3, 0x7C, 0x5D, 0xCF, 0x7F, 0x4E, 0x2B, 0xFF, 0x67, 0x30, + 0x0E, 0xFF, 0x60, 0x29, 0x07, 0xFF, 0x61, 0x29, 0x06, 0xFF, 0x64, 0x2B, 0x06, 0xFF, 0x68, 0x2E, + 0x06, 0xFF, 0x6A, 0x30, 0x07, 0xFF, 0x6C, 0x32, 0x08, 0xFF, 0x6D, 0x34, 0x08, 0xFF, 0x6E, 0x35, + 0x08, 0xFF, 0x72, 0x38, 0x09, 0xFF, 0x77, 0x3A, 0x09, 0xFF, 0x79, 0x3C, 0x0A, 0xFF, 0x7B, 0x3E, + 0x0A, 0xFF, 0x7D, 0x3F, 0x0A, 0xFF, 0x7E, 0x3F, 0x0B, 0xFF, 0x7F, 0x40, 0x0B, 0xFF, 0x7F, 0x41, + 0x0B, 0xFF, 0x80, 0x41, 0x0B, 0xFF, 0x81, 0x42, 0x0B, 0xFF, 0x81, 0x42, 0x0B, 0xFF, 0x81, 0x42, + 0x0B, 0xFF, 0x81, 0x42, 0x0B, 0xFF, 0x81, 0x42, 0x0B, 0xFF, 0x81, 0x42, 0x0A, 0xFF, 0x81, 0x42, + 0x0A, 0xFF, 0x81, 0x42, 0x0A, 0xFF, 0x81, 0x43, 0x0C, 0xFF, 0x84, 0x46, 0x11, 0xFF, 0x87, 0x4C, + 0x18, 0xFF, 0x8C, 0x53, 0x22, 0xFF, 0x8F, 0x59, 0x29, 0xFF, 0x90, 0x5B, 0x2D, 0xFF, 0x90, 0x5B, + 0x2E, 0xFF, 0x8F, 0x5B, 0x2E, 0xFF, 0x8E, 0x5A, 0x2F, 0xFF, 0x8D, 0x5A, 0x2F, 0xFF, 0x8B, 0x59, + 0x30, 0xFF, 0x8A, 0x58, 0x31, 0xFF, 0x88, 0x57, 0x31, 0xFF, 0x87, 0x56, 0x33, 0xFF, 0x89, 0x5A, + 0x38, 0xFF, 0x95, 0x6A, 0x4A, 0xFF, 0xAB, 0x87, 0x6A, 0xF3, 0xBA, 0x99, 0x7E, 0x74, 0xA8, 0x7C, + 0x51, 0x07, 0x61, 0x13, 0x00, 0x01, 0x83, 0x45, 0x0D, 0x01, 0x85, 0x48, 0x11, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC5, 0xA9, + 0x90, 0x2C, 0xA7, 0x80, 0x61, 0xC6, 0x83, 0x51, 0x2D, 0xFF, 0x69, 0x32, 0x0F, 0xFF, 0x63, 0x2A, + 0x07, 0xFF, 0x64, 0x2A, 0x06, 0xFF, 0x66, 0x2D, 0x07, 0xFF, 0x6A, 0x30, 0x07, 0xFF, 0x6D, 0x32, + 0x08, 0xFF, 0x6E, 0x34, 0x08, 0xFF, 0x6B, 0x34, 0x08, 0xFF, 0x66, 0x32, 0x06, 0xFF, 0x65, 0x32, + 0x06, 0xFF, 0x6B, 0x36, 0x08, 0xFF, 0x75, 0x3C, 0x0A, 0xFF, 0x7C, 0x3F, 0x0B, 0xFF, 0x80, 0x41, + 0x0B, 0xFF, 0x81, 0x42, 0x0B, 0xFF, 0x82, 0x43, 0x0B, 0xFF, 0x83, 0x44, 0x0B, 0xFF, 0x83, 0x44, + 0x0B, 0xFF, 0x84, 0x45, 0x0C, 0xFF, 0x84, 0x45, 0x0C, 0xFF, 0x85, 0x45, 0x0C, 0xFF, 0x85, 0x45, + 0x0C, 0xFF, 0x85, 0x45, 0x0C, 0xFF, 0x85, 0x45, 0x0C, 0xFF, 0x85, 0x45, 0x0C, 0xFF, 0x85, 0x45, + 0x0C, 0xFF, 0x85, 0x45, 0x0C, 0xFF, 0x85, 0x45, 0x0C, 0xFF, 0x84, 0x44, 0x0B, 0xFF, 0x83, 0x44, + 0x0B, 0xFF, 0x84, 0x45, 0x0D, 0xFF, 0x86, 0x49, 0x12, 0xFF, 0x8B, 0x51, 0x1C, 0xFF, 0x90, 0x58, + 0x27, 0xFF, 0x92, 0x5C, 0x2D, 0xFF, 0x92, 0x5D, 0x2F, 0xFF, 0x91, 0x5C, 0x2F, 0xFF, 0x8F, 0x5C, + 0x2F, 0xFF, 0x8E, 0x5B, 0x30, 0xFF, 0x8C, 0x5A, 0x31, 0xFF, 0x8A, 0x58, 0x31, 0xFF, 0x89, 0x58, + 0x32, 0xFF, 0x8B, 0x5B, 0x38, 0xFF, 0x98, 0x6C, 0x4B, 0xFF, 0xAE, 0x89, 0x6C, 0xED, 0xBF, 0x9F, + 0x85, 0x62, 0xD1, 0xB1, 0x92, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCD, 0xB2, 0x9C, 0x19, 0xAD, 0x88, + 0x69, 0xB4, 0x88, 0x57, 0x33, 0xFF, 0x6C, 0x34, 0x10, 0xFF, 0x65, 0x2B, 0x07, 0xFF, 0x66, 0x2C, + 0x06, 0xFF, 0x69, 0x2F, 0x07, 0xFF, 0x6D, 0x31, 0x07, 0xFF, 0x70, 0x34, 0x08, 0xFF, 0x6F, 0x35, + 0x08, 0xFF, 0x68, 0x33, 0x06, 0xFF, 0x60, 0x32, 0x08, 0xFF, 0x92, 0x74, 0x58, 0xFF, 0xA0, 0x89, + 0x71, 0xFF, 0x65, 0x3D, 0x14, 0xFF, 0x67, 0x36, 0x06, 0xFF, 0x77, 0x3F, 0x0A, 0xFF, 0x80, 0x43, + 0x0B, 0xFF, 0x84, 0x45, 0x0C, 0xFF, 0x86, 0x46, 0x0C, 0xFF, 0x86, 0x46, 0x0C, 0xFF, 0x87, 0x46, + 0x0C, 0xFF, 0x87, 0x47, 0x0C, 0xFF, 0x87, 0x47, 0x0C, 0xFF, 0x88, 0x47, 0x0C, 0xFF, 0x87, 0x47, + 0x0C, 0xFF, 0x87, 0x47, 0x0C, 0xFF, 0x87, 0x47, 0x0C, 0xFF, 0x87, 0x47, 0x0C, 0xFF, 0x87, 0x47, + 0x0C, 0xFF, 0x87, 0x47, 0x0C, 0xFF, 0x88, 0x47, 0x0C, 0xFF, 0x87, 0x47, 0x0C, 0xFF, 0x87, 0x47, + 0x0C, 0xFF, 0x86, 0x46, 0x0C, 0xFF, 0x86, 0x46, 0x0B, 0xFF, 0x85, 0x46, 0x0B, 0xFF, 0x87, 0x48, + 0x0F, 0xFF, 0x8B, 0x50, 0x18, 0xFF, 0x91, 0x58, 0x25, 0xFF, 0x94, 0x5E, 0x2E, 0xFF, 0x94, 0x5E, + 0x30, 0xFF, 0x92, 0x5D, 0x30, 0xFF, 0x90, 0x5C, 0x30, 0xFF, 0x8E, 0x5B, 0x30, 0xFF, 0x8D, 0x5A, + 0x31, 0xFF, 0x8B, 0x59, 0x32, 0xFF, 0x8D, 0x5D, 0x39, 0xFF, 0x9B, 0x6F, 0x4E, 0xFF, 0xB2, 0x8E, + 0x71, 0xE4, 0xC8, 0xAB, 0x93, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0xD4, 0xC1, 0x07, 0xB5, 0x92, 0x74, 0x8D, 0x90, 0x61, + 0x3C, 0xFE, 0x70, 0x39, 0x13, 0xFF, 0x67, 0x2D, 0x08, 0xFF, 0x68, 0x2D, 0x07, 0xFF, 0x6C, 0x30, + 0x07, 0xFF, 0x6F, 0x33, 0x08, 0xFF, 0x72, 0x36, 0x09, 0xFF, 0x71, 0x38, 0x09, 0xFF, 0x67, 0x32, + 0x05, 0xFF, 0x6C, 0x45, 0x1E, 0xFF, 0xA0, 0x8C, 0x77, 0xFF, 0xB8, 0xAE, 0xA1, 0xFF, 0xE4, 0xE2, + 0xDD, 0xFF, 0xC3, 0xB7, 0xA8, 0xFF, 0x74, 0x53, 0x2E, 0xFF, 0x66, 0x38, 0x06, 0xFF, 0x76, 0x40, + 0x0A, 0xFF, 0x81, 0x45, 0x0C, 0xFF, 0x86, 0x48, 0x0D, 0xFF, 0x89, 0x49, 0x0D, 0xFF, 0x89, 0x49, + 0x0D, 0xFF, 0x89, 0x49, 0x0D, 0xFF, 0x89, 0x49, 0x0D, 0xFF, 0x89, 0x49, 0x0D, 0xFF, 0x89, 0x49, + 0x0D, 0xFF, 0x89, 0x49, 0x0D, 0xFF, 0x89, 0x49, 0x0D, 0xFF, 0x89, 0x49, 0x0D, 0xFF, 0x89, 0x49, + 0x0D, 0xFF, 0x89, 0x49, 0x0D, 0xFF, 0x89, 0x49, 0x0D, 0xFF, 0x89, 0x49, 0x0D, 0xFF, 0x89, 0x49, + 0x0D, 0xFF, 0x89, 0x49, 0x0D, 0xFF, 0x89, 0x49, 0x0D, 0xFF, 0x88, 0x48, 0x0D, 0xFF, 0x88, 0x48, + 0x0C, 0xFF, 0x87, 0x47, 0x0C, 0xFF, 0x88, 0x49, 0x0E, 0xFF, 0x8C, 0x50, 0x18, 0xFF, 0x92, 0x5A, + 0x26, 0xFF, 0x95, 0x5F, 0x2E, 0xFF, 0x94, 0x5F, 0x30, 0xFF, 0x92, 0x5E, 0x30, 0xFF, 0x91, 0x5D, + 0x30, 0xFF, 0x8F, 0x5B, 0x31, 0xFF, 0x8D, 0x5A, 0x32, 0xFF, 0x90, 0x60, 0x3A, 0xFF, 0xA0, 0x75, + 0x53, 0xFF, 0xB7, 0x95, 0x78, 0xCD, 0xD0, 0xB8, 0xA3, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0x9F, 0x83, 0x59, 0x9C, 0x70, 0x4C, 0xF1, 0x77, 0x40, + 0x19, 0xFF, 0x69, 0x2F, 0x09, 0xFF, 0x69, 0x2E, 0x07, 0xFF, 0x6D, 0x31, 0x07, 0xFF, 0x71, 0x34, + 0x08, 0xFF, 0x73, 0x38, 0x09, 0xFF, 0x73, 0x39, 0x09, 0xFF, 0x68, 0x34, 0x05, 0xFF, 0x70, 0x4A, + 0x24, 0xFF, 0xC3, 0xB7, 0xAA, 0xFF, 0xEB, 0xEB, 0xEA, 0xFF, 0xCD, 0xC9, 0xC1, 0xFF, 0x9D, 0x94, + 0x83, 0xFF, 0xD0, 0xCC, 0xC3, 0xFF, 0xDD, 0xD6, 0xCE, 0xFF, 0x8E, 0x74, 0x54, 0xFF, 0x68, 0x3C, + 0x0B, 0xFF, 0x74, 0x40, 0x0A, 0xFF, 0x80, 0x46, 0x0C, 0xFF, 0x87, 0x49, 0x0D, 0xFF, 0x8A, 0x4A, + 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, + 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, + 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, + 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4A, + 0x0D, 0xFF, 0x8A, 0x4A, 0x0D, 0xFF, 0x89, 0x49, 0x0D, 0xFF, 0x88, 0x48, 0x0C, 0xFF, 0x89, 0x4A, + 0x0F, 0xFF, 0x8E, 0x53, 0x1A, 0xFF, 0x94, 0x5D, 0x29, 0xFF, 0x96, 0x60, 0x2F, 0xFF, 0x94, 0x5F, + 0x30, 0xFF, 0x92, 0x5E, 0x30, 0xFF, 0x90, 0x5C, 0x30, 0xFF, 0x8E, 0x5C, 0x32, 0xFF, 0x94, 0x64, + 0x3E, 0xFF, 0xA7, 0x7F, 0x5C, 0xFF, 0xBE, 0x9F, 0x83, 0xA0, 0xD7, 0xC4, 0xB1, 0x0E, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xCC, 0xB0, 0x96, 0x23, 0xAA, 0x83, 0x61, 0xCB, 0x83, 0x4E, 0x26, 0xFF, 0x6D, 0x33, + 0x0C, 0xFF, 0x6A, 0x2F, 0x07, 0xFF, 0x6E, 0x32, 0x07, 0xFF, 0x73, 0x36, 0x08, 0xFF, 0x76, 0x39, + 0x09, 0xFF, 0x75, 0x3A, 0x09, 0xFF, 0x6B, 0x37, 0x06, 0xFF, 0x6F, 0x4A, 0x21, 0xFF, 0xC5, 0xBA, + 0xAD, 0xFF, 0xE9, 0xE9, 0xE9, 0xFF, 0xE1, 0xE1, 0xE1, 0xFF, 0xE7, 0xE7, 0xE7, 0xFF, 0xD7, 0xD4, + 0xD0, 0xFF, 0x95, 0x8B, 0x78, 0xFF, 0xB2, 0xAA, 0x9C, 0xFF, 0xE6, 0xE3, 0xDD, 0xFF, 0xAB, 0x98, + 0x81, 0xFF, 0x6D, 0x46, 0x17, 0xFF, 0x70, 0x3E, 0x08, 0xFF, 0x7E, 0x46, 0x0C, 0xFF, 0x86, 0x49, + 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8C, 0x4C, 0x0D, 0xFF, 0x8D, 0x4C, 0x0D, 0xFF, 0x8D, 0x4C, + 0x0D, 0xFF, 0x8D, 0x4C, 0x0D, 0xFF, 0x8D, 0x4C, 0x0D, 0xFF, 0x8D, 0x4C, 0x0D, 0xFF, 0x8D, 0x4C, + 0x0D, 0xFF, 0x8D, 0x4C, 0x0D, 0xFF, 0x8D, 0x4C, 0x0D, 0xFF, 0x8D, 0x4C, 0x0D, 0xFF, 0x8D, 0x4C, + 0x0D, 0xFF, 0x8D, 0x4C, 0x0D, 0xFF, 0x8D, 0x4C, 0x0D, 0xFF, 0x8D, 0x4C, 0x0D, 0xFF, 0x8D, 0x4C, + 0x0D, 0xFF, 0x8C, 0x4C, 0x0D, 0xFF, 0x8C, 0x4B, 0x0D, 0xFF, 0x8C, 0x4B, 0x0D, 0xFF, 0x8B, 0x4A, + 0x0D, 0xFF, 0x8A, 0x4A, 0x0C, 0xFF, 0x8C, 0x4D, 0x11, 0xFF, 0x92, 0x57, 0x1F, 0xFF, 0x96, 0x60, + 0x2D, 0xFF, 0x96, 0x60, 0x2F, 0xFF, 0x94, 0x5F, 0x30, 0xFF, 0x91, 0x5D, 0x30, 0xFF, 0x91, 0x5E, + 0x34, 0xFF, 0x9A, 0x6C, 0x45, 0xFF, 0xB1, 0x8B, 0x6A, 0xF4, 0xC7, 0xA8, 0x8E, 0x61, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEE, 0xE2, + 0xD4, 0x04, 0xB9, 0x96, 0x77, 0x86, 0x94, 0x63, 0x3C, 0xFE, 0x73, 0x3A, 0x12, 0xFF, 0x6C, 0x31, + 0x08, 0xFF, 0x6F, 0x32, 0x08, 0xFF, 0x74, 0x36, 0x08, 0xFF, 0x77, 0x3A, 0x09, 0xFF, 0x78, 0x3C, + 0x0A, 0xFF, 0x70, 0x39, 0x08, 0xFF, 0x6D, 0x45, 0x1A, 0xFF, 0xC0, 0xB4, 0xA5, 0xFF, 0xEB, 0xEA, + 0xEB, 0xFF, 0xE4, 0xE4, 0xE4, 0xFF, 0xE5, 0xE4, 0xE4, 0xFF, 0xE4, 0xE3, 0xE3, 0xFF, 0xE8, 0xE7, + 0xE8, 0xFF, 0xE2, 0xE0, 0xDD, 0xFF, 0x9A, 0x90, 0x7F, 0xFF, 0x92, 0x86, 0x72, 0xFF, 0xDE, 0xDB, + 0xD6, 0xFF, 0xC5, 0xBA, 0xAB, 0xFF, 0x7A, 0x59, 0x2F, 0xFF, 0x6C, 0x3D, 0x08, 0xFF, 0x7B, 0x45, + 0x0C, 0xFF, 0x86, 0x4A, 0x0D, 0xFF, 0x8C, 0x4C, 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, + 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, + 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, + 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, + 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8D, 0x4D, + 0x0E, 0xFF, 0x8D, 0x4C, 0x0E, 0xFF, 0x8C, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, 0x0E, 0xFF, 0x8F, 0x52, + 0x17, 0xFF, 0x96, 0x5D, 0x28, 0xFF, 0x97, 0x61, 0x30, 0xFF, 0x95, 0x60, 0x30, 0xFF, 0x92, 0x5E, + 0x30, 0xFF, 0x94, 0x62, 0x37, 0xFF, 0xA3, 0x77, 0x52, 0xFF, 0xBB, 0x99, 0x7A, 0xCC, 0xD1, 0xB7, + 0xA0, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC7, 0xA9, + 0x8D, 0x36, 0xA7, 0x7C, 0x58, 0xE1, 0x7F, 0x48, 0x1E, 0xFF, 0x6F, 0x34, 0x0A, 0xFF, 0x70, 0x33, + 0x07, 0xFF, 0x74, 0x36, 0x08, 0xFF, 0x79, 0x3B, 0x09, 0xFF, 0x7B, 0x3E, 0x0A, 0xFF, 0x74, 0x3C, + 0x08, 0xFF, 0x6B, 0x3F, 0x12, 0xFF, 0xB5, 0xA5, 0x93, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xE5, 0xE4, + 0xE4, 0xFF, 0xE7, 0xE6, 0xE6, 0xFF, 0xE7, 0xE7, 0xE7, 0xFF, 0xE7, 0xE7, 0xE7, 0xFF, 0xE7, 0xE7, + 0xE7, 0xFF, 0xE9, 0xE9, 0xE9, 0xFF, 0xE9, 0xE8, 0xE7, 0xFF, 0xA8, 0xA0, 0x91, 0xFF, 0x7C, 0x6D, + 0x56, 0xFF, 0xC9, 0xC3, 0xBA, 0xFF, 0xD9, 0xD3, 0xCC, 0xFF, 0x90, 0x76, 0x55, 0xFF, 0x6B, 0x40, + 0x0C, 0xFF, 0x77, 0x43, 0x0A, 0xFF, 0x85, 0x4A, 0x0D, 0xFF, 0x8C, 0x4D, 0x0E, 0xFF, 0x8F, 0x4F, + 0x0E, 0xFF, 0x8F, 0x4F, 0x0E, 0xFF, 0x8F, 0x4F, 0x0E, 0xFF, 0x8F, 0x4F, 0x0E, 0xFF, 0x8F, 0x4F, + 0x0E, 0xFF, 0x8F, 0x4F, 0x0E, 0xFF, 0x8F, 0x4F, 0x0E, 0xFF, 0x8F, 0x4F, 0x0E, 0xFF, 0x8F, 0x4F, + 0x0E, 0xFF, 0x8F, 0x4F, 0x0E, 0xFF, 0x8F, 0x4F, 0x0E, 0xFF, 0x8F, 0x4F, 0x0E, 0xFF, 0x8F, 0x4F, + 0x0E, 0xFF, 0x8F, 0x4F, 0x0E, 0xFF, 0x8F, 0x4F, 0x0E, 0xFF, 0x8F, 0x4F, 0x0E, 0xFF, 0x8F, 0x4F, + 0x0E, 0xFF, 0x8F, 0x4F, 0x0E, 0xFF, 0x8E, 0x4E, 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8D, 0x4C, + 0x0D, 0xFF, 0x8E, 0x4F, 0x12, 0xFF, 0x94, 0x5A, 0x22, 0xFF, 0x98, 0x61, 0x2E, 0xFF, 0x95, 0x60, + 0x2F, 0xFF, 0x94, 0x5F, 0x31, 0xFF, 0x9A, 0x69, 0x3F, 0xFF, 0xAF, 0x87, 0x63, 0xFD, 0xC5, 0xA8, + 0x8B, 0x7D, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF7, 0xEE, 0xE4, 0x06, 0xB9, 0x95, + 0x73, 0x94, 0x92, 0x60, 0x36, 0xFF, 0x76, 0x3B, 0x10, 0xFF, 0x71, 0x34, 0x08, 0xFF, 0x75, 0x37, + 0x08, 0xFF, 0x7A, 0x3B, 0x09, 0xFF, 0x7E, 0x3F, 0x0A, 0xFF, 0x7C, 0x40, 0x0A, 0xFF, 0x70, 0x3D, + 0x0B, 0xFF, 0xA7, 0x91, 0x77, 0xFF, 0xEA, 0xE9, 0xE8, 0xFF, 0xE5, 0xE4, 0xE4, 0xFF, 0xE6, 0xE5, + 0xE5, 0xFF, 0xE8, 0xE7, 0xE7, 0xFF, 0xE9, 0xE9, 0xE9, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xEA, 0xEA, + 0xEA, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xBA, 0xB3, + 0xAA, 0xFF, 0x72, 0x62, 0x48, 0xFF, 0xAB, 0xA2, 0x92, 0xFF, 0xDF, 0xDD, 0xD9, 0xFF, 0xA9, 0x97, + 0x80, 0xFF, 0x70, 0x4A, 0x19, 0xFF, 0x73, 0x41, 0x08, 0xFF, 0x82, 0x4A, 0x0D, 0xFF, 0x8B, 0x4E, + 0x0E, 0xFF, 0x90, 0x50, 0x0E, 0xFF, 0x91, 0x50, 0x0F, 0xFF, 0x92, 0x50, 0x0F, 0xFF, 0x92, 0x50, + 0x0F, 0xFF, 0x92, 0x50, 0x0F, 0xFF, 0x92, 0x50, 0x0F, 0xFF, 0x92, 0x50, 0x0F, 0xFF, 0x92, 0x50, + 0x0F, 0xFF, 0x92, 0x50, 0x0F, 0xFF, 0x92, 0x50, 0x0F, 0xFF, 0x92, 0x50, 0x0F, 0xFF, 0x92, 0x50, + 0x0F, 0xFF, 0x92, 0x50, 0x0F, 0xFF, 0x92, 0x50, 0x0F, 0xFF, 0x92, 0x50, 0x0F, 0xFF, 0x92, 0x50, + 0x0F, 0xFF, 0x92, 0x50, 0x0F, 0xFF, 0x91, 0x50, 0x0F, 0xFF, 0x91, 0x50, 0x0F, 0xFF, 0x90, 0x4F, + 0x0E, 0xFF, 0x8F, 0x4E, 0x0D, 0xFF, 0x8E, 0x4D, 0x0F, 0xFF, 0x93, 0x56, 0x1C, 0xFF, 0x98, 0x61, + 0x2C, 0xFF, 0x97, 0x61, 0x2F, 0xFF, 0x97, 0x62, 0x34, 0xFF, 0xA4, 0x76, 0x4D, 0xFF, 0xBC, 0x99, + 0x79, 0xD7, 0xD3, 0xB9, 0xA1, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD0, 0xB4, 0x9A, 0x30, 0xA9, 0x7F, + 0x58, 0xE0, 0x83, 0x4A, 0x1E, 0xFF, 0x74, 0x37, 0x0A, 0xFF, 0x75, 0x37, 0x08, 0xFF, 0x7A, 0x3B, + 0x09, 0xFF, 0x7E, 0x3F, 0x0A, 0xFF, 0x82, 0x43, 0x0B, 0xFF, 0x7C, 0x42, 0x09, 0xFF, 0x9F, 0x7E, + 0x5B, 0xFF, 0xE9, 0xE6, 0xE3, 0xFF, 0xE9, 0xE9, 0xE9, 0xFF, 0xE7, 0xE7, 0xE6, 0xFF, 0xE7, 0xE7, + 0xE6, 0xFF, 0xE8, 0xE8, 0xE7, 0xFF, 0xE9, 0xE9, 0xE9, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xED, 0xED, + 0xEC, 0xFF, 0xED, 0xED, 0xEC, 0xFF, 0xED, 0xED, 0xEC, 0xFF, 0xED, 0xED, 0xEC, 0xFF, 0xF0, 0xF0, + 0xF0, 0xFF, 0xCB, 0xC7, 0xBE, 0xFF, 0x75, 0x65, 0x49, 0xFF, 0x8E, 0x80, 0x6A, 0xFF, 0xD9, 0xD7, + 0xD3, 0xFF, 0xC0, 0xB6, 0xA8, 0xFF, 0x7C, 0x5C, 0x31, 0xFF, 0x6F, 0x41, 0x09, 0xFF, 0x7E, 0x49, + 0x0D, 0xFF, 0x8A, 0x4E, 0x0E, 0xFF, 0x90, 0x51, 0x0F, 0xFF, 0x92, 0x52, 0x0F, 0xFF, 0x93, 0x52, + 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x52, + 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x52, + 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x52, + 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x92, 0x51, + 0x0F, 0xFF, 0x91, 0x50, 0x0F, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x92, 0x54, + 0x18, 0xFF, 0x97, 0x60, 0x2A, 0xFF, 0x98, 0x62, 0x30, 0xFF, 0x9D, 0x6A, 0x3D, 0xFF, 0xB2, 0x8A, + 0x64, 0xFE, 0xCA, 0xAB, 0x8E, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x9F, 0x80, 0x7C, 0x99, 0x67, + 0x3C, 0xFE, 0x7C, 0x3F, 0x12, 0xFF, 0x76, 0x38, 0x09, 0xFF, 0x7A, 0x3B, 0x09, 0xFF, 0x7E, 0x3F, + 0x0A, 0xFF, 0x83, 0x44, 0x0B, 0xFF, 0x86, 0x47, 0x0C, 0xFF, 0x82, 0x46, 0x0B, 0xFF, 0xBA, 0x9F, + 0x81, 0xFF, 0xF1, 0xF1, 0xF1, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xEB, 0xEA, 0xEA, 0xFF, 0xEA, 0xEA, + 0xEA, 0xFF, 0xE9, 0xE9, 0xE9, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xED, 0xED, + 0xED, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEE, 0xEE, + 0xEE, 0xFF, 0xF1, 0xF1, 0xF1, 0xFF, 0xD7, 0xD5, 0xD1, 0xFF, 0x82, 0x74, 0x5C, 0xFF, 0x77, 0x66, + 0x49, 0xFF, 0xCB, 0xC5, 0xBD, 0xFF, 0xD4, 0xCF, 0xC9, 0xFF, 0x90, 0x78, 0x55, 0xFF, 0x6F, 0x45, + 0x0F, 0xFF, 0x7B, 0x48, 0x0C, 0xFF, 0x89, 0x4F, 0x0F, 0xFF, 0x91, 0x53, 0x10, 0xFF, 0x94, 0x54, + 0x10, 0xFF, 0x95, 0x54, 0x10, 0xFF, 0x95, 0x54, 0x10, 0xFF, 0x95, 0x54, 0x10, 0xFF, 0x95, 0x54, + 0x10, 0xFF, 0x95, 0x54, 0x10, 0xFF, 0x95, 0x54, 0x0F, 0xFF, 0x95, 0x53, 0x0F, 0xFF, 0x94, 0x53, + 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x53, + 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x53, + 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x92, 0x51, 0x0E, 0xFF, 0x8F, 0x4F, + 0x0E, 0xFF, 0x91, 0x53, 0x15, 0xFF, 0x98, 0x5F, 0x28, 0xFF, 0x9B, 0x65, 0x33, 0xFF, 0xA9, 0x7B, + 0x50, 0xFF, 0xC2, 0xA0, 0x7E, 0xC6, 0xDA, 0xC3, 0xAC, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE7, 0xD8, 0xC9, 0x16, 0xB4, 0x8C, 0x67, 0xC4, 0x8C, 0x55, + 0x26, 0xFF, 0x7A, 0x3B, 0x0C, 0xFF, 0x7A, 0x3B, 0x09, 0xFF, 0x7F, 0x3F, 0x0A, 0xFF, 0x83, 0x43, + 0x0B, 0xFF, 0x88, 0x47, 0x0C, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8A, 0x4B, 0x0C, 0xFF, 0x8C, 0x58, + 0x20, 0xFF, 0xD3, 0xC3, 0xB0, 0xFF, 0xF1, 0xF1, 0xF2, 0xFF, 0xED, 0xEC, 0xEC, 0xFF, 0xED, 0xED, + 0xEC, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xEC, 0xEC, 0xEB, 0xFF, 0xED, 0xED, + 0xED, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xF0, 0xF0, 0xEF, 0xFF, 0xF0, 0xF0, 0xF0, 0xFF, 0xF0, 0xF0, + 0xEF, 0xFF, 0xF0, 0xF0, 0xEF, 0xFF, 0xF1, 0xF2, 0xF2, 0xFF, 0xE2, 0xE2, 0xDF, 0xFF, 0x94, 0x88, + 0x73, 0xFF, 0x6B, 0x58, 0x35, 0xFF, 0xB7, 0xAE, 0xA0, 0xFF, 0xE0, 0xDE, 0xDC, 0xFF, 0xA9, 0x99, + 0x82, 0xFF, 0x74, 0x4F, 0x1E, 0xFF, 0x77, 0x47, 0x0C, 0xFF, 0x87, 0x50, 0x11, 0xFF, 0x91, 0x55, + 0x12, 0xFF, 0x96, 0x57, 0x13, 0xFF, 0x97, 0x57, 0x13, 0xFF, 0x98, 0x57, 0x13, 0xFF, 0x97, 0x57, + 0x13, 0xFF, 0x97, 0x57, 0x13, 0xFF, 0x97, 0x57, 0x13, 0xFF, 0x97, 0x57, 0x12, 0xFF, 0x97, 0x56, + 0x12, 0xFF, 0x97, 0x56, 0x11, 0xFF, 0x97, 0x55, 0x10, 0xFF, 0x96, 0x55, 0x10, 0xFF, 0x96, 0x55, + 0x10, 0xFF, 0x96, 0x55, 0x10, 0xFF, 0x96, 0x55, 0x10, 0xFF, 0x96, 0x55, 0x10, 0xFF, 0x96, 0x55, + 0x10, 0xFF, 0x96, 0x55, 0x10, 0xFF, 0x95, 0x54, 0x10, 0xFF, 0x95, 0x53, 0x0F, 0xFF, 0x93, 0x52, + 0x0F, 0xFF, 0x91, 0x50, 0x0E, 0xFF, 0x92, 0x53, 0x15, 0xFF, 0x98, 0x60, 0x29, 0xFF, 0xA3, 0x70, + 0x41, 0xFF, 0xBA, 0x94, 0x6E, 0xF2, 0xD1, 0xB4, 0x98, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCF, 0xB2, 0x95, 0x45, 0xA8, 0x7A, 0x50, 0xF0, 0x84, 0x48, + 0x18, 0xFF, 0x7B, 0x3C, 0x0A, 0xFF, 0x7E, 0x3E, 0x0A, 0xFF, 0x84, 0x43, 0x0B, 0xFF, 0x88, 0x47, + 0x0C, 0xFF, 0x8C, 0x4B, 0x0D, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x8C, 0x4E, + 0x0B, 0xFF, 0x98, 0x6A, 0x36, 0xFF, 0xE2, 0xDA, 0xCF, 0xFF, 0xF0, 0xF1, 0xF2, 0xFF, 0xED, 0xED, + 0xED, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xED, 0xED, + 0xED, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEF, 0xEF, 0xEF, 0xFF, 0xF1, 0xF1, 0xF1, 0xFF, 0xF1, 0xF1, + 0xF1, 0xFF, 0xF1, 0xF1, 0xF1, 0xFF, 0xF2, 0xF1, 0xF1, 0xFF, 0xF3, 0xF3, 0xF3, 0xFF, 0xEC, 0xEC, + 0xEB, 0xFF, 0xA8, 0xA0, 0x90, 0xFF, 0x68, 0x54, 0x32, 0xFF, 0xA0, 0x93, 0x7D, 0xFF, 0xE2, 0xE1, + 0xDF, 0xFF, 0xC3, 0xBB, 0xAD, 0xFF, 0x81, 0x63, 0x38, 0xFF, 0x74, 0x47, 0x0E, 0xFF, 0x85, 0x50, + 0x12, 0xFF, 0x91, 0x56, 0x13, 0xFF, 0x98, 0x59, 0x13, 0xFF, 0x9A, 0x5A, 0x13, 0xFF, 0x9A, 0x5A, + 0x13, 0xFF, 0x9A, 0x5A, 0x13, 0xFF, 0x9A, 0x5A, 0x13, 0xFF, 0x9A, 0x5A, 0x13, 0xFF, 0x9A, 0x5A, + 0x13, 0xFF, 0x9A, 0x5A, 0x13, 0xFF, 0x9A, 0x5A, 0x13, 0xFF, 0x9A, 0x59, 0x13, 0xFF, 0x99, 0x58, + 0x11, 0xFF, 0x98, 0x57, 0x10, 0xFF, 0x98, 0x57, 0x10, 0xFF, 0x98, 0x57, 0x10, 0xFF, 0x98, 0x57, + 0x10, 0xFF, 0x98, 0x57, 0x10, 0xFF, 0x98, 0x57, 0x10, 0xFF, 0x97, 0x56, 0x10, 0xFF, 0x96, 0x55, + 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x92, 0x50, 0x0E, 0xFF, 0x92, 0x53, 0x14, 0xFF, 0x9E, 0x66, + 0x31, 0xFF, 0xB3, 0x88, 0x5D, 0xFF, 0xCB, 0xAB, 0x8B, 0x91, 0xF9, 0xEF, 0xE2, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC4, 0xA3, 0x82, 0x80, 0x9C, 0x68, 0x3B, 0xFF, 0x81, 0x43, + 0x11, 0xFF, 0x7E, 0x3E, 0x0A, 0xFF, 0x83, 0x42, 0x0B, 0xFF, 0x87, 0x47, 0x0C, 0xFF, 0x8C, 0x4B, + 0x0D, 0xFF, 0x90, 0x4E, 0x0E, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x96, 0x55, 0x10, 0xFF, 0x96, 0x55, + 0x10, 0xFF, 0x8D, 0x50, 0x0C, 0xFF, 0xA8, 0x83, 0x56, 0xFF, 0xEC, 0xE8, 0xE3, 0xFF, 0xEF, 0xEF, + 0xF0, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEE, 0xEE, + 0xEE, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xED, 0xED, 0xED, 0xFF, 0xEF, 0xEF, 0xEF, 0xFF, 0xF1, 0xF1, + 0xF1, 0xFF, 0xF2, 0xF2, 0xF2, 0xFF, 0xF2, 0xF2, 0xF2, 0xFF, 0xF2, 0xF2, 0xF2, 0xFF, 0xF3, 0xF3, + 0xF3, 0xFF, 0xF1, 0xF1, 0xF2, 0xFF, 0xBD, 0xB7, 0xAC, 0xFF, 0x6F, 0x5C, 0x38, 0xFF, 0x8A, 0x79, + 0x5C, 0xFF, 0xDB, 0xD8, 0xD3, 0xFF, 0xD9, 0xD5, 0xCF, 0xFF, 0x94, 0x7E, 0x5C, 0xFF, 0x74, 0x4C, + 0x15, 0xFF, 0x81, 0x50, 0x13, 0xFF, 0x90, 0x58, 0x15, 0xFF, 0x99, 0x5B, 0x16, 0xFF, 0x9C, 0x5D, + 0x16, 0xFF, 0x9D, 0x5D, 0x16, 0xFF, 0x9D, 0x5D, 0x16, 0xFF, 0x9D, 0x5D, 0x16, 0xFF, 0x9D, 0x5D, + 0x16, 0xFF, 0x9D, 0x5D, 0x16, 0xFF, 0x9D, 0x5D, 0x16, 0xFF, 0x9D, 0x5D, 0x16, 0xFF, 0x9D, 0x5D, + 0x16, 0xFF, 0x9C, 0x5C, 0x15, 0xFF, 0x9B, 0x5A, 0x13, 0xFF, 0x9A, 0x59, 0x11, 0xFF, 0x9A, 0x58, + 0x11, 0xFF, 0x9A, 0x58, 0x11, 0xFF, 0x9A, 0x58, 0x11, 0xFF, 0x99, 0x58, 0x11, 0xFF, 0x98, 0x57, + 0x10, 0xFF, 0x97, 0x56, 0x10, 0xFF, 0x95, 0x54, 0x10, 0xFF, 0x92, 0x51, 0x0E, 0xFF, 0x95, 0x58, + 0x1B, 0xFF, 0xAB, 0x7A, 0x4B, 0xFF, 0xC5, 0xA3, 0x80, 0xCB, 0xBA, 0xA6, 0x90, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xF0, 0xE5, 0xD6, 0x0B, 0xBA, 0x93, 0x6C, 0xB8, 0x94, 0x5C, 0x2B, 0xFF, 0x81, 0x41, + 0x0D, 0xFF, 0x82, 0x41, 0x0A, 0xFF, 0x87, 0x46, 0x0C, 0xFF, 0x8B, 0x4A, 0x0D, 0xFF, 0x90, 0x4E, + 0x0E, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x96, 0x55, 0x10, 0xFF, 0x99, 0x57, 0x10, 0xFF, 0x9A, 0x5A, + 0x13, 0xFF, 0x9A, 0x5C, 0x15, 0xFF, 0x92, 0x5A, 0x16, 0xFF, 0xBC, 0xA1, 0x7F, 0xFF, 0xEE, 0xEE, + 0xED, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xED, 0xED, + 0xED, 0xFF, 0xED, 0xED, 0xED, 0xFF, 0xED, 0xED, 0xED, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xED, 0xED, + 0xED, 0xFF, 0xEF, 0xEF, 0xEF, 0xFF, 0xF0, 0xF0, 0xF0, 0xFF, 0xF1, 0xF1, 0xF1, 0xFF, 0xF1, 0xF1, + 0xF1, 0xFF, 0xF1, 0xF1, 0xF1, 0xFF, 0xF2, 0xF2, 0xF3, 0xFF, 0xD0, 0xCC, 0xC4, 0xFF, 0x7D, 0x6D, + 0x4C, 0xFF, 0x7A, 0x67, 0x43, 0xFF, 0xCE, 0xC8, 0xBE, 0xFF, 0xE5, 0xE4, 0xE3, 0xFF, 0xAB, 0x9D, + 0x85, 0xFF, 0x7A, 0x57, 0x24, 0xFF, 0x7E, 0x50, 0x13, 0xFF, 0x8F, 0x59, 0x17, 0xFF, 0x99, 0x5E, + 0x18, 0xFF, 0x9E, 0x60, 0x19, 0xFF, 0x9F, 0x60, 0x19, 0xFF, 0x9F, 0x60, 0x19, 0xFF, 0x9F, 0x60, + 0x19, 0xFF, 0x9F, 0x60, 0x19, 0xFF, 0x9F, 0x60, 0x19, 0xFF, 0x9F, 0x60, 0x19, 0xFF, 0x9F, 0x60, + 0x19, 0xFF, 0x9F, 0x60, 0x19, 0xFF, 0x9F, 0x60, 0x19, 0xFF, 0x9F, 0x5F, 0x17, 0xFF, 0x9D, 0x5D, + 0x14, 0xFF, 0x9C, 0x5B, 0x12, 0xFF, 0x9B, 0x5A, 0x11, 0xFF, 0x9B, 0x5A, 0x11, 0xFF, 0x9B, 0x5A, + 0x11, 0xFF, 0x9A, 0x58, 0x11, 0xFF, 0x98, 0x57, 0x10, 0xFF, 0x96, 0x54, 0x0F, 0xFF, 0x93, 0x52, + 0x10, 0xFF, 0xA1, 0x6A, 0x31, 0xFF, 0xBF, 0x99, 0x71, 0xEC, 0xAF, 0x9A, 0x82, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xE1, 0xCD, 0xB7, 0x27, 0xB4, 0x88, 0x5D, 0xDB, 0x8F, 0x54, 0x20, 0xFF, 0x82, 0x42, + 0x0C, 0xFF, 0x86, 0x45, 0x0B, 0xFF, 0x8B, 0x49, 0x0C, 0xFF, 0x90, 0x4E, 0x0E, 0xFF, 0x93, 0x52, + 0x0E, 0xFF, 0x97, 0x55, 0x0F, 0xFF, 0x9A, 0x59, 0x11, 0xFF, 0x9E, 0x5D, 0x15, 0xFF, 0xA1, 0x62, + 0x1A, 0xFF, 0xA1, 0x63, 0x1C, 0xFF, 0x9D, 0x60, 0x1A, 0xFF, 0x97, 0x62, 0x22, 0xFF, 0xCB, 0xB8, + 0xA1, 0xFF, 0xEC, 0xED, 0xEE, 0xFF, 0xE9, 0xE9, 0xE9, 0xFF, 0xE9, 0xE9, 0xE9, 0xFF, 0xE9, 0xE9, + 0xE9, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xEA, 0xEA, + 0xEA, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEE, 0xEE, + 0xEE, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEF, 0xEF, 0xEF, 0xFF, 0xF0, 0xF0, 0xF1, 0xFF, 0xDD, 0xDB, + 0xD7, 0xFF, 0x90, 0x82, 0x66, 0xFF, 0x71, 0x5D, 0x35, 0xFF, 0xBD, 0xB4, 0xA4, 0xFF, 0xEA, 0xEA, + 0xEA, 0xFF, 0xC3, 0xBA, 0xAC, 0xFF, 0x85, 0x68, 0x3C, 0xFF, 0x7B, 0x50, 0x15, 0xFF, 0x8D, 0x59, + 0x19, 0xFF, 0x99, 0x5F, 0x1B, 0xFF, 0x9F, 0x62, 0x1C, 0xFF, 0xA1, 0x63, 0x1C, 0xFF, 0xA2, 0x63, + 0x1C, 0xFF, 0xA2, 0x63, 0x1C, 0xFF, 0xA2, 0x63, 0x1C, 0xFF, 0xA2, 0x63, 0x1C, 0xFF, 0xA2, 0x63, + 0x1C, 0xFF, 0xA2, 0x63, 0x1C, 0xFF, 0xA2, 0x63, 0x1C, 0xFF, 0xA2, 0x63, 0x1C, 0xFF, 0xA2, 0x63, + 0x1B, 0xFF, 0xA1, 0x62, 0x19, 0xFF, 0x9F, 0x5E, 0x14, 0xFF, 0x9D, 0x5C, 0x12, 0xFF, 0x9D, 0x5B, + 0x11, 0xFF, 0x9C, 0x5A, 0x11, 0xFF, 0x9B, 0x59, 0x11, 0xFF, 0x99, 0x57, 0x10, 0xFF, 0x96, 0x54, + 0x10, 0xFF, 0x9B, 0x5E, 0x1F, 0xFF, 0xB7, 0x8B, 0x5D, 0xFB, 0xD0, 0xB3, 0x94, 0x6B, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xD3, 0xB5, 0x97, 0x45, 0xAE, 0x7F, 0x51, 0xEF, 0x8D, 0x4F, 0x19, 0xFF, 0x85, 0x43, + 0x0B, 0xFF, 0x8A, 0x47, 0x0C, 0xFF, 0x8F, 0x4D, 0x0D, 0xFF, 0x93, 0x51, 0x0E, 0xFF, 0x97, 0x55, + 0x0F, 0xFF, 0x9C, 0x5B, 0x13, 0xFF, 0xA1, 0x61, 0x1A, 0xFF, 0xA4, 0x65, 0x1E, 0xFF, 0xA4, 0x66, + 0x1E, 0xFF, 0xA5, 0x66, 0x1E, 0xFF, 0xA4, 0x66, 0x1E, 0xFF, 0x9E, 0x62, 0x1B, 0xFF, 0x9D, 0x6F, + 0x34, 0xFF, 0xD5, 0xCA, 0xBA, 0xFF, 0xE8, 0xE9, 0xEA, 0xFF, 0xE5, 0xE5, 0xE5, 0xFF, 0xE5, 0xE5, + 0xE5, 0xFF, 0xE5, 0xE5, 0xE5, 0xFF, 0xE6, 0xE6, 0xE6, 0xFF, 0xE6, 0xE6, 0xE6, 0xFF, 0xE7, 0xE7, + 0xE7, 0xFF, 0xE7, 0xE7, 0xE7, 0xFF, 0xE6, 0xE6, 0xE6, 0xFF, 0xE7, 0xE7, 0xE7, 0xFF, 0xEA, 0xEA, + 0xEA, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xED, 0xED, + 0xEE, 0xFF, 0xE6, 0xE5, 0xE4, 0xFF, 0xA5, 0x9A, 0x85, 0xFF, 0x6F, 0x5A, 0x30, 0xFF, 0xA9, 0x9D, + 0x86, 0xFF, 0xE7, 0xE6, 0xE6, 0xFF, 0xD6, 0xD2, 0xCC, 0xFF, 0x96, 0x80, 0x5E, 0xFF, 0x7A, 0x54, + 0x1C, 0xFF, 0x89, 0x59, 0x1A, 0xFF, 0x99, 0x61, 0x1D, 0xFF, 0xA1, 0x65, 0x1E, 0xFF, 0xA4, 0x66, + 0x1E, 0xFF, 0xA5, 0x66, 0x1E, 0xFF, 0xA5, 0x66, 0x1E, 0xFF, 0xA5, 0x66, 0x1E, 0xFF, 0xA5, 0x66, + 0x1E, 0xFF, 0xA5, 0x66, 0x1E, 0xFF, 0xA5, 0x66, 0x1E, 0xFF, 0xA5, 0x66, 0x1E, 0xFF, 0xA5, 0x66, + 0x1E, 0xFF, 0xA5, 0x66, 0x1E, 0xFF, 0xA5, 0x66, 0x1E, 0xFF, 0xA3, 0x63, 0x1A, 0xFF, 0xA0, 0x5F, + 0x13, 0xFF, 0x9E, 0x5C, 0x12, 0xFF, 0x9D, 0x5B, 0x11, 0xFF, 0x9C, 0x5A, 0x11, 0xFF, 0x99, 0x57, + 0x10, 0xFF, 0x9A, 0x5B, 0x18, 0xFF, 0xB0, 0x7E, 0x49, 0xFF, 0xCF, 0xAE, 0x8C, 0x94, 0xFF, 0xFF, + 0xFF, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xCC, 0xAA, 0x88, 0x64, 0xA9, 0x77, 0x47, 0xFC, 0x8D, 0x4D, 0x15, 0xFF, 0x89, 0x46, + 0x0B, 0xFF, 0x8E, 0x4B, 0x0D, 0xFF, 0x92, 0x50, 0x0E, 0xFF, 0x97, 0x55, 0x10, 0xFF, 0x9E, 0x5E, + 0x17, 0xFF, 0xA3, 0x65, 0x1F, 0xFF, 0xA6, 0x68, 0x21, 0xFF, 0xA7, 0x69, 0x21, 0xFF, 0xA8, 0x6A, + 0x21, 0xFF, 0xA8, 0x6A, 0x21, 0xFF, 0xA8, 0x6A, 0x21, 0xFF, 0xA7, 0x6A, 0x21, 0xFF, 0x9E, 0x64, + 0x1D, 0xFF, 0xA6, 0x7F, 0x4B, 0xFF, 0xDA, 0xD4, 0xCC, 0xFF, 0xE3, 0xE4, 0xE5, 0xFF, 0xE2, 0xE2, + 0xE2, 0xFF, 0xE2, 0xE2, 0xE2, 0xFF, 0xE1, 0xE1, 0xE1, 0xFF, 0xE1, 0xE1, 0xE1, 0xFF, 0xE1, 0xE2, + 0xE2, 0xFF, 0xE2, 0xE2, 0xE2, 0xFF, 0xE3, 0xE3, 0xE3, 0xFF, 0xE2, 0xE2, 0xE2, 0xFF, 0xE2, 0xE2, + 0xE2, 0xFF, 0xE4, 0xE4, 0xE4, 0xFF, 0xE7, 0xE8, 0xE8, 0xFF, 0xE9, 0xE9, 0xE9, 0xFF, 0xE9, 0xE9, + 0xE9, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xB8, 0xB1, 0xA1, 0xFF, 0x74, 0x60, + 0x37, 0xFF, 0x97, 0x86, 0x68, 0xFF, 0xDE, 0xDC, 0xD8, 0xFF, 0xE2, 0xE1, 0xE0, 0xFF, 0xAB, 0x9D, + 0x84, 0xFF, 0x7F, 0x5E, 0x2B, 0xFF, 0x86, 0x59, 0x1B, 0xFF, 0x98, 0x63, 0x20, 0xFF, 0xA2, 0x67, + 0x21, 0xFF, 0xA6, 0x69, 0x21, 0xFF, 0xA8, 0x6A, 0x21, 0xFF, 0xA8, 0x6A, 0x21, 0xFF, 0xA8, 0x6A, + 0x21, 0xFF, 0xA8, 0x6A, 0x21, 0xFF, 0xA8, 0x6A, 0x21, 0xFF, 0xA8, 0x6A, 0x21, 0xFF, 0xA8, 0x6A, + 0x21, 0xFF, 0xA8, 0x6A, 0x21, 0xFF, 0xA8, 0x6A, 0x21, 0xFF, 0xA8, 0x6A, 0x21, 0xFF, 0xA7, 0x69, + 0x1E, 0xFF, 0xA3, 0x62, 0x16, 0xFF, 0xA0, 0x5E, 0x12, 0xFF, 0x9E, 0x5C, 0x11, 0xFF, 0x9C, 0x5A, + 0x10, 0xFF, 0x9C, 0x5C, 0x15, 0xFF, 0xAD, 0x77, 0x3E, 0xFF, 0xCC, 0xAA, 0x85, 0xB4, 0xF3, 0xEC, + 0xE1, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0x01, 0xCA, 0xA5, 0x81, 0x80, 0xA7, 0x71, 0x3D, 0xFF, 0x8E, 0x4D, 0x13, 0xFF, 0x8C, 0x49, + 0x0C, 0xFF, 0x92, 0x4F, 0x0D, 0xFF, 0x97, 0x55, 0x11, 0xFF, 0x9F, 0x60, 0x1B, 0xFF, 0xA5, 0x68, + 0x23, 0xFF, 0xA8, 0x6A, 0x24, 0xFF, 0xA9, 0x6C, 0x24, 0xFF, 0xAA, 0x6D, 0x25, 0xFF, 0xAB, 0x6E, + 0x25, 0xFF, 0xAB, 0x6E, 0x25, 0xFF, 0xAB, 0x6E, 0x25, 0xFF, 0xAB, 0x6E, 0x25, 0xFF, 0xA9, 0x6D, + 0x24, 0xFF, 0x9F, 0x67, 0x21, 0xFF, 0xB0, 0x90, 0x66, 0xFF, 0xDC, 0xDA, 0xD7, 0xFF, 0xDF, 0xDF, + 0xE0, 0xFF, 0xDE, 0xDE, 0xDE, 0xFF, 0xDE, 0xDE, 0xDE, 0xFF, 0xDE, 0xDE, 0xDE, 0xFF, 0xDD, 0xDE, + 0xDE, 0xFF, 0xDD, 0xDD, 0xDD, 0xFF, 0xDD, 0xDD, 0xDD, 0xFF, 0xDE, 0xDE, 0xDE, 0xFF, 0xE0, 0xE0, + 0xE1, 0xFF, 0xE2, 0xE2, 0xE3, 0xFF, 0xE2, 0xE3, 0xE3, 0xFF, 0xE3, 0xE3, 0xE3, 0xFF, 0xE5, 0xE5, + 0xE5, 0xFF, 0xE5, 0xE6, 0xE5, 0xFF, 0xE6, 0xE6, 0xE6, 0xFF, 0xE9, 0xE9, 0xEA, 0xFF, 0xCA, 0xC4, + 0xBA, 0xFF, 0x7F, 0x6D, 0x47, 0xFF, 0x88, 0x75, 0x51, 0xFF, 0xD2, 0xCD, 0xC4, 0xFF, 0xE6, 0xE7, + 0xE7, 0xFF, 0xC0, 0xB7, 0xA8, 0xFF, 0x89, 0x6E, 0x42, 0xFF, 0x83, 0x5A, 0x1E, 0xFF, 0x96, 0x64, + 0x22, 0xFF, 0xA2, 0x6A, 0x24, 0xFF, 0xA9, 0x6D, 0x24, 0xFF, 0xAB, 0x6E, 0x25, 0xFF, 0xAB, 0x6E, + 0x25, 0xFF, 0xAB, 0x6E, 0x25, 0xFF, 0xAB, 0x6E, 0x25, 0xFF, 0xAB, 0x6E, 0x25, 0xFF, 0xAB, 0x6E, + 0x25, 0xFF, 0xAB, 0x6E, 0x25, 0xFF, 0xAB, 0x6E, 0x25, 0xFF, 0xAB, 0x6E, 0x25, 0xFF, 0xAB, 0x6E, + 0x25, 0xFF, 0xAA, 0x6D, 0x23, 0xFF, 0xA6, 0x66, 0x1B, 0xFF, 0xA2, 0x5F, 0x13, 0xFF, 0x9F, 0x5C, + 0x11, 0xFF, 0x9F, 0x5D, 0x14, 0xFF, 0xAC, 0x74, 0x36, 0xFF, 0xCA, 0xA4, 0x7B, 0xCB, 0xE3, 0xCF, + 0xB6, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0x05, 0xCB, 0xA7, 0x81, 0x95, 0xA5, 0x6D, 0x37, 0xFF, 0x90, 0x4E, 0x12, 0xFF, 0x90, 0x4C, + 0x0C, 0xFF, 0x96, 0x54, 0x11, 0xFF, 0xA0, 0x62, 0x1F, 0xFF, 0xA6, 0x69, 0x25, 0xFF, 0xA9, 0x6C, + 0x26, 0xFF, 0xAB, 0x6E, 0x27, 0xFF, 0xAD, 0x70, 0x27, 0xFF, 0xAE, 0x71, 0x27, 0xFF, 0xAE, 0x71, + 0x27, 0xFF, 0xAE, 0x71, 0x27, 0xFF, 0xAE, 0x71, 0x27, 0xFF, 0xAE, 0x71, 0x27, 0xFF, 0xAD, 0x71, + 0x27, 0xFF, 0xAA, 0x6F, 0x26, 0xFF, 0xA0, 0x6C, 0x28, 0xFF, 0xBA, 0xA2, 0x81, 0xFF, 0xDB, 0xDB, + 0xDB, 0xFF, 0xDB, 0xDB, 0xDB, 0xFF, 0xDB, 0xDB, 0xDB, 0xFF, 0xDB, 0xDB, 0xDB, 0xFF, 0xDA, 0xDA, + 0xDA, 0xFF, 0xDB, 0xDB, 0xDB, 0xFF, 0xDB, 0xDB, 0xDB, 0xFF, 0xDC, 0xDC, 0xDD, 0xFF, 0xD2, 0xCD, + 0xC4, 0xFF, 0xB2, 0xA3, 0x89, 0xFF, 0xCB, 0xC0, 0xAF, 0xFF, 0xE2, 0xE1, 0xE1, 0xFF, 0xDF, 0xDF, + 0xDF, 0xFF, 0xE3, 0xE3, 0xE3, 0xFF, 0xE4, 0xE4, 0xE4, 0xFF, 0xE4, 0xE4, 0xE4, 0xFF, 0xE7, 0xE7, + 0xE7, 0xFF, 0xD5, 0xD3, 0xCD, 0xFF, 0x8E, 0x7F, 0x5E, 0xFF, 0x81, 0x6D, 0x45, 0xFF, 0xC4, 0xBD, + 0xB0, 0xFF, 0xE5, 0xE5, 0xE6, 0xFF, 0xD0, 0xCB, 0xC3, 0xFF, 0x98, 0x83, 0x5F, 0xFF, 0x82, 0x5D, + 0x23, 0xFF, 0x93, 0x64, 0x23, 0xFF, 0xA2, 0x6C, 0x27, 0xFF, 0xAA, 0x6F, 0x27, 0xFF, 0xAD, 0x71, + 0x27, 0xFF, 0xAE, 0x71, 0x27, 0xFF, 0xAE, 0x71, 0x27, 0xFF, 0xAE, 0x71, 0x27, 0xFF, 0xAE, 0x71, + 0x27, 0xFF, 0xAE, 0x71, 0x27, 0xFF, 0xAE, 0x71, 0x27, 0xFF, 0xAE, 0x71, 0x27, 0xFF, 0xAE, 0x71, + 0x27, 0xFF, 0xAE, 0x71, 0x28, 0xFF, 0xAD, 0x70, 0x27, 0xFF, 0xA8, 0x69, 0x1E, 0xFF, 0xA2, 0x60, + 0x13, 0xFF, 0xA0, 0x5E, 0x13, 0xFF, 0xAB, 0x72, 0x31, 0xFF, 0xC9, 0xA1, 0x76, 0xDB, 0xE2, 0xCE, + 0xB5, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0x08, 0xCB, 0xA6, 0x80, 0xA3, 0xA5, 0x6B, 0x33, 0xFF, 0x92, 0x4F, 0x11, 0xFF, 0x95, 0x52, + 0x12, 0xFF, 0xA1, 0x62, 0x21, 0xFF, 0xA7, 0x6A, 0x28, 0xFF, 0xAA, 0x6D, 0x29, 0xFF, 0xAC, 0x70, + 0x2A, 0xFF, 0xAE, 0x72, 0x2A, 0xFF, 0xB0, 0x74, 0x2B, 0xFF, 0xB0, 0x74, 0x2B, 0xFF, 0xB0, 0x74, + 0x2B, 0xFF, 0xB0, 0x74, 0x2B, 0xFF, 0xB0, 0x74, 0x2B, 0xFF, 0xB0, 0x74, 0x2B, 0xFF, 0xB0, 0x74, + 0x2B, 0xFF, 0xB0, 0x74, 0x2B, 0xFF, 0xAB, 0x71, 0x29, 0xFF, 0xA3, 0x71, 0x31, 0xFF, 0xC1, 0xB0, + 0x98, 0xFF, 0xD8, 0xD8, 0xD9, 0xFF, 0xD6, 0xD6, 0xD6, 0xFF, 0xD7, 0xD7, 0xD7, 0xFF, 0xD8, 0xD8, + 0xD8, 0xFF, 0xDA, 0xDA, 0xDA, 0xFF, 0xDA, 0xDB, 0xDB, 0xFF, 0xDE, 0xDE, 0xDE, 0xFF, 0xA3, 0x96, + 0x7B, 0xFF, 0x7F, 0x62, 0x30, 0xFF, 0x99, 0x7F, 0x53, 0xFF, 0xDF, 0xDB, 0xD5, 0xFF, 0xDC, 0xDD, + 0xDE, 0xFF, 0xDD, 0xDD, 0xDE, 0xFF, 0xE0, 0xE1, 0xE1, 0xFF, 0xE2, 0xE2, 0xE2, 0xFF, 0xE1, 0xE1, + 0xE1, 0xFF, 0xE4, 0xE5, 0xE5, 0xFF, 0xDD, 0xDC, 0xD9, 0xFF, 0xA2, 0x97, 0x7E, 0xFF, 0x82, 0x70, + 0x48, 0xFF, 0xB9, 0xB0, 0x9E, 0xFF, 0xE1, 0xE1, 0xE1, 0xFF, 0xDA, 0xD8, 0xD6, 0xFF, 0xAA, 0x9C, + 0x81, 0xFF, 0x85, 0x64, 0x2F, 0xFF, 0x90, 0x64, 0x25, 0xFF, 0xA2, 0x6E, 0x2A, 0xFF, 0xAB, 0x72, + 0x2A, 0xFF, 0xAF, 0x74, 0x2B, 0xFF, 0xB0, 0x74, 0x2B, 0xFF, 0xB0, 0x74, 0x2B, 0xFF, 0xB0, 0x74, + 0x2B, 0xFF, 0xB0, 0x74, 0x2B, 0xFF, 0xB0, 0x74, 0x2B, 0xFF, 0xB0, 0x74, 0x2B, 0xFF, 0xB0, 0x74, + 0x2B, 0xFF, 0xB0, 0x74, 0x2B, 0xFF, 0xB0, 0x74, 0x2B, 0xFF, 0xAF, 0x73, 0x2B, 0xFF, 0xAA, 0x6B, + 0x20, 0xFF, 0xA3, 0x61, 0x14, 0xFF, 0xAC, 0x71, 0x2E, 0xFF, 0xC9, 0xA0, 0x73, 0xE6, 0xE3, 0xCF, + 0xB6, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFB, + 0xF6, 0x09, 0xCC, 0xA7, 0x80, 0xAB, 0xA5, 0x6B, 0x31, 0xFF, 0x96, 0x54, 0x15, 0xFF, 0xA0, 0x61, + 0x23, 0xFF, 0xA7, 0x6B, 0x2B, 0xFF, 0xAA, 0x6E, 0x2B, 0xFF, 0xAD, 0x71, 0x2C, 0xFF, 0xAF, 0x74, + 0x2D, 0xFF, 0xB1, 0x76, 0x2D, 0xFF, 0xB3, 0x77, 0x2E, 0xFF, 0xB3, 0x78, 0x2E, 0xFF, 0xB3, 0x78, + 0x2E, 0xFF, 0xB3, 0x78, 0x2E, 0xFF, 0xB3, 0x78, 0x2E, 0xFF, 0xB3, 0x78, 0x2E, 0xFF, 0xB3, 0x78, + 0x2E, 0xFF, 0xB3, 0x78, 0x2E, 0xFF, 0xB2, 0x78, 0x2E, 0xFF, 0xAC, 0x73, 0x2B, 0xFF, 0xA7, 0x7A, + 0x3E, 0xFF, 0xC8, 0xBC, 0xAD, 0xFF, 0xD6, 0xD7, 0xD8, 0xFF, 0xD7, 0xD6, 0xD7, 0xFF, 0xD7, 0xD7, + 0xD7, 0xFF, 0xD8, 0xD8, 0xD8, 0xFF, 0xD8, 0xD8, 0xD8, 0xFF, 0xDB, 0xDC, 0xDC, 0xFF, 0xB6, 0xAF, + 0x9E, 0xFF, 0x8B, 0x78, 0x50, 0xFF, 0x98, 0x83, 0x5B, 0xFF, 0xD5, 0xCD, 0xBF, 0xFF, 0xE1, 0xDF, + 0xDB, 0xFF, 0xD9, 0xD6, 0xCE, 0xFF, 0xDA, 0xD7, 0xD0, 0xFF, 0xE3, 0xE2, 0xE0, 0xFF, 0xE6, 0xE6, + 0xE7, 0xFF, 0xE3, 0xE3, 0xE3, 0xFF, 0xE2, 0xE2, 0xE3, 0xFF, 0xE1, 0xE1, 0xE0, 0xFF, 0xB5, 0xAD, + 0x9A, 0xFF, 0x89, 0x77, 0x52, 0xFF, 0xB0, 0xA5, 0x8F, 0xFF, 0xDD, 0xDC, 0xDB, 0xFF, 0xDF, 0xDF, + 0xDF, 0xFF, 0xBC, 0xB3, 0xA2, 0xFF, 0x8C, 0x72, 0x43, 0xFF, 0x8C, 0x64, 0x27, 0xFF, 0xA1, 0x6F, + 0x2C, 0xFF, 0xAC, 0x75, 0x2D, 0xFF, 0xB1, 0x77, 0x2E, 0xFF, 0xB3, 0x78, 0x2E, 0xFF, 0xB3, 0x78, + 0x2E, 0xFF, 0xB3, 0x78, 0x2E, 0xFF, 0xB3, 0x78, 0x2E, 0xFF, 0xB3, 0x78, 0x2E, 0xFF, 0xB3, 0x78, + 0x2E, 0xFF, 0xB3, 0x78, 0x2E, 0xFF, 0xB3, 0x78, 0x2E, 0xFF, 0xB2, 0x77, 0x2E, 0xFF, 0xB1, 0x75, + 0x2D, 0xFF, 0xAB, 0x6C, 0x23, 0xFF, 0xAE, 0x73, 0x2E, 0xFF, 0xC9, 0xA0, 0x71, 0xEB, 0xE4, 0xCF, + 0xB6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFA, + 0xF5, 0x09, 0xCD, 0xA8, 0x80, 0xAC, 0xA9, 0x70, 0x35, 0xFF, 0xA1, 0x63, 0x27, 0xFF, 0xA6, 0x6A, + 0x2D, 0xFF, 0xAA, 0x6F, 0x2E, 0xFF, 0xAE, 0x72, 0x2F, 0xFF, 0xB1, 0x75, 0x30, 0xFF, 0xB3, 0x78, + 0x30, 0xFF, 0xB4, 0x7A, 0x31, 0xFF, 0xB6, 0x7B, 0x31, 0xFF, 0xB6, 0x7B, 0x31, 0xFF, 0xB6, 0x7B, + 0x31, 0xFF, 0xB6, 0x7B, 0x31, 0xFF, 0xB6, 0x7B, 0x31, 0xFF, 0xB6, 0x7B, 0x31, 0xFF, 0xB6, 0x7B, + 0x31, 0xFF, 0xB6, 0x7B, 0x31, 0xFF, 0xB6, 0x7B, 0x31, 0xFF, 0xB5, 0x7B, 0x31, 0xFF, 0xAF, 0x7A, + 0x34, 0xFF, 0xB3, 0x91, 0x61, 0xFF, 0xD1, 0xCC, 0xC4, 0xFF, 0xD7, 0xD7, 0xD8, 0xFF, 0xD6, 0xD6, + 0xD6, 0xFF, 0xD6, 0xD6, 0xD6, 0xFF, 0xD6, 0xD6, 0xD6, 0xFF, 0xD6, 0xD6, 0xD6, 0xFF, 0xDA, 0xDA, + 0xD9, 0xFF, 0xD6, 0xD4, 0xCF, 0xFF, 0xC8, 0xBF, 0xAF, 0xFF, 0x9D, 0x8A, 0x64, 0xFF, 0xAE, 0x9C, + 0x7B, 0xFF, 0xBB, 0xAD, 0x93, 0xFF, 0xB1, 0xA3, 0x88, 0xFF, 0xB4, 0xA6, 0x8B, 0xFF, 0xBB, 0xAF, + 0x97, 0xFF, 0xD8, 0xD4, 0xCC, 0xFF, 0xE2, 0xE2, 0xE2, 0xFF, 0xE0, 0xE0, 0xE1, 0xFF, 0xE2, 0xE2, + 0xE3, 0xFF, 0xC3, 0xBE, 0xB1, 0xFF, 0x90, 0x81, 0x5D, 0xFF, 0xA9, 0x9D, 0x82, 0xFF, 0xDA, 0xD8, + 0xD6, 0xFF, 0xE0, 0xE1, 0xE3, 0xFF, 0xCD, 0xC9, 0xBE, 0xFF, 0x99, 0x84, 0x5D, 0xFF, 0x8C, 0x67, + 0x2C, 0xFF, 0xA0, 0x71, 0x2F, 0xFF, 0xAE, 0x78, 0x31, 0xFF, 0xB4, 0x7B, 0x31, 0xFF, 0xB6, 0x7B, + 0x31, 0xFF, 0xB6, 0x7B, 0x31, 0xFF, 0xB6, 0x7B, 0x31, 0xFF, 0xB6, 0x7B, 0x31, 0xFF, 0xB6, 0x7B, + 0x31, 0xFF, 0xB6, 0x7B, 0x31, 0xFF, 0xB6, 0x7B, 0x31, 0xFF, 0xB5, 0x7B, 0x31, 0xFF, 0xB4, 0x79, + 0x31, 0xFF, 0xB3, 0x78, 0x31, 0xFF, 0xB5, 0x7E, 0x3C, 0xFF, 0xCB, 0xA2, 0x72, 0xED, 0xE5, 0xD0, + 0xB6, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xFD, 0x08, 0xD0, 0xAB, 0x83, 0xA6, 0xB3, 0x7D, 0x47, 0xFF, 0xA9, 0x6E, 0x33, 0xFF, 0xAA, 0x6E, + 0x30, 0xFF, 0xAE, 0x73, 0x32, 0xFF, 0xB1, 0x77, 0x33, 0xFF, 0xB4, 0x7A, 0x34, 0xFF, 0xB6, 0x7C, + 0x34, 0xFF, 0xB7, 0x7E, 0x35, 0xFF, 0xB9, 0x7F, 0x35, 0xFF, 0xB9, 0x7F, 0x35, 0xFF, 0xB9, 0x7F, + 0x35, 0xFF, 0xB9, 0x7F, 0x35, 0xFF, 0xB9, 0x7F, 0x35, 0xFF, 0xB9, 0x7F, 0x35, 0xFF, 0xB9, 0x7F, + 0x35, 0xFF, 0xB9, 0x7F, 0x35, 0xFF, 0xB9, 0x7F, 0x35, 0xFF, 0xBD, 0x86, 0x40, 0xFF, 0xC0, 0x8E, + 0x4E, 0xFF, 0xB9, 0x8B, 0x4E, 0xFF, 0xBE, 0xA2, 0x7C, 0xFF, 0xD7, 0xD4, 0xD0, 0xFF, 0xD8, 0xD8, + 0xD9, 0xFF, 0xD8, 0xD8, 0xD8, 0xFF, 0xD9, 0xD9, 0xD9, 0xFF, 0xD8, 0xD8, 0xD8, 0xFF, 0xD8, 0xD8, + 0xD8, 0xFF, 0xD8, 0xD8, 0xD9, 0xFF, 0xE0, 0xE0, 0xE1, 0xFF, 0xB6, 0xAB, 0x91, 0xFF, 0xA7, 0x95, + 0x71, 0xFF, 0xE5, 0xE2, 0xDC, 0xFF, 0xE2, 0xE1, 0xDD, 0xFF, 0xA4, 0x94, 0x71, 0xFF, 0x85, 0x6F, + 0x41, 0xFF, 0xB6, 0xAC, 0x96, 0xFF, 0xE1, 0xE1, 0xE2, 0xFF, 0xDF, 0xDF, 0xDF, 0xFF, 0xE0, 0xE0, + 0xE0, 0xFF, 0xE2, 0xE2, 0xE3, 0xFF, 0xCF, 0xCC, 0xC3, 0xFF, 0x9A, 0x8D, 0x6D, 0xFF, 0xA5, 0x98, + 0x7C, 0xFF, 0xD8, 0xD5, 0xD1, 0xFF, 0xE0, 0xE0, 0xE2, 0xFF, 0xD8, 0xD6, 0xD1, 0xFF, 0xA8, 0x97, + 0x76, 0xFF, 0x90, 0x6C, 0x32, 0xFF, 0xA4, 0x75, 0x32, 0xFF, 0xB3, 0x7C, 0x34, 0xFF, 0xB8, 0x7F, + 0x35, 0xFF, 0xB9, 0x7F, 0x35, 0xFF, 0xB9, 0x7F, 0x35, 0xFF, 0xB9, 0x7F, 0x35, 0xFF, 0xB9, 0x7F, + 0x35, 0xFF, 0xB9, 0x7F, 0x35, 0xFF, 0xB9, 0x7F, 0x35, 0xFF, 0xB8, 0x7F, 0x35, 0xFF, 0xB7, 0x7D, + 0x34, 0xFF, 0xB6, 0x7D, 0x36, 0xFF, 0xBD, 0x89, 0x4B, 0xFF, 0xD0, 0xAA, 0x7D, 0xE8, 0xE5, 0xD0, + 0xB6, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0x06, 0xD4, 0xB1, 0x8C, 0x9A, 0xBB, 0x89, 0x55, 0xFF, 0xAD, 0x73, 0x38, 0xFF, 0xAE, 0x73, + 0x33, 0xFF, 0xB2, 0x77, 0x35, 0xFF, 0xB5, 0x7B, 0x37, 0xFF, 0xB7, 0x7D, 0x38, 0xFF, 0xB9, 0x80, + 0x38, 0xFF, 0xBA, 0x81, 0x38, 0xFF, 0xBC, 0x82, 0x39, 0xFF, 0xBC, 0x83, 0x39, 0xFF, 0xBC, 0x83, + 0x39, 0xFF, 0xBC, 0x83, 0x39, 0xFF, 0xBC, 0x83, 0x39, 0xFF, 0xBC, 0x83, 0x39, 0xFF, 0xBC, 0x82, + 0x38, 0xFF, 0xBC, 0x83, 0x39, 0xFF, 0xC0, 0x8B, 0x46, 0xFF, 0xC5, 0x94, 0x55, 0xFF, 0xC5, 0x95, + 0x57, 0xFF, 0xC3, 0x93, 0x56, 0xFF, 0xBB, 0x90, 0x55, 0xFF, 0xC7, 0xB1, 0x92, 0xFF, 0xDC, 0xDB, + 0xD9, 0xFF, 0xDB, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, + 0xDC, 0xFF, 0xDB, 0xDB, 0xDB, 0xFF, 0xDF, 0xDF, 0xDE, 0xFF, 0xBD, 0xB5, 0xA2, 0xFF, 0xB6, 0xAB, + 0x91, 0xFF, 0xB6, 0xAA, 0x90, 0xFF, 0xE3, 0xE1, 0xDE, 0xFF, 0xD0, 0xCB, 0xBF, 0xFF, 0xB6, 0xAD, + 0x98, 0xFF, 0xD2, 0xD0, 0xC9, 0xFF, 0xDB, 0xDB, 0xDB, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDF, 0xDF, + 0xDF, 0xFF, 0xE0, 0xE0, 0xE0, 0xFF, 0xE3, 0xE3, 0xE4, 0xFF, 0xD8, 0xD6, 0xD2, 0xFF, 0xA6, 0x9C, + 0x81, 0xFF, 0xA2, 0x96, 0x78, 0xFF, 0xD6, 0xD3, 0xCC, 0xFF, 0xE1, 0xE1, 0xE3, 0xFF, 0xDF, 0xDE, + 0xDB, 0xFF, 0xB7, 0xA8, 0x8A, 0xFF, 0x9D, 0x75, 0x39, 0xFF, 0xB0, 0x7C, 0x37, 0xFF, 0xBA, 0x82, + 0x38, 0xFF, 0xBC, 0x83, 0x39, 0xFF, 0xBC, 0x83, 0x39, 0xFF, 0xBC, 0x83, 0x39, 0xFF, 0xBC, 0x83, + 0x39, 0xFF, 0xBC, 0x83, 0x39, 0xFF, 0xBC, 0x83, 0x39, 0xFF, 0xBB, 0x82, 0x39, 0xFF, 0xBA, 0x81, + 0x38, 0xFF, 0xB9, 0x81, 0x3A, 0xFF, 0xC1, 0x8F, 0x53, 0xFF, 0xD5, 0xB1, 0x87, 0xDF, 0xE6, 0xD1, + 0xB7, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0x02, 0xD5, 0xB3, 0x8C, 0x87, 0xC0, 0x91, 0x5D, 0xFF, 0xB1, 0x79, 0x3D, 0xFF, 0xB1, 0x77, + 0x37, 0xFF, 0xB5, 0x7B, 0x39, 0xFF, 0xB8, 0x7F, 0x3A, 0xFF, 0xBA, 0x81, 0x3B, 0xFF, 0xBC, 0x83, + 0x3B, 0xFF, 0xBD, 0x85, 0x3C, 0xFF, 0xBE, 0x86, 0x3C, 0xFF, 0xBE, 0x86, 0x3C, 0xFF, 0xBE, 0x86, + 0x3C, 0xFF, 0xBE, 0x86, 0x3C, 0xFF, 0xBE, 0x86, 0x3C, 0xFF, 0xBE, 0x86, 0x3C, 0xFF, 0xBE, 0x86, + 0x3C, 0xFF, 0xC3, 0x8F, 0x4A, 0xFF, 0xCA, 0x99, 0x5B, 0xFF, 0xCA, 0x9A, 0x5D, 0xFF, 0xCA, 0x9A, + 0x5C, 0xFF, 0xCA, 0x9A, 0x5C, 0xFF, 0xC5, 0x98, 0x5B, 0xFF, 0xBE, 0x96, 0x5E, 0xFF, 0xCF, 0xBD, + 0xA5, 0xFF, 0xE0, 0xE0, 0xE0, 0xFF, 0xDF, 0xDF, 0xDF, 0xFF, 0xE0, 0xE0, 0xE0, 0xFF, 0xE0, 0xE0, + 0xE0, 0xFF, 0xE0, 0xE0, 0xE1, 0xFF, 0xE0, 0xDF, 0xDD, 0xFF, 0xC2, 0xBC, 0xAA, 0xFF, 0xE5, 0xE4, + 0xE1, 0xFF, 0xBE, 0xB6, 0xA1, 0xFF, 0xB6, 0xAB, 0x92, 0xFF, 0xE1, 0xE0, 0xDE, 0xFF, 0xE0, 0xE0, + 0xE2, 0xFF, 0xDC, 0xDC, 0xDD, 0xFF, 0xDB, 0xDB, 0xDB, 0xFF, 0xDB, 0xDB, 0xDB, 0xFF, 0xDD, 0xDD, + 0xDD, 0xFF, 0xE0, 0xE0, 0xE0, 0xFF, 0xE2, 0xE2, 0xE2, 0xFF, 0xE4, 0xE4, 0xE5, 0xFF, 0xE0, 0xDF, + 0xDD, 0xFF, 0xB5, 0xAE, 0x99, 0xFF, 0xA2, 0x97, 0x79, 0xFF, 0xD4, 0xD0, 0xC7, 0xFF, 0xE2, 0xE2, + 0xE4, 0xFF, 0xE0, 0xDD, 0xD8, 0xFF, 0xAA, 0x8B, 0x58, 0xFF, 0xAE, 0x7D, 0x38, 0xFF, 0xBC, 0x85, + 0x3C, 0xFF, 0xBE, 0x86, 0x3C, 0xFF, 0xBE, 0x86, 0x3C, 0xFF, 0xBE, 0x86, 0x3C, 0xFF, 0xBE, 0x86, + 0x3C, 0xFF, 0xBE, 0x86, 0x3C, 0xFF, 0xBE, 0x86, 0x3C, 0xFF, 0xBE, 0x86, 0x3C, 0xFF, 0xBD, 0x84, + 0x3B, 0xFF, 0xBD, 0x85, 0x3E, 0xFF, 0xC5, 0x96, 0x5B, 0xFF, 0xD7, 0xB6, 0x8C, 0xD0, 0xE6, 0xD1, + 0xB4, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xD8, 0xB6, 0x90, 0x6C, 0xC7, 0x99, 0x67, 0xFF, 0xB6, 0x7E, 0x43, 0xFF, 0xB4, 0x7B, + 0x3B, 0xFF, 0xB8, 0x7E, 0x3C, 0xFF, 0xBB, 0x82, 0x3D, 0xFF, 0xBD, 0x85, 0x3E, 0xFF, 0xBF, 0x87, + 0x3F, 0xFF, 0xC0, 0x89, 0x3F, 0xFF, 0xC1, 0x8A, 0x40, 0xFF, 0xC2, 0x8A, 0x40, 0xFF, 0xC2, 0x8A, + 0x40, 0xFF, 0xC2, 0x8A, 0x40, 0xFF, 0xC2, 0x8A, 0x40, 0xFF, 0xC1, 0x89, 0x3F, 0xFF, 0xC4, 0x90, + 0x49, 0xFF, 0xCC, 0x9D, 0x60, 0xFF, 0xCE, 0x9F, 0x63, 0xFF, 0xCE, 0x9F, 0x63, 0xFF, 0xCE, 0x9F, + 0x63, 0xFF, 0xCD, 0x9F, 0x63, 0xFF, 0xCC, 0x9F, 0x63, 0xFF, 0xC9, 0x9C, 0x61, 0xFF, 0xC1, 0x9D, + 0x68, 0xFF, 0xD6, 0xCA, 0xB7, 0xFF, 0xE4, 0xE5, 0xE5, 0xFF, 0xE3, 0xE3, 0xE3, 0xFF, 0xE4, 0xE4, + 0xE4, 0xFF, 0xE4, 0xE4, 0xE5, 0xFF, 0xE1, 0xE0, 0xDD, 0xFF, 0xC0, 0xB8, 0xA5, 0xFF, 0xE4, 0xE2, + 0xDF, 0xFF, 0xE6, 0xE5, 0xE4, 0xFF, 0xBB, 0xB2, 0x9B, 0xFF, 0xBA, 0xAF, 0x97, 0xFF, 0xDF, 0xDD, + 0xDB, 0xFF, 0xDE, 0xDD, 0xDC, 0xFF, 0xDD, 0xDD, 0xDD, 0xFF, 0xDD, 0xDD, 0xDD, 0xFF, 0xDD, 0xDD, + 0xDD, 0xFF, 0xDE, 0xDE, 0xDE, 0xFF, 0xE1, 0xE1, 0xE1, 0xFF, 0xE3, 0xE3, 0xE3, 0xFF, 0xE5, 0xE5, + 0xE5, 0xFF, 0xE6, 0xE6, 0xE6, 0xFF, 0xC5, 0xBF, 0xB1, 0xFF, 0xA7, 0x9D, 0x81, 0xFF, 0xD5, 0xD1, + 0xC8, 0xFF, 0xE7, 0xE5, 0xE2, 0xFF, 0xB4, 0x95, 0x65, 0xFF, 0xB2, 0x81, 0x3B, 0xFF, 0xBF, 0x89, + 0x40, 0xFF, 0xC2, 0x8A, 0x40, 0xFF, 0xC2, 0x8A, 0x40, 0xFF, 0xC2, 0x8A, 0x40, 0xFF, 0xC2, 0x8A, + 0x40, 0xFF, 0xC2, 0x8A, 0x40, 0xFF, 0xC2, 0x8A, 0x40, 0xFF, 0xC1, 0x89, 0x40, 0xFF, 0xC0, 0x88, + 0x3F, 0xFF, 0xC0, 0x8A, 0x44, 0xFF, 0xCB, 0x9D, 0x64, 0xFF, 0xDC, 0xBC, 0x95, 0xBC, 0xEF, 0xE2, + 0xD0, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xDC, 0xBD, 0x97, 0x4E, 0xCC, 0xA1, 0x70, 0xF3, 0xBB, 0x86, 0x4B, 0xFF, 0xB8, 0x7F, + 0x3F, 0xFF, 0xBB, 0x82, 0x40, 0xFF, 0xBE, 0x86, 0x41, 0xFF, 0xC0, 0x89, 0x42, 0xFF, 0xC2, 0x8A, + 0x42, 0xFF, 0xC3, 0x8C, 0x43, 0xFF, 0xC4, 0x8D, 0x43, 0xFF, 0xC4, 0x8D, 0x43, 0xFF, 0xC4, 0x8D, + 0x43, 0xFF, 0xC4, 0x8D, 0x43, 0xFF, 0xC4, 0x8D, 0x43, 0xFF, 0xC5, 0x8F, 0x47, 0xFF, 0xCD, 0x9E, + 0x60, 0xFF, 0xD0, 0xA4, 0x69, 0xFF, 0xD0, 0xA3, 0x68, 0xFF, 0xD0, 0xA3, 0x68, 0xFF, 0xD0, 0xA3, + 0x68, 0xFF, 0xD0, 0xA3, 0x68, 0xFF, 0xD0, 0xA3, 0x68, 0xFF, 0xCF, 0xA3, 0x68, 0xFF, 0xCB, 0xA0, + 0x66, 0xFF, 0xC5, 0xA5, 0x75, 0xFF, 0xDD, 0xD5, 0xC8, 0xFF, 0xE7, 0xE8, 0xE8, 0xFF, 0xE7, 0xE7, + 0xE7, 0xFF, 0xE7, 0xE7, 0xE7, 0xFF, 0xE6, 0xE6, 0xE4, 0xFF, 0xBB, 0xB1, 0x99, 0xFF, 0xB6, 0xA6, + 0x86, 0xFF, 0xD1, 0xCA, 0xB9, 0xFF, 0xE4, 0xE3, 0xE1, 0xFF, 0xBC, 0xAF, 0x96, 0xFF, 0xB9, 0xA9, + 0x8A, 0xFF, 0xBE, 0xB0, 0x94, 0xFF, 0xDA, 0xD8, 0xD2, 0xFF, 0xDF, 0xE0, 0xE0, 0xFF, 0xE0, 0xE0, + 0xE0, 0xFF, 0xE0, 0xE0, 0xE0, 0xFF, 0xDF, 0xDF, 0xDF, 0xFF, 0xE2, 0xE2, 0xE2, 0xFF, 0xE5, 0xE5, + 0xE5, 0xFF, 0xE6, 0xE6, 0xE6, 0xFF, 0xE9, 0xE9, 0xEA, 0xFF, 0xD4, 0xD0, 0xC5, 0xFF, 0xB8, 0xAE, + 0x95, 0xFF, 0xD9, 0xCE, 0xBB, 0xFF, 0xB5, 0x90, 0x56, 0xFF, 0xBA, 0x88, 0x41, 0xFF, 0xC3, 0x8D, + 0x44, 0xFF, 0xC4, 0x8D, 0x43, 0xFF, 0xC4, 0x8D, 0x43, 0xFF, 0xC4, 0x8D, 0x43, 0xFF, 0xC4, 0x8D, + 0x43, 0xFF, 0xC4, 0x8D, 0x43, 0xFF, 0xC4, 0x8D, 0x43, 0xFF, 0xC3, 0x8D, 0x43, 0xFF, 0xC3, 0x8C, + 0x42, 0xFF, 0xC4, 0x8F, 0x4A, 0xFF, 0xD0, 0xA5, 0x6F, 0xFF, 0xDF, 0xC0, 0x9B, 0x9E, 0xFF, 0xFF, + 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xE6, 0xCF, 0xB1, 0x30, 0xD1, 0xA9, 0x79, 0xE2, 0xC1, 0x8E, 0x55, 0xFF, 0xBC, 0x83, + 0x44, 0xFF, 0xBE, 0x86, 0x44, 0xFF, 0xC1, 0x8A, 0x45, 0xFF, 0xC3, 0x8C, 0x46, 0xFF, 0xC5, 0x8E, + 0x46, 0xFF, 0xC7, 0x90, 0x47, 0xFF, 0xC8, 0x91, 0x48, 0xFF, 0xC8, 0x91, 0x48, 0xFF, 0xC8, 0x91, + 0x48, 0xFF, 0xC8, 0x91, 0x48, 0xFF, 0xC8, 0x90, 0x47, 0xFF, 0xCC, 0x9B, 0x59, 0xFF, 0xD3, 0xA8, + 0x6E, 0xFF, 0xD3, 0xA8, 0x6E, 0xFF, 0xD3, 0xA8, 0x6E, 0xFF, 0xD3, 0xA8, 0x6E, 0xFF, 0xD3, 0xA8, + 0x6E, 0xFF, 0xD3, 0xA8, 0x6E, 0xFF, 0xD3, 0xA8, 0x6E, 0xFF, 0xD3, 0xA8, 0x6E, 0xFF, 0xD2, 0xA8, + 0x6E, 0xFF, 0xCC, 0xA4, 0x6B, 0xFF, 0xCC, 0xAF, 0x84, 0xFF, 0xE3, 0xDE, 0xD5, 0xFF, 0xEA, 0xEA, + 0xEB, 0xFF, 0xE9, 0xE9, 0xEA, 0xFF, 0xE8, 0xE7, 0xE6, 0xFF, 0xB0, 0xA6, 0x8B, 0xFF, 0x9A, 0x89, + 0x5F, 0xFF, 0xB5, 0xAA, 0x8E, 0xFF, 0xE7, 0xE7, 0xE6, 0xFF, 0xC4, 0xBC, 0xAA, 0xFF, 0xA2, 0x8E, + 0x64, 0xFF, 0xA8, 0x94, 0x6C, 0xFF, 0xD4, 0xD0, 0xC5, 0xFF, 0xE2, 0xE2, 0xE3, 0xFF, 0xE1, 0xE1, + 0xE1, 0xFF, 0xE3, 0xE3, 0xE3, 0xFF, 0xE2, 0xE2, 0xE2, 0xFF, 0xE1, 0xE1, 0xE1, 0xFF, 0xE4, 0xE4, + 0xE4, 0xFF, 0xE6, 0xE6, 0xE6, 0xFF, 0xE7, 0xE7, 0xE8, 0xFF, 0xEB, 0xEB, 0xEC, 0xFF, 0xE3, 0xDF, + 0xD7, 0xFF, 0xBD, 0xA8, 0x81, 0xFF, 0xB3, 0x89, 0x48, 0xFF, 0xBF, 0x8D, 0x46, 0xFF, 0xC5, 0x90, + 0x47, 0xFF, 0xC7, 0x91, 0x48, 0xFF, 0xC8, 0x91, 0x48, 0xFF, 0xC8, 0x91, 0x48, 0xFF, 0xC8, 0x91, + 0x48, 0xFF, 0xC8, 0x91, 0x48, 0xFF, 0xC8, 0x91, 0x48, 0xFF, 0xC7, 0x91, 0x48, 0xFF, 0xC5, 0x90, + 0x47, 0xFF, 0xC9, 0x96, 0x53, 0xFF, 0xD5, 0xAE, 0x7B, 0xFE, 0xE2, 0xC5, 0xA1, 0x78, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xEE, 0xDE, 0xC7, 0x12, 0xD7, 0xB1, 0x82, 0xC4, 0xC9, 0x98, 0x60, 0xFF, 0xC1, 0x89, + 0x4A, 0xFF, 0xC2, 0x8A, 0x48, 0xFF, 0xC4, 0x8D, 0x49, 0xFF, 0xC7, 0x90, 0x4A, 0xFF, 0xC9, 0x92, + 0x4A, 0xFF, 0xCA, 0x94, 0x4B, 0xFF, 0xCB, 0x95, 0x4B, 0xFF, 0xCB, 0x95, 0x4B, 0xFF, 0xCB, 0x95, + 0x4B, 0xFF, 0xCB, 0x95, 0x4B, 0xFF, 0xCC, 0x97, 0x4F, 0xFF, 0xD4, 0xA8, 0x6C, 0xFF, 0xD6, 0xAD, + 0x75, 0xFF, 0xD6, 0xAD, 0x74, 0xFF, 0xD6, 0xAD, 0x74, 0xFF, 0xD6, 0xAD, 0x74, 0xFF, 0xD6, 0xAD, + 0x74, 0xFF, 0xD6, 0xAD, 0x74, 0xFF, 0xD6, 0xAD, 0x74, 0xFF, 0xD6, 0xAD, 0x74, 0xFF, 0xD6, 0xAD, + 0x74, 0xFF, 0xD5, 0xAC, 0x74, 0xFF, 0xCF, 0xA8, 0x71, 0xFF, 0xD1, 0xB8, 0x93, 0xFF, 0xE7, 0xE4, + 0xDF, 0xFF, 0xEC, 0xEC, 0xED, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xD9, 0xD7, 0xCF, 0xFF, 0xC3, 0xBD, + 0xAC, 0xFF, 0xDA, 0xD8, 0xD0, 0xFF, 0xE9, 0xE9, 0xE9, 0xFF, 0xD7, 0xD4, 0xCD, 0xFF, 0xBF, 0xB8, + 0xA4, 0xFF, 0xAC, 0xA1, 0x84, 0xFF, 0xCD, 0xC9, 0xBC, 0xFF, 0xE6, 0xE6, 0xE7, 0xFF, 0xE4, 0xE4, + 0xE4, 0xFF, 0xE5, 0xE5, 0xE5, 0xFF, 0xE6, 0xE6, 0xE6, 0xFF, 0xE5, 0xE5, 0xE5, 0xFF, 0xE4, 0xE4, + 0xE4, 0xFF, 0xE6, 0xE6, 0xE6, 0xFF, 0xE8, 0xE8, 0xE8, 0xFF, 0xEC, 0xED, 0xED, 0xFF, 0xDA, 0xD6, + 0xC9, 0xFF, 0xB9, 0xA6, 0x80, 0xFF, 0xB6, 0x92, 0x59, 0xFF, 0xBB, 0x8D, 0x48, 0xFF, 0xC3, 0x92, + 0x4B, 0xFF, 0xC8, 0x94, 0x4B, 0xFF, 0xCB, 0x95, 0x4B, 0xFF, 0xCB, 0x95, 0x4B, 0xFF, 0xCB, 0x95, + 0x4B, 0xFF, 0xCB, 0x95, 0x4B, 0xFF, 0xCB, 0x95, 0x4B, 0xFF, 0xCB, 0x95, 0x4B, 0xFF, 0xCA, 0x94, + 0x4C, 0xFF, 0xCF, 0x9E, 0x5E, 0xFF, 0xDB, 0xB6, 0x86, 0xF1, 0xD7, 0xBF, 0xA0, 0x4D, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x02, 0xDE, 0xBB, 0x91, 0x92, 0xD0, 0xA2, 0x6C, 0xFF, 0xC5, 0x90, + 0x52, 0xFF, 0xC5, 0x8E, 0x4B, 0xFF, 0xC8, 0x91, 0x4C, 0xFF, 0xCB, 0x94, 0x4E, 0xFF, 0xCC, 0x96, + 0x4E, 0xFF, 0xCE, 0x98, 0x4F, 0xFF, 0xCF, 0x99, 0x4F, 0xFF, 0xCF, 0x99, 0x4F, 0xFF, 0xCF, 0x99, + 0x4F, 0xFF, 0xCF, 0x99, 0x4E, 0xFF, 0xD3, 0xA2, 0x5E, 0xFF, 0xD9, 0xB1, 0x79, 0xFF, 0xDA, 0xB1, + 0x7A, 0xFF, 0xDA, 0xB1, 0x7A, 0xFF, 0xDA, 0xB1, 0x7A, 0xFF, 0xDA, 0xB1, 0x7A, 0xFF, 0xDA, 0xB1, + 0x7A, 0xFF, 0xDA, 0xB1, 0x7A, 0xFF, 0xDA, 0xB1, 0x7A, 0xFF, 0xDA, 0xB1, 0x7A, 0xFF, 0xDA, 0xB1, + 0x7A, 0xFF, 0xDA, 0xB1, 0x7A, 0xFF, 0xD8, 0xB0, 0x79, 0xFF, 0xD1, 0xAD, 0x77, 0xFF, 0xD6, 0xC0, + 0xA0, 0xFF, 0xEA, 0xE8, 0xE5, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEF, 0xEF, 0xEF, 0xFF, 0xEF, 0xEF, + 0xF0, 0xFF, 0xED, 0xED, 0xEE, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xE8, 0xE9, + 0xE9, 0xFF, 0xDF, 0xDE, 0xDC, 0xFF, 0xDF, 0xDF, 0xDC, 0xFF, 0xE8, 0xE8, 0xE8, 0xFF, 0xE7, 0xE7, + 0xE7, 0xFF, 0xE7, 0xE7, 0xE7, 0xFF, 0xE7, 0xE7, 0xE7, 0xFF, 0xE8, 0xE8, 0xE8, 0xFF, 0xE8, 0xE8, + 0xE8, 0xFF, 0xE7, 0xE7, 0xE7, 0xFF, 0xE9, 0xE9, 0xE9, 0xFF, 0xF2, 0xF2, 0xF1, 0xFF, 0xD7, 0xD3, + 0xC4, 0xFF, 0xB8, 0xAD, 0x8F, 0xFF, 0xC7, 0xB4, 0x91, 0xFF, 0xB3, 0x91, 0x56, 0xFF, 0xB8, 0x8D, + 0x4A, 0xFF, 0xC3, 0x94, 0x4E, 0xFF, 0xCB, 0x98, 0x4F, 0xFF, 0xCE, 0x99, 0x4F, 0xFF, 0xCF, 0x99, + 0x4F, 0xFF, 0xCF, 0x99, 0x4F, 0xFF, 0xCF, 0x99, 0x4F, 0xFF, 0xCE, 0x98, 0x4F, 0xFF, 0xCE, 0x99, + 0x52, 0xFF, 0xD5, 0xA8, 0x6B, 0xFF, 0xE0, 0xBF, 0x92, 0xD7, 0xCE, 0xBA, 0xA0, 0x22, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3, 0xC4, 0x9E, 0x55, 0xD7, 0xAD, 0x7A, 0xF8, 0xCC, 0x99, + 0x5C, 0xFF, 0xC9, 0x92, 0x4F, 0xFF, 0xCC, 0x95, 0x50, 0xFF, 0xCD, 0x98, 0x51, 0xFF, 0xCF, 0x9A, + 0x51, 0xFF, 0xD0, 0x9C, 0x52, 0xFF, 0xD1, 0x9D, 0x52, 0xFF, 0xD2, 0x9D, 0x52, 0xFF, 0xD1, 0x9D, + 0x52, 0xFF, 0xD2, 0x9D, 0x53, 0xFF, 0xD9, 0xAD, 0x6E, 0xFF, 0xDD, 0xB7, 0x80, 0xFF, 0xDD, 0xB6, + 0x7F, 0xFF, 0xDD, 0xB6, 0x7F, 0xFF, 0xDD, 0xB6, 0x7F, 0xFF, 0xDD, 0xB6, 0x7F, 0xFF, 0xDD, 0xB6, + 0x7F, 0xFF, 0xDD, 0xB6, 0x7F, 0xFF, 0xDD, 0xB6, 0x7F, 0xFF, 0xDD, 0xB6, 0x7F, 0xFF, 0xDD, 0xB6, + 0x7F, 0xFF, 0xDD, 0xB6, 0x7F, 0xFF, 0xDD, 0xB6, 0x7F, 0xFF, 0xDB, 0xB5, 0x7F, 0xFF, 0xD4, 0xB1, + 0x7D, 0xFF, 0xDA, 0xC9, 0xAC, 0xFF, 0xED, 0xEC, 0xEA, 0xFF, 0xF0, 0xF0, 0xF0, 0xFF, 0xF0, 0xEF, + 0xEF, 0xFF, 0xEF, 0xEF, 0xEF, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xEB, 0xEB, + 0xEB, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xEA, 0xEA, + 0xEA, 0xFF, 0xE9, 0xE9, 0xE9, 0xFF, 0xE9, 0xE9, 0xE9, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xEB, 0xEB, + 0xEB, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xE9, 0xE9, 0xE5, 0xFF, 0xEE, 0xEE, 0xEC, 0xFF, 0xF0, 0xF0, + 0xF0, 0xFF, 0xDE, 0xDA, 0xCF, 0xFF, 0xC9, 0xC1, 0xAA, 0xFF, 0xD0, 0xC3, 0xA8, 0xFF, 0xB5, 0x98, + 0x63, 0xFF, 0xB8, 0x90, 0x4E, 0xFF, 0xC9, 0x99, 0x52, 0xFF, 0xD0, 0x9C, 0x52, 0xFF, 0xD1, 0x9D, + 0x52, 0xFF, 0xD2, 0x9D, 0x52, 0xFF, 0xD1, 0x9D, 0x52, 0xFF, 0xD1, 0x9C, 0x53, 0xFF, 0xD2, 0xA0, + 0x5A, 0xFF, 0xDC, 0xB3, 0x7B, 0xFF, 0xDF, 0xC2, 0x9A, 0xA4, 0xC7, 0xBD, 0xAF, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEB, 0xD6, 0xB7, 0x22, 0xDD, 0xB7, 0x86, 0xD4, 0xD3, 0xA3, + 0x69, 0xFF, 0xCD, 0x97, 0x55, 0xFF, 0xCF, 0x98, 0x53, 0xFF, 0xD1, 0x9B, 0x54, 0xFF, 0xD2, 0x9D, + 0x55, 0xFF, 0xD3, 0x9F, 0x56, 0xFF, 0xD4, 0xA0, 0x56, 0xFF, 0xD5, 0xA1, 0x56, 0xFF, 0xD4, 0xA1, + 0x56, 0xFF, 0xD6, 0xA3, 0x5A, 0xFF, 0xDE, 0xB6, 0x7C, 0xFF, 0xE0, 0xBB, 0x85, 0xFF, 0xDF, 0xBB, + 0x84, 0xFF, 0xDF, 0xBB, 0x84, 0xFF, 0xDF, 0xBB, 0x84, 0xFF, 0xDF, 0xBB, 0x84, 0xFF, 0xDF, 0xBB, + 0x84, 0xFF, 0xDF, 0xBB, 0x84, 0xFF, 0xDF, 0xBB, 0x84, 0xFF, 0xDF, 0xBB, 0x84, 0xFF, 0xDF, 0xBB, + 0x84, 0xFF, 0xDF, 0xBB, 0x84, 0xFF, 0xE0, 0xBB, 0x84, 0xFF, 0xDF, 0xBB, 0x84, 0xFF, 0xDE, 0xB9, + 0x84, 0xFF, 0xD7, 0xB6, 0x84, 0xFF, 0xDE, 0xD0, 0xB6, 0xFF, 0xEF, 0xEF, 0xEE, 0xFF, 0xF1, 0xF1, + 0xF1, 0xFF, 0xF1, 0xF1, 0xF1, 0xFF, 0xF0, 0xF0, 0xF0, 0xFF, 0xEF, 0xEF, 0xEF, 0xFF, 0xEE, 0xEE, + 0xEE, 0xFF, 0xED, 0xED, 0xED, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xED, 0xED, 0xED, 0xFF, 0xED, 0xED, + 0xED, 0xFF, 0xED, 0xED, 0xED, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xEE, 0xEE, + 0xED, 0xFF, 0xE7, 0xE6, 0xE2, 0xFF, 0xEA, 0xEA, 0xE6, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEC, 0xEC, + 0xEC, 0xFF, 0xF1, 0xF1, 0xF2, 0xFF, 0xE6, 0xE4, 0xDC, 0xFF, 0xD0, 0xCB, 0xB9, 0xFF, 0xDC, 0xD4, + 0xC0, 0xFF, 0xBE, 0xA1, 0x6E, 0xFF, 0xC4, 0x98, 0x53, 0xFF, 0xD1, 0x9F, 0x56, 0xFF, 0xD4, 0xA1, + 0x56, 0xFF, 0xD5, 0xA1, 0x56, 0xFF, 0xD4, 0xA1, 0x56, 0xFF, 0xD4, 0xA0, 0x57, 0xFF, 0xD7, 0xA8, + 0x66, 0xFF, 0xE1, 0xBC, 0x8A, 0xFA, 0xE0, 0xC5, 0xA2, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x03, 0xE2, 0xC0, 0x93, 0x95, 0xD9, 0xAE, + 0x77, 0xFF, 0xD2, 0x9F, 0x5F, 0xFF, 0xD1, 0x9C, 0x57, 0xFF, 0xD4, 0x9E, 0x58, 0xFF, 0xD5, 0xA1, + 0x59, 0xFF, 0xD6, 0xA3, 0x5A, 0xFF, 0xD7, 0xA4, 0x5A, 0xFF, 0xD8, 0xA4, 0x5A, 0xFF, 0xD7, 0xA4, + 0x59, 0xFF, 0xDA, 0xA9, 0x63, 0xFF, 0xE2, 0xBC, 0x86, 0xFF, 0xE3, 0xBF, 0x8A, 0xFF, 0xE3, 0xBF, + 0x8A, 0xFF, 0xE3, 0xBF, 0x8A, 0xFF, 0xE3, 0xBF, 0x8A, 0xFF, 0xE3, 0xBF, 0x8A, 0xFF, 0xE3, 0xBF, + 0x8A, 0xFF, 0xE3, 0xBF, 0x8A, 0xFF, 0xE3, 0xBF, 0x8A, 0xFF, 0xE3, 0xBF, 0x8A, 0xFF, 0xE3, 0xBF, + 0x8A, 0xFF, 0xE3, 0xBF, 0x8A, 0xFF, 0xE3, 0xBF, 0x8A, 0xFF, 0xE3, 0xBF, 0x8A, 0xFF, 0xE2, 0xBF, + 0x8A, 0xFF, 0xE0, 0xBD, 0x89, 0xFF, 0xD9, 0xBB, 0x8B, 0xFF, 0xE2, 0xD5, 0xBF, 0xFF, 0xF1, 0xF1, + 0xF1, 0xFF, 0xF3, 0xF3, 0xF3, 0xFF, 0xF2, 0xF2, 0xF2, 0xFF, 0xF2, 0xF2, 0xF2, 0xFF, 0xF1, 0xF1, + 0xF1, 0xFF, 0xF0, 0xF0, 0xF0, 0xFF, 0xEF, 0xEF, 0xEF, 0xFF, 0xEF, 0xEF, 0xEF, 0xFF, 0xEF, 0xEF, + 0xEF, 0xFF, 0xF0, 0xF0, 0xF0, 0xFF, 0xEF, 0xEF, 0xF0, 0xFF, 0xEF, 0xEE, 0xEE, 0xFF, 0xE7, 0xE6, + 0xE2, 0xFF, 0xEA, 0xEA, 0xE7, 0xFF, 0xF1, 0xF1, 0xF1, 0xFF, 0xF0, 0xF0, 0xF0, 0xFF, 0xF0, 0xF0, + 0xF0, 0xFF, 0xF1, 0xF1, 0xF0, 0xFF, 0xF3, 0xF3, 0xF3, 0xFF, 0xE9, 0xE8, 0xE2, 0xFF, 0xE5, 0xE2, + 0xD7, 0xFF, 0xD1, 0xBC, 0x97, 0xFF, 0xC4, 0x9A, 0x55, 0xFF, 0xD4, 0xA3, 0x5A, 0xFF, 0xD7, 0xA5, + 0x5A, 0xFF, 0xD8, 0xA5, 0x5A, 0xFF, 0xD7, 0xA4, 0x5A, 0xFF, 0xD7, 0xA6, 0x5E, 0xFF, 0xDD, 0xB3, + 0x76, 0xFF, 0xE6, 0xC5, 0x97, 0xD7, 0xD8, 0xC5, 0xAB, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8, 0xCC, 0xA3, 0x44, 0xE0, 0xB8, + 0x85, 0xEE, 0xD8, 0xA8, 0x6C, 0xFF, 0xD5, 0xA0, 0x5D, 0xFF, 0xD6, 0xA2, 0x5C, 0xFF, 0xD8, 0xA4, + 0x5D, 0xFF, 0xD9, 0xA6, 0x5E, 0xFF, 0xDA, 0xA7, 0x5E, 0xFF, 0xDB, 0xA8, 0x5E, 0xFF, 0xDB, 0xA8, + 0x5D, 0xFF, 0xDD, 0xAE, 0x6A, 0xFF, 0xE5, 0xC1, 0x8D, 0xFF, 0xE6, 0xC2, 0x90, 0xFF, 0xE6, 0xC2, + 0x90, 0xFF, 0xE6, 0xC2, 0x90, 0xFF, 0xE6, 0xC2, 0x90, 0xFF, 0xE6, 0xC2, 0x90, 0xFF, 0xE6, 0xC2, + 0x90, 0xFF, 0xE6, 0xC2, 0x90, 0xFF, 0xE6, 0xC2, 0x90, 0xFF, 0xE6, 0xC2, 0x90, 0xFF, 0xE6, 0xC2, + 0x90, 0xFF, 0xE6, 0xC2, 0x90, 0xFF, 0xE6, 0xC2, 0x90, 0xFF, 0xE6, 0xC2, 0x90, 0xFF, 0xE6, 0xC2, + 0x90, 0xFF, 0xE5, 0xC2, 0x90, 0xFF, 0xE2, 0xC1, 0x8F, 0xFF, 0xDC, 0xBF, 0x92, 0xFF, 0xE5, 0xDA, + 0xC4, 0xFF, 0xF3, 0xF3, 0xF3, 0xFF, 0xF4, 0xF5, 0xF5, 0xFF, 0xF3, 0xF3, 0xF3, 0xFF, 0xF3, 0xF3, + 0xF3, 0xFF, 0xF2, 0xF2, 0xF2, 0xFF, 0xF2, 0xF2, 0xF2, 0xFF, 0xF1, 0xF1, 0xF1, 0xFF, 0xF2, 0xF2, + 0xF2, 0xFF, 0xF2, 0xF2, 0xF2, 0xFF, 0xF1, 0xF1, 0xF1, 0xFF, 0xEA, 0xEA, 0xE7, 0xFF, 0xEE, 0xEE, + 0xEB, 0xFF, 0xF2, 0xF2, 0xF2, 0xFF, 0xF2, 0xF2, 0xF2, 0xFF, 0xF3, 0xF3, 0xF3, 0xFF, 0xEF, 0xEF, + 0xEC, 0xFF, 0xCF, 0xCB, 0xB8, 0xFF, 0xEB, 0xEA, 0xE4, 0xFF, 0xF2, 0xF2, 0xF4, 0xFF, 0xF1, 0xF0, + 0xED, 0xFF, 0xD1, 0xB8, 0x8C, 0xFF, 0xCC, 0xA0, 0x5A, 0xFF, 0xD8, 0xA7, 0x5E, 0xFF, 0xDB, 0xA8, + 0x5E, 0xFF, 0xDB, 0xA8, 0x5E, 0xFF, 0xDB, 0xA8, 0x5F, 0xFF, 0xDC, 0xAD, 0x69, 0xFF, 0xE4, 0xBE, + 0x88, 0xFF, 0xE8, 0xCC, 0xA2, 0x90, 0xB9, 0xC2, 0xCF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE5, 0xD4, 0xB9, 0x0E, 0xE3, 0xC0, + 0x91, 0xAF, 0xDF, 0xB4, 0x7C, 0xFF, 0xD9, 0xA7, 0x66, 0xFF, 0xD9, 0xA5, 0x60, 0xFF, 0xDA, 0xA8, + 0x60, 0xFF, 0xDB, 0xA9, 0x61, 0xFF, 0xDC, 0xAB, 0x62, 0xFF, 0xDD, 0xAC, 0x62, 0xFF, 0xDD, 0xAB, + 0x61, 0xFF, 0xE0, 0xB3, 0x6F, 0xFF, 0xE8, 0xC7, 0x93, 0xFF, 0xE9, 0xC8, 0x95, 0xFF, 0xE9, 0xC8, + 0x94, 0xFF, 0xE9, 0xC8, 0x94, 0xFF, 0xE9, 0xC8, 0x94, 0xFF, 0xE9, 0xC8, 0x94, 0xFF, 0xE9, 0xC8, + 0x94, 0xFF, 0xE9, 0xC8, 0x94, 0xFF, 0xE9, 0xC8, 0x94, 0xFF, 0xE9, 0xC8, 0x94, 0xFF, 0xE9, 0xC8, + 0x94, 0xFF, 0xE9, 0xC8, 0x94, 0xFF, 0xE9, 0xC8, 0x94, 0xFF, 0xE9, 0xC8, 0x94, 0xFF, 0xE9, 0xC8, + 0x94, 0xFF, 0xE8, 0xC8, 0x94, 0xFF, 0xE8, 0xC8, 0x94, 0xFF, 0xE5, 0xC4, 0x93, 0xFF, 0xDF, 0xC4, + 0x96, 0xFF, 0xE7, 0xDC, 0xC8, 0xFF, 0xF5, 0xF4, 0xF4, 0xFF, 0xF6, 0xF6, 0xF6, 0xFF, 0xF5, 0xF5, + 0xF5, 0xFF, 0xF4, 0xF4, 0xF4, 0xFF, 0xF4, 0xF4, 0xF4, 0xFF, 0xF3, 0xF3, 0xF3, 0xFF, 0xF4, 0xF4, + 0xF4, 0xFF, 0xF4, 0xF4, 0xF4, 0xFF, 0xF1, 0xF0, 0xEE, 0xFF, 0xF2, 0xF2, 0xF1, 0xFF, 0xF4, 0xF4, + 0xF4, 0xFF, 0xF3, 0xF3, 0xF3, 0xFF, 0xF3, 0xF3, 0xF3, 0xFF, 0xF6, 0xF6, 0xF6, 0xFF, 0xD7, 0xD5, + 0xC7, 0xFF, 0xCF, 0xCC, 0xB9, 0xFF, 0xF4, 0xF4, 0xF3, 0xFF, 0xF5, 0xF5, 0xF4, 0xFF, 0xDC, 0xCD, + 0xAF, 0xFF, 0xCB, 0xA4, 0x64, 0xFF, 0xD7, 0xA9, 0x61, 0xFF, 0xDD, 0xAC, 0x62, 0xFF, 0xDE, 0xAC, + 0x62, 0xFF, 0xDE, 0xAC, 0x62, 0xFF, 0xDE, 0xAD, 0x65, 0xFF, 0xE2, 0xB8, 0x7A, 0xFF, 0xE8, 0xC8, + 0x98, 0xE8, 0xE4, 0xCE, 0xAB, 0x3A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE1, 0xC3, + 0x9A, 0x4F, 0xE5, 0xBE, 0x89, 0xF0, 0xDE, 0xB0, 0x73, 0xFF, 0xDC, 0xA9, 0x65, 0xFF, 0xDD, 0xAA, + 0x63, 0xFF, 0xDE, 0xAC, 0x64, 0xFF, 0xDF, 0xAE, 0x65, 0xFF, 0xDF, 0xAE, 0x65, 0xFF, 0xE0, 0xAF, + 0x64, 0xFF, 0xE2, 0xB6, 0x71, 0xFF, 0xEA, 0xCA, 0x96, 0xFF, 0xEB, 0xCB, 0x99, 0xFF, 0xEB, 0xCB, + 0x99, 0xFF, 0xEB, 0xCB, 0x99, 0xFF, 0xEB, 0xCB, 0x99, 0xFF, 0xEB, 0xCB, 0x99, 0xFF, 0xEB, 0xCB, + 0x99, 0xFF, 0xEB, 0xCB, 0x99, 0xFF, 0xEB, 0xCB, 0x99, 0xFF, 0xEB, 0xCB, 0x99, 0xFF, 0xEB, 0xCB, + 0x99, 0xFF, 0xEB, 0xCB, 0x99, 0xFF, 0xEB, 0xCB, 0x99, 0xFF, 0xEB, 0xCB, 0x99, 0xFF, 0xEB, 0xCB, + 0x99, 0xFF, 0xEB, 0xCB, 0x99, 0xFF, 0xEA, 0xCB, 0x99, 0xFF, 0xEA, 0xCB, 0x99, 0xFF, 0xE7, 0xC9, + 0x98, 0xFF, 0xE2, 0xC8, 0x9B, 0xFF, 0xE9, 0xDD, 0xC8, 0xFF, 0xF5, 0xF5, 0xF4, 0xFF, 0xF7, 0xF7, + 0xF8, 0xFF, 0xF6, 0xF6, 0xF6, 0xFF, 0xF6, 0xF6, 0xF6, 0xFF, 0xF6, 0xF6, 0xF7, 0xFF, 0xF3, 0xF2, + 0xF0, 0xFF, 0xF5, 0xF4, 0xF2, 0xFF, 0xF7, 0xF7, 0xF6, 0xFF, 0xF6, 0xF6, 0xF6, 0xFF, 0xF6, 0xF6, + 0xF6, 0xFF, 0xF6, 0xF6, 0xF6, 0xFF, 0xF6, 0xF6, 0xF7, 0xFF, 0xF7, 0xF7, 0xF7, 0xFF, 0xF1, 0xF0, + 0xED, 0xFF, 0xF5, 0xF5, 0xF3, 0xFF, 0xF9, 0xF9, 0xF9, 0xFF, 0xE4, 0xD7, 0xBE, 0xFF, 0xCB, 0xA7, + 0x68, 0xFF, 0xD7, 0xAA, 0x63, 0xFF, 0xDE, 0xAE, 0x65, 0xFF, 0xE0, 0xAF, 0x65, 0xFF, 0xE0, 0xAF, + 0x65, 0xFF, 0xE0, 0xAF, 0x67, 0xFF, 0xE2, 0xB4, 0x71, 0xFF, 0xE8, 0xC3, 0x8C, 0xFF, 0xEA, 0xCE, + 0xA3, 0x9B, 0xCB, 0xC7, 0xBD, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xCA, + 0xAD, 0x0D, 0xE8, 0xC5, 0x95, 0xA7, 0xE5, 0xBB, 0x84, 0xFF, 0xE0, 0xAF, 0x6F, 0xFF, 0xDF, 0xAD, + 0x67, 0xFF, 0xE0, 0xAF, 0x67, 0xFF, 0xE1, 0xB1, 0x68, 0xFF, 0xE1, 0xB2, 0x69, 0xFF, 0xE2, 0xB2, + 0x68, 0xFF, 0xE4, 0xB7, 0x72, 0xFF, 0xEB, 0xCC, 0x99, 0xFF, 0xEC, 0xCE, 0x9F, 0xFF, 0xEC, 0xCE, + 0x9E, 0xFF, 0xEC, 0xCE, 0x9E, 0xFF, 0xEC, 0xCE, 0x9E, 0xFF, 0xEC, 0xCE, 0x9E, 0xFF, 0xEC, 0xCE, + 0x9E, 0xFF, 0xEC, 0xCE, 0x9E, 0xFF, 0xEC, 0xCE, 0x9E, 0xFF, 0xEC, 0xCE, 0x9E, 0xFF, 0xEC, 0xCE, + 0x9E, 0xFF, 0xEC, 0xCE, 0x9E, 0xFF, 0xEC, 0xCE, 0x9E, 0xFF, 0xEC, 0xCE, 0x9E, 0xFF, 0xEC, 0xCE, + 0x9E, 0xFF, 0xEC, 0xCE, 0x9E, 0xFF, 0xEC, 0xCE, 0x9E, 0xFF, 0xEC, 0xCE, 0x9E, 0xFF, 0xEC, 0xCE, + 0x9E, 0xFF, 0xEA, 0xCD, 0x9D, 0xFF, 0xE4, 0xCB, 0x9E, 0xFF, 0xE9, 0xDC, 0xC3, 0xFF, 0xF6, 0xF4, + 0xF1, 0xFF, 0xF9, 0xF9, 0xFA, 0xFF, 0xF9, 0xF9, 0xFA, 0xFF, 0xF2, 0xEF, 0xE8, 0xFF, 0xE0, 0xD2, + 0xB6, 0xFF, 0xE6, 0xDA, 0xC2, 0xFF, 0xF7, 0xF6, 0xF3, 0xFF, 0xF9, 0xF9, 0xF9, 0xFF, 0xF8, 0xF8, + 0xF8, 0xFF, 0xF9, 0xF8, 0xF8, 0xFF, 0xEF, 0xEF, 0xE9, 0xFF, 0xF5, 0xF5, 0xF3, 0xFF, 0xF9, 0xF9, + 0xFA, 0xFF, 0xFA, 0xFA, 0xFA, 0xFF, 0xEE, 0xE8, 0xD9, 0xFF, 0xD5, 0xB8, 0x85, 0xFF, 0xD8, 0xAC, + 0x66, 0xFF, 0xE0, 0xB2, 0x69, 0xFF, 0xE2, 0xB3, 0x69, 0xFF, 0xE2, 0xB3, 0x69, 0xFF, 0xE2, 0xB3, + 0x69, 0xFF, 0xE3, 0xB5, 0x6E, 0xFF, 0xE7, 0xBF, 0x82, 0xFF, 0xED, 0xCD, 0x9C, 0xE3, 0xE9, 0xD2, + 0xAE, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xE6, 0xCB, 0xA1, 0x3C, 0xEA, 0xC4, 0x91, 0xE3, 0xE5, 0xBA, 0x7F, 0xFF, 0xE2, 0xB2, + 0x6E, 0xFF, 0xE2, 0xB1, 0x6B, 0xFF, 0xE3, 0xB3, 0x6B, 0xFF, 0xE4, 0xB5, 0x6C, 0xFF, 0xE4, 0xB5, + 0x6C, 0xFF, 0xE6, 0xB8, 0x71, 0xFF, 0xED, 0xCD, 0x98, 0xFF, 0xEF, 0xD2, 0xA4, 0xFF, 0xEF, 0xD2, + 0xA3, 0xFF, 0xEF, 0xD2, 0xA3, 0xFF, 0xEF, 0xD2, 0xA3, 0xFF, 0xEF, 0xD2, 0xA3, 0xFF, 0xEF, 0xD2, + 0xA3, 0xFF, 0xEF, 0xD2, 0xA3, 0xFF, 0xEF, 0xD2, 0xA3, 0xFF, 0xEF, 0xD2, 0xA3, 0xFF, 0xEF, 0xD2, + 0xA3, 0xFF, 0xEF, 0xD2, 0xA3, 0xFF, 0xEF, 0xD2, 0xA3, 0xFF, 0xEF, 0xD2, 0xA3, 0xFF, 0xEF, 0xD2, + 0xA3, 0xFF, 0xEF, 0xD2, 0xA3, 0xFF, 0xEF, 0xD2, 0xA3, 0xFF, 0xEF, 0xD2, 0xA3, 0xFF, 0xEF, 0xD2, + 0xA3, 0xFF, 0xEE, 0xD2, 0xA3, 0xFF, 0xEC, 0xD0, 0xA2, 0xFF, 0xE8, 0xCE, 0xA1, 0xFF, 0xEA, 0xD8, + 0xB7, 0xFF, 0xF3, 0xEC, 0xDF, 0xFF, 0xF2, 0xEB, 0xDE, 0xFF, 0xE5, 0xD2, 0xAF, 0xFF, 0xE3, 0xCB, + 0x9F, 0xFF, 0xE4, 0xCC, 0xA1, 0xFF, 0xEB, 0xDC, 0xBF, 0xFF, 0xF8, 0xF6, 0xF1, 0xFF, 0xFB, 0xFB, + 0xFC, 0xFF, 0xF0, 0xEF, 0xE9, 0xFF, 0xCF, 0xCB, 0xB6, 0xFF, 0xF1, 0xF0, 0xEB, 0xFF, 0xFB, 0xFB, + 0xFC, 0xFF, 0xF1, 0xEB, 0xDE, 0xFF, 0xE1, 0xCD, 0xA7, 0xFF, 0xDF, 0xB9, 0x7B, 0xFF, 0xE2, 0xB4, + 0x6C, 0xFF, 0xE4, 0xB6, 0x6D, 0xFF, 0xE5, 0xB6, 0x6D, 0xFF, 0xE5, 0xB6, 0x6D, 0xFF, 0xE5, 0xB7, + 0x6F, 0xFF, 0xE7, 0xBD, 0x7C, 0xFF, 0xEC, 0xCB, 0x95, 0xFD, 0xED, 0xD2, 0xA7, 0x84, 0xD3, 0xD3, + 0xD4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xC9, 0xD6, 0xE3, 0x02, 0xEB, 0xCC, 0x9C, 0x7C, 0xEA, 0xC4, 0x8E, 0xFC, 0xE6, 0xBA, + 0x7C, 0xFF, 0xE5, 0xB5, 0x70, 0xFF, 0xE5, 0xB6, 0x6F, 0xFF, 0xE6, 0xB7, 0x70, 0xFF, 0xE6, 0xB8, + 0x70, 0xFF, 0xE7, 0xB9, 0x70, 0xFF, 0xED, 0xCA, 0x91, 0xFF, 0xF1, 0xD5, 0xA8, 0xFF, 0xF1, 0xD5, + 0xA7, 0xFF, 0xF1, 0xD5, 0xA7, 0xFF, 0xF1, 0xD5, 0xA7, 0xFF, 0xF1, 0xD5, 0xA7, 0xFF, 0xF1, 0xD5, + 0xA7, 0xFF, 0xF1, 0xD5, 0xA7, 0xFF, 0xF1, 0xD5, 0xA7, 0xFF, 0xF1, 0xD5, 0xA7, 0xFF, 0xF1, 0xD5, + 0xA7, 0xFF, 0xF1, 0xD5, 0xA7, 0xFF, 0xF1, 0xD5, 0xA7, 0xFF, 0xF1, 0xD5, 0xA7, 0xFF, 0xF1, 0xD5, + 0xA7, 0xFF, 0xF1, 0xD5, 0xA7, 0xFF, 0xF1, 0xD5, 0xA7, 0xFF, 0xF1, 0xD5, 0xA7, 0xFF, 0xF1, 0xD5, + 0xA7, 0xFF, 0xF1, 0xD5, 0xA7, 0xFF, 0xF0, 0xD5, 0xA7, 0xFF, 0xEF, 0xD4, 0xA7, 0xFF, 0xED, 0xD2, + 0xA5, 0xFF, 0xEB, 0xD3, 0xA9, 0xFF, 0xEB, 0xD3, 0xA9, 0xFF, 0xEC, 0xD2, 0xA5, 0xFF, 0xEF, 0xD4, + 0xA7, 0xFF, 0xEE, 0xD4, 0xA7, 0xFF, 0xEA, 0xD1, 0xA5, 0xFF, 0xEB, 0xDB, 0xBB, 0xFF, 0xF8, 0xF4, + 0xED, 0xFF, 0xF8, 0xF8, 0xF6, 0xFF, 0xF1, 0xF0, 0xE9, 0xFF, 0xFC, 0xFC, 0xFB, 0xFF, 0xF4, 0xEF, + 0xE3, 0xFF, 0xE4, 0xD2, 0xAF, 0xFF, 0xE7, 0xCD, 0x9F, 0xFF, 0xE6, 0xBC, 0x78, 0xFF, 0xE6, 0xB9, + 0x6F, 0xFF, 0xE7, 0xB9, 0x70, 0xFF, 0xE7, 0xB9, 0x70, 0xFF, 0xE7, 0xB9, 0x71, 0xFF, 0xE8, 0xBD, + 0x79, 0xFF, 0xEC, 0xC9, 0x90, 0xFF, 0xEF, 0xD3, 0xA3, 0xC1, 0xEA, 0xD6, 0xB5, 0x1D, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEB, 0xD4, 0xAF, 0x15, 0xED, 0xCC, 0x9A, 0xB3, 0xEB, 0xC5, + 0x8D, 0xFF, 0xE8, 0xBB, 0x7B, 0xFF, 0xE7, 0xB8, 0x73, 0xFF, 0xE8, 0xB9, 0x72, 0xFF, 0xE8, 0xBA, + 0x73, 0xFF, 0xE9, 0xBB, 0x72, 0xFF, 0xEC, 0xC5, 0x86, 0xFF, 0xF1, 0xD7, 0xAA, 0xFF, 0xF2, 0xD7, + 0xAC, 0xFF, 0xF2, 0xD7, 0xAB, 0xFF, 0xF2, 0xD7, 0xAB, 0xFF, 0xF2, 0xD7, 0xAB, 0xFF, 0xF2, 0xD7, + 0xAB, 0xFF, 0xF2, 0xD7, 0xAB, 0xFF, 0xF2, 0xD7, 0xAB, 0xFF, 0xF2, 0xD7, 0xAB, 0xFF, 0xF2, 0xD7, + 0xAB, 0xFF, 0xF2, 0xD7, 0xAB, 0xFF, 0xF2, 0xD7, 0xAB, 0xFF, 0xF2, 0xD7, 0xAB, 0xFF, 0xF2, 0xD7, + 0xAB, 0xFF, 0xF2, 0xD7, 0xAB, 0xFF, 0xF2, 0xD7, 0xAB, 0xFF, 0xF2, 0xD7, 0xAB, 0xFF, 0xF2, 0xD7, + 0xAB, 0xFF, 0xF2, 0xD7, 0xAB, 0xFF, 0xF2, 0xD7, 0xAB, 0xFF, 0xF2, 0xD7, 0xAB, 0xFF, 0xF2, 0xD7, + 0xAB, 0xFF, 0xF1, 0xD7, 0xAB, 0xFF, 0xF1, 0xD7, 0xAB, 0xFF, 0xF2, 0xD7, 0xAB, 0xFF, 0xF2, 0xD7, + 0xAB, 0xFF, 0xF2, 0xD7, 0xAB, 0xFF, 0xF1, 0xD7, 0xAB, 0xFF, 0xED, 0xD4, 0xA9, 0xFF, 0xEC, 0xDA, + 0xB8, 0xFF, 0xF7, 0xF2, 0xE8, 0xFF, 0xFE, 0xFE, 0xFF, 0xFF, 0xF6, 0xF2, 0xE9, 0xFF, 0xE7, 0xD6, + 0xB4, 0xFF, 0xEB, 0xD4, 0xAA, 0xFF, 0xED, 0xCE, 0x98, 0xFF, 0xE9, 0xBD, 0x74, 0xFF, 0xE9, 0xBC, + 0x73, 0xFF, 0xE9, 0xBC, 0x73, 0xFF, 0xE9, 0xBC, 0x74, 0xFF, 0xEA, 0xBE, 0x79, 0xFF, 0xEC, 0xC8, + 0x8C, 0xFF, 0xF0, 0xD2, 0xA0, 0xE6, 0xEE, 0xD6, 0xB0, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEC, 0xD2, 0xA8, 0x35, 0xEF, 0xCD, + 0x99, 0xD7, 0xED, 0xC7, 0x8D, 0xFF, 0xEA, 0xBE, 0x7D, 0xFF, 0xEA, 0xBC, 0x76, 0xFF, 0xEA, 0xBC, + 0x76, 0xFF, 0xEA, 0xBD, 0x76, 0xFF, 0xEC, 0xC0, 0x7B, 0xFF, 0xF2, 0xD5, 0xA4, 0xFF, 0xF3, 0xDA, + 0xB0, 0xFF, 0xF3, 0xDA, 0xAF, 0xFF, 0xF3, 0xDA, 0xAF, 0xFF, 0xF3, 0xDA, 0xAF, 0xFF, 0xF3, 0xDA, + 0xAF, 0xFF, 0xF3, 0xDA, 0xAF, 0xFF, 0xF3, 0xDA, 0xAF, 0xFF, 0xF3, 0xDA, 0xAF, 0xFF, 0xF3, 0xDA, + 0xAF, 0xFF, 0xF3, 0xDA, 0xAF, 0xFF, 0xF3, 0xDA, 0xAF, 0xFF, 0xF3, 0xDA, 0xAF, 0xFF, 0xF3, 0xDA, + 0xAF, 0xFF, 0xF3, 0xDA, 0xAF, 0xFF, 0xF3, 0xDA, 0xAF, 0xFF, 0xF3, 0xDA, 0xAF, 0xFF, 0xF3, 0xDA, + 0xAF, 0xFF, 0xF3, 0xDA, 0xAF, 0xFF, 0xF3, 0xDA, 0xAF, 0xFF, 0xF3, 0xDA, 0xAF, 0xFF, 0xF3, 0xDA, + 0xAF, 0xFF, 0xF3, 0xDA, 0xAF, 0xFF, 0xF3, 0xDA, 0xAF, 0xFF, 0xF3, 0xDA, 0xAF, 0xFF, 0xF3, 0xDA, + 0xAF, 0xFF, 0xF3, 0xDA, 0xAF, 0xFF, 0xF3, 0xDA, 0xAF, 0xFF, 0xF2, 0xDA, 0xAF, 0xFF, 0xEF, 0xD7, + 0xAE, 0xFF, 0xEE, 0xDB, 0xB8, 0xFF, 0xF6, 0xEC, 0xD9, 0xFF, 0xED, 0xDD, 0xBD, 0xFF, 0xED, 0xD6, + 0xAD, 0xFF, 0xF1, 0xD9, 0xAE, 0xFF, 0xED, 0xC9, 0x89, 0xFF, 0xEB, 0xBE, 0x75, 0xFF, 0xEB, 0xBF, + 0x77, 0xFF, 0xEB, 0xBF, 0x77, 0xFF, 0xEC, 0xC1, 0x7B, 0xFF, 0xEE, 0xC9, 0x8A, 0xFF, 0xF1, 0xD2, + 0x9E, 0xF6, 0xF0, 0xD7, 0xAD, 0x72, 0xDE, 0xDF, 0xE4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xD3, + 0xA6, 0x50, 0xF1, 0xCF, 0x99, 0xE4, 0xEE, 0xC9, 0x8E, 0xFF, 0xEC, 0xC1, 0x7F, 0xFF, 0xEC, 0xBF, + 0x79, 0xFF, 0xEC, 0xC0, 0x79, 0xFF, 0xEC, 0xC0, 0x78, 0xFF, 0xF1, 0xCD, 0x91, 0xFF, 0xF5, 0xDC, + 0xB3, 0xFF, 0xF5, 0xDD, 0xB4, 0xFF, 0xF5, 0xDD, 0xB3, 0xFF, 0xF5, 0xDD, 0xB3, 0xFF, 0xF5, 0xDD, + 0xB3, 0xFF, 0xF5, 0xDD, 0xB3, 0xFF, 0xF5, 0xDD, 0xB3, 0xFF, 0xF5, 0xDD, 0xB3, 0xFF, 0xF5, 0xDD, + 0xB3, 0xFF, 0xF5, 0xDD, 0xB3, 0xFF, 0xF5, 0xDD, 0xB3, 0xFF, 0xF5, 0xDD, 0xB3, 0xFF, 0xF5, 0xDD, + 0xB3, 0xFF, 0xF5, 0xDD, 0xB3, 0xFF, 0xF5, 0xDD, 0xB3, 0xFF, 0xF5, 0xDD, 0xB3, 0xFF, 0xF5, 0xDD, + 0xB3, 0xFF, 0xF5, 0xDD, 0xB3, 0xFF, 0xF5, 0xDD, 0xB3, 0xFF, 0xF5, 0xDD, 0xB3, 0xFF, 0xF5, 0xDD, + 0xB3, 0xFF, 0xF5, 0xDD, 0xB3, 0xFF, 0xF5, 0xDD, 0xB3, 0xFF, 0xF5, 0xDD, 0xB3, 0xFF, 0xF5, 0xDD, + 0xB3, 0xFF, 0xF5, 0xDD, 0xB3, 0xFF, 0xF5, 0xDD, 0xB3, 0xFF, 0xF5, 0xDD, 0xB3, 0xFF, 0xF4, 0xDC, + 0xB3, 0xFF, 0xF3, 0xDB, 0xB3, 0xFF, 0xF2, 0xDB, 0xB3, 0xFF, 0xF2, 0xDB, 0xB3, 0xFF, 0xF3, 0xDC, + 0xB4, 0xFF, 0xF2, 0xD5, 0xA3, 0xFF, 0xED, 0xC3, 0x7D, 0xFF, 0xED, 0xC1, 0x79, 0xFF, 0xED, 0xC1, + 0x7A, 0xFF, 0xED, 0xC3, 0x7D, 0xFF, 0xEF, 0xCA, 0x8B, 0xFF, 0xF2, 0xD3, 0x9E, 0xFC, 0xF3, 0xD8, + 0xAA, 0x92, 0xE7, 0xDA, 0xC3, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF9, 0xFF, + 0xFF, 0x01, 0xF2, 0xD4, 0xA4, 0x5E, 0xF2, 0xD1, 0x9C, 0xEA, 0xF0, 0xCB, 0x90, 0xFF, 0xEE, 0xC3, + 0x81, 0xFF, 0xEE, 0xC2, 0x7D, 0xFF, 0xEE, 0xC2, 0x7C, 0xFF, 0xEF, 0xC5, 0x80, 0xFF, 0xF5, 0xD7, + 0xA7, 0xFF, 0xF6, 0xE0, 0xB8, 0xFF, 0xF6, 0xDF, 0xB7, 0xFF, 0xF6, 0xDF, 0xB7, 0xFF, 0xF6, 0xDF, + 0xB7, 0xFF, 0xF6, 0xDF, 0xB7, 0xFF, 0xF6, 0xDF, 0xB7, 0xFF, 0xF6, 0xDF, 0xB7, 0xFF, 0xF6, 0xDF, + 0xB7, 0xFF, 0xF6, 0xDF, 0xB7, 0xFF, 0xF6, 0xDF, 0xB7, 0xFF, 0xF6, 0xDF, 0xB7, 0xFF, 0xF6, 0xDF, + 0xB7, 0xFF, 0xF6, 0xDF, 0xB7, 0xFF, 0xF6, 0xDF, 0xB7, 0xFF, 0xF6, 0xDF, 0xB7, 0xFF, 0xF6, 0xDF, + 0xB7, 0xFF, 0xF6, 0xDF, 0xB7, 0xFF, 0xF6, 0xDF, 0xB7, 0xFF, 0xF6, 0xDF, 0xB7, 0xFF, 0xF6, 0xDF, + 0xB7, 0xFF, 0xF6, 0xDF, 0xB7, 0xFF, 0xF6, 0xDF, 0xB7, 0xFF, 0xF6, 0xDF, 0xB7, 0xFF, 0xF6, 0xDF, + 0xB7, 0xFF, 0xF6, 0xDF, 0xB7, 0xFF, 0xF6, 0xDF, 0xB7, 0xFF, 0xF6, 0xDF, 0xB7, 0xFF, 0xF6, 0xDF, + 0xB7, 0xFF, 0xF6, 0xDF, 0xB7, 0xFF, 0xF6, 0xDF, 0xB7, 0xFF, 0xF6, 0xDF, 0xB8, 0xFF, 0xF6, 0xDE, + 0xB3, 0xFF, 0xF1, 0xCC, 0x8D, 0xFF, 0xEF, 0xC4, 0x7C, 0xFF, 0xEF, 0xC4, 0x7D, 0xFF, 0xEF, 0xC7, + 0x80, 0xFF, 0xF1, 0xCC, 0x8D, 0xFF, 0xF3, 0xD4, 0x9F, 0xFF, 0xF3, 0xD9, 0xA9, 0xA2, 0xEF, 0xDD, + 0xBE, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xE5, 0xE3, 0xDD, 0x03, 0xF2, 0xD6, 0xA7, 0x67, 0xF3, 0xD3, 0x9E, 0xEB, 0xF2, 0xCE, + 0x94, 0xFF, 0xF0, 0xC8, 0x86, 0xFF, 0xF0, 0xC5, 0x80, 0xFF, 0xF0, 0xC5, 0x7E, 0xFF, 0xF2, 0xCD, + 0x8D, 0xFF, 0xF6, 0xDE, 0xB4, 0xFF, 0xF7, 0xE2, 0xBC, 0xFF, 0xF7, 0xE2, 0xBB, 0xFF, 0xF7, 0xE2, + 0xBB, 0xFF, 0xF7, 0xE2, 0xBB, 0xFF, 0xF7, 0xE2, 0xBB, 0xFF, 0xF7, 0xE2, 0xBB, 0xFF, 0xF7, 0xE2, + 0xBB, 0xFF, 0xF7, 0xE2, 0xBB, 0xFF, 0xF7, 0xE2, 0xBB, 0xFF, 0xF7, 0xE2, 0xBB, 0xFF, 0xF7, 0xE2, + 0xBB, 0xFF, 0xF7, 0xE2, 0xBB, 0xFF, 0xF7, 0xE2, 0xBB, 0xFF, 0xF7, 0xE2, 0xBB, 0xFF, 0xF7, 0xE2, + 0xBB, 0xFF, 0xF7, 0xE2, 0xBB, 0xFF, 0xF7, 0xE2, 0xBB, 0xFF, 0xF7, 0xE2, 0xBB, 0xFF, 0xF7, 0xE2, + 0xBB, 0xFF, 0xF7, 0xE2, 0xBB, 0xFF, 0xF7, 0xE2, 0xBB, 0xFF, 0xF7, 0xE2, 0xBB, 0xFF, 0xF7, 0xE2, + 0xBB, 0xFF, 0xF7, 0xE2, 0xBB, 0xFF, 0xF7, 0xE2, 0xBB, 0xFF, 0xF7, 0xE2, 0xBB, 0xFF, 0xF7, 0xE2, + 0xBB, 0xFF, 0xF7, 0xE2, 0xBB, 0xFF, 0xF7, 0xE2, 0xBB, 0xFF, 0xF7, 0xE2, 0xBB, 0xFF, 0xF4, 0xD5, + 0x9D, 0xFF, 0xF1, 0xC8, 0x80, 0xFF, 0xF0, 0xC8, 0x80, 0xFF, 0xF1, 0xC9, 0x84, 0xFF, 0xF3, 0xCF, + 0x91, 0xFF, 0xF5, 0xD6, 0xA1, 0xFE, 0xF5, 0xDA, 0xAB, 0xA9, 0xEF, 0xDE, 0xBF, 0x1C, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE7, 0xE5, 0xE2, 0x03, 0xF4, 0xD8, 0xA8, 0x60, 0xF4, 0xD4, + 0xA0, 0xE4, 0xF4, 0xD1, 0x98, 0xFF, 0xF2, 0xCC, 0x8B, 0xFF, 0xF2, 0xC9, 0x84, 0xFF, 0xF2, 0xC8, + 0x82, 0xFF, 0xF4, 0xD3, 0x98, 0xFF, 0xF8, 0xE2, 0xBA, 0xFF, 0xF8, 0xE4, 0xBE, 0xFF, 0xF8, 0xE4, + 0xBE, 0xFF, 0xF8, 0xE4, 0xBE, 0xFF, 0xF8, 0xE4, 0xBE, 0xFF, 0xF8, 0xE4, 0xBE, 0xFF, 0xF8, 0xE4, + 0xBE, 0xFF, 0xF8, 0xE4, 0xBE, 0xFF, 0xF8, 0xE4, 0xBE, 0xFF, 0xF8, 0xE4, 0xBE, 0xFF, 0xF8, 0xE4, + 0xBE, 0xFF, 0xF8, 0xE4, 0xBE, 0xFF, 0xF8, 0xE4, 0xBE, 0xFF, 0xF8, 0xE4, 0xBE, 0xFF, 0xF8, 0xE4, + 0xBE, 0xFF, 0xF8, 0xE4, 0xBE, 0xFF, 0xF8, 0xE4, 0xBE, 0xFF, 0xF8, 0xE4, 0xBE, 0xFF, 0xF8, 0xE4, + 0xBE, 0xFF, 0xF8, 0xE4, 0xBE, 0xFF, 0xF8, 0xE4, 0xBE, 0xFF, 0xF8, 0xE4, 0xBE, 0xFF, 0xF8, 0xE4, + 0xBE, 0xFF, 0xF8, 0xE4, 0xBE, 0xFF, 0xF8, 0xE4, 0xBE, 0xFF, 0xF8, 0xE4, 0xBE, 0xFF, 0xF8, 0xE4, + 0xBE, 0xFF, 0xF8, 0xE4, 0xBE, 0xFF, 0xF8, 0xE4, 0xBE, 0xFF, 0xF6, 0xDA, 0xA8, 0xFF, 0xF3, 0xCB, + 0x86, 0xFF, 0xF2, 0xCA, 0x83, 0xFF, 0xF3, 0xCD, 0x89, 0xFF, 0xF4, 0xD2, 0x96, 0xFF, 0xF6, 0xD8, + 0xA3, 0xF9, 0xF6, 0xDB, 0xAC, 0x9E, 0xF1, 0xE0, 0xC1, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF4, 0xFA, 0xFF, 0x01, 0xF4, 0xDA, + 0xAD, 0x4E, 0xF6, 0xD7, 0xA2, 0xD3, 0xF5, 0xD4, 0x9D, 0xFF, 0xF4, 0xD0, 0x92, 0xFF, 0xF3, 0xCC, + 0x88, 0xFF, 0xF3, 0xCB, 0x85, 0xFF, 0xF5, 0xD5, 0x9D, 0xFF, 0xF9, 0xE4, 0xBC, 0xFF, 0xF9, 0xE6, + 0xC1, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, + 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, + 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, + 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, + 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, + 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, + 0xC0, 0xFF, 0xF9, 0xE5, 0xC1, 0xFF, 0xF7, 0xDC, 0xAC, 0xFF, 0xF4, 0xCE, 0x8B, 0xFF, 0xF3, 0xCC, + 0x87, 0xFF, 0xF4, 0xD0, 0x90, 0xFF, 0xF6, 0xD5, 0x9D, 0xFF, 0xF7, 0xDA, 0xA6, 0xF0, 0xF7, 0xDC, + 0xAF, 0x84, 0xF3, 0xE2, 0xC5, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xF4, 0xDB, 0xB1, 0x31, 0xF5, 0xD8, 0xA5, 0xAC, 0xF7, 0xD7, 0xA2, 0xFA, 0xF6, 0xD4, + 0x9B, 0xFF, 0xF5, 0xCF, 0x90, 0xFF, 0xF4, 0xCD, 0x8A, 0xFF, 0xF6, 0xD5, 0x9C, 0xFF, 0xFA, 0xE3, + 0xBC, 0xFF, 0xFA, 0xE7, 0xC4, 0xFF, 0xFA, 0xE6, 0xC3, 0xFF, 0xFA, 0xE6, 0xC3, 0xFF, 0xFA, 0xE6, + 0xC3, 0xFF, 0xFA, 0xE6, 0xC3, 0xFF, 0xFA, 0xE6, 0xC3, 0xFF, 0xFA, 0xE6, 0xC3, 0xFF, 0xFA, 0xE6, + 0xC3, 0xFF, 0xFA, 0xE6, 0xC3, 0xFF, 0xFA, 0xE6, 0xC3, 0xFF, 0xFA, 0xE6, 0xC3, 0xFF, 0xFA, 0xE6, + 0xC3, 0xFF, 0xFA, 0xE6, 0xC3, 0xFF, 0xFA, 0xE6, 0xC3, 0xFF, 0xFA, 0xE6, 0xC3, 0xFF, 0xFA, 0xE6, + 0xC3, 0xFF, 0xFA, 0xE6, 0xC3, 0xFF, 0xFA, 0xE6, 0xC3, 0xFF, 0xFA, 0xE6, 0xC3, 0xFF, 0xFA, 0xE6, + 0xC3, 0xFF, 0xFA, 0xE6, 0xC3, 0xFF, 0xFA, 0xE6, 0xC3, 0xFF, 0xFA, 0xE7, 0xC4, 0xFF, 0xFA, 0xE6, + 0xC1, 0xFF, 0xF8, 0xDC, 0xAA, 0xFF, 0xF5, 0xD0, 0x8E, 0xFF, 0xF5, 0xD0, 0x8D, 0xFF, 0xF6, 0xD5, + 0x98, 0xFF, 0xF7, 0xD9, 0xA3, 0xFF, 0xF8, 0xDC, 0xAA, 0xD7, 0xF8, 0xDE, 0xB1, 0x5E, 0xF5, 0xE9, + 0xD4, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEC, 0xD9, 0xBB, 0x12, 0xF5, 0xDA, 0xAA, 0x70, 0xF8, 0xD9, + 0xA4, 0xD8, 0xF8, 0xD8, 0xA1, 0xFF, 0xF7, 0xD5, 0x9A, 0xFF, 0xF6, 0xD1, 0x90, 0xFF, 0xF7, 0xD4, + 0x98, 0xFF, 0xF9, 0xE0, 0xB4, 0xFF, 0xFB, 0xE8, 0xC5, 0xFF, 0xFB, 0xE8, 0xC8, 0xFF, 0xFB, 0xE8, + 0xC8, 0xFF, 0xFB, 0xE8, 0xC7, 0xFF, 0xFB, 0xE8, 0xC7, 0xFF, 0xFB, 0xE8, 0xC7, 0xFF, 0xFB, 0xE8, + 0xC7, 0xFF, 0xFB, 0xE8, 0xC7, 0xFF, 0xFB, 0xE8, 0xC7, 0xFF, 0xFB, 0xE8, 0xC7, 0xFF, 0xFB, 0xE8, + 0xC7, 0xFF, 0xFB, 0xE8, 0xC7, 0xFF, 0xFB, 0xE8, 0xC7, 0xFF, 0xFB, 0xE8, 0xC7, 0xFF, 0xFB, 0xE8, + 0xC7, 0xFF, 0xFB, 0xE8, 0xC7, 0xFF, 0xFB, 0xE8, 0xC7, 0xFF, 0xFB, 0xE8, 0xC7, 0xFF, 0xFB, 0xE8, + 0xC7, 0xFF, 0xFB, 0xE8, 0xC8, 0xFF, 0xFB, 0xE8, 0xC8, 0xFF, 0xFA, 0xE4, 0xBD, 0xFF, 0xF8, 0xD9, + 0xA2, 0xFF, 0xF7, 0xD2, 0x91, 0xFF, 0xF7, 0xD5, 0x97, 0xFF, 0xF8, 0xD9, 0xA2, 0xFF, 0xF8, 0xDB, + 0xA7, 0xF0, 0xF8, 0xDD, 0xAE, 0x9E, 0xF7, 0xE2, 0xBC, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF2, 0xDB, + 0xB3, 0x2F, 0xF7, 0xDB, 0xA9, 0x99, 0xF9, 0xDB, 0xA6, 0xE9, 0xF9, 0xDA, 0xA3, 0xFF, 0xF8, 0xD6, + 0x9B, 0xFF, 0xF7, 0xD5, 0x98, 0xFF, 0xF9, 0xDB, 0xA7, 0xFF, 0xFB, 0xE4, 0xBD, 0xFF, 0xFC, 0xE9, + 0xC9, 0xFF, 0xFC, 0xEA, 0xCB, 0xFF, 0xFC, 0xEA, 0xCB, 0xFF, 0xFC, 0xEA, 0xCA, 0xFF, 0xFC, 0xEA, + 0xCA, 0xFF, 0xFC, 0xEA, 0xCA, 0xFF, 0xFC, 0xEA, 0xCA, 0xFF, 0xFC, 0xEA, 0xCA, 0xFF, 0xFC, 0xEA, + 0xCA, 0xFF, 0xFC, 0xEA, 0xCA, 0xFF, 0xFC, 0xEA, 0xCA, 0xFF, 0xFC, 0xEA, 0xCA, 0xFF, 0xFC, 0xEA, + 0xCA, 0xFF, 0xFC, 0xEA, 0xCA, 0xFF, 0xFC, 0xEA, 0xCB, 0xFF, 0xFC, 0xEA, 0xCB, 0xFF, 0xFC, 0xEA, + 0xCB, 0xFF, 0xFC, 0xE7, 0xC3, 0xFF, 0xFA, 0xE0, 0xB0, 0xFF, 0xF8, 0xD8, 0x9C, 0xFF, 0xF8, 0xD7, + 0x9A, 0xFF, 0xF9, 0xDA, 0xA3, 0xFF, 0xF9, 0xDD, 0xA9, 0xF8, 0xF9, 0xDE, 0xAC, 0xC0, 0xF9, 0xE0, + 0xB4, 0x52, 0xF7, 0xEB, 0xD7, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xED, 0xE0, 0xC9, 0x08, 0xF5, 0xDD, 0xB2, 0x42, 0xF8, 0xDC, 0xAA, 0x9E, 0xF9, 0xDC, + 0xA8, 0xE4, 0xF9, 0xDB, 0xA5, 0xFE, 0xF9, 0xD9, 0xA1, 0xFF, 0xF9, 0xDA, 0xA1, 0xFF, 0xFA, 0xDE, + 0xAC, 0xFF, 0xFB, 0xE4, 0xBB, 0xFF, 0xFC, 0xE9, 0xC7, 0xFF, 0xFC, 0xEA, 0xCC, 0xFF, 0xFC, 0xEB, + 0xCD, 0xFF, 0xFC, 0xEB, 0xCE, 0xFF, 0xFC, 0xEB, 0xCD, 0xFF, 0xFC, 0xEB, 0xCD, 0xFF, 0xFC, 0xEB, + 0xCD, 0xFF, 0xFC, 0xEB, 0xCD, 0xFF, 0xFC, 0xEB, 0xCD, 0xFF, 0xFC, 0xEB, 0xCD, 0xFF, 0xFC, 0xEB, + 0xCE, 0xFF, 0xFC, 0xEB, 0xCD, 0xFF, 0xFC, 0xEA, 0xCA, 0xFF, 0xFB, 0xE7, 0xC0, 0xFF, 0xFA, 0xE1, + 0xB2, 0xFF, 0xFA, 0xDC, 0xA5, 0xFF, 0xF9, 0xDA, 0xA1, 0xFF, 0xFA, 0xDC, 0xA5, 0xFF, 0xFA, 0xDD, + 0xAA, 0xF3, 0xF9, 0xDE, 0xAD, 0xBF, 0xF7, 0xDF, 0xB2, 0x67, 0xF2, 0xE1, 0xC0, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEF, 0xE2, 0xCD, 0x08, 0xF5, 0xDD, + 0xB4, 0x36, 0xF8, 0xDE, 0xAD, 0x82, 0xFA, 0xDE, 0xAC, 0xC6, 0xFA, 0xDD, 0xA9, 0xF0, 0xFA, 0xDC, + 0xA6, 0xFF, 0xFA, 0xDD, 0xA7, 0xFF, 0xFB, 0xDE, 0xAC, 0xFF, 0xFB, 0xE2, 0xB3, 0xFF, 0xFB, 0xE5, + 0xBB, 0xFF, 0xFB, 0xE7, 0xC1, 0xFF, 0xFC, 0xE9, 0xC5, 0xFF, 0xFC, 0xE9, 0xC9, 0xFF, 0xFC, 0xEA, + 0xCA, 0xFF, 0xFC, 0xEA, 0xC9, 0xFF, 0xFC, 0xE9, 0xC8, 0xFF, 0xFC, 0xE8, 0xC3, 0xFF, 0xFC, 0xE6, + 0xBE, 0xFF, 0xFB, 0xE3, 0xB7, 0xFF, 0xFB, 0xE0, 0xAF, 0xFF, 0xFB, 0xDE, 0xA9, 0xFF, 0xFA, 0xDD, + 0xA7, 0xFF, 0xFB, 0xDE, 0xA9, 0xF9, 0xFA, 0xDF, 0xAE, 0xD9, 0xFA, 0xDF, 0xAF, 0x9F, 0xF6, 0xDF, + 0xB5, 0x51, 0xF5, 0xE1, 0xBE, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFB, 0xEA, 0xCC, 0x18, 0xFB, 0xE3, 0xB8, 0x42, 0xFB, 0xE2, + 0xB5, 0x7B, 0xFB, 0xE0, 0xAF, 0xAF, 0xFB, 0xDF, 0xAC, 0xD3, 0xFB, 0xDF, 0xAB, 0xE8, 0xFB, 0xDF, + 0xAC, 0xF8, 0xFB, 0xDF, 0xAD, 0xFF, 0xFB, 0xE0, 0xAE, 0xFF, 0xFB, 0xE0, 0xAF, 0xFF, 0xFB, 0xE1, + 0xB0, 0xFF, 0xFB, 0xE0, 0xB0, 0xFF, 0xFB, 0xE0, 0xAF, 0xFF, 0xFB, 0xE0, 0xAE, 0xFF, 0xFB, 0xE0, + 0xAD, 0xFC, 0xFB, 0xDF, 0xAC, 0xEF, 0xFB, 0xDF, 0xAD, 0xDC, 0xFB, 0xE0, 0xAF, 0xC0, 0xFB, 0xE2, + 0xB5, 0x91, 0xFB, 0xE4, 0xB9, 0x58, 0xFB, 0xE6, 0xC0, 0x26, 0xF8, 0xF8, 0xF4, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFC, 0xEB, 0xCC, 0x07, 0xFC, 0xE4, 0xBB, 0x1F, 0xFB, 0xE2, 0xB4, 0x37, 0xFB, 0xE0, + 0xAE, 0x50, 0xFB, 0xE0, 0xAF, 0x69, 0xFB, 0xE1, 0xB0, 0x7B, 0xFB, 0xE1, 0xAF, 0x85, 0xFB, 0xE1, + 0xB1, 0x8B, 0xFC, 0xE1, 0xB0, 0x88, 0xFB, 0xE1, 0xB0, 0x7F, 0xFB, 0xE1, 0xB0, 0x71, 0xFB, 0xE0, + 0xAF, 0x5A, 0xFB, 0xE2, 0xB3, 0x41, 0xFC, 0xE4, 0xBA, 0x29, 0xFC, 0xE8, 0xC4, 0x10, 0xFF, 0xFF, + 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF6, 0xE8, 0x02, 0xFE, 0xED, + 0xCE, 0x03, 0xFD, 0xF2, 0xD9, 0x02, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, + 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, + 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, + 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xFE, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, + 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0xFF, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x00, + 0x00, 0x00, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, + 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, + 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, + 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0xF8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, + 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, + 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, + 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xF8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, + 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, + 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0xFE, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, + 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0xFF, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0x00, + 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x00, + 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, + 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xFE, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x28, 0x00, + 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x44, 0x0C, 0x01, 0x82, 0x44, 0x0C, 0x01, 0x82, 0x44, + 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x03, 0x82, 0x44, 0x0C, 0x03, 0x82, 0x44, + 0x0C, 0x04, 0x82, 0x44, 0x0C, 0x05, 0x82, 0x44, 0x0C, 0x05, 0x82, 0x44, 0x0C, 0x06, 0x82, 0x44, + 0x0C, 0x07, 0x82, 0x44, 0x0C, 0x08, 0x82, 0x44, 0x0C, 0x09, 0x82, 0x44, 0x0C, 0x09, 0x82, 0x44, + 0x0C, 0x0A, 0x82, 0x44, 0x0C, 0x0A, 0x82, 0x44, 0x0C, 0x0B, 0x82, 0x44, 0x0C, 0x0B, 0x82, 0x44, + 0x0C, 0x0B, 0x82, 0x44, 0x0C, 0x0B, 0x82, 0x44, 0x0C, 0x0B, 0x82, 0x44, 0x0C, 0x0B, 0x82, 0x44, + 0x0C, 0x0B, 0x82, 0x44, 0x0C, 0x0B, 0x82, 0x44, 0x0C, 0x0B, 0x82, 0x44, 0x0C, 0x0B, 0x82, 0x44, + 0x0C, 0x0B, 0x82, 0x44, 0x0C, 0x0A, 0x82, 0x44, 0x0C, 0x0A, 0x82, 0x44, 0x0C, 0x09, 0x82, 0x44, + 0x0C, 0x09, 0x82, 0x44, 0x0C, 0x08, 0x82, 0x44, 0x0C, 0x07, 0x82, 0x44, 0x0C, 0x07, 0x82, 0x44, + 0x0C, 0x06, 0x82, 0x44, 0x0C, 0x05, 0x82, 0x44, 0x0C, 0x04, 0x82, 0x44, 0x0C, 0x03, 0x82, 0x44, + 0x0C, 0x03, 0x82, 0x44, 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x01, 0x82, 0x44, + 0x0C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x44, + 0x0C, 0x01, 0x82, 0x44, 0x0C, 0x01, 0x82, 0x44, 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x03, 0x82, 0x44, + 0x0C, 0x05, 0x82, 0x44, 0x0C, 0x06, 0x82, 0x44, 0x0C, 0x07, 0x82, 0x44, 0x0C, 0x09, 0x82, 0x44, + 0x0C, 0x0B, 0x82, 0x44, 0x0C, 0x0C, 0x82, 0x44, 0x0C, 0x0D, 0x82, 0x44, 0x0C, 0x0F, 0x82, 0x44, + 0x0C, 0x10, 0x82, 0x44, 0x0C, 0x12, 0x82, 0x44, 0x0C, 0x13, 0x82, 0x44, 0x0C, 0x14, 0x82, 0x44, + 0x0C, 0x15, 0x82, 0x44, 0x0C, 0x16, 0x82, 0x44, 0x0C, 0x17, 0x82, 0x44, 0x0C, 0x17, 0x82, 0x44, + 0x0C, 0x18, 0x82, 0x44, 0x0C, 0x18, 0x82, 0x44, 0x0C, 0x19, 0x82, 0x44, 0x0C, 0x19, 0x82, 0x44, + 0x0C, 0x19, 0x82, 0x44, 0x0C, 0x18, 0x82, 0x44, 0x0C, 0x18, 0x82, 0x44, 0x0C, 0x17, 0x82, 0x44, + 0x0C, 0x17, 0x82, 0x44, 0x0C, 0x16, 0x82, 0x44, 0x0C, 0x15, 0x82, 0x44, 0x0C, 0x14, 0x82, 0x44, + 0x0C, 0x13, 0x82, 0x44, 0x0C, 0x12, 0x82, 0x44, 0x0C, 0x10, 0x82, 0x44, 0x0C, 0x0F, 0x82, 0x44, + 0x0C, 0x0E, 0x82, 0x44, 0x0C, 0x0C, 0x82, 0x44, 0x0C, 0x0B, 0x82, 0x44, 0x0C, 0x09, 0x82, 0x44, + 0x0C, 0x08, 0x82, 0x44, 0x0C, 0x06, 0x82, 0x44, 0x0C, 0x05, 0x82, 0x44, 0x0C, 0x03, 0x82, 0x44, + 0x0C, 0x03, 0x82, 0x44, 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x44, 0x0C, 0x01, 0x82, 0x44, 0x0C, 0x01, 0x82, 0x44, + 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x04, 0x82, 0x44, 0x0C, 0x06, 0x82, 0x44, 0x0C, 0x09, 0x82, 0x44, + 0x0C, 0x0B, 0x82, 0x44, 0x0C, 0x0E, 0x82, 0x44, 0x0C, 0x11, 0x82, 0x44, 0x0C, 0x14, 0x82, 0x44, + 0x0C, 0x17, 0x82, 0x44, 0x0C, 0x1A, 0x82, 0x44, 0x0C, 0x1C, 0x82, 0x44, 0x0C, 0x1F, 0x82, 0x44, + 0x0C, 0x22, 0x82, 0x44, 0x0C, 0x24, 0x82, 0x44, 0x0C, 0x25, 0x82, 0x44, 0x0C, 0x28, 0x82, 0x44, + 0x0C, 0x29, 0x82, 0x44, 0x0C, 0x2A, 0x82, 0x44, 0x0C, 0x2B, 0x82, 0x44, 0x0C, 0x2C, 0x82, 0x44, + 0x0C, 0x2E, 0x82, 0x44, 0x0C, 0x2E, 0x82, 0x44, 0x0C, 0x2E, 0x82, 0x44, 0x0C, 0x2E, 0x82, 0x44, + 0x0C, 0x2E, 0x82, 0x44, 0x0C, 0x2E, 0x82, 0x44, 0x0C, 0x2E, 0x82, 0x44, 0x0C, 0x2D, 0x82, 0x44, + 0x0C, 0x2C, 0x82, 0x44, 0x0C, 0x2B, 0x82, 0x44, 0x0C, 0x29, 0x82, 0x44, 0x0C, 0x28, 0x82, 0x44, + 0x0C, 0x26, 0x82, 0x44, 0x0C, 0x24, 0x82, 0x44, 0x0C, 0x22, 0x82, 0x44, 0x0C, 0x20, 0x82, 0x44, + 0x0C, 0x1D, 0x82, 0x44, 0x0C, 0x1B, 0x82, 0x44, 0x0C, 0x17, 0x82, 0x44, 0x0C, 0x14, 0x82, 0x44, + 0x0C, 0x12, 0x82, 0x44, 0x0C, 0x0F, 0x82, 0x44, 0x0C, 0x0C, 0x82, 0x44, 0x0C, 0x09, 0x82, 0x44, + 0x0C, 0x07, 0x82, 0x44, 0x0C, 0x05, 0x82, 0x44, 0x0C, 0x03, 0x82, 0x44, 0x0C, 0x01, 0x82, 0x44, + 0x0C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x82, 0x44, 0x0C, 0x01, 0x82, 0x44, 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x03, 0x82, 0x44, + 0x0C, 0x06, 0x82, 0x44, 0x0C, 0x0A, 0x82, 0x44, 0x0C, 0x0E, 0x82, 0x44, 0x0C, 0x13, 0x82, 0x44, + 0x0C, 0x18, 0x82, 0x44, 0x0C, 0x1D, 0x82, 0x44, 0x0C, 0x22, 0x82, 0x44, 0x0C, 0x27, 0x82, 0x44, + 0x0C, 0x2C, 0x82, 0x44, 0x0C, 0x30, 0x82, 0x44, 0x0C, 0x34, 0x82, 0x44, 0x0C, 0x37, 0x82, 0x44, + 0x0C, 0x3A, 0x82, 0x44, 0x0C, 0x3D, 0x82, 0x44, 0x0C, 0x40, 0x82, 0x44, 0x0C, 0x42, 0x82, 0x44, + 0x0C, 0x44, 0x82, 0x44, 0x0C, 0x46, 0x82, 0x44, 0x0C, 0x47, 0x82, 0x44, 0x0C, 0x48, 0x82, 0x44, + 0x0C, 0x4A, 0x82, 0x44, 0x0C, 0x4A, 0x82, 0x44, 0x0C, 0x4A, 0x82, 0x44, 0x0C, 0x4A, 0x82, 0x44, + 0x0C, 0x4A, 0x82, 0x44, 0x0C, 0x4A, 0x82, 0x44, 0x0C, 0x4A, 0x82, 0x44, 0x0C, 0x49, 0x82, 0x44, + 0x0C, 0x47, 0x82, 0x44, 0x0C, 0x46, 0x82, 0x44, 0x0C, 0x44, 0x82, 0x44, 0x0C, 0x42, 0x82, 0x44, + 0x0C, 0x40, 0x82, 0x44, 0x0C, 0x3E, 0x82, 0x44, 0x0C, 0x3A, 0x82, 0x44, 0x0C, 0x37, 0x82, 0x44, + 0x0C, 0x34, 0x82, 0x44, 0x0C, 0x31, 0x82, 0x44, 0x0C, 0x2C, 0x82, 0x44, 0x0C, 0x28, 0x82, 0x44, + 0x0C, 0x23, 0x82, 0x44, 0x0C, 0x1E, 0x82, 0x44, 0x0C, 0x19, 0x82, 0x44, 0x0C, 0x13, 0x82, 0x44, + 0x0C, 0x0F, 0x82, 0x44, 0x0C, 0x0A, 0x82, 0x44, 0x0C, 0x06, 0x82, 0x44, 0x0C, 0x03, 0x82, 0x44, + 0x0C, 0x02, 0x81, 0x43, 0x0B, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x82, 0x44, 0x0C, 0x01, 0x82, 0x44, 0x0C, 0x03, 0x82, 0x44, 0x0C, 0x07, 0x82, 0x44, + 0x0C, 0x0C, 0x82, 0x44, 0x0C, 0x12, 0x82, 0x44, 0x0C, 0x1B, 0x82, 0x44, 0x0C, 0x23, 0x82, 0x44, + 0x0C, 0x2B, 0x82, 0x44, 0x0C, 0x33, 0x82, 0x44, 0x0C, 0x3B, 0x82, 0x44, 0x0C, 0x41, 0x82, 0x44, + 0x0C, 0x47, 0x82, 0x44, 0x0C, 0x4C, 0x82, 0x44, 0x0C, 0x51, 0x82, 0x44, 0x0C, 0x55, 0x82, 0x44, + 0x0C, 0x59, 0x82, 0x44, 0x0C, 0x5C, 0x82, 0x44, 0x0C, 0x5F, 0x82, 0x44, 0x0C, 0x61, 0x82, 0x44, + 0x0C, 0x64, 0x82, 0x44, 0x0C, 0x66, 0x82, 0x44, 0x0C, 0x67, 0x82, 0x44, 0x0C, 0x69, 0x82, 0x44, + 0x0C, 0x6A, 0x82, 0x44, 0x0C, 0x6A, 0x82, 0x44, 0x0C, 0x6A, 0x82, 0x44, 0x0C, 0x6B, 0x82, 0x44, + 0x0C, 0x6B, 0x82, 0x44, 0x0C, 0x6A, 0x82, 0x44, 0x0C, 0x6A, 0x82, 0x44, 0x0C, 0x69, 0x82, 0x44, + 0x0C, 0x67, 0x82, 0x44, 0x0C, 0x66, 0x82, 0x44, 0x0C, 0x64, 0x82, 0x44, 0x0C, 0x62, 0x82, 0x44, + 0x0C, 0x60, 0x82, 0x44, 0x0C, 0x5D, 0x82, 0x44, 0x0C, 0x59, 0x82, 0x44, 0x0C, 0x55, 0x82, 0x44, + 0x0C, 0x51, 0x82, 0x44, 0x0C, 0x4D, 0x82, 0x44, 0x0C, 0x48, 0x82, 0x44, 0x0C, 0x42, 0x82, 0x44, + 0x0C, 0x3C, 0x82, 0x44, 0x0C, 0x34, 0x82, 0x44, 0x0C, 0x2D, 0x82, 0x44, 0x0C, 0x24, 0x82, 0x44, + 0x0C, 0x1C, 0x82, 0x44, 0x0C, 0x13, 0x82, 0x44, 0x0C, 0x0D, 0x82, 0x44, 0x0C, 0x07, 0x82, 0x44, + 0x0C, 0x03, 0x81, 0x43, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x42, + 0x09, 0x01, 0x82, 0x44, 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x06, 0x82, 0x44, 0x0C, 0x0B, 0x82, 0x44, + 0x0C, 0x13, 0x82, 0x44, 0x0C, 0x1E, 0x82, 0x44, 0x0C, 0x2A, 0x82, 0x44, 0x0C, 0x37, 0x82, 0x44, + 0x0C, 0x43, 0x82, 0x44, 0x0C, 0x4E, 0x82, 0x44, 0x0C, 0x57, 0x82, 0x44, 0x0C, 0x5F, 0x82, 0x44, + 0x0C, 0x66, 0x82, 0x44, 0x0C, 0x6B, 0x82, 0x44, 0x0C, 0x70, 0x82, 0x44, 0x0C, 0x75, 0x82, 0x44, + 0x0C, 0x79, 0x82, 0x44, 0x0C, 0x7C, 0x82, 0x44, 0x0C, 0x7F, 0x82, 0x44, 0x0C, 0x81, 0x82, 0x44, + 0x0C, 0x83, 0x82, 0x44, 0x0C, 0x85, 0x82, 0x43, 0x0B, 0x86, 0x81, 0x43, 0x0A, 0x88, 0x81, 0x42, + 0x0A, 0x88, 0x81, 0x42, 0x09, 0x88, 0x81, 0x42, 0x09, 0x89, 0x81, 0x42, 0x09, 0x89, 0x81, 0x42, + 0x09, 0x89, 0x81, 0x43, 0x0A, 0x89, 0x82, 0x43, 0x0B, 0x89, 0x82, 0x44, 0x0C, 0x88, 0x82, 0x44, + 0x0C, 0x87, 0x82, 0x44, 0x0C, 0x85, 0x82, 0x44, 0x0C, 0x83, 0x82, 0x44, 0x0C, 0x81, 0x82, 0x44, + 0x0C, 0x7F, 0x82, 0x44, 0x0C, 0x7C, 0x82, 0x44, 0x0C, 0x79, 0x82, 0x44, 0x0C, 0x75, 0x82, 0x44, + 0x0C, 0x71, 0x82, 0x44, 0x0C, 0x6C, 0x82, 0x44, 0x0C, 0x66, 0x82, 0x44, 0x0C, 0x60, 0x82, 0x44, + 0x0C, 0x58, 0x82, 0x44, 0x0C, 0x4F, 0x82, 0x44, 0x0C, 0x45, 0x82, 0x44, 0x0C, 0x39, 0x82, 0x44, + 0x0C, 0x2C, 0x82, 0x44, 0x0C, 0x1F, 0x82, 0x44, 0x0C, 0x14, 0x82, 0x44, 0x0C, 0x0C, 0x82, 0x44, + 0x0C, 0x06, 0x81, 0x43, 0x0B, 0x03, 0x8F, 0x57, 0x25, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x42, + 0x09, 0x01, 0x82, 0x44, 0x0C, 0x03, 0x82, 0x44, 0x0C, 0x08, 0x82, 0x44, 0x0C, 0x10, 0x82, 0x44, + 0x0C, 0x1C, 0x82, 0x44, 0x0C, 0x2A, 0x82, 0x44, 0x0C, 0x3B, 0x82, 0x44, 0x0C, 0x4C, 0x82, 0x44, + 0x0C, 0x5B, 0x82, 0x44, 0x0C, 0x68, 0x82, 0x44, 0x0C, 0x73, 0x82, 0x44, 0x0C, 0x7B, 0x82, 0x44, + 0x0C, 0x83, 0x82, 0x44, 0x0C, 0x88, 0x82, 0x44, 0x0C, 0x8D, 0x82, 0x44, 0x0C, 0x91, 0x82, 0x44, + 0x0C, 0x95, 0x82, 0x44, 0x0C, 0x97, 0x81, 0x43, 0x0B, 0x99, 0x81, 0x42, 0x09, 0x9B, 0x81, 0x43, + 0x0A, 0x9D, 0x83, 0x46, 0x0E, 0xA0, 0x87, 0x4B, 0x14, 0xA4, 0x8B, 0x52, 0x1D, 0xA9, 0x8E, 0x57, + 0x25, 0xAF, 0x8F, 0x58, 0x28, 0xB2, 0x8F, 0x59, 0x28, 0xB3, 0x8F, 0x59, 0x28, 0xB2, 0x8F, 0x57, + 0x26, 0xB0, 0x8C, 0x53, 0x20, 0xAC, 0x87, 0x4C, 0x16, 0xA7, 0x84, 0x46, 0x0F, 0xA2, 0x82, 0x43, + 0x0B, 0xA0, 0x81, 0x42, 0x09, 0x9E, 0x81, 0x43, 0x0A, 0x9D, 0x82, 0x44, 0x0C, 0x9C, 0x82, 0x44, + 0x0C, 0x9A, 0x82, 0x44, 0x0C, 0x98, 0x82, 0x44, 0x0C, 0x95, 0x82, 0x44, 0x0C, 0x91, 0x82, 0x44, + 0x0C, 0x8D, 0x82, 0x44, 0x0C, 0x89, 0x82, 0x44, 0x0C, 0x83, 0x82, 0x44, 0x0C, 0x7C, 0x82, 0x44, + 0x0C, 0x74, 0x82, 0x44, 0x0C, 0x6A, 0x82, 0x44, 0x0C, 0x5D, 0x82, 0x44, 0x0C, 0x4E, 0x82, 0x44, + 0x0C, 0x3D, 0x82, 0x44, 0x0C, 0x2C, 0x82, 0x44, 0x0C, 0x1D, 0x82, 0x44, 0x0C, 0x11, 0x82, 0x44, + 0x0C, 0x09, 0x82, 0x44, 0x0C, 0x04, 0x83, 0x46, 0x0F, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x45, + 0x0E, 0x02, 0x82, 0x44, 0x0C, 0x04, 0x82, 0x44, 0x0C, 0x0A, 0x82, 0x44, 0x0C, 0x14, 0x82, 0x44, + 0x0C, 0x22, 0x82, 0x44, 0x0C, 0x34, 0x82, 0x44, 0x0C, 0x47, 0x82, 0x44, 0x0C, 0x5B, 0x82, 0x44, + 0x0C, 0x6D, 0x82, 0x44, 0x0C, 0x7C, 0x82, 0x44, 0x0C, 0x87, 0x82, 0x44, 0x0C, 0x90, 0x82, 0x44, + 0x0C, 0x97, 0x82, 0x44, 0x0C, 0x9D, 0x82, 0x44, 0x0C, 0xA1, 0x82, 0x43, 0x0B, 0xA5, 0x81, 0x42, + 0x09, 0xA7, 0x83, 0x45, 0x0D, 0xAA, 0x8A, 0x50, 0x1C, 0xB3, 0x93, 0x5F, 0x31, 0xC1, 0x9A, 0x6B, + 0x44, 0xD1, 0x9C, 0x71, 0x4E, 0xDE, 0x9C, 0x73, 0x53, 0xE8, 0x9C, 0x74, 0x57, 0xF1, 0x9B, 0x74, + 0x58, 0xF6, 0x9A, 0x73, 0x58, 0xF8, 0x9A, 0x73, 0x58, 0xF9, 0x9A, 0x74, 0x59, 0xF8, 0x9C, 0x76, + 0x5B, 0xF7, 0x9E, 0x77, 0x5B, 0xF2, 0x9E, 0x76, 0x57, 0xEA, 0x9E, 0x74, 0x52, 0xE1, 0x9C, 0x6F, + 0x4A, 0xD6, 0x95, 0x63, 0x37, 0xC7, 0x8C, 0x53, 0x20, 0xB9, 0x84, 0x47, 0x10, 0xAF, 0x81, 0x42, + 0x0A, 0xAB, 0x81, 0x43, 0x0A, 0xAA, 0x82, 0x44, 0x0C, 0xA8, 0x82, 0x44, 0x0C, 0xA5, 0x82, 0x44, + 0x0C, 0xA2, 0x82, 0x44, 0x0C, 0x9D, 0x82, 0x44, 0x0C, 0x98, 0x82, 0x44, 0x0C, 0x91, 0x82, 0x44, + 0x0C, 0x89, 0x82, 0x44, 0x0C, 0x7E, 0x82, 0x44, 0x0C, 0x6F, 0x82, 0x44, 0x0C, 0x5D, 0x82, 0x44, + 0x0C, 0x4A, 0x82, 0x44, 0x0C, 0x36, 0x82, 0x44, 0x0C, 0x24, 0x82, 0x44, 0x0C, 0x15, 0x82, 0x44, + 0x0C, 0x0B, 0x82, 0x44, 0x0C, 0x05, 0x82, 0x43, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x46, + 0x0F, 0x02, 0x82, 0x44, 0x0C, 0x04, 0x82, 0x44, 0x0C, 0x0A, 0x82, 0x44, 0x0C, 0x15, 0x82, 0x44, + 0x0C, 0x24, 0x82, 0x44, 0x0C, 0x37, 0x82, 0x44, 0x0C, 0x4C, 0x82, 0x44, 0x0C, 0x61, 0x82, 0x44, + 0x0C, 0x74, 0x82, 0x44, 0x0C, 0x83, 0x82, 0x44, 0x0C, 0x8F, 0x82, 0x44, 0x0C, 0x98, 0x82, 0x44, + 0x0C, 0x9F, 0x81, 0x43, 0x0B, 0xA4, 0x81, 0x43, 0x0A, 0xA7, 0x88, 0x4D, 0x16, 0xB1, 0x94, 0x61, + 0x33, 0xC5, 0x9C, 0x70, 0x4B, 0xDD, 0x9B, 0x72, 0x53, 0xF0, 0x94, 0x6C, 0x50, 0xFB, 0x8C, 0x63, + 0x48, 0xFF, 0x85, 0x5B, 0x40, 0xFF, 0x7F, 0x55, 0x3A, 0xFF, 0x7C, 0x50, 0x36, 0xFF, 0x79, 0x4E, + 0x34, 0xFF, 0x79, 0x4D, 0x33, 0xFF, 0x79, 0x4D, 0x33, 0xFF, 0x7A, 0x4F, 0x35, 0xFF, 0x7C, 0x52, + 0x37, 0xFF, 0x80, 0x56, 0x3C, 0xFF, 0x85, 0x5C, 0x42, 0xFF, 0x8B, 0x63, 0x49, 0xFF, 0x92, 0x6B, + 0x51, 0xFF, 0x9A, 0x74, 0x5A, 0xFC, 0x9F, 0x79, 0x5C, 0xF4, 0x9F, 0x76, 0x53, 0xE4, 0x97, 0x66, + 0x3C, 0xCD, 0x8A, 0x51, 0x1C, 0xB9, 0x82, 0x43, 0x0B, 0xAE, 0x81, 0x43, 0x0A, 0xAC, 0x82, 0x44, + 0x0C, 0xAA, 0x82, 0x44, 0x0C, 0xA5, 0x82, 0x44, 0x0C, 0xA0, 0x82, 0x44, 0x0C, 0x99, 0x82, 0x44, + 0x0C, 0x91, 0x82, 0x44, 0x0C, 0x85, 0x82, 0x44, 0x0C, 0x76, 0x82, 0x44, 0x0C, 0x64, 0x82, 0x44, + 0x0C, 0x4F, 0x82, 0x44, 0x0C, 0x3A, 0x82, 0x44, 0x0C, 0x26, 0x82, 0x44, 0x0C, 0x17, 0x82, 0x44, + 0x0C, 0x0C, 0x82, 0x44, 0x0C, 0x05, 0x82, 0x43, 0x0B, 0x02, 0x87, 0x4A, 0x13, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x45, + 0x0E, 0x02, 0x82, 0x44, 0x0C, 0x04, 0x82, 0x44, 0x0C, 0x0A, 0x82, 0x44, 0x0C, 0x14, 0x82, 0x44, + 0x0C, 0x22, 0x82, 0x44, 0x0C, 0x34, 0x82, 0x44, 0x0C, 0x48, 0x82, 0x44, 0x0C, 0x5C, 0x82, 0x44, + 0x0C, 0x6E, 0x82, 0x44, 0x0C, 0x7D, 0x82, 0x44, 0x0C, 0x88, 0x82, 0x43, 0x0B, 0x91, 0x81, 0x43, + 0x0A, 0x96, 0x8A, 0x4F, 0x1A, 0xA4, 0x99, 0x68, 0x3F, 0xC6, 0x9C, 0x73, 0x52, 0xE9, 0x93, 0x6A, + 0x4E, 0xFB, 0x84, 0x5A, 0x3E, 0xFF, 0x79, 0x4C, 0x30, 0xFF, 0x72, 0x43, 0x28, 0xFF, 0x6E, 0x40, + 0x25, 0xFF, 0x6D, 0x3F, 0x24, 0xFF, 0x6D, 0x3F, 0x24, 0xFF, 0x6E, 0x40, 0x24, 0xFF, 0x70, 0x41, + 0x26, 0xFF, 0x71, 0x42, 0x27, 0xFF, 0x72, 0x43, 0x28, 0xFF, 0x72, 0x45, 0x29, 0xFF, 0x73, 0x46, + 0x2A, 0xFF, 0x74, 0x47, 0x2C, 0xFF, 0x75, 0x49, 0x2E, 0xFF, 0x77, 0x4A, 0x2F, 0xFF, 0x79, 0x4D, + 0x32, 0xFF, 0x7E, 0x52, 0x38, 0xFF, 0x85, 0x5B, 0x40, 0xFF, 0x8F, 0x67, 0x4D, 0xFF, 0x9B, 0x75, + 0x5A, 0xFD, 0xA2, 0x7B, 0x5D, 0xF0, 0x9D, 0x70, 0x49, 0xD3, 0x8D, 0x55, 0x22, 0xB2, 0x82, 0x43, + 0x0B, 0xA1, 0x81, 0x43, 0x0B, 0x9D, 0x82, 0x44, 0x0C, 0x99, 0x82, 0x44, 0x0C, 0x92, 0x82, 0x44, + 0x0C, 0x8A, 0x82, 0x44, 0x0C, 0x7E, 0x82, 0x44, 0x0C, 0x70, 0x82, 0x44, 0x0C, 0x5E, 0x82, 0x44, + 0x0C, 0x4B, 0x82, 0x44, 0x0C, 0x37, 0x82, 0x44, 0x0C, 0x24, 0x82, 0x44, 0x0C, 0x15, 0x82, 0x44, + 0x0C, 0x0B, 0x82, 0x44, 0x0C, 0x05, 0x82, 0x43, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x42, + 0x09, 0x01, 0x82, 0x44, 0x0C, 0x03, 0x82, 0x44, 0x0C, 0x08, 0x82, 0x44, 0x0C, 0x10, 0x82, 0x44, + 0x0C, 0x1C, 0x82, 0x44, 0x0C, 0x2B, 0x82, 0x44, 0x0C, 0x3C, 0x82, 0x44, 0x0C, 0x4D, 0x82, 0x44, + 0x0C, 0x5C, 0x82, 0x44, 0x0C, 0x69, 0x81, 0x42, 0x09, 0x72, 0x86, 0x4A, 0x13, 0x7F, 0x98, 0x67, + 0x3D, 0xAD, 0x9D, 0x73, 0x53, 0xE3, 0x8E, 0x64, 0x47, 0xFC, 0x7C, 0x4E, 0x31, 0xFF, 0x6F, 0x40, + 0x23, 0xFF, 0x6A, 0x3A, 0x1E, 0xFF, 0x69, 0x39, 0x1C, 0xFF, 0x6B, 0x3A, 0x1D, 0xFF, 0x6C, 0x3C, + 0x1E, 0xFF, 0x6E, 0x3E, 0x20, 0xFF, 0x70, 0x40, 0x21, 0xFF, 0x72, 0x42, 0x23, 0xFF, 0x74, 0x43, + 0x24, 0xFF, 0x75, 0x45, 0x26, 0xFF, 0x76, 0x46, 0x27, 0xFF, 0x77, 0x47, 0x28, 0xFF, 0x78, 0x48, + 0x29, 0xFF, 0x79, 0x49, 0x2A, 0xFF, 0x79, 0x4A, 0x2B, 0xFF, 0x79, 0x4B, 0x2C, 0xFF, 0x79, 0x4B, + 0x2D, 0xFF, 0x79, 0x4B, 0x2E, 0xFF, 0x7A, 0x4C, 0x30, 0xFF, 0x7C, 0x4F, 0x33, 0xFF, 0x81, 0x55, + 0x39, 0xFF, 0x8B, 0x61, 0x46, 0xFF, 0x99, 0x72, 0x58, 0xFF, 0xA4, 0x7E, 0x61, 0xEE, 0x9D, 0x70, + 0x48, 0xC0, 0x89, 0x4F, 0x19, 0x92, 0x81, 0x42, 0x09, 0x82, 0x82, 0x44, 0x0C, 0x7E, 0x82, 0x44, + 0x0C, 0x76, 0x82, 0x44, 0x0C, 0x6B, 0x82, 0x44, 0x0C, 0x5E, 0x82, 0x44, 0x0C, 0x4F, 0x82, 0x44, + 0x0C, 0x3E, 0x82, 0x44, 0x0C, 0x2D, 0x82, 0x44, 0x0C, 0x1E, 0x82, 0x44, 0x0C, 0x11, 0x82, 0x44, + 0x0C, 0x09, 0x82, 0x44, 0x0C, 0x04, 0x83, 0x45, 0x0F, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x42, + 0x09, 0x01, 0x82, 0x44, 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x06, 0x82, 0x44, 0x0C, 0x0C, 0x82, 0x44, + 0x0C, 0x14, 0x82, 0x44, 0x0C, 0x1F, 0x82, 0x44, 0x0C, 0x2B, 0x82, 0x44, 0x0C, 0x38, 0x82, 0x43, + 0x0B, 0x44, 0x81, 0x42, 0x09, 0x4D, 0x95, 0x62, 0x33, 0x74, 0xA0, 0x76, 0x54, 0xC4, 0x92, 0x67, + 0x49, 0xF7, 0x7B, 0x4C, 0x2E, 0xFF, 0x6C, 0x3B, 0x1E, 0xFF, 0x67, 0x36, 0x18, 0xFF, 0x67, 0x36, + 0x18, 0xFF, 0x6A, 0x38, 0x19, 0xFF, 0x6C, 0x3A, 0x1B, 0xFF, 0x6F, 0x3C, 0x1C, 0xFF, 0x71, 0x3F, + 0x1D, 0xFF, 0x73, 0x41, 0x1F, 0xFF, 0x75, 0x43, 0x20, 0xFF, 0x77, 0x45, 0x22, 0xFF, 0x79, 0x47, + 0x23, 0xFF, 0x7A, 0x48, 0x24, 0xFF, 0x7C, 0x49, 0x26, 0xFF, 0x7D, 0x4B, 0x27, 0xFF, 0x7D, 0x4C, + 0x28, 0xFF, 0x7E, 0x4D, 0x29, 0xFF, 0x7E, 0x4D, 0x2A, 0xFF, 0x7F, 0x4E, 0x2B, 0xFF, 0x7F, 0x4E, + 0x2C, 0xFF, 0x7E, 0x4F, 0x2D, 0xFF, 0x7E, 0x4E, 0x2E, 0xFF, 0x7D, 0x4E, 0x2F, 0xFF, 0x7D, 0x4F, + 0x30, 0xFF, 0x7D, 0x50, 0x32, 0xFF, 0x82, 0x55, 0x39, 0xFF, 0x8D, 0x63, 0x47, 0xFF, 0x9D, 0x77, + 0x5B, 0xFC, 0xA6, 0x7F, 0x60, 0xD8, 0x9A, 0x6A, 0x3E, 0x90, 0x83, 0x45, 0x0D, 0x61, 0x81, 0x43, + 0x0A, 0x59, 0x82, 0x44, 0x0C, 0x51, 0x82, 0x44, 0x0C, 0x46, 0x82, 0x44, 0x0C, 0x3A, 0x82, 0x44, + 0x0C, 0x2D, 0x82, 0x44, 0x0C, 0x20, 0x82, 0x44, 0x0C, 0x15, 0x82, 0x44, 0x0C, 0x0C, 0x82, 0x44, + 0x0C, 0x06, 0x81, 0x43, 0x0B, 0x03, 0x8C, 0x54, 0x21, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x82, 0x44, 0x0C, 0x01, 0x82, 0x44, 0x0C, 0x04, 0x82, 0x44, 0x0C, 0x07, 0x82, 0x44, + 0x0C, 0x0C, 0x82, 0x44, 0x0C, 0x13, 0x82, 0x44, 0x0C, 0x1C, 0x80, 0x41, 0x08, 0x23, 0x87, 0x4B, + 0x13, 0x2D, 0xA3, 0x78, 0x53, 0x76, 0x9C, 0x73, 0x54, 0xDE, 0x82, 0x54, 0x35, 0xFF, 0x6D, 0x3A, + 0x1B, 0xFF, 0x64, 0x31, 0x13, 0xFF, 0x63, 0x30, 0x11, 0xFF, 0x66, 0x31, 0x12, 0xFF, 0x69, 0x33, + 0x13, 0xFF, 0x6B, 0x36, 0x13, 0xFF, 0x6E, 0x39, 0x15, 0xFF, 0x71, 0x3C, 0x17, 0xFF, 0x74, 0x3F, + 0x19, 0xFF, 0x77, 0x42, 0x1B, 0xFF, 0x7A, 0x45, 0x1E, 0xFF, 0x7C, 0x47, 0x20, 0xFF, 0x7E, 0x4A, + 0x23, 0xFF, 0x80, 0x4C, 0x24, 0xFF, 0x81, 0x4D, 0x25, 0xFF, 0x82, 0x4E, 0x27, 0xFF, 0x83, 0x4F, + 0x28, 0xFF, 0x83, 0x50, 0x29, 0xFF, 0x84, 0x51, 0x2A, 0xFF, 0x84, 0x51, 0x2B, 0xFF, 0x84, 0x51, + 0x2C, 0xFF, 0x83, 0x52, 0x2D, 0xFF, 0x83, 0x52, 0x2E, 0xFF, 0x82, 0x52, 0x2E, 0xFF, 0x82, 0x51, + 0x2F, 0xFF, 0x81, 0x51, 0x30, 0xFF, 0x80, 0x51, 0x31, 0xFF, 0x80, 0x52, 0x34, 0xFF, 0x86, 0x5A, + 0x3C, 0xFF, 0x95, 0x6C, 0x50, 0xFF, 0xA6, 0x81, 0x64, 0xEE, 0xA8, 0x7F, 0x5C, 0x9A, 0x8C, 0x53, + 0x1F, 0x44, 0x80, 0x40, 0x07, 0x34, 0x82, 0x44, 0x0C, 0x2E, 0x82, 0x44, 0x0C, 0x25, 0x82, 0x44, + 0x0C, 0x1D, 0x82, 0x44, 0x0C, 0x14, 0x82, 0x44, 0x0C, 0x0D, 0x82, 0x44, 0x0C, 0x08, 0x82, 0x44, + 0x0C, 0x04, 0x83, 0x46, 0x0F, 0x02, 0xA0, 0x71, 0x46, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x85, 0x48, 0x11, 0x01, 0x82, 0x43, 0x0B, 0x02, 0x82, 0x44, 0x0C, 0x03, 0x82, 0x44, + 0x0C, 0x06, 0x82, 0x44, 0x0C, 0x0A, 0x7B, 0x3A, 0x00, 0x0D, 0x9B, 0x68, 0x39, 0x19, 0xA9, 0x82, + 0x62, 0x81, 0x93, 0x68, 0x48, 0xEE, 0x73, 0x41, 0x20, 0xFF, 0x62, 0x2C, 0x0C, 0xFF, 0x5E, 0x27, + 0x07, 0xFF, 0x5F, 0x28, 0x06, 0xFF, 0x62, 0x29, 0x06, 0xFF, 0x65, 0x2B, 0x06, 0xFF, 0x67, 0x2D, + 0x07, 0xFF, 0x6A, 0x30, 0x07, 0xFF, 0x6C, 0x32, 0x08, 0xFF, 0x6F, 0x34, 0x09, 0xFF, 0x71, 0x36, + 0x0A, 0xFF, 0x74, 0x38, 0x0B, 0xFF, 0x76, 0x3A, 0x0D, 0xFF, 0x78, 0x3D, 0x0F, 0xFF, 0x7B, 0x40, + 0x12, 0xFF, 0x7E, 0x44, 0x16, 0xFF, 0x80, 0x48, 0x1A, 0xFF, 0x83, 0x4C, 0x1F, 0xFF, 0x86, 0x50, + 0x24, 0xFF, 0x88, 0x52, 0x28, 0xFF, 0x89, 0x54, 0x29, 0xFF, 0x89, 0x55, 0x2A, 0xFF, 0x89, 0x55, + 0x2B, 0xFF, 0x89, 0x55, 0x2C, 0xFF, 0x88, 0x55, 0x2D, 0xFF, 0x88, 0x55, 0x2E, 0xFF, 0x87, 0x55, + 0x2F, 0xFF, 0x86, 0x55, 0x2F, 0xFF, 0x84, 0x54, 0x30, 0xFF, 0x83, 0x53, 0x31, 0xFF, 0x82, 0x53, + 0x32, 0xFF, 0x84, 0x56, 0x37, 0xFF, 0x8F, 0x64, 0x46, 0xFF, 0xA2, 0x7C, 0x60, 0xF9, 0xAE, 0x8A, + 0x6C, 0xA6, 0x9D, 0x6D, 0x42, 0x31, 0x7C, 0x3B, 0x00, 0x17, 0x82, 0x44, 0x0C, 0x15, 0x82, 0x44, + 0x0C, 0x0F, 0x82, 0x44, 0x0C, 0x0B, 0x82, 0x44, 0x0C, 0x07, 0x82, 0x44, 0x0C, 0x04, 0x81, 0x43, + 0x0B, 0x02, 0x83, 0x46, 0x0E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x4B, 0x14, 0x01, 0x83, 0x45, 0x0E, 0x01, 0x83, 0x45, + 0x0D, 0x02, 0x5F, 0x0F, 0x00, 0x03, 0xB2, 0x8C, 0x69, 0x10, 0xAC, 0x87, 0x69, 0x88, 0x8E, 0x61, + 0x40, 0xF6, 0x6D, 0x39, 0x16, 0xFF, 0x60, 0x29, 0x08, 0xFF, 0x5F, 0x27, 0x05, 0xFF, 0x62, 0x29, + 0x05, 0xFF, 0x65, 0x2C, 0x06, 0xFF, 0x68, 0x2E, 0x06, 0xFF, 0x6B, 0x31, 0x07, 0xFF, 0x6E, 0x33, + 0x07, 0xFF, 0x71, 0x35, 0x08, 0xFF, 0x73, 0x37, 0x08, 0xFF, 0x75, 0x39, 0x08, 0xFF, 0x77, 0x3A, + 0x09, 0xFF, 0x78, 0x3B, 0x09, 0xFF, 0x79, 0x3C, 0x09, 0xFF, 0x7A, 0x3C, 0x09, 0xFF, 0x7B, 0x3D, + 0x09, 0xFF, 0x7B, 0x3D, 0x09, 0xFF, 0x7C, 0x3E, 0x0A, 0xFF, 0x7D, 0x3F, 0x0C, 0xFF, 0x7F, 0x42, + 0x0F, 0xFF, 0x82, 0x46, 0x13, 0xFF, 0x85, 0x4C, 0x1A, 0xFF, 0x89, 0x52, 0x22, 0xFF, 0x8C, 0x56, + 0x28, 0xFF, 0x8D, 0x58, 0x2B, 0xFF, 0x8D, 0x59, 0x2C, 0xFF, 0x8C, 0x58, 0x2D, 0xFF, 0x8C, 0x58, + 0x2D, 0xFF, 0x8B, 0x58, 0x2E, 0xFF, 0x8A, 0x57, 0x2F, 0xFF, 0x88, 0x57, 0x30, 0xFF, 0x87, 0x56, + 0x30, 0xFF, 0x85, 0x55, 0x31, 0xFF, 0x85, 0x56, 0x34, 0xFF, 0x8C, 0x60, 0x40, 0xFF, 0xA0, 0x79, + 0x5B, 0xFE, 0xB2, 0x90, 0x73, 0xAF, 0xAE, 0x87, 0x65, 0x26, 0x6E, 0x25, 0x00, 0x07, 0x82, 0x44, + 0x0C, 0x07, 0x82, 0x44, 0x0C, 0x05, 0x82, 0x44, 0x0C, 0x03, 0x82, 0x44, 0x0D, 0x01, 0x84, 0x46, + 0x0F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xC9, 0xAA, 0x8F, 0x09, 0xAE, 0x89, 0x6C, 0x84, 0x8D, 0x60, 0x3E, 0xF8, 0x6C, 0x37, + 0x13, 0xFF, 0x61, 0x29, 0x07, 0xFF, 0x61, 0x29, 0x06, 0xFF, 0x65, 0x2C, 0x06, 0xFF, 0x68, 0x2E, + 0x07, 0xFF, 0x6B, 0x31, 0x07, 0xFF, 0x6C, 0x33, 0x08, 0xFF, 0x6D, 0x34, 0x08, 0xFF, 0x71, 0x37, + 0x09, 0xFF, 0x76, 0x3A, 0x09, 0xFF, 0x79, 0x3C, 0x0A, 0xFF, 0x7B, 0x3E, 0x0A, 0xFF, 0x7D, 0x3F, + 0x0A, 0xFF, 0x7E, 0x40, 0x0A, 0xFF, 0x7F, 0x40, 0x0A, 0xFF, 0x7F, 0x41, 0x0B, 0xFF, 0x80, 0x41, + 0x0B, 0xFF, 0x81, 0x42, 0x0B, 0xFF, 0x81, 0x42, 0x0B, 0xFF, 0x81, 0x42, 0x0A, 0xFF, 0x81, 0x42, + 0x0A, 0xFF, 0x81, 0x42, 0x0A, 0xFF, 0x81, 0x42, 0x0B, 0xFF, 0x81, 0x43, 0x0D, 0xFF, 0x84, 0x47, + 0x12, 0xFF, 0x88, 0x4D, 0x19, 0xFF, 0x8C, 0x54, 0x23, 0xFF, 0x8F, 0x59, 0x2A, 0xFF, 0x90, 0x5B, + 0x2D, 0xFF, 0x8F, 0x5B, 0x2E, 0xFF, 0x8E, 0x5A, 0x2F, 0xFF, 0x8D, 0x5A, 0x2F, 0xFF, 0x8B, 0x59, + 0x30, 0xFF, 0x8A, 0x58, 0x31, 0xFF, 0x87, 0x57, 0x31, 0xFF, 0x87, 0x57, 0x33, 0xFF, 0x8D, 0x5F, + 0x3E, 0xFF, 0xA0, 0x78, 0x5A, 0xFF, 0xB4, 0x92, 0x77, 0xAC, 0xBA, 0x97, 0x79, 0x1B, 0x00, 0x00, + 0x00, 0x00, 0x84, 0x46, 0x0F, 0x02, 0x84, 0x47, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEE, 0xDF, + 0xD2, 0x05, 0xB4, 0x91, 0x74, 0x77, 0x91, 0x63, 0x40, 0xF5, 0x6E, 0x38, 0x14, 0xFF, 0x63, 0x2B, + 0x07, 0xFF, 0x64, 0x2B, 0x06, 0xFF, 0x67, 0x2D, 0x07, 0xFF, 0x6B, 0x31, 0x07, 0xFF, 0x6D, 0x33, + 0x08, 0xFF, 0x6C, 0x34, 0x08, 0xFF, 0x67, 0x33, 0x07, 0xFF, 0x67, 0x36, 0x0B, 0xFF, 0x68, 0x35, + 0x06, 0xFF, 0x73, 0x3B, 0x0A, 0xFF, 0x7C, 0x3F, 0x0B, 0xFF, 0x81, 0x42, 0x0B, 0xFF, 0x82, 0x43, + 0x0B, 0xFF, 0x83, 0x43, 0x0B, 0xFF, 0x83, 0x44, 0x0B, 0xFF, 0x84, 0x44, 0x0C, 0xFF, 0x84, 0x45, + 0x0C, 0xFF, 0x85, 0x45, 0x0C, 0xFF, 0x85, 0x45, 0x0C, 0xFF, 0x85, 0x45, 0x0C, 0xFF, 0x85, 0x45, + 0x0C, 0xFF, 0x85, 0x45, 0x0C, 0xFF, 0x85, 0x45, 0x0C, 0xFF, 0x85, 0x45, 0x0C, 0xFF, 0x84, 0x45, + 0x0B, 0xFF, 0x84, 0x44, 0x0B, 0xFF, 0x84, 0x45, 0x0D, 0xFF, 0x87, 0x4A, 0x13, 0xFF, 0x8C, 0x52, + 0x1E, 0xFF, 0x91, 0x59, 0x28, 0xFF, 0x92, 0x5D, 0x2E, 0xFF, 0x92, 0x5D, 0x2F, 0xFF, 0x90, 0x5C, + 0x2F, 0xFF, 0x8E, 0x5B, 0x30, 0xFF, 0x8C, 0x5A, 0x31, 0xFF, 0x8A, 0x58, 0x31, 0xFF, 0x89, 0x58, + 0x33, 0xFF, 0x8F, 0x60, 0x3E, 0xFF, 0xA3, 0x7B, 0x5C, 0xFE, 0xB8, 0x97, 0x7B, 0x9D, 0xCA, 0xAD, + 0x95, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBA, 0x99, + 0x7D, 0x5B, 0x97, 0x6B, 0x48, 0xEF, 0x72, 0x3C, 0x17, 0xFF, 0x65, 0x2C, 0x08, 0xFF, 0x67, 0x2C, + 0x06, 0xFF, 0x6A, 0x2F, 0x07, 0xFF, 0x6E, 0x33, 0x07, 0xFF, 0x70, 0x35, 0x08, 0xFF, 0x6C, 0x34, + 0x07, 0xFF, 0x63, 0x32, 0x08, 0xFF, 0x80, 0x60, 0x3F, 0xFF, 0xBB, 0xAA, 0x99, 0xFF, 0x7F, 0x60, + 0x3F, 0xFF, 0x64, 0x36, 0x07, 0xFF, 0x75, 0x3E, 0x09, 0xFF, 0x80, 0x43, 0x0B, 0xFF, 0x85, 0x46, + 0x0C, 0xFF, 0x87, 0x47, 0x0C, 0xFF, 0x87, 0x47, 0x0C, 0xFF, 0x87, 0x47, 0x0C, 0xFF, 0x88, 0x48, + 0x0C, 0xFF, 0x88, 0x48, 0x0C, 0xFF, 0x88, 0x48, 0x0C, 0xFF, 0x88, 0x48, 0x0C, 0xFF, 0x88, 0x48, + 0x0C, 0xFF, 0x88, 0x48, 0x0C, 0xFF, 0x88, 0x48, 0x0C, 0xFF, 0x88, 0x48, 0x0C, 0xFF, 0x88, 0x48, + 0x0C, 0xFF, 0x87, 0x47, 0x0C, 0xFF, 0x87, 0x47, 0x0C, 0xFF, 0x86, 0x46, 0x0B, 0xFF, 0x86, 0x46, + 0x0C, 0xFF, 0x88, 0x49, 0x10, 0xFF, 0x8C, 0x51, 0x1A, 0xFF, 0x92, 0x5A, 0x28, 0xFF, 0x94, 0x5E, + 0x2F, 0xFF, 0x93, 0x5E, 0x30, 0xFF, 0x91, 0x5D, 0x30, 0xFF, 0x8F, 0x5B, 0x30, 0xFF, 0x8D, 0x5A, + 0x31, 0xFF, 0x8B, 0x59, 0x33, 0xFF, 0x92, 0x63, 0x40, 0xFF, 0xA7, 0x80, 0x60, 0xFB, 0xBE, 0x9E, + 0x84, 0x84, 0xE5, 0xD8, 0xCC, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0xA5, 0x8A, 0x32, 0xA1, 0x77, + 0x55, 0xD8, 0x79, 0x44, 0x1D, 0xFF, 0x68, 0x2F, 0x09, 0xFF, 0x69, 0x2E, 0x07, 0xFF, 0x6C, 0x31, + 0x07, 0xFF, 0x70, 0x34, 0x08, 0xFF, 0x72, 0x38, 0x09, 0xFF, 0x6D, 0x36, 0x07, 0xFF, 0x66, 0x3A, + 0x10, 0xFF, 0xA2, 0x8D, 0x77, 0xFF, 0xC0, 0xB7, 0xAC, 0xFF, 0xC1, 0xBB, 0xB1, 0xFF, 0xDC, 0xD7, + 0xCF, 0xFF, 0x9A, 0x83, 0x69, 0xFF, 0x68, 0x3E, 0x10, 0xFF, 0x73, 0x3E, 0x09, 0xFF, 0x81, 0x46, + 0x0C, 0xFF, 0x87, 0x48, 0x0D, 0xFF, 0x89, 0x49, 0x0D, 0xFF, 0x89, 0x4A, 0x0D, 0xFF, 0x8A, 0x4A, + 0x0D, 0xFF, 0x8A, 0x4A, 0x0D, 0xFF, 0x8A, 0x4A, 0x0D, 0xFF, 0x8A, 0x4A, 0x0D, 0xFF, 0x8A, 0x4A, + 0x0D, 0xFF, 0x8A, 0x4A, 0x0D, 0xFF, 0x8A, 0x4A, 0x0D, 0xFF, 0x8A, 0x4A, 0x0D, 0xFF, 0x8A, 0x4A, + 0x0D, 0xFF, 0x8A, 0x4A, 0x0D, 0xFF, 0x8A, 0x49, 0x0D, 0xFF, 0x89, 0x49, 0x0D, 0xFF, 0x89, 0x49, + 0x0D, 0xFF, 0x88, 0x48, 0x0C, 0xFF, 0x88, 0x48, 0x0C, 0xFF, 0x89, 0x4A, 0x10, 0xFF, 0x8E, 0x53, + 0x1B, 0xFF, 0x94, 0x5C, 0x29, 0xFF, 0x95, 0x5F, 0x2F, 0xFF, 0x93, 0x5E, 0x30, 0xFF, 0x91, 0x5D, + 0x30, 0xFF, 0x8F, 0x5B, 0x31, 0xFF, 0x8D, 0x5C, 0x34, 0xFF, 0x96, 0x68, 0x44, 0xFF, 0xAE, 0x88, + 0x68, 0xF0, 0xC4, 0xA8, 0x8F, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD4, 0xBC, 0xA5, 0x0F, 0xAD, 0x87, 0x66, 0xAC, 0x85, 0x52, + 0x2B, 0xFF, 0x6C, 0x32, 0x0B, 0xFF, 0x6A, 0x2F, 0x07, 0xFF, 0x6E, 0x32, 0x07, 0xFF, 0x73, 0x36, + 0x08, 0xFF, 0x75, 0x39, 0x09, 0xFF, 0x6F, 0x38, 0x07, 0xFF, 0x68, 0x3D, 0x11, 0xFF, 0xAC, 0x9B, + 0x87, 0xFF, 0xE6, 0xE5, 0xE4, 0xFF, 0xE5, 0xE5, 0xE4, 0xFF, 0xBE, 0xB9, 0xAF, 0xFF, 0xA4, 0x9B, + 0x8B, 0xFF, 0xD9, 0xD5, 0xCE, 0xFF, 0xB9, 0xA9, 0x96, 0xFF, 0x74, 0x4E, 0x22, 0xFF, 0x6F, 0x3D, + 0x08, 0xFF, 0x7F, 0x46, 0x0C, 0xFF, 0x87, 0x49, 0x0D, 0xFF, 0x8A, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, + 0x0D, 0xFF, 0x8C, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8C, 0x4B, 0x0D, 0xFF, 0x8C, 0x4B, + 0x0D, 0xFF, 0x8C, 0x4B, 0x0D, 0xFF, 0x8C, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8C, 0x4B, + 0x0D, 0xFF, 0x8C, 0x4B, 0x0D, 0xFF, 0x8C, 0x4B, 0x0D, 0xFF, 0x8C, 0x4B, 0x0D, 0xFF, 0x8C, 0x4B, + 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4A, 0x0D, 0xFF, 0x8A, 0x4A, 0x0D, 0xFF, 0x89, 0x49, + 0x0C, 0xFF, 0x8B, 0x4C, 0x12, 0xFF, 0x91, 0x56, 0x1F, 0xFF, 0x96, 0x5F, 0x2C, 0xFF, 0x95, 0x60, + 0x30, 0xFF, 0x93, 0x5E, 0x30, 0xFF, 0x90, 0x5C, 0x30, 0xFF, 0x90, 0x5E, 0x35, 0xFF, 0x9D, 0x71, + 0x4C, 0xFF, 0xB6, 0x93, 0x74, 0xD1, 0xCD, 0xB2, 0x9A, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBB, 0x99, 0x7B, 0x65, 0x95, 0x66, 0x40, 0xF7, 0x73, 0x3A, + 0x12, 0xFF, 0x6B, 0x30, 0x07, 0xFF, 0x6F, 0x33, 0x08, 0xFF, 0x74, 0x37, 0x09, 0xFF, 0x77, 0x3A, + 0x09, 0xFF, 0x73, 0x3A, 0x08, 0xFF, 0x6A, 0x3C, 0x0F, 0xFF, 0xAB, 0x98, 0x83, 0xFF, 0xE8, 0xE7, + 0xE6, 0xFF, 0xE4, 0xE3, 0xE3, 0xFF, 0xE3, 0xE3, 0xE3, 0xFF, 0xE8, 0xE7, 0xE8, 0xFF, 0xCB, 0xC7, + 0xBE, 0xFF, 0x93, 0x88, 0x75, 0xFF, 0xC4, 0xBD, 0xB2, 0xFF, 0xD0, 0xC8, 0xBB, 0xFF, 0x86, 0x67, + 0x42, 0xFF, 0x6D, 0x3E, 0x09, 0xFF, 0x7C, 0x45, 0x0B, 0xFF, 0x87, 0x4A, 0x0D, 0xFF, 0x8C, 0x4C, + 0x0D, 0xFF, 0x8D, 0x4D, 0x0E, 0xFF, 0x8D, 0x4C, 0x0E, 0xFF, 0x8D, 0x4C, 0x0D, 0xFF, 0x8D, 0x4C, + 0x0E, 0xFF, 0x8D, 0x4C, 0x0E, 0xFF, 0x8D, 0x4C, 0x0E, 0xFF, 0x8D, 0x4C, 0x0E, 0xFF, 0x8D, 0x4C, + 0x0E, 0xFF, 0x8D, 0x4C, 0x0E, 0xFF, 0x8D, 0x4C, 0x0E, 0xFF, 0x8D, 0x4C, 0x0E, 0xFF, 0x8D, 0x4C, + 0x0E, 0xFF, 0x8D, 0x4D, 0x0E, 0xFF, 0x8D, 0x4C, 0x0D, 0xFF, 0x8D, 0x4C, 0x0E, 0xFF, 0x8D, 0x4C, + 0x0D, 0xFF, 0x8C, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8E, 0x50, 0x15, 0xFF, 0x95, 0x5C, + 0x26, 0xFF, 0x97, 0x61, 0x2F, 0xFF, 0x94, 0x5F, 0x30, 0xFF, 0x92, 0x5D, 0x30, 0xFF, 0x94, 0x63, + 0x39, 0xFF, 0xA8, 0x7E, 0x5A, 0xFF, 0xC0, 0x9F, 0x83, 0x93, 0xE4, 0xD4, 0xC3, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xCC, 0xAF, 0x95, 0x20, 0xA8, 0x7E, 0x5B, 0xCE, 0x7F, 0x49, 0x1F, 0xFF, 0x6E, 0x33, + 0x09, 0xFF, 0x70, 0x33, 0x07, 0xFF, 0x75, 0x37, 0x09, 0xFF, 0x79, 0x3C, 0x0A, 0xFF, 0x77, 0x3D, + 0x09, 0xFF, 0x6B, 0x3A, 0x0B, 0xFF, 0xA1, 0x8B, 0x73, 0xFF, 0xE7, 0xE6, 0xE4, 0xFF, 0xE6, 0xE6, + 0xE6, 0xFF, 0xE6, 0xE6, 0xE6, 0xFF, 0xE7, 0xE6, 0xE6, 0xFF, 0xE6, 0xE6, 0xE6, 0xFF, 0xEA, 0xEA, + 0xEA, 0xFF, 0xD8, 0xD5, 0xD0, 0xFF, 0x8F, 0x83, 0x6E, 0xFF, 0xA7, 0x9D, 0x8E, 0xFF, 0xDA, 0xD5, + 0xCE, 0xFF, 0x9D, 0x87, 0x6B, 0xFF, 0x6E, 0x44, 0x12, 0xFF, 0x78, 0x43, 0x09, 0xFF, 0x86, 0x4A, + 0x0D, 0xFF, 0x8C, 0x4D, 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x8F, 0x4E, + 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x8F, 0x4E, + 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x8F, 0x4E, + 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x8F, 0x4E, + 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8D, 0x4C, 0x0D, 0xFF, 0x8D, 0x4D, + 0x10, 0xFF, 0x93, 0x58, 0x1F, 0xFF, 0x97, 0x61, 0x2D, 0xFF, 0x95, 0x60, 0x2F, 0xFF, 0x93, 0x5F, + 0x31, 0xFF, 0x9B, 0x6C, 0x42, 0xFF, 0xB4, 0x8F, 0x6D, 0xEA, 0xCB, 0xAE, 0x94, 0x42, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xBA, 0x97, 0x77, 0x76, 0x94, 0x62, 0x39, 0xFD, 0x75, 0x3A, 0x0F, 0xFF, 0x71, 0x34, + 0x08, 0xFF, 0x76, 0x38, 0x08, 0xFF, 0x7B, 0x3C, 0x0A, 0xFF, 0x7D, 0x40, 0x0A, 0xFF, 0x71, 0x3B, + 0x07, 0xFF, 0x94, 0x77, 0x57, 0xFF, 0xE3, 0xE1, 0xDE, 0xFF, 0xE5, 0xE5, 0xE5, 0xFF, 0xE6, 0xE5, + 0xE5, 0xFF, 0xE8, 0xE8, 0xE8, 0xFF, 0xEA, 0xE9, 0xE9, 0xFF, 0xEA, 0xE9, 0xE9, 0xFF, 0xE9, 0xE9, + 0xE9, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xE2, 0xE1, 0xDF, 0xFF, 0x97, 0x8C, 0x7B, 0xFF, 0x8C, 0x7F, + 0x69, 0xFF, 0xD3, 0xCF, 0xC8, 0xFF, 0xB5, 0xA7, 0x95, 0xFF, 0x76, 0x52, 0x23, 0xFF, 0x73, 0x41, + 0x08, 0xFF, 0x83, 0x4A, 0x0D, 0xFF, 0x8D, 0x4E, 0x0E, 0xFF, 0x90, 0x50, 0x0E, 0xFF, 0x91, 0x50, + 0x0F, 0xFF, 0x91, 0x50, 0x0E, 0xFF, 0x91, 0x50, 0x0E, 0xFF, 0x91, 0x50, 0x0E, 0xFF, 0x91, 0x50, + 0x0E, 0xFF, 0x91, 0x50, 0x0F, 0xFF, 0x91, 0x50, 0x0F, 0xFF, 0x91, 0x50, 0x0F, 0xFF, 0x91, 0x50, + 0x0F, 0xFF, 0x91, 0x50, 0x0F, 0xFF, 0x91, 0x50, 0x0F, 0xFF, 0x91, 0x50, 0x0F, 0xFF, 0x91, 0x50, + 0x0F, 0xFF, 0x91, 0x50, 0x0E, 0xFF, 0x91, 0x50, 0x0F, 0xFF, 0x90, 0x4F, 0x0F, 0xFF, 0x8F, 0x4E, + 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x91, 0x54, 0x19, 0xFF, 0x97, 0x5F, 0x2A, 0xFF, 0x97, 0x61, + 0x2F, 0xFF, 0x97, 0x63, 0x35, 0xFF, 0xA8, 0x7C, 0x54, 0xFF, 0xC1, 0xA0, 0x81, 0xA4, 0xE0, 0xCD, + 0xBA, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xBD, + 0xA6, 0x1C, 0xAB, 0x81, 0x5C, 0xCD, 0x83, 0x4A, 0x1E, 0xFF, 0x73, 0x36, 0x09, 0xFF, 0x76, 0x38, + 0x09, 0xFF, 0x7B, 0x3D, 0x0A, 0xFF, 0x81, 0x41, 0x0B, 0xFF, 0x7E, 0x41, 0x09, 0xFF, 0x90, 0x68, + 0x3E, 0xFF, 0xDF, 0xDA, 0xD3, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xE6, 0xE6, 0xE6, 0xFF, 0xE7, 0xE7, + 0xE6, 0xFF, 0xE8, 0xE8, 0xE8, 0xFF, 0xEB, 0xEB, 0xEA, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xEC, 0xEC, + 0xEC, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEA, 0xE9, 0xE8, 0xFF, 0xA6, 0x9D, + 0x8D, 0xFF, 0x7A, 0x6A, 0x4F, 0xFF, 0xC0, 0xB9, 0xB0, 0xFF, 0xCA, 0xC1, 0xB7, 0xFF, 0x86, 0x69, + 0x42, 0xFF, 0x70, 0x42, 0x0B, 0xFF, 0x80, 0x49, 0x0C, 0xFF, 0x8C, 0x4F, 0x0F, 0xFF, 0x91, 0x51, + 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x52, + 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x52, + 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x52, + 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x92, 0x51, + 0x0F, 0xFF, 0x91, 0x50, 0x0E, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x91, 0x52, 0x15, 0xFF, 0x97, 0x5E, + 0x27, 0xFF, 0x98, 0x62, 0x30, 0xFF, 0x9F, 0x6D, 0x41, 0xFF, 0xB7, 0x91, 0x6D, 0xEA, 0xCF, 0xB2, + 0x97, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0xA3, + 0x84, 0x5F, 0x9B, 0x6A, 0x3F, 0xF8, 0x7B, 0x3E, 0x11, 0xFF, 0x76, 0x38, 0x08, 0xFF, 0x7B, 0x3D, + 0x09, 0xFF, 0x81, 0x41, 0x0B, 0xFF, 0x86, 0x46, 0x0C, 0xFF, 0x84, 0x45, 0x09, 0xFF, 0xA7, 0x82, + 0x5A, 0xFF, 0xED, 0xEB, 0xE9, 0xFF, 0xEB, 0xEB, 0xEC, 0xFF, 0xEB, 0xEA, 0xEA, 0xFF, 0xEA, 0xEA, + 0xEA, 0xFF, 0xEA, 0xEA, 0xE9, 0xFF, 0xEB, 0xEA, 0xEA, 0xFF, 0xED, 0xED, 0xEC, 0xFF, 0xEE, 0xEE, + 0xEE, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEF, 0xEF, 0xEF, 0xFF, 0xEE, 0xEF, + 0xEE, 0xFF, 0xB8, 0xB1, 0xA6, 0xFF, 0x73, 0x62, 0x46, 0xFF, 0xA9, 0x9F, 0x8D, 0xFF, 0xD6, 0xD2, + 0xCD, 0xFF, 0x9D, 0x88, 0x6B, 0xFF, 0x72, 0x49, 0x14, 0xFF, 0x7C, 0x48, 0x0C, 0xFF, 0x8B, 0x50, + 0x10, 0xFF, 0x93, 0x53, 0x10, 0xFF, 0x95, 0x54, 0x11, 0xFF, 0x95, 0x54, 0x11, 0xFF, 0x95, 0x54, + 0x10, 0xFF, 0x95, 0x54, 0x10, 0xFF, 0x95, 0x54, 0x10, 0xFF, 0x95, 0x54, 0x10, 0xFF, 0x95, 0x54, + 0x0F, 0xFF, 0x95, 0x53, 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x53, + 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x94, 0x54, 0x0F, 0xFF, 0x94, 0x53, + 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x90, 0x52, + 0x13, 0xFF, 0x97, 0x5D, 0x25, 0xFF, 0x9B, 0x66, 0x34, 0xFF, 0xAE, 0x82, 0x58, 0xFF, 0xC7, 0xA6, + 0x87, 0x8F, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF6, 0xEE, 0xE3, 0x09, 0xB7, 0x90, + 0x6C, 0xAA, 0x8E, 0x56, 0x28, 0xFF, 0x7A, 0x3B, 0x0B, 0xFF, 0x7C, 0x3C, 0x09, 0xFF, 0x81, 0x41, + 0x0A, 0xFF, 0x86, 0x46, 0x0C, 0xFF, 0x8B, 0x4A, 0x0D, 0xFF, 0x8D, 0x4D, 0x0D, 0xFF, 0x89, 0x50, + 0x13, 0xFF, 0xC0, 0xA8, 0x8C, 0xFF, 0xF0, 0xF0, 0xF0, 0xFF, 0xED, 0xED, 0xED, 0xFF, 0xED, 0xED, + 0xED, 0xFF, 0xED, 0xED, 0xEC, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xED, 0xED, 0xEC, 0xFF, 0xEE, 0xEE, + 0xEE, 0xFF, 0xEF, 0xEF, 0xEF, 0xFF, 0xF0, 0xF0, 0xF0, 0xFF, 0xF0, 0xF0, 0xF0, 0xFF, 0xF0, 0xF1, + 0xF0, 0xFF, 0xF1, 0xF2, 0xF2, 0xFF, 0xCA, 0xC5, 0xBE, 0xFF, 0x79, 0x69, 0x4A, 0xFF, 0x92, 0x85, + 0x6D, 0xFF, 0xD8, 0xD5, 0xD1, 0xFF, 0xB6, 0xA9, 0x97, 0xFF, 0x7B, 0x58, 0x29, 0xFF, 0x78, 0x48, + 0x0D, 0xFF, 0x8A, 0x51, 0x12, 0xFF, 0x94, 0x56, 0x13, 0xFF, 0x97, 0x58, 0x13, 0xFF, 0x98, 0x58, + 0x13, 0xFF, 0x98, 0x58, 0x13, 0xFF, 0x98, 0x58, 0x13, 0xFF, 0x98, 0x58, 0x13, 0xFF, 0x98, 0x57, + 0x13, 0xFF, 0x98, 0x57, 0x12, 0xFF, 0x97, 0x56, 0x11, 0xFF, 0x97, 0x56, 0x10, 0xFF, 0x97, 0x55, + 0x10, 0xFF, 0x96, 0x55, 0x10, 0xFF, 0x97, 0x55, 0x10, 0xFF, 0x97, 0x56, 0x10, 0xFF, 0x97, 0x56, + 0x10, 0xFF, 0x96, 0x55, 0x10, 0xFF, 0x95, 0x54, 0x10, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x92, 0x50, + 0x0E, 0xFF, 0x91, 0x52, 0x13, 0xFF, 0x98, 0x5E, 0x26, 0xFF, 0xA6, 0x75, 0x46, 0xFF, 0xBF, 0x9B, + 0x78, 0xD3, 0xD6, 0xBD, 0xA3, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD5, 0xBC, 0xA2, 0x2B, 0xAB, 0x7E, + 0x54, 0xE1, 0x85, 0x49, 0x18, 0xFF, 0x7C, 0x3C, 0x0A, 0xFF, 0x81, 0x40, 0x0A, 0xFF, 0x86, 0x45, + 0x0B, 0xFF, 0x8B, 0x4A, 0x0D, 0xFF, 0x90, 0x4E, 0x0E, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x91, 0x51, + 0x0D, 0xFF, 0x90, 0x5C, 0x1F, 0xFF, 0xD4, 0xC4, 0xB2, 0xFF, 0xF1, 0xF1, 0xF2, 0xFF, 0xED, 0xED, + 0xEE, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEF, 0xEF, 0xEF, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEE, 0xEE, + 0xEE, 0xFF, 0xEF, 0xEF, 0xEF, 0xFF, 0xF1, 0xF1, 0xF1, 0xFF, 0xF2, 0xF2, 0xF2, 0xFF, 0xF2, 0xF2, + 0xF2, 0xFF, 0xF2, 0xF2, 0xF2, 0xFF, 0xF4, 0xF4, 0xF5, 0xFF, 0xDA, 0xD8, 0xD3, 0xFF, 0x87, 0x79, + 0x5F, 0xFF, 0x80, 0x6F, 0x50, 0xFF, 0xD0, 0xCC, 0xC3, 0xFF, 0xCF, 0xC9, 0xBE, 0xFF, 0x8B, 0x70, + 0x49, 0xFF, 0x76, 0x4A, 0x11, 0xFF, 0x87, 0x52, 0x12, 0xFF, 0x94, 0x58, 0x14, 0xFF, 0x9A, 0x5A, + 0x14, 0xFF, 0x9B, 0x5B, 0x14, 0xFF, 0x9B, 0x5B, 0x14, 0xFF, 0x9B, 0x5B, 0x14, 0xFF, 0x9B, 0x5B, + 0x14, 0xFF, 0x9B, 0x5B, 0x14, 0xFF, 0x9B, 0x5B, 0x14, 0xFF, 0x9B, 0x5A, 0x14, 0xFF, 0x9A, 0x5A, + 0x13, 0xFF, 0x99, 0x58, 0x12, 0xFF, 0x99, 0x57, 0x10, 0xFF, 0x99, 0x57, 0x10, 0xFF, 0x99, 0x57, + 0x10, 0xFF, 0x99, 0x57, 0x10, 0xFF, 0x98, 0x57, 0x10, 0xFF, 0x97, 0x56, 0x10, 0xFF, 0x96, 0x54, + 0x0F, 0xFF, 0x93, 0x51, 0x0E, 0xFF, 0x92, 0x52, 0x13, 0xFF, 0x9F, 0x67, 0x32, 0xFF, 0xB8, 0x8F, + 0x67, 0xF6, 0xD0, 0xB2, 0x95, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC8, 0xA7, 0x86, 0x5E, 0xA0, 0x6D, + 0x40, 0xF9, 0x82, 0x43, 0x11, 0xFF, 0x80, 0x3F, 0x0A, 0xFF, 0x85, 0x45, 0x0B, 0xFF, 0x8A, 0x4A, + 0x0D, 0xFF, 0x8F, 0x4E, 0x0E, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x96, 0x55, 0x10, 0xFF, 0x98, 0x57, + 0x10, 0xFF, 0x92, 0x54, 0x0E, 0xFF, 0x9E, 0x71, 0x3B, 0xFF, 0xE2, 0xDB, 0xD0, 0xFF, 0xEF, 0xF0, + 0xF1, 0xFF, 0xED, 0xED, 0xED, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEE, 0xEE, + 0xEE, 0xFF, 0xED, 0xED, 0xED, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xF0, 0xF0, 0xF0, 0xFF, 0xF1, 0xF1, + 0xF1, 0xFF, 0xF1, 0xF1, 0xF1, 0xFF, 0xF1, 0xF1, 0xF1, 0xFF, 0xF3, 0xF3, 0xF4, 0xFF, 0xE5, 0xE4, + 0xE3, 0xFF, 0x9A, 0x8F, 0x78, 0xFF, 0x75, 0x62, 0x3E, 0xFF, 0xC0, 0xB8, 0xAA, 0xFF, 0xDE, 0xDC, + 0xD8, 0xFF, 0xA0, 0x8D, 0x70, 0xFF, 0x78, 0x51, 0x1B, 0xFF, 0x84, 0x52, 0x13, 0xFF, 0x94, 0x5A, + 0x17, 0xFF, 0x9B, 0x5D, 0x17, 0xFF, 0x9D, 0x5E, 0x18, 0xFF, 0x9E, 0x5E, 0x18, 0xFF, 0x9E, 0x5E, + 0x18, 0xFF, 0x9E, 0x5E, 0x18, 0xFF, 0x9E, 0x5E, 0x18, 0xFF, 0x9E, 0x5E, 0x18, 0xFF, 0x9E, 0x5E, + 0x17, 0xFF, 0x9E, 0x5E, 0x17, 0xFF, 0x9D, 0x5D, 0x15, 0xFF, 0x9C, 0x5B, 0x13, 0xFF, 0x9B, 0x59, + 0x11, 0xFF, 0x9A, 0x59, 0x11, 0xFF, 0x9A, 0x59, 0x11, 0xFF, 0x9A, 0x58, 0x11, 0xFF, 0x98, 0x57, + 0x10, 0xFF, 0x96, 0x55, 0x10, 0xFF, 0x93, 0x52, 0x0E, 0xFF, 0x96, 0x58, 0x1A, 0xFF, 0xB1, 0x83, + 0x54, 0xFF, 0xC3, 0xA4, 0x83, 0x8E, 0x00, 0x24, 0x4C, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x02, 0xBF, 0x99, 0x74, 0x92, 0x98, 0x61, + 0x30, 0xFF, 0x82, 0x42, 0x0D, 0xFF, 0x84, 0x43, 0x0A, 0xFF, 0x8A, 0x49, 0x0C, 0xFF, 0x8F, 0x4E, + 0x0E, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x97, 0x56, 0x10, 0xFF, 0x9A, 0x59, 0x12, 0xFF, 0x9D, 0x5D, + 0x15, 0xFF, 0x9F, 0x61, 0x19, 0xFF, 0x97, 0x5C, 0x16, 0xFF, 0xAD, 0x89, 0x5D, 0xFF, 0xE7, 0xE4, + 0xE0, 0xFF, 0xEB, 0xEB, 0xEC, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xEB, 0xEB, + 0xEB, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xED, 0xED, + 0xED, 0xFF, 0xEF, 0xEF, 0xEF, 0xFF, 0xEF, 0xEF, 0xEF, 0xFF, 0xEF, 0xEF, 0xEF, 0xFF, 0xF1, 0xF1, + 0xF1, 0xFF, 0xEC, 0xEB, 0xEB, 0xFF, 0xB0, 0xA7, 0x96, 0xFF, 0x74, 0x61, 0x3B, 0xFF, 0xAD, 0xA2, + 0x8E, 0xFF, 0xE4, 0xE4, 0xE1, 0xFF, 0xB8, 0xAD, 0x99, 0xFF, 0x80, 0x5F, 0x2F, 0xFF, 0x80, 0x52, + 0x14, 0xFF, 0x93, 0x5B, 0x19, 0xFF, 0x9D, 0x60, 0x1A, 0xFF, 0xA0, 0x62, 0x1B, 0xFF, 0xA1, 0x62, + 0x1B, 0xFF, 0xA1, 0x62, 0x1B, 0xFF, 0xA1, 0x62, 0x1A, 0xFF, 0xA1, 0x62, 0x1A, 0xFF, 0xA1, 0x62, + 0x1B, 0xFF, 0xA1, 0x62, 0x1B, 0xFF, 0xA1, 0x62, 0x1B, 0xFF, 0xA1, 0x62, 0x1A, 0xFF, 0xA0, 0x60, + 0x18, 0xFF, 0x9E, 0x5D, 0x13, 0xFF, 0x9D, 0x5B, 0x11, 0xFF, 0x9C, 0x5B, 0x11, 0xFF, 0x9B, 0x5A, + 0x11, 0xFF, 0x9A, 0x58, 0x10, 0xFF, 0x97, 0x56, 0x0F, 0xFF, 0x95, 0x54, 0x11, 0xFF, 0xA6, 0x70, + 0x39, 0xFF, 0xC1, 0x9E, 0x79, 0xC0, 0xC5, 0xB4, 0xA2, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE9, 0xD9, 0xC7, 0x0F, 0xBA, 0x91, 0x68, 0xBB, 0x93, 0x58, + 0x24, 0xFF, 0x84, 0x43, 0x0C, 0xFF, 0x89, 0x47, 0x0B, 0xFF, 0x8E, 0x4D, 0x0D, 0xFF, 0x93, 0x51, + 0x0E, 0xFF, 0x97, 0x55, 0x10, 0xFF, 0x9C, 0x5C, 0x14, 0xFF, 0xA1, 0x62, 0x1B, 0xFF, 0xA3, 0x65, + 0x1D, 0xFF, 0xA4, 0x65, 0x1E, 0xFF, 0xA2, 0x64, 0x1D, 0xFF, 0x99, 0x60, 0x1C, 0xFF, 0xBA, 0x9F, + 0x7C, 0xFF, 0xE7, 0xE7, 0xE6, 0xFF, 0xE7, 0xE7, 0xE7, 0xFF, 0xE6, 0xE6, 0xE6, 0xFF, 0xE7, 0xE7, + 0xE7, 0xFF, 0xE7, 0xE7, 0xE7, 0xFF, 0xE8, 0xE8, 0xE8, 0xFF, 0xE8, 0xE8, 0xE8, 0xFF, 0xE8, 0xE8, + 0xE8, 0xFF, 0xE8, 0xE8, 0xE8, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xEC, 0xEC, + 0xEC, 0xFF, 0xED, 0xED, 0xED, 0xFF, 0xED, 0xED, 0xEE, 0xFF, 0xC3, 0xBE, 0xB2, 0xFF, 0x7B, 0x69, + 0x45, 0xFF, 0x9B, 0x8C, 0x71, 0xFF, 0xE1, 0xDF, 0xDC, 0xFF, 0xCE, 0xC8, 0xBD, 0xFF, 0x8E, 0x74, + 0x4C, 0xFF, 0x7E, 0x54, 0x19, 0xFF, 0x90, 0x5C, 0x1B, 0xFF, 0x9D, 0x62, 0x1D, 0xFF, 0xA2, 0x65, + 0x1D, 0xFF, 0xA4, 0x65, 0x1D, 0xFF, 0xA4, 0x65, 0x1D, 0xFF, 0xA4, 0x65, 0x1D, 0xFF, 0xA4, 0x65, + 0x1D, 0xFF, 0xA4, 0x65, 0x1D, 0xFF, 0xA4, 0x65, 0x1D, 0xFF, 0xA4, 0x65, 0x1E, 0xFF, 0xA4, 0x65, + 0x1E, 0xFF, 0xA4, 0x65, 0x1D, 0xFF, 0xA2, 0x62, 0x18, 0xFF, 0x9F, 0x5E, 0x13, 0xFF, 0x9E, 0x5C, + 0x12, 0xFF, 0x9D, 0x5B, 0x11, 0xFF, 0x9B, 0x59, 0x11, 0xFF, 0x98, 0x56, 0x10, 0xFF, 0xA0, 0x64, + 0x26, 0xFF, 0xBF, 0x96, 0x6B, 0xE1, 0xE0, 0xCA, 0xB1, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDA, 0xC1, 0xA6, 0x1F, 0xB4, 0x88, 0x5B, 0xD9, 0x91, 0x53, + 0x1D, 0xFF, 0x88, 0x46, 0x0B, 0xFF, 0x8D, 0x4B, 0x0C, 0xFF, 0x92, 0x50, 0x0E, 0xFF, 0x98, 0x56, + 0x11, 0xFF, 0x9F, 0x5F, 0x19, 0xFF, 0xA4, 0x66, 0x1F, 0xFF, 0xA6, 0x68, 0x21, 0xFF, 0xA7, 0x69, + 0x21, 0xFF, 0xA7, 0x69, 0x21, 0xFF, 0xA7, 0x69, 0x21, 0xFF, 0xA4, 0x67, 0x1F, 0xFF, 0x9C, 0x68, + 0x27, 0xFF, 0xC5, 0xB2, 0x9A, 0xFF, 0xE4, 0xE5, 0xE6, 0xFF, 0xE3, 0xE3, 0xE3, 0xFF, 0xE2, 0xE2, + 0xE2, 0xFF, 0xE2, 0xE2, 0xE2, 0xFF, 0xE2, 0xE2, 0xE2, 0xFF, 0xE3, 0xE3, 0xE3, 0xFF, 0xE3, 0xE3, + 0xE3, 0xFF, 0xE3, 0xE3, 0xE3, 0xFF, 0xE3, 0xE3, 0xE3, 0xFF, 0xE5, 0xE5, 0xE5, 0xFF, 0xE8, 0xE8, + 0xE8, 0xFF, 0xE9, 0xE9, 0xE9, 0xFF, 0xE9, 0xE9, 0xEA, 0xFF, 0xEC, 0xEC, 0xED, 0xFF, 0xD4, 0xD0, + 0xC9, 0xFF, 0x88, 0x78, 0x57, 0xFF, 0x8C, 0x7A, 0x58, 0xFF, 0xD7, 0xD3, 0xCC, 0xFF, 0xDC, 0xDA, + 0xD7, 0xFF, 0xA1, 0x8F, 0x70, 0xFF, 0x7F, 0x5A, 0x22, 0xFF, 0x8D, 0x5C, 0x1C, 0xFF, 0x9D, 0x65, + 0x20, 0xFF, 0xA5, 0x68, 0x20, 0xFF, 0xA7, 0x69, 0x21, 0xFF, 0xA7, 0x69, 0x21, 0xFF, 0xA7, 0x69, + 0x21, 0xFF, 0xA7, 0x69, 0x21, 0xFF, 0xA7, 0x69, 0x21, 0xFF, 0xA7, 0x69, 0x21, 0xFF, 0xA7, 0x69, + 0x21, 0xFF, 0xA7, 0x69, 0x21, 0xFF, 0xA7, 0x69, 0x21, 0xFF, 0xA6, 0x68, 0x1E, 0xFF, 0xA3, 0x62, + 0x16, 0xFF, 0x9F, 0x5D, 0x12, 0xFF, 0x9E, 0x5B, 0x11, 0xFF, 0x9B, 0x59, 0x10, 0xFF, 0x9F, 0x61, + 0x1F, 0xFF, 0xBA, 0x8D, 0x5D, 0xF1, 0xDC, 0xC4, 0xAA, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD7, 0xBB, 0x9E, 0x34, 0xB1, 0x81, 0x51, 0xEB, 0x91, 0x51, + 0x18, 0xFF, 0x8C, 0x49, 0x0C, 0xFF, 0x91, 0x4F, 0x0D, 0xFF, 0x98, 0x57, 0x13, 0xFF, 0xA1, 0x62, + 0x1D, 0xFF, 0xA6, 0x69, 0x23, 0xFF, 0xA9, 0x6B, 0x24, 0xFF, 0xAA, 0x6D, 0x24, 0xFF, 0xAA, 0x6D, + 0x24, 0xFF, 0xAB, 0x6D, 0x24, 0xFF, 0xAB, 0x6D, 0x24, 0xFF, 0xAA, 0x6E, 0x24, 0xFF, 0xA5, 0x6A, + 0x22, 0xFF, 0xA2, 0x73, 0x37, 0xFF, 0xCE, 0xC2, 0xB2, 0xFF, 0xE0, 0xE1, 0xE2, 0xFF, 0xDE, 0xDE, + 0xDE, 0xFF, 0xDE, 0xDE, 0xDE, 0xFF, 0xDE, 0xDE, 0xDE, 0xFF, 0xDE, 0xDE, 0xDE, 0xFF, 0xDD, 0xDE, + 0xDE, 0xFF, 0xDE, 0xDE, 0xDE, 0xFF, 0xDF, 0xDF, 0xDF, 0xFF, 0xE2, 0xE2, 0xE2, 0xFF, 0xE3, 0xE3, + 0xE3, 0xFF, 0xE3, 0xE4, 0xE4, 0xFF, 0xE5, 0xE5, 0xE5, 0xFF, 0xE6, 0xE6, 0xE6, 0xFF, 0xE8, 0xE8, + 0xE9, 0xFF, 0xDD, 0xDB, 0xD8, 0xFF, 0x98, 0x8B, 0x6F, 0xFF, 0x81, 0x6E, 0x48, 0xFF, 0xC8, 0xC0, + 0xB4, 0xFF, 0xE3, 0xE3, 0xE2, 0xFF, 0xB6, 0xAA, 0x96, 0xFF, 0x85, 0x66, 0x35, 0xFF, 0x8A, 0x5D, + 0x1E, 0xFF, 0x9D, 0x67, 0x23, 0xFF, 0xA7, 0x6C, 0x24, 0xFF, 0xAA, 0x6D, 0x24, 0xFF, 0xAA, 0x6E, + 0x24, 0xFF, 0xAA, 0x6D, 0x24, 0xFF, 0xAB, 0x6D, 0x24, 0xFF, 0xAB, 0x6D, 0x24, 0xFF, 0xAB, 0x6D, + 0x24, 0xFF, 0xAA, 0x6D, 0x24, 0xFF, 0xAB, 0x6D, 0x24, 0xFF, 0xAB, 0x6E, 0x25, 0xFF, 0xAA, 0x6C, + 0x23, 0xFF, 0xA6, 0x66, 0x1A, 0xFF, 0xA1, 0x5F, 0x13, 0xFF, 0x9E, 0x5C, 0x11, 0xFF, 0xA1, 0x61, + 0x1B, 0xFF, 0xB8, 0x88, 0x54, 0xF9, 0xD6, 0xB9, 0x99, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0xBD, 0x9F, 0x47, 0xAF, 0x7D, 0x4B, 0xF1, 0x92, 0x52, + 0x15, 0xFF, 0x90, 0x4C, 0x0C, 0xFF, 0x98, 0x56, 0x13, 0xFF, 0xA2, 0x64, 0x21, 0xFF, 0xA7, 0x6B, + 0x26, 0xFF, 0xAA, 0x6D, 0x27, 0xFF, 0xAC, 0x6F, 0x27, 0xFF, 0xAE, 0x71, 0x28, 0xFF, 0xAE, 0x71, + 0x28, 0xFF, 0xAE, 0x71, 0x28, 0xFF, 0xAE, 0x71, 0x28, 0xFF, 0xAE, 0x71, 0x28, 0xFF, 0xAD, 0x71, + 0x28, 0xFF, 0xA6, 0x6C, 0x24, 0xFF, 0xA9, 0x81, 0x4C, 0xFF, 0xD2, 0xCC, 0xC3, 0xFF, 0xDB, 0xDC, + 0xDD, 0xFF, 0xDA, 0xDA, 0xDA, 0xFF, 0xDA, 0xDA, 0xDA, 0xFF, 0xDA, 0xDA, 0xDA, 0xFF, 0xDB, 0xDB, + 0xDB, 0xFF, 0xDB, 0xDB, 0xDC, 0xFF, 0xD8, 0xD6, 0xD3, 0xFF, 0xB4, 0xA6, 0x8F, 0xFF, 0xBD, 0xB0, + 0x99, 0xFF, 0xE0, 0xDE, 0xDC, 0xFF, 0xDF, 0xDF, 0xE0, 0xFF, 0xE2, 0xE2, 0xE2, 0xFF, 0xE4, 0xE4, + 0xE4, 0xFF, 0xE5, 0xE5, 0xE6, 0xFF, 0xE2, 0xE1, 0xE0, 0xFF, 0xAA, 0xA0, 0x8A, 0xFF, 0x80, 0x6D, + 0x45, 0xFF, 0xB9, 0xB0, 0x9E, 0xFF, 0xE2, 0xE2, 0xE3, 0xFF, 0xC8, 0xC1, 0xB6, 0xFF, 0x92, 0x79, + 0x50, 0xFF, 0x87, 0x5F, 0x22, 0xFF, 0x9B, 0x68, 0x25, 0xFF, 0xA8, 0x6E, 0x27, 0xFF, 0xAC, 0x71, + 0x28, 0xFF, 0xAE, 0x71, 0x28, 0xFF, 0xAE, 0x71, 0x28, 0xFF, 0xAE, 0x71, 0x28, 0xFF, 0xAE, 0x71, + 0x28, 0xFF, 0xAE, 0x71, 0x28, 0xFF, 0xAE, 0x71, 0x28, 0xFF, 0xAE, 0x71, 0x28, 0xFF, 0xAE, 0x71, + 0x28, 0xFF, 0xAD, 0x70, 0x27, 0xFF, 0xA9, 0x69, 0x1E, 0xFF, 0xA2, 0x5F, 0x12, 0xFF, 0xA2, 0x62, + 0x18, 0xFF, 0xB7, 0x86, 0x4E, 0xFE, 0xD5, 0xB6, 0x93, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0xBC, 0x9E, 0x53, 0xB0, 0x7C, 0x48, 0xF5, 0x94, 0x52, + 0x14, 0xFF, 0x97, 0x54, 0x13, 0xFF, 0xA2, 0x65, 0x24, 0xFF, 0xA8, 0x6C, 0x29, 0xFF, 0xAB, 0x6F, + 0x2A, 0xFF, 0xAE, 0x72, 0x2A, 0xFF, 0xB0, 0x74, 0x2B, 0xFF, 0xB1, 0x75, 0x2B, 0xFF, 0xB1, 0x75, + 0x2B, 0xFF, 0xB1, 0x75, 0x2B, 0xFF, 0xB1, 0x75, 0x2B, 0xFF, 0xB1, 0x75, 0x2B, 0xFF, 0xB1, 0x75, + 0x2B, 0xFF, 0xAF, 0x74, 0x2B, 0xFF, 0xA7, 0x6F, 0x28, 0xFF, 0xB0, 0x8F, 0x62, 0xFF, 0xD3, 0xD0, + 0xCC, 0xFF, 0xD6, 0xD6, 0xD7, 0xFF, 0xD7, 0xD7, 0xD7, 0xFF, 0xD9, 0xD9, 0xD9, 0xFF, 0xDA, 0xDA, + 0xDA, 0xFF, 0xDD, 0xDD, 0xDE, 0xFF, 0xC3, 0xBE, 0xB2, 0xFF, 0x80, 0x68, 0x3A, 0xFF, 0x8F, 0x73, + 0x44, 0xFF, 0xDA, 0xD3, 0xCA, 0xFF, 0xDF, 0xE0, 0xE2, 0xFF, 0xDF, 0xE0, 0xE1, 0xFF, 0xE2, 0xE3, + 0xE3, 0xFF, 0xE2, 0xE2, 0xE3, 0xFF, 0xE2, 0xE3, 0xE3, 0xFF, 0xE4, 0xE4, 0xE4, 0xFF, 0xBD, 0xB7, + 0xA8, 0xFF, 0x89, 0x79, 0x54, 0xFF, 0xAF, 0xA4, 0x8E, 0xFF, 0xDE, 0xDE, 0xDD, 0xFF, 0xD5, 0xD3, + 0xCE, 0xFF, 0xA2, 0x90, 0x70, 0xFF, 0x87, 0x63, 0x2B, 0xFF, 0x99, 0x69, 0x27, 0xFF, 0xA8, 0x71, + 0x2B, 0xFF, 0xAF, 0x74, 0x2B, 0xFF, 0xB1, 0x75, 0x2B, 0xFF, 0xB1, 0x75, 0x2B, 0xFF, 0xB1, 0x75, + 0x2B, 0xFF, 0xB1, 0x75, 0x2B, 0xFF, 0xB1, 0x75, 0x2B, 0xFF, 0xB1, 0x75, 0x2B, 0xFF, 0xB1, 0x75, + 0x2B, 0xFF, 0xB1, 0x75, 0x2C, 0xFF, 0xB0, 0x74, 0x2B, 0xFF, 0xAA, 0x6B, 0x20, 0xFF, 0xA5, 0x64, + 0x19, 0xFF, 0xB8, 0x84, 0x4A, 0xFF, 0xD5, 0xB5, 0x91, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD9, 0xBC, 0x9D, 0x59, 0xB1, 0x7C, 0x46, 0xF7, 0x9A, 0x59, + 0x1B, 0xFF, 0xA1, 0x64, 0x26, 0xFF, 0xA8, 0x6C, 0x2C, 0xFF, 0xAC, 0x70, 0x2C, 0xFF, 0xAF, 0x73, + 0x2D, 0xFF, 0xB1, 0x76, 0x2E, 0xFF, 0xB3, 0x78, 0x2F, 0xFF, 0xB4, 0x79, 0x2F, 0xFF, 0xB4, 0x79, + 0x2F, 0xFF, 0xB4, 0x79, 0x2F, 0xFF, 0xB4, 0x79, 0x2F, 0xFF, 0xB4, 0x79, 0x2F, 0xFF, 0xB4, 0x79, + 0x2F, 0xFF, 0xB4, 0x79, 0x2F, 0xFF, 0xB2, 0x78, 0x2E, 0xFF, 0xA9, 0x73, 0x2D, 0xFF, 0xB9, 0x9F, + 0x7D, 0xFF, 0xD5, 0xD5, 0xD4, 0xFF, 0xD6, 0xD7, 0xD7, 0xFF, 0xD7, 0xD7, 0xD7, 0xFF, 0xD7, 0xD7, + 0xD7, 0xFF, 0xD8, 0xD8, 0xD8, 0xFF, 0xD4, 0xD2, 0xCE, 0xFF, 0xAA, 0x9F, 0x87, 0xFF, 0xA2, 0x91, + 0x6F, 0xFF, 0xBD, 0xB1, 0x99, 0xFF, 0xD2, 0xCB, 0xBC, 0xFF, 0xC9, 0xC0, 0xAF, 0xFF, 0xCD, 0xC5, + 0xB7, 0xFF, 0xDE, 0xDB, 0xD5, 0xFF, 0xE2, 0xE1, 0xDF, 0xFF, 0xE2, 0xE2, 0xE2, 0xFF, 0xE3, 0xE3, + 0xE4, 0xFF, 0xCC, 0xC8, 0xBD, 0xFF, 0x95, 0x86, 0x66, 0xFF, 0xA7, 0x9B, 0x81, 0xFF, 0xDA, 0xD8, + 0xD5, 0xFF, 0xDC, 0xDC, 0xDB, 0xFF, 0xB3, 0xA7, 0x91, 0xFF, 0x8C, 0x6D, 0x39, 0xFF, 0x96, 0x6A, + 0x29, 0xFF, 0xA9, 0x74, 0x2E, 0xFF, 0xB1, 0x78, 0x2F, 0xFF, 0xB4, 0x79, 0x2F, 0xFF, 0xB4, 0x79, + 0x2F, 0xFF, 0xB4, 0x79, 0x2F, 0xFF, 0xB4, 0x79, 0x2F, 0xFF, 0xB4, 0x79, 0x2F, 0xFF, 0xB4, 0x79, + 0x2F, 0xFF, 0xB4, 0x79, 0x2F, 0xFF, 0xB3, 0x78, 0x2F, 0xFF, 0xB1, 0x76, 0x2E, 0xFF, 0xAD, 0x6F, + 0x27, 0xFF, 0xB9, 0x86, 0x4A, 0xFF, 0xD6, 0xB6, 0x90, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDA, 0xBD, 0x9D, 0x57, 0xB5, 0x82, 0x4D, 0xF7, 0xA5, 0x69, + 0x2F, 0xFF, 0xA8, 0x6C, 0x2E, 0xFF, 0xAC, 0x71, 0x30, 0xFF, 0xB0, 0x75, 0x31, 0xFF, 0xB3, 0x78, + 0x32, 0xFF, 0xB5, 0x7B, 0x32, 0xFF, 0xB7, 0x7C, 0x33, 0xFF, 0xB7, 0x7D, 0x33, 0xFF, 0xB8, 0x7D, + 0x33, 0xFF, 0xB8, 0x7D, 0x33, 0xFF, 0xB8, 0x7D, 0x33, 0xFF, 0xB8, 0x7D, 0x33, 0xFF, 0xB8, 0x7D, + 0x33, 0xFF, 0xB7, 0x7D, 0x33, 0xFF, 0xB7, 0x7E, 0x33, 0xFF, 0xB8, 0x82, 0x3C, 0xFF, 0xB4, 0x89, + 0x4D, 0xFF, 0xC7, 0xB6, 0x9F, 0xFF, 0xD7, 0xD8, 0xD8, 0xFF, 0xD6, 0xD7, 0xD7, 0xFF, 0xD7, 0xD7, + 0xD7, 0xFF, 0xD7, 0xD7, 0xD7, 0xFF, 0xD8, 0xD8, 0xD8, 0xFF, 0xDB, 0xDC, 0xDC, 0xFF, 0xDB, 0xD9, + 0xD5, 0xFF, 0xA9, 0x99, 0x79, 0xFF, 0xAD, 0x9B, 0x78, 0xFF, 0xD1, 0xCA, 0xB9, 0xFF, 0xBB, 0xB0, + 0x99, 0xFF, 0x9D, 0x89, 0x63, 0xFF, 0xAE, 0xA1, 0x85, 0xFF, 0xDF, 0xDE, 0xDC, 0xFF, 0xE0, 0xE0, + 0xE0, 0xFF, 0xE2, 0xE2, 0xE3, 0xFF, 0xD5, 0xD3, 0xCD, 0xFF, 0xA0, 0x95, 0x79, 0xFF, 0xA3, 0x96, + 0x79, 0xFF, 0xD6, 0xD4, 0xCF, 0xFF, 0xE0, 0xE0, 0xE2, 0xFF, 0xC5, 0xBD, 0xAF, 0xFF, 0x95, 0x7B, + 0x4D, 0xFF, 0x96, 0x6C, 0x2D, 0xFF, 0xAB, 0x77, 0x32, 0xFF, 0xB5, 0x7C, 0x33, 0xFF, 0xB7, 0x7D, + 0x33, 0xFF, 0xB8, 0x7D, 0x33, 0xFF, 0xB8, 0x7D, 0x33, 0xFF, 0xB8, 0x7D, 0x33, 0xFF, 0xB8, 0x7D, + 0x33, 0xFF, 0xB7, 0x7D, 0x33, 0xFF, 0xB7, 0x7C, 0x33, 0xFF, 0xB5, 0x7B, 0x32, 0xFF, 0xB5, 0x7C, + 0x37, 0xFF, 0xC0, 0x90, 0x57, 0xFF, 0xD7, 0xB7, 0x92, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDD, 0xC0, 0xA1, 0x4F, 0xBF, 0x90, 0x5E, 0xF4, 0xAD, 0x74, + 0x3A, 0xFF, 0xAC, 0x71, 0x32, 0xFF, 0xB0, 0x76, 0x34, 0xFF, 0xB4, 0x7A, 0x35, 0xFF, 0xB7, 0x7D, + 0x36, 0xFF, 0xB8, 0x7F, 0x36, 0xFF, 0xBA, 0x80, 0x37, 0xFF, 0xBB, 0x81, 0x37, 0xFF, 0xBA, 0x81, + 0x37, 0xFF, 0xBB, 0x81, 0x37, 0xFF, 0xBB, 0x81, 0x37, 0xFF, 0xBB, 0x81, 0x37, 0xFF, 0xBA, 0x81, + 0x37, 0xFF, 0xBB, 0x82, 0x38, 0xFF, 0xC0, 0x8B, 0x46, 0xFF, 0xC4, 0x93, 0x53, 0xFF, 0xC0, 0x91, + 0x52, 0xFF, 0xBA, 0x93, 0x5E, 0xFF, 0xD0, 0xC4, 0xB5, 0xFF, 0xDB, 0xDB, 0xDC, 0xFF, 0xDA, 0xDA, + 0xDA, 0xFF, 0xDB, 0xDB, 0xDB, 0xFF, 0xDB, 0xDB, 0xDB, 0xFF, 0xD9, 0xD9, 0xD9, 0xFF, 0xDD, 0xDE, + 0xDF, 0xFF, 0xC0, 0xB9, 0xA6, 0xFF, 0xAA, 0x9B, 0x7B, 0xFF, 0xD6, 0xD0, 0xC4, 0xFF, 0xDF, 0xDD, + 0xD8, 0xFF, 0xA3, 0x95, 0x74, 0xFF, 0xAA, 0x9F, 0x85, 0xFF, 0xDA, 0xDA, 0xD8, 0xFF, 0xDD, 0xDD, + 0xDE, 0xFF, 0xDF, 0xDF, 0xDF, 0xFF, 0xE1, 0xE2, 0xE2, 0xFF, 0xDC, 0xDB, 0xD8, 0xFF, 0xAE, 0xA5, + 0x8E, 0xFF, 0xA2, 0x95, 0x78, 0xFF, 0xD3, 0xD0, 0xC8, 0xFF, 0xE1, 0xE2, 0xE3, 0xFF, 0xD3, 0xCE, + 0xC4, 0xFF, 0xA3, 0x8B, 0x61, 0xFF, 0x9F, 0x74, 0x34, 0xFF, 0xB3, 0x7D, 0x36, 0xFF, 0xBA, 0x81, + 0x37, 0xFF, 0xBB, 0x81, 0x37, 0xFF, 0xBB, 0x81, 0x37, 0xFF, 0xBB, 0x81, 0x37, 0xFF, 0xBA, 0x81, + 0x37, 0xFF, 0xBB, 0x81, 0x37, 0xFF, 0xBA, 0x80, 0x37, 0xFF, 0xB8, 0x7F, 0x36, 0xFF, 0xB9, 0x81, + 0x3D, 0xFF, 0xC8, 0x9B, 0x66, 0xFF, 0xDB, 0xBD, 0x9A, 0x7D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xC3, 0xA4, 0x40, 0xC4, 0x99, 0x68, 0xEF, 0xB2, 0x7A, + 0x40, 0xFF, 0xB0, 0x75, 0x36, 0xFF, 0xB4, 0x7A, 0x38, 0xFF, 0xB7, 0x7E, 0x39, 0xFF, 0xBA, 0x81, + 0x3A, 0xFF, 0xBC, 0x83, 0x3A, 0xFF, 0xBD, 0x84, 0x3B, 0xFF, 0xBE, 0x85, 0x3B, 0xFF, 0xBD, 0x85, + 0x3B, 0xFF, 0xBD, 0x85, 0x3B, 0xFF, 0xBD, 0x85, 0x3B, 0xFF, 0xBD, 0x85, 0x3B, 0xFF, 0xBE, 0x85, + 0x3C, 0xFF, 0xC3, 0x8F, 0x4B, 0xFF, 0xC9, 0x98, 0x5A, 0xFF, 0xC9, 0x99, 0x5A, 0xFF, 0xC8, 0x98, + 0x5A, 0xFF, 0xC2, 0x95, 0x58, 0xFF, 0xC0, 0x9E, 0x6F, 0xFF, 0xD8, 0xD1, 0xC5, 0xFF, 0xDE, 0xDF, + 0xE0, 0xFF, 0xDE, 0xDE, 0xDE, 0xFF, 0xDF, 0xDF, 0xDF, 0xFF, 0xDF, 0xDF, 0xDF, 0xFF, 0xE0, 0xE0, + 0xDF, 0xFF, 0xC5, 0xBF, 0xB0, 0xFF, 0xD6, 0xD2, 0xC8, 0xFF, 0xB3, 0xA8, 0x8D, 0xFF, 0xD3, 0xCE, + 0xC2, 0xFF, 0xDF, 0xDE, 0xDD, 0xFF, 0xDB, 0xDB, 0xD9, 0xFF, 0xDB, 0xDB, 0xDB, 0xFF, 0xDA, 0xDA, + 0xDA, 0xFF, 0xDD, 0xDD, 0xDD, 0xFF, 0xE0, 0xE0, 0xE0, 0xFF, 0xE2, 0xE3, 0xE3, 0xFF, 0xE2, 0xE2, + 0xE1, 0xFF, 0xBD, 0xB7, 0xA6, 0xFF, 0xA4, 0x99, 0x7C, 0xFF, 0xD1, 0xCD, 0xC2, 0xFF, 0xE2, 0xE3, + 0xE5, 0xFF, 0xD9, 0xD4, 0xCB, 0xFF, 0xA6, 0x84, 0x4E, 0xFF, 0xB1, 0x7E, 0x38, 0xFF, 0xBD, 0x84, + 0x3B, 0xFF, 0xBE, 0x85, 0x3B, 0xFF, 0xBD, 0x85, 0x3B, 0xFF, 0xBD, 0x85, 0x3B, 0xFF, 0xBD, 0x85, + 0x3B, 0xFF, 0xBE, 0x85, 0x3B, 0xFF, 0xBD, 0x85, 0x3B, 0xFF, 0xBC, 0x83, 0x3A, 0xFF, 0xBD, 0x87, + 0x42, 0xFF, 0xCD, 0xA2, 0x6E, 0xFD, 0xDE, 0xC1, 0x9E, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xC4, 0xA4, 0x2B, 0xCB, 0xA0, 0x70, 0xE5, 0xB8, 0x81, + 0x47, 0xFF, 0xB4, 0x7A, 0x3A, 0xFF, 0xB7, 0x7E, 0x3C, 0xFF, 0xBB, 0x82, 0x3D, 0xFF, 0xBD, 0x85, + 0x3D, 0xFF, 0xBF, 0x87, 0x3E, 0xFF, 0xC0, 0x89, 0x3F, 0xFF, 0xC1, 0x89, 0x3F, 0xFF, 0xC1, 0x89, + 0x3F, 0xFF, 0xC1, 0x89, 0x3F, 0xFF, 0xC1, 0x89, 0x3F, 0xFF, 0xC1, 0x89, 0x3F, 0xFF, 0xC5, 0x92, + 0x4D, 0xFF, 0xCC, 0x9E, 0x61, 0xFF, 0xCD, 0x9E, 0x62, 0xFF, 0xCD, 0x9E, 0x61, 0xFF, 0xCD, 0x9E, + 0x61, 0xFF, 0xCC, 0x9E, 0x61, 0xFF, 0xC5, 0x9A, 0x5E, 0xFF, 0xC7, 0xA9, 0x7F, 0xFF, 0xDE, 0xDA, + 0xD4, 0xFF, 0xE3, 0xE3, 0xE4, 0xFF, 0xE3, 0xE3, 0xE3, 0xFF, 0xE3, 0xE3, 0xE4, 0xFF, 0xE3, 0xE2, + 0xE0, 0xFF, 0xC4, 0xBE, 0xAC, 0xFF, 0xE5, 0xE4, 0xE2, 0xFF, 0xD9, 0xD6, 0xCE, 0xFF, 0xB3, 0xA7, + 0x8C, 0xFF, 0xD4, 0xCF, 0xC4, 0xFF, 0xDF, 0xDF, 0xE0, 0xFF, 0xDD, 0xDD, 0xDC, 0xFF, 0xDD, 0xDD, + 0xDD, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDE, 0xDE, 0xDE, 0xFF, 0xE1, 0xE1, 0xE1, 0xFF, 0xE4, 0xE4, + 0xE4, 0xFF, 0xE6, 0xE6, 0xE6, 0xFF, 0xCD, 0xC8, 0xBC, 0xFF, 0xAA, 0xA1, 0x86, 0xFF, 0xD1, 0xCD, + 0xC2, 0xFF, 0xE5, 0xE3, 0xE0, 0xFF, 0xB3, 0x93, 0x62, 0xFF, 0xB4, 0x81, 0x3B, 0xFF, 0xC0, 0x89, + 0x3F, 0xFF, 0xC1, 0x89, 0x3F, 0xFF, 0xC1, 0x89, 0x3F, 0xFF, 0xC1, 0x89, 0x3F, 0xFF, 0xC1, 0x89, + 0x3F, 0xFF, 0xC1, 0x89, 0x3F, 0xFF, 0xC0, 0x89, 0x3F, 0xFF, 0xBF, 0x87, 0x3E, 0xFF, 0xC1, 0x8D, + 0x4A, 0xFF, 0xD1, 0xA9, 0x77, 0xF7, 0xE2, 0xCA, 0xA9, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3, 0xCA, 0xAA, 0x17, 0xD0, 0xA8, 0x7B, 0xCE, 0xBE, 0x8A, + 0x51, 0xFF, 0xB8, 0x7F, 0x3F, 0xFF, 0xBB, 0x82, 0x3F, 0xFF, 0xBE, 0x86, 0x41, 0xFF, 0xC1, 0x89, + 0x42, 0xFF, 0xC2, 0x8B, 0x42, 0xFF, 0xC3, 0x8D, 0x43, 0xFF, 0xC4, 0x8D, 0x43, 0xFF, 0xC4, 0x8D, + 0x43, 0xFF, 0xC4, 0x8D, 0x43, 0xFF, 0xC4, 0x8D, 0x43, 0xFF, 0xC7, 0x91, 0x4A, 0xFF, 0xCE, 0xA0, + 0x63, 0xFF, 0xD0, 0xA3, 0x68, 0xFF, 0xD0, 0xA3, 0x68, 0xFF, 0xD0, 0xA3, 0x68, 0xFF, 0xD0, 0xA3, + 0x68, 0xFF, 0xD0, 0xA3, 0x68, 0xFF, 0xCF, 0xA2, 0x67, 0xFF, 0xC8, 0x9E, 0x65, 0xFF, 0xCD, 0xB5, + 0x91, 0xFF, 0xE4, 0xE2, 0xDF, 0xFF, 0xE7, 0xE7, 0xE7, 0xFF, 0xE6, 0xE6, 0xE7, 0xFF, 0xE7, 0xE7, + 0xE6, 0xFF, 0xC0, 0xB6, 0xA0, 0xFF, 0xBB, 0xAD, 0x90, 0xFF, 0xD9, 0xD4, 0xCB, 0xFF, 0xD6, 0xD2, + 0xC8, 0xFF, 0xB6, 0xA8, 0x8A, 0xFF, 0xC0, 0xB2, 0x97, 0xFF, 0xD2, 0xCC, 0xBF, 0xFF, 0xDF, 0xE0, + 0xE0, 0xFF, 0xE0, 0xE0, 0xE0, 0xFF, 0xDF, 0xDF, 0xDF, 0xFF, 0xDF, 0xDF, 0xDF, 0xFF, 0xE3, 0xE3, + 0xE3, 0xFF, 0xE5, 0xE5, 0xE5, 0xFF, 0xE8, 0xE9, 0xE9, 0xFF, 0xD9, 0xD7, 0xCF, 0xFF, 0xBB, 0xB2, + 0x9B, 0xFF, 0xD7, 0xCC, 0xB9, 0xFF, 0xB6, 0x90, 0x57, 0xFF, 0xBC, 0x88, 0x41, 0xFF, 0xC3, 0x8D, + 0x43, 0xFF, 0xC4, 0x8D, 0x43, 0xFF, 0xC4, 0x8D, 0x43, 0xFF, 0xC4, 0x8D, 0x43, 0xFF, 0xC4, 0x8D, + 0x43, 0xFF, 0xC4, 0x8D, 0x43, 0xFF, 0xC3, 0x8C, 0x43, 0xFF, 0xC2, 0x8B, 0x42, 0xFF, 0xC7, 0x94, + 0x53, 0xFF, 0xD6, 0xB0, 0x81, 0xED, 0xE8, 0xD2, 0xB5, 0x3A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF5, 0xEC, 0xDE, 0x09, 0xD6, 0xB1, 0x86, 0xAC, 0xC4, 0x93, + 0x5C, 0xFF, 0xBC, 0x84, 0x45, 0xFF, 0xBF, 0x87, 0x44, 0xFF, 0xC2, 0x8B, 0x46, 0xFF, 0xC4, 0x8D, + 0x46, 0xFF, 0xC5, 0x8F, 0x47, 0xFF, 0xC8, 0x91, 0x48, 0xFF, 0xC8, 0x91, 0x48, 0xFF, 0xC8, 0x91, + 0x48, 0xFF, 0xC8, 0x91, 0x48, 0xFF, 0xC8, 0x91, 0x48, 0xFF, 0xCE, 0x9F, 0x5F, 0xFF, 0xD3, 0xA9, + 0x6F, 0xFF, 0xD3, 0xA8, 0x6E, 0xFF, 0xD3, 0xA8, 0x6E, 0xFF, 0xD3, 0xA8, 0x6E, 0xFF, 0xD3, 0xA8, + 0x6E, 0xFF, 0xD3, 0xA8, 0x6E, 0xFF, 0xD3, 0xA8, 0x6E, 0xFF, 0xD2, 0xA8, 0x6E, 0xFF, 0xCB, 0xA4, + 0x6D, 0xFF, 0xD4, 0xC0, 0xA3, 0xFF, 0xE8, 0xE7, 0xE6, 0xFF, 0xE9, 0xEA, 0xEA, 0xFF, 0xEA, 0xEA, + 0xE9, 0xFF, 0xB8, 0xB0, 0x98, 0xFF, 0x9C, 0x8C, 0x64, 0xFF, 0xC4, 0xBB, 0xA8, 0xFF, 0xE3, 0xE2, + 0xE0, 0xFF, 0xB0, 0xA3, 0x85, 0xFF, 0xA2, 0x8E, 0x62, 0xFF, 0xC3, 0xB9, 0xA5, 0xFF, 0xE2, 0xE2, + 0xE3, 0xFF, 0xE1, 0xE1, 0xE2, 0xFF, 0xE3, 0xE3, 0xE3, 0xFF, 0xE2, 0xE2, 0xE2, 0xFF, 0xE2, 0xE2, + 0xE2, 0xFF, 0xE5, 0xE5, 0xE5, 0xFF, 0xE7, 0xE7, 0xE7, 0xFF, 0xEA, 0xEA, 0xEB, 0xFF, 0xE6, 0xE3, + 0xDE, 0xFF, 0xC0, 0xAC, 0x88, 0xFF, 0xB4, 0x89, 0x49, 0xFF, 0xC1, 0x8E, 0x46, 0xFF, 0xC7, 0x91, + 0x48, 0xFF, 0xC8, 0x91, 0x48, 0xFF, 0xC8, 0x91, 0x48, 0xFF, 0xC8, 0x91, 0x48, 0xFF, 0xC8, 0x91, + 0x48, 0xFF, 0xC8, 0x91, 0x48, 0xFF, 0xC7, 0x91, 0x48, 0xFF, 0xC7, 0x90, 0x48, 0xFF, 0xCD, 0x9D, + 0x5F, 0xFF, 0xDB, 0xB8, 0x8C, 0xD5, 0xE8, 0xD3, 0xB7, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDB, 0xB8, 0x8D, 0x7E, 0xCD, 0x9F, + 0x69, 0xFF, 0xC2, 0x8B, 0x4D, 0xFF, 0xC3, 0x8B, 0x48, 0xFF, 0xC5, 0x8F, 0x4A, 0xFF, 0xC8, 0x92, + 0x4B, 0xFF, 0xCA, 0x94, 0x4B, 0xFF, 0xCC, 0x95, 0x4C, 0xFF, 0xCC, 0x96, 0x4C, 0xFF, 0xCC, 0x96, + 0x4C, 0xFF, 0xCC, 0x96, 0x4B, 0xFF, 0xCE, 0x9B, 0x55, 0xFF, 0xD6, 0xAC, 0x72, 0xFF, 0xD7, 0xAE, + 0x75, 0xFF, 0xD7, 0xAE, 0x75, 0xFF, 0xD7, 0xAE, 0x75, 0xFF, 0xD7, 0xAE, 0x75, 0xFF, 0xD7, 0xAE, + 0x75, 0xFF, 0xD7, 0xAE, 0x75, 0xFF, 0xD7, 0xAE, 0x75, 0xFF, 0xD7, 0xAE, 0x75, 0xFF, 0xD5, 0xAC, + 0x74, 0xFF, 0xCF, 0xAA, 0x77, 0xFF, 0xDB, 0xCC, 0xB4, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xEC, 0xEC, + 0xED, 0xFF, 0xE1, 0xDF, 0xDA, 0xFF, 0xD1, 0xCD, 0xC1, 0xFF, 0xE3, 0xE2, 0xDE, 0xFF, 0xE7, 0xE6, + 0xE6, 0xFF, 0xD5, 0xD2, 0xC9, 0xFF, 0xBD, 0xB6, 0xA2, 0xFF, 0xC2, 0xBD, 0xAC, 0xFF, 0xE5, 0xE5, + 0xE4, 0xFF, 0xE4, 0xE4, 0xE4, 0xFF, 0xE5, 0xE5, 0xE5, 0xFF, 0xE6, 0xE6, 0xE6, 0xFF, 0xE6, 0xE6, + 0xE6, 0xFF, 0xE5, 0xE5, 0xE5, 0xFF, 0xE7, 0xE7, 0xE7, 0xFF, 0xEC, 0xEC, 0xED, 0xFF, 0xDD, 0xDA, + 0xD0, 0xFF, 0xB9, 0xA9, 0x85, 0xFF, 0xB8, 0x96, 0x5F, 0xFF, 0xBA, 0x8D, 0x48, 0xFF, 0xC4, 0x92, + 0x4B, 0xFF, 0xCA, 0x95, 0x4C, 0xFF, 0xCB, 0x96, 0x4C, 0xFF, 0xCC, 0x96, 0x4C, 0xFF, 0xCC, 0x96, + 0x4C, 0xFF, 0xCC, 0x96, 0x4C, 0xFF, 0xCB, 0x95, 0x4C, 0xFF, 0xCB, 0x96, 0x4F, 0xFF, 0xD4, 0xA8, + 0x6D, 0xFF, 0xDC, 0xBC, 0x93, 0xAD, 0xC5, 0xBC, 0xAE, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3, 0xC5, 0xA0, 0x48, 0xD4, 0xAA, + 0x76, 0xF2, 0xC9, 0x94, 0x57, 0xFF, 0xC7, 0x8F, 0x4C, 0xFF, 0xCA, 0x93, 0x4E, 0xFF, 0xCC, 0x96, + 0x4F, 0xFF, 0xCE, 0x98, 0x4F, 0xFF, 0xCF, 0x9A, 0x50, 0xFF, 0xD0, 0x9A, 0x50, 0xFF, 0xCF, 0x9A, + 0x50, 0xFF, 0xD0, 0x9A, 0x50, 0xFF, 0xD5, 0xA7, 0x66, 0xFF, 0xDB, 0xB3, 0x7C, 0xFF, 0xDB, 0xB3, + 0x7B, 0xFF, 0xDB, 0xB3, 0x7B, 0xFF, 0xDB, 0xB3, 0x7B, 0xFF, 0xDB, 0xB3, 0x7B, 0xFF, 0xDB, 0xB3, + 0x7B, 0xFF, 0xDB, 0xB3, 0x7B, 0xFF, 0xDB, 0xB3, 0x7B, 0xFF, 0xDB, 0xB3, 0x7B, 0xFF, 0xDB, 0xB3, + 0x7B, 0xFF, 0xD8, 0xB1, 0x7A, 0xFF, 0xD2, 0xB1, 0x80, 0xFF, 0xDF, 0xD4, 0xC0, 0xFF, 0xEE, 0xEE, + 0xEE, 0xFF, 0xEF, 0xEF, 0xF0, 0xFF, 0xF0, 0xF0, 0xF1, 0xFF, 0xED, 0xED, 0xED, 0xFF, 0xEB, 0xEB, + 0xEB, 0xFF, 0xEB, 0xEB, 0xEC, 0xFF, 0xE8, 0xE8, 0xE8, 0xFF, 0xE4, 0xE4, 0xE3, 0xFF, 0xE8, 0xE8, + 0xE8, 0xFF, 0xE8, 0xE8, 0xE8, 0xFF, 0xE7, 0xE7, 0xE7, 0xFF, 0xE8, 0xE8, 0xE8, 0xFF, 0xE9, 0xE9, + 0xE9, 0xFF, 0xE8, 0xE8, 0xE8, 0xFF, 0xE9, 0xE9, 0xE9, 0xFF, 0xEF, 0xEF, 0xED, 0xFF, 0xE6, 0xE5, + 0xDF, 0xFF, 0xC3, 0xBB, 0xA2, 0xFF, 0xC7, 0xB8, 0x99, 0xFF, 0xB7, 0x99, 0x64, 0xFF, 0xB7, 0x8E, + 0x4B, 0xFF, 0xC5, 0x96, 0x4F, 0xFF, 0xCD, 0x99, 0x50, 0xFF, 0xCF, 0x9A, 0x50, 0xFF, 0xD0, 0x9A, + 0x50, 0xFF, 0xD0, 0x9A, 0x50, 0xFF, 0xCF, 0x99, 0x50, 0xFF, 0xD0, 0x9D, 0x58, 0xFF, 0xDB, 0xB2, + 0x7D, 0xFE, 0xDF, 0xC2, 0x9C, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEA, 0xD3, 0xB3, 0x1A, 0xDB, 0xB5, + 0x85, 0xCF, 0xD0, 0x9E, 0x63, 0xFF, 0xCB, 0x94, 0x52, 0xFF, 0xCD, 0x97, 0x51, 0xFF, 0xCF, 0x9A, + 0x52, 0xFF, 0xD1, 0x9C, 0x53, 0xFF, 0xD2, 0x9E, 0x54, 0xFF, 0xD3, 0x9F, 0x54, 0xFF, 0xD3, 0x9F, + 0x54, 0xFF, 0xD4, 0xA0, 0x56, 0xFF, 0xDB, 0xB2, 0x76, 0xFF, 0xDE, 0xB9, 0x82, 0xFF, 0xDE, 0xB8, + 0x81, 0xFF, 0xDE, 0xB8, 0x81, 0xFF, 0xDE, 0xB8, 0x81, 0xFF, 0xDE, 0xB8, 0x81, 0xFF, 0xDE, 0xB8, + 0x81, 0xFF, 0xDE, 0xB8, 0x81, 0xFF, 0xDE, 0xB8, 0x81, 0xFF, 0xDE, 0xB8, 0x81, 0xFF, 0xDE, 0xB8, + 0x81, 0xFF, 0xDE, 0xB8, 0x81, 0xFF, 0xDB, 0xB6, 0x80, 0xFF, 0xD6, 0xB7, 0x89, 0xFF, 0xE4, 0xDB, + 0xCC, 0xFF, 0xF0, 0xF0, 0xF1, 0xFF, 0xF0, 0xF0, 0xF0, 0xFF, 0xF0, 0xF0, 0xF0, 0xFF, 0xEF, 0xEF, + 0xEF, 0xFF, 0xED, 0xED, 0xED, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xEB, 0xEB, + 0xEB, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xEB, 0xEB, + 0xEB, 0xFF, 0xED, 0xEC, 0xEC, 0xFF, 0xE8, 0xE8, 0xE4, 0xFF, 0xEC, 0xEC, 0xE9, 0xFF, 0xEE, 0xEF, + 0xEF, 0xFF, 0xEB, 0xEA, 0xE7, 0xFF, 0xD3, 0xCE, 0xBC, 0xFF, 0xD2, 0xC9, 0xB2, 0xFF, 0xBE, 0xA5, + 0x77, 0xFF, 0xBD, 0x94, 0x52, 0xFF, 0xCD, 0x9C, 0x53, 0xFF, 0xD2, 0x9F, 0x54, 0xFF, 0xD3, 0x9F, + 0x54, 0xFF, 0xD3, 0x9E, 0x54, 0xFF, 0xD2, 0x9E, 0x55, 0xFF, 0xD6, 0xA6, 0x65, 0xFF, 0xE0, 0xBC, + 0x8C, 0xEC, 0xD8, 0xC1, 0xA2, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x02, 0xE1, 0xBF, + 0x91, 0x8D, 0xD7, 0xAA, 0x73, 0xFF, 0xD0, 0x9B, 0x5A, 0xFF, 0xD1, 0x9B, 0x55, 0xFF, 0xD3, 0x9E, + 0x57, 0xFF, 0xD4, 0xA0, 0x58, 0xFF, 0xD5, 0xA2, 0x58, 0xFF, 0xD6, 0xA3, 0x58, 0xFF, 0xD6, 0xA3, + 0x58, 0xFF, 0xD8, 0xA6, 0x5F, 0xFF, 0xE0, 0xBA, 0x82, 0xFF, 0xE1, 0xBD, 0x88, 0xFF, 0xE1, 0xBD, + 0x87, 0xFF, 0xE1, 0xBD, 0x87, 0xFF, 0xE1, 0xBD, 0x87, 0xFF, 0xE1, 0xBD, 0x87, 0xFF, 0xE1, 0xBD, + 0x87, 0xFF, 0xE1, 0xBD, 0x87, 0xFF, 0xE1, 0xBD, 0x87, 0xFF, 0xE1, 0xBD, 0x87, 0xFF, 0xE1, 0xBD, + 0x87, 0xFF, 0xE1, 0xBD, 0x87, 0xFF, 0xE1, 0xBD, 0x87, 0xFF, 0xDE, 0xBA, 0x85, 0xFF, 0xD9, 0xBD, + 0x92, 0xFF, 0xE7, 0xE0, 0xD3, 0xFF, 0xF2, 0xF2, 0xF3, 0xFF, 0xF2, 0xF2, 0xF2, 0xFF, 0xF1, 0xF1, + 0xF1, 0xFF, 0xF0, 0xF0, 0xF0, 0xFF, 0xEF, 0xEF, 0xEF, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEE, 0xEE, + 0xEE, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEE, 0xED, + 0xED, 0xFF, 0xE7, 0xE7, 0xE2, 0xFF, 0xEB, 0xEB, 0xE8, 0xFF, 0xF0, 0xF0, 0xF0, 0xFF, 0xEE, 0xEE, + 0xEE, 0xFF, 0xF1, 0xF2, 0xF2, 0xFF, 0xF0, 0xEF, 0xED, 0xFF, 0xDC, 0xD8, 0xCC, 0xFF, 0xE0, 0xD8, + 0xC7, 0xFF, 0xC1, 0xA0, 0x67, 0xFF, 0xCD, 0x9E, 0x56, 0xFF, 0xD5, 0xA3, 0x58, 0xFF, 0xD6, 0xA3, + 0x58, 0xFF, 0xD6, 0xA3, 0x58, 0xFF, 0xD6, 0xA4, 0x5C, 0xFF, 0xDD, 0xB2, 0x76, 0xFF, 0xE3, 0xC4, + 0x98, 0xBB, 0xD5, 0xC3, 0xAE, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE7, 0xCB, + 0xA1, 0x41, 0xDE, 0xB6, 0x82, 0xEC, 0xD6, 0xA4, 0x67, 0xFF, 0xD4, 0x9F, 0x5B, 0xFF, 0xD6, 0xA1, + 0x5B, 0xFF, 0xD7, 0xA4, 0x5C, 0xFF, 0xD9, 0xA6, 0x5D, 0xFF, 0xDA, 0xA7, 0x5D, 0xFF, 0xDA, 0xA7, + 0x5C, 0xFF, 0xDC, 0xAD, 0x67, 0xFF, 0xE4, 0xC0, 0x8B, 0xFF, 0xE5, 0xC1, 0x8E, 0xFF, 0xE5, 0xC1, + 0x8E, 0xFF, 0xE5, 0xC1, 0x8E, 0xFF, 0xE5, 0xC1, 0x8E, 0xFF, 0xE5, 0xC1, 0x8E, 0xFF, 0xE5, 0xC1, + 0x8E, 0xFF, 0xE5, 0xC1, 0x8E, 0xFF, 0xE5, 0xC1, 0x8E, 0xFF, 0xE5, 0xC1, 0x8E, 0xFF, 0xE5, 0xC1, + 0x8E, 0xFF, 0xE5, 0xC1, 0x8E, 0xFF, 0xE5, 0xC1, 0x8E, 0xFF, 0xE4, 0xC1, 0x8E, 0xFF, 0xE0, 0xBF, + 0x8C, 0xFF, 0xDC, 0xC3, 0x9A, 0xFF, 0xEA, 0xE4, 0xD9, 0xFF, 0xF4, 0xF5, 0xF5, 0xFF, 0xF3, 0xF3, + 0xF3, 0xFF, 0xF3, 0xF3, 0xF3, 0xFF, 0xF2, 0xF2, 0xF2, 0xFF, 0xF1, 0xF1, 0xF1, 0xFF, 0xF0, 0xF0, + 0xF0, 0xFF, 0xF1, 0xF1, 0xF1, 0xFF, 0xF1, 0xF1, 0xF2, 0xFF, 0xF0, 0xF0, 0xF0, 0xFF, 0xEA, 0xEA, + 0xE6, 0xFF, 0xED, 0xED, 0xEB, 0xFF, 0xF2, 0xF2, 0xF2, 0xFF, 0xF1, 0xF1, 0xF2, 0xFF, 0xF2, 0xF2, + 0xF1, 0xFF, 0xE0, 0xDD, 0xD2, 0xFF, 0xEE, 0xED, 0xE9, 0xFF, 0xF1, 0xF1, 0xF1, 0xFF, 0xE9, 0xE3, + 0xD7, 0xFF, 0xC9, 0xA7, 0x6D, 0xFF, 0xD2, 0xA3, 0x5B, 0xFF, 0xD9, 0xA7, 0x5D, 0xFF, 0xDA, 0xA7, + 0x5D, 0xFF, 0xDA, 0xA7, 0x5D, 0xFF, 0xDB, 0xAC, 0x67, 0xFF, 0xE3, 0xBE, 0x88, 0xFC, 0xE7, 0xCC, + 0xA3, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEA, 0xD7, + 0xBA, 0x0C, 0xE3, 0xBF, 0x8F, 0xAE, 0xDD, 0xB1, 0x77, 0xFF, 0xD8, 0xA5, 0x62, 0xFF, 0xD9, 0xA5, + 0x5F, 0xFF, 0xDA, 0xA8, 0x60, 0xFF, 0xDB, 0xAA, 0x61, 0xFF, 0xDC, 0xAB, 0x61, 0xFF, 0xDD, 0xAB, + 0x60, 0xFF, 0xDF, 0xB2, 0x6D, 0xFF, 0xE8, 0xC5, 0x92, 0xFF, 0xE8, 0xC7, 0x94, 0xFF, 0xE8, 0xC7, + 0x94, 0xFF, 0xE8, 0xC7, 0x94, 0xFF, 0xE8, 0xC7, 0x94, 0xFF, 0xE8, 0xC7, 0x94, 0xFF, 0xE8, 0xC7, + 0x94, 0xFF, 0xE8, 0xC7, 0x94, 0xFF, 0xE8, 0xC7, 0x94, 0xFF, 0xE8, 0xC7, 0x94, 0xFF, 0xE8, 0xC7, + 0x94, 0xFF, 0xE8, 0xC7, 0x94, 0xFF, 0xE8, 0xC7, 0x94, 0xFF, 0xE8, 0xC7, 0x94, 0xFF, 0xE7, 0xC7, + 0x94, 0xFF, 0xE3, 0xC3, 0x91, 0xFF, 0xE0, 0xC9, 0xA0, 0xFF, 0xED, 0xE7, 0xDC, 0xFF, 0xF6, 0xF6, + 0xF7, 0xFF, 0xF5, 0xF5, 0xF5, 0xFF, 0xF4, 0xF4, 0xF4, 0xFF, 0xF3, 0xF3, 0xF3, 0xFF, 0xF3, 0xF3, + 0xF3, 0xFF, 0xF3, 0xF3, 0xF3, 0xFF, 0xF4, 0xF3, 0xF3, 0xFF, 0xF0, 0xF0, 0xEE, 0xFF, 0xF2, 0xF2, + 0xF0, 0xFF, 0xF4, 0xF4, 0xF4, 0xFF, 0xF3, 0xF3, 0xF3, 0xFF, 0xF5, 0xF5, 0xF5, 0xFF, 0xE3, 0xE2, + 0xD9, 0xFF, 0xCB, 0xC7, 0xB3, 0xFF, 0xF2, 0xF1, 0xEE, 0xFF, 0xF3, 0xF2, 0xF0, 0xFF, 0xD9, 0xC5, + 0xA1, 0xFF, 0xCE, 0xA4, 0x61, 0xFF, 0xDA, 0xAA, 0x61, 0xFF, 0xDD, 0xAB, 0x61, 0xFF, 0xDD, 0xAB, + 0x61, 0xFF, 0xDD, 0xAC, 0x64, 0xFF, 0xE2, 0xB7, 0x79, 0xFF, 0xE8, 0xC8, 0x99, 0xD5, 0xE3, 0xCD, + 0xAD, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xE2, 0xC3, 0x99, 0x4F, 0xE4, 0xBC, 0x87, 0xF2, 0xDD, 0xAE, 0x6F, 0xFF, 0xDC, 0xA9, + 0x63, 0xFF, 0xDD, 0xAB, 0x63, 0xFF, 0xDE, 0xAD, 0x65, 0xFF, 0xDF, 0xAE, 0x65, 0xFF, 0xDF, 0xAE, + 0x64, 0xFF, 0xE2, 0xB5, 0x70, 0xFF, 0xEA, 0xCA, 0x96, 0xFF, 0xEA, 0xCB, 0x99, 0xFF, 0xEA, 0xCB, + 0x99, 0xFF, 0xEA, 0xCB, 0x99, 0xFF, 0xEA, 0xCB, 0x99, 0xFF, 0xEA, 0xCB, 0x99, 0xFF, 0xEA, 0xCB, + 0x99, 0xFF, 0xEA, 0xCB, 0x99, 0xFF, 0xEA, 0xCB, 0x99, 0xFF, 0xEA, 0xCB, 0x99, 0xFF, 0xEA, 0xCB, + 0x99, 0xFF, 0xEA, 0xCB, 0x99, 0xFF, 0xEA, 0xCB, 0x99, 0xFF, 0xEA, 0xCB, 0x99, 0xFF, 0xEA, 0xCB, + 0x99, 0xFF, 0xEA, 0xCB, 0x99, 0xFF, 0xE6, 0xC8, 0x97, 0xFF, 0xE3, 0xCC, 0xA5, 0xFF, 0xEE, 0xE7, + 0xDC, 0xFF, 0xF7, 0xF7, 0xF8, 0xFF, 0xF7, 0xF7, 0xF7, 0xFF, 0xF6, 0xF6, 0xF6, 0xFF, 0xF6, 0xF6, + 0xF7, 0xFF, 0xF4, 0xF3, 0xF1, 0xFF, 0xF5, 0xF4, 0xF2, 0xFF, 0xF6, 0xF6, 0xF6, 0xFF, 0xF6, 0xF6, + 0xF6, 0xFF, 0xF6, 0xF6, 0xF6, 0xFF, 0xF6, 0xF6, 0xF6, 0xFF, 0xF7, 0xF7, 0xF7, 0xFF, 0xF0, 0xEF, + 0xEC, 0xFF, 0xF2, 0xF1, 0xEE, 0xFF, 0xF8, 0xF8, 0xF7, 0xFF, 0xDF, 0xCF, 0xAF, 0xFF, 0xCD, 0xA6, + 0x65, 0xFF, 0xDA, 0xAC, 0x64, 0xFF, 0xDF, 0xAF, 0x65, 0xFF, 0xE0, 0xAF, 0x65, 0xFF, 0xE0, 0xAF, + 0x66, 0xFF, 0xE1, 0xB4, 0x6F, 0xFF, 0xE8, 0xC3, 0x8D, 0xFE, 0xE9, 0xCE, 0xA4, 0x7C, 0x36, 0xA7, + 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xDF, 0xCB, 0xAE, 0x0C, 0xE8, 0xC5, 0x94, 0xA8, 0xE4, 0xB9, 0x81, 0xFF, 0xE0, 0xAE, + 0x6C, 0xFF, 0xDF, 0xAE, 0x67, 0xFF, 0xE1, 0xB0, 0x68, 0xFF, 0xE2, 0xB2, 0x69, 0xFF, 0xE2, 0xB2, + 0x68, 0xFF, 0xE4, 0xB7, 0x71, 0xFF, 0xEB, 0xCC, 0x99, 0xFF, 0xEC, 0xCE, 0x9F, 0xFF, 0xEC, 0xCE, + 0x9F, 0xFF, 0xEC, 0xCE, 0x9F, 0xFF, 0xEC, 0xCE, 0x9F, 0xFF, 0xEC, 0xCE, 0x9F, 0xFF, 0xEC, 0xCE, + 0x9F, 0xFF, 0xEC, 0xCE, 0x9F, 0xFF, 0xEC, 0xCE, 0x9F, 0xFF, 0xEC, 0xCE, 0x9F, 0xFF, 0xEC, 0xCE, + 0x9F, 0xFF, 0xEC, 0xCE, 0x9F, 0xFF, 0xEC, 0xCE, 0x9F, 0xFF, 0xEC, 0xCE, 0x9F, 0xFF, 0xEC, 0xCE, + 0x9F, 0xFF, 0xEC, 0xCE, 0x9F, 0xFF, 0xEC, 0xCE, 0x9F, 0xFF, 0xE9, 0xCC, 0x9D, 0xFF, 0xE5, 0xCE, + 0xA6, 0xFF, 0xEE, 0xE6, 0xD6, 0xFF, 0xF8, 0xF8, 0xF7, 0xFF, 0xF9, 0xFA, 0xFB, 0xFF, 0xF3, 0xF0, + 0xEA, 0xFF, 0xE2, 0xD4, 0xB8, 0xFF, 0xE7, 0xDB, 0xC3, 0xFF, 0xF7, 0xF6, 0xF3, 0xFF, 0xF8, 0xF9, + 0xF9, 0xFF, 0xF9, 0xF9, 0xF9, 0xFF, 0xF1, 0xF0, 0xEB, 0xFF, 0xF0, 0xEF, 0xEA, 0xFF, 0xF9, 0xFA, + 0xFA, 0xFF, 0xFA, 0xFA, 0xF9, 0xFF, 0xEB, 0xE2, 0xCF, 0xFF, 0xD5, 0xB4, 0x7A, 0xFF, 0xDC, 0xAF, + 0x67, 0xFF, 0xE1, 0xB3, 0x69, 0xFF, 0xE3, 0xB3, 0x69, 0xFF, 0xE2, 0xB3, 0x69, 0xFF, 0xE3, 0xB4, + 0x6D, 0xFF, 0xE7, 0xBF, 0x82, 0xFF, 0xEC, 0xCD, 0x9D, 0xCF, 0xE7, 0xD2, 0xB1, 0x22, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE7, 0xCB, 0xA0, 0x3B, 0xEA, 0xC4, 0x90, 0xE3, 0xE5, 0xB9, + 0x7C, 0xFF, 0xE2, 0xB2, 0x6D, 0xFF, 0xE3, 0xB3, 0x6C, 0xFF, 0xE4, 0xB5, 0x6D, 0xFF, 0xE5, 0xB6, + 0x6D, 0xFF, 0xE6, 0xB8, 0x71, 0xFF, 0xED, 0xCD, 0x98, 0xFF, 0xF0, 0xD3, 0xA5, 0xFF, 0xEF, 0xD2, + 0xA4, 0xFF, 0xEF, 0xD2, 0xA4, 0xFF, 0xEF, 0xD2, 0xA4, 0xFF, 0xEF, 0xD2, 0xA4, 0xFF, 0xEF, 0xD2, + 0xA4, 0xFF, 0xEF, 0xD2, 0xA4, 0xFF, 0xEF, 0xD2, 0xA4, 0xFF, 0xEF, 0xD2, 0xA4, 0xFF, 0xEF, 0xD2, + 0xA4, 0xFF, 0xEF, 0xD2, 0xA4, 0xFF, 0xEF, 0xD2, 0xA4, 0xFF, 0xEF, 0xD2, 0xA4, 0xFF, 0xEF, 0xD2, + 0xA4, 0xFF, 0xEF, 0xD2, 0xA4, 0xFF, 0xEF, 0xD2, 0xA4, 0xFF, 0xEF, 0xD2, 0xA4, 0xFF, 0xEC, 0xD0, + 0xA2, 0xFF, 0xE9, 0xD0, 0xA5, 0xFF, 0xED, 0xDE, 0xC3, 0xFF, 0xF1, 0xE8, 0xD7, 0xFF, 0xE7, 0xD4, + 0xB2, 0xFF, 0xE6, 0xCD, 0xA0, 0xFF, 0xE7, 0xCE, 0xA2, 0xFF, 0xEC, 0xDD, 0xC0, 0xFF, 0xF8, 0xF6, + 0xF1, 0xFF, 0xFA, 0xFA, 0xFA, 0xFF, 0xDC, 0xDA, 0xCA, 0xFF, 0xE7, 0xE6, 0xDC, 0xFF, 0xFB, 0xFB, + 0xFB, 0xFF, 0xEF, 0xE7, 0xD7, 0xFF, 0xE2, 0xCB, 0xA1, 0xFF, 0xE1, 0xB8, 0x76, 0xFF, 0xE4, 0xB6, + 0x6D, 0xFF, 0xE5, 0xB7, 0x6E, 0xFF, 0xE5, 0xB7, 0x6E, 0xFF, 0xE5, 0xB7, 0x6F, 0xFF, 0xE7, 0xBD, + 0x7C, 0xFF, 0xED, 0xCB, 0x96, 0xF6, 0xEC, 0xD3, 0xA9, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD1, 0xDD, 0xE8, 0x02, 0xEC, 0xCC, 0x9C, 0x79, 0xEA, 0xC4, + 0x8D, 0xFB, 0xE6, 0xBA, 0x7A, 0xFF, 0xE6, 0xB6, 0x70, 0xFF, 0xE6, 0xB7, 0x70, 0xFF, 0xE7, 0xB9, + 0x71, 0xFF, 0xE7, 0xB9, 0x71, 0xFF, 0xED, 0xCA, 0x91, 0xFF, 0xF1, 0xD6, 0xA9, 0xFF, 0xF1, 0xD6, + 0xA9, 0xFF, 0xF1, 0xD6, 0xA9, 0xFF, 0xF1, 0xD6, 0xA9, 0xFF, 0xF1, 0xD6, 0xA9, 0xFF, 0xF1, 0xD6, + 0xA9, 0xFF, 0xF1, 0xD6, 0xA9, 0xFF, 0xF1, 0xD6, 0xA9, 0xFF, 0xF1, 0xD6, 0xA9, 0xFF, 0xF1, 0xD6, + 0xA9, 0xFF, 0xF1, 0xD6, 0xA9, 0xFF, 0xF1, 0xD6, 0xA9, 0xFF, 0xF1, 0xD6, 0xA9, 0xFF, 0xF1, 0xD6, + 0xA9, 0xFF, 0xF1, 0xD6, 0xA9, 0xFF, 0xF1, 0xD6, 0xA9, 0xFF, 0xF1, 0xD6, 0xA9, 0xFF, 0xF1, 0xD6, + 0xA8, 0xFF, 0xF0, 0xD5, 0xA8, 0xFF, 0xEE, 0xD3, 0xA7, 0xFF, 0xED, 0xD3, 0xA8, 0xFF, 0xEE, 0xD3, + 0xA7, 0xFF, 0xF0, 0xD5, 0xA8, 0xFF, 0xF0, 0xD5, 0xA8, 0xFF, 0xEB, 0xD2, 0xA7, 0xFF, 0xED, 0xDC, + 0xBC, 0xFF, 0xF8, 0xF5, 0xED, 0xFF, 0xF8, 0xF8, 0xF6, 0xFF, 0xFB, 0xFB, 0xFA, 0xFF, 0xF2, 0xEB, + 0xDD, 0xFF, 0xE5, 0xD2, 0xAD, 0xFF, 0xE9, 0xCC, 0x9A, 0xFF, 0xE7, 0xBB, 0x74, 0xFF, 0xE8, 0xBA, + 0x71, 0xFF, 0xE8, 0xBA, 0x71, 0xFF, 0xE8, 0xBA, 0x72, 0xFF, 0xE9, 0xBE, 0x79, 0xFF, 0xED, 0xCA, + 0x91, 0xFF, 0xEF, 0xD3, 0xA5, 0xA5, 0xE9, 0xD8, 0xBC, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEA, 0xD3, 0xAE, 0x13, 0xEE, 0xCD, + 0x9A, 0xAD, 0xEC, 0xC5, 0x8D, 0xFF, 0xE9, 0xBC, 0x7B, 0xFF, 0xE8, 0xBA, 0x74, 0xFF, 0xE9, 0xBB, + 0x74, 0xFF, 0xE9, 0xBC, 0x73, 0xFF, 0xEC, 0xC4, 0x85, 0xFF, 0xF2, 0xD7, 0xAB, 0xFF, 0xF2, 0xD9, + 0xAD, 0xFF, 0xF2, 0xD8, 0xAD, 0xFF, 0xF2, 0xD8, 0xAD, 0xFF, 0xF2, 0xD9, 0xAD, 0xFF, 0xF2, 0xD9, + 0xAD, 0xFF, 0xF2, 0xD9, 0xAD, 0xFF, 0xF2, 0xD9, 0xAD, 0xFF, 0xF2, 0xD9, 0xAD, 0xFF, 0xF2, 0xD9, + 0xAD, 0xFF, 0xF2, 0xD9, 0xAD, 0xFF, 0xF2, 0xD9, 0xAD, 0xFF, 0xF2, 0xD9, 0xAD, 0xFF, 0xF2, 0xD9, + 0xAD, 0xFF, 0xF2, 0xD9, 0xAD, 0xFF, 0xF2, 0xD9, 0xAD, 0xFF, 0xF2, 0xD8, 0xAD, 0xFF, 0xF2, 0xD9, + 0xAD, 0xFF, 0xF2, 0xD9, 0xAD, 0xFF, 0xF2, 0xD8, 0xAD, 0xFF, 0xF2, 0xD8, 0xAD, 0xFF, 0xF2, 0xD9, + 0xAD, 0xFF, 0xF2, 0xD9, 0xAD, 0xFF, 0xF2, 0xD9, 0xAD, 0xFF, 0xF2, 0xD8, 0xAD, 0xFF, 0xEE, 0xD6, + 0xAB, 0xFF, 0xEE, 0xDC, 0xBA, 0xFF, 0xF9, 0xF3, 0xEA, 0xFF, 0xF6, 0xF0, 0xE4, 0xFF, 0xE9, 0xD7, + 0xB2, 0xFF, 0xED, 0xD6, 0xAC, 0xFF, 0xED, 0xCB, 0x8F, 0xFF, 0xEA, 0xBD, 0x74, 0xFF, 0xEA, 0xBD, + 0x75, 0xFF, 0xEA, 0xBD, 0x75, 0xFF, 0xEB, 0xBF, 0x7A, 0xFF, 0xED, 0xCA, 0x8E, 0xFF, 0xF0, 0xD3, + 0xA2, 0xD0, 0xED, 0xD7, 0xB3, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEC, 0xD3, + 0xA9, 0x2B, 0xF0, 0xCE, 0x9A, 0xCB, 0xEE, 0xC8, 0x8D, 0xFF, 0xEB, 0xBF, 0x7D, 0xFF, 0xEB, 0xBE, + 0x78, 0xFF, 0xEB, 0xBE, 0x77, 0xFF, 0xEC, 0xC1, 0x7B, 0xFF, 0xF2, 0xD4, 0xA1, 0xFF, 0xF4, 0xDC, + 0xB3, 0xFF, 0xF4, 0xDB, 0xB1, 0xFF, 0xF4, 0xDC, 0xB2, 0xFF, 0xF4, 0xDC, 0xB2, 0xFF, 0xF4, 0xDC, + 0xB2, 0xFF, 0xF4, 0xDC, 0xB2, 0xFF, 0xF4, 0xDC, 0xB2, 0xFF, 0xF4, 0xDC, 0xB2, 0xFF, 0xF4, 0xDC, + 0xB2, 0xFF, 0xF4, 0xDC, 0xB2, 0xFF, 0xF4, 0xDC, 0xB2, 0xFF, 0xF4, 0xDC, 0xB2, 0xFF, 0xF4, 0xDC, + 0xB2, 0xFF, 0xF4, 0xDC, 0xB2, 0xFF, 0xF4, 0xDC, 0xB2, 0xFF, 0xF4, 0xDC, 0xB2, 0xFF, 0xF4, 0xDC, + 0xB2, 0xFF, 0xF4, 0xDB, 0xB2, 0xFF, 0xF4, 0xDC, 0xB2, 0xFF, 0xF4, 0xDC, 0xB2, 0xFF, 0xF4, 0xDC, + 0xB2, 0xFF, 0xF4, 0xDB, 0xB2, 0xFF, 0xF4, 0xDC, 0xB1, 0xFF, 0xF4, 0xDC, 0xB2, 0xFF, 0xF4, 0xDB, + 0xB2, 0xFF, 0xF1, 0xD9, 0xB0, 0xFF, 0xF1, 0xDD, 0xB8, 0xFF, 0xF0, 0xDC, 0xB8, 0xFF, 0xF0, 0xDA, + 0xB1, 0xFF, 0xF2, 0xD8, 0xAA, 0xFF, 0xED, 0xC4, 0x81, 0xFF, 0xEC, 0xBF, 0x78, 0xFF, 0xEC, 0xC0, + 0x79, 0xFF, 0xEC, 0xC2, 0x7D, 0xFF, 0xEF, 0xCB, 0x8E, 0xFF, 0xF2, 0xD4, 0xA1, 0xE5, 0xF0, 0xD8, + 0xAF, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xF2, 0xD5, 0xA6, 0x3B, 0xF1, 0xD0, 0x9B, 0xD6, 0xEF, 0xCA, 0x8F, 0xFF, 0xEE, 0xC2, + 0x80, 0xFF, 0xED, 0xC1, 0x7B, 0xFF, 0xED, 0xC1, 0x7A, 0xFF, 0xF1, 0xCB, 0x8C, 0xFF, 0xF6, 0xDD, + 0xB3, 0xFF, 0xF6, 0xDF, 0xB6, 0xFF, 0xF6, 0xDF, 0xB6, 0xFF, 0xF6, 0xDF, 0xB6, 0xFF, 0xF6, 0xDF, + 0xB6, 0xFF, 0xF6, 0xDF, 0xB6, 0xFF, 0xF6, 0xDF, 0xB6, 0xFF, 0xF6, 0xDF, 0xB6, 0xFF, 0xF6, 0xDF, + 0xB6, 0xFF, 0xF6, 0xDF, 0xB6, 0xFF, 0xF6, 0xDF, 0xB6, 0xFF, 0xF6, 0xDF, 0xB6, 0xFF, 0xF6, 0xDF, + 0xB6, 0xFF, 0xF6, 0xDF, 0xB6, 0xFF, 0xF6, 0xDF, 0xB6, 0xFF, 0xF6, 0xDF, 0xB6, 0xFF, 0xF6, 0xDF, + 0xB6, 0xFF, 0xF6, 0xDF, 0xB6, 0xFF, 0xF6, 0xDF, 0xB6, 0xFF, 0xF6, 0xDF, 0xB6, 0xFF, 0xF6, 0xDF, + 0xB6, 0xFF, 0xF6, 0xDF, 0xB6, 0xFF, 0xF6, 0xDF, 0xB6, 0xFF, 0xF6, 0xDF, 0xB6, 0xFF, 0xF6, 0xDF, + 0xB6, 0xFF, 0xF6, 0xDF, 0xB6, 0xFF, 0xF5, 0xDE, 0xB5, 0xFF, 0xF5, 0xDE, 0xB6, 0xFF, 0xF5, 0xDE, + 0xB6, 0xFF, 0xF2, 0xD1, 0x97, 0xFF, 0xEE, 0xC3, 0x7B, 0xFF, 0xEE, 0xC3, 0x7C, 0xFF, 0xEF, 0xC5, + 0x80, 0xFF, 0xF1, 0xCD, 0x8F, 0xFF, 0xF3, 0xD5, 0xA1, 0xED, 0xF3, 0xD9, 0xAD, 0x61, 0xD5, 0xE7, + 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF2, 0xD6, 0xA8, 0x47, 0xF3, 0xD3, 0x9E, 0xDB, 0xF2, 0xCD, + 0x92, 0xFF, 0xF0, 0xC7, 0x84, 0xFF, 0xEF, 0xC4, 0x7F, 0xFF, 0xF0, 0xC5, 0x7F, 0xFF, 0xF4, 0xD4, + 0x9F, 0xFF, 0xF7, 0xE1, 0xBA, 0xFF, 0xF7, 0xE1, 0xBA, 0xFF, 0xF7, 0xE1, 0xBA, 0xFF, 0xF7, 0xE1, + 0xBA, 0xFF, 0xF7, 0xE1, 0xBA, 0xFF, 0xF7, 0xE1, 0xBA, 0xFF, 0xF7, 0xE1, 0xBA, 0xFF, 0xF7, 0xE1, + 0xBA, 0xFF, 0xF7, 0xE1, 0xBA, 0xFF, 0xF7, 0xE1, 0xBA, 0xFF, 0xF7, 0xE1, 0xBA, 0xFF, 0xF7, 0xE1, + 0xBA, 0xFF, 0xF7, 0xE1, 0xBA, 0xFF, 0xF7, 0xE1, 0xBA, 0xFF, 0xF7, 0xE1, 0xBA, 0xFF, 0xF7, 0xE1, + 0xBA, 0xFF, 0xF7, 0xE1, 0xBA, 0xFF, 0xF7, 0xE1, 0xBA, 0xFF, 0xF7, 0xE1, 0xBA, 0xFF, 0xF7, 0xE1, + 0xBA, 0xFF, 0xF7, 0xE1, 0xBA, 0xFF, 0xF7, 0xE1, 0xBA, 0xFF, 0xF7, 0xE1, 0xBA, 0xFF, 0xF7, 0xE1, + 0xBA, 0xFF, 0xF7, 0xE1, 0xBA, 0xFF, 0xF7, 0xE1, 0xBA, 0xFF, 0xF7, 0xE2, 0xBB, 0xFF, 0xF5, 0xDA, + 0xA9, 0xFF, 0xF1, 0xC9, 0x83, 0xFF, 0xF0, 0xC7, 0x7F, 0xFF, 0xF1, 0xC9, 0x84, 0xFF, 0xF3, 0xCF, + 0x92, 0xFF, 0xF5, 0xD7, 0xA3, 0xF1, 0xF4, 0xDA, 0xAF, 0x6F, 0xE5, 0xE4, 0xDD, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF4, 0xD8, 0xA9, 0x45, 0xF4, 0xD5, + 0xA0, 0xD3, 0xF3, 0xD1, 0x97, 0xFF, 0xF2, 0xCB, 0x8A, 0xFF, 0xF1, 0xC8, 0x82, 0xFF, 0xF2, 0xCB, + 0x86, 0xFF, 0xF6, 0xDB, 0xAB, 0xFF, 0xF8, 0xE4, 0xBE, 0xFF, 0xF8, 0xE4, 0xBE, 0xFF, 0xF8, 0xE4, + 0xBD, 0xFF, 0xF8, 0xE4, 0xBD, 0xFF, 0xF8, 0xE4, 0xBD, 0xFF, 0xF8, 0xE4, 0xBD, 0xFF, 0xF8, 0xE4, + 0xBD, 0xFF, 0xF8, 0xE4, 0xBD, 0xFF, 0xF8, 0xE4, 0xBD, 0xFF, 0xF8, 0xE4, 0xBD, 0xFF, 0xF8, 0xE4, + 0xBD, 0xFF, 0xF8, 0xE4, 0xBD, 0xFF, 0xF8, 0xE4, 0xBD, 0xFF, 0xF8, 0xE4, 0xBD, 0xFF, 0xF8, 0xE4, + 0xBD, 0xFF, 0xF8, 0xE4, 0xBD, 0xFF, 0xF8, 0xE4, 0xBD, 0xFF, 0xF8, 0xE4, 0xBD, 0xFF, 0xF8, 0xE4, + 0xBD, 0xFF, 0xF8, 0xE4, 0xBD, 0xFF, 0xF8, 0xE4, 0xBD, 0xFF, 0xF8, 0xE4, 0xBD, 0xFF, 0xF8, 0xE4, + 0xBD, 0xFF, 0xF8, 0xE4, 0xBD, 0xFF, 0xF8, 0xE4, 0xBF, 0xFF, 0xF7, 0xDF, 0xB3, 0xFF, 0xF3, 0xCE, + 0x8D, 0xFF, 0xF2, 0xCA, 0x82, 0xFF, 0xF3, 0xCD, 0x89, 0xFF, 0xF5, 0xD2, 0x98, 0xFF, 0xF6, 0xD8, + 0xA5, 0xE9, 0xF5, 0xDC, 0xB0, 0x6A, 0xEA, 0xE5, 0xDB, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF4, 0xDB, + 0xAF, 0x35, 0xF5, 0xD7, 0xA3, 0xBD, 0xF5, 0xD4, 0x9D, 0xFE, 0xF4, 0xCF, 0x91, 0xFF, 0xF3, 0xCB, + 0x87, 0xFF, 0xF4, 0xCE, 0x8C, 0xFF, 0xF7, 0xDD, 0xAE, 0xFF, 0xF9, 0xE6, 0xC1, 0xFF, 0xF9, 0xE6, + 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, + 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, + 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, + 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, + 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, 0xC0, 0xFF, 0xF9, 0xE5, + 0xC0, 0xFF, 0xF9, 0xE6, 0xC1, 0xFF, 0xF8, 0xE1, 0xB6, 0xFF, 0xF5, 0xD1, 0x93, 0xFF, 0xF4, 0xCC, + 0x87, 0xFF, 0xF5, 0xD0, 0x91, 0xFF, 0xF6, 0xD6, 0x9E, 0xFF, 0xF7, 0xDA, 0xA8, 0xD5, 0xF6, 0xDD, + 0xB3, 0x52, 0xEC, 0xED, 0xF2, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xF3, 0xDC, 0xB4, 0x1D, 0xF5, 0xD8, 0xA7, 0x90, 0xF7, 0xD8, 0xA2, 0xF0, 0xF6, 0xD4, + 0x9A, 0xFF, 0xF5, 0xD0, 0x8F, 0xFF, 0xF5, 0xD0, 0x8F, 0xFF, 0xF8, 0xDC, 0xAC, 0xFF, 0xFA, 0xE6, + 0xC2, 0xFF, 0xFB, 0xE7, 0xC5, 0xFF, 0xFB, 0xE7, 0xC4, 0xFF, 0xFB, 0xE7, 0xC4, 0xFF, 0xFB, 0xE7, + 0xC4, 0xFF, 0xFB, 0xE7, 0xC4, 0xFF, 0xFB, 0xE7, 0xC4, 0xFF, 0xFB, 0xE7, 0xC4, 0xFF, 0xFB, 0xE7, + 0xC4, 0xFF, 0xFB, 0xE7, 0xC4, 0xFF, 0xFB, 0xE7, 0xC4, 0xFF, 0xFB, 0xE7, 0xC4, 0xFF, 0xFB, 0xE7, + 0xC4, 0xFF, 0xFB, 0xE7, 0xC4, 0xFF, 0xFB, 0xE7, 0xC4, 0xFF, 0xFB, 0xE7, 0xC4, 0xFF, 0xFB, 0xE7, + 0xC4, 0xFF, 0xFB, 0xE7, 0xC4, 0xFF, 0xFB, 0xE7, 0xC4, 0xFF, 0xFB, 0xE7, 0xC4, 0xFF, 0xFA, 0xE7, + 0xC4, 0xFF, 0xF9, 0xE0, 0xB3, 0xFF, 0xF6, 0xD3, 0x94, 0xFF, 0xF5, 0xD0, 0x8E, 0xFF, 0xF7, 0xD5, + 0x9A, 0xFF, 0xF8, 0xDA, 0xA4, 0xF9, 0xF8, 0xDC, 0xAC, 0xAF, 0xF8, 0xE0, 0xB4, 0x32, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8, 0xDA, 0xC4, 0x08, 0xF5, 0xDA, 0xAB, 0x51, 0xF7, 0xD9, + 0xA6, 0xC2, 0xF8, 0xD9, 0xA2, 0xFC, 0xF8, 0xD6, 0x9A, 0xFF, 0xF7, 0xD3, 0x94, 0xFF, 0xF8, 0xD9, + 0xA3, 0xFF, 0xFB, 0xE4, 0xBD, 0xFF, 0xFC, 0xE8, 0xC9, 0xFF, 0xFC, 0xE9, 0xC9, 0xFF, 0xFC, 0xE9, + 0xC9, 0xFF, 0xFC, 0xE9, 0xC8, 0xFF, 0xFC, 0xE9, 0xC8, 0xFF, 0xFC, 0xE9, 0xC8, 0xFF, 0xFC, 0xE9, + 0xC8, 0xFF, 0xFC, 0xE9, 0xC8, 0xFF, 0xFC, 0xE9, 0xC8, 0xFF, 0xFC, 0xE9, 0xC8, 0xFF, 0xFC, 0xE9, + 0xC8, 0xFF, 0xFC, 0xE9, 0xC8, 0xFF, 0xFC, 0xE9, 0xC8, 0xFF, 0xFC, 0xE9, 0xC8, 0xFF, 0xFC, 0xE9, + 0xC8, 0xFF, 0xFC, 0xE9, 0xC9, 0xFF, 0xFC, 0xE9, 0xC9, 0xFF, 0xFB, 0xE6, 0xC1, 0xFF, 0xF9, 0xDD, + 0xAA, 0xFF, 0xF7, 0xD5, 0x96, 0xFF, 0xF8, 0xD6, 0x99, 0xFF, 0xF8, 0xDA, 0xA4, 0xFF, 0xF9, 0xDC, + 0xA9, 0xD6, 0xF8, 0xDE, 0xB0, 0x6D, 0xF7, 0xE5, 0xC5, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF2, 0xDC, + 0xB6, 0x1A, 0xF7, 0xDC, 0xAB, 0x74, 0xF9, 0xDC, 0xA8, 0xD2, 0xF9, 0xDA, 0xA4, 0xFC, 0xF8, 0xD8, + 0x9E, 0xFF, 0xF9, 0xD8, 0x9F, 0xFF, 0xFA, 0xDF, 0xAF, 0xFF, 0xFB, 0xE6, 0xC0, 0xFF, 0xFC, 0xEA, + 0xCA, 0xFF, 0xFC, 0xEA, 0xCC, 0xFF, 0xFC, 0xEA, 0xCC, 0xFF, 0xFC, 0xEA, 0xCC, 0xFF, 0xFC, 0xEA, + 0xCC, 0xFF, 0xFC, 0xEA, 0xCC, 0xFF, 0xFC, 0xEA, 0xCB, 0xFF, 0xFC, 0xEA, 0xCB, 0xFF, 0xFC, 0xEA, + 0xCC, 0xFF, 0xFC, 0xEA, 0xCC, 0xFF, 0xFC, 0xEA, 0xCC, 0xFF, 0xFC, 0xEA, 0xCC, 0xFF, 0xFC, 0xEA, + 0xCB, 0xFF, 0xFC, 0xE7, 0xC3, 0xFF, 0xFB, 0xE1, 0xB4, 0xFF, 0xF9, 0xDA, 0xA2, 0xFF, 0xF9, 0xD9, + 0x9E, 0xFF, 0xF9, 0xDB, 0xA5, 0xFF, 0xF9, 0xDD, 0xAB, 0xE1, 0xF8, 0xDE, 0xAF, 0x8E, 0xF8, 0xE2, + 0xB9, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF5, 0xDE, 0xB5, 0x21, 0xF8, 0xDD, 0xAD, 0x6E, 0xF9, 0xDD, + 0xAA, 0xBE, 0xFA, 0xDC, 0xA7, 0xEF, 0xFA, 0xDB, 0xA4, 0xFF, 0xFA, 0xDC, 0xA6, 0xFF, 0xFB, 0xE0, + 0xAF, 0xFF, 0xFB, 0xE4, 0xBB, 0xFF, 0xFC, 0xE8, 0xC3, 0xFF, 0xFC, 0xEA, 0xCA, 0xFF, 0xFC, 0xEB, + 0xCC, 0xFF, 0xFC, 0xEB, 0xCD, 0xFF, 0xFC, 0xEB, 0xCE, 0xFF, 0xFC, 0xEB, 0xCD, 0xFF, 0xFC, 0xEB, + 0xCC, 0xFF, 0xFC, 0xEA, 0xCA, 0xFF, 0xFC, 0xE9, 0xC5, 0xFF, 0xFB, 0xE5, 0xBD, 0xFF, 0xFB, 0xE1, + 0xB2, 0xFF, 0xFA, 0xDD, 0xA8, 0xFF, 0xFA, 0xDC, 0xA5, 0xFF, 0xFA, 0xDD, 0xA8, 0xF5, 0xF9, 0xDE, + 0xAC, 0xCE, 0xF9, 0xDE, 0xB0, 0x83, 0xF6, 0xE0, 0xB7, 0x31, 0xE6, 0xE4, 0xDF, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF5, 0xE1, + 0xBD, 0x12, 0xFA, 0xE3, 0xB8, 0x44, 0xFB, 0xE0, 0xB0, 0x84, 0xFB, 0xDF, 0xAE, 0xBB, 0xFB, 0xDE, + 0xAB, 0xE2, 0xFB, 0xDE, 0xAA, 0xF4, 0xFB, 0xDF, 0xAC, 0xFD, 0xFB, 0xE1, 0xB0, 0xFF, 0xFB, 0xE2, + 0xB3, 0xFF, 0xFB, 0xE3, 0xB6, 0xFF, 0xFB, 0xE3, 0xB7, 0xFF, 0xFB, 0xE3, 0xB6, 0xFF, 0xFB, 0xE2, + 0xB4, 0xFF, 0xFB, 0xE1, 0xB1, 0xFF, 0xFB, 0xE0, 0xAE, 0xFF, 0xFB, 0xDF, 0xAB, 0xF6, 0xFB, 0xDF, + 0xAC, 0xE8, 0xFB, 0xE0, 0xB0, 0xC6, 0xFB, 0xE1, 0xB1, 0x92, 0xFB, 0xE3, 0xB8, 0x52, 0xF7, 0xE3, + 0xBE, 0x1B, 0xA5, 0xE6, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xEA, 0xC9, 0x0F, 0xFC, 0xE3, + 0xB5, 0x29, 0xFB, 0xE1, 0xB3, 0x4D, 0xFB, 0xE0, 0xAF, 0x6C, 0xFB, 0xE0, 0xAD, 0x89, 0xFB, 0xE0, + 0xAE, 0x9C, 0xFB, 0xE0, 0xAE, 0xA6, 0xFB, 0xE0, 0xAF, 0xAB, 0xFB, 0xE0, 0xAE, 0xA8, 0xFB, 0xE0, + 0xAE, 0x9F, 0xFB, 0xE0, 0xAE, 0x8F, 0xFB, 0xE1, 0xAF, 0x74, 0xFB, 0xE2, 0xB4, 0x55, 0xFC, 0xE3, + 0xB7, 0x32, 0xFC, 0xE8, 0xC3, 0x14, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xEC, + 0xCE, 0x06, 0xFD, 0xE8, 0xC0, 0x09, 0xFC, 0xE6, 0xBC, 0x0B, 0xFC, 0xE8, 0xC0, 0x0A, 0xFD, 0xEC, + 0xCB, 0x07, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFE, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFE, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFE, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFE, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFC, 0x0F, 0xFF, 0xFF, 0xFF, 0x28, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x60, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x25, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x82, 0x44, 0x0C, 0x01, 0x82, 0x44, 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x03, 0x82, 0x44, + 0x0C, 0x04, 0x82, 0x44, 0x0C, 0x05, 0x82, 0x44, 0x0C, 0x06, 0x82, 0x44, 0x0C, 0x07, 0x82, 0x44, + 0x0C, 0x08, 0x82, 0x44, 0x0C, 0x09, 0x82, 0x44, 0x0C, 0x0B, 0x82, 0x44, 0x0C, 0x0B, 0x82, 0x44, + 0x0C, 0x0C, 0x82, 0x44, 0x0C, 0x0D, 0x82, 0x44, 0x0C, 0x0D, 0x82, 0x44, 0x0C, 0x0E, 0x82, 0x44, + 0x0C, 0x0E, 0x82, 0x44, 0x0C, 0x0E, 0x82, 0x44, 0x0C, 0x0E, 0x82, 0x44, 0x0C, 0x0E, 0x82, 0x44, + 0x0C, 0x0D, 0x82, 0x44, 0x0C, 0x0D, 0x82, 0x44, 0x0C, 0x0C, 0x82, 0x44, 0x0C, 0x0B, 0x82, 0x44, + 0x0C, 0x0A, 0x82, 0x44, 0x0C, 0x09, 0x82, 0x44, 0x0C, 0x08, 0x82, 0x44, 0x0C, 0x06, 0x82, 0x44, + 0x0C, 0x05, 0x82, 0x44, 0x0C, 0x04, 0x82, 0x44, 0x0C, 0x03, 0x82, 0x44, 0x0C, 0x02, 0x82, 0x44, + 0x0C, 0x01, 0x82, 0x44, 0x0C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x44, 0x0C, 0x01, 0x82, 0x44, + 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x04, 0x82, 0x44, 0x0C, 0x07, 0x82, 0x44, 0x0C, 0x09, 0x82, 0x44, + 0x0C, 0x0C, 0x82, 0x44, 0x0C, 0x0F, 0x82, 0x44, 0x0C, 0x12, 0x82, 0x44, 0x0C, 0x14, 0x82, 0x44, + 0x0C, 0x17, 0x82, 0x44, 0x0C, 0x1A, 0x82, 0x44, 0x0C, 0x1C, 0x82, 0x44, 0x0C, 0x1E, 0x82, 0x44, + 0x0C, 0x1F, 0x82, 0x44, 0x0C, 0x20, 0x82, 0x44, 0x0C, 0x21, 0x82, 0x44, 0x0C, 0x22, 0x82, 0x44, + 0x0C, 0x23, 0x82, 0x44, 0x0C, 0x23, 0x82, 0x44, 0x0C, 0x22, 0x82, 0x44, 0x0C, 0x22, 0x82, 0x44, + 0x0C, 0x21, 0x82, 0x44, 0x0C, 0x20, 0x82, 0x44, 0x0C, 0x1E, 0x82, 0x44, 0x0C, 0x1D, 0x82, 0x44, + 0x0C, 0x1B, 0x82, 0x44, 0x0C, 0x18, 0x82, 0x44, 0x0C, 0x16, 0x82, 0x44, 0x0C, 0x13, 0x82, 0x44, + 0x0C, 0x10, 0x82, 0x44, 0x0C, 0x0D, 0x82, 0x44, 0x0C, 0x0A, 0x82, 0x44, 0x0C, 0x07, 0x82, 0x44, + 0x0C, 0x05, 0x82, 0x44, 0x0C, 0x03, 0x82, 0x44, 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x44, 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x04, 0x82, 0x44, + 0x0C, 0x08, 0x82, 0x44, 0x0C, 0x0E, 0x82, 0x44, 0x0C, 0x14, 0x82, 0x44, 0x0C, 0x1A, 0x82, 0x44, + 0x0C, 0x20, 0x82, 0x44, 0x0C, 0x26, 0x82, 0x44, 0x0C, 0x2B, 0x82, 0x44, 0x0C, 0x30, 0x82, 0x44, + 0x0C, 0x34, 0x82, 0x44, 0x0C, 0x38, 0x82, 0x44, 0x0C, 0x3B, 0x82, 0x44, 0x0C, 0x3F, 0x82, 0x44, + 0x0C, 0x41, 0x82, 0x44, 0x0C, 0x42, 0x82, 0x44, 0x0C, 0x44, 0x82, 0x44, 0x0C, 0x45, 0x82, 0x44, + 0x0C, 0x45, 0x82, 0x44, 0x0C, 0x45, 0x82, 0x44, 0x0C, 0x46, 0x82, 0x44, 0x0C, 0x45, 0x82, 0x44, + 0x0C, 0x43, 0x82, 0x44, 0x0C, 0x41, 0x82, 0x44, 0x0C, 0x3F, 0x82, 0x44, 0x0C, 0x3D, 0x82, 0x44, + 0x0C, 0x3A, 0x82, 0x44, 0x0C, 0x36, 0x82, 0x44, 0x0C, 0x32, 0x82, 0x44, 0x0C, 0x2D, 0x82, 0x44, + 0x0C, 0x28, 0x82, 0x44, 0x0C, 0x22, 0x82, 0x44, 0x0C, 0x1C, 0x82, 0x44, 0x0C, 0x16, 0x82, 0x44, + 0x0C, 0x0F, 0x82, 0x44, 0x0C, 0x0A, 0x82, 0x44, 0x0C, 0x05, 0x82, 0x44, 0x0C, 0x02, 0x81, 0x43, + 0x0B, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x82, 0x44, 0x0C, 0x01, 0x82, 0x44, 0x0C, 0x04, 0x82, 0x44, 0x0C, 0x0A, 0x82, 0x44, + 0x0C, 0x13, 0x82, 0x44, 0x0C, 0x1F, 0x82, 0x44, 0x0C, 0x2B, 0x82, 0x44, 0x0C, 0x37, 0x82, 0x44, + 0x0C, 0x41, 0x82, 0x44, 0x0C, 0x49, 0x82, 0x44, 0x0C, 0x51, 0x82, 0x44, 0x0C, 0x57, 0x82, 0x44, + 0x0C, 0x5C, 0x82, 0x44, 0x0C, 0x61, 0x82, 0x44, 0x0C, 0x65, 0x82, 0x44, 0x0C, 0x68, 0x82, 0x44, + 0x0C, 0x6B, 0x82, 0x44, 0x0C, 0x6D, 0x82, 0x44, 0x0C, 0x6F, 0x82, 0x44, 0x0B, 0x6F, 0x82, 0x43, + 0x0B, 0x70, 0x82, 0x44, 0x0B, 0x70, 0x82, 0x44, 0x0C, 0x70, 0x82, 0x44, 0x0C, 0x6F, 0x82, 0x44, + 0x0C, 0x6E, 0x82, 0x44, 0x0C, 0x6C, 0x82, 0x44, 0x0C, 0x69, 0x82, 0x44, 0x0C, 0x66, 0x82, 0x44, + 0x0C, 0x63, 0x82, 0x44, 0x0C, 0x5E, 0x82, 0x44, 0x0C, 0x59, 0x82, 0x44, 0x0C, 0x53, 0x82, 0x44, + 0x0C, 0x4C, 0x82, 0x44, 0x0C, 0x44, 0x82, 0x44, 0x0C, 0x3A, 0x82, 0x44, 0x0C, 0x2F, 0x82, 0x44, + 0x0C, 0x23, 0x82, 0x44, 0x0C, 0x17, 0x82, 0x44, 0x0C, 0x0D, 0x82, 0x44, 0x0C, 0x06, 0x82, 0x44, + 0x0C, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x82, 0x44, 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x08, 0x82, 0x44, 0x0C, 0x12, 0x82, 0x44, + 0x0C, 0x22, 0x82, 0x44, 0x0C, 0x35, 0x82, 0x44, 0x0C, 0x49, 0x82, 0x44, 0x0C, 0x59, 0x82, 0x44, + 0x0C, 0x67, 0x82, 0x44, 0x0C, 0x71, 0x82, 0x44, 0x0C, 0x79, 0x82, 0x44, 0x0C, 0x80, 0x82, 0x44, + 0x0C, 0x85, 0x82, 0x44, 0x0C, 0x8A, 0x81, 0x43, 0x0A, 0x8D, 0x81, 0x42, 0x09, 0x8F, 0x81, 0x43, + 0x0A, 0x91, 0x83, 0x45, 0x0D, 0x94, 0x85, 0x49, 0x12, 0x98, 0x87, 0x4B, 0x14, 0x9A, 0x87, 0x4B, + 0x14, 0x9B, 0x87, 0x4B, 0x14, 0x9B, 0x85, 0x48, 0x12, 0x99, 0x83, 0x45, 0x0D, 0x96, 0x81, 0x42, + 0x0A, 0x94, 0x81, 0x42, 0x09, 0x92, 0x81, 0x43, 0x0A, 0x90, 0x82, 0x44, 0x0C, 0x8E, 0x82, 0x44, + 0x0C, 0x8B, 0x82, 0x44, 0x0C, 0x87, 0x82, 0x44, 0x0C, 0x82, 0x82, 0x44, 0x0C, 0x7C, 0x82, 0x44, + 0x0C, 0x74, 0x82, 0x44, 0x0C, 0x6B, 0x82, 0x44, 0x0C, 0x5E, 0x82, 0x44, 0x0C, 0x4F, 0x82, 0x44, + 0x0C, 0x3C, 0x82, 0x44, 0x0C, 0x28, 0x82, 0x44, 0x0C, 0x17, 0x82, 0x44, 0x0C, 0x0B, 0x82, 0x44, + 0x0C, 0x04, 0x8B, 0x51, 0x1D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x4E, + 0x18, 0x01, 0x82, 0x44, 0x0C, 0x03, 0x82, 0x44, 0x0C, 0x0B, 0x82, 0x44, 0x0C, 0x1A, 0x82, 0x44, + 0x0C, 0x2F, 0x82, 0x44, 0x0C, 0x49, 0x82, 0x44, 0x0C, 0x62, 0x82, 0x44, 0x0C, 0x76, 0x82, 0x44, + 0x0C, 0x85, 0x82, 0x44, 0x0C, 0x90, 0x82, 0x44, 0x0C, 0x98, 0x82, 0x43, 0x0B, 0x9E, 0x81, 0x43, + 0x0A, 0xA2, 0x84, 0x47, 0x0F, 0xA8, 0x8B, 0x52, 0x1E, 0xB2, 0x92, 0x5F, 0x32, 0xC1, 0x96, 0x67, + 0x40, 0xD0, 0x97, 0x6B, 0x48, 0xDB, 0x98, 0x6E, 0x4E, 0xE5, 0x97, 0x6E, 0x4F, 0xEA, 0x97, 0x6E, + 0x50, 0xEB, 0x99, 0x70, 0x51, 0xEA, 0x9A, 0x70, 0x50, 0xE5, 0x99, 0x6D, 0x4A, 0xDB, 0x98, 0x69, + 0x42, 0xD0, 0x93, 0x5F, 0x32, 0xC2, 0x8A, 0x51, 0x1D, 0xB4, 0x83, 0x46, 0x0E, 0xAB, 0x81, 0x42, + 0x0A, 0xA7, 0x82, 0x43, 0x0B, 0xA4, 0x82, 0x44, 0x0C, 0xA1, 0x82, 0x44, 0x0C, 0x9B, 0x82, 0x44, + 0x0C, 0x94, 0x82, 0x44, 0x0C, 0x8A, 0x82, 0x44, 0x0C, 0x7C, 0x82, 0x44, 0x0C, 0x69, 0x82, 0x44, + 0x0C, 0x51, 0x82, 0x44, 0x0C, 0x38, 0x82, 0x44, 0x0C, 0x20, 0x82, 0x44, 0x0C, 0x0F, 0x82, 0x44, + 0x0C, 0x06, 0x83, 0x45, 0x0E, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x52, + 0x1D, 0x01, 0x82, 0x44, 0x0C, 0x04, 0x82, 0x44, 0x0C, 0x0C, 0x82, 0x44, 0x0C, 0x1C, 0x82, 0x44, + 0x0C, 0x34, 0x82, 0x44, 0x0C, 0x4F, 0x82, 0x44, 0x0C, 0x6A, 0x82, 0x44, 0x0C, 0x80, 0x82, 0x44, + 0x0C, 0x90, 0x82, 0x44, 0x0B, 0x9B, 0x81, 0x43, 0x0A, 0xA1, 0x88, 0x4D, 0x17, 0xAD, 0x93, 0x60, + 0x33, 0xC6, 0x97, 0x6A, 0x47, 0xE1, 0x92, 0x68, 0x4A, 0xF3, 0x89, 0x5F, 0x43, 0xFC, 0x81, 0x57, + 0x3C, 0xFF, 0x7C, 0x51, 0x37, 0xFF, 0x79, 0x4D, 0x33, 0xFF, 0x78, 0x4C, 0x32, 0xFF, 0x79, 0x4D, + 0x33, 0xFF, 0x7A, 0x4F, 0x35, 0xFF, 0x7E, 0x54, 0x3A, 0xFF, 0x83, 0x5A, 0x40, 0xFF, 0x8A, 0x61, + 0x48, 0xFF, 0x92, 0x6B, 0x50, 0xFC, 0x9A, 0x71, 0x54, 0xF3, 0x9B, 0x70, 0x4D, 0xE1, 0x93, 0x60, + 0x33, 0xC7, 0x87, 0x4B, 0x14, 0xB2, 0x81, 0x43, 0x0A, 0xA9, 0x82, 0x44, 0x0C, 0xA5, 0x82, 0x44, + 0x0C, 0x9E, 0x82, 0x44, 0x0C, 0x94, 0x82, 0x44, 0x0C, 0x86, 0x82, 0x44, 0x0C, 0x72, 0x82, 0x44, + 0x0C, 0x59, 0x82, 0x44, 0x0C, 0x3D, 0x82, 0x44, 0x0C, 0x23, 0x82, 0x44, 0x0C, 0x11, 0x82, 0x44, + 0x0C, 0x06, 0x82, 0x44, 0x0C, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x4B, + 0x14, 0x01, 0x82, 0x44, 0x0C, 0x03, 0x82, 0x44, 0x0C, 0x0A, 0x82, 0x44, 0x0C, 0x18, 0x82, 0x44, + 0x0C, 0x2D, 0x82, 0x44, 0x0C, 0x45, 0x82, 0x44, 0x0C, 0x5D, 0x82, 0x44, 0x0C, 0x71, 0x81, 0x42, + 0x0A, 0x7E, 0x87, 0x4B, 0x14, 0x8F, 0x95, 0x64, 0x39, 0xBB, 0x95, 0x6A, 0x49, 0xE7, 0x87, 0x5C, + 0x3F, 0xFC, 0x77, 0x4A, 0x2E, 0xFF, 0x6F, 0x40, 0x24, 0xFF, 0x6C, 0x3C, 0x21, 0xFF, 0x6D, 0x3D, + 0x21, 0xFF, 0x6E, 0x3F, 0x22, 0xFF, 0x70, 0x41, 0x24, 0xFF, 0x72, 0x43, 0x26, 0xFF, 0x74, 0x45, + 0x27, 0xFF, 0x75, 0x46, 0x29, 0xFF, 0x76, 0x48, 0x2B, 0xFF, 0x77, 0x49, 0x2C, 0xFF, 0x78, 0x4A, + 0x2E, 0xFF, 0x7A, 0x4D, 0x31, 0xFF, 0x7F, 0x53, 0x38, 0xFF, 0x89, 0x5F, 0x44, 0xFF, 0x96, 0x6E, + 0x53, 0xFC, 0x9E, 0x75, 0x55, 0xE7, 0x96, 0x65, 0x3A, 0xBD, 0x85, 0x49, 0x12, 0x98, 0x81, 0x42, + 0x0A, 0x8D, 0x82, 0x44, 0x0C, 0x85, 0x82, 0x44, 0x0C, 0x77, 0x82, 0x44, 0x0C, 0x65, 0x82, 0x44, + 0x0C, 0x4E, 0x82, 0x44, 0x0C, 0x35, 0x82, 0x44, 0x0C, 0x1F, 0x82, 0x44, 0x0C, 0x0E, 0x82, 0x44, + 0x0C, 0x05, 0x84, 0x46, 0x0F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x82, 0x44, 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x07, 0x82, 0x44, 0x0C, 0x11, 0x82, 0x44, + 0x0C, 0x1F, 0x82, 0x44, 0x0C, 0x30, 0x81, 0x43, 0x0B, 0x42, 0x82, 0x44, 0x0C, 0x50, 0x95, 0x62, + 0x35, 0x81, 0x98, 0x6C, 0x4A, 0xD0, 0x85, 0x59, 0x3B, 0xFB, 0x71, 0x41, 0x24, 0xFF, 0x69, 0x37, + 0x1A, 0xFF, 0x69, 0x37, 0x19, 0xFF, 0x6C, 0x3A, 0x1B, 0xFF, 0x6F, 0x3D, 0x1D, 0xFF, 0x72, 0x40, + 0x1F, 0xFF, 0x75, 0x43, 0x21, 0xFF, 0x77, 0x45, 0x23, 0xFF, 0x79, 0x47, 0x25, 0xFF, 0x7B, 0x49, + 0x26, 0xFF, 0x7C, 0x4B, 0x28, 0xFF, 0x7D, 0x4C, 0x29, 0xFF, 0x7D, 0x4D, 0x2B, 0xFF, 0x7E, 0x4E, + 0x2C, 0xFF, 0x7D, 0x4E, 0x2D, 0xFF, 0x7D, 0x4E, 0x2E, 0xFF, 0x7C, 0x4E, 0x30, 0xFF, 0x7F, 0x52, + 0x34, 0xFF, 0x88, 0x5D, 0x41, 0xFF, 0x98, 0x71, 0x55, 0xFA, 0xA1, 0x77, 0x56, 0xCF, 0x93, 0x5F, + 0x30, 0x87, 0x81, 0x43, 0x0A, 0x61, 0x82, 0x43, 0x0B, 0x57, 0x82, 0x44, 0x0C, 0x48, 0x82, 0x44, + 0x0C, 0x37, 0x82, 0x44, 0x0C, 0x25, 0x82, 0x44, 0x0C, 0x15, 0x82, 0x44, 0x0C, 0x0A, 0x82, 0x44, + 0x0C, 0x04, 0x8C, 0x54, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x83, 0x45, 0x0D, 0x01, 0x82, 0x44, 0x0C, 0x04, 0x82, 0x44, 0x0C, 0x09, 0x82, 0x44, + 0x0C, 0x10, 0x80, 0x40, 0x07, 0x19, 0x8C, 0x51, 0x1C, 0x28, 0x9F, 0x74, 0x50, 0x80, 0x8E, 0x62, + 0x42, 0xE7, 0x73, 0x41, 0x22, 0xFF, 0x64, 0x30, 0x12, 0xFF, 0x63, 0x2E, 0x0E, 0xFF, 0x66, 0x31, + 0x0F, 0xFF, 0x6A, 0x34, 0x11, 0xFF, 0x6E, 0x37, 0x13, 0xFF, 0x72, 0x3B, 0x14, 0xFF, 0x75, 0x3F, + 0x17, 0xFF, 0x79, 0x43, 0x1A, 0xFF, 0x7C, 0x47, 0x1E, 0xFF, 0x7F, 0x4A, 0x21, 0xFF, 0x82, 0x4D, + 0x24, 0xFF, 0x83, 0x4F, 0x27, 0xFF, 0x84, 0x50, 0x29, 0xFF, 0x85, 0x51, 0x2A, 0xFF, 0x85, 0x52, + 0x2B, 0xFF, 0x84, 0x52, 0x2D, 0xFF, 0x84, 0x52, 0x2E, 0xFF, 0x83, 0x52, 0x2F, 0xFF, 0x82, 0x52, + 0x30, 0xFF, 0x80, 0x51, 0x31, 0xFF, 0x83, 0x55, 0x37, 0xFF, 0x90, 0x65, 0x49, 0xFF, 0xA2, 0x7B, + 0x5E, 0xE5, 0xA3, 0x79, 0x54, 0x80, 0x86, 0x49, 0x12, 0x34, 0x81, 0x42, 0x09, 0x28, 0x82, 0x44, + 0x0C, 0x1E, 0x82, 0x44, 0x0C, 0x14, 0x82, 0x44, 0x0C, 0x0B, 0x82, 0x44, 0x0C, 0x05, 0x83, 0x46, + 0x0F, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x45, 0x0D, 0x01, 0x83, 0x45, 0x0D, 0x03, 0x73, 0x2D, + 0x00, 0x05, 0xA6, 0x79, 0x50, 0x12, 0xA3, 0x7B, 0x5C, 0x86, 0x84, 0x55, 0x34, 0xF5, 0x66, 0x31, + 0x10, 0xFF, 0x5E, 0x27, 0x06, 0xFF, 0x61, 0x29, 0x05, 0xFF, 0x65, 0x2C, 0x06, 0xFF, 0x69, 0x2F, + 0x07, 0xFF, 0x6D, 0x31, 0x07, 0xFF, 0x70, 0x34, 0x08, 0xFF, 0x73, 0x37, 0x08, 0xFF, 0x75, 0x39, + 0x09, 0xFF, 0x77, 0x3B, 0x0A, 0xFF, 0x79, 0x3D, 0x0C, 0xFF, 0x7C, 0x3F, 0x0E, 0xFF, 0x7E, 0x43, + 0x12, 0xFF, 0x81, 0x47, 0x17, 0xFF, 0x85, 0x4D, 0x1D, 0xFF, 0x88, 0x52, 0x24, 0xFF, 0x8A, 0x55, + 0x29, 0xFF, 0x8B, 0x57, 0x2C, 0xFF, 0x8B, 0x57, 0x2D, 0xFF, 0x8A, 0x57, 0x2E, 0xFF, 0x89, 0x56, + 0x2F, 0xFF, 0x87, 0x55, 0x30, 0xFF, 0x85, 0x54, 0x30, 0xFF, 0x84, 0x54, 0x33, 0xFF, 0x8B, 0x5E, + 0x3F, 0xFF, 0x9F, 0x78, 0x5B, 0xF1, 0xAE, 0x89, 0x6B, 0x80, 0x94, 0x5E, 0x2D, 0x16, 0x7D, 0x3C, + 0x01, 0x0C, 0x82, 0x44, 0x0C, 0x08, 0x82, 0x44, 0x0C, 0x04, 0x82, 0x44, 0x0C, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCA, 0xAB, + 0x8F, 0x09, 0xA5, 0x7E, 0x5F, 0x84, 0x81, 0x51, 0x2F, 0xF9, 0x65, 0x2E, 0x0C, 0xFF, 0x61, 0x29, + 0x06, 0xFF, 0x65, 0x2C, 0x06, 0xFF, 0x69, 0x30, 0x07, 0xFF, 0x6B, 0x32, 0x07, 0xFF, 0x6E, 0x34, + 0x07, 0xFF, 0x74, 0x39, 0x09, 0xFF, 0x79, 0x3C, 0x09, 0xFF, 0x7B, 0x3E, 0x0A, 0xFF, 0x7D, 0x3F, + 0x0A, 0xFF, 0x7E, 0x40, 0x0A, 0xFF, 0x7F, 0x40, 0x0A, 0xFF, 0x7F, 0x41, 0x0A, 0xFF, 0x80, 0x41, + 0x0A, 0xFF, 0x80, 0x41, 0x0A, 0xFF, 0x80, 0x42, 0x0B, 0xFF, 0x82, 0x44, 0x0E, 0xFF, 0x84, 0x48, + 0x13, 0xFF, 0x89, 0x4F, 0x1C, 0xFF, 0x8C, 0x55, 0x25, 0xFF, 0x8F, 0x5A, 0x2C, 0xFF, 0x8F, 0x5B, + 0x2E, 0xFF, 0x8D, 0x5A, 0x2F, 0xFF, 0x8B, 0x59, 0x30, 0xFF, 0x89, 0x58, 0x31, 0xFF, 0x87, 0x56, + 0x32, 0xFF, 0x8B, 0x5D, 0x3B, 0xFF, 0xA0, 0x78, 0x59, 0xF6, 0xB4, 0x91, 0x75, 0x79, 0xAB, 0x7F, + 0x56, 0x07, 0x63, 0x16, 0x00, 0x02, 0x85, 0x48, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFA, 0x03, 0xAC, 0x86, + 0x68, 0x76, 0x85, 0x54, 0x31, 0xF7, 0x67, 0x2F, 0x0B, 0xFF, 0x64, 0x2B, 0x06, 0xFF, 0x69, 0x2F, + 0x07, 0xFF, 0x6D, 0x33, 0x08, 0xFF, 0x6A, 0x32, 0x05, 0xFF, 0x6E, 0x3E, 0x14, 0xFF, 0x70, 0x43, + 0x19, 0xFF, 0x6D, 0x38, 0x07, 0xFF, 0x7C, 0x40, 0x0B, 0xFF, 0x82, 0x43, 0x0B, 0xFF, 0x83, 0x44, + 0x0B, 0xFF, 0x84, 0x45, 0x0C, 0xFF, 0x85, 0x45, 0x0C, 0xFF, 0x85, 0x45, 0x0C, 0xFF, 0x85, 0x46, + 0x0C, 0xFF, 0x85, 0x46, 0x0C, 0xFF, 0x85, 0x46, 0x0C, 0xFF, 0x85, 0x45, 0x0C, 0xFF, 0x85, 0x45, + 0x0B, 0xFF, 0x84, 0x45, 0x0B, 0xFF, 0x85, 0x47, 0x0E, 0xFF, 0x89, 0x4C, 0x15, 0xFF, 0x8E, 0x55, + 0x21, 0xFF, 0x91, 0x5B, 0x2B, 0xFF, 0x92, 0x5D, 0x2F, 0xFF, 0x90, 0x5C, 0x30, 0xFF, 0x8D, 0x5A, + 0x31, 0xFF, 0x8A, 0x58, 0x31, 0xFF, 0x8E, 0x5E, 0x3A, 0xFF, 0xA3, 0x7B, 0x5B, 0xF2, 0xBA, 0x99, + 0x7D, 0x67, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB4, 0x91, 0x74, 0x52, 0x8D, 0x5E, + 0x3A, 0xEE, 0x6B, 0x33, 0x0E, 0xFF, 0x68, 0x2D, 0x06, 0xFF, 0x6D, 0x31, 0x07, 0xFF, 0x71, 0x35, + 0x08, 0xFF, 0x6A, 0x33, 0x06, 0xFF, 0x77, 0x51, 0x2C, 0xFF, 0xA8, 0x97, 0x83, 0xFF, 0xC1, 0xB6, + 0xA8, 0xFF, 0x83, 0x63, 0x40, 0xFF, 0x6E, 0x3B, 0x08, 0xFF, 0x7F, 0x44, 0x0B, 0xFF, 0x87, 0x47, + 0x0C, 0xFF, 0x88, 0x48, 0x0D, 0xFF, 0x89, 0x49, 0x0D, 0xFF, 0x89, 0x49, 0x0D, 0xFF, 0x89, 0x49, + 0x0D, 0xFF, 0x89, 0x49, 0x0D, 0xFF, 0x89, 0x49, 0x0D, 0xFF, 0x89, 0x49, 0x0D, 0xFF, 0x89, 0x49, + 0x0D, 0xFF, 0x88, 0x48, 0x0D, 0xFF, 0x88, 0x48, 0x0C, 0xFF, 0x88, 0x47, 0x0C, 0xFF, 0x87, 0x48, + 0x0D, 0xFF, 0x8A, 0x4C, 0x13, 0xFF, 0x90, 0x56, 0x21, 0xFF, 0x94, 0x5D, 0x2C, 0xFF, 0x93, 0x5E, + 0x30, 0xFF, 0x90, 0x5C, 0x30, 0xFF, 0x8D, 0x5A, 0x31, 0xFF, 0x91, 0x62, 0x3D, 0xFF, 0xA9, 0x82, + 0x62, 0xE8, 0xC2, 0xA4, 0x8A, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC2, 0xA4, 0x87, 0x25, 0x9A, 0x6E, 0x4A, 0xD1, 0x72, 0x3B, + 0x13, 0xFF, 0x6A, 0x2F, 0x07, 0xFF, 0x6F, 0x33, 0x08, 0xFF, 0x74, 0x38, 0x09, 0xFF, 0x6D, 0x36, + 0x06, 0xFF, 0x80, 0x5E, 0x3A, 0xFF, 0xD1, 0xCA, 0xC1, 0xFF, 0xD9, 0xD7, 0xD4, 0xFF, 0xB6, 0xB0, + 0xA4, 0xFF, 0xC7, 0xBE, 0xB3, 0xFF, 0x9D, 0x85, 0x69, 0xFF, 0x72, 0x43, 0x11, 0xFF, 0x7D, 0x44, + 0x0A, 0xFF, 0x88, 0x4A, 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, + 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, + 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4B, 0x0D, 0xFF, 0x8B, 0x4A, + 0x0D, 0xFF, 0x8A, 0x4A, 0x0C, 0xFF, 0x8A, 0x4A, 0x0D, 0xFF, 0x8C, 0x4F, 0x14, 0xFF, 0x92, 0x59, + 0x24, 0xFF, 0x95, 0x5F, 0x2F, 0xFF, 0x93, 0x5E, 0x30, 0xFF, 0x8F, 0x5C, 0x31, 0xFF, 0x98, 0x69, + 0x43, 0xFF, 0xB2, 0x8D, 0x6D, 0xC7, 0xCD, 0xB1, 0x99, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFA, 0xF1, 0xE4, 0x04, 0xAB, 0x83, 0x61, 0x92, 0x81, 0x4B, 0x23, 0xFF, 0x6C, 0x31, + 0x08, 0xFF, 0x71, 0x34, 0x08, 0xFF, 0x77, 0x3A, 0x09, 0xFF, 0x71, 0x39, 0x07, 0xFF, 0x7F, 0x5B, + 0x35, 0xFF, 0xD3, 0xCC, 0xC3, 0xFF, 0xE7, 0xE6, 0xE7, 0xFF, 0xE5, 0xE5, 0xE5, 0xFF, 0xDE, 0xDC, + 0xD9, 0xFF, 0xAE, 0xA6, 0x98, 0xFF, 0xB8, 0xB0, 0xA3, 0xFF, 0xB4, 0xA4, 0x8F, 0xFF, 0x7A, 0x52, + 0x24, 0xFF, 0x79, 0x43, 0x09, 0xFF, 0x88, 0x4B, 0x0D, 0xFF, 0x8D, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, + 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, + 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8E, 0x4D, + 0x0E, 0xFF, 0x8D, 0x4D, 0x0E, 0xFF, 0x8D, 0x4C, 0x0E, 0xFF, 0x8C, 0x4B, 0x0D, 0xFF, 0x8C, 0x4C, + 0x0F, 0xFF, 0x90, 0x54, 0x1A, 0xFF, 0x96, 0x5E, 0x2B, 0xFF, 0x95, 0x5F, 0x30, 0xFF, 0x92, 0x5F, + 0x33, 0xFF, 0xA2, 0x76, 0x50, 0xFF, 0xBD, 0x9B, 0x7D, 0x84, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xBE, 0x9C, 0x7D, 0x3C, 0x95, 0x65, 0x3D, 0xEA, 0x73, 0x37, 0x0D, 0xFF, 0x72, 0x35, + 0x08, 0xFF, 0x79, 0x3B, 0x09, 0xFF, 0x78, 0x3C, 0x08, 0xFF, 0x7A, 0x50, 0x25, 0xFF, 0xCC, 0xC2, + 0xB7, 0xFF, 0xE8, 0xE8, 0xE8, 0xFF, 0xE7, 0xE6, 0xE6, 0xFF, 0xE8, 0xE7, 0xE7, 0xFF, 0xE9, 0xE9, + 0xE9, 0xFF, 0xE6, 0xE5, 0xE4, 0xFF, 0xAF, 0xA8, 0x9B, 0xFF, 0xA3, 0x9A, 0x8A, 0xFF, 0xBF, 0xB5, + 0xA7, 0xFF, 0x89, 0x69, 0x42, 0xFF, 0x76, 0x43, 0x0A, 0xFF, 0x87, 0x4B, 0x0C, 0xFF, 0x8E, 0x4F, + 0x0E, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x90, 0x4F, + 0x0E, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x90, 0x4F, + 0x0E, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x8F, 0x4E, + 0x0E, 0xFF, 0x8E, 0x4D, 0x0D, 0xFF, 0x8F, 0x51, 0x13, 0xFF, 0x95, 0x5C, 0x25, 0xFF, 0x96, 0x60, + 0x2F, 0xFF, 0x98, 0x66, 0x39, 0xFF, 0xB0, 0x89, 0x65, 0xE2, 0xCB, 0xAE, 0x93, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0x04, 0xAD, 0x84, 0x60, 0x9A, 0x83, 0x4B, 0x1F, 0xFF, 0x74, 0x36, 0x08, 0xFF, 0x7A, 0x3B, + 0x09, 0xFF, 0x80, 0x40, 0x0A, 0xFF, 0x80, 0x4B, 0x16, 0xFF, 0xC2, 0xB2, 0xA0, 0xFF, 0xEA, 0xEA, + 0xEA, 0xFF, 0xE6, 0xE6, 0xE6, 0xFF, 0xE8, 0xE8, 0xE8, 0xFF, 0xEB, 0xEB, 0xEA, 0xFF, 0xEC, 0xEC, + 0xEC, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xBA, 0xB4, 0xA9, 0xFF, 0x92, 0x86, + 0x71, 0xFF, 0xBE, 0xB5, 0xAA, 0xFF, 0x9D, 0x86, 0x69, 0xFF, 0x76, 0x49, 0x13, 0xFF, 0x83, 0x4A, + 0x0C, 0xFF, 0x8F, 0x50, 0x0F, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x93, 0x51, 0x0F, 0xFF, 0x93, 0x51, + 0x0F, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x92, 0x51, + 0x0F, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x92, 0x51, + 0x0F, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x90, 0x4F, 0x0E, 0xFF, 0x90, 0x50, 0x11, 0xFF, 0x94, 0x5A, + 0x21, 0xFF, 0x97, 0x61, 0x2F, 0xFF, 0xA5, 0x77, 0x4C, 0xFF, 0xC0, 0x9E, 0x7E, 0x8C, 0xFF, 0xFF, + 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0xAE, + 0x91, 0x2B, 0x9E, 0x6D, 0x44, 0xE2, 0x7A, 0x3D, 0x0F, 0xFF, 0x7A, 0x3B, 0x09, 0xFF, 0x81, 0x41, + 0x0B, 0xFF, 0x86, 0x46, 0x0B, 0xFF, 0x8E, 0x57, 0x20, 0xFF, 0xD8, 0xCC, 0xBD, 0xFF, 0xED, 0xEE, + 0xEF, 0xFF, 0xEB, 0xEA, 0xEA, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xED, 0xED, + 0xED, 0xFF, 0xEF, 0xEF, 0xEE, 0xFF, 0xEF, 0xEF, 0xEF, 0xFF, 0xF0, 0xF1, 0xF1, 0xFF, 0xCA, 0xC5, + 0xBD, 0xFF, 0x8B, 0x7D, 0x66, 0xFF, 0xB3, 0xAB, 0x9C, 0xFF, 0xB3, 0xA4, 0x90, 0xFF, 0x7D, 0x57, + 0x26, 0xFF, 0x7F, 0x4A, 0x0C, 0xFF, 0x90, 0x53, 0x10, 0xFF, 0x95, 0x55, 0x11, 0xFF, 0x96, 0x55, + 0x11, 0xFF, 0x95, 0x55, 0x11, 0xFF, 0x95, 0x55, 0x11, 0xFF, 0x95, 0x54, 0x10, 0xFF, 0x95, 0x54, + 0x10, 0xFF, 0x95, 0x54, 0x0F, 0xFF, 0x95, 0x54, 0x0F, 0xFF, 0x95, 0x54, 0x0F, 0xFF, 0x95, 0x54, + 0x0F, 0xFF, 0x95, 0x54, 0x0F, 0xFF, 0x94, 0x53, 0x0F, 0xFF, 0x93, 0x52, 0x0E, 0xFF, 0x91, 0x50, + 0x10, 0xFF, 0x94, 0x59, 0x1E, 0xFF, 0x9E, 0x69, 0x38, 0xFF, 0xB7, 0x90, 0x6A, 0xD9, 0xD2, 0xB7, + 0x9C, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x97, + 0x73, 0x6D, 0x90, 0x5A, 0x2B, 0xFE, 0x7B, 0x3C, 0x0A, 0xFF, 0x81, 0x41, 0x0A, 0xFF, 0x88, 0x47, + 0x0C, 0xFF, 0x8E, 0x4D, 0x0E, 0xFF, 0x8D, 0x4E, 0x0C, 0xFF, 0xA1, 0x76, 0x45, 0xFF, 0xE6, 0xE1, + 0xDA, 0xFF, 0xEE, 0xEF, 0xEF, 0xFF, 0xEE, 0xEE, 0xED, 0xFF, 0xEE, 0xEE, 0xED, 0xFF, 0xEE, 0xEE, + 0xED, 0xFF, 0xEF, 0xEF, 0xEF, 0xFF, 0xF1, 0xF1, 0xF1, 0xFF, 0xF1, 0xF1, 0xF1, 0xFF, 0xF3, 0xF3, + 0xF4, 0xFF, 0xD9, 0xD7, 0xD2, 0xFF, 0x8F, 0x82, 0x6A, 0xFF, 0xA4, 0x9A, 0x87, 0xFF, 0xC5, 0xBC, + 0xB0, 0xFF, 0x8D, 0x70, 0x48, 0xFF, 0x7D, 0x4C, 0x10, 0xFF, 0x90, 0x55, 0x12, 0xFF, 0x98, 0x59, + 0x13, 0xFF, 0x9A, 0x5A, 0x13, 0xFF, 0x9A, 0x59, 0x13, 0xFF, 0x99, 0x59, 0x13, 0xFF, 0x99, 0x59, + 0x13, 0xFF, 0x99, 0x59, 0x13, 0xFF, 0x99, 0x58, 0x12, 0xFF, 0x98, 0x57, 0x11, 0xFF, 0x98, 0x56, + 0x10, 0xFF, 0x98, 0x56, 0x10, 0xFF, 0x98, 0x56, 0x10, 0xFF, 0x97, 0x55, 0x10, 0xFF, 0x95, 0x53, + 0x0F, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x97, 0x5B, 0x21, 0xFF, 0xAF, 0x81, 0x56, 0xFB, 0xCA, 0xAA, + 0x8A, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF9, 0xF0, 0xE2, 0x07, 0xB0, 0x85, + 0x5D, 0xAD, 0x88, 0x4C, 0x1A, 0xFF, 0x80, 0x3F, 0x0A, 0xFF, 0x87, 0x46, 0x0C, 0xFF, 0x8E, 0x4D, + 0x0D, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x97, 0x55, 0x10, 0xFF, 0x92, 0x54, 0x0F, 0xFF, 0xB4, 0x94, + 0x6C, 0xFF, 0xEC, 0xEB, 0xE9, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEE, 0xEE, + 0xEE, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEF, 0xEF, 0xEF, 0xFF, 0xF1, 0xF1, 0xF1, 0xFF, 0xF2, 0xF2, + 0xF2, 0xFF, 0xF3, 0xF3, 0xF4, 0xFF, 0xE5, 0xE4, 0xE2, 0xFF, 0x9D, 0x92, 0x7C, 0xFF, 0x96, 0x88, + 0x6E, 0xFF, 0xCE, 0xC8, 0xBE, 0xFF, 0xA3, 0x8E, 0x70, 0xFF, 0x7E, 0x53, 0x1A, 0xFF, 0x8D, 0x56, + 0x14, 0xFF, 0x9A, 0x5D, 0x17, 0xFF, 0x9D, 0x5E, 0x17, 0xFF, 0x9E, 0x5E, 0x17, 0xFF, 0x9E, 0x5E, + 0x17, 0xFF, 0x9E, 0x5E, 0x17, 0xFF, 0x9D, 0x5E, 0x17, 0xFF, 0x9D, 0x5D, 0x16, 0xFF, 0x9C, 0x5B, + 0x14, 0xFF, 0x9B, 0x5A, 0x12, 0xFF, 0x9A, 0x59, 0x11, 0xFF, 0x9A, 0x58, 0x11, 0xFF, 0x99, 0x57, + 0x10, 0xFF, 0x96, 0x55, 0x0F, 0xFF, 0x93, 0x52, 0x10, 0xFF, 0xA4, 0x6F, 0x3A, 0xFF, 0xC0, 0x9D, + 0x79, 0x9E, 0x87, 0x96, 0xA1, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0xBD, 0xA2, 0x1E, 0xA8, 0x78, + 0x4B, 0xD9, 0x86, 0x47, 0x12, 0xFF, 0x86, 0x45, 0x0B, 0xFF, 0x8D, 0x4C, 0x0D, 0xFF, 0x93, 0x52, + 0x0E, 0xFF, 0x99, 0x57, 0x11, 0xFF, 0x9D, 0x5D, 0x15, 0xFF, 0x9F, 0x60, 0x19, 0xFF, 0x9A, 0x61, + 0x1E, 0xFF, 0xC4, 0xAE, 0x91, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xEA, 0xEA, + 0xEA, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xED, 0xED, + 0xED, 0xFF, 0xEF, 0xEF, 0xEF, 0xFF, 0xF0, 0xF0, 0xF1, 0xFF, 0xEB, 0xEB, 0xEA, 0xFF, 0xB0, 0xA7, + 0x95, 0xFF, 0x8D, 0x7E, 0x60, 0xFF, 0xCC, 0xC5, 0xBB, 0xFF, 0xB9, 0xAD, 0x99, 0xFF, 0x85, 0x61, + 0x2E, 0xFF, 0x8B, 0x57, 0x16, 0xFF, 0x9C, 0x60, 0x1A, 0xFF, 0xA1, 0x62, 0x1B, 0xFF, 0xA1, 0x62, + 0x1B, 0xFF, 0xA1, 0x62, 0x1B, 0xFF, 0xA1, 0x62, 0x1B, 0xFF, 0xA1, 0x62, 0x1B, 0xFF, 0xA1, 0x62, + 0x1B, 0xFF, 0xA1, 0x62, 0x1A, 0xFF, 0x9F, 0x5F, 0x16, 0xFF, 0x9D, 0x5C, 0x12, 0xFF, 0x9C, 0x5B, + 0x11, 0xFF, 0x9A, 0x59, 0x11, 0xFF, 0x97, 0x55, 0x0F, 0xFF, 0x9C, 0x5F, 0x20, 0xFF, 0xBA, 0x91, + 0x67, 0xCE, 0xD0, 0xBB, 0xA6, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCB, 0xAA, 0x88, 0x3C, 0xA3, 0x6F, + 0x3E, 0xF0, 0x87, 0x46, 0x0E, 0xFF, 0x8C, 0x49, 0x0C, 0xFF, 0x93, 0x51, 0x0E, 0xFF, 0x9A, 0x59, + 0x13, 0xFF, 0xA1, 0x62, 0x1B, 0xFF, 0xA5, 0x66, 0x1F, 0xFF, 0xA6, 0x67, 0x1F, 0xFF, 0xA3, 0x66, + 0x1D, 0xFF, 0xA0, 0x6C, 0x2D, 0xFF, 0xCF, 0xC0, 0xAD, 0xFF, 0xE6, 0xE7, 0xE8, 0xFF, 0xE4, 0xE4, + 0xE4, 0xFF, 0xE5, 0xE5, 0xE5, 0xFF, 0xE5, 0xE5, 0xE5, 0xFF, 0xE6, 0xE6, 0xE6, 0xFF, 0xE6, 0xE6, + 0xE6, 0xFF, 0xE7, 0xE7, 0xE7, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xEB, 0xEB, 0xEC, 0xFF, 0xEC, 0xEC, + 0xEC, 0xFF, 0xC2, 0xBC, 0xAF, 0xFF, 0x8C, 0x7C, 0x5C, 0xFF, 0xBF, 0xB7, 0xA9, 0xFF, 0xCD, 0xC5, + 0xBA, 0xFF, 0x91, 0x76, 0x4C, 0xFF, 0x88, 0x59, 0x1B, 0xFF, 0x9C, 0x62, 0x1D, 0xFF, 0xA4, 0x67, + 0x1F, 0xFF, 0xA6, 0x67, 0x1F, 0xFF, 0xA6, 0x67, 0x1F, 0xFF, 0xA5, 0x67, 0x1F, 0xFF, 0xA5, 0x67, + 0x1F, 0xFF, 0xA6, 0x67, 0x1F, 0xFF, 0xA5, 0x67, 0x1F, 0xFF, 0xA4, 0x65, 0x1C, 0xFF, 0xA1, 0x60, + 0x15, 0xFF, 0x9E, 0x5C, 0x12, 0xFF, 0x9B, 0x59, 0x10, 0xFF, 0x9B, 0x5B, 0x16, 0xFF, 0xB5, 0x87, + 0x54, 0xE9, 0xDA, 0xC1, 0xA5, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC7, 0xA2, 0x7C, 0x59, 0xA0, 0x68, + 0x34, 0xFC, 0x8B, 0x49, 0x0D, 0xFF, 0x92, 0x4F, 0x0E, 0xFF, 0x9B, 0x5B, 0x16, 0xFF, 0xA4, 0x66, + 0x20, 0xFF, 0xA8, 0x6B, 0x23, 0xFF, 0xAA, 0x6C, 0x24, 0xFF, 0xAA, 0x6D, 0x24, 0xFF, 0xAA, 0x6D, + 0x24, 0xFF, 0xA6, 0x6A, 0x21, 0xFF, 0xA7, 0x7B, 0x42, 0xFF, 0xD4, 0xCD, 0xC1, 0xFF, 0xE0, 0xE1, + 0xE2, 0xFF, 0xDF, 0xDF, 0xDF, 0xFF, 0xDF, 0xDF, 0xDF, 0xFF, 0xDE, 0xDF, 0xDF, 0xFF, 0xDF, 0xDF, + 0xDF, 0xFF, 0xE0, 0xE0, 0xE0, 0xFF, 0xE2, 0xE2, 0xE2, 0xFF, 0xE5, 0xE5, 0xE5, 0xFF, 0xE6, 0xE6, + 0xE6, 0xFF, 0xE9, 0xE9, 0xEA, 0xFF, 0xD0, 0xCC, 0xC4, 0xFF, 0x92, 0x82, 0x64, 0xFF, 0xB0, 0xA5, + 0x90, 0xFF, 0xD6, 0xD3, 0xCD, 0xFF, 0xA3, 0x90, 0x71, 0xFF, 0x89, 0x60, 0x25, 0xFF, 0x9B, 0x65, + 0x21, 0xFF, 0xA7, 0x6B, 0x23, 0xFF, 0xAA, 0x6D, 0x24, 0xFF, 0xAA, 0x6D, 0x24, 0xFF, 0xAA, 0x6D, + 0x24, 0xFF, 0xAA, 0x6D, 0x24, 0xFF, 0xAA, 0x6D, 0x24, 0xFF, 0xAA, 0x6D, 0x24, 0xFF, 0xA9, 0x6C, + 0x22, 0xFF, 0xA6, 0x65, 0x1A, 0xFF, 0xA0, 0x5E, 0x12, 0xFF, 0x9E, 0x5C, 0x13, 0xFF, 0xB3, 0x81, + 0x4A, 0xF6, 0xD5, 0xB7, 0x95, 0x4A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC8, 0xA3, 0x7C, 0x6E, 0xA0, 0x65, + 0x2D, 0xFF, 0x90, 0x4D, 0x0D, 0xFF, 0x9C, 0x5B, 0x18, 0xFF, 0xA6, 0x69, 0x25, 0xFF, 0xAA, 0x6E, + 0x27, 0xFF, 0xAD, 0x70, 0x28, 0xFF, 0xAE, 0x72, 0x28, 0xFF, 0xAE, 0x72, 0x28, 0xFF, 0xAE, 0x72, + 0x28, 0xFF, 0xAE, 0x72, 0x28, 0xFF, 0xA8, 0x6E, 0x25, 0xFF, 0xB0, 0x8B, 0x5B, 0xFF, 0xD5, 0xD1, + 0xCC, 0xFF, 0xDA, 0xDA, 0xDB, 0xFF, 0xDA, 0xDA, 0xDA, 0xFF, 0xDA, 0xDA, 0xDA, 0xFF, 0xDC, 0xDC, + 0xDD, 0xFF, 0xCA, 0xC3, 0xB9, 0xFF, 0xA9, 0x97, 0x79, 0xFF, 0xD6, 0xD0, 0xC8, 0xFF, 0xE0, 0xE1, + 0xE2, 0xFF, 0xE3, 0xE3, 0xE3, 0xFF, 0xE5, 0xE5, 0xE6, 0xFF, 0xD9, 0xD7, 0xD3, 0xFF, 0x9E, 0x91, + 0x76, 0xFF, 0xA6, 0x99, 0x80, 0xFF, 0xD7, 0xD5, 0xD1, 0xFF, 0xB6, 0xAA, 0x95, 0xFF, 0x8E, 0x6B, + 0x37, 0xFF, 0x99, 0x66, 0x24, 0xFF, 0xA9, 0x6F, 0x28, 0xFF, 0xAE, 0x72, 0x28, 0xFF, 0xAE, 0x72, + 0x28, 0xFF, 0xAE, 0x72, 0x28, 0xFF, 0xAE, 0x72, 0x28, 0xFF, 0xAE, 0x72, 0x28, 0xFF, 0xAE, 0x72, + 0x28, 0xFF, 0xAE, 0x71, 0x28, 0xFF, 0xA9, 0x69, 0x1E, 0xFF, 0xA2, 0x60, 0x13, 0xFF, 0xB3, 0x7E, + 0x43, 0xFC, 0xD3, 0xB2, 0x8E, 0x5D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC9, 0xA3, 0x7B, 0x7A, 0xA2, 0x66, + 0x2B, 0xFF, 0x9A, 0x59, 0x1A, 0xFF, 0xA6, 0x6A, 0x29, 0xFF, 0xAC, 0x70, 0x2B, 0xFF, 0xAF, 0x73, + 0x2C, 0xFF, 0xB2, 0x76, 0x2D, 0xFF, 0xB3, 0x77, 0x2D, 0xFF, 0xB3, 0x77, 0x2D, 0xFF, 0xB3, 0x77, + 0x2D, 0xFF, 0xB3, 0x77, 0x2D, 0xFF, 0xB2, 0x77, 0x2D, 0xFF, 0xAB, 0x73, 0x2B, 0xFF, 0xB7, 0x99, + 0x72, 0xFF, 0xD4, 0xD3, 0xD1, 0xFF, 0xD7, 0xD7, 0xD7, 0xFF, 0xD8, 0xD8, 0xD8, 0xFF, 0xDB, 0xDB, + 0xDC, 0xFF, 0xBC, 0xB6, 0xA7, 0xFF, 0x8D, 0x77, 0x4D, 0xFF, 0xC1, 0xB5, 0x9F, 0xFF, 0xDC, 0xD9, + 0xD5, 0xFF, 0xD8, 0xD5, 0xCF, 0xFF, 0xE1, 0xE0, 0xDE, 0xFF, 0xE4, 0xE4, 0xE5, 0xFF, 0xDF, 0xDE, + 0xDD, 0xFF, 0xB0, 0xA7, 0x92, 0xFF, 0xA3, 0x96, 0x7B, 0xFF, 0xD4, 0xD2, 0xCC, 0xFF, 0xC8, 0xC0, + 0xB5, 0xFF, 0x97, 0x7C, 0x50, 0xFF, 0x96, 0x69, 0x28, 0xFF, 0xAB, 0x73, 0x2C, 0xFF, 0xB2, 0x77, + 0x2D, 0xFF, 0xB2, 0x77, 0x2D, 0xFF, 0xB3, 0x77, 0x2D, 0xFF, 0xB3, 0x77, 0x2D, 0xFF, 0xB3, 0x77, + 0x2D, 0xFF, 0xB2, 0x77, 0x2D, 0xFF, 0xB1, 0x75, 0x2D, 0xFF, 0xAB, 0x6C, 0x22, 0xFF, 0xB5, 0x80, + 0x41, 0xFF, 0xD4, 0xB3, 0x8D, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCB, 0xA5, 0x7C, 0x7B, 0xAA, 0x71, + 0x38, 0xFF, 0xA6, 0x69, 0x2C, 0xFF, 0xAC, 0x71, 0x2F, 0xFF, 0xB1, 0x76, 0x30, 0xFF, 0xB4, 0x79, + 0x31, 0xFF, 0xB6, 0x7C, 0x32, 0xFF, 0xB7, 0x7C, 0x32, 0xFF, 0xB7, 0x7C, 0x32, 0xFF, 0xB7, 0x7C, + 0x32, 0xFF, 0xB7, 0x7C, 0x32, 0xFF, 0xB7, 0x7C, 0x32, 0xFF, 0xB6, 0x7D, 0x34, 0xFF, 0xB3, 0x83, + 0x42, 0xFF, 0xC5, 0xB2, 0x98, 0xFF, 0xD7, 0xD7, 0xD7, 0xFF, 0xD7, 0xD7, 0xD7, 0xFF, 0xD7, 0xD7, + 0xD7, 0xFF, 0xD7, 0xD7, 0xD6, 0xFF, 0xD2, 0xD0, 0xC9, 0xFF, 0xB4, 0xA6, 0x8C, 0xFF, 0xB8, 0xA9, + 0x8D, 0xFF, 0xC7, 0xBD, 0xAB, 0xFF, 0xAE, 0x9F, 0x82, 0xFF, 0xC2, 0xB9, 0xA8, 0xFF, 0xE1, 0xE1, + 0xE2, 0xFF, 0xE0, 0xE0, 0xE0, 0xFF, 0xBE, 0xB8, 0xA9, 0xFF, 0xA4, 0x98, 0x7C, 0xFF, 0xD0, 0xCC, + 0xC4, 0xFF, 0xD4, 0xD1, 0xCC, 0xFF, 0xA5, 0x91, 0x6E, 0xFF, 0x98, 0x6E, 0x30, 0xFF, 0xAD, 0x78, + 0x31, 0xFF, 0xB6, 0x7C, 0x32, 0xFF, 0xB7, 0x7C, 0x32, 0xFF, 0xB7, 0x7C, 0x32, 0xFF, 0xB7, 0x7C, + 0x32, 0xFF, 0xB7, 0x7C, 0x32, 0xFF, 0xB6, 0x7B, 0x32, 0xFF, 0xB4, 0x79, 0x32, 0xFF, 0xBD, 0x8B, + 0x4F, 0xFF, 0xD6, 0xB5, 0x8F, 0x6A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD1, 0xAD, 0x86, 0x71, 0xB6, 0x82, + 0x4C, 0xFF, 0xAC, 0x71, 0x33, 0xFF, 0xB2, 0x77, 0x35, 0xFF, 0xB6, 0x7C, 0x36, 0xFF, 0xB9, 0x7F, + 0x37, 0xFF, 0xBB, 0x81, 0x38, 0xFF, 0xBB, 0x82, 0x38, 0xFF, 0xBB, 0x82, 0x38, 0xFF, 0xBB, 0x82, + 0x38, 0xFF, 0xBB, 0x81, 0x37, 0xFF, 0xBC, 0x84, 0x3B, 0xFF, 0xC2, 0x8E, 0x4B, 0xFF, 0xC3, 0x93, + 0x54, 0xFF, 0xBD, 0x94, 0x5D, 0xFF, 0xCF, 0xC2, 0xB0, 0xFF, 0xDB, 0xDC, 0xDC, 0xFF, 0xDB, 0xDB, + 0xDB, 0xFF, 0xDB, 0xDB, 0xDB, 0xFF, 0xDD, 0xDD, 0xDE, 0xFF, 0xC9, 0xC2, 0xB4, 0xFF, 0xB7, 0xAB, + 0x91, 0xFF, 0xD9, 0xD5, 0xCC, 0xFF, 0xBA, 0xB1, 0x9C, 0xFF, 0xBD, 0xB6, 0xA5, 0xFF, 0xDC, 0xDD, + 0xDD, 0xFF, 0xDF, 0xDF, 0xDF, 0xFF, 0xE2, 0xE2, 0xE2, 0xFF, 0xCC, 0xC8, 0xBD, 0xFF, 0xAA, 0x9F, + 0x86, 0xFF, 0xCD, 0xC8, 0xBE, 0xFF, 0xDD, 0xDC, 0xDA, 0xFF, 0xB5, 0xA4, 0x86, 0xFF, 0xA4, 0x79, + 0x39, 0xFF, 0xB7, 0x80, 0x37, 0xFF, 0xBB, 0x82, 0x38, 0xFF, 0xBB, 0x82, 0x38, 0xFF, 0xBB, 0x82, + 0x38, 0xFF, 0xBB, 0x82, 0x38, 0xFF, 0xBA, 0x81, 0x37, 0xFF, 0xB9, 0x80, 0x39, 0xFF, 0xC5, 0x97, + 0x5F, 0xFD, 0xDB, 0xBC, 0x98, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD4, 0xB2, 0x8A, 0x5E, 0xBD, 0x8C, + 0x57, 0xFD, 0xB2, 0x78, 0x39, 0xFF, 0xB6, 0x7D, 0x3A, 0xFF, 0xBA, 0x82, 0x3B, 0xFF, 0xBD, 0x85, + 0x3C, 0xFF, 0xBF, 0x87, 0x3D, 0xFF, 0xBF, 0x87, 0x3D, 0xFF, 0xBF, 0x87, 0x3D, 0xFF, 0xBF, 0x87, + 0x3D, 0xFF, 0xC0, 0x88, 0x3F, 0xFF, 0xC7, 0x95, 0x53, 0xFF, 0xCB, 0x9C, 0x5E, 0xFF, 0xCB, 0x9B, + 0x5E, 0xFF, 0xC8, 0x99, 0x5C, 0xFF, 0xC3, 0xA0, 0x6E, 0xFF, 0xD8, 0xD0, 0xC3, 0xFF, 0xE1, 0xE1, + 0xE2, 0xFF, 0xE1, 0xE1, 0xE1, 0xFF, 0xE2, 0xE2, 0xE2, 0xFF, 0xCF, 0xCA, 0xBE, 0xFF, 0xDA, 0xD7, + 0xCF, 0xFF, 0xBE, 0xB5, 0xA0, 0xFF, 0xD7, 0xD4, 0xCD, 0xFF, 0xDF, 0xDF, 0xE0, 0xFF, 0xDC, 0xDC, + 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xE0, 0xE0, 0xE0, 0xFF, 0xE4, 0xE4, 0xE5, 0xFF, 0xD8, 0xD5, + 0xD0, 0xFF, 0xB4, 0xAC, 0x95, 0xFF, 0xCC, 0xC8, 0xBC, 0xFF, 0xDF, 0xDC, 0xD7, 0xFF, 0xB0, 0x8C, + 0x57, 0xFF, 0xB9, 0x83, 0x3A, 0xFF, 0xBF, 0x87, 0x3D, 0xFF, 0xBF, 0x87, 0x3D, 0xFF, 0xBF, 0x87, + 0x3D, 0xFF, 0xBF, 0x87, 0x3D, 0xFF, 0xBE, 0x86, 0x3D, 0xFF, 0xBE, 0x86, 0x3F, 0xFF, 0xCC, 0xA0, + 0x69, 0xF7, 0xDE, 0xC2, 0x9F, 0x4E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD9, 0xB8, 0x91, 0x41, 0xC5, 0x97, + 0x63, 0xF3, 0xB8, 0x7F, 0x40, 0xFF, 0xBB, 0x82, 0x3F, 0xFF, 0xBF, 0x87, 0x41, 0xFF, 0xC2, 0x8A, + 0x42, 0xFF, 0xC3, 0x8C, 0x42, 0xFF, 0xC3, 0x8C, 0x42, 0xFF, 0xC3, 0x8C, 0x42, 0xFF, 0xC3, 0x8C, + 0x42, 0xFF, 0xC9, 0x97, 0x54, 0xFF, 0xCF, 0xA2, 0x67, 0xFF, 0xCF, 0xA2, 0x67, 0xFF, 0xCF, 0xA2, + 0x67, 0xFF, 0xCF, 0xA2, 0x67, 0xFF, 0xCC, 0xA0, 0x65, 0xFF, 0xCB, 0xAB, 0x7F, 0xFF, 0xE0, 0xDB, + 0xD4, 0xFF, 0xE6, 0xE7, 0xE7, 0xFF, 0xE7, 0xE7, 0xE8, 0xFF, 0xCA, 0xC2, 0xB1, 0xFF, 0xC8, 0xBD, + 0xA9, 0xFF, 0xD7, 0xD3, 0xC9, 0xFF, 0xBE, 0xB2, 0x9A, 0xFF, 0xC9, 0xBE, 0xAA, 0xFF, 0xDB, 0xDA, + 0xD6, 0xFF, 0xDF, 0xDF, 0xDF, 0xFF, 0xDF, 0xDF, 0xDF, 0xFF, 0xE1, 0xE1, 0xE1, 0xFF, 0xE6, 0xE6, + 0xE6, 0xFF, 0xE1, 0xE0, 0xDD, 0xFF, 0xC4, 0xBD, 0xAC, 0xFF, 0xD2, 0xC9, 0xB6, 0xFF, 0xB8, 0x92, + 0x58, 0xFF, 0xBF, 0x89, 0x40, 0xFF, 0xC3, 0x8C, 0x42, 0xFF, 0xC3, 0x8C, 0x42, 0xFF, 0xC3, 0x8C, + 0x42, 0xFF, 0xC3, 0x8C, 0x42, 0xFF, 0xC2, 0x8B, 0x42, 0xFF, 0xC3, 0x8D, 0x47, 0xFF, 0xD2, 0xA9, + 0x75, 0xED, 0xE5, 0xCD, 0xAD, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE2, 0xC7, 0xA4, 0x24, 0xCE, 0xA2, + 0x70, 0xDF, 0xBF, 0x88, 0x4A, 0xFF, 0xC0, 0x88, 0x45, 0xFF, 0xC3, 0x8D, 0x47, 0xFF, 0xC7, 0x90, + 0x48, 0xFF, 0xC8, 0x92, 0x48, 0xFF, 0xC9, 0x92, 0x49, 0xFF, 0xC9, 0x92, 0x48, 0xFF, 0xCA, 0x96, + 0x4F, 0xFF, 0xD2, 0xA7, 0x6B, 0xFF, 0xD4, 0xA9, 0x70, 0xFF, 0xD4, 0xA9, 0x6F, 0xFF, 0xD4, 0xA9, + 0x6F, 0xFF, 0xD4, 0xA9, 0x6F, 0xFF, 0xD4, 0xA9, 0x6F, 0xFF, 0xD0, 0xA7, 0x6D, 0xFF, 0xD2, 0xB8, + 0x92, 0xFF, 0xE6, 0xE4, 0xE0, 0xFF, 0xEB, 0xEC, 0xED, 0xFF, 0xCA, 0xC4, 0xB4, 0xFF, 0xAC, 0xA0, + 0x80, 0xFF, 0xDD, 0xDA, 0xD3, 0xFF, 0xC0, 0xB7, 0xA2, 0xFF, 0xA9, 0x99, 0x74, 0xFF, 0xD5, 0xD1, + 0xC9, 0xFF, 0xE3, 0xE3, 0xE4, 0xFF, 0xE3, 0xE3, 0xE3, 0xFF, 0xE3, 0xE3, 0xE3, 0xFF, 0xE4, 0xE4, + 0xE4, 0xFF, 0xE8, 0xE8, 0xE8, 0xFF, 0xE8, 0xE8, 0xE6, 0xFF, 0xC7, 0xB5, 0x97, 0xFF, 0xB7, 0x8C, + 0x4B, 0xFF, 0xC3, 0x90, 0x47, 0xFF, 0xC8, 0x92, 0x49, 0xFF, 0xC9, 0x92, 0x49, 0xFF, 0xC9, 0x92, + 0x49, 0xFF, 0xC9, 0x92, 0x49, 0xFF, 0xC8, 0x91, 0x48, 0xFF, 0xCA, 0x97, 0x53, 0xFF, 0xD8, 0xB2, + 0x82, 0xD4, 0xE4, 0xCE, 0xB1, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xED, 0xD9, 0xBE, 0x0A, 0xD6, 0xAE, + 0x7E, 0xB7, 0xC8, 0x93, 0x57, 0xFF, 0xC5, 0x8E, 0x4A, 0xFF, 0xC9, 0x92, 0x4C, 0xFF, 0xCC, 0x95, + 0x4D, 0xFF, 0xCD, 0x98, 0x4E, 0xFF, 0xCE, 0x98, 0x4E, 0xFF, 0xCE, 0x98, 0x4E, 0xFF, 0xD3, 0xA4, + 0x63, 0xFF, 0xD9, 0xB0, 0x79, 0xFF, 0xD9, 0xB0, 0x78, 0xFF, 0xD9, 0xB0, 0x78, 0xFF, 0xD9, 0xB0, + 0x78, 0xFF, 0xD9, 0xB0, 0x78, 0xFF, 0xD9, 0xB0, 0x78, 0xFF, 0xD9, 0xB0, 0x78, 0xFF, 0xD4, 0xAD, + 0x77, 0xFF, 0xD8, 0xC3, 0xA4, 0xFF, 0xEB, 0xE9, 0xE7, 0xFF, 0xEB, 0xEB, 0xEA, 0xFF, 0xE6, 0xE5, + 0xE2, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xE4, 0xE3, 0xE1, 0xFF, 0xD4, 0xD1, 0xC8, 0xFF, 0xDD, 0xDC, + 0xD8, 0xFF, 0xE7, 0xE7, 0xE7, 0xFF, 0xE6, 0xE6, 0xE6, 0xFF, 0xE7, 0xE7, 0xE7, 0xFF, 0xE7, 0xE7, + 0xE7, 0xFF, 0xE9, 0xE9, 0xE9, 0xFF, 0xEA, 0xE9, 0xE6, 0xFF, 0xC3, 0xB8, 0x9D, 0xFF, 0xBC, 0xA1, + 0x72, 0xFF, 0xB9, 0x8F, 0x4C, 0xFF, 0xC7, 0x94, 0x4D, 0xFF, 0xCD, 0x98, 0x4E, 0xFF, 0xCE, 0x98, + 0x4E, 0xFF, 0xCE, 0x98, 0x4E, 0xFF, 0xCD, 0x97, 0x4E, 0xFF, 0xD2, 0xA2, 0x63, 0xFF, 0xDC, 0xBB, + 0x8E, 0xA9, 0xC0, 0xBC, 0xB7, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xBA, + 0x8D, 0x7B, 0xD1, 0xA1, 0x67, 0xFF, 0xCB, 0x94, 0x51, 0xFF, 0xCE, 0x98, 0x51, 0xFF, 0xD0, 0x9B, + 0x52, 0xFF, 0xD2, 0x9D, 0x53, 0xFF, 0xD2, 0x9E, 0x53, 0xFF, 0xD3, 0x9F, 0x55, 0xFF, 0xDB, 0xB1, + 0x75, 0xFF, 0xDD, 0xB8, 0x81, 0xFF, 0xDD, 0xB7, 0x80, 0xFF, 0xDD, 0xB7, 0x80, 0xFF, 0xDD, 0xB7, + 0x80, 0xFF, 0xDD, 0xB7, 0x80, 0xFF, 0xDD, 0xB7, 0x80, 0xFF, 0xDD, 0xB7, 0x80, 0xFF, 0xDD, 0xB7, + 0x80, 0xFF, 0xD8, 0xB4, 0x80, 0xFF, 0xDE, 0xCD, 0xB1, 0xFF, 0xEE, 0xEE, 0xED, 0xFF, 0xF0, 0xF1, + 0xF1, 0xFF, 0xEF, 0xEF, 0xEF, 0xFF, 0xED, 0xED, 0xED, 0xFF, 0xEC, 0xEC, 0xED, 0xFF, 0xEA, 0xEA, + 0xEB, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xEB, 0xEB, + 0xEB, 0xFF, 0xE9, 0xE9, 0xE6, 0xFF, 0xEE, 0xEE, 0xED, 0xFF, 0xE5, 0xE3, 0xDD, 0xFF, 0xD2, 0xCA, + 0xB6, 0xFF, 0xC4, 0xB0, 0x89, 0xFF, 0xBD, 0x96, 0x56, 0xFF, 0xCE, 0x9C, 0x53, 0xFF, 0xD2, 0x9E, + 0x53, 0xFF, 0xD2, 0x9E, 0x53, 0xFF, 0xD2, 0x9E, 0x55, 0xFF, 0xDA, 0xB0, 0x76, 0xFE, 0xDE, 0xC1, + 0x9A, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE5, 0xC8, + 0x9E, 0x36, 0xDA, 0xAF, 0x79, 0xEA, 0xD1, 0x9D, 0x5B, 0xFF, 0xD2, 0x9D, 0x57, 0xFF, 0xD5, 0xA0, + 0x58, 0xFF, 0xD6, 0xA3, 0x59, 0xFF, 0xD7, 0xA3, 0x59, 0xFF, 0xD8, 0xA7, 0x60, 0xFF, 0xE1, 0xBB, + 0x83, 0xFF, 0xE2, 0xBE, 0x89, 0xFF, 0xE2, 0xBE, 0x88, 0xFF, 0xE2, 0xBE, 0x88, 0xFF, 0xE2, 0xBE, + 0x88, 0xFF, 0xE2, 0xBE, 0x88, 0xFF, 0xE2, 0xBE, 0x88, 0xFF, 0xE2, 0xBE, 0x88, 0xFF, 0xE2, 0xBE, + 0x88, 0xFF, 0xE1, 0xBD, 0x88, 0xFF, 0xDC, 0xBB, 0x89, 0xFF, 0xE3, 0xD5, 0xBC, 0xFF, 0xF1, 0xF1, + 0xF0, 0xFF, 0xF2, 0xF2, 0xF2, 0xFF, 0xF1, 0xF1, 0xF1, 0xFF, 0xEF, 0xEF, 0xEF, 0xFF, 0xEE, 0xEE, + 0xEE, 0xFF, 0xEF, 0xEF, 0xEF, 0xFF, 0xEF, 0xEF, 0xEF, 0xFF, 0xEE, 0xEE, 0xED, 0xFF, 0xE9, 0xE9, + 0xE6, 0xFF, 0xED, 0xED, 0xEB, 0xFF, 0xEF, 0xEF, 0xF0, 0xFF, 0xF0, 0xF0, 0xF0, 0xFF, 0xEB, 0xEA, + 0xE6, 0xFF, 0xE2, 0xDE, 0xD3, 0xFF, 0xCB, 0xAE, 0x7E, 0xFF, 0xCF, 0x9F, 0x56, 0xFF, 0xD7, 0xA4, + 0x59, 0xFF, 0xD7, 0xA3, 0x59, 0xFF, 0xD8, 0xA8, 0x62, 0xFF, 0xE1, 0xBC, 0x89, 0xE3, 0xE0, 0xC8, + 0xA6, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xDF, + 0xC2, 0x08, 0xE1, 0xBB, 0x8A, 0xAC, 0xD9, 0xA9, 0x6C, 0xFF, 0xD6, 0xA2, 0x5D, 0xFF, 0xD9, 0xA5, + 0x5E, 0xFF, 0xDA, 0xA8, 0x5F, 0xFF, 0xDB, 0xA9, 0x5E, 0xFF, 0xDD, 0xAE, 0x69, 0xFF, 0xE6, 0xC2, + 0x8E, 0xFF, 0xE7, 0xC4, 0x91, 0xFF, 0xE7, 0xC4, 0x91, 0xFF, 0xE7, 0xC4, 0x91, 0xFF, 0xE7, 0xC4, + 0x91, 0xFF, 0xE7, 0xC4, 0x91, 0xFF, 0xE7, 0xC4, 0x91, 0xFF, 0xE7, 0xC4, 0x91, 0xFF, 0xE7, 0xC4, + 0x91, 0xFF, 0xE7, 0xC4, 0x91, 0xFF, 0xE5, 0xC3, 0x90, 0xFF, 0xE0, 0xC2, 0x93, 0xFF, 0xE7, 0xDB, + 0xC4, 0xFF, 0xF4, 0xF3, 0xF3, 0xFF, 0xF4, 0xF4, 0xF4, 0xFF, 0xF3, 0xF3, 0xF3, 0xFF, 0xF2, 0xF2, + 0xF2, 0xFF, 0xF2, 0xF2, 0xF2, 0xFF, 0xF2, 0xF2, 0xF2, 0xFF, 0xEE, 0xEE, 0xEC, 0xFF, 0xF0, 0xF0, + 0xEF, 0xFF, 0xF2, 0xF2, 0xF3, 0xFF, 0xF1, 0xF0, 0xEF, 0xFF, 0xD8, 0xD5, 0xC7, 0xFF, 0xEE, 0xEE, + 0xEB, 0xFF, 0xEC, 0xE9, 0xE1, 0xFF, 0xD0, 0xAF, 0x79, 0xFF, 0xD6, 0xA6, 0x5D, 0xFF, 0xDC, 0xA9, + 0x5F, 0xFF, 0xDB, 0xA9, 0x60, 0xFF, 0xE0, 0xB5, 0x76, 0xFF, 0xE7, 0xC8, 0x99, 0x9E, 0xD9, 0xD3, + 0xC8, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xE3, 0xC2, 0x96, 0x4D, 0xE1, 0xB7, 0x7F, 0xF3, 0xDC, 0xA9, 0x66, 0xFF, 0xDC, 0xAA, + 0x63, 0xFF, 0xDE, 0xAD, 0x64, 0xFF, 0xDF, 0xAE, 0x64, 0xFF, 0xE1, 0xB4, 0x6E, 0xFF, 0xE9, 0xC9, + 0x95, 0xFF, 0xEA, 0xCA, 0x98, 0xFF, 0xEA, 0xCA, 0x98, 0xFF, 0xEA, 0xCA, 0x98, 0xFF, 0xEA, 0xCA, + 0x98, 0xFF, 0xEA, 0xCA, 0x98, 0xFF, 0xEA, 0xCA, 0x98, 0xFF, 0xEA, 0xCA, 0x98, 0xFF, 0xEA, 0xCA, + 0x98, 0xFF, 0xEA, 0xCA, 0x98, 0xFF, 0xEA, 0xCA, 0x98, 0xFF, 0xE9, 0xC9, 0x97, 0xFF, 0xE4, 0xC8, + 0x9A, 0xFF, 0xEA, 0xDD, 0xC8, 0xFF, 0xF5, 0xF5, 0xF4, 0xFF, 0xF6, 0xF6, 0xF7, 0xFF, 0xF6, 0xF6, + 0xF6, 0xFF, 0xF4, 0xF3, 0xF2, 0xFF, 0xF4, 0xF4, 0xF2, 0xFF, 0xF5, 0xF5, 0xF5, 0xFF, 0xF5, 0xF5, + 0xF5, 0xFF, 0xF6, 0xF6, 0xF6, 0xFF, 0xF2, 0xF2, 0xF0, 0xFF, 0xE9, 0xE8, 0xE2, 0xFF, 0xF3, 0xF1, + 0xEC, 0xFF, 0xD7, 0xBE, 0x93, 0xFF, 0xD5, 0xA9, 0x63, 0xFF, 0xDE, 0xAE, 0x64, 0xFF, 0xDF, 0xAE, + 0x65, 0xFF, 0xE0, 0xB2, 0x6C, 0xFF, 0xE7, 0xC3, 0x8D, 0xED, 0xE8, 0xCE, 0xA7, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xE2, 0xCC, 0xAB, 0x0A, 0xE7, 0xC3, 0x90, 0xA9, 0xE3, 0xB5, 0x79, 0xFF, 0xE0, 0xAE, + 0x69, 0xFF, 0xE1, 0xB1, 0x69, 0xFF, 0xE2, 0xB2, 0x69, 0xFF, 0xE4, 0xB7, 0x71, 0xFF, 0xEC, 0xCC, + 0x99, 0xFF, 0xED, 0xCF, 0xA0, 0xFF, 0xED, 0xCF, 0x9F, 0xFF, 0xED, 0xCF, 0x9F, 0xFF, 0xED, 0xCF, + 0x9F, 0xFF, 0xED, 0xCF, 0x9F, 0xFF, 0xED, 0xCF, 0x9F, 0xFF, 0xED, 0xCF, 0x9F, 0xFF, 0xED, 0xCF, + 0x9F, 0xFF, 0xED, 0xCF, 0x9F, 0xFF, 0xED, 0xCF, 0x9F, 0xFF, 0xED, 0xCF, 0x9F, 0xFF, 0xEC, 0xCF, + 0x9F, 0xFF, 0xE8, 0xCD, 0xA0, 0xFF, 0xEB, 0xDD, 0xC3, 0xFF, 0xF6, 0xF4, 0xEF, 0xFF, 0xF5, 0xF2, + 0xEC, 0xFF, 0xE5, 0xD7, 0xBC, 0xFF, 0xEA, 0xDD, 0xC5, 0xFF, 0xF8, 0xF6, 0xF4, 0xFF, 0xF8, 0xF9, + 0xF9, 0xFF, 0xEA, 0xE9, 0xE1, 0xFF, 0xF4, 0xF4, 0xF2, 0xFF, 0xF9, 0xF8, 0xF6, 0xFF, 0xE5, 0xD6, + 0xB6, 0xFF, 0xD9, 0xB0, 0x6D, 0xFF, 0xE1, 0xB3, 0x69, 0xFF, 0xE3, 0xB4, 0x6A, 0xFF, 0xE3, 0xB4, + 0x6C, 0xFF, 0xE7, 0xBF, 0x82, 0xFF, 0xEC, 0xCE, 0x9F, 0x9B, 0xE1, 0xD6, 0xC5, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEA, 0xCB, 0x9E, 0x36, 0xE9, 0xC3, 0x8D, 0xE3, 0xE5, 0xB7, + 0x76, 0xFF, 0xE4, 0xB5, 0x6E, 0xFF, 0xE6, 0xB7, 0x6F, 0xFF, 0xE7, 0xB9, 0x72, 0xFF, 0xEE, 0xCD, + 0x98, 0xFF, 0xF0, 0xD4, 0xA7, 0xFF, 0xF0, 0xD4, 0xA6, 0xFF, 0xF0, 0xD4, 0xA6, 0xFF, 0xF0, 0xD4, + 0xA6, 0xFF, 0xF0, 0xD4, 0xA6, 0xFF, 0xF0, 0xD4, 0xA6, 0xFF, 0xF0, 0xD4, 0xA6, 0xFF, 0xF0, 0xD4, + 0xA6, 0xFF, 0xF0, 0xD4, 0xA6, 0xFF, 0xF0, 0xD4, 0xA6, 0xFF, 0xF0, 0xD4, 0xA6, 0xFF, 0xF0, 0xD4, + 0xA6, 0xFF, 0xF0, 0xD4, 0xA6, 0xFF, 0xED, 0xD2, 0xA5, 0xFF, 0xED, 0xD8, 0xB4, 0xFF, 0xEC, 0xD7, + 0xB3, 0xFF, 0xEB, 0xD1, 0xA4, 0xFF, 0xEB, 0xD1, 0xA5, 0xFF, 0xEE, 0xDF, 0xC3, 0xFF, 0xF8, 0xF6, + 0xF0, 0xFF, 0xEB, 0xEA, 0xE2, 0xFF, 0xF6, 0xF5, 0xF2, 0xFF, 0xEC, 0xE1, 0xCA, 0xFF, 0xE5, 0xC7, + 0x94, 0xFF, 0xE5, 0xB8, 0x70, 0xFF, 0xE6, 0xB8, 0x6F, 0xFF, 0xE7, 0xB8, 0x70, 0xFF, 0xE8, 0xBE, + 0x7C, 0xFF, 0xED, 0xCD, 0x98, 0xDA, 0xED, 0xD4, 0xAD, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xED, 0xCD, 0x9C, 0x6D, 0xEB, 0xC4, + 0x8C, 0xF8, 0xE8, 0xBB, 0x78, 0xFF, 0xE8, 0xBA, 0x73, 0xFF, 0xE9, 0xBB, 0x73, 0xFF, 0xEE, 0xCA, + 0x8F, 0xFF, 0xF2, 0xD8, 0xAD, 0xFF, 0xF2, 0xD8, 0xAC, 0xFF, 0xF2, 0xD8, 0xAC, 0xFF, 0xF2, 0xD8, + 0xAC, 0xFF, 0xF2, 0xD8, 0xAC, 0xFF, 0xF2, 0xD8, 0xAC, 0xFF, 0xF2, 0xD8, 0xAC, 0xFF, 0xF2, 0xD8, + 0xAC, 0xFF, 0xF2, 0xD8, 0xAC, 0xFF, 0xF2, 0xD8, 0xAC, 0xFF, 0xF2, 0xD8, 0xAC, 0xFF, 0xF2, 0xD8, + 0xAC, 0xFF, 0xF2, 0xD8, 0xAC, 0xFF, 0xF2, 0xD8, 0xAC, 0xFF, 0xF2, 0xD7, 0xAB, 0xFF, 0xF1, 0xD7, + 0xAB, 0xFF, 0xF2, 0xD8, 0xAC, 0xFF, 0xF2, 0xD8, 0xAC, 0xFF, 0xEF, 0xD6, 0xAB, 0xFF, 0xF0, 0xDF, + 0xC0, 0xFF, 0xF9, 0xF5, 0xEE, 0xFF, 0xF1, 0xE7, 0xD2, 0xFF, 0xEB, 0xD5, 0xAC, 0xFF, 0xEC, 0xC8, + 0x8B, 0xFF, 0xE9, 0xBC, 0x73, 0xFF, 0xEA, 0xBD, 0x74, 0xFF, 0xEB, 0xC0, 0x7C, 0xFF, 0xEE, 0xCD, + 0x95, 0xF4, 0xEF, 0xD5, 0xA9, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEA, 0xD6, 0xB4, 0x0A, 0xF0, 0xCF, + 0x9C, 0x94, 0xEE, 0xC8, 0x8D, 0xFE, 0xEB, 0xBF, 0x7C, 0xFF, 0xEC, 0xBF, 0x77, 0xFF, 0xED, 0xC4, + 0x81, 0xFF, 0xF4, 0xD8, 0xAB, 0xFF, 0xF5, 0xDC, 0xB3, 0xFF, 0xF5, 0xDC, 0xB2, 0xFF, 0xF5, 0xDC, + 0xB2, 0xFF, 0xF5, 0xDC, 0xB2, 0xFF, 0xF5, 0xDC, 0xB2, 0xFF, 0xF5, 0xDC, 0xB2, 0xFF, 0xF5, 0xDC, + 0xB2, 0xFF, 0xF5, 0xDC, 0xB2, 0xFF, 0xF5, 0xDC, 0xB2, 0xFF, 0xF5, 0xDC, 0xB2, 0xFF, 0xF5, 0xDC, + 0xB2, 0xFF, 0xF5, 0xDC, 0xB2, 0xFF, 0xF5, 0xDC, 0xB2, 0xFF, 0xF5, 0xDC, 0xB2, 0xFF, 0xF5, 0xDC, + 0xB2, 0xFF, 0xF5, 0xDC, 0xB2, 0xFF, 0xF5, 0xDC, 0xB2, 0xFF, 0xF4, 0xDC, 0xB2, 0xFF, 0xF2, 0xDB, + 0xB1, 0xFF, 0xF2, 0xDE, 0xB9, 0xFF, 0xF1, 0xDB, 0xB5, 0xFF, 0xF2, 0xD7, 0xA8, 0xFF, 0xED, 0xC4, + 0x7F, 0xFF, 0xEC, 0xC0, 0x78, 0xFF, 0xED, 0xC3, 0x7F, 0xFF, 0xF0, 0xCE, 0x94, 0xFB, 0xF2, 0xD6, + 0xA7, 0x87, 0xEB, 0xDE, 0xC5, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF2, 0xD7, + 0xAB, 0x12, 0xF2, 0xD2, 0x9E, 0xA4, 0xF0, 0xCB, 0x90, 0xFF, 0xEF, 0xC4, 0x81, 0xFF, 0xEF, 0xC3, + 0x7D, 0xFF, 0xF3, 0xD0, 0x97, 0xFF, 0xF6, 0xDF, 0xB7, 0xFF, 0xF7, 0xE0, 0xB8, 0xFF, 0xF7, 0xE0, + 0xB8, 0xFF, 0xF7, 0xE0, 0xB8, 0xFF, 0xF7, 0xE0, 0xB8, 0xFF, 0xF7, 0xE0, 0xB8, 0xFF, 0xF7, 0xE0, + 0xB8, 0xFF, 0xF7, 0xE0, 0xB8, 0xFF, 0xF7, 0xE0, 0xB8, 0xFF, 0xF7, 0xE0, 0xB8, 0xFF, 0xF7, 0xE0, + 0xB8, 0xFF, 0xF7, 0xE0, 0xB8, 0xFF, 0xF7, 0xE0, 0xB8, 0xFF, 0xF7, 0xE0, 0xB8, 0xFF, 0xF7, 0xE0, + 0xB8, 0xFF, 0xF7, 0xE0, 0xB8, 0xFF, 0xF7, 0xE0, 0xB8, 0xFF, 0xF6, 0xE0, 0xB8, 0xFF, 0xF6, 0xE0, + 0xB8, 0xFF, 0xF6, 0xE0, 0xB8, 0xFF, 0xF6, 0xDF, 0xB6, 0xFF, 0xF2, 0xD0, 0x94, 0xFF, 0xEF, 0xC4, + 0x7D, 0xFF, 0xF0, 0xC8, 0x83, 0xFF, 0xF3, 0xD1, 0x96, 0xFE, 0xF3, 0xD8, 0xA7, 0x99, 0xF1, 0xDD, + 0xBB, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xF2, 0xD9, 0xAE, 0x17, 0xF4, 0xD4, 0xA1, 0xA1, 0xF3, 0xD0, 0x95, 0xFD, 0xF1, 0xCA, + 0x87, 0xFF, 0xF2, 0xC9, 0x84, 0xFF, 0xF5, 0xD9, 0xA6, 0xFF, 0xF8, 0xE3, 0xBD, 0xFF, 0xF8, 0xE3, + 0xBD, 0xFF, 0xF8, 0xE3, 0xBD, 0xFF, 0xF8, 0xE3, 0xBD, 0xFF, 0xF8, 0xE3, 0xBD, 0xFF, 0xF8, 0xE3, + 0xBD, 0xFF, 0xF8, 0xE3, 0xBD, 0xFF, 0xF8, 0xE3, 0xBD, 0xFF, 0xF8, 0xE3, 0xBD, 0xFF, 0xF8, 0xE3, + 0xBD, 0xFF, 0xF8, 0xE3, 0xBD, 0xFF, 0xF8, 0xE3, 0xBD, 0xFF, 0xF8, 0xE3, 0xBD, 0xFF, 0xF8, 0xE3, + 0xBD, 0xFF, 0xF8, 0xE3, 0xBD, 0xFF, 0xF8, 0xE3, 0xBD, 0xFF, 0xF8, 0xE3, 0xBD, 0xFF, 0xF8, 0xE3, + 0xBD, 0xFF, 0xF8, 0xE3, 0xBD, 0xFF, 0xF5, 0xD8, 0xA4, 0xFF, 0xF2, 0xCA, 0x84, 0xFF, 0xF3, 0xCD, + 0x8A, 0xFF, 0xF5, 0xD4, 0x9B, 0xFB, 0xF6, 0xDA, 0xA9, 0x98, 0xF2, 0xDE, 0xBC, 0x13, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF5, 0xDC, 0xB3, 0x10, 0xF5, 0xD7, 0xA5, 0x87, 0xF5, 0xD4, + 0x9C, 0xF1, 0xF4, 0xCF, 0x90, 0xFF, 0xF4, 0xCE, 0x8C, 0xFF, 0xF7, 0xDC, 0xAB, 0xFF, 0xFA, 0xE6, + 0xC1, 0xFF, 0xFA, 0xE6, 0xC1, 0xFF, 0xFA, 0xE6, 0xC1, 0xFF, 0xFA, 0xE6, 0xC1, 0xFF, 0xFA, 0xE6, + 0xC1, 0xFF, 0xFA, 0xE6, 0xC1, 0xFF, 0xFA, 0xE6, 0xC1, 0xFF, 0xFA, 0xE6, 0xC1, 0xFF, 0xFA, 0xE6, + 0xC1, 0xFF, 0xFA, 0xE6, 0xC1, 0xFF, 0xFA, 0xE6, 0xC1, 0xFF, 0xFA, 0xE6, 0xC1, 0xFF, 0xFA, 0xE6, + 0xC1, 0xFF, 0xFA, 0xE6, 0xC1, 0xFF, 0xFA, 0xE6, 0xC1, 0xFF, 0xFA, 0xE6, 0xC1, 0xFF, 0xF9, 0xE5, + 0xC0, 0xFF, 0xF7, 0xDB, 0xA9, 0xFF, 0xF4, 0xCF, 0x8C, 0xFF, 0xF5, 0xD1, 0x93, 0xFF, 0xF7, 0xD8, + 0xA2, 0xED, 0xF7, 0xDC, 0xAC, 0x7B, 0xF4, 0xE1, 0xC0, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEE, 0xE0, 0xC7, 0x05, 0xF5, 0xD9, + 0xA9, 0x56, 0xF7, 0xD8, 0xA3, 0xCC, 0xF7, 0xD5, 0x9A, 0xFF, 0xF6, 0xD2, 0x94, 0xFF, 0xF8, 0xDB, + 0xA8, 0xFF, 0xFA, 0xE6, 0xC1, 0xFF, 0xFB, 0xE8, 0xC7, 0xFF, 0xFB, 0xE8, 0xC7, 0xFF, 0xFB, 0xE8, + 0xC7, 0xFF, 0xFB, 0xE8, 0xC7, 0xFF, 0xFB, 0xE8, 0xC7, 0xFF, 0xFB, 0xE8, 0xC7, 0xFF, 0xFB, 0xE8, + 0xC7, 0xFF, 0xFB, 0xE8, 0xC7, 0xFF, 0xFB, 0xE8, 0xC7, 0xFF, 0xFB, 0xE8, 0xC5, 0xFF, 0xFB, 0xE8, + 0xC7, 0xFF, 0xFB, 0xE8, 0xC7, 0xFF, 0xFB, 0xE8, 0xC7, 0xFF, 0xFA, 0xE5, 0xC0, 0xFF, 0xF8, 0xDB, + 0xA6, 0xFF, 0xF7, 0xD4, 0x95, 0xFF, 0xF7, 0xD7, 0x9E, 0xFE, 0xF8, 0xDB, 0xA8, 0xC5, 0xF8, 0xDE, + 0xB1, 0x4D, 0xFB, 0xEF, 0xDA, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xF4, 0xDB, 0xB0, 0x1E, 0xF7, 0xDB, 0xA9, 0x82, 0xF8, 0xDA, 0xA4, 0xDD, 0xF8, 0xD7, + 0x9E, 0xFF, 0xF9, 0xDA, 0xA4, 0xFF, 0xFB, 0xE2, 0xB7, 0xFF, 0xFC, 0xE8, 0xC5, 0xFF, 0xFC, 0xEA, + 0xCB, 0xFF, 0xFC, 0xEA, 0xCC, 0xFF, 0xFC, 0xEA, 0xCC, 0xFF, 0xFC, 0xEA, 0xCB, 0xFF, 0xFC, 0xEA, + 0xCB, 0xFF, 0xFC, 0xEA, 0xCB, 0xFF, 0xFC, 0xEA, 0xCC, 0xFF, 0xFC, 0xEA, 0xCC, 0xFF, 0xFC, 0xEA, + 0xCB, 0xFF, 0xFC, 0xE8, 0xC4, 0xFF, 0xFB, 0xE2, 0xB6, 0xFF, 0xF9, 0xDB, 0xA3, 0xFF, 0xF9, 0xD9, + 0xA0, 0xFE, 0xF9, 0xDC, 0xA8, 0xD9, 0xF8, 0xDE, 0xAE, 0x79, 0xF8, 0xE2, 0xB9, 0x19, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFA, 0xFF, 0x01, 0xF7, 0xDD, 0xB1, 0x28, 0xF8, 0xDD, + 0xAC, 0x78, 0xF9, 0xDC, 0xA8, 0xC5, 0xFA, 0xDC, 0xA6, 0xF0, 0xFB, 0xDE, 0xAB, 0xFF, 0xFB, 0xE2, + 0xB5, 0xFF, 0xFC, 0xE6, 0xBF, 0xFF, 0xFC, 0xE8, 0xC4, 0xFF, 0xFC, 0xE9, 0xC8, 0xFF, 0xFC, 0xEA, + 0xC9, 0xFF, 0xFC, 0xE9, 0xC8, 0xFF, 0xFC, 0xE8, 0xC4, 0xFF, 0xFB, 0xE6, 0xBE, 0xFF, 0xFB, 0xE2, + 0xB5, 0xFF, 0xFA, 0xDF, 0xAC, 0xFF, 0xFA, 0xDD, 0xA8, 0xEE, 0xFA, 0xDE, 0xAA, 0xC0, 0xF9, 0xDE, + 0xAF, 0x73, 0xF7, 0xE0, 0xB6, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFA, 0xE6, 0xC1, 0x12, 0xFB, 0xE2, 0xB5, 0x3E, 0xFB, 0xE0, 0xAF, 0x73, 0xFB, 0xDF, + 0xAC, 0xA1, 0xFB, 0xDF, 0xAC, 0xC1, 0xFB, 0xE0, 0xAF, 0xD6, 0xFB, 0xE1, 0xB0, 0xDE, 0xFB, 0xE1, + 0xB1, 0xE1, 0xFB, 0xE1, 0xB0, 0xDE, 0xFB, 0xE0, 0xAF, 0xD5, 0xFB, 0xE0, 0xAD, 0xBF, 0xFB, 0xDF, + 0xAD, 0x9E, 0xFB, 0xE1, 0xB2, 0x6F, 0xFB, 0xE3, 0xB8, 0x3A, 0xFA, 0xE7, 0xC5, 0x0F, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xEA, + 0xCA, 0x04, 0xFB, 0xE2, 0xB2, 0x0F, 0xFC, 0xE2, 0xB3, 0x1F, 0xFC, 0xE2, 0xB2, 0x29, 0xFC, 0xE2, + 0xB2, 0x2D, 0xFC, 0xE2, 0xB3, 0x29, 0xFB, 0xE3, 0xB3, 0x1E, 0xFB, 0xE3, 0xB5, 0x0E, 0xFD, 0xEE, + 0xD3, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, + 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xF8, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xF8, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0xFE, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0xF8, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0xF8, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0xFE, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xC0, + 0x00, 0x00, 0x01, 0xFF, 0x00, 0x00, 0xFF, 0xE0, 0x00, 0x00, 0x03, 0xFF, 0x00, 0x00, 0xFF, 0xF8, + 0x00, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0xFF, 0xFF, + 0x80, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x07, 0xFF, 0xFF, 0x00, 0x00, 0x28, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x44, 0x0C, 0x01, 0x82, 0x44, + 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x04, 0x82, 0x44, 0x0C, 0x07, 0x82, 0x44, 0x0C, 0x09, 0x82, 0x44, + 0x0C, 0x0C, 0x82, 0x44, 0x0C, 0x0E, 0x82, 0x44, 0x0C, 0x10, 0x82, 0x44, 0x0C, 0x12, 0x82, 0x44, + 0x0C, 0x14, 0x82, 0x44, 0x0C, 0x14, 0x82, 0x44, 0x0C, 0x15, 0x82, 0x44, 0x0C, 0x15, 0x82, 0x44, + 0x0C, 0x14, 0x82, 0x44, 0x0C, 0x13, 0x82, 0x44, 0x0C, 0x12, 0x82, 0x44, 0x0C, 0x10, 0x82, 0x44, + 0x0C, 0x0D, 0x82, 0x44, 0x0C, 0x0B, 0x82, 0x44, 0x0C, 0x08, 0x82, 0x44, 0x0C, 0x06, 0x82, 0x44, + 0x0C, 0x03, 0x82, 0x44, 0x0C, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x44, 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x06, 0x82, 0x44, + 0x0C, 0x0D, 0x82, 0x44, 0x0C, 0x15, 0x82, 0x44, 0x0C, 0x1D, 0x82, 0x44, 0x0C, 0x24, 0x82, 0x44, + 0x0C, 0x2B, 0x82, 0x44, 0x0C, 0x30, 0x82, 0x44, 0x0C, 0x35, 0x82, 0x44, 0x0C, 0x39, 0x82, 0x44, + 0x0C, 0x3B, 0x82, 0x44, 0x0C, 0x3D, 0x82, 0x44, 0x0C, 0x3E, 0x82, 0x44, 0x0C, 0x3E, 0x82, 0x44, + 0x0C, 0x3D, 0x82, 0x44, 0x0C, 0x3A, 0x82, 0x44, 0x0C, 0x37, 0x82, 0x44, 0x0C, 0x34, 0x82, 0x44, + 0x0C, 0x2E, 0x82, 0x44, 0x0C, 0x29, 0x82, 0x44, 0x0C, 0x22, 0x82, 0x44, 0x0C, 0x1A, 0x82, 0x44, + 0x0C, 0x11, 0x82, 0x44, 0x0C, 0x0A, 0x82, 0x44, 0x0C, 0x04, 0x82, 0x44, 0x0C, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x82, 0x44, 0x0C, 0x01, 0x82, 0x44, 0x0C, 0x07, 0x82, 0x44, 0x0C, 0x14, 0x82, 0x44, + 0x0C, 0x28, 0x82, 0x44, 0x0C, 0x3D, 0x82, 0x44, 0x0C, 0x4E, 0x82, 0x44, 0x0C, 0x5A, 0x82, 0x44, + 0x0C, 0x64, 0x82, 0x44, 0x0B, 0x6C, 0x81, 0x43, 0x0A, 0x71, 0x81, 0x43, 0x0A, 0x75, 0x82, 0x44, + 0x0B, 0x78, 0x83, 0x45, 0x0D, 0x7B, 0x83, 0x46, 0x0E, 0x7C, 0x83, 0x45, 0x0D, 0x7B, 0x82, 0x43, + 0x0A, 0x7A, 0x81, 0x42, 0x09, 0x77, 0x81, 0x43, 0x0B, 0x74, 0x82, 0x44, 0x0C, 0x6F, 0x82, 0x44, + 0x0C, 0x69, 0x82, 0x44, 0x0C, 0x61, 0x82, 0x44, 0x0C, 0x56, 0x82, 0x44, 0x0C, 0x48, 0x82, 0x44, + 0x0C, 0x35, 0x82, 0x44, 0x0C, 0x20, 0x82, 0x44, 0x0C, 0x0E, 0x82, 0x44, 0x0D, 0x04, 0x97, 0x64, + 0x35, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x82, 0x45, 0x0D, 0x03, 0x82, 0x44, 0x0C, 0x0D, 0x82, 0x44, 0x0C, 0x26, 0x82, 0x44, + 0x0C, 0x49, 0x82, 0x44, 0x0C, 0x6A, 0x82, 0x44, 0x0C, 0x81, 0x82, 0x43, 0x0B, 0x8F, 0x82, 0x43, + 0x0B, 0x98, 0x85, 0x49, 0x12, 0xA2, 0x8A, 0x51, 0x1E, 0xAE, 0x8F, 0x5B, 0x2E, 0xBD, 0x94, 0x65, + 0x3F, 0xCE, 0x96, 0x6A, 0x48, 0xD9, 0x96, 0x6A, 0x49, 0xDB, 0x97, 0x6B, 0x48, 0xD7, 0x94, 0x64, + 0x3C, 0xC9, 0x8E, 0x58, 0x2A, 0xB9, 0x88, 0x4E, 0x1A, 0xAD, 0x83, 0x46, 0x0F, 0xA3, 0x81, 0x43, + 0x0A, 0x9C, 0x82, 0x44, 0x0C, 0x96, 0x82, 0x44, 0x0C, 0x8B, 0x82, 0x44, 0x0C, 0x7A, 0x82, 0x44, + 0x0C, 0x5F, 0x82, 0x44, 0x0C, 0x3B, 0x82, 0x44, 0x0C, 0x1B, 0x82, 0x44, 0x0C, 0x08, 0x85, 0x48, + 0x12, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x83, 0x45, 0x0D, 0x03, 0x82, 0x44, 0x0C, 0x0F, 0x82, 0x44, 0x0C, 0x2B, 0x82, 0x44, + 0x0C, 0x52, 0x82, 0x44, 0x0C, 0x76, 0x82, 0x43, 0x0B, 0x8D, 0x86, 0x4B, 0x14, 0xA2, 0x8F, 0x5C, + 0x30, 0xC4, 0x8E, 0x61, 0x3F, 0xE7, 0x82, 0x55, 0x37, 0xF6, 0x7B, 0x4E, 0x32, 0xFD, 0x78, 0x4B, + 0x31, 0xFF, 0x78, 0x4B, 0x31, 0xFF, 0x79, 0x4D, 0x32, 0xFF, 0x7C, 0x51, 0x36, 0xFF, 0x80, 0x55, + 0x3B, 0xFF, 0x86, 0x5C, 0x40, 0xFB, 0x90, 0x65, 0x48, 0xF3, 0x97, 0x6B, 0x47, 0xE0, 0x8E, 0x58, + 0x28, 0xBC, 0x84, 0x47, 0x0F, 0xA4, 0x81, 0x43, 0x0B, 0x97, 0x82, 0x44, 0x0C, 0x87, 0x82, 0x44, + 0x0C, 0x6A, 0x82, 0x44, 0x0C, 0x43, 0x82, 0x44, 0x0C, 0x1E, 0x82, 0x44, 0x0C, 0x09, 0x82, 0x44, + 0x0C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x82, 0x44, 0x0C, 0x02, 0x82, 0x44, 0x0C, 0x0A, 0x82, 0x44, 0x0C, 0x1D, 0x81, 0x43, + 0x0A, 0x38, 0x84, 0x47, 0x0F, 0x55, 0x91, 0x5D, 0x30, 0x90, 0x8B, 0x5D, 0x3B, 0xDF, 0x77, 0x48, + 0x2B, 0xFC, 0x6D, 0x3D, 0x20, 0xFF, 0x6C, 0x3B, 0x1C, 0xFF, 0x70, 0x3E, 0x1E, 0xFF, 0x73, 0x42, + 0x21, 0xFF, 0x77, 0x45, 0x24, 0xFF, 0x79, 0x48, 0x27, 0xFF, 0x7B, 0x4A, 0x29, 0xFF, 0x7C, 0x4C, + 0x2B, 0xFF, 0x7C, 0x4D, 0x2D, 0xFF, 0x7E, 0x50, 0x32, 0xFF, 0x84, 0x58, 0x3B, 0xFF, 0x8F, 0x65, + 0x48, 0xF7, 0x9A, 0x6E, 0x4B, 0xCF, 0x8D, 0x56, 0x24, 0x85, 0x81, 0x43, 0x0A, 0x60, 0x82, 0x44, + 0x0C, 0x4A, 0x82, 0x44, 0x0C, 0x2E, 0x82, 0x44, 0x0C, 0x15, 0x82, 0x44, 0x0C, 0x06, 0x89, 0x4F, + 0x1A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x83, 0x46, 0x0E, 0x01, 0x82, 0x45, 0x0D, 0x04, 0x7D, 0x3C, 0x01, 0x0A, 0x92, 0x5C, + 0x2A, 0x1E, 0x95, 0x68, 0x45, 0x88, 0x7A, 0x49, 0x29, 0xEF, 0x66, 0x31, 0x12, 0xFF, 0x63, 0x2D, + 0x0B, 0xFF, 0x69, 0x31, 0x0C, 0xFF, 0x6E, 0x36, 0x0E, 0xFF, 0x73, 0x3B, 0x11, 0xFF, 0x78, 0x40, + 0x14, 0xFF, 0x7D, 0x46, 0x1A, 0xFF, 0x81, 0x4B, 0x20, 0xFF, 0x84, 0x4F, 0x25, 0xFF, 0x86, 0x52, + 0x29, 0xFF, 0x87, 0x54, 0x2C, 0xFF, 0x86, 0x54, 0x2E, 0xFF, 0x84, 0x53, 0x2F, 0xFF, 0x83, 0x53, + 0x32, 0xFF, 0x8A, 0x5D, 0x3F, 0xFF, 0x9A, 0x71, 0x52, 0xDC, 0x9F, 0x73, 0x4C, 0x63, 0x82, 0x43, + 0x0A, 0x1F, 0x81, 0x43, 0x0A, 0x13, 0x82, 0x44, 0x0C, 0x08, 0x83, 0x45, 0x0D, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0x9B, 0x7C, 0x09, 0x98, 0x6D, + 0x4D, 0x85, 0x74, 0x40, 0x1E, 0xF7, 0x62, 0x2B, 0x07, 0xFF, 0x66, 0x2C, 0x05, 0xFF, 0x69, 0x2F, + 0x05, 0xFF, 0x70, 0x35, 0x06, 0xFF, 0x77, 0x3A, 0x09, 0xFF, 0x7B, 0x3D, 0x09, 0xFF, 0x7D, 0x3F, + 0x0A, 0xFF, 0x7E, 0x40, 0x0B, 0xFF, 0x80, 0x42, 0x0C, 0xFF, 0x81, 0x44, 0x0F, 0xFF, 0x84, 0x48, + 0x13, 0xFF, 0x88, 0x4F, 0x1D, 0xFF, 0x8C, 0x56, 0x28, 0xFF, 0x8D, 0x59, 0x2D, 0xFF, 0x8B, 0x59, + 0x2F, 0xFF, 0x88, 0x57, 0x30, 0xFF, 0x89, 0x5B, 0x38, 0xFF, 0x9B, 0x72, 0x52, 0xE2, 0xAE, 0x8A, + 0x6C, 0x4F, 0x76, 0x2C, 0x00, 0x03, 0x7A, 0x38, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x02, 0x9F, 0x76, 0x55, 0x71, 0x78, 0x43, + 0x1F, 0xF7, 0x67, 0x2D, 0x07, 0xFF, 0x6B, 0x30, 0x06, 0xFF, 0x6C, 0x37, 0x0C, 0xFF, 0x7F, 0x59, + 0x36, 0xFF, 0x79, 0x4D, 0x23, 0xFF, 0x79, 0x3E, 0x09, 0xFF, 0x84, 0x45, 0x0B, 0xFF, 0x86, 0x46, + 0x0C, 0xFF, 0x86, 0x46, 0x0C, 0xFF, 0x86, 0x46, 0x0C, 0xFF, 0x86, 0x46, 0x0C, 0xFF, 0x86, 0x46, + 0x0B, 0xFF, 0x86, 0x46, 0x0C, 0xFF, 0x87, 0x48, 0x10, 0xFF, 0x8A, 0x4E, 0x17, 0xFF, 0x90, 0x58, + 0x26, 0xFF, 0x91, 0x5C, 0x2E, 0xFF, 0x8E, 0x5B, 0x30, 0xFF, 0x8D, 0x5D, 0x37, 0xFF, 0xA0, 0x76, + 0x55, 0xDC, 0xBA, 0x99, 0x7E, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x83, 0x62, 0x42, 0x82, 0x4F, 0x29, 0xEB, 0x6B, 0x30, + 0x08, 0xFF, 0x70, 0x34, 0x07, 0xFF, 0x71, 0x3D, 0x10, 0xFF, 0xA7, 0x91, 0x7B, 0xFF, 0xCA, 0xC3, + 0xBB, 0xFF, 0xB6, 0xAB, 0x9B, 0xFF, 0x8A, 0x67, 0x41, 0xFF, 0x7C, 0x45, 0x0D, 0xFF, 0x88, 0x49, + 0x0C, 0xFF, 0x8B, 0x4A, 0x0D, 0xFF, 0x8B, 0x4A, 0x0D, 0xFF, 0x8B, 0x4A, 0x0D, 0xFF, 0x8B, 0x4A, + 0x0D, 0xFF, 0x8B, 0x4A, 0x0D, 0xFF, 0x8A, 0x4A, 0x0D, 0xFF, 0x8A, 0x4A, 0x0C, 0xFF, 0x8A, 0x4B, + 0x0F, 0xFF, 0x8D, 0x51, 0x17, 0xFF, 0x93, 0x5B, 0x28, 0xFF, 0x92, 0x5D, 0x30, 0xFF, 0x93, 0x62, + 0x39, 0xFF, 0xA9, 0x81, 0x5F, 0xC2, 0xC7, 0xAA, 0x91, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xC3, 0xA2, 0x84, 0x13, 0x96, 0x66, 0x40, 0xBF, 0x72, 0x37, 0x0E, 0xFF, 0x74, 0x36, + 0x08, 0xFF, 0x75, 0x3E, 0x0E, 0xFF, 0xA7, 0x90, 0x78, 0xFF, 0xE4, 0xE3, 0xE2, 0xFF, 0xE5, 0xE5, + 0xE4, 0xFF, 0xCE, 0xCA, 0xC3, 0xFF, 0xAD, 0xA3, 0x93, 0xFF, 0x9D, 0x84, 0x66, 0xFF, 0x7E, 0x4C, + 0x15, 0xFF, 0x88, 0x4A, 0x0C, 0xFF, 0x8E, 0x4E, 0x0E, 0xFF, 0x8E, 0x4E, 0x0E, 0xFF, 0x8E, 0x4E, + 0x0E, 0xFF, 0x8E, 0x4E, 0x0E, 0xFF, 0x8E, 0x4E, 0x0E, 0xFF, 0x8E, 0x4E, 0x0E, 0xFF, 0x8E, 0x4D, + 0x0E, 0xFF, 0x8D, 0x4D, 0x0D, 0xFF, 0x8E, 0x4E, 0x11, 0xFF, 0x92, 0x57, 0x1F, 0xFF, 0x94, 0x5E, + 0x2E, 0xFF, 0x9C, 0x6C, 0x43, 0xFD, 0xB7, 0x94, 0x73, 0x80, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xAA, 0x81, 0x5D, 0x55, 0x82, 0x4A, 0x1F, 0xF9, 0x76, 0x38, 0x08, 0xFF, 0x7C, 0x3F, + 0x09, 0xFF, 0x9E, 0x7D, 0x5A, 0xFF, 0xE3, 0xE1, 0xDF, 0xFF, 0xE8, 0xE8, 0xE8, 0xFF, 0xEA, 0xEA, + 0xEA, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xD3, 0xD0, 0xCB, 0xFF, 0xA6, 0x9C, 0x8C, 0xFF, 0xA6, 0x95, + 0x7D, 0xFF, 0x84, 0x59, 0x27, 0xFF, 0x87, 0x4B, 0x0C, 0xFF, 0x91, 0x51, 0x0F, 0xFF, 0x92, 0x51, + 0x0F, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x92, 0x51, + 0x0F, 0xFF, 0x92, 0x51, 0x0F, 0xFF, 0x91, 0x50, 0x0E, 0xFF, 0x90, 0x4F, 0x0F, 0xFF, 0x92, 0x55, + 0x18, 0xFF, 0x97, 0x61, 0x2E, 0xFF, 0xAA, 0x7F, 0x57, 0xDA, 0xC8, 0xA8, 0x8B, 0x1F, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDB, 0xC3, + 0xA9, 0x0C, 0xA0, 0x71, 0x48, 0xB8, 0x7C, 0x3F, 0x0F, 0xFF, 0x81, 0x41, 0x0A, 0xFF, 0x88, 0x48, + 0x0C, 0xFF, 0xAF, 0x8D, 0x68, 0xFF, 0xEB, 0xEA, 0xE9, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xEC, 0xEC, + 0xEC, 0xFF, 0xEF, 0xEF, 0xEE, 0xFF, 0xF1, 0xF1, 0xF1, 0xFF, 0xDD, 0xDB, 0xD6, 0xFF, 0xA7, 0x9E, + 0x8D, 0xFF, 0xAB, 0x9E, 0x8A, 0xFF, 0x91, 0x70, 0x47, 0xFF, 0x86, 0x4F, 0x11, 0xFF, 0x94, 0x55, + 0x11, 0xFF, 0x97, 0x56, 0x12, 0xFF, 0x97, 0x56, 0x12, 0xFF, 0x96, 0x56, 0x11, 0xFF, 0x96, 0x55, + 0x10, 0xFF, 0x96, 0x55, 0x10, 0xFF, 0x96, 0x54, 0x10, 0xFF, 0x95, 0x54, 0x0F, 0xFF, 0x93, 0x52, + 0x0F, 0xFF, 0x93, 0x54, 0x16, 0xFF, 0xA2, 0x6E, 0x3D, 0xFC, 0xC1, 0x9E, 0x7B, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x96, + 0x71, 0x2C, 0x94, 0x5D, 0x2E, 0xE9, 0x81, 0x41, 0x0B, 0xFF, 0x8B, 0x4A, 0x0D, 0xFF, 0x92, 0x51, + 0x0E, 0xFF, 0x96, 0x5B, 0x19, 0xFF, 0xCB, 0xB5, 0x9B, 0xFF, 0xEE, 0xEF, 0xEF, 0xFF, 0xEE, 0xEE, + 0xEE, 0xFF, 0xEE, 0xEE, 0xEE, 0xFF, 0xEF, 0xEF, 0xEF, 0xFF, 0xF3, 0xF3, 0xF3, 0xFF, 0xE7, 0xE5, + 0xE3, 0xFF, 0xB1, 0xA9, 0x99, 0xFF, 0xAB, 0x9F, 0x8B, 0xFF, 0xA5, 0x8F, 0x70, 0xFF, 0x89, 0x59, + 0x1D, 0xFF, 0x96, 0x59, 0x14, 0xFF, 0x9D, 0x5D, 0x16, 0xFF, 0x9D, 0x5D, 0x16, 0xFF, 0x9C, 0x5C, + 0x16, 0xFF, 0x9C, 0x5C, 0x15, 0xFF, 0x9B, 0x5A, 0x13, 0xFF, 0x9A, 0x59, 0x11, 0xFF, 0x99, 0x57, + 0x10, 0xFF, 0x96, 0x54, 0x0F, 0xFF, 0x99, 0x5C, 0x1F, 0xFF, 0xB6, 0x8C, 0x62, 0xB9, 0xD0, 0xBD, + 0xA8, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB3, 0x88, + 0x5F, 0x50, 0x8F, 0x53, 0x1F, 0xFA, 0x89, 0x47, 0x0B, 0xFF, 0x93, 0x52, 0x0F, 0xFF, 0x9C, 0x5B, + 0x14, 0xFF, 0xA0, 0x60, 0x18, 0xFF, 0xA4, 0x70, 0x33, 0xFF, 0xD7, 0xCC, 0xBC, 0xFF, 0xE9, 0xEA, + 0xEA, 0xFF, 0xE9, 0xE9, 0xE9, 0xFF, 0xE9, 0xE9, 0xE9, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xEE, 0xEE, + 0xEE, 0xFF, 0xE9, 0xE9, 0xE8, 0xFF, 0xBD, 0xB5, 0xA7, 0xFF, 0xA8, 0x9D, 0x87, 0xFF, 0xB6, 0xA7, + 0x91, 0xFF, 0x8F, 0x68, 0x33, 0xFF, 0x97, 0x5E, 0x19, 0xFF, 0xA2, 0x63, 0x1C, 0xFF, 0xA3, 0x64, + 0x1C, 0xFF, 0xA2, 0x64, 0x1C, 0xFF, 0xA2, 0x63, 0x1C, 0xFF, 0xA1, 0x62, 0x1A, 0xFF, 0x9F, 0x5E, + 0x14, 0xFF, 0x9C, 0x5A, 0x11, 0xFF, 0x99, 0x58, 0x13, 0xFF, 0xAC, 0x79, 0x44, 0xDC, 0xCE, 0xAF, + 0x90, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB3, 0x86, + 0x5A, 0x75, 0x91, 0x52, 0x18, 0xFF, 0x92, 0x50, 0x0F, 0xFF, 0x9F, 0x60, 0x1B, 0xFF, 0xA7, 0x69, + 0x22, 0xFF, 0xA9, 0x6C, 0x23, 0xFF, 0xA7, 0x6A, 0x21, 0xFF, 0xAD, 0x82, 0x4B, 0xFF, 0xD9, 0xD3, + 0xCB, 0xFF, 0xE1, 0xE1, 0xE2, 0xFF, 0xE0, 0xE0, 0xE0, 0xFF, 0xE0, 0xE0, 0xE1, 0xFF, 0xE1, 0xE0, + 0xDF, 0xFF, 0xE4, 0xE4, 0xE3, 0xFF, 0xE7, 0xE7, 0xE7, 0xFF, 0xC8, 0xC1, 0xB7, 0xFF, 0xA7, 0x9B, + 0x84, 0xFF, 0xBE, 0xB4, 0xA4, 0xFF, 0x9B, 0x7D, 0x52, 0xFF, 0x98, 0x64, 0x21, 0xFF, 0xA7, 0x6A, + 0x22, 0xFF, 0xA9, 0x6C, 0x23, 0xFF, 0xA9, 0x6C, 0x23, 0xFF, 0xA9, 0x6C, 0x23, 0xFF, 0xA9, 0x6B, + 0x22, 0xFF, 0xA5, 0x65, 0x1A, 0xFF, 0x9F, 0x5C, 0x12, 0xFF, 0xAA, 0x72, 0x35, 0xED, 0xCC, 0xA9, + 0x82, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x02, 0xB9, 0x8D, + 0x60, 0x94, 0x97, 0x56, 0x18, 0xFF, 0xA0, 0x62, 0x1F, 0xFF, 0xAB, 0x6E, 0x28, 0xFF, 0xAF, 0x72, + 0x2A, 0xFF, 0xB0, 0x73, 0x2A, 0xFF, 0xB0, 0x73, 0x2A, 0xFF, 0xAC, 0x71, 0x29, 0xFF, 0xB5, 0x92, + 0x64, 0xFF, 0xD5, 0xD3, 0xCF, 0xFF, 0xD9, 0xD9, 0xDA, 0xFF, 0xDB, 0xDB, 0xDB, 0xFF, 0xB8, 0xAE, + 0x9C, 0xFF, 0xB9, 0xAC, 0x94, 0xFF, 0xDF, 0xDE, 0xDD, 0xFF, 0xE3, 0xE3, 0xE3, 0xFF, 0xD1, 0xCD, + 0xC5, 0xFF, 0xAC, 0xA2, 0x8C, 0xFF, 0xC2, 0xBB, 0xAE, 0xFF, 0xAC, 0x98, 0x79, 0xFF, 0x99, 0x6C, + 0x2D, 0xFF, 0xAA, 0x70, 0x28, 0xFF, 0xB0, 0x73, 0x2A, 0xFF, 0xB0, 0x73, 0x2A, 0xFF, 0xB0, 0x73, + 0x2A, 0xFF, 0xAF, 0x73, 0x29, 0xFF, 0xA9, 0x6A, 0x1F, 0xFF, 0xAD, 0x74, 0x32, 0xF5, 0xCE, 0xA9, + 0x81, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x03, 0xBF, 0x94, + 0x67, 0x9D, 0xA4, 0x68, 0x2B, 0xFF, 0xAC, 0x70, 0x2E, 0xFF, 0xB2, 0x77, 0x30, 0xFF, 0xB5, 0x7B, + 0x31, 0xFF, 0xB6, 0x7B, 0x31, 0xFF, 0xB6, 0x7B, 0x31, 0xFF, 0xB6, 0x7B, 0x31, 0xFF, 0xB3, 0x7D, + 0x37, 0xFF, 0xC1, 0xA9, 0x88, 0xFF, 0xD6, 0xD6, 0xD5, 0xFF, 0xD8, 0xD8, 0xD8, 0xFF, 0xCD, 0xCA, + 0xC2, 0xFF, 0xBB, 0xB0, 0x9A, 0xFF, 0xBF, 0xB4, 0x9E, 0xFF, 0xBE, 0xB5, 0xA0, 0xFF, 0xD2, 0xCE, + 0xC3, 0xFF, 0xD8, 0xD6, 0xD3, 0xFF, 0xB7, 0xAF, 0x9D, 0xFF, 0xC4, 0xBF, 0xB2, 0xFF, 0xBC, 0xAF, + 0x9A, 0xFF, 0x9F, 0x78, 0x3F, 0xFF, 0xAF, 0x78, 0x30, 0xFF, 0xB6, 0x7B, 0x31, 0xFF, 0xB6, 0x7B, + 0x31, 0xFF, 0xB6, 0x7B, 0x31, 0xFF, 0xB4, 0x79, 0x30, 0xFF, 0xB8, 0x81, 0x41, 0xF7, 0xD2, 0xAF, + 0x86, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x01, 0xC9, 0x9F, + 0x73, 0x8E, 0xB1, 0x78, 0x3C, 0xFF, 0xB4, 0x79, 0x36, 0xFF, 0xB9, 0x80, 0x38, 0xFF, 0xBC, 0x83, + 0x39, 0xFF, 0xBC, 0x83, 0x39, 0xFF, 0xBC, 0x83, 0x39, 0xFF, 0xBE, 0x87, 0x3F, 0xFF, 0xC4, 0x92, + 0x51, 0xFF, 0xC2, 0x97, 0x5D, 0xFF, 0xCF, 0xBE, 0xA8, 0xFF, 0xDC, 0xDD, 0xDD, 0xFF, 0xDF, 0xDF, + 0xE0, 0xFF, 0xD5, 0xD2, 0xCB, 0xFF, 0xC5, 0xBD, 0xAA, 0xFF, 0xCC, 0xC5, 0xB8, 0xFF, 0xD1, 0xCE, + 0xC8, 0xFF, 0xDE, 0xDE, 0xDF, 0xFF, 0xDD, 0xDC, 0xDA, 0xFF, 0xC3, 0xBE, 0xAF, 0xFF, 0xC8, 0xC2, + 0xB6, 0xFF, 0xCA, 0xBF, 0xAE, 0xFF, 0xAE, 0x82, 0x44, 0xFF, 0xBB, 0x82, 0x38, 0xFF, 0xBC, 0x83, + 0x39, 0xFF, 0xBC, 0x83, 0x39, 0xFF, 0xBB, 0x82, 0x38, 0xFF, 0xC2, 0x90, 0x53, 0xF3, 0xD8, 0xB7, + 0x8F, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCD, 0xA4, + 0x76, 0x6B, 0xBA, 0x84, 0x49, 0xFF, 0xBB, 0x82, 0x3E, 0xFF, 0xC0, 0x88, 0x40, 0xFF, 0xC2, 0x8B, + 0x41, 0xFF, 0xC2, 0x8B, 0x41, 0xFF, 0xC3, 0x8D, 0x45, 0xFF, 0xCC, 0x9C, 0x5D, 0xFF, 0xCF, 0xA1, + 0x65, 0xFF, 0xCE, 0xA0, 0x64, 0xFF, 0xCB, 0xA4, 0x70, 0xFF, 0xDA, 0xD0, 0xC0, 0xFF, 0xE6, 0xE7, + 0xE8, 0xFF, 0xDA, 0xD6, 0xCE, 0xFF, 0xCE, 0xC7, 0xB6, 0xFF, 0xC9, 0xC0, 0xAF, 0xFF, 0xD1, 0xCA, + 0xBD, 0xFF, 0xDE, 0xDD, 0xDD, 0xFF, 0xE0, 0xE0, 0xE1, 0xFF, 0xE3, 0xE2, 0xE2, 0xFF, 0xD2, 0xCF, + 0xC4, 0xFF, 0xCD, 0xC4, 0xB2, 0xFF, 0xB9, 0x90, 0x54, 0xFF, 0xC1, 0x8A, 0x40, 0xFF, 0xC2, 0x8B, + 0x41, 0xFF, 0xC2, 0x8B, 0x41, 0xFF, 0xC1, 0x8A, 0x41, 0xFF, 0xCB, 0x9C, 0x60, 0xEA, 0xDD, 0xBF, + 0x99, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD5, 0xAE, + 0x80, 0x47, 0xC5, 0x93, 0x58, 0xF7, 0xC2, 0x8A, 0x47, 0xFF, 0xC8, 0x91, 0x49, 0xFF, 0xCA, 0x94, + 0x4A, 0xFF, 0xCA, 0x94, 0x4A, 0xFF, 0xCF, 0x9D, 0x5B, 0xFF, 0xD5, 0xAB, 0x72, 0xFF, 0xD5, 0xAB, + 0x72, 0xFF, 0xD5, 0xAB, 0x72, 0xFF, 0xD4, 0xAA, 0x71, 0xFF, 0xD3, 0xB2, 0x83, 0xFF, 0xE5, 0xDE, + 0xD5, 0xFF, 0xDE, 0xDC, 0xD7, 0xFF, 0xCC, 0xC5, 0xB6, 0xFF, 0xD5, 0xD1, 0xC5, 0xFF, 0xBE, 0xB5, + 0x9E, 0xFF, 0xE1, 0xE0, 0xDF, 0xFF, 0xE4, 0xE4, 0xE4, 0xFF, 0xE5, 0xE5, 0xE5, 0xFF, 0xE9, 0xE9, + 0xE9, 0xFF, 0xD1, 0xC5, 0xB0, 0xFF, 0xBA, 0x92, 0x54, 0xFF, 0xC5, 0x91, 0x48, 0xFF, 0xCA, 0x94, + 0x4A, 0xFF, 0xCA, 0x94, 0x4A, 0xFF, 0xCA, 0x95, 0x4D, 0xFF, 0xD4, 0xA9, 0x72, 0xD5, 0xDE, 0xC4, + 0xA2, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xBD, + 0x92, 0x23, 0xD2, 0xA4, 0x6C, 0xE2, 0xCB, 0x94, 0x51, 0xFF, 0xCE, 0x99, 0x51, 0xFF, 0xD1, 0x9C, + 0x52, 0xFF, 0xD2, 0x9E, 0x55, 0xFF, 0xDA, 0xB0, 0x75, 0xFF, 0xDC, 0xB6, 0x7F, 0xFF, 0xDC, 0xB6, + 0x7F, 0xFF, 0xDC, 0xB6, 0x7F, 0xFF, 0xDC, 0xB6, 0x7F, 0xFF, 0xDB, 0xB5, 0x7D, 0xFF, 0xDB, 0xBF, + 0x96, 0xFF, 0xEA, 0xE6, 0xDF, 0xFF, 0xEF, 0xEF, 0xEF, 0xFF, 0xEC, 0xEC, 0xEC, 0xFF, 0xE6, 0xE6, + 0xE5, 0xFF, 0xE9, 0xE9, 0xE9, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xEA, 0xEA, 0xE9, 0xFF, 0xEB, 0xEB, + 0xE9, 0xFF, 0xE2, 0xE0, 0xD8, 0xFF, 0xCB, 0xBB, 0x9D, 0xFF, 0xC0, 0x9C, 0x61, 0xFF, 0xCE, 0x9B, + 0x51, 0xFF, 0xD1, 0x9C, 0x52, 0xFF, 0xD3, 0xA1, 0x5C, 0xFF, 0xDD, 0xB8, 0x87, 0xAC, 0xD7, 0xCD, + 0xBF, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xDF, + 0xC4, 0x06, 0xDD, 0xB4, 0x81, 0xA0, 0xD4, 0xA0, 0x5F, 0xFF, 0xD5, 0xA1, 0x59, 0xFF, 0xD7, 0xA4, + 0x5A, 0xFF, 0xDA, 0xA9, 0x61, 0xFF, 0xE2, 0xBD, 0x86, 0xFF, 0xE3, 0xBF, 0x8B, 0xFF, 0xE3, 0xBF, + 0x8B, 0xFF, 0xE3, 0xBF, 0x8B, 0xFF, 0xE3, 0xBF, 0x8B, 0xFF, 0xE3, 0xBF, 0x8B, 0xFF, 0xE2, 0xBE, + 0x8A, 0xFF, 0xE1, 0xCA, 0xA5, 0xFF, 0xEF, 0xEC, 0xE6, 0xFF, 0xF2, 0xF3, 0xF3, 0xFF, 0xF0, 0xF0, + 0xF0, 0xFF, 0xF0, 0xF0, 0xF0, 0xFF, 0xEF, 0xEF, 0xEF, 0xFF, 0xEC, 0xEC, 0xE9, 0xFF, 0xEF, 0xEF, + 0xEE, 0xFF, 0xED, 0xED, 0xEA, 0xFF, 0xEB, 0xEA, 0xE6, 0xFF, 0xD7, 0xC2, 0x9F, 0xFF, 0xD3, 0xA2, + 0x5A, 0xFF, 0xD8, 0xA5, 0x5B, 0xFF, 0xDC, 0xB0, 0x70, 0xF7, 0xE2, 0xC3, 0x98, 0x56, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xE3, 0xBF, 0x90, 0x41, 0xDE, 0xB1, 0x75, 0xF2, 0xDB, 0xA8, 0x62, 0xFF, 0xDD, 0xAC, + 0x62, 0xFF, 0xE0, 0xB1, 0x6B, 0xFF, 0xE8, 0xC7, 0x92, 0xFF, 0xE9, 0xC9, 0x97, 0xFF, 0xE9, 0xC9, + 0x96, 0xFF, 0xE9, 0xC9, 0x96, 0xFF, 0xE9, 0xC9, 0x96, 0xFF, 0xE9, 0xC9, 0x96, 0xFF, 0xE9, 0xC9, + 0x96, 0xFF, 0xE7, 0xC8, 0x96, 0xFF, 0xE7, 0xD2, 0xAF, 0xFF, 0xF2, 0xEF, 0xE9, 0xFF, 0xF5, 0xF6, + 0xF7, 0xFF, 0xF3, 0xF3, 0xF2, 0xFF, 0xF3, 0xF3, 0xF1, 0xFF, 0xF4, 0xF4, 0xF4, 0xFF, 0xF4, 0xF4, + 0xF3, 0xFF, 0xEA, 0xEA, 0xE4, 0xFF, 0xEC, 0xE5, 0xD9, 0xFF, 0xD7, 0xB4, 0x7B, 0xFF, 0xDC, 0xAC, + 0x62, 0xFF, 0xE0, 0xB0, 0x69, 0xFF, 0xE5, 0xC0, 0x89, 0xCA, 0xE7, 0xCF, 0xA9, 0x14, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xE6, 0xCD, 0xA7, 0x09, 0xE6, 0xC0, 0x8B, 0xA1, 0xE2, 0xB3, 0x72, 0xFF, 0xE2, 0xB2, + 0x6A, 0xFF, 0xE5, 0xB8, 0x71, 0xFF, 0xED, 0xCD, 0x9A, 0xFF, 0xEE, 0xD1, 0xA2, 0xFF, 0xEE, 0xD1, + 0xA1, 0xFF, 0xEE, 0xD1, 0xA1, 0xFF, 0xEE, 0xD1, 0xA1, 0xFF, 0xEE, 0xD1, 0xA1, 0xFF, 0xEE, 0xD1, + 0xA1, 0xFF, 0xEE, 0xD1, 0xA1, 0xFF, 0xED, 0xD0, 0xA1, 0xFF, 0xEC, 0xD7, 0xB3, 0xFF, 0xF2, 0xEA, + 0xDC, 0xFF, 0xEA, 0xDB, 0xC0, 0xFF, 0xED, 0xDE, 0xC4, 0xFF, 0xF6, 0xF4, 0xEF, 0xFF, 0xE9, 0xE8, + 0xE1, 0xFF, 0xF4, 0xF1, 0xEB, 0xFF, 0xE4, 0xCC, 0xA0, 0xFF, 0xE1, 0xB3, 0x6A, 0xFF, 0xE4, 0xB5, + 0x6C, 0xFF, 0xE7, 0xBE, 0x80, 0xF6, 0xEB, 0xCD, 0x9F, 0x5D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEB, 0xCC, 0x9C, 0x2A, 0xEA, 0xC3, 0x8A, 0xD9, 0xE8, 0xBA, + 0x76, 0xFF, 0xE9, 0xBB, 0x74, 0xFF, 0xEF, 0xCE, 0x98, 0xFF, 0xF2, 0xD8, 0xAC, 0xFF, 0xF2, 0xD7, + 0xAB, 0xFF, 0xF2, 0xD7, 0xAB, 0xFF, 0xF2, 0xD7, 0xAB, 0xFF, 0xF2, 0xD7, 0xAB, 0xFF, 0xF2, 0xD7, + 0xAB, 0xFF, 0xF2, 0xD7, 0xAB, 0xFF, 0xF2, 0xD7, 0xAB, 0xFF, 0xF1, 0xD7, 0xAA, 0xFF, 0xF0, 0xD7, + 0xAD, 0xFF, 0xF0, 0xD6, 0xAA, 0xFF, 0xF0, 0xD6, 0xAB, 0xFF, 0xF1, 0xE1, 0xC3, 0xFF, 0xF4, 0xEF, + 0xE3, 0xFF, 0xED, 0xDC, 0xBD, 0xFF, 0xE9, 0xC3, 0x85, 0xFF, 0xE9, 0xBB, 0x72, 0xFF, 0xEB, 0xC1, + 0x7F, 0xFF, 0xEE, 0xCE, 0x9A, 0xA5, 0xED, 0xD8, 0xB7, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEF, 0xCF, 0x9C, 0x4B, 0xEE, 0xC8, + 0x8D, 0xE8, 0xED, 0xC0, 0x7C, 0xFF, 0xEF, 0xC9, 0x88, 0xFF, 0xF5, 0xDC, 0xB1, 0xFF, 0xF5, 0xDD, + 0xB4, 0xFF, 0xF5, 0xDD, 0xB4, 0xFF, 0xF5, 0xDD, 0xB4, 0xFF, 0xF5, 0xDD, 0xB4, 0xFF, 0xF5, 0xDD, + 0xB4, 0xFF, 0xF5, 0xDD, 0xB4, 0xFF, 0xF5, 0xDD, 0xB4, 0xFF, 0xF5, 0xDD, 0xB4, 0xFF, 0xF5, 0xDD, + 0xB4, 0xFF, 0xF5, 0xDD, 0xB4, 0xFF, 0xF5, 0xDD, 0xB4, 0xFF, 0xF4, 0xDD, 0xB4, 0xFF, 0xF4, 0xE0, + 0xBB, 0xFF, 0xF2, 0xD7, 0xA8, 0xFF, 0xEE, 0xC4, 0x7E, 0xFF, 0xEE, 0xC7, 0x83, 0xFF, 0xF1, 0xD1, + 0x99, 0xC2, 0xF1, 0xD8, 0xAE, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFA, 0xFF, 0xFF, 0x01, 0xF3, 0xD3, + 0xA0, 0x56, 0xF2, 0xCE, 0x93, 0xE7, 0xF1, 0xC9, 0x86, 0xFF, 0xF4, 0xD5, 0x9F, 0xFF, 0xF8, 0xE2, + 0xBB, 0xFF, 0xF8, 0xE3, 0xBC, 0xFF, 0xF8, 0xE3, 0xBC, 0xFF, 0xF8, 0xE3, 0xBC, 0xFF, 0xF8, 0xE3, + 0xBC, 0xFF, 0xF8, 0xE3, 0xBC, 0xFF, 0xF8, 0xE3, 0xBC, 0xFF, 0xF8, 0xE3, 0xBC, 0xFF, 0xF8, 0xE3, + 0xBC, 0xFF, 0xF8, 0xE3, 0xBC, 0xFF, 0xF8, 0xE3, 0xBC, 0xFF, 0xF8, 0xE3, 0xBC, 0xFF, 0xF7, 0xE0, + 0xB6, 0xFF, 0xF3, 0xD0, 0x92, 0xFF, 0xF2, 0xCC, 0x8A, 0xFF, 0xF4, 0xD4, 0x9E, 0xC4, 0xF4, 0xDA, + 0xAE, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0x01, 0xF5, 0xD7, 0xA5, 0x44, 0xF5, 0xD4, 0x9B, 0xCE, 0xF5, 0xD1, 0x93, 0xFF, 0xF7, 0xDB, + 0xA8, 0xFF, 0xFA, 0xE5, 0xC0, 0xFF, 0xFA, 0xE6, 0xC3, 0xFF, 0xFA, 0xE6, 0xC2, 0xFF, 0xFA, 0xE6, + 0xC2, 0xFF, 0xFA, 0xE6, 0xC2, 0xFF, 0xFA, 0xE6, 0xC2, 0xFF, 0xFA, 0xE6, 0xC2, 0xFF, 0xFA, 0xE6, + 0xC2, 0xFF, 0xFA, 0xE6, 0xC3, 0xFF, 0xFA, 0xE6, 0xC3, 0xFF, 0xF9, 0xE3, 0xBB, 0xFF, 0xF6, 0xD7, + 0x9E, 0xFF, 0xF6, 0xD3, 0x96, 0xF8, 0xF7, 0xD8, 0xA4, 0xA6, 0xF7, 0xDD, 0xB1, 0x21, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF5, 0xDA, 0xAC, 0x1E, 0xF7, 0xD9, 0xA4, 0x84, 0xF8, 0xD8, + 0x9F, 0xE5, 0xF9, 0xDC, 0xA8, 0xFF, 0xFB, 0xE4, 0xBD, 0xFF, 0xFC, 0xE8, 0xC8, 0xFF, 0xFC, 0xE9, + 0xCA, 0xFF, 0xFC, 0xEA, 0xCA, 0xFF, 0xFC, 0xEA, 0xCA, 0xFF, 0xFC, 0xE9, 0xCA, 0xFF, 0xFC, 0xE9, + 0xC9, 0xFF, 0xFC, 0xE8, 0xC5, 0xFF, 0xFB, 0xE2, 0xB7, 0xFF, 0xF9, 0xDB, 0xA4, 0xFA, 0xF8, 0xDA, + 0xA3, 0xCE, 0xF8, 0xDC, 0xAB, 0x5B, 0xF9, 0xE2, 0xB9, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF1, 0xE6, 0xCF, 0x03, 0xF8, 0xDD, + 0xAC, 0x2A, 0xF9, 0xDC, 0xA9, 0x71, 0xFA, 0xDD, 0xAA, 0xC4, 0xFB, 0xE1, 0xB2, 0xE5, 0xFB, 0xE4, + 0xB8, 0xF2, 0xFB, 0xE6, 0xBE, 0xF8, 0xFB, 0xE7, 0xC0, 0xF9, 0xFB, 0xE5, 0xBD, 0xF7, 0xFB, 0xE3, + 0xB6, 0xEF, 0xFB, 0xE1, 0xB0, 0xDD, 0xFA, 0xDE, 0xAB, 0xAD, 0xF9, 0xDE, 0xAC, 0x56, 0xF8, 0xE0, + 0xB4, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFB, 0xE2, 0xB6, 0x12, 0xFB, 0xDF, 0xAD, 0x2D, 0xFB, 0xDF, + 0xAB, 0x46, 0xFB, 0xE0, 0xAE, 0x58, 0xFB, 0xE1, 0xB0, 0x5C, 0xFB, 0xE0, 0xAE, 0x53, 0xFB, 0xDF, + 0xAC, 0x3E, 0xFB, 0xE1, 0xB1, 0x24, 0xFC, 0xE7, 0xC1, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x03, 0xE0, 0x00, + 0x00, 0x01, 0xE0, 0x00, 0x00, 0x01, 0xE0, 0x00, 0x00, 0x01, 0xE0, 0x00, 0x00, 0x01, 0xE0, 0x00, + 0x00, 0x03, 0xF8, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x07, 0xE0, 0x00, + 0x00, 0x03, 0xE0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x01, 0xC0, 0x00, + 0x00, 0x01, 0xC0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, + 0x00, 0x01, 0xC0, 0x00, 0x00, 0x01, 0xC0, 0x00, 0x00, 0x01, 0xC0, 0x00, 0x00, 0x01, 0xC0, 0x00, + 0x00, 0x03, 0xE0, 0x00, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x07, 0xF8, 0x00, + 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x1F, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0x80, + 0x01, 0xFF, 0xFF, 0xF0, 0x07, 0xFF +}; + +void *get_window_icon_raw_data(int *len) +{ + *len = (int)sizeof(window_icon_hexData); + return window_icon_hexData; +} + diff --git a/LinuxGUI/Ventoy2Disk/Include/Ventoy2Disk.h b/LinuxGUI/Ventoy2Disk/Include/Ventoy2Disk.h new file mode 100644 index 0000000..32f452c --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Include/Ventoy2Disk.h @@ -0,0 +1,26 @@ +/****************************************************************************** + * Ventoy2Disk.h + * + * Copyright (c) 2021, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ +#ifndef __VENTOY2DISK_H__ +#define __VENTOY2DISK_H__ + + + +#endif /* __VENTOY2DISK_H__ */ + diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/buidexfat.sh b/LinuxGUI/Ventoy2Disk/Lib/exfat/buidexfat.sh new file mode 100644 index 0000000..00a83c6 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/buidexfat.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +CUR="$PWD" + +rm -rf src +mkdir -p src/libexfat +mkdir -p src/mkfs + +rm -rf exfat-1.3.0 +unzip exfat-1.3.0.zip + +cd exfat-1.3.0 +autoreconf --install +./configure --prefix="$CUR" CFLAGS='-O2 -D_FILE_OFFSET_BITS=64' +make + +cp -a libexfat/*.c ../src/libexfat/ +cp -a libexfat/*.h ../src/libexfat/ +cp -a mkfs/*.c ../src/mkfs/ +cp -a mkfs/*.h ../src/mkfs/ +rm -f ../src/libexfat/log.c + +cd .. +rm -rf exfat-1.3.0 + +mv src/mkfs/main.c src/mkfs/mkexfat_main.c +sed 's//"exfat.h"/g' -i src/mkfs/mkexfat_main.c +sed 's//"exfat.h"/g' -i src/mkfs/mkexfat.h +sed 's/int main/int mkexfat_main/g' -i src/mkfs/mkexfat_main.c + diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/exfat-1.3.0.zip b/LinuxGUI/Ventoy2Disk/Lib/exfat/exfat-1.3.0.zip new file mode 100644 index 0000000..aa1d5f3 Binary files /dev/null and b/LinuxGUI/Ventoy2Disk/Lib/exfat/exfat-1.3.0.zip differ diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/byteorder.h b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/byteorder.h new file mode 100644 index 0000000..ba54410 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/byteorder.h @@ -0,0 +1,68 @@ +/* + byteorder.h (12.01.10) + Endianness stuff. exFAT uses little-endian byte order. + + Free exFAT implementation. + Copyright (C) 2010-2018 Andrew Nayenko + + 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. +*/ + +#ifndef BYTEORDER_H_INCLUDED +#define BYTEORDER_H_INCLUDED + +#include "platform.h" +#include +#include + +typedef struct { uint16_t __u16; } le16_t; +typedef struct { uint32_t __u32; } le32_t; +typedef struct { uint64_t __u64; } le64_t; + +#if EXFAT_BYTE_ORDER == EXFAT_LITTLE_ENDIAN + +static inline uint16_t le16_to_cpu(le16_t v) { return v.__u16; } +static inline uint32_t le32_to_cpu(le32_t v) { return v.__u32; } +static inline uint64_t le64_to_cpu(le64_t v) { return v.__u64; } + +static inline le16_t cpu_to_le16(uint16_t v) { le16_t t = {v}; return t; } +static inline le32_t cpu_to_le32(uint32_t v) { le32_t t = {v}; return t; } +static inline le64_t cpu_to_le64(uint64_t v) { le64_t t = {v}; return t; } + +typedef size_t bitmap_t; + +#elif EXFAT_BYTE_ORDER == EXFAT_BIG_ENDIAN + +static inline uint16_t le16_to_cpu(le16_t v) + { return exfat_bswap16(v.__u16); } +static inline uint32_t le32_to_cpu(le32_t v) + { return exfat_bswap32(v.__u32); } +static inline uint64_t le64_to_cpu(le64_t v) + { return exfat_bswap64(v.__u64); } + +static inline le16_t cpu_to_le16(uint16_t v) + { le16_t t = {exfat_bswap16(v)}; return t; } +static inline le32_t cpu_to_le32(uint32_t v) + { le32_t t = {exfat_bswap32(v)}; return t; } +static inline le64_t cpu_to_le64(uint64_t v) + { le64_t t = {exfat_bswap64(v)}; return t; } + +typedef unsigned char bitmap_t; + +#else +#error Wow! You have a PDP machine?! +#endif + +#endif /* ifndef BYTEORDER_H_INCLUDED */ diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/cluster.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/cluster.c new file mode 100644 index 0000000..15cd9aa --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/cluster.c @@ -0,0 +1,491 @@ +/* + cluster.c (03.09.09) + exFAT file system implementation library. + + Free exFAT implementation. + Copyright (C) 2010-2018 Andrew Nayenko + + 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. +*/ + +#include "exfat.h" +#include +#include +#include + +/* + * Sector to absolute offset. + */ +static off_t s2o(const struct exfat* ef, off_t sector) +{ + return sector << ef->sb->sector_bits; +} + +/* + * Cluster to sector. + */ +static off_t c2s(const struct exfat* ef, cluster_t cluster) +{ + if (cluster < EXFAT_FIRST_DATA_CLUSTER) + exfat_bug("invalid cluster number %u", cluster); + return le32_to_cpu(ef->sb->cluster_sector_start) + + ((off_t) (cluster - EXFAT_FIRST_DATA_CLUSTER) << ef->sb->spc_bits); +} + +/* + * Cluster to absolute offset. + */ +off_t exfat_c2o(const struct exfat* ef, cluster_t cluster) +{ + return s2o(ef, c2s(ef, cluster)); +} + +/* + * Sector to cluster. + */ +static cluster_t s2c(const struct exfat* ef, off_t sector) +{ + return ((sector - le32_to_cpu(ef->sb->cluster_sector_start)) >> + ef->sb->spc_bits) + EXFAT_FIRST_DATA_CLUSTER; +} + +/* + * Size in bytes to size in clusters (rounded upwards). + */ +static uint32_t bytes2clusters(const struct exfat* ef, uint64_t bytes) +{ + uint64_t cluster_size = CLUSTER_SIZE(*ef->sb); + return DIV_ROUND_UP(bytes, cluster_size); +} + +cluster_t exfat_next_cluster(const struct exfat* ef, + const struct exfat_node* node, cluster_t cluster) +{ + le32_t next; + off_t fat_offset; + + if (cluster < EXFAT_FIRST_DATA_CLUSTER) + exfat_bug("bad cluster 0x%x", cluster); + + if (node->is_contiguous) + return cluster + 1; + fat_offset = s2o(ef, le32_to_cpu(ef->sb->fat_sector_start)) + + cluster * sizeof(cluster_t); + if (exfat_pread(ef->dev, &next, sizeof(next), fat_offset) < 0) + return EXFAT_CLUSTER_BAD; /* the caller should handle this and print + appropriate error message */ + return le32_to_cpu(next); +} + +cluster_t exfat_advance_cluster(const struct exfat* ef, + struct exfat_node* node, uint32_t count) +{ + uint32_t i; + + if (node->fptr_index > count) + { + node->fptr_index = 0; + node->fptr_cluster = node->start_cluster; + } + + for (i = node->fptr_index; i < count; i++) + { + node->fptr_cluster = exfat_next_cluster(ef, node, node->fptr_cluster); + if (CLUSTER_INVALID(*ef->sb, node->fptr_cluster)) + break; /* the caller should handle this and print appropriate + error message */ + } + node->fptr_index = count; + return node->fptr_cluster; +} + +static cluster_t find_bit_and_set(bitmap_t* bitmap, size_t start, size_t end) +{ + const size_t start_index = start / sizeof(bitmap_t) / 8; + const size_t end_index = DIV_ROUND_UP(end, sizeof(bitmap_t) * 8); + size_t i; + size_t start_bitindex; + size_t end_bitindex; + size_t c; + + for (i = start_index; i < end_index; i++) + { + if (bitmap[i] == ~((bitmap_t) 0)) + continue; + start_bitindex = MAX(i * sizeof(bitmap_t) * 8, start); + end_bitindex = MIN((i + 1) * sizeof(bitmap_t) * 8, end); + for (c = start_bitindex; c < end_bitindex; c++) + if (BMAP_GET(bitmap, c) == 0) + { + BMAP_SET(bitmap, c); + return c + EXFAT_FIRST_DATA_CLUSTER; + } + } + return EXFAT_CLUSTER_END; +} + +static int flush_nodes(struct exfat* ef, struct exfat_node* node) +{ + struct exfat_node* p; + + for (p = node->child; p != NULL; p = p->next) + { + int rc = flush_nodes(ef, p); + if (rc != 0) + return rc; + } + return exfat_flush_node(ef, node); +} + +int exfat_flush_nodes(struct exfat* ef) +{ + return flush_nodes(ef, ef->root); +} + +int exfat_flush(struct exfat* ef) +{ + if (ef->cmap.dirty) + { + if (exfat_pwrite(ef->dev, ef->cmap.chunk, + BMAP_SIZE(ef->cmap.chunk_size), + exfat_c2o(ef, ef->cmap.start_cluster)) < 0) + { + exfat_error("failed to write clusters bitmap"); + return -EIO; + } + ef->cmap.dirty = false; + } + + return 0; +} + +static bool set_next_cluster(const struct exfat* ef, bool contiguous, + cluster_t current, cluster_t next) +{ + off_t fat_offset; + le32_t next_le32; + + if (contiguous) + return true; + fat_offset = s2o(ef, le32_to_cpu(ef->sb->fat_sector_start)) + + current * sizeof(cluster_t); + next_le32 = cpu_to_le32(next); + if (exfat_pwrite(ef->dev, &next_le32, sizeof(next_le32), fat_offset) < 0) + { + exfat_error("failed to write the next cluster %#x after %#x", next, + current); + return false; + } + return true; +} + +static cluster_t allocate_cluster(struct exfat* ef, cluster_t hint) +{ + cluster_t cluster; + + hint -= EXFAT_FIRST_DATA_CLUSTER; + if (hint >= ef->cmap.chunk_size) + hint = 0; + + cluster = find_bit_and_set(ef->cmap.chunk, hint, ef->cmap.chunk_size); + if (cluster == EXFAT_CLUSTER_END) + cluster = find_bit_and_set(ef->cmap.chunk, 0, hint); + if (cluster == EXFAT_CLUSTER_END) + { + exfat_error("no free space left"); + return EXFAT_CLUSTER_END; + } + + ef->cmap.dirty = true; + return cluster; +} + +static void free_cluster(struct exfat* ef, cluster_t cluster) +{ + if (cluster - EXFAT_FIRST_DATA_CLUSTER >= ef->cmap.size) + exfat_bug("caller must check cluster validity (%#x, %#x)", cluster, + ef->cmap.size); + + BMAP_CLR(ef->cmap.chunk, cluster - EXFAT_FIRST_DATA_CLUSTER); + ef->cmap.dirty = true; +} + +static bool make_noncontiguous(const struct exfat* ef, cluster_t first, + cluster_t last) +{ + cluster_t c; + + for (c = first; c < last; c++) + if (!set_next_cluster(ef, false, c, c + 1)) + return false; + return true; +} + +static int shrink_file(struct exfat* ef, struct exfat_node* node, + uint32_t current, uint32_t difference); + +static int grow_file(struct exfat* ef, struct exfat_node* node, + uint32_t current, uint32_t difference) +{ + cluster_t previous; + cluster_t next; + uint32_t allocated = 0; + + if (difference == 0) + exfat_bug("zero clusters count passed"); + + if (node->start_cluster != EXFAT_CLUSTER_FREE) + { + /* get the last cluster of the file */ + previous = exfat_advance_cluster(ef, node, current - 1); + if (CLUSTER_INVALID(*ef->sb, previous)) + { + exfat_error("invalid cluster 0x%x while growing", previous); + return -EIO; + } + } + else + { + if (node->fptr_index != 0) + exfat_bug("non-zero pointer index (%u)", node->fptr_index); + /* file does not have clusters (i.e. is empty), allocate + the first one for it */ + previous = allocate_cluster(ef, 0); + if (CLUSTER_INVALID(*ef->sb, previous)) + return -ENOSPC; + node->fptr_cluster = node->start_cluster = previous; + allocated = 1; + /* file consists of only one cluster, so it's contiguous */ + node->is_contiguous = true; + } + + while (allocated < difference) + { + next = allocate_cluster(ef, previous + 1); + if (CLUSTER_INVALID(*ef->sb, next)) + { + if (allocated != 0) + shrink_file(ef, node, current + allocated, allocated); + return -ENOSPC; + } + if (next != previous - 1 && node->is_contiguous) + { + /* it's a pity, but we are not able to keep the file contiguous + anymore */ + if (!make_noncontiguous(ef, node->start_cluster, previous)) + return -EIO; + node->is_contiguous = false; + node->is_dirty = true; + } + if (!set_next_cluster(ef, node->is_contiguous, previous, next)) + return -EIO; + previous = next; + allocated++; + } + + if (!set_next_cluster(ef, node->is_contiguous, previous, + EXFAT_CLUSTER_END)) + return -EIO; + return 0; +} + +static int shrink_file(struct exfat* ef, struct exfat_node* node, + uint32_t current, uint32_t difference) +{ + cluster_t previous; + cluster_t next; + + if (difference == 0) + exfat_bug("zero difference passed"); + if (node->start_cluster == EXFAT_CLUSTER_FREE) + exfat_bug("unable to shrink empty file (%u clusters)", current); + if (current < difference) + exfat_bug("file underflow (%u < %u)", current, difference); + + /* crop the file */ + if (current > difference) + { + cluster_t last = exfat_advance_cluster(ef, node, + current - difference - 1); + if (CLUSTER_INVALID(*ef->sb, last)) + { + exfat_error("invalid cluster 0x%x while shrinking", last); + return -EIO; + } + previous = exfat_next_cluster(ef, node, last); + if (!set_next_cluster(ef, node->is_contiguous, last, + EXFAT_CLUSTER_END)) + return -EIO; + } + else + { + previous = node->start_cluster; + node->start_cluster = EXFAT_CLUSTER_FREE; + node->is_dirty = true; + } + node->fptr_index = 0; + node->fptr_cluster = node->start_cluster; + + /* free remaining clusters */ + while (difference--) + { + if (CLUSTER_INVALID(*ef->sb, previous)) + { + exfat_error("invalid cluster 0x%x while freeing after shrink", + previous); + return -EIO; + } + + next = exfat_next_cluster(ef, node, previous); + if (!set_next_cluster(ef, node->is_contiguous, previous, + EXFAT_CLUSTER_FREE)) + return -EIO; + free_cluster(ef, previous); + previous = next; + } + return 0; +} + +static bool erase_raw(struct exfat* ef, size_t size, off_t offset) +{ + if (exfat_pwrite(ef->dev, ef->zero_cluster, size, offset) < 0) + { + exfat_error("failed to erase %zu bytes at %"PRId64, size, offset); + return false; + } + return true; +} + +static int erase_range(struct exfat* ef, struct exfat_node* node, + uint64_t begin, uint64_t end) +{ + uint64_t cluster_boundary; + cluster_t cluster; + + if (begin >= end) + return 0; + + cluster_boundary = (begin | (CLUSTER_SIZE(*ef->sb) - 1)) + 1; + cluster = exfat_advance_cluster(ef, node, + begin / CLUSTER_SIZE(*ef->sb)); + if (CLUSTER_INVALID(*ef->sb, cluster)) + { + exfat_error("invalid cluster 0x%x while erasing", cluster); + return -EIO; + } + /* erase from the beginning to the closest cluster boundary */ + if (!erase_raw(ef, MIN(cluster_boundary, end) - begin, + exfat_c2o(ef, cluster) + begin % CLUSTER_SIZE(*ef->sb))) + return -EIO; + /* erase whole clusters */ + while (cluster_boundary < end) + { + cluster = exfat_next_cluster(ef, node, cluster); + /* the cluster cannot be invalid because we have just allocated it */ + if (CLUSTER_INVALID(*ef->sb, cluster)) + exfat_bug("invalid cluster 0x%x after allocation", cluster); + if (!erase_raw(ef, CLUSTER_SIZE(*ef->sb), exfat_c2o(ef, cluster))) + return -EIO; + cluster_boundary += CLUSTER_SIZE(*ef->sb); + } + return 0; +} + +int exfat_truncate(struct exfat* ef, struct exfat_node* node, uint64_t size, + bool erase) +{ + uint32_t c1 = bytes2clusters(ef, node->size); + uint32_t c2 = bytes2clusters(ef, size); + int rc = 0; + + if (node->references == 0 && node->parent) + exfat_bug("no references, node changes can be lost"); + + if (node->size == size) + return 0; + + if (c1 < c2) + rc = grow_file(ef, node, c1, c2 - c1); + else if (c1 > c2) + rc = shrink_file(ef, node, c1, c1 - c2); + + if (rc != 0) + return rc; + + if (erase) + { + rc = erase_range(ef, node, node->size, size); + if (rc != 0) + return rc; + } + + exfat_update_mtime(node); + node->size = size; + node->is_dirty = true; + return 0; +} + +uint32_t exfat_count_free_clusters(const struct exfat* ef) +{ + uint32_t free_clusters = 0; + uint32_t i; + + for (i = 0; i < ef->cmap.size; i++) + if (BMAP_GET(ef->cmap.chunk, i) == 0) + free_clusters++; + return free_clusters; +} + +static int find_used_clusters(const struct exfat* ef, + cluster_t* a, cluster_t* b) +{ + const cluster_t end = le32_to_cpu(ef->sb->cluster_count); + + /* find first used cluster */ + for (*a = *b + 1; *a < end; (*a)++) + if (BMAP_GET(ef->cmap.chunk, *a - EXFAT_FIRST_DATA_CLUSTER)) + break; + if (*a >= end) + return 1; + + /* find last contiguous used cluster */ + for (*b = *a; *b < end; (*b)++) + if (BMAP_GET(ef->cmap.chunk, *b - EXFAT_FIRST_DATA_CLUSTER) == 0) + { + (*b)--; + break; + } + + return 0; +} + +int exfat_find_used_sectors(const struct exfat* ef, off_t* a, off_t* b) +{ + cluster_t ca, cb; + + if (*a == 0 && *b == 0) + ca = cb = EXFAT_FIRST_DATA_CLUSTER - 1; + else + { + ca = s2c(ef, *a); + cb = s2c(ef, *b); + } + if (find_used_clusters(ef, &ca, &cb) != 0) + return 1; + if (*a != 0 || *b != 0) + *a = c2s(ef, ca); + *b = c2s(ef, cb) + (CLUSTER_SIZE(*ef->sb) - 1) / SECTOR_SIZE(*ef->sb); + return 0; +} diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/compiler.h b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/compiler.h new file mode 100644 index 0000000..7eb686c --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/compiler.h @@ -0,0 +1,66 @@ +/* + compiler.h (09.06.13) + Compiler-specific definitions. Note that unknown compiler is not a + showstopper. + + Free exFAT implementation. + Copyright (C) 2010-2018 Andrew Nayenko + + 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. +*/ + +#ifndef COMPILER_H_INCLUDED +#define COMPILER_H_INCLUDED + +#if __STDC_VERSION__ < 199901L +#error C99-compliant compiler is required +#endif + +#if defined(__clang__) + +#define PRINTF __attribute__((format(printf, 1, 2))) +#define NORETURN __attribute__((noreturn)) +#define PACKED __attribute__((packed)) +#if __has_extension(c_static_assert) +#define USE_C11_STATIC_ASSERT +#endif + +#elif defined(__GNUC__) + +#define PRINTF __attribute__((format(printf, 1, 2))) +#define NORETURN __attribute__((noreturn)) +#define PACKED __attribute__((packed)) +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) +#define USE_C11_STATIC_ASSERT +#endif + +#else + +#define PRINTF +#define NORETURN +#define PACKED + +#endif + +#ifdef USE_C11_STATIC_ASSERT +#define STATIC_ASSERT(cond) _Static_assert(cond, #cond) +#else +#define CONCAT2(a, b) a ## b +#define CONCAT1(a, b) CONCAT2(a, b) +#define STATIC_ASSERT(cond) \ + extern void CONCAT1(static_assert, __LINE__)(int x[(cond) ? 1 : -1]) +#endif + +#endif /* ifndef COMPILER_H_INCLUDED */ diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/config.h b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/config.h new file mode 100644 index 0000000..73059a7 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/config.h @@ -0,0 +1,40 @@ +/* libexfat/config.h. Generated from config.h.in by configure. */ +/* libexfat/config.h.in. Generated from configure.ac by autoheader. */ + +/* Name of package */ +#define PACKAGE "exfat" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "relan@users.noreply.github.com" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "Free exFAT implementation" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "Free exFAT implementation 1.3.0" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "exfat" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "https://github.com/relan/exfat" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "1.3.0" + +/* Define if block devices are not supported. */ +/* #undef USE_UBLIO */ + +/* Version number of package */ +#define VERSION "1.3.0" + +/* Enable large inode numbers on Mac OS X 10.5. */ +#ifndef _DARWIN_USE_64_BIT_INODE +# define _DARWIN_USE_64_BIT_INODE 1 +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +/* #undef _FILE_OFFSET_BITS */ + +/* Define for large files, on AIX-style hosts. */ +/* #undef _LARGE_FILES */ diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/exfat.h b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/exfat.h new file mode 100644 index 0000000..b3ff78d --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/exfat.h @@ -0,0 +1,255 @@ +/* + exfat.h (29.08.09) + Definitions of structures and constants used in exFAT file system + implementation. + + Free exFAT implementation. + Copyright (C) 2010-2018 Andrew Nayenko + + 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. +*/ + +#ifndef EXFAT_H_INCLUDED +#define EXFAT_H_INCLUDED + +#ifndef ANDROID +/* Android.bp is used instead of autotools when targeting Android */ +#include "config.h" +#endif +#include "compiler.h" +#include "exfatfs.h" +#include +#include +#include +#include +#include +#include + +#define EXFAT_NAME_MAX 255 +/* UTF-16 encodes code points up to U+FFFF as single 16-bit code units. + UTF-8 uses up to 3 bytes (i.e. 8-bit code units) to encode code points + up to U+FFFF. One additional character is for null terminator. */ +#define EXFAT_UTF8_NAME_BUFFER_MAX (EXFAT_NAME_MAX * 3 + 1) +#define EXFAT_UTF8_ENAME_BUFFER_MAX (EXFAT_ENAME_MAX * 3 + 1) + +#define SECTOR_SIZE(sb) (1 << (sb).sector_bits) +#define CLUSTER_SIZE(sb) (SECTOR_SIZE(sb) << (sb).spc_bits) +#define CLUSTER_INVALID(sb, c) ((c) < EXFAT_FIRST_DATA_CLUSTER || \ + (c) - EXFAT_FIRST_DATA_CLUSTER >= le32_to_cpu((sb).cluster_count)) + +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define DIV_ROUND_UP(x, d) (((x) + (d) - 1) / (d)) +#define ROUND_UP(x, d) (DIV_ROUND_UP(x, d) * (d)) + +#define BMAP_SIZE(count) (ROUND_UP(count, sizeof(bitmap_t) * 8) / 8) +#define BMAP_BLOCK(index) ((index) / sizeof(bitmap_t) / 8) +#define BMAP_MASK(index) ((bitmap_t) 1 << ((index) % (sizeof(bitmap_t) * 8))) +#define BMAP_GET(bitmap, index) \ + ((bitmap)[BMAP_BLOCK(index)] & BMAP_MASK(index)) +#define BMAP_SET(bitmap, index) \ + ((bitmap)[BMAP_BLOCK(index)] |= BMAP_MASK(index)) +#define BMAP_CLR(bitmap, index) \ + ((bitmap)[BMAP_BLOCK(index)] &= ~BMAP_MASK(index)) + +#define EXFAT_REPAIR(hook, ef, ...) \ + (exfat_ask_to_fix(ef) && exfat_fix_ ## hook(ef, __VA_ARGS__)) + +/* The size of off_t type must be 64 bits. File systems larger than 2 GB will + be corrupted with 32-bit off_t. */ +STATIC_ASSERT(sizeof(off_t) == 8); + +struct exfat_node +{ + struct exfat_node* parent; + struct exfat_node* child; + struct exfat_node* next; + struct exfat_node* prev; + + int references; + uint32_t fptr_index; + cluster_t fptr_cluster; + off_t entry_offset; + cluster_t start_cluster; + uint16_t attrib; + uint8_t continuations; + bool is_contiguous : 1; + bool is_cached : 1; + bool is_dirty : 1; + bool is_unlinked : 1; + uint64_t size; + time_t mtime, atime; + le16_t name[EXFAT_NAME_MAX + 1]; +}; + +enum exfat_mode +{ + EXFAT_MODE_RO, + EXFAT_MODE_RW, + EXFAT_MODE_ANY, +}; + +struct exfat_dev; + +struct exfat +{ + struct exfat_dev* dev; + struct exfat_super_block* sb; + uint16_t* upcase; + struct exfat_node* root; + struct + { + cluster_t start_cluster; + uint32_t size; /* in bits */ + bitmap_t* chunk; + uint32_t chunk_size; /* in bits */ + bool dirty; + } + cmap; + char label[EXFAT_UTF8_ENAME_BUFFER_MAX]; + void* zero_cluster; + int dmask, fmask; + uid_t uid; + gid_t gid; + int ro; + bool noatime; + enum { EXFAT_REPAIR_NO, EXFAT_REPAIR_ASK, EXFAT_REPAIR_YES } repair; +}; + +/* in-core nodes iterator */ +struct exfat_iterator +{ + struct exfat_node* parent; + struct exfat_node* current; +}; + +struct exfat_human_bytes +{ + uint64_t value; + const char* unit; +}; + +extern int exfat_errors; +extern int exfat_errors_fixed; + +#define VLOG_LOG 1 +#define VLOG_DEBUG 2 +void ventoy_syslog_newline(int level, const char *Fmt, ...); +#define exfat_bug(fmt, args...) ventoy_syslog_newline(VLOG_LOG, fmt, ##args) +#define exfat_error(fmt, args...) ventoy_syslog_newline(VLOG_LOG, fmt, ##args) +#define exfat_error(fmt, args...) ventoy_syslog_newline(VLOG_LOG, fmt, ##args) +#define exfat_warn(fmt, args...) ventoy_syslog_newline(VLOG_LOG, fmt, ##args) +#define exfat_debug(fmt, args...) ventoy_syslog_newline(VLOG_DEBUG, fmt, ##args) + +#if 0 +void exfat_bug(const char* format, ...) PRINTF NORETURN; +void exfat_error(const char* format, ...) PRINTF; +void exfat_warn(const char* format, ...) PRINTF; +void exfat_debug(const char* format, ...) PRINTF; +#endif /* #if 0 */ + +struct exfat_dev* exfat_open(const char* spec, enum exfat_mode mode); +int exfat_close(struct exfat_dev* dev); +int exfat_fsync(struct exfat_dev* dev); +enum exfat_mode exfat_get_mode(const struct exfat_dev* dev); +off_t exfat_get_size(const struct exfat_dev* dev); +off_t exfat_seek(struct exfat_dev* dev, off_t offset, int whence); +ssize_t exfat_read(struct exfat_dev* dev, void* buffer, size_t size); +ssize_t exfat_write(struct exfat_dev* dev, const void* buffer, size_t size); +ssize_t exfat_pread(struct exfat_dev* dev, void* buffer, size_t size, + off_t offset); +ssize_t exfat_pwrite(struct exfat_dev* dev, const void* buffer, size_t size, + off_t offset); +ssize_t exfat_generic_pread(const struct exfat* ef, struct exfat_node* node, + void* buffer, size_t size, off_t offset); +ssize_t exfat_generic_pwrite(struct exfat* ef, struct exfat_node* node, + const void* buffer, size_t size, off_t offset); + +int exfat_opendir(struct exfat* ef, struct exfat_node* dir, + struct exfat_iterator* it); +void exfat_closedir(struct exfat* ef, struct exfat_iterator* it); +struct exfat_node* exfat_readdir(struct exfat_iterator* it); +int exfat_lookup(struct exfat* ef, struct exfat_node** node, + const char* path); +int exfat_split(struct exfat* ef, struct exfat_node** parent, + struct exfat_node** node, le16_t* name, const char* path); + +off_t exfat_c2o(const struct exfat* ef, cluster_t cluster); +cluster_t exfat_next_cluster(const struct exfat* ef, + const struct exfat_node* node, cluster_t cluster); +cluster_t exfat_advance_cluster(const struct exfat* ef, + struct exfat_node* node, uint32_t count); +int exfat_flush_nodes(struct exfat* ef); +int exfat_flush(struct exfat* ef); +int exfat_truncate(struct exfat* ef, struct exfat_node* node, uint64_t size, + bool erase); +uint32_t exfat_count_free_clusters(const struct exfat* ef); +int exfat_find_used_sectors(const struct exfat* ef, off_t* a, off_t* b); + +void exfat_stat(const struct exfat* ef, const struct exfat_node* node, + struct stat* stbuf); +void exfat_get_name(const struct exfat_node* node, + char buffer[EXFAT_UTF8_NAME_BUFFER_MAX]); +uint16_t exfat_start_checksum(const struct exfat_entry_meta1* entry); +uint16_t exfat_add_checksum(const void* entry, uint16_t sum); +le16_t exfat_calc_checksum(const struct exfat_entry* entries, int n); +uint32_t exfat_vbr_start_checksum(const void* sector, size_t size); +uint32_t exfat_vbr_add_checksum(const void* sector, size_t size, uint32_t sum); +le16_t exfat_calc_name_hash(const struct exfat* ef, const le16_t* name, + size_t length); +void exfat_humanize_bytes(uint64_t value, struct exfat_human_bytes* hb); +void exfat_print_info(const struct exfat_super_block* sb, + uint32_t free_clusters); + +int utf16_to_utf8(char* output, const le16_t* input, size_t outsize, + size_t insize); +int utf8_to_utf16(le16_t* output, const char* input, size_t outsize, + size_t insize); +size_t utf16_length(const le16_t* str); + +struct exfat_node* exfat_get_node(struct exfat_node* node); +void exfat_put_node(struct exfat* ef, struct exfat_node* node); +int exfat_cleanup_node(struct exfat* ef, struct exfat_node* node); +int exfat_cache_directory(struct exfat* ef, struct exfat_node* dir); +void exfat_reset_cache(struct exfat* ef); +int exfat_flush_node(struct exfat* ef, struct exfat_node* node); +int exfat_unlink(struct exfat* ef, struct exfat_node* node); +int exfat_rmdir(struct exfat* ef, struct exfat_node* node); +int exfat_mknod(struct exfat* ef, const char* path); +int exfat_mkdir(struct exfat* ef, const char* path); +int exfat_rename(struct exfat* ef, const char* old_path, const char* new_path); +void exfat_utimes(struct exfat_node* node, const struct timespec tv[2]); +void exfat_update_atime(struct exfat_node* node); +void exfat_update_mtime(struct exfat_node* node); +const char* exfat_get_label(struct exfat* ef); +int exfat_set_label(struct exfat* ef, const char* label); + +int exfat_mount(struct exfat* ef, const char* spec, const char* options); +void exfat_unmount(struct exfat* ef); + +time_t exfat_exfat2unix(le16_t date, le16_t time, uint8_t centisec); +void exfat_unix2exfat(time_t unix_time, le16_t* date, le16_t* time, + uint8_t* centisec); +void exfat_tzset(void); + +bool exfat_ask_to_fix(const struct exfat* ef); +bool exfat_fix_invalid_vbr_checksum(const struct exfat* ef, void* sector, + uint32_t vbr_checksum); +bool exfat_fix_invalid_node_checksum(const struct exfat* ef, + struct exfat_node* node); +bool exfat_fix_unknown_entry(struct exfat* ef, struct exfat_node* dir, + const struct exfat_entry* entry, off_t offset); + +#endif /* ifndef EXFAT_H_INCLUDED */ diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/exfatfs.h b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/exfatfs.h new file mode 100644 index 0000000..b7b6cac --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/exfatfs.h @@ -0,0 +1,180 @@ +/* + exfatfs.h (29.08.09) + Definitions of structures and constants used in exFAT file system. + + Free exFAT implementation. + Copyright (C) 2010-2018 Andrew Nayenko + + 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. +*/ + +#ifndef EXFATFS_H_INCLUDED +#define EXFATFS_H_INCLUDED + +#include "byteorder.h" +#include "compiler.h" + +typedef uint32_t cluster_t; /* cluster number */ + +#define EXFAT_FIRST_DATA_CLUSTER 2 +#define EXFAT_LAST_DATA_CLUSTER 0xfffffff6 + +#define EXFAT_CLUSTER_FREE 0 /* free cluster */ +#define EXFAT_CLUSTER_BAD 0xfffffff7 /* cluster contains bad sector */ +#define EXFAT_CLUSTER_END 0xffffffff /* final cluster of file or directory */ + +#define EXFAT_STATE_MOUNTED 2 + +struct exfat_super_block +{ + uint8_t jump[3]; /* 0x00 jmp and nop instructions */ + uint8_t oem_name[8]; /* 0x03 "EXFAT " */ + uint8_t __unused1[53]; /* 0x0B always 0 */ + le64_t sector_start; /* 0x40 partition first sector */ + le64_t sector_count; /* 0x48 partition sectors count */ + le32_t fat_sector_start; /* 0x50 FAT first sector */ + le32_t fat_sector_count; /* 0x54 FAT sectors count */ + le32_t cluster_sector_start; /* 0x58 first cluster sector */ + le32_t cluster_count; /* 0x5C total clusters count */ + le32_t rootdir_cluster; /* 0x60 first cluster of the root dir */ + le32_t volume_serial; /* 0x64 volume serial number */ + struct /* 0x68 FS version */ + { + uint8_t minor; + uint8_t major; + } + version; + le16_t volume_state; /* 0x6A volume state flags */ + uint8_t sector_bits; /* 0x6C sector size as (1 << n) */ + uint8_t spc_bits; /* 0x6D sectors per cluster as (1 << n) */ + uint8_t fat_count; /* 0x6E always 1 */ + uint8_t drive_no; /* 0x6F always 0x80 */ + uint8_t allocated_percent; /* 0x70 percentage of allocated space */ + uint8_t __unused2[397]; /* 0x71 always 0 */ + le16_t boot_signature; /* the value of 0xAA55 */ +} +PACKED; +STATIC_ASSERT(sizeof(struct exfat_super_block) == 512); + +#define EXFAT_ENTRY_VALID 0x80 +#define EXFAT_ENTRY_CONTINUED 0x40 +#define EXFAT_ENTRY_OPTIONAL 0x20 + +#define EXFAT_ENTRY_BITMAP (0x01 | EXFAT_ENTRY_VALID) +#define EXFAT_ENTRY_UPCASE (0x02 | EXFAT_ENTRY_VALID) +#define EXFAT_ENTRY_LABEL (0x03 | EXFAT_ENTRY_VALID) +#define EXFAT_ENTRY_FILE (0x05 | EXFAT_ENTRY_VALID) +#define EXFAT_ENTRY_FILE_INFO (0x00 | EXFAT_ENTRY_VALID | EXFAT_ENTRY_CONTINUED) +#define EXFAT_ENTRY_FILE_NAME (0x01 | EXFAT_ENTRY_VALID | EXFAT_ENTRY_CONTINUED) +#define EXFAT_ENTRY_FILE_TAIL (0x00 | EXFAT_ENTRY_VALID \ + | EXFAT_ENTRY_CONTINUED \ + | EXFAT_ENTRY_OPTIONAL) + +struct exfat_entry /* common container for all entries */ +{ + uint8_t type; /* any of EXFAT_ENTRY_xxx */ + uint8_t data[31]; +} +PACKED; +STATIC_ASSERT(sizeof(struct exfat_entry) == 32); + +#define EXFAT_ENAME_MAX 15 + +struct exfat_entry_bitmap /* allocated clusters bitmap */ +{ + uint8_t type; /* EXFAT_ENTRY_BITMAP */ + uint8_t __unknown1[19]; + le32_t start_cluster; + le64_t size; /* in bytes */ +} +PACKED; +STATIC_ASSERT(sizeof(struct exfat_entry_bitmap) == 32); + +#define EXFAT_UPCASE_CHARS 0x10000 + +struct exfat_entry_upcase /* upper case translation table */ +{ + uint8_t type; /* EXFAT_ENTRY_UPCASE */ + uint8_t __unknown1[3]; + le32_t checksum; + uint8_t __unknown2[12]; + le32_t start_cluster; + le64_t size; /* in bytes */ +} +PACKED; +STATIC_ASSERT(sizeof(struct exfat_entry_upcase) == 32); + +struct exfat_entry_label /* volume label */ +{ + uint8_t type; /* EXFAT_ENTRY_LABEL */ + uint8_t length; /* number of characters */ + le16_t name[EXFAT_ENAME_MAX]; /* in UTF-16LE */ +} +PACKED; +STATIC_ASSERT(sizeof(struct exfat_entry_label) == 32); + +#define EXFAT_ATTRIB_RO 0x01 +#define EXFAT_ATTRIB_HIDDEN 0x02 +#define EXFAT_ATTRIB_SYSTEM 0x04 +#define EXFAT_ATTRIB_VOLUME 0x08 +#define EXFAT_ATTRIB_DIR 0x10 +#define EXFAT_ATTRIB_ARCH 0x20 + +struct exfat_entry_meta1 /* file or directory info (part 1) */ +{ + uint8_t type; /* EXFAT_ENTRY_FILE */ + uint8_t continuations; + le16_t checksum; + le16_t attrib; /* combination of EXFAT_ATTRIB_xxx */ + le16_t __unknown1; + le16_t crtime, crdate; /* creation date and time */ + le16_t mtime, mdate; /* latest modification date and time */ + le16_t atime, adate; /* latest access date and time */ + uint8_t crtime_cs; /* creation time in cs (centiseconds) */ + uint8_t mtime_cs; /* latest modification time in cs */ + uint8_t __unknown2[10]; +} +PACKED; +STATIC_ASSERT(sizeof(struct exfat_entry_meta1) == 32); + +#define EXFAT_FLAG_ALWAYS1 (1u << 0) +#define EXFAT_FLAG_CONTIGUOUS (1u << 1) + +struct exfat_entry_meta2 /* file or directory info (part 2) */ +{ + uint8_t type; /* EXFAT_ENTRY_FILE_INFO */ + uint8_t flags; /* combination of EXFAT_FLAG_xxx */ + uint8_t __unknown1; + uint8_t name_length; + le16_t name_hash; + le16_t __unknown2; + le64_t valid_size; /* in bytes, less or equal to size */ + uint8_t __unknown3[4]; + le32_t start_cluster; + le64_t size; /* in bytes */ +} +PACKED; +STATIC_ASSERT(sizeof(struct exfat_entry_meta2) == 32); + +struct exfat_entry_name /* file or directory name */ +{ + uint8_t type; /* EXFAT_ENTRY_FILE_NAME */ + uint8_t __unknown; + le16_t name[EXFAT_ENAME_MAX]; /* in UTF-16LE */ +} +PACKED; +STATIC_ASSERT(sizeof(struct exfat_entry_name) == 32); + +#endif /* ifndef EXFATFS_H_INCLUDED */ diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/io.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/io.c new file mode 100644 index 0000000..4dee536 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/io.c @@ -0,0 +1,511 @@ +/* + io.c (02.09.09) + exFAT file system implementation library. + + Free exFAT implementation. + Copyright (C) 2010-2018 Andrew Nayenko + + 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. +*/ + +#include "exfat.h" +#include +#include +#include +#include +#include +#include +#include +#if defined(__APPLE__) +#include +#elif defined(__OpenBSD__) +#include +#include +#include +#include +#elif __linux__ +#include +#endif +#ifdef USE_UBLIO +#include +#include +#endif + +struct exfat_dev +{ + int fd; + enum exfat_mode mode; + off_t size; /* in bytes */ +#ifdef USE_UBLIO + off_t pos; + ublio_filehandle_t ufh; +#endif +}; + +int g_vtoy_exfat_disk_fd = -1; +uint64_t g_vtoy_exfat_part_size = 0; + +static bool is_open(int fd) +{ + return fcntl(fd, F_GETFD) != -1; +} + +static int open_ro(const char* spec) +{ + return open(spec, O_RDONLY); +} + +static int open_rw(const char* spec) +{ + int fd = open(spec, O_RDWR); +#ifdef __linux__ + int ro = 0; + + /* + This ioctl is needed because after "blockdev --setro" kernel still + allows to open the device in read-write mode but fails writes. + */ + if (fd != -1 && ioctl(fd, BLKROGET, &ro) == 0 && ro) + { + close(fd); + errno = EROFS; + return -1; + } +#endif + return fd; +} + +struct exfat_dev* exfat_open(const char* spec, enum exfat_mode mode) +{ + struct exfat_dev* dev; + struct stat stbuf; +#ifdef USE_UBLIO + struct ublio_param up; +#endif + + /* The system allocates file descriptors sequentially. If we have been + started with stdin (0), stdout (1) or stderr (2) closed, the system + will give us descriptor 0, 1 or 2 later when we open block device, + FUSE communication pipe, etc. As a result, functions using stdin, + stdout or stderr will actually work with a different thing and can + corrupt it. Protect descriptors 0, 1 and 2 from such misuse. */ + while (!is_open(STDIN_FILENO) + || !is_open(STDOUT_FILENO) + || !is_open(STDERR_FILENO)) + { + /* we don't need those descriptors, let them leak */ + if (open("/dev/null", O_RDWR) == -1) + { + exfat_error("failed to open /dev/null"); + return NULL; + } + } + + dev = malloc(sizeof(struct exfat_dev)); + if (dev == NULL) + { + exfat_error("failed to allocate memory for device structure"); + return NULL; + } + + switch (mode) + { + case EXFAT_MODE_RO: + dev->fd = g_vtoy_exfat_disk_fd < 0 ? open_ro(spec) : g_vtoy_exfat_disk_fd; + if (dev->fd == -1) + { + free(dev); + exfat_error("failed to open '%s' in read-only mode: %s", spec, + strerror(errno)); + return NULL; + } + dev->mode = EXFAT_MODE_RO; + break; + case EXFAT_MODE_RW: + dev->fd = g_vtoy_exfat_disk_fd < 0 ? open_rw(spec) : g_vtoy_exfat_disk_fd; + if (dev->fd == -1) + { + free(dev); + exfat_error("failed to open '%s' in read-write mode: %s", spec, + strerror(errno)); + return NULL; + } + dev->mode = EXFAT_MODE_RW; + break; + case EXFAT_MODE_ANY: + dev->fd = g_vtoy_exfat_disk_fd < 0 ? open_rw(spec) : g_vtoy_exfat_disk_fd; + if (dev->fd != -1) + { + dev->mode = EXFAT_MODE_RW; + break; + } + dev->fd = g_vtoy_exfat_disk_fd < 0 ? open_ro(spec) : g_vtoy_exfat_disk_fd; + if (dev->fd != -1) + { + dev->mode = EXFAT_MODE_RO; + exfat_warn("'%s' is write-protected, mounting read-only", spec); + break; + } + free(dev); + exfat_error("failed to open '%s': %s", spec, strerror(errno)); + return NULL; + } + + if (fstat(dev->fd, &stbuf) != 0) + { + close(dev->fd); + free(dev); + exfat_error("failed to fstat '%s'", spec); + return NULL; + } + if (!S_ISBLK(stbuf.st_mode) && + !S_ISCHR(stbuf.st_mode) && + !S_ISREG(stbuf.st_mode)) + { + close(dev->fd); + free(dev); + exfat_error("'%s' is neither a device, nor a regular file", spec); + return NULL; + } + +#if defined(__APPLE__) + if (!S_ISREG(stbuf.st_mode)) + { + uint32_t block_size = 0; + uint64_t blocks = 0; + + if (ioctl(dev->fd, DKIOCGETBLOCKSIZE, &block_size) != 0) + { + close(dev->fd); + free(dev); + exfat_error("failed to get block size"); + return NULL; + } + if (ioctl(dev->fd, DKIOCGETBLOCKCOUNT, &blocks) != 0) + { + close(dev->fd); + free(dev); + exfat_error("failed to get blocks count"); + return NULL; + } + dev->size = blocks * block_size; + } + else +#elif defined(__OpenBSD__) + if (!S_ISREG(stbuf.st_mode)) + { + struct disklabel lab; + struct partition* pp; + char* partition; + + if (ioctl(dev->fd, DIOCGDINFO, &lab) == -1) + { + close(dev->fd); + free(dev); + exfat_error("failed to get disklabel"); + return NULL; + } + + /* Don't need to check that partition letter is valid as we won't get + this far otherwise. */ + partition = strchr(spec, '\0') - 1; + pp = &(lab.d_partitions[*partition - 'a']); + dev->size = DL_GETPSIZE(pp) * lab.d_secsize; + + if (pp->p_fstype != FS_NTFS) + exfat_warn("partition type is not 0x07 (NTFS/exFAT); " + "you can fix this with fdisk(8)"); + } + else +#endif + { + /* works for Linux, FreeBSD, Solaris */ + dev->size = exfat_seek(dev, 0, SEEK_END); + if (dev->size <= 0) + { + close(dev->fd); + free(dev); + exfat_error("failed to get size of '%s'", spec); + return NULL; + } + if (exfat_seek(dev, 0, SEEK_SET) == -1) + { + close(dev->fd); + free(dev); + exfat_error("failed to seek to the beginning of '%s'", spec); + return NULL; + } + } + +#ifdef USE_UBLIO + memset(&up, 0, sizeof(struct ublio_param)); + up.up_blocksize = 256 * 1024; + up.up_items = 64; + up.up_grace = 32; + up.up_priv = &dev->fd; + + dev->pos = 0; + dev->ufh = ublio_open(&up); + if (dev->ufh == NULL) + { + close(dev->fd); + free(dev); + exfat_error("failed to initialize ublio"); + return NULL; + } +#endif + + return dev; +} + +int exfat_close(struct exfat_dev* dev) +{ + int rc = 0; + +#ifdef USE_UBLIO + if (ublio_close(dev->ufh) != 0) + { + exfat_error("failed to close ublio"); + rc = -EIO; + } +#endif + if (dev->fd != g_vtoy_exfat_disk_fd) + { + if (close(dev->fd) != 0) + { + exfat_error("failed to close device: %s", strerror(errno)); + rc = -EIO; + } + } + + free(dev); + return rc; +} + +int exfat_fsync(struct exfat_dev* dev) +{ + int rc = 0; + +#ifdef USE_UBLIO + if (ublio_fsync(dev->ufh) != 0) + { + exfat_error("ublio fsync failed"); + rc = -EIO; + } +#endif + if (fsync(dev->fd) != 0) + { + exfat_error("fsync failed: %s", strerror(errno)); + rc = -EIO; + } + return rc; +} + +enum exfat_mode exfat_get_mode(const struct exfat_dev* dev) +{ + return dev->mode; +} + + +off_t exfat_get_size(const struct exfat_dev* dev) +{ + return dev->size; +} + +off_t exfat_seek(struct exfat_dev* dev, off_t offset, int whence) +{ +#ifdef USE_UBLIO + /* XXX SEEK_CUR will be handled incorrectly */ + return dev->pos = lseek(dev->fd, offset, whence); +#else + + if (SEEK_SET == whence) + { + if (offset > g_vtoy_exfat_part_size) + { + return -1; + } + + lseek(dev->fd, 512 * 2048 + offset, SEEK_SET); + return offset; + } + else if (SEEK_END == whence) + { + if (offset == 0) + { + offset = 512 * 2048 + g_vtoy_exfat_part_size; + lseek(dev->fd, offset, SEEK_SET); + return (off_t)g_vtoy_exfat_part_size; + } + else + { + exfat_error("Invalid SEEK_END offset %llu", (unsigned long long)offset); + return -1; + } + } + else + { + exfat_error("Invalid seek whence %d", whence); + return lseek(dev->fd, offset, whence); + } +#endif +} + +ssize_t exfat_read(struct exfat_dev* dev, void* buffer, size_t size) +{ +#ifdef USE_UBLIO + ssize_t result = ublio_pread(dev->ufh, buffer, size, dev->pos); + if (result >= 0) + dev->pos += size; + return result; +#else + return read(dev->fd, buffer, size); +#endif +} + +ssize_t exfat_write(struct exfat_dev* dev, const void* buffer, size_t size) +{ +#ifdef USE_UBLIO + ssize_t result = ublio_pwrite(dev->ufh, buffer, size, dev->pos); + if (result >= 0) + dev->pos += size; + return result; +#else + return write(dev->fd, buffer, size); +#endif +} + +ssize_t exfat_pread(struct exfat_dev* dev, void* buffer, size_t size, + off_t offset) +{ +#ifdef USE_UBLIO + return ublio_pread(dev->ufh, buffer, size, offset); +#else + return pread(dev->fd, buffer, size, offset); +#endif +} + +ssize_t exfat_pwrite(struct exfat_dev* dev, const void* buffer, size_t size, + off_t offset) +{ +#ifdef USE_UBLIO + return ublio_pwrite(dev->ufh, buffer, size, offset); +#else + return pwrite(dev->fd, buffer, size, offset); +#endif +} + +ssize_t exfat_generic_pread(const struct exfat* ef, struct exfat_node* node, + void* buffer, size_t size, off_t offset) +{ + cluster_t cluster; + char* bufp = buffer; + off_t lsize, loffset, remainder; + + if (offset >= node->size) + return 0; + if (size == 0) + return 0; + + cluster = exfat_advance_cluster(ef, node, offset / CLUSTER_SIZE(*ef->sb)); + if (CLUSTER_INVALID(*ef->sb, cluster)) + { + exfat_error("invalid cluster 0x%x while reading", cluster); + return -EIO; + } + + loffset = offset % CLUSTER_SIZE(*ef->sb); + remainder = MIN(size, node->size - offset); + while (remainder > 0) + { + if (CLUSTER_INVALID(*ef->sb, cluster)) + { + exfat_error("invalid cluster 0x%x while reading", cluster); + return -EIO; + } + lsize = MIN(CLUSTER_SIZE(*ef->sb) - loffset, remainder); + if (exfat_pread(ef->dev, bufp, lsize, + exfat_c2o(ef, cluster) + loffset) < 0) + { + exfat_error("failed to read cluster %#x", cluster); + return -EIO; + } + bufp += lsize; + loffset = 0; + remainder -= lsize; + cluster = exfat_next_cluster(ef, node, cluster); + } + if (!(node->attrib & EXFAT_ATTRIB_DIR) && !ef->ro && !ef->noatime) + exfat_update_atime(node); + return MIN(size, node->size - offset) - remainder; +} + +ssize_t exfat_generic_pwrite(struct exfat* ef, struct exfat_node* node, + const void* buffer, size_t size, off_t offset) +{ + int rc; + cluster_t cluster; + const char* bufp = buffer; + off_t lsize, loffset, remainder; + + if (offset > node->size) + { + rc = exfat_truncate(ef, node, offset, true); + if (rc != 0) + return rc; + } + if (offset + size > node->size) + { + rc = exfat_truncate(ef, node, offset + size, false); + if (rc != 0) + return rc; + } + if (size == 0) + return 0; + + cluster = exfat_advance_cluster(ef, node, offset / CLUSTER_SIZE(*ef->sb)); + if (CLUSTER_INVALID(*ef->sb, cluster)) + { + exfat_error("invalid cluster 0x%x while writing", cluster); + return -EIO; + } + + loffset = offset % CLUSTER_SIZE(*ef->sb); + remainder = size; + while (remainder > 0) + { + if (CLUSTER_INVALID(*ef->sb, cluster)) + { + exfat_error("invalid cluster 0x%x while writing", cluster); + return -EIO; + } + lsize = MIN(CLUSTER_SIZE(*ef->sb) - loffset, remainder); + if (exfat_pwrite(ef->dev, bufp, lsize, + exfat_c2o(ef, cluster) + loffset) < 0) + { + exfat_error("failed to write cluster %#x", cluster); + return -EIO; + } + bufp += lsize; + loffset = 0; + remainder -= lsize; + cluster = exfat_next_cluster(ef, node, cluster); + } + if (!(node->attrib & EXFAT_ATTRIB_DIR)) + /* directory's mtime should be updated by the caller only when it + creates or removes something in this directory */ + exfat_update_mtime(node); + return size - remainder; +} diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/lookup.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/lookup.c new file mode 100644 index 0000000..8fa8e0f --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/lookup.c @@ -0,0 +1,224 @@ +/* + lookup.c (02.09.09) + exFAT file system implementation library. + + Free exFAT implementation. + Copyright (C) 2010-2018 Andrew Nayenko + + 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. +*/ + +#include "exfat.h" +#include +#include +#include + +int exfat_opendir(struct exfat* ef, struct exfat_node* dir, + struct exfat_iterator* it) +{ + int rc; + + exfat_get_node(dir); + it->parent = dir; + it->current = NULL; + rc = exfat_cache_directory(ef, dir); + if (rc != 0) + exfat_put_node(ef, dir); + return rc; +} + +void exfat_closedir(struct exfat* ef, struct exfat_iterator* it) +{ + exfat_put_node(ef, it->parent); + it->parent = NULL; + it->current = NULL; +} + +struct exfat_node* exfat_readdir(struct exfat_iterator* it) +{ + if (it->current == NULL) + it->current = it->parent->child; + else + it->current = it->current->next; + + if (it->current != NULL) + return exfat_get_node(it->current); + else + return NULL; +} + +static int compare_char(struct exfat* ef, uint16_t a, uint16_t b) +{ + return (int) ef->upcase[a] - (int) ef->upcase[b]; +} + +static int compare_name(struct exfat* ef, const le16_t* a, const le16_t* b) +{ + while (le16_to_cpu(*a) && le16_to_cpu(*b)) + { + int rc = compare_char(ef, le16_to_cpu(*a), le16_to_cpu(*b)); + if (rc != 0) + return rc; + a++; + b++; + } + return compare_char(ef, le16_to_cpu(*a), le16_to_cpu(*b)); +} + +static int lookup_name(struct exfat* ef, struct exfat_node* parent, + struct exfat_node** node, const char* name, size_t n) +{ + struct exfat_iterator it; + le16_t buffer[EXFAT_NAME_MAX + 1]; + int rc; + + *node = NULL; + + rc = utf8_to_utf16(buffer, name, EXFAT_NAME_MAX + 1, n); + if (rc != 0) + return rc; + + rc = exfat_opendir(ef, parent, &it); + if (rc != 0) + return rc; + while ((*node = exfat_readdir(&it))) + { + if (compare_name(ef, buffer, (*node)->name) == 0) + { + exfat_closedir(ef, &it); + return 0; + } + exfat_put_node(ef, *node); + } + exfat_closedir(ef, &it); + return -ENOENT; +} + +static size_t get_comp(const char* path, const char** comp) +{ + const char* end; + + *comp = path + strspn(path, "/"); /* skip leading slashes */ + end = strchr(*comp, '/'); + if (end == NULL) + return strlen(*comp); + else + return end - *comp; +} + +int exfat_lookup(struct exfat* ef, struct exfat_node** node, + const char* path) +{ + struct exfat_node* parent; + const char* p; + size_t n; + int rc; + + /* start from the root directory */ + parent = *node = exfat_get_node(ef->root); + for (p = path; (n = get_comp(p, &p)); p += n) + { + if (n == 1 && *p == '.') /* skip "." component */ + continue; + rc = lookup_name(ef, parent, node, p, n); + if (rc != 0) + { + exfat_put_node(ef, parent); + return rc; + } + exfat_put_node(ef, parent); + parent = *node; + } + return 0; +} + +static bool is_last_comp(const char* comp, size_t length) +{ + const char* p = comp + length; + + return get_comp(p, &p) == 0; +} + +static bool is_allowed(const char* comp, size_t length) +{ + size_t i; + + for (i = 0; i < length; i++) + switch (comp[i]) + { + case 0x01 ... 0x1f: + case '/': + case '\\': + case ':': + case '*': + case '?': + case '"': + case '<': + case '>': + case '|': + return false; + } + return true; +} + +int exfat_split(struct exfat* ef, struct exfat_node** parent, + struct exfat_node** node, le16_t* name, const char* path) +{ + const char* p; + size_t n; + int rc; + + memset(name, 0, (EXFAT_NAME_MAX + 1) * sizeof(le16_t)); + *parent = *node = exfat_get_node(ef->root); + for (p = path; (n = get_comp(p, &p)); p += n) + { + if (n == 1 && *p == '.') + continue; + if (is_last_comp(p, n)) + { + if (!is_allowed(p, n)) + { + /* contains characters that are not allowed */ + exfat_put_node(ef, *parent); + return -ENOENT; + } + rc = utf8_to_utf16(name, p, EXFAT_NAME_MAX + 1, n); + if (rc != 0) + { + exfat_put_node(ef, *parent); + return rc; + } + + rc = lookup_name(ef, *parent, node, p, n); + if (rc != 0 && rc != -ENOENT) + { + exfat_put_node(ef, *parent); + return rc; + } + return 0; + } + rc = lookup_name(ef, *parent, node, p, n); + if (rc != 0) + { + exfat_put_node(ef, *parent); + return rc; + } + exfat_put_node(ef, *parent); + *parent = *node; + } + exfat_bug("impossible"); + + return 1; +} diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/mount.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/mount.c new file mode 100644 index 0000000..4284aee --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/mount.c @@ -0,0 +1,389 @@ +/* + mount.c (22.10.09) + exFAT file system implementation library. + + Free exFAT implementation. + Copyright (C) 2010-2018 Andrew Nayenko + + 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. +*/ + +#include "exfat.h" +#include +#include +#include +#include +#include +#include + +static uint64_t rootdir_size(const struct exfat* ef) +{ + uint32_t clusters = 0; + uint32_t clusters_max = le32_to_cpu(ef->sb->cluster_count); + cluster_t rootdir_cluster = le32_to_cpu(ef->sb->rootdir_cluster); + + /* Iterate all clusters of the root directory to calculate its size. + It can't be contiguous because there is no flag to indicate this. */ + do + { + if (clusters == clusters_max) /* infinite loop detected */ + { + exfat_error("root directory cannot occupy all %d clusters", + clusters); + return 0; + } + if (CLUSTER_INVALID(*ef->sb, rootdir_cluster)) + { + exfat_error("bad cluster %#x while reading root directory", + rootdir_cluster); + return 0; + } + rootdir_cluster = exfat_next_cluster(ef, ef->root, rootdir_cluster); + clusters++; + } + while (rootdir_cluster != EXFAT_CLUSTER_END); + + return (uint64_t) clusters * CLUSTER_SIZE(*ef->sb); +} + +static const char* get_option(const char* options, const char* option_name) +{ + const char* p; + size_t length = strlen(option_name); + + for (p = strstr(options, option_name); p; p = strstr(p + 1, option_name)) + if ((p == options || p[-1] == ',') && p[length] == '=') + return p + length + 1; + return NULL; +} + +static int get_int_option(const char* options, const char* option_name, + int base, int default_value) +{ + const char* p = get_option(options, option_name); + + if (p == NULL) + return default_value; + return strtol(p, NULL, base); +} + +static bool match_option(const char* options, const char* option_name) +{ + const char* p; + size_t length = strlen(option_name); + + for (p = strstr(options, option_name); p; p = strstr(p + 1, option_name)) + if ((p == options || p[-1] == ',') && + (p[length] == ',' || p[length] == '\0')) + return true; + return false; +} + +static void parse_options(struct exfat* ef, const char* options) +{ + int opt_umask; + + opt_umask = get_int_option(options, "umask", 8, 0); + ef->dmask = get_int_option(options, "dmask", 8, opt_umask); + ef->fmask = get_int_option(options, "fmask", 8, opt_umask); + + ef->uid = get_int_option(options, "uid", 10, geteuid()); + ef->gid = get_int_option(options, "gid", 10, getegid()); + + ef->noatime = match_option(options, "noatime"); + + switch (get_int_option(options, "repair", 10, 0)) + { + case 1: + ef->repair = EXFAT_REPAIR_ASK; + break; + case 2: + ef->repair = EXFAT_REPAIR_YES; + break; + default: + ef->repair = EXFAT_REPAIR_NO; + break; + } +} + +static bool verify_vbr_checksum(const struct exfat* ef, void* sector) +{ + off_t sector_size = SECTOR_SIZE(*ef->sb); + uint32_t vbr_checksum; + int i; + + if (exfat_pread(ef->dev, sector, sector_size, 0) < 0) + { + exfat_error("failed to read boot sector"); + return false; + } + vbr_checksum = exfat_vbr_start_checksum(sector, sector_size); + for (i = 1; i < 11; i++) + { + if (exfat_pread(ef->dev, sector, sector_size, i * sector_size) < 0) + { + exfat_error("failed to read VBR sector"); + return false; + } + vbr_checksum = exfat_vbr_add_checksum(sector, sector_size, + vbr_checksum); + } + if (exfat_pread(ef->dev, sector, sector_size, i * sector_size) < 0) + { + exfat_error("failed to read VBR checksum sector"); + return false; + } + for (i = 0; i < sector_size / sizeof(vbr_checksum); i++) + if (le32_to_cpu(((const le32_t*) sector)[i]) != vbr_checksum) + { + exfat_error("invalid VBR checksum 0x%x (expected 0x%x)", + le32_to_cpu(((const le32_t*) sector)[i]), vbr_checksum); + if (!EXFAT_REPAIR(invalid_vbr_checksum, ef, sector, vbr_checksum)) + return false; + } + return true; +} + +static int commit_super_block(const struct exfat* ef) +{ + if (exfat_pwrite(ef->dev, ef->sb, sizeof(struct exfat_super_block), 0) < 0) + { + exfat_error("failed to write super block"); + return 1; + } + return exfat_fsync(ef->dev); +} + +static int prepare_super_block(const struct exfat* ef) +{ + if (le16_to_cpu(ef->sb->volume_state) & EXFAT_STATE_MOUNTED) + exfat_warn("volume was not unmounted cleanly"); + + if (ef->ro) + return 0; + + ef->sb->volume_state = cpu_to_le16( + le16_to_cpu(ef->sb->volume_state) | EXFAT_STATE_MOUNTED); + return commit_super_block(ef); +} + +static void exfat_free(struct exfat* ef) +{ + exfat_close(ef->dev); /* first of all, close the descriptor */ + ef->dev = NULL; /* struct exfat_dev is freed by exfat_close() */ + free(ef->root); + ef->root = NULL; + free(ef->zero_cluster); + ef->zero_cluster = NULL; + free(ef->cmap.chunk); + ef->cmap.chunk = NULL; + free(ef->upcase); + ef->upcase = NULL; + free(ef->sb); + ef->sb = NULL; +} + +int exfat_mount(struct exfat* ef, const char* spec, const char* options) +{ + int rc; + enum exfat_mode mode; + + exfat_tzset(); + memset(ef, 0, sizeof(struct exfat)); + + parse_options(ef, options); + + if (match_option(options, "ro")) + mode = EXFAT_MODE_RO; + else if (match_option(options, "ro_fallback")) + mode = EXFAT_MODE_ANY; + else + mode = EXFAT_MODE_RW; + ef->dev = exfat_open(spec, mode); + if (ef->dev == NULL) + return -EIO; + if (exfat_get_mode(ef->dev) == EXFAT_MODE_RO) + { + if (mode == EXFAT_MODE_ANY) + ef->ro = -1; + else + ef->ro = 1; + } + + ef->sb = malloc(sizeof(struct exfat_super_block)); + if (ef->sb == NULL) + { + exfat_error("failed to allocate memory for the super block"); + exfat_free(ef); + return -ENOMEM; + } + memset(ef->sb, 0, sizeof(struct exfat_super_block)); + + if (exfat_pread(ef->dev, ef->sb, sizeof(struct exfat_super_block), 0) < 0) + { + exfat_error("failed to read boot sector"); + exfat_free(ef); + return -EIO; + } + if (memcmp(ef->sb->oem_name, "EXFAT ", 8) != 0) + { + exfat_error("exFAT file system is not found"); + exfat_free(ef); + return -EIO; + } + /* sector cannot be smaller than 512 bytes */ + if (ef->sb->sector_bits < 9) + { + exfat_error("too small sector size: 2^%hhd", ef->sb->sector_bits); + exfat_free(ef); + return -EIO; + } + /* officially exFAT supports cluster size up to 32 MB */ + if ((int) ef->sb->sector_bits + (int) ef->sb->spc_bits > 25) + { + exfat_error("too big cluster size: 2^(%hhd+%hhd)", + ef->sb->sector_bits, ef->sb->spc_bits); + exfat_free(ef); + return -EIO; + } + ef->zero_cluster = malloc(CLUSTER_SIZE(*ef->sb)); + if (ef->zero_cluster == NULL) + { + exfat_error("failed to allocate zero sector"); + exfat_free(ef); + return -ENOMEM; + } + /* use zero_cluster as a temporary buffer for VBR checksum verification */ + if (!verify_vbr_checksum(ef, ef->zero_cluster)) + { + exfat_free(ef); + return -EIO; + } + memset(ef->zero_cluster, 0, CLUSTER_SIZE(*ef->sb)); + if (ef->sb->version.major != 1 || ef->sb->version.minor != 0) + { + exfat_error("unsupported exFAT version: %hhu.%hhu", + ef->sb->version.major, ef->sb->version.minor); + exfat_free(ef); + return -EIO; + } + if (ef->sb->fat_count != 1) + { + exfat_error("unsupported FAT count: %hhu", ef->sb->fat_count); + exfat_free(ef); + return -EIO; + } + if (le64_to_cpu(ef->sb->sector_count) * SECTOR_SIZE(*ef->sb) > + exfat_get_size(ef->dev)) + { + /* this can cause I/O errors later but we don't fail mounting to let + user rescue data */ + exfat_warn("file system in sectors is larger than device: " + "%"PRIu64" * %d > %"PRIu64, + le64_to_cpu(ef->sb->sector_count), SECTOR_SIZE(*ef->sb), + exfat_get_size(ef->dev)); + } + if ((off_t) le32_to_cpu(ef->sb->cluster_count) * CLUSTER_SIZE(*ef->sb) > + exfat_get_size(ef->dev)) + { + exfat_error("file system in clusters is larger than device: " + "%u * %d > %"PRIu64, + le32_to_cpu(ef->sb->cluster_count), CLUSTER_SIZE(*ef->sb), + exfat_get_size(ef->dev)); + exfat_free(ef); + return -EIO; + } + + ef->root = malloc(sizeof(struct exfat_node)); + if (ef->root == NULL) + { + exfat_error("failed to allocate root node"); + exfat_free(ef); + return -ENOMEM; + } + memset(ef->root, 0, sizeof(struct exfat_node)); + ef->root->attrib = EXFAT_ATTRIB_DIR; + ef->root->start_cluster = le32_to_cpu(ef->sb->rootdir_cluster); + ef->root->fptr_cluster = ef->root->start_cluster; + ef->root->name[0] = cpu_to_le16('\0'); + ef->root->size = rootdir_size(ef); + if (ef->root->size == 0) + { + exfat_free(ef); + return -EIO; + } + /* exFAT does not have time attributes for the root directory */ + ef->root->mtime = 0; + ef->root->atime = 0; + /* always keep at least 1 reference to the root node */ + exfat_get_node(ef->root); + + rc = exfat_cache_directory(ef, ef->root); + if (rc != 0) + goto error; + if (ef->upcase == NULL) + { + exfat_error("upcase table is not found"); + goto error; + } + if (ef->cmap.chunk == NULL) + { + exfat_error("clusters bitmap is not found"); + goto error; + } + + if (prepare_super_block(ef) != 0) + goto error; + + return 0; + +error: + exfat_put_node(ef, ef->root); + exfat_reset_cache(ef); + exfat_free(ef); + return -EIO; +} + +static void finalize_super_block(struct exfat* ef) +{ + if (ef->ro) + return; + + ef->sb->volume_state = cpu_to_le16( + le16_to_cpu(ef->sb->volume_state) & ~EXFAT_STATE_MOUNTED); + + /* Some implementations set the percentage of allocated space to 0xff + on FS creation and never update it. In this case leave it as is. */ + if (ef->sb->allocated_percent != 0xff) + { + uint32_t free, total; + + free = exfat_count_free_clusters(ef); + total = le32_to_cpu(ef->sb->cluster_count); + ef->sb->allocated_percent = ((total - free) * 100 + total / 2) / total; + } + + commit_super_block(ef); /* ignore return code */ +} + +void exfat_unmount(struct exfat* ef) +{ + exfat_flush_nodes(ef); /* ignore return code */ + exfat_flush(ef); /* ignore return code */ + exfat_put_node(ef, ef->root); + exfat_reset_cache(ef); + finalize_super_block(ef); + exfat_free(ef); /* will close the descriptor */ +} diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/node.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/node.c new file mode 100644 index 0000000..ab1d7d6 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/node.c @@ -0,0 +1,1226 @@ +/* + node.c (09.10.09) + exFAT file system implementation library. + + Free exFAT implementation. + Copyright (C) 2010-2018 Andrew Nayenko + + 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. +*/ + +#include "exfat.h" +#include +#include +#include + +#define EXFAT_ENTRY_NONE (-1) + +struct exfat_node* exfat_get_node(struct exfat_node* node) +{ + /* if we switch to multi-threaded mode we will need atomic + increment here and atomic decrement in exfat_put_node() */ + node->references++; + return node; +} + +void exfat_put_node(struct exfat* ef, struct exfat_node* node) +{ + char buffer[EXFAT_UTF8_NAME_BUFFER_MAX]; + + --node->references; + if (node->references < 0) + { + exfat_get_name(node, buffer); + exfat_bug("reference counter of '%s' is below zero", buffer); + } + else if (node->references == 0 && node != ef->root) + { + if (node->is_dirty) + { + exfat_get_name(node, buffer); + exfat_warn("dirty node '%s' with zero references", buffer); + } + } +} + +/** + * This function must be called on rmdir and unlink (after the last + * exfat_put_node()) to free clusters. + */ +int exfat_cleanup_node(struct exfat* ef, struct exfat_node* node) +{ + int rc = 0; + + if (node->references != 0) + exfat_bug("unable to cleanup a node with %d references", + node->references); + + if (node->is_unlinked) + { + /* free all clusters and node structure itself */ + rc = exfat_truncate(ef, node, 0, true); + /* free the node even in case of error or its memory will be lost */ + free(node); + } + return rc; +} + +static int read_entries(struct exfat* ef, struct exfat_node* dir, + struct exfat_entry* entries, int n, off_t offset) +{ + ssize_t size; + + if (!(dir->attrib & EXFAT_ATTRIB_DIR)) + exfat_bug("attempted to read entries from a file"); + + size = exfat_generic_pread(ef, dir, entries, + sizeof(struct exfat_entry[n]), offset); + if (size == sizeof(struct exfat_entry[n])) + return 0; /* success */ + if (size == 0) + return -ENOENT; + if (size < 0) + return -EIO; + exfat_error("read %zd bytes instead of %zu bytes", size, + sizeof(struct exfat_entry[n])); + return -EIO; +} + +static int write_entries(struct exfat* ef, struct exfat_node* dir, + const struct exfat_entry* entries, int n, off_t offset) +{ + ssize_t size; + + if (!(dir->attrib & EXFAT_ATTRIB_DIR)) + exfat_bug("attempted to write entries into a file"); + + size = exfat_generic_pwrite(ef, dir, entries, + sizeof(struct exfat_entry[n]), offset); + if (size == sizeof(struct exfat_entry[n])) + return 0; /* success */ + if (size < 0) + return -EIO; + exfat_error("wrote %zd bytes instead of %zu bytes", size, + sizeof(struct exfat_entry[n])); + return -EIO; +} + +static struct exfat_node* allocate_node(void) +{ + struct exfat_node* node = malloc(sizeof(struct exfat_node)); + if (node == NULL) + { + exfat_error("failed to allocate node"); + return NULL; + } + memset(node, 0, sizeof(struct exfat_node)); + return node; +} + +static void init_node_meta1(struct exfat_node* node, + const struct exfat_entry_meta1* meta1) +{ + node->attrib = le16_to_cpu(meta1->attrib); + node->continuations = meta1->continuations; + node->mtime = exfat_exfat2unix(meta1->mdate, meta1->mtime, + meta1->mtime_cs); + /* there is no centiseconds field for atime */ + node->atime = exfat_exfat2unix(meta1->adate, meta1->atime, 0); +} + +static void init_node_meta2(struct exfat_node* node, + const struct exfat_entry_meta2* meta2) +{ + node->size = le64_to_cpu(meta2->size); + node->start_cluster = le32_to_cpu(meta2->start_cluster); + node->fptr_cluster = node->start_cluster; + node->is_contiguous = ((meta2->flags & EXFAT_FLAG_CONTIGUOUS) != 0); +} + +static void init_node_name(struct exfat_node* node, + const struct exfat_entry* entries, int n) +{ + int i; + + for (i = 0; i < n; i++) + memcpy(node->name + i * EXFAT_ENAME_MAX, + ((const struct exfat_entry_name*) &entries[i])->name, + EXFAT_ENAME_MAX * sizeof(le16_t)); +} + +static bool check_entries(const struct exfat_entry* entry, int n) +{ + int previous = EXFAT_ENTRY_NONE; + int current; + int i; + + /* check transitions between entries types */ + for (i = 0; i < n + 1; previous = current, i++) + { + bool valid = false; + + current = (i < n) ? entry[i].type : EXFAT_ENTRY_NONE; + switch (previous) + { + case EXFAT_ENTRY_NONE: + valid = (current == EXFAT_ENTRY_FILE); + break; + case EXFAT_ENTRY_FILE: + valid = (current == EXFAT_ENTRY_FILE_INFO); + break; + case EXFAT_ENTRY_FILE_INFO: + valid = (current == EXFAT_ENTRY_FILE_NAME); + break; + case EXFAT_ENTRY_FILE_NAME: + valid = (current == EXFAT_ENTRY_FILE_NAME || + current == EXFAT_ENTRY_NONE || + current >= EXFAT_ENTRY_FILE_TAIL); + break; + case EXFAT_ENTRY_FILE_TAIL ... 0xff: + valid = (current >= EXFAT_ENTRY_FILE_TAIL || + current == EXFAT_ENTRY_NONE); + break; + } + + if (!valid) + { + exfat_error("unexpected entry type %#x after %#x at %d/%d", + current, previous, i, n); + return false; + } + } + return true; +} + +static bool check_node(const struct exfat* ef, struct exfat_node* node, + le16_t actual_checksum, const struct exfat_entry_meta1* meta1, + const struct exfat_entry_meta2* meta2) +{ + int cluster_size = CLUSTER_SIZE(*ef->sb); + uint64_t clusters_heap_size = + (uint64_t) le32_to_cpu(ef->sb->cluster_count) * cluster_size; + char buffer[EXFAT_UTF8_NAME_BUFFER_MAX]; + bool ret = true; + + /* + Validate checksum first. If it's invalid all other fields probably + contain just garbage. + */ + if (le16_to_cpu(actual_checksum) != le16_to_cpu(meta1->checksum)) + { + exfat_get_name(node, buffer); + exfat_error("'%s' has invalid checksum (%#hx != %#hx)", buffer, + le16_to_cpu(actual_checksum), le16_to_cpu(meta1->checksum)); + if (!EXFAT_REPAIR(invalid_node_checksum, ef, node)) + ret = false; + } + + /* + exFAT does not support sparse files but allows files with uninitialized + clusters. For such files valid_size means initialized data size and + cannot be greater than file size. See SetFileValidData() function + description in MSDN. + */ + if (le64_to_cpu(meta2->valid_size) > node->size) + { + exfat_get_name(node, buffer); + exfat_error("'%s' has valid size (%"PRIu64") greater than size " + "(%"PRIu64")", buffer, le64_to_cpu(meta2->valid_size), + node->size); + ret = false; + } + + /* + Empty file must have zero start cluster. Non-empty file must start + with a valid cluster. Directories cannot be empty (i.e. must always + have a valid start cluster), but we will check this later while + reading that directory to give user a chance to read this directory. + */ + if (node->size == 0 && node->start_cluster != EXFAT_CLUSTER_FREE) + { + exfat_get_name(node, buffer); + exfat_error("'%s' is empty but start cluster is %#x", buffer, + node->start_cluster); + ret = false; + } + if (node->size > 0 && CLUSTER_INVALID(*ef->sb, node->start_cluster)) + { + exfat_get_name(node, buffer); + exfat_error("'%s' points to invalid cluster %#x", buffer, + node->start_cluster); + ret = false; + } + + /* File or directory cannot be larger than clusters heap. */ + if (node->size > clusters_heap_size) + { + exfat_get_name(node, buffer); + exfat_error("'%s' is larger than clusters heap: %"PRIu64" > %"PRIu64, + buffer, node->size, clusters_heap_size); + ret = false; + } + + /* Empty file or directory must be marked as non-contiguous. */ + if (node->size == 0 && node->is_contiguous) + { + exfat_get_name(node, buffer); + exfat_error("'%s' is empty but marked as contiguous (%#hx)", buffer, + node->attrib); + ret = false; + } + + /* Directory size must be aligned on at cluster boundary. */ + if ((node->attrib & EXFAT_ATTRIB_DIR) && node->size % cluster_size != 0) + { + exfat_get_name(node, buffer); + exfat_error("'%s' directory size %"PRIu64" is not divisible by %d", buffer, + node->size, cluster_size); + ret = false; + } + + return ret; +} + +static int parse_file_entries(struct exfat* ef, struct exfat_node* node, + const struct exfat_entry* entries, int n) +{ + const struct exfat_entry_meta1* meta1; + const struct exfat_entry_meta2* meta2; + int mandatory_entries; + + if (!check_entries(entries, n)) + return -EIO; + + meta1 = (const struct exfat_entry_meta1*) &entries[0]; + if (meta1->continuations < 2) + { + exfat_error("too few continuations (%hhu)", meta1->continuations); + return -EIO; + } + meta2 = (const struct exfat_entry_meta2*) &entries[1]; + if (meta2->flags & ~(EXFAT_FLAG_ALWAYS1 | EXFAT_FLAG_CONTIGUOUS)) + { + exfat_error("unknown flags in meta2 (%#hhx)", meta2->flags); + return -EIO; + } + mandatory_entries = 2 + DIV_ROUND_UP(meta2->name_length, EXFAT_ENAME_MAX); + if (meta1->continuations < mandatory_entries - 1) + { + exfat_error("too few continuations (%hhu < %d)", + meta1->continuations, mandatory_entries - 1); + return -EIO; + } + + init_node_meta1(node, meta1); + init_node_meta2(node, meta2); + init_node_name(node, entries + 2, mandatory_entries - 2); + + if (!check_node(ef, node, exfat_calc_checksum(entries, n), meta1, meta2)) + return -EIO; + + return 0; +} + +static int parse_file_entry(struct exfat* ef, struct exfat_node* parent, + struct exfat_node** node, off_t* offset, int n) +{ + struct exfat_entry entries[n]; + int rc; + + rc = read_entries(ef, parent, entries, n, *offset); + if (rc != 0) + return rc; + + /* a new node has zero references */ + *node = allocate_node(); + if (*node == NULL) + return -ENOMEM; + (*node)->entry_offset = *offset; + + rc = parse_file_entries(ef, *node, entries, n); + if (rc != 0) + { + free(*node); + return rc; + } + + *offset += sizeof(struct exfat_entry[n]); + return 0; +} + +static void decompress_upcase(uint16_t* output, const le16_t* source, + size_t size) +{ + size_t si; + size_t oi; + + for (oi = 0; oi < EXFAT_UPCASE_CHARS; oi++) + output[oi] = oi; + + for (si = 0, oi = 0; si < size && oi < EXFAT_UPCASE_CHARS; si++) + { + uint16_t ch = le16_to_cpu(source[si]); + + if (ch == 0xffff && si + 1 < size) /* indicates a run */ + oi += le16_to_cpu(source[++si]); + else + output[oi++] = ch; + } +} + +/* + * Read one entry in a directory at offset position and build a new node + * structure. + */ +static int readdir(struct exfat* ef, struct exfat_node* parent, + struct exfat_node** node, off_t* offset) +{ + int rc; + struct exfat_entry entry; + const struct exfat_entry_meta1* meta1; + const struct exfat_entry_upcase* upcase; + const struct exfat_entry_bitmap* bitmap; + const struct exfat_entry_label* label; + uint64_t upcase_size = 0; + le16_t* upcase_comp = NULL; + + for (;;) + { + rc = read_entries(ef, parent, &entry, 1, *offset); + if (rc != 0) + return rc; + + switch (entry.type) + { + case EXFAT_ENTRY_FILE: + meta1 = (const struct exfat_entry_meta1*) &entry; + return parse_file_entry(ef, parent, node, offset, + 1 + meta1->continuations); + + case EXFAT_ENTRY_UPCASE: + if (ef->upcase != NULL) + break; + upcase = (const struct exfat_entry_upcase*) &entry; + if (CLUSTER_INVALID(*ef->sb, le32_to_cpu(upcase->start_cluster))) + { + exfat_error("invalid cluster 0x%x in upcase table", + le32_to_cpu(upcase->start_cluster)); + return -EIO; + } + upcase_size = le64_to_cpu(upcase->size); + if (upcase_size == 0 || + upcase_size > EXFAT_UPCASE_CHARS * sizeof(uint16_t) || + upcase_size % sizeof(uint16_t) != 0) + { + exfat_error("bad upcase table size (%"PRIu64" bytes)", + upcase_size); + return -EIO; + } + upcase_comp = malloc(upcase_size); + if (upcase_comp == NULL) + { + exfat_error("failed to allocate upcase table (%"PRIu64" bytes)", + upcase_size); + return -ENOMEM; + } + + /* read compressed upcase table */ + if (exfat_pread(ef->dev, upcase_comp, upcase_size, + exfat_c2o(ef, le32_to_cpu(upcase->start_cluster))) < 0) + { + free(upcase_comp); + exfat_error("failed to read upper case table " + "(%"PRIu64" bytes starting at cluster %#x)", + upcase_size, + le32_to_cpu(upcase->start_cluster)); + return -EIO; + } + + /* decompress upcase table */ + ef->upcase = calloc(EXFAT_UPCASE_CHARS, sizeof(uint16_t)); + if (ef->upcase == NULL) + { + free(upcase_comp); + exfat_error("failed to allocate decompressed upcase table"); + return -ENOMEM; + } + decompress_upcase(ef->upcase, upcase_comp, + upcase_size / sizeof(uint16_t)); + free(upcase_comp); + break; + + case EXFAT_ENTRY_BITMAP: + bitmap = (const struct exfat_entry_bitmap*) &entry; + ef->cmap.start_cluster = le32_to_cpu(bitmap->start_cluster); + if (CLUSTER_INVALID(*ef->sb, ef->cmap.start_cluster)) + { + exfat_error("invalid cluster 0x%x in clusters bitmap", + ef->cmap.start_cluster); + return -EIO; + } + ef->cmap.size = le32_to_cpu(ef->sb->cluster_count); + if (le64_to_cpu(bitmap->size) < DIV_ROUND_UP(ef->cmap.size, 8)) + { + exfat_error("invalid clusters bitmap size: %"PRIu64 + " (expected at least %u)", + le64_to_cpu(bitmap->size), + DIV_ROUND_UP(ef->cmap.size, 8)); + return -EIO; + } + /* FIXME bitmap can be rather big, up to 512 MB */ + ef->cmap.chunk_size = ef->cmap.size; + ef->cmap.chunk = malloc(BMAP_SIZE(ef->cmap.chunk_size)); + if (ef->cmap.chunk == NULL) + { + exfat_error("failed to allocate clusters bitmap chunk " + "(%"PRIu64" bytes)", le64_to_cpu(bitmap->size)); + return -ENOMEM; + } + + if (exfat_pread(ef->dev, ef->cmap.chunk, + BMAP_SIZE(ef->cmap.chunk_size), + exfat_c2o(ef, ef->cmap.start_cluster)) < 0) + { + exfat_error("failed to read clusters bitmap " + "(%"PRIu64" bytes starting at cluster %#x)", + le64_to_cpu(bitmap->size), ef->cmap.start_cluster); + return -EIO; + } + break; + + case EXFAT_ENTRY_LABEL: + label = (const struct exfat_entry_label*) &entry; + if (label->length > EXFAT_ENAME_MAX) + { + exfat_error("too long label (%hhu chars)", label->length); + return -EIO; + } + if (utf16_to_utf8(ef->label, label->name, + sizeof(ef->label), EXFAT_ENAME_MAX) != 0) + return -EIO; + break; + + default: + if (!(entry.type & EXFAT_ENTRY_VALID)) + break; /* deleted entry, ignore it */ + + exfat_error("unknown entry type %#hhx", entry.type); + if (!EXFAT_REPAIR(unknown_entry, ef, parent, &entry, *offset)) + return -EIO; + } + *offset += sizeof(entry); + } + /* we never reach here */ +} + +int exfat_cache_directory(struct exfat* ef, struct exfat_node* dir) +{ + off_t offset = 0; + int rc; + struct exfat_node* node; + struct exfat_node* current = NULL; + + if (dir->is_cached) + return 0; /* already cached */ + + while ((rc = readdir(ef, dir, &node, &offset)) == 0) + { + node->parent = dir; + if (current != NULL) + { + current->next = node; + node->prev = current; + } + else + dir->child = node; + + current = node; + } + + if (rc != -ENOENT) + { + /* rollback */ + for (current = dir->child; current; current = node) + { + node = current->next; + free(current); + } + dir->child = NULL; + return rc; + } + + dir->is_cached = true; + return 0; +} + +static void tree_attach(struct exfat_node* dir, struct exfat_node* node) +{ + node->parent = dir; + if (dir->child) + { + dir->child->prev = node; + node->next = dir->child; + } + dir->child = node; +} + +static void tree_detach(struct exfat_node* node) +{ + if (node->prev) + node->prev->next = node->next; + else /* this is the first node in the list */ + node->parent->child = node->next; + if (node->next) + node->next->prev = node->prev; + node->parent = NULL; + node->prev = NULL; + node->next = NULL; +} + +static void reset_cache(struct exfat* ef, struct exfat_node* node) +{ + char buffer[EXFAT_UTF8_NAME_BUFFER_MAX]; + + while (node->child) + { + struct exfat_node* p = node->child; + reset_cache(ef, p); + tree_detach(p); + free(p); + } + node->is_cached = false; + if (node->references != 0) + { + exfat_get_name(node, buffer); + exfat_warn("non-zero reference counter (%d) for '%s'", + node->references, buffer); + } + if (node != ef->root && node->is_dirty) + { + exfat_get_name(node, buffer); + exfat_bug("node '%s' is dirty", buffer); + } + while (node->references) + exfat_put_node(ef, node); +} + +void exfat_reset_cache(struct exfat* ef) +{ + reset_cache(ef, ef->root); +} + +int exfat_flush_node(struct exfat* ef, struct exfat_node* node) +{ + struct exfat_entry entries[1 + node->continuations]; + struct exfat_entry_meta1* meta1 = (struct exfat_entry_meta1*) &entries[0]; + struct exfat_entry_meta2* meta2 = (struct exfat_entry_meta2*) &entries[1]; + int rc; + + if (!node->is_dirty) + return 0; /* no need to flush */ + + if (ef->ro) + exfat_bug("unable to flush node to read-only FS"); + + if (node->parent == NULL) + return 0; /* do not flush unlinked node */ + + rc = read_entries(ef, node->parent, entries, 1 + node->continuations, + node->entry_offset); + if (rc != 0) + return rc; + if (!check_entries(entries, 1 + node->continuations)) + return -EIO; + + meta1->attrib = cpu_to_le16(node->attrib); + exfat_unix2exfat(node->mtime, &meta1->mdate, &meta1->mtime, + &meta1->mtime_cs); + exfat_unix2exfat(node->atime, &meta1->adate, &meta1->atime, NULL); + meta2->size = meta2->valid_size = cpu_to_le64(node->size); + meta2->start_cluster = cpu_to_le32(node->start_cluster); + meta2->flags = EXFAT_FLAG_ALWAYS1; + /* empty files must not be marked as contiguous */ + if (node->size != 0 && node->is_contiguous) + meta2->flags |= EXFAT_FLAG_CONTIGUOUS; + /* name hash remains unchanged, no need to recalculate it */ + + meta1->checksum = exfat_calc_checksum(entries, 1 + node->continuations); + rc = write_entries(ef, node->parent, entries, 1 + node->continuations, + node->entry_offset); + if (rc != 0) + return rc; + + node->is_dirty = false; + return exfat_flush(ef); +} + +static int erase_entries(struct exfat* ef, struct exfat_node* dir, int n, + off_t offset) +{ + struct exfat_entry entries[n]; + int rc; + int i; + + rc = read_entries(ef, dir, entries, n, offset); + if (rc != 0) + return rc; + for (i = 0; i < n; i++) + entries[i].type &= ~EXFAT_ENTRY_VALID; + return write_entries(ef, dir, entries, n, offset); +} + +static int erase_node(struct exfat* ef, struct exfat_node* node) +{ + int rc; + + exfat_get_node(node->parent); + rc = erase_entries(ef, node->parent, 1 + node->continuations, + node->entry_offset); + if (rc != 0) + { + exfat_put_node(ef, node->parent); + return rc; + } + rc = exfat_flush_node(ef, node->parent); + exfat_put_node(ef, node->parent); + return rc; +} + +static int shrink_directory(struct exfat* ef, struct exfat_node* dir, + off_t deleted_offset) +{ + const struct exfat_node* node; + const struct exfat_node* last_node; + uint64_t entries = 0; + uint64_t new_size; + + if (!(dir->attrib & EXFAT_ATTRIB_DIR)) + exfat_bug("attempted to shrink a file"); + if (!dir->is_cached) + exfat_bug("attempted to shrink uncached directory"); + + for (last_node = node = dir->child; node; node = node->next) + { + if (deleted_offset < node->entry_offset) + { + /* there are other entries after the removed one, no way to shrink + this directory */ + return 0; + } + if (last_node->entry_offset < node->entry_offset) + last_node = node; + } + + if (last_node) + { + /* offset of the last entry */ + entries += last_node->entry_offset / sizeof(struct exfat_entry); + /* two subentries with meta info */ + entries += 2; + /* subentries with file name */ + entries += DIV_ROUND_UP(utf16_length(last_node->name), + EXFAT_ENAME_MAX); + } + + new_size = DIV_ROUND_UP(entries * sizeof(struct exfat_entry), + CLUSTER_SIZE(*ef->sb)) * CLUSTER_SIZE(*ef->sb); + if (new_size == 0) /* directory always has at least 1 cluster */ + new_size = CLUSTER_SIZE(*ef->sb); + if (new_size == dir->size) + return 0; + return exfat_truncate(ef, dir, new_size, true); +} + +static int delete(struct exfat* ef, struct exfat_node* node) +{ + struct exfat_node* parent = node->parent; + off_t deleted_offset = node->entry_offset; + int rc; + + exfat_get_node(parent); + rc = erase_node(ef, node); + if (rc != 0) + { + exfat_put_node(ef, parent); + return rc; + } + tree_detach(node); + rc = shrink_directory(ef, parent, deleted_offset); + node->is_unlinked = true; + if (rc != 0) + { + exfat_flush_node(ef, parent); + exfat_put_node(ef, parent); + return rc; + } + exfat_update_mtime(parent); + rc = exfat_flush_node(ef, parent); + exfat_put_node(ef, parent); + return rc; +} + +int exfat_unlink(struct exfat* ef, struct exfat_node* node) +{ + if (node->attrib & EXFAT_ATTRIB_DIR) + return -EISDIR; + return delete(ef, node); +} + +int exfat_rmdir(struct exfat* ef, struct exfat_node* node) +{ + int rc; + + if (!(node->attrib & EXFAT_ATTRIB_DIR)) + return -ENOTDIR; + /* check that directory is empty */ + rc = exfat_cache_directory(ef, node); + if (rc != 0) + return rc; + if (node->child) + return -ENOTEMPTY; + return delete(ef, node); +} + +static int check_slot(struct exfat* ef, struct exfat_node* dir, off_t offset, + int n) +{ + struct exfat_entry entries[n]; + int rc; + size_t i; + + /* Root directory contains entries, that don't have any nodes associated + with them (clusters bitmap, upper case table, label). We need to be + careful not to overwrite them. */ + if (dir != ef->root) + return 0; + + rc = read_entries(ef, dir, entries, n, offset); + if (rc != 0) + return rc; + for (i = 0; i < n; i++) + if (entries[i].type & EXFAT_ENTRY_VALID) + return -EINVAL; + return 0; +} + +static int find_slot(struct exfat* ef, struct exfat_node* dir, + off_t* offset, int n) +{ + bitmap_t* dmap; + struct exfat_node* p; + size_t i; + int contiguous = 0; + + if (!dir->is_cached) + exfat_bug("directory is not cached"); + + /* build a bitmap of valid entries in the directory */ + dmap = calloc(BMAP_SIZE(dir->size / sizeof(struct exfat_entry)), + sizeof(bitmap_t)); + if (dmap == NULL) + { + exfat_error("failed to allocate directory bitmap (%"PRIu64")", + dir->size / sizeof(struct exfat_entry)); + return -ENOMEM; + } + for (p = dir->child; p != NULL; p = p->next) + for (i = 0; i < 1 + p->continuations; i++) + BMAP_SET(dmap, p->entry_offset / sizeof(struct exfat_entry) + i); + + /* find a slot in the directory entries bitmap */ + for (i = 0; i < dir->size / sizeof(struct exfat_entry); i++) + { + if (BMAP_GET(dmap, i) == 0) + { + if (contiguous++ == 0) + *offset = (off_t) i * sizeof(struct exfat_entry); + if (contiguous == n) + /* suitable slot is found, check that it's not occupied */ + switch (check_slot(ef, dir, *offset, n)) + { + case 0: + free(dmap); + return 0; + case -EIO: + free(dmap); + return -EIO; + case -EINVAL: + /* slot at (i-n) is occupied, go back and check (i-n+1) */ + i -= contiguous - 1; + contiguous = 0; + break; + } + } + else + contiguous = 0; + } + free(dmap); + + /* no suitable slots found, extend the directory */ + if (contiguous == 0) + *offset = dir->size; + return exfat_truncate(ef, dir, + ROUND_UP(dir->size + sizeof(struct exfat_entry[n - contiguous]), + CLUSTER_SIZE(*ef->sb)), + true); +} + +static int commit_entry(struct exfat* ef, struct exfat_node* dir, + const le16_t* name, off_t offset, uint16_t attrib) +{ + struct exfat_node* node; + const size_t name_length = utf16_length(name); + const int name_entries = DIV_ROUND_UP(name_length, EXFAT_ENAME_MAX); + struct exfat_entry entries[2 + name_entries]; + struct exfat_entry_meta1* meta1 = (struct exfat_entry_meta1*) &entries[0]; + struct exfat_entry_meta2* meta2 = (struct exfat_entry_meta2*) &entries[1]; + int i; + int rc; + + memset(entries, 0, sizeof(struct exfat_entry[2])); + + meta1->type = EXFAT_ENTRY_FILE; + meta1->continuations = 1 + name_entries; + meta1->attrib = cpu_to_le16(attrib); + exfat_unix2exfat(time(NULL), &meta1->crdate, &meta1->crtime, + &meta1->crtime_cs); + meta1->adate = meta1->mdate = meta1->crdate; + meta1->atime = meta1->mtime = meta1->crtime; + meta1->mtime_cs = meta1->crtime_cs; /* there is no atime_cs */ + + meta2->type = EXFAT_ENTRY_FILE_INFO; + meta2->flags = EXFAT_FLAG_ALWAYS1; + meta2->name_length = name_length; + meta2->name_hash = exfat_calc_name_hash(ef, name, name_length); + meta2->start_cluster = cpu_to_le32(EXFAT_CLUSTER_FREE); + + for (i = 0; i < name_entries; i++) + { + struct exfat_entry_name* name_entry; + + name_entry = (struct exfat_entry_name*) &entries[2 + i]; + name_entry->type = EXFAT_ENTRY_FILE_NAME; + name_entry->__unknown = 0; + memcpy(name_entry->name, name + i * EXFAT_ENAME_MAX, + EXFAT_ENAME_MAX * sizeof(le16_t)); + } + + meta1->checksum = exfat_calc_checksum(entries, 2 + name_entries); + rc = write_entries(ef, dir, entries, 2 + name_entries, offset); + if (rc != 0) + return rc; + + node = allocate_node(); + if (node == NULL) + return -ENOMEM; + node->entry_offset = offset; + memcpy(node->name, name, name_length * sizeof(le16_t)); + init_node_meta1(node, meta1); + init_node_meta2(node, meta2); + + tree_attach(dir, node); + return 0; +} + +static int create(struct exfat* ef, const char* path, uint16_t attrib) +{ + struct exfat_node* dir; + struct exfat_node* existing; + off_t offset = -1; + le16_t name[EXFAT_NAME_MAX + 1]; + int rc; + + rc = exfat_split(ef, &dir, &existing, name, path); + if (rc != 0) + return rc; + if (existing != NULL) + { + exfat_put_node(ef, existing); + exfat_put_node(ef, dir); + return -EEXIST; + } + + rc = find_slot(ef, dir, &offset, + 2 + DIV_ROUND_UP(utf16_length(name), EXFAT_ENAME_MAX)); + if (rc != 0) + { + exfat_put_node(ef, dir); + return rc; + } + rc = commit_entry(ef, dir, name, offset, attrib); + if (rc != 0) + { + exfat_put_node(ef, dir); + return rc; + } + exfat_update_mtime(dir); + rc = exfat_flush_node(ef, dir); + exfat_put_node(ef, dir); + return rc; +} + +int exfat_mknod(struct exfat* ef, const char* path) +{ + return create(ef, path, EXFAT_ATTRIB_ARCH); +} + +int exfat_mkdir(struct exfat* ef, const char* path) +{ + int rc; + struct exfat_node* node; + + rc = create(ef, path, EXFAT_ATTRIB_DIR); + if (rc != 0) + return rc; + rc = exfat_lookup(ef, &node, path); + if (rc != 0) + return 0; + /* directories always have at least one cluster */ + rc = exfat_truncate(ef, node, CLUSTER_SIZE(*ef->sb), true); + if (rc != 0) + { + delete(ef, node); + exfat_put_node(ef, node); + return rc; + } + rc = exfat_flush_node(ef, node); + if (rc != 0) + { + delete(ef, node); + exfat_put_node(ef, node); + return rc; + } + exfat_put_node(ef, node); + return 0; +} + +static int rename_entry(struct exfat* ef, struct exfat_node* dir, + struct exfat_node* node, const le16_t* name, off_t new_offset) +{ + const size_t name_length = utf16_length(name); + const int name_entries = DIV_ROUND_UP(name_length, EXFAT_ENAME_MAX); + struct exfat_entry entries[2 + name_entries]; + struct exfat_entry_meta1* meta1 = (struct exfat_entry_meta1*) &entries[0]; + struct exfat_entry_meta2* meta2 = (struct exfat_entry_meta2*) &entries[1]; + int rc; + int i; + + rc = read_entries(ef, node->parent, entries, 2, node->entry_offset); + if (rc != 0) + return rc; + + meta1->continuations = 1 + name_entries; + meta2->name_length = name_length; + meta2->name_hash = exfat_calc_name_hash(ef, name, name_length); + + rc = erase_node(ef, node); + if (rc != 0) + return rc; + + node->entry_offset = new_offset; + node->continuations = 1 + name_entries; + + for (i = 0; i < name_entries; i++) + { + struct exfat_entry_name* name_entry; + + name_entry = (struct exfat_entry_name*) &entries[2 + i]; + name_entry->type = EXFAT_ENTRY_FILE_NAME; + name_entry->__unknown = 0; + memcpy(name_entry->name, name + i * EXFAT_ENAME_MAX, + EXFAT_ENAME_MAX * sizeof(le16_t)); + } + + meta1->checksum = exfat_calc_checksum(entries, 2 + name_entries); + rc = write_entries(ef, dir, entries, 2 + name_entries, new_offset); + if (rc != 0) + return rc; + + memcpy(node->name, name, (EXFAT_NAME_MAX + 1) * sizeof(le16_t)); + tree_detach(node); + tree_attach(dir, node); + return 0; +} + +int exfat_rename(struct exfat* ef, const char* old_path, const char* new_path) +{ + struct exfat_node* node; + struct exfat_node* existing; + struct exfat_node* dir; + off_t offset = -1; + le16_t name[EXFAT_NAME_MAX + 1]; + int rc; + + rc = exfat_lookup(ef, &node, old_path); + if (rc != 0) + return rc; + + rc = exfat_split(ef, &dir, &existing, name, new_path); + if (rc != 0) + { + exfat_put_node(ef, node); + return rc; + } + + /* check that target is not a subdirectory of the source */ + if (node->attrib & EXFAT_ATTRIB_DIR) + { + struct exfat_node* p; + + for (p = dir; p; p = p->parent) + if (node == p) + { + if (existing != NULL) + exfat_put_node(ef, existing); + exfat_put_node(ef, dir); + exfat_put_node(ef, node); + return -EINVAL; + } + } + + if (existing != NULL) + { + /* remove target if it's not the same node as source */ + if (existing != node) + { + if (existing->attrib & EXFAT_ATTRIB_DIR) + { + if (node->attrib & EXFAT_ATTRIB_DIR) + rc = exfat_rmdir(ef, existing); + else + rc = -ENOTDIR; + } + else + { + if (!(node->attrib & EXFAT_ATTRIB_DIR)) + rc = exfat_unlink(ef, existing); + else + rc = -EISDIR; + } + exfat_put_node(ef, existing); + if (rc != 0) + { + /* free clusters even if something went wrong; overwise they + will be just lost */ + exfat_cleanup_node(ef, existing); + exfat_put_node(ef, dir); + exfat_put_node(ef, node); + return rc; + } + rc = exfat_cleanup_node(ef, existing); + if (rc != 0) + { + exfat_put_node(ef, dir); + exfat_put_node(ef, node); + return rc; + } + } + else + exfat_put_node(ef, existing); + } + + rc = find_slot(ef, dir, &offset, + 2 + DIV_ROUND_UP(utf16_length(name), EXFAT_ENAME_MAX)); + if (rc != 0) + { + exfat_put_node(ef, dir); + exfat_put_node(ef, node); + return rc; + } + rc = rename_entry(ef, dir, node, name, offset); + if (rc != 0) + { + exfat_put_node(ef, dir); + exfat_put_node(ef, node); + return rc; + } + rc = exfat_flush_node(ef, dir); + exfat_put_node(ef, dir); + exfat_put_node(ef, node); + /* node itself is not marked as dirty, no need to flush it */ + return rc; +} + +void exfat_utimes(struct exfat_node* node, const struct timespec tv[2]) +{ + node->atime = tv[0].tv_sec; + node->mtime = tv[1].tv_sec; + node->is_dirty = true; +} + +void exfat_update_atime(struct exfat_node* node) +{ + node->atime = time(NULL); + node->is_dirty = true; +} + +void exfat_update_mtime(struct exfat_node* node) +{ + node->mtime = time(NULL); + node->is_dirty = true; +} + +const char* exfat_get_label(struct exfat* ef) +{ + return ef->label; +} + +static int find_label(struct exfat* ef, off_t* offset) +{ + struct exfat_entry entry; + int rc; + + for (*offset = 0; ; *offset += sizeof(entry)) + { + rc = read_entries(ef, ef->root, &entry, 1, *offset); + if (rc != 0) + return rc; + + if (entry.type == EXFAT_ENTRY_LABEL) + return 0; + } +} + +int exfat_set_label(struct exfat* ef, const char* label) +{ + le16_t label_utf16[EXFAT_ENAME_MAX + 1]; + int rc; + off_t offset; + struct exfat_entry_label entry; + + memset(label_utf16, 0, sizeof(label_utf16)); + rc = utf8_to_utf16(label_utf16, label, EXFAT_ENAME_MAX + 1, strlen(label)); + if (rc != 0) + return rc; + + rc = find_label(ef, &offset); + if (rc == -ENOENT) + rc = find_slot(ef, ef->root, &offset, 1); + if (rc != 0) + return rc; + + entry.type = EXFAT_ENTRY_LABEL; + entry.length = utf16_length(label_utf16); + memcpy(entry.name, label_utf16, sizeof(entry.name)); + if (entry.length == 0) + entry.type ^= EXFAT_ENTRY_VALID; + + rc = write_entries(ef, ef->root, (struct exfat_entry*) &entry, 1, offset); + if (rc != 0) + return rc; + + strcpy(ef->label, label); + return 0; +} diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/platform.h b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/platform.h new file mode 100644 index 0000000..9ab3155 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/platform.h @@ -0,0 +1,63 @@ +/* + platform.h (14.05.13) + OS-specific code (libc-specific in fact). Note that systems with the + same kernel can use different libc implementations. + + Free exFAT implementation. + Copyright (C) 2010-2018 Andrew Nayenko + + 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. +*/ + +#ifndef PLATFORM_H_INCLUDED +#define PLATFORM_H_INCLUDED + +#if defined(__linux__) || defined(__GLIBC__) || defined(__GNU__) + +#include +#include +#define exfat_bswap16(x) bswap_16(x) +#define exfat_bswap32(x) bswap_32(x) +#define exfat_bswap64(x) bswap_64(x) +#define EXFAT_BYTE_ORDER __BYTE_ORDER +#define EXFAT_LITTLE_ENDIAN __LITTLE_ENDIAN +#define EXFAT_BIG_ENDIAN __BIG_ENDIAN + +#elif defined(__APPLE__) + +#include +#include +#define exfat_bswap16(x) OSSwapInt16(x) +#define exfat_bswap32(x) OSSwapInt32(x) +#define exfat_bswap64(x) OSSwapInt64(x) +#define EXFAT_BYTE_ORDER BYTE_ORDER +#define EXFAT_LITTLE_ENDIAN LITTLE_ENDIAN +#define EXFAT_BIG_ENDIAN BIG_ENDIAN + +#elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__) || defined(__OpenBSD__) + +#include +#define exfat_bswap16(x) bswap16(x) +#define exfat_bswap32(x) bswap32(x) +#define exfat_bswap64(x) bswap64(x) +#define EXFAT_BYTE_ORDER _BYTE_ORDER +#define EXFAT_LITTLE_ENDIAN _LITTLE_ENDIAN +#define EXFAT_BIG_ENDIAN _BIG_ENDIAN + +#else +#error Unknown platform +#endif + +#endif /* ifndef PLATFORM_H_INCLUDED */ diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/repair.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/repair.c new file mode 100644 index 0000000..620ad52 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/repair.c @@ -0,0 +1,103 @@ +/* + repair.c (09.03.17) + exFAT file system implementation library. + + Free exFAT implementation. + Copyright (C) 2010-2018 Andrew Nayenko + + 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. +*/ + +#include "exfat.h" +#include + +int exfat_errors_fixed; + +bool exfat_ask_to_fix(const struct exfat* ef) +{ + const char* question = "Fix (Y/N)?"; + char answer[8]; + bool yeah, nope; + + switch (ef->repair) + { + case EXFAT_REPAIR_NO: + return false; + case EXFAT_REPAIR_YES: + printf("%s %s", question, "Y\n"); + return true; + case EXFAT_REPAIR_ASK: + do + { + printf("%s ", question); + fflush(stdout); + if (fgets(answer, sizeof(answer), stdin)) + { + yeah = strcasecmp(answer, "Y\n") == 0; + nope = strcasecmp(answer, "N\n") == 0; + } + else + { + yeah = false; + nope = true; + } + } + while (!yeah && !nope); + return yeah; + } + exfat_bug("invalid repair option value: %d", ef->repair); + return false; +} + +bool exfat_fix_invalid_vbr_checksum(const struct exfat* ef, void* sector, + uint32_t vbr_checksum) +{ + size_t i; + off_t sector_size = SECTOR_SIZE(*ef->sb); + + for (i = 0; i < sector_size / sizeof(vbr_checksum); i++) + ((le32_t*) sector)[i] = cpu_to_le32(vbr_checksum); + if (exfat_pwrite(ef->dev, sector, sector_size, 11 * sector_size) < 0) + { + exfat_error("failed to write correct VBR checksum"); + return false; + } + exfat_errors_fixed++; + return true; +} + +bool exfat_fix_invalid_node_checksum(const struct exfat* ef, + struct exfat_node* node) +{ + /* checksum will be rewritten by exfat_flush_node() */ + node->is_dirty = true; + + exfat_errors_fixed++; + return true; +} + +bool exfat_fix_unknown_entry(struct exfat* ef, struct exfat_node* dir, + const struct exfat_entry* entry, off_t offset) +{ + struct exfat_entry deleted = *entry; + + deleted.type &= ~EXFAT_ENTRY_VALID; + if (exfat_generic_pwrite(ef, dir, &deleted, sizeof(struct exfat_entry), + offset) != sizeof(struct exfat_entry)) + return false; + + exfat_errors_fixed++; + return true; +} diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/time.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/time.c new file mode 100644 index 0000000..31ae5a2 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/time.c @@ -0,0 +1,164 @@ +/* + time.c (03.02.12) + exFAT file system implementation library. + + Free exFAT implementation. + Copyright (C) 2010-2018 Andrew Nayenko + + 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. +*/ + +#include "exfat.h" + +/* timezone offset from UTC in seconds; positive for western timezones, + negative for eastern ones */ +static long exfat_timezone; + +#define SEC_IN_MIN 60ll +#define SEC_IN_HOUR (60 * SEC_IN_MIN) +#define SEC_IN_DAY (24 * SEC_IN_HOUR) +#define SEC_IN_YEAR (365 * SEC_IN_DAY) /* not leap year */ +/* Unix epoch started at 0:00:00 UTC 1 January 1970 */ +#define UNIX_EPOCH_YEAR 1970 +/* exFAT epoch started at 0:00:00 UTC 1 January 1980 */ +#define EXFAT_EPOCH_YEAR 1980 +/* number of years from Unix epoch to exFAT epoch */ +#define EPOCH_DIFF_YEAR (EXFAT_EPOCH_YEAR - UNIX_EPOCH_YEAR) +/* number of days from Unix epoch to exFAT epoch (considering leap days) */ +#define EPOCH_DIFF_DAYS (EPOCH_DIFF_YEAR * 365 + EPOCH_DIFF_YEAR / 4) +/* number of seconds from Unix epoch to exFAT epoch (considering leap days) */ +#define EPOCH_DIFF_SEC (EPOCH_DIFF_DAYS * SEC_IN_DAY) +/* number of leap years passed from exFAT epoch to the specified year + (excluding the specified year itself) */ +#define LEAP_YEARS(year) ((EXFAT_EPOCH_YEAR + (year) - 1) / 4 \ + - (EXFAT_EPOCH_YEAR - 1) / 4) +/* checks whether the specified year is leap */ +#define IS_LEAP_YEAR(year) ((EXFAT_EPOCH_YEAR + (year)) % 4 == 0) + +static const time_t days_in_year[] = +{ + /* Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec */ + 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 +}; + +time_t exfat_exfat2unix(le16_t date, le16_t time, uint8_t centisec) +{ + time_t unix_time = EPOCH_DIFF_SEC; + uint16_t ndate = le16_to_cpu(date); + uint16_t ntime = le16_to_cpu(time); + + uint16_t day = ndate & 0x1f; /* 5 bits, 1-31 */ + uint16_t month = ndate >> 5 & 0xf; /* 4 bits, 1-12 */ + uint16_t year = ndate >> 9; /* 7 bits, 1-127 (+1980) */ + + uint16_t twosec = ntime & 0x1f; /* 5 bits, 0-29 (2 sec granularity) */ + uint16_t min = ntime >> 5 & 0x3f; /* 6 bits, 0-59 */ + uint16_t hour = ntime >> 11; /* 5 bits, 0-23 */ + + if (day == 0 || month == 0 || month > 12) + { + exfat_error("bad date %u-%02hu-%02hu", + year + EXFAT_EPOCH_YEAR, month, day); + return 0; + } + if (hour > 23 || min > 59 || twosec > 29) + { + exfat_error("bad time %hu:%02hu:%02u", + hour, min, twosec * 2); + return 0; + } + if (centisec > 199) + { + exfat_error("bad centiseconds count %hhu", centisec); + return 0; + } + + /* every 4th year between 1904 and 2096 is leap */ + unix_time += year * SEC_IN_YEAR + LEAP_YEARS(year) * SEC_IN_DAY; + unix_time += days_in_year[month] * SEC_IN_DAY; + /* if it's leap year and February has passed we should add 1 day */ + if ((EXFAT_EPOCH_YEAR + year) % 4 == 0 && month > 2) + unix_time += SEC_IN_DAY; + unix_time += (day - 1) * SEC_IN_DAY; + + unix_time += hour * SEC_IN_HOUR; + unix_time += min * SEC_IN_MIN; + /* exFAT represents time with 2 sec granularity */ + unix_time += twosec * 2; + unix_time += centisec / 100; + + /* exFAT stores timestamps in local time, so we correct it to UTC */ + unix_time += exfat_timezone; + + return unix_time; +} + +void exfat_unix2exfat(time_t unix_time, le16_t* date, le16_t* time, + uint8_t* centisec) +{ + time_t shift = EPOCH_DIFF_SEC + exfat_timezone; + uint16_t day, month, year; + uint16_t twosec, min, hour; + int days; + int i; + + /* time before exFAT epoch cannot be represented */ + if (unix_time < shift) + unix_time = shift; + + unix_time -= shift; + + days = unix_time / SEC_IN_DAY; + year = (4 * days) / (4 * 365 + 1); + days -= year * 365 + LEAP_YEARS(year); + month = 0; + for (i = 1; i <= 12; i++) + { + int leap_day = (IS_LEAP_YEAR(year) && i == 2); + int leap_sub = (IS_LEAP_YEAR(year) && i >= 3); + + if (i == 12 || days - leap_sub < days_in_year[i + 1] + leap_day) + { + month = i; + days -= days_in_year[i] + leap_sub; + break; + } + } + day = days + 1; + + hour = (unix_time % SEC_IN_DAY) / SEC_IN_HOUR; + min = (unix_time % SEC_IN_HOUR) / SEC_IN_MIN; + twosec = (unix_time % SEC_IN_MIN) / 2; + + *date = cpu_to_le16(day | (month << 5) | (year << 9)); + *time = cpu_to_le16(twosec | (min << 5) | (hour << 11)); + if (centisec) + *centisec = (unix_time % 2) * 100; +} + +void exfat_tzset(void) +{ + time_t now; + struct tm* utc; + + tzset(); + now = time(NULL); + utc = gmtime(&now); + /* gmtime() always sets tm_isdst to 0 because daylight savings never + affect UTC. Setting tm_isdst to -1 makes mktime() to determine whether + summer time is in effect. */ + utc->tm_isdst = -1; + exfat_timezone = mktime(utc) - now; +} diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/utf.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/utf.c new file mode 100644 index 0000000..0d0018c --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/utf.c @@ -0,0 +1,245 @@ +/* + utf.c (13.09.09) + exFAT file system implementation library. + + Free exFAT implementation. + Copyright (C) 2010-2018 Andrew Nayenko + + 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. +*/ + +#include "exfat.h" +#include + +static char* wchar_to_utf8(char* output, wchar_t wc, size_t outsize) +{ + if (wc <= 0x7f) + { + if (outsize < 1) + return NULL; + *output++ = (char) wc; + } + else if (wc <= 0x7ff) + { + if (outsize < 2) + return NULL; + *output++ = 0xc0 | (wc >> 6); + *output++ = 0x80 | (wc & 0x3f); + } + else if (wc <= 0xffff) + { + if (outsize < 3) + return NULL; + *output++ = 0xe0 | (wc >> 12); + *output++ = 0x80 | ((wc >> 6) & 0x3f); + *output++ = 0x80 | (wc & 0x3f); + } + else if (wc <= 0x1fffff) + { + if (outsize < 4) + return NULL; + *output++ = 0xf0 | (wc >> 18); + *output++ = 0x80 | ((wc >> 12) & 0x3f); + *output++ = 0x80 | ((wc >> 6) & 0x3f); + *output++ = 0x80 | (wc & 0x3f); + } + else if (wc <= 0x3ffffff) + { + if (outsize < 5) + return NULL; + *output++ = 0xf8 | (wc >> 24); + *output++ = 0x80 | ((wc >> 18) & 0x3f); + *output++ = 0x80 | ((wc >> 12) & 0x3f); + *output++ = 0x80 | ((wc >> 6) & 0x3f); + *output++ = 0x80 | (wc & 0x3f); + } + else if (wc <= 0x7fffffff) + { + if (outsize < 6) + return NULL; + *output++ = 0xfc | (wc >> 30); + *output++ = 0x80 | ((wc >> 24) & 0x3f); + *output++ = 0x80 | ((wc >> 18) & 0x3f); + *output++ = 0x80 | ((wc >> 12) & 0x3f); + *output++ = 0x80 | ((wc >> 6) & 0x3f); + *output++ = 0x80 | (wc & 0x3f); + } + else + return NULL; + + return output; +} + +static const le16_t* utf16_to_wchar(const le16_t* input, wchar_t* wc, + size_t insize) +{ + if ((le16_to_cpu(input[0]) & 0xfc00) == 0xd800) + { + if (insize < 2 || (le16_to_cpu(input[1]) & 0xfc00) != 0xdc00) + return NULL; + *wc = ((wchar_t) (le16_to_cpu(input[0]) & 0x3ff) << 10); + *wc |= (le16_to_cpu(input[1]) & 0x3ff); + *wc += 0x10000; + return input + 2; + } + else + { + *wc = le16_to_cpu(*input); + return input + 1; + } +} + +int utf16_to_utf8(char* output, const le16_t* input, size_t outsize, + size_t insize) +{ + const le16_t* inp = input; + char* outp = output; + wchar_t wc; + + while (inp - input < insize) + { + inp = utf16_to_wchar(inp, &wc, insize - (inp - input)); + if (inp == NULL) + { + exfat_error("illegal UTF-16 sequence"); + return -EILSEQ; + } + outp = wchar_to_utf8(outp, wc, outsize - (outp - output)); + if (outp == NULL) + { + exfat_error("name is too long"); + return -ENAMETOOLONG; + } + if (wc == 0) + return 0; + } + if (outp - output >= outsize) + { + exfat_error("name is too long"); + return -ENAMETOOLONG; + } + *outp = '\0'; + return 0; +} + +static const char* utf8_to_wchar(const char* input, wchar_t* wc, + size_t insize) +{ + if ((input[0] & 0x80) == 0 && insize >= 1) + { + *wc = (wchar_t) input[0]; + return input + 1; + } + if ((input[0] & 0xe0) == 0xc0 && insize >= 2) + { + *wc = (((wchar_t) input[0] & 0x1f) << 6) | + ((wchar_t) input[1] & 0x3f); + return input + 2; + } + if ((input[0] & 0xf0) == 0xe0 && insize >= 3) + { + *wc = (((wchar_t) input[0] & 0x0f) << 12) | + (((wchar_t) input[1] & 0x3f) << 6) | + ((wchar_t) input[2] & 0x3f); + return input + 3; + } + if ((input[0] & 0xf8) == 0xf0 && insize >= 4) + { + *wc = (((wchar_t) input[0] & 0x07) << 18) | + (((wchar_t) input[1] & 0x3f) << 12) | + (((wchar_t) input[2] & 0x3f) << 6) | + ((wchar_t) input[3] & 0x3f); + return input + 4; + } + if ((input[0] & 0xfc) == 0xf8 && insize >= 5) + { + *wc = (((wchar_t) input[0] & 0x03) << 24) | + (((wchar_t) input[1] & 0x3f) << 18) | + (((wchar_t) input[2] & 0x3f) << 12) | + (((wchar_t) input[3] & 0x3f) << 6) | + ((wchar_t) input[4] & 0x3f); + return input + 5; + } + if ((input[0] & 0xfe) == 0xfc && insize >= 6) + { + *wc = (((wchar_t) input[0] & 0x01) << 30) | + (((wchar_t) input[1] & 0x3f) << 24) | + (((wchar_t) input[2] & 0x3f) << 18) | + (((wchar_t) input[3] & 0x3f) << 12) | + (((wchar_t) input[4] & 0x3f) << 6) | + ((wchar_t) input[5] & 0x3f); + return input + 6; + } + return NULL; +} + +static le16_t* wchar_to_utf16(le16_t* output, wchar_t wc, size_t outsize) +{ + if (wc <= 0xffff) /* if character is from BMP */ + { + if (outsize == 0) + return NULL; + output[0] = cpu_to_le16(wc); + return output + 1; + } + if (outsize < 2) + return NULL; + wc -= 0x10000; + output[0] = cpu_to_le16(0xd800 | ((wc >> 10) & 0x3ff)); + output[1] = cpu_to_le16(0xdc00 | (wc & 0x3ff)); + return output + 2; +} + +int utf8_to_utf16(le16_t* output, const char* input, size_t outsize, + size_t insize) +{ + const char* inp = input; + le16_t* outp = output; + wchar_t wc; + + while (inp - input < insize) + { + inp = utf8_to_wchar(inp, &wc, insize - (inp - input)); + if (inp == NULL) + { + exfat_error("illegal UTF-8 sequence"); + return -EILSEQ; + } + outp = wchar_to_utf16(outp, wc, outsize - (outp - output)); + if (outp == NULL) + { + exfat_error("name is too long"); + return -ENAMETOOLONG; + } + if (wc == 0) + break; + } + if (outp - output >= outsize) + { + exfat_error("name is too long"); + return -ENAMETOOLONG; + } + *outp = cpu_to_le16(0); + return 0; +} + +size_t utf16_length(const le16_t* str) +{ + size_t i = 0; + + while (le16_to_cpu(str[i])) + i++; + return i; +} diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/utils.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/utils.c new file mode 100644 index 0000000..7baa663 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/utils.c @@ -0,0 +1,180 @@ +/* + utils.c (04.09.09) + exFAT file system implementation library. + + Free exFAT implementation. + Copyright (C) 2010-2018 Andrew Nayenko + + 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. +*/ + +#include "exfat.h" +#include +#include +#include + +void exfat_stat(const struct exfat* ef, const struct exfat_node* node, + struct stat* stbuf) +{ + memset(stbuf, 0, sizeof(struct stat)); + if (node->attrib & EXFAT_ATTRIB_DIR) + stbuf->st_mode = S_IFDIR | (0777 & ~ef->dmask); + else + stbuf->st_mode = S_IFREG | (0777 & ~ef->fmask); + stbuf->st_nlink = 1; + stbuf->st_uid = ef->uid; + stbuf->st_gid = ef->gid; + stbuf->st_size = node->size; + stbuf->st_blocks = ROUND_UP(node->size, CLUSTER_SIZE(*ef->sb)) / 512; + stbuf->st_mtime = node->mtime; + stbuf->st_atime = node->atime; + /* set ctime to mtime to ensure we don't break programs that rely on ctime + (e.g. rsync) */ + stbuf->st_ctime = node->mtime; +} + +void exfat_get_name(const struct exfat_node* node, + char buffer[EXFAT_UTF8_NAME_BUFFER_MAX]) +{ + if (utf16_to_utf8(buffer, node->name, EXFAT_UTF8_NAME_BUFFER_MAX, + EXFAT_NAME_MAX) != 0) + exfat_bug("failed to convert name to UTF-8"); +} + +static uint16_t add_checksum_byte(uint16_t sum, uint8_t byte) +{ + return ((sum << 15) | (sum >> 1)) + byte; +} + +static uint16_t add_checksum_bytes(uint16_t sum, const void* buffer, size_t n) +{ + int i; + + for (i = 0; i < n; i++) + sum = add_checksum_byte(sum, ((const uint8_t*) buffer)[i]); + return sum; +} + +uint16_t exfat_start_checksum(const struct exfat_entry_meta1* entry) +{ + uint16_t sum = 0; + int i; + + for (i = 0; i < sizeof(struct exfat_entry); i++) + if (i != 2 && i != 3) /* skip checksum field itself */ + sum = add_checksum_byte(sum, ((const uint8_t*) entry)[i]); + return sum; +} + +uint16_t exfat_add_checksum(const void* entry, uint16_t sum) +{ + return add_checksum_bytes(sum, entry, sizeof(struct exfat_entry)); +} + +le16_t exfat_calc_checksum(const struct exfat_entry* entries, int n) +{ + uint16_t checksum; + int i; + + checksum = exfat_start_checksum((const struct exfat_entry_meta1*) entries); + for (i = 1; i < n; i++) + checksum = exfat_add_checksum(entries + i, checksum); + return cpu_to_le16(checksum); +} + +uint32_t exfat_vbr_start_checksum(const void* sector, size_t size) +{ + size_t i; + uint32_t sum = 0; + + for (i = 0; i < size; i++) + /* skip volume_state and allocated_percent fields */ + if (i != 0x6a && i != 0x6b && i != 0x70) + sum = ((sum << 31) | (sum >> 1)) + ((const uint8_t*) sector)[i]; + return sum; +} + +uint32_t exfat_vbr_add_checksum(const void* sector, size_t size, uint32_t sum) +{ + size_t i; + + for (i = 0; i < size; i++) + sum = ((sum << 31) | (sum >> 1)) + ((const uint8_t*) sector)[i]; + return sum; +} + +le16_t exfat_calc_name_hash(const struct exfat* ef, const le16_t* name, + size_t length) +{ + size_t i; + uint16_t hash = 0; + + for (i = 0; i < length; i++) + { + uint16_t c = le16_to_cpu(name[i]); + + /* convert to upper case */ + c = ef->upcase[c]; + + hash = ((hash << 15) | (hash >> 1)) + (c & 0xff); + hash = ((hash << 15) | (hash >> 1)) + (c >> 8); + } + return cpu_to_le16(hash); +} + +void exfat_humanize_bytes(uint64_t value, struct exfat_human_bytes* hb) +{ + size_t i; + /* 16 EB (minus 1 byte) is the largest size that can be represented by + uint64_t */ + const char* units[] = {"bytes", "KB", "MB", "GB", "TB", "PB", "EB"}; + uint64_t divisor = 1; + uint64_t temp = 0; + + for (i = 0; ; i++, divisor *= 1024) + { + temp = (value + divisor / 2) / divisor; + + if (temp == 0) + break; + if (temp / 1024 * 1024 == temp) + continue; + if (temp < 10240) + break; + } + hb->value = temp; + hb->unit = units[i]; +} + +void exfat_print_info(const struct exfat_super_block* sb, + uint32_t free_clusters) +{ + struct exfat_human_bytes hb; + off_t total_space = le64_to_cpu(sb->sector_count) * SECTOR_SIZE(*sb); + off_t avail_space = (off_t) free_clusters * CLUSTER_SIZE(*sb); + + printf("File system version %hhu.%hhu\n", + sb->version.major, sb->version.minor); + exfat_humanize_bytes(SECTOR_SIZE(*sb), &hb); + printf("Sector size %10"PRIu64" %s\n", hb.value, hb.unit); + exfat_humanize_bytes(CLUSTER_SIZE(*sb), &hb); + printf("Cluster size %10"PRIu64" %s\n", hb.value, hb.unit); + exfat_humanize_bytes(total_space, &hb); + printf("Volume size %10"PRIu64" %s\n", hb.value, hb.unit); + exfat_humanize_bytes(total_space - avail_space, &hb); + printf("Used space %10"PRIu64" %s\n", hb.value, hb.unit); + exfat_humanize_bytes(avail_space, &hb); + printf("Available space %10"PRIu64" %s\n", hb.value, hb.unit); +} diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/cbm.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/cbm.c new file mode 100644 index 0000000..ad5accc --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/cbm.c @@ -0,0 +1,79 @@ +/* + cbm.c (09.11.10) + Clusters Bitmap creation code. + + Free exFAT implementation. + Copyright (C) 2011-2018 Andrew Nayenko + + 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. +*/ + +#include "cbm.h" +#include "fat.h" +#include "uct.h" +#include "rootdir.h" +#include +#include + +static off_t cbm_alignment(void) +{ + return get_cluster_size(); +} + +static off_t cbm_size(void) +{ + return DIV_ROUND_UP( + (get_volume_size() - get_position(&cbm)) / get_cluster_size(), + CHAR_BIT); +} + +static int cbm_write(struct exfat_dev* dev) +{ + uint32_t allocated_clusters = + DIV_ROUND_UP(cbm.get_size(), get_cluster_size()) + + DIV_ROUND_UP(uct.get_size(), get_cluster_size()) + + DIV_ROUND_UP(rootdir.get_size(), get_cluster_size()); + size_t bitmap_size = ROUND_UP(allocated_clusters, CHAR_BIT); + bitmap_t* bitmap = malloc(BMAP_SIZE(bitmap_size)); + size_t i; + + if (bitmap == NULL) + { + exfat_error("failed to allocate bitmap of %zu bytes", + BMAP_SIZE(bitmap_size)); + return 1; + } + memset(bitmap, 0, BMAP_SIZE(bitmap_size)); + + for (i = 0; i < bitmap_size; i++) + if (i < allocated_clusters) + BMAP_SET(bitmap, i); + if (exfat_write(dev, bitmap, bitmap_size / CHAR_BIT) < 0) + { + free(bitmap); + exfat_error("failed to write bitmap of %zu bytes", + bitmap_size / CHAR_BIT); + return 1; + } + free(bitmap); + return 0; +} + +const struct fs_object cbm = +{ + .get_alignment = cbm_alignment, + .get_size = cbm_size, + .write = cbm_write, +}; diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/cbm.h b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/cbm.h new file mode 100644 index 0000000..3803b79 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/cbm.h @@ -0,0 +1,30 @@ +/* + cbm.h (09.11.10) + Clusters Bitmap creation code. + + Free exFAT implementation. + Copyright (C) 2011-2018 Andrew Nayenko + + 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. +*/ + +#ifndef MKFS_CBM_H_INCLUDED +#define MKFS_CBM_H_INCLUDED + +#include "mkexfat.h" + +extern const struct fs_object cbm; + +#endif /* ifndef MKFS_CBM_H_INCLUDED */ diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/fat.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/fat.c new file mode 100644 index 0000000..c5174a7 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/fat.c @@ -0,0 +1,88 @@ +/* + fat.c (09.11.10) + File Allocation Table creation code. + + Free exFAT implementation. + Copyright (C) 2011-2018 Andrew Nayenko + + 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. +*/ + +#include "fat.h" +#include "cbm.h" +#include "uct.h" +#include "rootdir.h" +#include + +static off_t fat_alignment(void) +{ + return (off_t) 128 * get_sector_size(); +} + +static off_t fat_size(void) +{ + return get_volume_size() / get_cluster_size() * sizeof(cluster_t); +} + +static cluster_t fat_write_entry(struct exfat_dev* dev, cluster_t cluster, + cluster_t value) +{ + le32_t fat_entry = cpu_to_le32(value); + if (exfat_write(dev, &fat_entry, sizeof(fat_entry)) < 0) + { + exfat_error("failed to write FAT entry 0x%x", value); + return 0; + } + return cluster + 1; +} + +static cluster_t fat_write_entries(struct exfat_dev* dev, cluster_t cluster, + uint64_t length) +{ + cluster_t end = cluster + DIV_ROUND_UP(length, get_cluster_size()); + + while (cluster < end - 1) + { + cluster = fat_write_entry(dev, cluster, cluster + 1); + if (cluster == 0) + return 0; + } + return fat_write_entry(dev, cluster, EXFAT_CLUSTER_END); +} + +static int fat_write(struct exfat_dev* dev) +{ + cluster_t c = 0; + + if (!(c = fat_write_entry(dev, c, 0xfffffff8))) /* media type */ + return 1; + if (!(c = fat_write_entry(dev, c, 0xffffffff))) /* some weird constant */ + return 1; + if (!(c = fat_write_entries(dev, c, cbm.get_size()))) + return 1; + if (!(c = fat_write_entries(dev, c, uct.get_size()))) + return 1; + if (!(c = fat_write_entries(dev, c, rootdir.get_size()))) + return 1; + + return 0; +} + +const struct fs_object fat = +{ + .get_alignment = fat_alignment, + .get_size = fat_size, + .write = fat_write, +}; diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/fat.h b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/fat.h new file mode 100644 index 0000000..fbecaa2 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/fat.h @@ -0,0 +1,30 @@ +/* + fat.h (09.11.10) + File Allocation Table creation code. + + Free exFAT implementation. + Copyright (C) 2011-2018 Andrew Nayenko + + 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. +*/ + +#ifndef MKFS_FAT_H_INCLUDED +#define MKFS_FAT_H_INCLUDED + +#include "mkexfat.h" + +extern const struct fs_object fat; + +#endif /* ifndef MKFS_FAT_H_INCLUDED */ diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.c new file mode 100644 index 0000000..10ecf23 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.c @@ -0,0 +1,167 @@ +/* + mkexfat.c (22.04.12) + FS creation engine. + + Free exFAT implementation. + Copyright (C) 2011-2018 Andrew Nayenko + + 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. +*/ + +#include "mkexfat.h" +#include +#include +#include +#include +#include + +static int check_size(off_t volume_size) +{ + const struct fs_object** pp; + off_t position = 0; + + for (pp = objects; *pp; pp++) + { + position = ROUND_UP(position, (*pp)->get_alignment()); + position += (*pp)->get_size(); + } + + if (position > volume_size) + { + struct exfat_human_bytes vhb; + + exfat_humanize_bytes(volume_size, &vhb); + exfat_error("too small device (%"PRIu64" %s)", vhb.value, vhb.unit); + return 1; + } + + return 0; + +} + +static int erase_object(struct exfat_dev* dev, const void* block, + size_t block_size, off_t start, off_t size) +{ + const off_t block_count = DIV_ROUND_UP(size, block_size); + off_t i; + + if (exfat_seek(dev, start, SEEK_SET) == (off_t) -1) + { + exfat_error("seek to 0x%"PRIx64" failed", start); + return 1; + } + for (i = 0; i < size; i += block_size) + { + if (exfat_write(dev, block, MIN(size - i, block_size)) < 0) + { + exfat_error("failed to erase block %"PRIu64"/%"PRIu64 + " at 0x%"PRIx64, i + 1, block_count, start); + return 1; + } + } + return 0; +} + +static int erase(struct exfat_dev* dev) +{ + const struct fs_object** pp; + off_t position = 0; + const size_t block_size = 1024 * 1024; + void* block = malloc(block_size); + + if (block == NULL) + { + exfat_error("failed to allocate erase block of %zu bytes", block_size); + return 1; + } + memset(block, 0, block_size); + + for (pp = objects; *pp; pp++) + { + position = ROUND_UP(position, (*pp)->get_alignment()); + if (erase_object(dev, block, block_size, position, + (*pp)->get_size()) != 0) + { + free(block); + return 1; + } + position += (*pp)->get_size(); + } + + free(block); + return 0; +} + +static int create(struct exfat_dev* dev) +{ + const struct fs_object** pp; + off_t position = 0; + + for (pp = objects; *pp; pp++) + { + position = ROUND_UP(position, (*pp)->get_alignment()); + if (exfat_seek(dev, position, SEEK_SET) == (off_t) -1) + { + exfat_error("seek to 0x%"PRIx64" failed", position); + return 1; + } + if ((*pp)->write(dev) != 0) + return 1; + position += (*pp)->get_size(); + } + return 0; +} + +int mkfs(struct exfat_dev* dev, off_t volume_size) +{ + if (check_size(volume_size) != 0) + return 1; + + exfat_debug("Creating... "); + //fputs("Creating... ", stdout); + //fflush(stdout); + if (erase(dev) != 0) + return 1; + if (create(dev) != 0) + return 1; + //puts("done."); + + //fputs("Flushing... ", stdout); + //fflush(stdout); + exfat_debug("Flushing... "); + if (exfat_fsync(dev) != 0) + return 1; + //puts("done."); + + return 0; +} + +off_t get_position(const struct fs_object* object) +{ + const struct fs_object** pp; + off_t position = 0; + + for (pp = objects; *pp; pp++) + { + position = ROUND_UP(position, (*pp)->get_alignment()); + if (*pp == object) + return position; + position += (*pp)->get_size(); + } + exfat_bug("unknown object"); + + return 0; +} + diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.h b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.h new file mode 100644 index 0000000..54816af --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.h @@ -0,0 +1,49 @@ +/* + mkexfat.h (09.11.10) + FS creation engine. + + Free exFAT implementation. + Copyright (C) 2011-2018 Andrew Nayenko + + 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. +*/ + +#ifndef MKFS_MKEXFAT_H_INCLUDED +#define MKFS_MKEXFAT_H_INCLUDED + +#include "exfat.h" + +struct fs_object +{ + off_t (*get_alignment)(void); + off_t (*get_size)(void); + int (*write)(struct exfat_dev* dev); +}; + +extern const struct fs_object* objects[]; + +int get_sector_bits(void); +int get_spc_bits(void); +off_t get_volume_size(void); +const le16_t* get_volume_label(void); +uint32_t get_volume_serial(void); +uint64_t get_first_sector(void); +int get_sector_size(void); +int get_cluster_size(void); + +int mkfs(struct exfat_dev* dev, off_t volume_size); +off_t get_position(const struct fs_object* object); + +#endif /* ifndef MKFS_MKEXFAT_H_INCLUDED */ diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat_main.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat_main.c new file mode 100644 index 0000000..c65035f --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat_main.c @@ -0,0 +1,268 @@ +/* + main.c (15.08.10) + Creates exFAT file system. + + Free exFAT implementation. + Copyright (C) 2011-2018 Andrew Nayenko + + 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. +*/ + +#include "mkexfat.h" +#include "vbr.h" +#include "fat.h" +#include "cbm.h" +#include "uct.h" +#include "rootdir.h" +#include "exfat.h" +#include +#include +#include +#include +#include +#include +#include + +const struct fs_object* objects[] = +{ + &vbr, + &vbr, + &fat, + /* clusters heap */ + &cbm, + &uct, + &rootdir, + NULL, +}; + +static struct +{ + int sector_bits; + int spc_bits; + off_t volume_size; + le16_t volume_label[EXFAT_ENAME_MAX + 1]; + uint32_t volume_serial; + uint64_t first_sector; +} +param; + +extern int g_vtoy_exfat_disk_fd; +extern uint64_t g_vtoy_exfat_part_size; + +int get_sector_bits(void) +{ + return param.sector_bits; +} + +int get_spc_bits(void) +{ + return param.spc_bits; +} + +off_t get_volume_size(void) +{ + return param.volume_size; +} + +const le16_t* get_volume_label(void) +{ + return param.volume_label; +} + +uint32_t get_volume_serial(void) +{ + return param.volume_serial; +} + +uint64_t get_first_sector(void) +{ + return param.first_sector; +} + +int get_sector_size(void) +{ + return 1 << get_sector_bits(); +} + +int get_cluster_size(void) +{ + return get_sector_size() << get_spc_bits(); +} + +static int setup_spc_bits(int sector_bits, int user_defined, off_t volume_size) +{ + int i; + + if (user_defined != -1) + { + off_t cluster_size = 1 << sector_bits << user_defined; + if (volume_size / cluster_size > EXFAT_LAST_DATA_CLUSTER) + { + struct exfat_human_bytes chb, vhb; + + exfat_humanize_bytes(cluster_size, &chb); + exfat_humanize_bytes(volume_size, &vhb); + exfat_error("cluster size %"PRIu64" %s is too small for " + "%"PRIu64" %s volume, try -s %d", + chb.value, chb.unit, + vhb.value, vhb.unit, + 1 << setup_spc_bits(sector_bits, -1, volume_size)); + return -1; + } + return user_defined; + } + + if (volume_size < 256ull * 1024 * 1024) + return MAX(0, 12 - sector_bits); /* 4 KB */ + if (volume_size < 32ull * 1024 * 1024 * 1024) + return MAX(0, 15 - sector_bits); /* 32 KB */ + + for (i = 17; ; i++) /* 128 KB or more */ + if (DIV_ROUND_UP(volume_size, 1 << i) <= EXFAT_LAST_DATA_CLUSTER) + return MAX(0, i - sector_bits); +} + +static int setup_volume_label(le16_t label[EXFAT_ENAME_MAX + 1], const char* s) +{ + memset(label, 0, (EXFAT_ENAME_MAX + 1) * sizeof(le16_t)); + if (s == NULL) + return 0; + return utf8_to_utf16(label, s, EXFAT_ENAME_MAX + 1, strlen(s)); +} + +static uint32_t setup_volume_serial(uint32_t user_defined) +{ + struct timeval now; + + if (user_defined != 0) + return user_defined; + + if (gettimeofday(&now, NULL) != 0) + { + exfat_error("failed to form volume id"); + return 0; + } + return (now.tv_sec << 20) | now.tv_usec; +} + +static int setup(struct exfat_dev* dev, int sector_bits, int spc_bits, + const char* volume_label, uint32_t volume_serial, + uint64_t first_sector) +{ + param.sector_bits = sector_bits; + param.first_sector = first_sector; + param.volume_size = exfat_get_size(dev); + + param.spc_bits = setup_spc_bits(sector_bits, spc_bits, param.volume_size); + if (param.spc_bits == -1) + return 1; + + if (setup_volume_label(param.volume_label, volume_label) != 0) + return 1; + + param.volume_serial = setup_volume_serial(volume_serial); + if (param.volume_serial == 0) + return 1; + + return mkfs(dev, param.volume_size); +} + +static int logarithm2(int n) +{ + int i; + + for (i = 0; i < sizeof(int) * CHAR_BIT - 1; i++) + if ((1 << i) == n) + return i; + return -1; +} + +static void usage(const char* prog) +{ + fprintf(stderr, "Usage: %s [-i volume-id] [-n label] " + "[-p partition-first-sector] " + "[-s sectors-per-cluster] [-V] \n", prog); + exit(1); +} + +int mkexfat_main(const char *devpath, int fd, uint64_t part_sector_count) +{ + int spc_bits = -1; + uint32_t volume_serial = 0; + uint64_t first_sector = 0; + struct exfat_dev* dev; + +#if 0 + while ((opt = getopt(argc, argv, "i:n:p:s:V")) != -1) + { + switch (opt) + { + case 'i': + volume_serial = strtol(optarg, NULL, 16); + break; + case 'n': + volume_label = optarg; + break; + case 'p': + first_sector = strtoll(optarg, NULL, 10); + break; + case 's': + spc_bits = logarithm2(atoi(optarg)); + if (spc_bits < 0) + { + exfat_error("invalid option value: '%s'", optarg); + return 1; + } + break; + case 'V': + puts("Copyright (C) 2011-2018 Andrew Nayenko"); + return 0; + default: + usage(argv[0]); + break; + } + } +#endif /* #if 0 */ + + /* + * DiskSize > 32GB Cluster Size use 128KB + * DiskSize < 32GB Cluster Size use 32KB + */ + if ((part_sector_count / 2097152) > 32) + { + spc_bits = logarithm2(256); + } + else + { + spc_bits = logarithm2(64); + } + + g_vtoy_exfat_disk_fd = fd; + g_vtoy_exfat_part_size = part_sector_count * 512; + + dev = exfat_open(devpath, EXFAT_MODE_RW); + if (dev == NULL) + return 1; + if (setup(dev, 9, spc_bits, "Ventoy", volume_serial, first_sector) != 0) + { + exfat_close(dev); + return 1; + } + if (exfat_close(dev) != 0) + return 1; + + return 0; +} + diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/rootdir.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/rootdir.c new file mode 100644 index 0000000..323da8a --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/rootdir.c @@ -0,0 +1,102 @@ +/* + rootdir.c (09.11.10) + Root directory creation code. + + Free exFAT implementation. + Copyright (C) 2011-2018 Andrew Nayenko + + 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. +*/ + +#include "rootdir.h" +#include "uct.h" +#include "cbm.h" +#include "uctc.h" +#include + +static off_t rootdir_alignment(void) +{ + return get_cluster_size(); +} + +static off_t rootdir_size(void) +{ + return get_cluster_size(); +} + +static void init_label_entry(struct exfat_entry_label* label_entry) +{ + memset(label_entry, 0, sizeof(struct exfat_entry_label)); + label_entry->type = EXFAT_ENTRY_LABEL ^ EXFAT_ENTRY_VALID; + + if (utf16_length(get_volume_label()) == 0) + return; + + memcpy(label_entry->name, get_volume_label(), + EXFAT_ENAME_MAX * sizeof(le16_t)); + label_entry->length = utf16_length(get_volume_label()); + label_entry->type |= EXFAT_ENTRY_VALID; +} + +static void init_bitmap_entry(struct exfat_entry_bitmap* bitmap_entry) +{ + memset(bitmap_entry, 0, sizeof(struct exfat_entry_bitmap)); + bitmap_entry->type = EXFAT_ENTRY_BITMAP; + bitmap_entry->start_cluster = cpu_to_le32(EXFAT_FIRST_DATA_CLUSTER); + bitmap_entry->size = cpu_to_le64(cbm.get_size()); +} + +static void init_upcase_entry(struct exfat_entry_upcase* upcase_entry) +{ + size_t i; + uint32_t sum = 0; + + for (i = 0; i < sizeof(upcase_table); i++) + sum = ((sum << 31) | (sum >> 1)) + upcase_table[i]; + + memset(upcase_entry, 0, sizeof(struct exfat_entry_upcase)); + upcase_entry->type = EXFAT_ENTRY_UPCASE; + upcase_entry->checksum = cpu_to_le32(sum); + upcase_entry->start_cluster = cpu_to_le32( + (get_position(&uct) - get_position(&cbm)) / get_cluster_size() + + EXFAT_FIRST_DATA_CLUSTER); + upcase_entry->size = cpu_to_le64(sizeof(upcase_table)); +} + +static int rootdir_write(struct exfat_dev* dev) +{ + struct exfat_entry_label label_entry; + struct exfat_entry_bitmap bitmap_entry; + struct exfat_entry_upcase upcase_entry; + + init_label_entry(&label_entry); + init_bitmap_entry(&bitmap_entry); + init_upcase_entry(&upcase_entry); + + if (exfat_write(dev, &label_entry, sizeof(struct exfat_entry)) < 0) + return 1; + if (exfat_write(dev, &bitmap_entry, sizeof(struct exfat_entry)) < 0) + return 1; + if (exfat_write(dev, &upcase_entry, sizeof(struct exfat_entry)) < 0) + return 1; + return 0; +} + +const struct fs_object rootdir = +{ + .get_alignment = rootdir_alignment, + .get_size = rootdir_size, + .write = rootdir_write, +}; diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/rootdir.h b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/rootdir.h new file mode 100644 index 0000000..87f437f --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/rootdir.h @@ -0,0 +1,30 @@ +/* + rootdir.h (09.11.10) + Root directory creation code. + + Free exFAT implementation. + Copyright (C) 2011-2018 Andrew Nayenko + + 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. +*/ + +#ifndef MKFS_ROOTDIR_H_INCLUDED +#define MKFS_ROOTDIR_H_INCLUDED + +#include "mkexfat.h" + +extern const struct fs_object rootdir; + +#endif /* ifndef MKFS_ROOTDIR_H_INCLUDED */ diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uct.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uct.c new file mode 100644 index 0000000..98cdce8 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uct.c @@ -0,0 +1,52 @@ +/* + uct.c (09.11.10) + Upper Case Table creation code. + + Free exFAT implementation. + Copyright (C) 2011-2018 Andrew Nayenko + + 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. +*/ + +#include "uct.h" +#include "uctc.h" + +static off_t uct_alignment(void) +{ + return get_cluster_size(); +} + +static off_t uct_size(void) +{ + return sizeof(upcase_table); +} + +static int uct_write(struct exfat_dev* dev) +{ + if (exfat_write(dev, upcase_table, sizeof(upcase_table)) < 0) + { + exfat_error("failed to write upcase table of %zu bytes", + sizeof(upcase_table)); + return 1; + } + return 0; +} + +const struct fs_object uct = +{ + .get_alignment = uct_alignment, + .get_size = uct_size, + .write = uct_write, +}; diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uct.h b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uct.h new file mode 100644 index 0000000..ce619ec --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uct.h @@ -0,0 +1,30 @@ +/* + uct.h (09.11.10) + Upper Case Table creation code. + + Free exFAT implementation. + Copyright (C) 2011-2018 Andrew Nayenko + + 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. +*/ + +#ifndef MKFS_UCT_H_INCLUDED +#define MKFS_UCT_H_INCLUDED + +#include "mkexfat.h" + +extern const struct fs_object uct; + +#endif /* ifndef MKFS_UCT_H_INCLUDED */ diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uctc.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uctc.c new file mode 100644 index 0000000..518219c --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uctc.c @@ -0,0 +1,757 @@ +/* + uctc.c (30.04.12) + Upper Case Table contents. + + Free exFAT implementation. + Copyright (C) 2011-2018 Andrew Nayenko + + 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. +*/ + +#include "uctc.h" + +uint8_t upcase_table[5836] = +{ + 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, + 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, + 0x08, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x00, + 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, + 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, 0x00, + 0x14, 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, 0x00, + 0x18, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1b, 0x00, + 0x1c, 0x00, 0x1d, 0x00, 0x1e, 0x00, 0x1f, 0x00, + 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, + 0x24, 0x00, 0x25, 0x00, 0x26, 0x00, 0x27, 0x00, + 0x28, 0x00, 0x29, 0x00, 0x2a, 0x00, 0x2b, 0x00, + 0x2c, 0x00, 0x2d, 0x00, 0x2e, 0x00, 0x2f, 0x00, + 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, + 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, + 0x38, 0x00, 0x39, 0x00, 0x3a, 0x00, 0x3b, 0x00, + 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00, + 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, + 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, + 0x48, 0x00, 0x49, 0x00, 0x4a, 0x00, 0x4b, 0x00, + 0x4c, 0x00, 0x4d, 0x00, 0x4e, 0x00, 0x4f, 0x00, + 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, + 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, + 0x58, 0x00, 0x59, 0x00, 0x5a, 0x00, 0x5b, 0x00, + 0x5c, 0x00, 0x5d, 0x00, 0x5e, 0x00, 0x5f, 0x00, + 0x60, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, + 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, + 0x48, 0x00, 0x49, 0x00, 0x4a, 0x00, 0x4b, 0x00, + 0x4c, 0x00, 0x4d, 0x00, 0x4e, 0x00, 0x4f, 0x00, + 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, + 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, + 0x58, 0x00, 0x59, 0x00, 0x5a, 0x00, 0x7b, 0x00, + 0x7c, 0x00, 0x7d, 0x00, 0x7e, 0x00, 0x7f, 0x00, + 0x80, 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, + 0x84, 0x00, 0x85, 0x00, 0x86, 0x00, 0x87, 0x00, + 0x88, 0x00, 0x89, 0x00, 0x8a, 0x00, 0x8b, 0x00, + 0x8c, 0x00, 0x8d, 0x00, 0x8e, 0x00, 0x8f, 0x00, + 0x90, 0x00, 0x91, 0x00, 0x92, 0x00, 0x93, 0x00, + 0x94, 0x00, 0x95, 0x00, 0x96, 0x00, 0x97, 0x00, + 0x98, 0x00, 0x99, 0x00, 0x9a, 0x00, 0x9b, 0x00, + 0x9c, 0x00, 0x9d, 0x00, 0x9e, 0x00, 0x9f, 0x00, + 0xa0, 0x00, 0xa1, 0x00, 0xa2, 0x00, 0xa3, 0x00, + 0xa4, 0x00, 0xa5, 0x00, 0xa6, 0x00, 0xa7, 0x00, + 0xa8, 0x00, 0xa9, 0x00, 0xaa, 0x00, 0xab, 0x00, + 0xac, 0x00, 0xad, 0x00, 0xae, 0x00, 0xaf, 0x00, + 0xb0, 0x00, 0xb1, 0x00, 0xb2, 0x00, 0xb3, 0x00, + 0xb4, 0x00, 0xb5, 0x00, 0xb6, 0x00, 0xb7, 0x00, + 0xb8, 0x00, 0xb9, 0x00, 0xba, 0x00, 0xbb, 0x00, + 0xbc, 0x00, 0xbd, 0x00, 0xbe, 0x00, 0xbf, 0x00, + 0xc0, 0x00, 0xc1, 0x00, 0xc2, 0x00, 0xc3, 0x00, + 0xc4, 0x00, 0xc5, 0x00, 0xc6, 0x00, 0xc7, 0x00, + 0xc8, 0x00, 0xc9, 0x00, 0xca, 0x00, 0xcb, 0x00, + 0xcc, 0x00, 0xcd, 0x00, 0xce, 0x00, 0xcf, 0x00, + 0xd0, 0x00, 0xd1, 0x00, 0xd2, 0x00, 0xd3, 0x00, + 0xd4, 0x00, 0xd5, 0x00, 0xd6, 0x00, 0xd7, 0x00, + 0xd8, 0x00, 0xd9, 0x00, 0xda, 0x00, 0xdb, 0x00, + 0xdc, 0x00, 0xdd, 0x00, 0xde, 0x00, 0xdf, 0x00, + 0xc0, 0x00, 0xc1, 0x00, 0xc2, 0x00, 0xc3, 0x00, + 0xc4, 0x00, 0xc5, 0x00, 0xc6, 0x00, 0xc7, 0x00, + 0xc8, 0x00, 0xc9, 0x00, 0xca, 0x00, 0xcb, 0x00, + 0xcc, 0x00, 0xcd, 0x00, 0xce, 0x00, 0xcf, 0x00, + 0xd0, 0x00, 0xd1, 0x00, 0xd2, 0x00, 0xd3, 0x00, + 0xd4, 0x00, 0xd5, 0x00, 0xd6, 0x00, 0xf7, 0x00, + 0xd8, 0x00, 0xd9, 0x00, 0xda, 0x00, 0xdb, 0x00, + 0xdc, 0x00, 0xdd, 0x00, 0xde, 0x00, 0x78, 0x01, + 0x00, 0x01, 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, + 0x04, 0x01, 0x04, 0x01, 0x06, 0x01, 0x06, 0x01, + 0x08, 0x01, 0x08, 0x01, 0x0a, 0x01, 0x0a, 0x01, + 0x0c, 0x01, 0x0c, 0x01, 0x0e, 0x01, 0x0e, 0x01, + 0x10, 0x01, 0x10, 0x01, 0x12, 0x01, 0x12, 0x01, + 0x14, 0x01, 0x14, 0x01, 0x16, 0x01, 0x16, 0x01, + 0x18, 0x01, 0x18, 0x01, 0x1a, 0x01, 0x1a, 0x01, + 0x1c, 0x01, 0x1c, 0x01, 0x1e, 0x01, 0x1e, 0x01, + 0x20, 0x01, 0x20, 0x01, 0x22, 0x01, 0x22, 0x01, + 0x24, 0x01, 0x24, 0x01, 0x26, 0x01, 0x26, 0x01, + 0x28, 0x01, 0x28, 0x01, 0x2a, 0x01, 0x2a, 0x01, + 0x2c, 0x01, 0x2c, 0x01, 0x2e, 0x01, 0x2e, 0x01, + 0x30, 0x01, 0x31, 0x01, 0x32, 0x01, 0x32, 0x01, + 0x34, 0x01, 0x34, 0x01, 0x36, 0x01, 0x36, 0x01, + 0x38, 0x01, 0x39, 0x01, 0x39, 0x01, 0x3b, 0x01, + 0x3b, 0x01, 0x3d, 0x01, 0x3d, 0x01, 0x3f, 0x01, + 0x3f, 0x01, 0x41, 0x01, 0x41, 0x01, 0x43, 0x01, + 0x43, 0x01, 0x45, 0x01, 0x45, 0x01, 0x47, 0x01, + 0x47, 0x01, 0x49, 0x01, 0x4a, 0x01, 0x4a, 0x01, + 0x4c, 0x01, 0x4c, 0x01, 0x4e, 0x01, 0x4e, 0x01, + 0x50, 0x01, 0x50, 0x01, 0x52, 0x01, 0x52, 0x01, + 0x54, 0x01, 0x54, 0x01, 0x56, 0x01, 0x56, 0x01, + 0x58, 0x01, 0x58, 0x01, 0x5a, 0x01, 0x5a, 0x01, + 0x5c, 0x01, 0x5c, 0x01, 0x5e, 0x01, 0x5e, 0x01, + 0x60, 0x01, 0x60, 0x01, 0x62, 0x01, 0x62, 0x01, + 0x64, 0x01, 0x64, 0x01, 0x66, 0x01, 0x66, 0x01, + 0x68, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x6a, 0x01, + 0x6c, 0x01, 0x6c, 0x01, 0x6e, 0x01, 0x6e, 0x01, + 0x70, 0x01, 0x70, 0x01, 0x72, 0x01, 0x72, 0x01, + 0x74, 0x01, 0x74, 0x01, 0x76, 0x01, 0x76, 0x01, + 0x78, 0x01, 0x79, 0x01, 0x79, 0x01, 0x7b, 0x01, + 0x7b, 0x01, 0x7d, 0x01, 0x7d, 0x01, 0x7f, 0x01, + 0x43, 0x02, 0x81, 0x01, 0x82, 0x01, 0x82, 0x01, + 0x84, 0x01, 0x84, 0x01, 0x86, 0x01, 0x87, 0x01, + 0x87, 0x01, 0x89, 0x01, 0x8a, 0x01, 0x8b, 0x01, + 0x8b, 0x01, 0x8d, 0x01, 0x8e, 0x01, 0x8f, 0x01, + 0x90, 0x01, 0x91, 0x01, 0x91, 0x01, 0x93, 0x01, + 0x94, 0x01, 0xf6, 0x01, 0x96, 0x01, 0x97, 0x01, + 0x98, 0x01, 0x98, 0x01, 0x3d, 0x02, 0x9b, 0x01, + 0x9c, 0x01, 0x9d, 0x01, 0x20, 0x02, 0x9f, 0x01, + 0xa0, 0x01, 0xa0, 0x01, 0xa2, 0x01, 0xa2, 0x01, + 0xa4, 0x01, 0xa4, 0x01, 0xa6, 0x01, 0xa7, 0x01, + 0xa7, 0x01, 0xa9, 0x01, 0xaa, 0x01, 0xab, 0x01, + 0xac, 0x01, 0xac, 0x01, 0xae, 0x01, 0xaf, 0x01, + 0xaf, 0x01, 0xb1, 0x01, 0xb2, 0x01, 0xb3, 0x01, + 0xb3, 0x01, 0xb5, 0x01, 0xb5, 0x01, 0xb7, 0x01, + 0xb8, 0x01, 0xb8, 0x01, 0xba, 0x01, 0xbb, 0x01, + 0xbc, 0x01, 0xbc, 0x01, 0xbe, 0x01, 0xf7, 0x01, + 0xc0, 0x01, 0xc1, 0x01, 0xc2, 0x01, 0xc3, 0x01, + 0xc4, 0x01, 0xc5, 0x01, 0xc4, 0x01, 0xc7, 0x01, + 0xc8, 0x01, 0xc7, 0x01, 0xca, 0x01, 0xcb, 0x01, + 0xca, 0x01, 0xcd, 0x01, 0xcd, 0x01, 0xcf, 0x01, + 0xcf, 0x01, 0xd1, 0x01, 0xd1, 0x01, 0xd3, 0x01, + 0xd3, 0x01, 0xd5, 0x01, 0xd5, 0x01, 0xd7, 0x01, + 0xd7, 0x01, 0xd9, 0x01, 0xd9, 0x01, 0xdb, 0x01, + 0xdb, 0x01, 0x8e, 0x01, 0xde, 0x01, 0xde, 0x01, + 0xe0, 0x01, 0xe0, 0x01, 0xe2, 0x01, 0xe2, 0x01, + 0xe4, 0x01, 0xe4, 0x01, 0xe6, 0x01, 0xe6, 0x01, + 0xe8, 0x01, 0xe8, 0x01, 0xea, 0x01, 0xea, 0x01, + 0xec, 0x01, 0xec, 0x01, 0xee, 0x01, 0xee, 0x01, + 0xf0, 0x01, 0xf1, 0x01, 0xf2, 0x01, 0xf1, 0x01, + 0xf4, 0x01, 0xf4, 0x01, 0xf6, 0x01, 0xf7, 0x01, + 0xf8, 0x01, 0xf8, 0x01, 0xfa, 0x01, 0xfa, 0x01, + 0xfc, 0x01, 0xfc, 0x01, 0xfe, 0x01, 0xfe, 0x01, + 0x00, 0x02, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x04, 0x02, 0x04, 0x02, 0x06, 0x02, 0x06, 0x02, + 0x08, 0x02, 0x08, 0x02, 0x0a, 0x02, 0x0a, 0x02, + 0x0c, 0x02, 0x0c, 0x02, 0x0e, 0x02, 0x0e, 0x02, + 0x10, 0x02, 0x10, 0x02, 0x12, 0x02, 0x12, 0x02, + 0x14, 0x02, 0x14, 0x02, 0x16, 0x02, 0x16, 0x02, + 0x18, 0x02, 0x18, 0x02, 0x1a, 0x02, 0x1a, 0x02, + 0x1c, 0x02, 0x1c, 0x02, 0x1e, 0x02, 0x1e, 0x02, + 0x20, 0x02, 0x21, 0x02, 0x22, 0x02, 0x22, 0x02, + 0x24, 0x02, 0x24, 0x02, 0x26, 0x02, 0x26, 0x02, + 0x28, 0x02, 0x28, 0x02, 0x2a, 0x02, 0x2a, 0x02, + 0x2c, 0x02, 0x2c, 0x02, 0x2e, 0x02, 0x2e, 0x02, + 0x30, 0x02, 0x30, 0x02, 0x32, 0x02, 0x32, 0x02, + 0x34, 0x02, 0x35, 0x02, 0x36, 0x02, 0x37, 0x02, + 0x38, 0x02, 0x39, 0x02, 0x65, 0x2c, 0x3b, 0x02, + 0x3b, 0x02, 0x3d, 0x02, 0x66, 0x2c, 0x3f, 0x02, + 0x40, 0x02, 0x41, 0x02, 0x41, 0x02, 0x43, 0x02, + 0x44, 0x02, 0x45, 0x02, 0x46, 0x02, 0x46, 0x02, + 0x48, 0x02, 0x48, 0x02, 0x4a, 0x02, 0x4a, 0x02, + 0x4c, 0x02, 0x4c, 0x02, 0x4e, 0x02, 0x4e, 0x02, + 0x50, 0x02, 0x51, 0x02, 0x52, 0x02, 0x81, 0x01, + 0x86, 0x01, 0x55, 0x02, 0x89, 0x01, 0x8a, 0x01, + 0x58, 0x02, 0x8f, 0x01, 0x5a, 0x02, 0x90, 0x01, + 0x5c, 0x02, 0x5d, 0x02, 0x5e, 0x02, 0x5f, 0x02, + 0x93, 0x01, 0x61, 0x02, 0x62, 0x02, 0x94, 0x01, + 0x64, 0x02, 0x65, 0x02, 0x66, 0x02, 0x67, 0x02, + 0x97, 0x01, 0x96, 0x01, 0x6a, 0x02, 0x62, 0x2c, + 0x6c, 0x02, 0x6d, 0x02, 0x6e, 0x02, 0x9c, 0x01, + 0x70, 0x02, 0x71, 0x02, 0x9d, 0x01, 0x73, 0x02, + 0x74, 0x02, 0x9f, 0x01, 0x76, 0x02, 0x77, 0x02, + 0x78, 0x02, 0x79, 0x02, 0x7a, 0x02, 0x7b, 0x02, + 0x7c, 0x02, 0x64, 0x2c, 0x7e, 0x02, 0x7f, 0x02, + 0xa6, 0x01, 0x81, 0x02, 0x82, 0x02, 0xa9, 0x01, + 0x84, 0x02, 0x85, 0x02, 0x86, 0x02, 0x87, 0x02, + 0xae, 0x01, 0x44, 0x02, 0xb1, 0x01, 0xb2, 0x01, + 0x45, 0x02, 0x8d, 0x02, 0x8e, 0x02, 0x8f, 0x02, + 0x90, 0x02, 0x91, 0x02, 0xb7, 0x01, 0x93, 0x02, + 0x94, 0x02, 0x95, 0x02, 0x96, 0x02, 0x97, 0x02, + 0x98, 0x02, 0x99, 0x02, 0x9a, 0x02, 0x9b, 0x02, + 0x9c, 0x02, 0x9d, 0x02, 0x9e, 0x02, 0x9f, 0x02, + 0xa0, 0x02, 0xa1, 0x02, 0xa2, 0x02, 0xa3, 0x02, + 0xa4, 0x02, 0xa5, 0x02, 0xa6, 0x02, 0xa7, 0x02, + 0xa8, 0x02, 0xa9, 0x02, 0xaa, 0x02, 0xab, 0x02, + 0xac, 0x02, 0xad, 0x02, 0xae, 0x02, 0xaf, 0x02, + 0xb0, 0x02, 0xb1, 0x02, 0xb2, 0x02, 0xb3, 0x02, + 0xb4, 0x02, 0xb5, 0x02, 0xb6, 0x02, 0xb7, 0x02, + 0xb8, 0x02, 0xb9, 0x02, 0xba, 0x02, 0xbb, 0x02, + 0xbc, 0x02, 0xbd, 0x02, 0xbe, 0x02, 0xbf, 0x02, + 0xc0, 0x02, 0xc1, 0x02, 0xc2, 0x02, 0xc3, 0x02, + 0xc4, 0x02, 0xc5, 0x02, 0xc6, 0x02, 0xc7, 0x02, + 0xc8, 0x02, 0xc9, 0x02, 0xca, 0x02, 0xcb, 0x02, + 0xcc, 0x02, 0xcd, 0x02, 0xce, 0x02, 0xcf, 0x02, + 0xd0, 0x02, 0xd1, 0x02, 0xd2, 0x02, 0xd3, 0x02, + 0xd4, 0x02, 0xd5, 0x02, 0xd6, 0x02, 0xd7, 0x02, + 0xd8, 0x02, 0xd9, 0x02, 0xda, 0x02, 0xdb, 0x02, + 0xdc, 0x02, 0xdd, 0x02, 0xde, 0x02, 0xdf, 0x02, + 0xe0, 0x02, 0xe1, 0x02, 0xe2, 0x02, 0xe3, 0x02, + 0xe4, 0x02, 0xe5, 0x02, 0xe6, 0x02, 0xe7, 0x02, + 0xe8, 0x02, 0xe9, 0x02, 0xea, 0x02, 0xeb, 0x02, + 0xec, 0x02, 0xed, 0x02, 0xee, 0x02, 0xef, 0x02, + 0xf0, 0x02, 0xf1, 0x02, 0xf2, 0x02, 0xf3, 0x02, + 0xf4, 0x02, 0xf5, 0x02, 0xf6, 0x02, 0xf7, 0x02, + 0xf8, 0x02, 0xf9, 0x02, 0xfa, 0x02, 0xfb, 0x02, + 0xfc, 0x02, 0xfd, 0x02, 0xfe, 0x02, 0xff, 0x02, + 0x00, 0x03, 0x01, 0x03, 0x02, 0x03, 0x03, 0x03, + 0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x07, 0x03, + 0x08, 0x03, 0x09, 0x03, 0x0a, 0x03, 0x0b, 0x03, + 0x0c, 0x03, 0x0d, 0x03, 0x0e, 0x03, 0x0f, 0x03, + 0x10, 0x03, 0x11, 0x03, 0x12, 0x03, 0x13, 0x03, + 0x14, 0x03, 0x15, 0x03, 0x16, 0x03, 0x17, 0x03, + 0x18, 0x03, 0x19, 0x03, 0x1a, 0x03, 0x1b, 0x03, + 0x1c, 0x03, 0x1d, 0x03, 0x1e, 0x03, 0x1f, 0x03, + 0x20, 0x03, 0x21, 0x03, 0x22, 0x03, 0x23, 0x03, + 0x24, 0x03, 0x25, 0x03, 0x26, 0x03, 0x27, 0x03, + 0x28, 0x03, 0x29, 0x03, 0x2a, 0x03, 0x2b, 0x03, + 0x2c, 0x03, 0x2d, 0x03, 0x2e, 0x03, 0x2f, 0x03, + 0x30, 0x03, 0x31, 0x03, 0x32, 0x03, 0x33, 0x03, + 0x34, 0x03, 0x35, 0x03, 0x36, 0x03, 0x37, 0x03, + 0x38, 0x03, 0x39, 0x03, 0x3a, 0x03, 0x3b, 0x03, + 0x3c, 0x03, 0x3d, 0x03, 0x3e, 0x03, 0x3f, 0x03, + 0x40, 0x03, 0x41, 0x03, 0x42, 0x03, 0x43, 0x03, + 0x44, 0x03, 0x45, 0x03, 0x46, 0x03, 0x47, 0x03, + 0x48, 0x03, 0x49, 0x03, 0x4a, 0x03, 0x4b, 0x03, + 0x4c, 0x03, 0x4d, 0x03, 0x4e, 0x03, 0x4f, 0x03, + 0x50, 0x03, 0x51, 0x03, 0x52, 0x03, 0x53, 0x03, + 0x54, 0x03, 0x55, 0x03, 0x56, 0x03, 0x57, 0x03, + 0x58, 0x03, 0x59, 0x03, 0x5a, 0x03, 0x5b, 0x03, + 0x5c, 0x03, 0x5d, 0x03, 0x5e, 0x03, 0x5f, 0x03, + 0x60, 0x03, 0x61, 0x03, 0x62, 0x03, 0x63, 0x03, + 0x64, 0x03, 0x65, 0x03, 0x66, 0x03, 0x67, 0x03, + 0x68, 0x03, 0x69, 0x03, 0x6a, 0x03, 0x6b, 0x03, + 0x6c, 0x03, 0x6d, 0x03, 0x6e, 0x03, 0x6f, 0x03, + 0x70, 0x03, 0x71, 0x03, 0x72, 0x03, 0x73, 0x03, + 0x74, 0x03, 0x75, 0x03, 0x76, 0x03, 0x77, 0x03, + 0x78, 0x03, 0x79, 0x03, 0x7a, 0x03, 0xfd, 0x03, + 0xfe, 0x03, 0xff, 0x03, 0x7e, 0x03, 0x7f, 0x03, + 0x80, 0x03, 0x81, 0x03, 0x82, 0x03, 0x83, 0x03, + 0x84, 0x03, 0x85, 0x03, 0x86, 0x03, 0x87, 0x03, + 0x88, 0x03, 0x89, 0x03, 0x8a, 0x03, 0x8b, 0x03, + 0x8c, 0x03, 0x8d, 0x03, 0x8e, 0x03, 0x8f, 0x03, + 0x90, 0x03, 0x91, 0x03, 0x92, 0x03, 0x93, 0x03, + 0x94, 0x03, 0x95, 0x03, 0x96, 0x03, 0x97, 0x03, + 0x98, 0x03, 0x99, 0x03, 0x9a, 0x03, 0x9b, 0x03, + 0x9c, 0x03, 0x9d, 0x03, 0x9e, 0x03, 0x9f, 0x03, + 0xa0, 0x03, 0xa1, 0x03, 0xa2, 0x03, 0xa3, 0x03, + 0xa4, 0x03, 0xa5, 0x03, 0xa6, 0x03, 0xa7, 0x03, + 0xa8, 0x03, 0xa9, 0x03, 0xaa, 0x03, 0xab, 0x03, + 0x86, 0x03, 0x88, 0x03, 0x89, 0x03, 0x8a, 0x03, + 0xb0, 0x03, 0x91, 0x03, 0x92, 0x03, 0x93, 0x03, + 0x94, 0x03, 0x95, 0x03, 0x96, 0x03, 0x97, 0x03, + 0x98, 0x03, 0x99, 0x03, 0x9a, 0x03, 0x9b, 0x03, + 0x9c, 0x03, 0x9d, 0x03, 0x9e, 0x03, 0x9f, 0x03, + 0xa0, 0x03, 0xa1, 0x03, 0xa3, 0x03, 0xa3, 0x03, + 0xa4, 0x03, 0xa5, 0x03, 0xa6, 0x03, 0xa7, 0x03, + 0xa8, 0x03, 0xa9, 0x03, 0xaa, 0x03, 0xab, 0x03, + 0x8c, 0x03, 0x8e, 0x03, 0x8f, 0x03, 0xcf, 0x03, + 0xd0, 0x03, 0xd1, 0x03, 0xd2, 0x03, 0xd3, 0x03, + 0xd4, 0x03, 0xd5, 0x03, 0xd6, 0x03, 0xd7, 0x03, + 0xd8, 0x03, 0xd8, 0x03, 0xda, 0x03, 0xda, 0x03, + 0xdc, 0x03, 0xdc, 0x03, 0xde, 0x03, 0xde, 0x03, + 0xe0, 0x03, 0xe0, 0x03, 0xe2, 0x03, 0xe2, 0x03, + 0xe4, 0x03, 0xe4, 0x03, 0xe6, 0x03, 0xe6, 0x03, + 0xe8, 0x03, 0xe8, 0x03, 0xea, 0x03, 0xea, 0x03, + 0xec, 0x03, 0xec, 0x03, 0xee, 0x03, 0xee, 0x03, + 0xf0, 0x03, 0xf1, 0x03, 0xf9, 0x03, 0xf3, 0x03, + 0xf4, 0x03, 0xf5, 0x03, 0xf6, 0x03, 0xf7, 0x03, + 0xf7, 0x03, 0xf9, 0x03, 0xfa, 0x03, 0xfa, 0x03, + 0xfc, 0x03, 0xfd, 0x03, 0xfe, 0x03, 0xff, 0x03, + 0x00, 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, 0x04, + 0x04, 0x04, 0x05, 0x04, 0x06, 0x04, 0x07, 0x04, + 0x08, 0x04, 0x09, 0x04, 0x0a, 0x04, 0x0b, 0x04, + 0x0c, 0x04, 0x0d, 0x04, 0x0e, 0x04, 0x0f, 0x04, + 0x10, 0x04, 0x11, 0x04, 0x12, 0x04, 0x13, 0x04, + 0x14, 0x04, 0x15, 0x04, 0x16, 0x04, 0x17, 0x04, + 0x18, 0x04, 0x19, 0x04, 0x1a, 0x04, 0x1b, 0x04, + 0x1c, 0x04, 0x1d, 0x04, 0x1e, 0x04, 0x1f, 0x04, + 0x20, 0x04, 0x21, 0x04, 0x22, 0x04, 0x23, 0x04, + 0x24, 0x04, 0x25, 0x04, 0x26, 0x04, 0x27, 0x04, + 0x28, 0x04, 0x29, 0x04, 0x2a, 0x04, 0x2b, 0x04, + 0x2c, 0x04, 0x2d, 0x04, 0x2e, 0x04, 0x2f, 0x04, + 0x10, 0x04, 0x11, 0x04, 0x12, 0x04, 0x13, 0x04, + 0x14, 0x04, 0x15, 0x04, 0x16, 0x04, 0x17, 0x04, + 0x18, 0x04, 0x19, 0x04, 0x1a, 0x04, 0x1b, 0x04, + 0x1c, 0x04, 0x1d, 0x04, 0x1e, 0x04, 0x1f, 0x04, + 0x20, 0x04, 0x21, 0x04, 0x22, 0x04, 0x23, 0x04, + 0x24, 0x04, 0x25, 0x04, 0x26, 0x04, 0x27, 0x04, + 0x28, 0x04, 0x29, 0x04, 0x2a, 0x04, 0x2b, 0x04, + 0x2c, 0x04, 0x2d, 0x04, 0x2e, 0x04, 0x2f, 0x04, + 0x00, 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, 0x04, + 0x04, 0x04, 0x05, 0x04, 0x06, 0x04, 0x07, 0x04, + 0x08, 0x04, 0x09, 0x04, 0x0a, 0x04, 0x0b, 0x04, + 0x0c, 0x04, 0x0d, 0x04, 0x0e, 0x04, 0x0f, 0x04, + 0x60, 0x04, 0x60, 0x04, 0x62, 0x04, 0x62, 0x04, + 0x64, 0x04, 0x64, 0x04, 0x66, 0x04, 0x66, 0x04, + 0x68, 0x04, 0x68, 0x04, 0x6a, 0x04, 0x6a, 0x04, + 0x6c, 0x04, 0x6c, 0x04, 0x6e, 0x04, 0x6e, 0x04, + 0x70, 0x04, 0x70, 0x04, 0x72, 0x04, 0x72, 0x04, + 0x74, 0x04, 0x74, 0x04, 0x76, 0x04, 0x76, 0x04, + 0x78, 0x04, 0x78, 0x04, 0x7a, 0x04, 0x7a, 0x04, + 0x7c, 0x04, 0x7c, 0x04, 0x7e, 0x04, 0x7e, 0x04, + 0x80, 0x04, 0x80, 0x04, 0x82, 0x04, 0x83, 0x04, + 0x84, 0x04, 0x85, 0x04, 0x86, 0x04, 0x87, 0x04, + 0x88, 0x04, 0x89, 0x04, 0x8a, 0x04, 0x8a, 0x04, + 0x8c, 0x04, 0x8c, 0x04, 0x8e, 0x04, 0x8e, 0x04, + 0x90, 0x04, 0x90, 0x04, 0x92, 0x04, 0x92, 0x04, + 0x94, 0x04, 0x94, 0x04, 0x96, 0x04, 0x96, 0x04, + 0x98, 0x04, 0x98, 0x04, 0x9a, 0x04, 0x9a, 0x04, + 0x9c, 0x04, 0x9c, 0x04, 0x9e, 0x04, 0x9e, 0x04, + 0xa0, 0x04, 0xa0, 0x04, 0xa2, 0x04, 0xa2, 0x04, + 0xa4, 0x04, 0xa4, 0x04, 0xa6, 0x04, 0xa6, 0x04, + 0xa8, 0x04, 0xa8, 0x04, 0xaa, 0x04, 0xaa, 0x04, + 0xac, 0x04, 0xac, 0x04, 0xae, 0x04, 0xae, 0x04, + 0xb0, 0x04, 0xb0, 0x04, 0xb2, 0x04, 0xb2, 0x04, + 0xb4, 0x04, 0xb4, 0x04, 0xb6, 0x04, 0xb6, 0x04, + 0xb8, 0x04, 0xb8, 0x04, 0xba, 0x04, 0xba, 0x04, + 0xbc, 0x04, 0xbc, 0x04, 0xbe, 0x04, 0xbe, 0x04, + 0xc0, 0x04, 0xc1, 0x04, 0xc1, 0x04, 0xc3, 0x04, + 0xc3, 0x04, 0xc5, 0x04, 0xc5, 0x04, 0xc7, 0x04, + 0xc7, 0x04, 0xc9, 0x04, 0xc9, 0x04, 0xcb, 0x04, + 0xcb, 0x04, 0xcd, 0x04, 0xcd, 0x04, 0xc0, 0x04, + 0xd0, 0x04, 0xd0, 0x04, 0xd2, 0x04, 0xd2, 0x04, + 0xd4, 0x04, 0xd4, 0x04, 0xd6, 0x04, 0xd6, 0x04, + 0xd8, 0x04, 0xd8, 0x04, 0xda, 0x04, 0xda, 0x04, + 0xdc, 0x04, 0xdc, 0x04, 0xde, 0x04, 0xde, 0x04, + 0xe0, 0x04, 0xe0, 0x04, 0xe2, 0x04, 0xe2, 0x04, + 0xe4, 0x04, 0xe4, 0x04, 0xe6, 0x04, 0xe6, 0x04, + 0xe8, 0x04, 0xe8, 0x04, 0xea, 0x04, 0xea, 0x04, + 0xec, 0x04, 0xec, 0x04, 0xee, 0x04, 0xee, 0x04, + 0xf0, 0x04, 0xf0, 0x04, 0xf2, 0x04, 0xf2, 0x04, + 0xf4, 0x04, 0xf4, 0x04, 0xf6, 0x04, 0xf6, 0x04, + 0xf8, 0x04, 0xf8, 0x04, 0xfa, 0x04, 0xfa, 0x04, + 0xfc, 0x04, 0xfc, 0x04, 0xfe, 0x04, 0xfe, 0x04, + 0x00, 0x05, 0x00, 0x05, 0x02, 0x05, 0x02, 0x05, + 0x04, 0x05, 0x04, 0x05, 0x06, 0x05, 0x06, 0x05, + 0x08, 0x05, 0x08, 0x05, 0x0a, 0x05, 0x0a, 0x05, + 0x0c, 0x05, 0x0c, 0x05, 0x0e, 0x05, 0x0e, 0x05, + 0x10, 0x05, 0x10, 0x05, 0x12, 0x05, 0x12, 0x05, + 0x14, 0x05, 0x15, 0x05, 0x16, 0x05, 0x17, 0x05, + 0x18, 0x05, 0x19, 0x05, 0x1a, 0x05, 0x1b, 0x05, + 0x1c, 0x05, 0x1d, 0x05, 0x1e, 0x05, 0x1f, 0x05, + 0x20, 0x05, 0x21, 0x05, 0x22, 0x05, 0x23, 0x05, + 0x24, 0x05, 0x25, 0x05, 0x26, 0x05, 0x27, 0x05, + 0x28, 0x05, 0x29, 0x05, 0x2a, 0x05, 0x2b, 0x05, + 0x2c, 0x05, 0x2d, 0x05, 0x2e, 0x05, 0x2f, 0x05, + 0x30, 0x05, 0x31, 0x05, 0x32, 0x05, 0x33, 0x05, + 0x34, 0x05, 0x35, 0x05, 0x36, 0x05, 0x37, 0x05, + 0x38, 0x05, 0x39, 0x05, 0x3a, 0x05, 0x3b, 0x05, + 0x3c, 0x05, 0x3d, 0x05, 0x3e, 0x05, 0x3f, 0x05, + 0x40, 0x05, 0x41, 0x05, 0x42, 0x05, 0x43, 0x05, + 0x44, 0x05, 0x45, 0x05, 0x46, 0x05, 0x47, 0x05, + 0x48, 0x05, 0x49, 0x05, 0x4a, 0x05, 0x4b, 0x05, + 0x4c, 0x05, 0x4d, 0x05, 0x4e, 0x05, 0x4f, 0x05, + 0x50, 0x05, 0x51, 0x05, 0x52, 0x05, 0x53, 0x05, + 0x54, 0x05, 0x55, 0x05, 0x56, 0x05, 0x57, 0x05, + 0x58, 0x05, 0x59, 0x05, 0x5a, 0x05, 0x5b, 0x05, + 0x5c, 0x05, 0x5d, 0x05, 0x5e, 0x05, 0x5f, 0x05, + 0x60, 0x05, 0x31, 0x05, 0x32, 0x05, 0x33, 0x05, + 0x34, 0x05, 0x35, 0x05, 0x36, 0x05, 0x37, 0x05, + 0x38, 0x05, 0x39, 0x05, 0x3a, 0x05, 0x3b, 0x05, + 0x3c, 0x05, 0x3d, 0x05, 0x3e, 0x05, 0x3f, 0x05, + 0x40, 0x05, 0x41, 0x05, 0x42, 0x05, 0x43, 0x05, + 0x44, 0x05, 0x45, 0x05, 0x46, 0x05, 0x47, 0x05, + 0x48, 0x05, 0x49, 0x05, 0x4a, 0x05, 0x4b, 0x05, + 0x4c, 0x05, 0x4d, 0x05, 0x4e, 0x05, 0x4f, 0x05, + 0x50, 0x05, 0x51, 0x05, 0x52, 0x05, 0x53, 0x05, + 0x54, 0x05, 0x55, 0x05, 0x56, 0x05, 0xff, 0xff, + 0xf6, 0x17, 0x63, 0x2c, 0x7e, 0x1d, 0x7f, 0x1d, + 0x80, 0x1d, 0x81, 0x1d, 0x82, 0x1d, 0x83, 0x1d, + 0x84, 0x1d, 0x85, 0x1d, 0x86, 0x1d, 0x87, 0x1d, + 0x88, 0x1d, 0x89, 0x1d, 0x8a, 0x1d, 0x8b, 0x1d, + 0x8c, 0x1d, 0x8d, 0x1d, 0x8e, 0x1d, 0x8f, 0x1d, + 0x90, 0x1d, 0x91, 0x1d, 0x92, 0x1d, 0x93, 0x1d, + 0x94, 0x1d, 0x95, 0x1d, 0x96, 0x1d, 0x97, 0x1d, + 0x98, 0x1d, 0x99, 0x1d, 0x9a, 0x1d, 0x9b, 0x1d, + 0x9c, 0x1d, 0x9d, 0x1d, 0x9e, 0x1d, 0x9f, 0x1d, + 0xa0, 0x1d, 0xa1, 0x1d, 0xa2, 0x1d, 0xa3, 0x1d, + 0xa4, 0x1d, 0xa5, 0x1d, 0xa6, 0x1d, 0xa7, 0x1d, + 0xa8, 0x1d, 0xa9, 0x1d, 0xaa, 0x1d, 0xab, 0x1d, + 0xac, 0x1d, 0xad, 0x1d, 0xae, 0x1d, 0xaf, 0x1d, + 0xb0, 0x1d, 0xb1, 0x1d, 0xb2, 0x1d, 0xb3, 0x1d, + 0xb4, 0x1d, 0xb5, 0x1d, 0xb6, 0x1d, 0xb7, 0x1d, + 0xb8, 0x1d, 0xb9, 0x1d, 0xba, 0x1d, 0xbb, 0x1d, + 0xbc, 0x1d, 0xbd, 0x1d, 0xbe, 0x1d, 0xbf, 0x1d, + 0xc0, 0x1d, 0xc1, 0x1d, 0xc2, 0x1d, 0xc3, 0x1d, + 0xc4, 0x1d, 0xc5, 0x1d, 0xc6, 0x1d, 0xc7, 0x1d, + 0xc8, 0x1d, 0xc9, 0x1d, 0xca, 0x1d, 0xcb, 0x1d, + 0xcc, 0x1d, 0xcd, 0x1d, 0xce, 0x1d, 0xcf, 0x1d, + 0xd0, 0x1d, 0xd1, 0x1d, 0xd2, 0x1d, 0xd3, 0x1d, + 0xd4, 0x1d, 0xd5, 0x1d, 0xd6, 0x1d, 0xd7, 0x1d, + 0xd8, 0x1d, 0xd9, 0x1d, 0xda, 0x1d, 0xdb, 0x1d, + 0xdc, 0x1d, 0xdd, 0x1d, 0xde, 0x1d, 0xdf, 0x1d, + 0xe0, 0x1d, 0xe1, 0x1d, 0xe2, 0x1d, 0xe3, 0x1d, + 0xe4, 0x1d, 0xe5, 0x1d, 0xe6, 0x1d, 0xe7, 0x1d, + 0xe8, 0x1d, 0xe9, 0x1d, 0xea, 0x1d, 0xeb, 0x1d, + 0xec, 0x1d, 0xed, 0x1d, 0xee, 0x1d, 0xef, 0x1d, + 0xf0, 0x1d, 0xf1, 0x1d, 0xf2, 0x1d, 0xf3, 0x1d, + 0xf4, 0x1d, 0xf5, 0x1d, 0xf6, 0x1d, 0xf7, 0x1d, + 0xf8, 0x1d, 0xf9, 0x1d, 0xfa, 0x1d, 0xfb, 0x1d, + 0xfc, 0x1d, 0xfd, 0x1d, 0xfe, 0x1d, 0xff, 0x1d, + 0x00, 0x1e, 0x00, 0x1e, 0x02, 0x1e, 0x02, 0x1e, + 0x04, 0x1e, 0x04, 0x1e, 0x06, 0x1e, 0x06, 0x1e, + 0x08, 0x1e, 0x08, 0x1e, 0x0a, 0x1e, 0x0a, 0x1e, + 0x0c, 0x1e, 0x0c, 0x1e, 0x0e, 0x1e, 0x0e, 0x1e, + 0x10, 0x1e, 0x10, 0x1e, 0x12, 0x1e, 0x12, 0x1e, + 0x14, 0x1e, 0x14, 0x1e, 0x16, 0x1e, 0x16, 0x1e, + 0x18, 0x1e, 0x18, 0x1e, 0x1a, 0x1e, 0x1a, 0x1e, + 0x1c, 0x1e, 0x1c, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x20, 0x1e, 0x20, 0x1e, 0x22, 0x1e, 0x22, 0x1e, + 0x24, 0x1e, 0x24, 0x1e, 0x26, 0x1e, 0x26, 0x1e, + 0x28, 0x1e, 0x28, 0x1e, 0x2a, 0x1e, 0x2a, 0x1e, + 0x2c, 0x1e, 0x2c, 0x1e, 0x2e, 0x1e, 0x2e, 0x1e, + 0x30, 0x1e, 0x30, 0x1e, 0x32, 0x1e, 0x32, 0x1e, + 0x34, 0x1e, 0x34, 0x1e, 0x36, 0x1e, 0x36, 0x1e, + 0x38, 0x1e, 0x38, 0x1e, 0x3a, 0x1e, 0x3a, 0x1e, + 0x3c, 0x1e, 0x3c, 0x1e, 0x3e, 0x1e, 0x3e, 0x1e, + 0x40, 0x1e, 0x40, 0x1e, 0x42, 0x1e, 0x42, 0x1e, + 0x44, 0x1e, 0x44, 0x1e, 0x46, 0x1e, 0x46, 0x1e, + 0x48, 0x1e, 0x48, 0x1e, 0x4a, 0x1e, 0x4a, 0x1e, + 0x4c, 0x1e, 0x4c, 0x1e, 0x4e, 0x1e, 0x4e, 0x1e, + 0x50, 0x1e, 0x50, 0x1e, 0x52, 0x1e, 0x52, 0x1e, + 0x54, 0x1e, 0x54, 0x1e, 0x56, 0x1e, 0x56, 0x1e, + 0x58, 0x1e, 0x58, 0x1e, 0x5a, 0x1e, 0x5a, 0x1e, + 0x5c, 0x1e, 0x5c, 0x1e, 0x5e, 0x1e, 0x5e, 0x1e, + 0x60, 0x1e, 0x60, 0x1e, 0x62, 0x1e, 0x62, 0x1e, + 0x64, 0x1e, 0x64, 0x1e, 0x66, 0x1e, 0x66, 0x1e, + 0x68, 0x1e, 0x68, 0x1e, 0x6a, 0x1e, 0x6a, 0x1e, + 0x6c, 0x1e, 0x6c, 0x1e, 0x6e, 0x1e, 0x6e, 0x1e, + 0x70, 0x1e, 0x70, 0x1e, 0x72, 0x1e, 0x72, 0x1e, + 0x74, 0x1e, 0x74, 0x1e, 0x76, 0x1e, 0x76, 0x1e, + 0x78, 0x1e, 0x78, 0x1e, 0x7a, 0x1e, 0x7a, 0x1e, + 0x7c, 0x1e, 0x7c, 0x1e, 0x7e, 0x1e, 0x7e, 0x1e, + 0x80, 0x1e, 0x80, 0x1e, 0x82, 0x1e, 0x82, 0x1e, + 0x84, 0x1e, 0x84, 0x1e, 0x86, 0x1e, 0x86, 0x1e, + 0x88, 0x1e, 0x88, 0x1e, 0x8a, 0x1e, 0x8a, 0x1e, + 0x8c, 0x1e, 0x8c, 0x1e, 0x8e, 0x1e, 0x8e, 0x1e, + 0x90, 0x1e, 0x90, 0x1e, 0x92, 0x1e, 0x92, 0x1e, + 0x94, 0x1e, 0x94, 0x1e, 0x96, 0x1e, 0x97, 0x1e, + 0x98, 0x1e, 0x99, 0x1e, 0x9a, 0x1e, 0x9b, 0x1e, + 0x9c, 0x1e, 0x9d, 0x1e, 0x9e, 0x1e, 0x9f, 0x1e, + 0xa0, 0x1e, 0xa0, 0x1e, 0xa2, 0x1e, 0xa2, 0x1e, + 0xa4, 0x1e, 0xa4, 0x1e, 0xa6, 0x1e, 0xa6, 0x1e, + 0xa8, 0x1e, 0xa8, 0x1e, 0xaa, 0x1e, 0xaa, 0x1e, + 0xac, 0x1e, 0xac, 0x1e, 0xae, 0x1e, 0xae, 0x1e, + 0xb0, 0x1e, 0xb0, 0x1e, 0xb2, 0x1e, 0xb2, 0x1e, + 0xb4, 0x1e, 0xb4, 0x1e, 0xb6, 0x1e, 0xb6, 0x1e, + 0xb8, 0x1e, 0xb8, 0x1e, 0xba, 0x1e, 0xba, 0x1e, + 0xbc, 0x1e, 0xbc, 0x1e, 0xbe, 0x1e, 0xbe, 0x1e, + 0xc0, 0x1e, 0xc0, 0x1e, 0xc2, 0x1e, 0xc2, 0x1e, + 0xc4, 0x1e, 0xc4, 0x1e, 0xc6, 0x1e, 0xc6, 0x1e, + 0xc8, 0x1e, 0xc8, 0x1e, 0xca, 0x1e, 0xca, 0x1e, + 0xcc, 0x1e, 0xcc, 0x1e, 0xce, 0x1e, 0xce, 0x1e, + 0xd0, 0x1e, 0xd0, 0x1e, 0xd2, 0x1e, 0xd2, 0x1e, + 0xd4, 0x1e, 0xd4, 0x1e, 0xd6, 0x1e, 0xd6, 0x1e, + 0xd8, 0x1e, 0xd8, 0x1e, 0xda, 0x1e, 0xda, 0x1e, + 0xdc, 0x1e, 0xdc, 0x1e, 0xde, 0x1e, 0xde, 0x1e, + 0xe0, 0x1e, 0xe0, 0x1e, 0xe2, 0x1e, 0xe2, 0x1e, + 0xe4, 0x1e, 0xe4, 0x1e, 0xe6, 0x1e, 0xe6, 0x1e, + 0xe8, 0x1e, 0xe8, 0x1e, 0xea, 0x1e, 0xea, 0x1e, + 0xec, 0x1e, 0xec, 0x1e, 0xee, 0x1e, 0xee, 0x1e, + 0xf0, 0x1e, 0xf0, 0x1e, 0xf2, 0x1e, 0xf2, 0x1e, + 0xf4, 0x1e, 0xf4, 0x1e, 0xf6, 0x1e, 0xf6, 0x1e, + 0xf8, 0x1e, 0xf8, 0x1e, 0xfa, 0x1e, 0xfb, 0x1e, + 0xfc, 0x1e, 0xfd, 0x1e, 0xfe, 0x1e, 0xff, 0x1e, + 0x08, 0x1f, 0x09, 0x1f, 0x0a, 0x1f, 0x0b, 0x1f, + 0x0c, 0x1f, 0x0d, 0x1f, 0x0e, 0x1f, 0x0f, 0x1f, + 0x08, 0x1f, 0x09, 0x1f, 0x0a, 0x1f, 0x0b, 0x1f, + 0x0c, 0x1f, 0x0d, 0x1f, 0x0e, 0x1f, 0x0f, 0x1f, + 0x18, 0x1f, 0x19, 0x1f, 0x1a, 0x1f, 0x1b, 0x1f, + 0x1c, 0x1f, 0x1d, 0x1f, 0x16, 0x1f, 0x17, 0x1f, + 0x18, 0x1f, 0x19, 0x1f, 0x1a, 0x1f, 0x1b, 0x1f, + 0x1c, 0x1f, 0x1d, 0x1f, 0x1e, 0x1f, 0x1f, 0x1f, + 0x28, 0x1f, 0x29, 0x1f, 0x2a, 0x1f, 0x2b, 0x1f, + 0x2c, 0x1f, 0x2d, 0x1f, 0x2e, 0x1f, 0x2f, 0x1f, + 0x28, 0x1f, 0x29, 0x1f, 0x2a, 0x1f, 0x2b, 0x1f, + 0x2c, 0x1f, 0x2d, 0x1f, 0x2e, 0x1f, 0x2f, 0x1f, + 0x38, 0x1f, 0x39, 0x1f, 0x3a, 0x1f, 0x3b, 0x1f, + 0x3c, 0x1f, 0x3d, 0x1f, 0x3e, 0x1f, 0x3f, 0x1f, + 0x38, 0x1f, 0x39, 0x1f, 0x3a, 0x1f, 0x3b, 0x1f, + 0x3c, 0x1f, 0x3d, 0x1f, 0x3e, 0x1f, 0x3f, 0x1f, + 0x48, 0x1f, 0x49, 0x1f, 0x4a, 0x1f, 0x4b, 0x1f, + 0x4c, 0x1f, 0x4d, 0x1f, 0x46, 0x1f, 0x47, 0x1f, + 0x48, 0x1f, 0x49, 0x1f, 0x4a, 0x1f, 0x4b, 0x1f, + 0x4c, 0x1f, 0x4d, 0x1f, 0x4e, 0x1f, 0x4f, 0x1f, + 0x50, 0x1f, 0x59, 0x1f, 0x52, 0x1f, 0x5b, 0x1f, + 0x54, 0x1f, 0x5d, 0x1f, 0x56, 0x1f, 0x5f, 0x1f, + 0x58, 0x1f, 0x59, 0x1f, 0x5a, 0x1f, 0x5b, 0x1f, + 0x5c, 0x1f, 0x5d, 0x1f, 0x5e, 0x1f, 0x5f, 0x1f, + 0x68, 0x1f, 0x69, 0x1f, 0x6a, 0x1f, 0x6b, 0x1f, + 0x6c, 0x1f, 0x6d, 0x1f, 0x6e, 0x1f, 0x6f, 0x1f, + 0x68, 0x1f, 0x69, 0x1f, 0x6a, 0x1f, 0x6b, 0x1f, + 0x6c, 0x1f, 0x6d, 0x1f, 0x6e, 0x1f, 0x6f, 0x1f, + 0xba, 0x1f, 0xbb, 0x1f, 0xc8, 0x1f, 0xc9, 0x1f, + 0xca, 0x1f, 0xcb, 0x1f, 0xda, 0x1f, 0xdb, 0x1f, + 0xf8, 0x1f, 0xf9, 0x1f, 0xea, 0x1f, 0xeb, 0x1f, + 0xfa, 0x1f, 0xfb, 0x1f, 0x7e, 0x1f, 0x7f, 0x1f, + 0x88, 0x1f, 0x89, 0x1f, 0x8a, 0x1f, 0x8b, 0x1f, + 0x8c, 0x1f, 0x8d, 0x1f, 0x8e, 0x1f, 0x8f, 0x1f, + 0x88, 0x1f, 0x89, 0x1f, 0x8a, 0x1f, 0x8b, 0x1f, + 0x8c, 0x1f, 0x8d, 0x1f, 0x8e, 0x1f, 0x8f, 0x1f, + 0x98, 0x1f, 0x99, 0x1f, 0x9a, 0x1f, 0x9b, 0x1f, + 0x9c, 0x1f, 0x9d, 0x1f, 0x9e, 0x1f, 0x9f, 0x1f, + 0x98, 0x1f, 0x99, 0x1f, 0x9a, 0x1f, 0x9b, 0x1f, + 0x9c, 0x1f, 0x9d, 0x1f, 0x9e, 0x1f, 0x9f, 0x1f, + 0xa8, 0x1f, 0xa9, 0x1f, 0xaa, 0x1f, 0xab, 0x1f, + 0xac, 0x1f, 0xad, 0x1f, 0xae, 0x1f, 0xaf, 0x1f, + 0xa8, 0x1f, 0xa9, 0x1f, 0xaa, 0x1f, 0xab, 0x1f, + 0xac, 0x1f, 0xad, 0x1f, 0xae, 0x1f, 0xaf, 0x1f, + 0xb8, 0x1f, 0xb9, 0x1f, 0xb2, 0x1f, 0xbc, 0x1f, + 0xb4, 0x1f, 0xb5, 0x1f, 0xb6, 0x1f, 0xb7, 0x1f, + 0xb8, 0x1f, 0xb9, 0x1f, 0xba, 0x1f, 0xbb, 0x1f, + 0xbc, 0x1f, 0xbd, 0x1f, 0xbe, 0x1f, 0xbf, 0x1f, + 0xc0, 0x1f, 0xc1, 0x1f, 0xc2, 0x1f, 0xc3, 0x1f, + 0xc4, 0x1f, 0xc5, 0x1f, 0xc6, 0x1f, 0xc7, 0x1f, + 0xc8, 0x1f, 0xc9, 0x1f, 0xca, 0x1f, 0xcb, 0x1f, + 0xc3, 0x1f, 0xcd, 0x1f, 0xce, 0x1f, 0xcf, 0x1f, + 0xd8, 0x1f, 0xd9, 0x1f, 0xd2, 0x1f, 0xd3, 0x1f, + 0xd4, 0x1f, 0xd5, 0x1f, 0xd6, 0x1f, 0xd7, 0x1f, + 0xd8, 0x1f, 0xd9, 0x1f, 0xda, 0x1f, 0xdb, 0x1f, + 0xdc, 0x1f, 0xdd, 0x1f, 0xde, 0x1f, 0xdf, 0x1f, + 0xe8, 0x1f, 0xe9, 0x1f, 0xe2, 0x1f, 0xe3, 0x1f, + 0xe4, 0x1f, 0xec, 0x1f, 0xe6, 0x1f, 0xe7, 0x1f, + 0xe8, 0x1f, 0xe9, 0x1f, 0xea, 0x1f, 0xeb, 0x1f, + 0xec, 0x1f, 0xed, 0x1f, 0xee, 0x1f, 0xef, 0x1f, + 0xf0, 0x1f, 0xf1, 0x1f, 0xf2, 0x1f, 0xf3, 0x1f, + 0xf4, 0x1f, 0xf5, 0x1f, 0xf6, 0x1f, 0xf7, 0x1f, + 0xf8, 0x1f, 0xf9, 0x1f, 0xfa, 0x1f, 0xfb, 0x1f, + 0xf3, 0x1f, 0xfd, 0x1f, 0xfe, 0x1f, 0xff, 0x1f, + 0x00, 0x20, 0x01, 0x20, 0x02, 0x20, 0x03, 0x20, + 0x04, 0x20, 0x05, 0x20, 0x06, 0x20, 0x07, 0x20, + 0x08, 0x20, 0x09, 0x20, 0x0a, 0x20, 0x0b, 0x20, + 0x0c, 0x20, 0x0d, 0x20, 0x0e, 0x20, 0x0f, 0x20, + 0x10, 0x20, 0x11, 0x20, 0x12, 0x20, 0x13, 0x20, + 0x14, 0x20, 0x15, 0x20, 0x16, 0x20, 0x17, 0x20, + 0x18, 0x20, 0x19, 0x20, 0x1a, 0x20, 0x1b, 0x20, + 0x1c, 0x20, 0x1d, 0x20, 0x1e, 0x20, 0x1f, 0x20, + 0x20, 0x20, 0x21, 0x20, 0x22, 0x20, 0x23, 0x20, + 0x24, 0x20, 0x25, 0x20, 0x26, 0x20, 0x27, 0x20, + 0x28, 0x20, 0x29, 0x20, 0x2a, 0x20, 0x2b, 0x20, + 0x2c, 0x20, 0x2d, 0x20, 0x2e, 0x20, 0x2f, 0x20, + 0x30, 0x20, 0x31, 0x20, 0x32, 0x20, 0x33, 0x20, + 0x34, 0x20, 0x35, 0x20, 0x36, 0x20, 0x37, 0x20, + 0x38, 0x20, 0x39, 0x20, 0x3a, 0x20, 0x3b, 0x20, + 0x3c, 0x20, 0x3d, 0x20, 0x3e, 0x20, 0x3f, 0x20, + 0x40, 0x20, 0x41, 0x20, 0x42, 0x20, 0x43, 0x20, + 0x44, 0x20, 0x45, 0x20, 0x46, 0x20, 0x47, 0x20, + 0x48, 0x20, 0x49, 0x20, 0x4a, 0x20, 0x4b, 0x20, + 0x4c, 0x20, 0x4d, 0x20, 0x4e, 0x20, 0x4f, 0x20, + 0x50, 0x20, 0x51, 0x20, 0x52, 0x20, 0x53, 0x20, + 0x54, 0x20, 0x55, 0x20, 0x56, 0x20, 0x57, 0x20, + 0x58, 0x20, 0x59, 0x20, 0x5a, 0x20, 0x5b, 0x20, + 0x5c, 0x20, 0x5d, 0x20, 0x5e, 0x20, 0x5f, 0x20, + 0x60, 0x20, 0x61, 0x20, 0x62, 0x20, 0x63, 0x20, + 0x64, 0x20, 0x65, 0x20, 0x66, 0x20, 0x67, 0x20, + 0x68, 0x20, 0x69, 0x20, 0x6a, 0x20, 0x6b, 0x20, + 0x6c, 0x20, 0x6d, 0x20, 0x6e, 0x20, 0x6f, 0x20, + 0x70, 0x20, 0x71, 0x20, 0x72, 0x20, 0x73, 0x20, + 0x74, 0x20, 0x75, 0x20, 0x76, 0x20, 0x77, 0x20, + 0x78, 0x20, 0x79, 0x20, 0x7a, 0x20, 0x7b, 0x20, + 0x7c, 0x20, 0x7d, 0x20, 0x7e, 0x20, 0x7f, 0x20, + 0x80, 0x20, 0x81, 0x20, 0x82, 0x20, 0x83, 0x20, + 0x84, 0x20, 0x85, 0x20, 0x86, 0x20, 0x87, 0x20, + 0x88, 0x20, 0x89, 0x20, 0x8a, 0x20, 0x8b, 0x20, + 0x8c, 0x20, 0x8d, 0x20, 0x8e, 0x20, 0x8f, 0x20, + 0x90, 0x20, 0x91, 0x20, 0x92, 0x20, 0x93, 0x20, + 0x94, 0x20, 0x95, 0x20, 0x96, 0x20, 0x97, 0x20, + 0x98, 0x20, 0x99, 0x20, 0x9a, 0x20, 0x9b, 0x20, + 0x9c, 0x20, 0x9d, 0x20, 0x9e, 0x20, 0x9f, 0x20, + 0xa0, 0x20, 0xa1, 0x20, 0xa2, 0x20, 0xa3, 0x20, + 0xa4, 0x20, 0xa5, 0x20, 0xa6, 0x20, 0xa7, 0x20, + 0xa8, 0x20, 0xa9, 0x20, 0xaa, 0x20, 0xab, 0x20, + 0xac, 0x20, 0xad, 0x20, 0xae, 0x20, 0xaf, 0x20, + 0xb0, 0x20, 0xb1, 0x20, 0xb2, 0x20, 0xb3, 0x20, + 0xb4, 0x20, 0xb5, 0x20, 0xb6, 0x20, 0xb7, 0x20, + 0xb8, 0x20, 0xb9, 0x20, 0xba, 0x20, 0xbb, 0x20, + 0xbc, 0x20, 0xbd, 0x20, 0xbe, 0x20, 0xbf, 0x20, + 0xc0, 0x20, 0xc1, 0x20, 0xc2, 0x20, 0xc3, 0x20, + 0xc4, 0x20, 0xc5, 0x20, 0xc6, 0x20, 0xc7, 0x20, + 0xc8, 0x20, 0xc9, 0x20, 0xca, 0x20, 0xcb, 0x20, + 0xcc, 0x20, 0xcd, 0x20, 0xce, 0x20, 0xcf, 0x20, + 0xd0, 0x20, 0xd1, 0x20, 0xd2, 0x20, 0xd3, 0x20, + 0xd4, 0x20, 0xd5, 0x20, 0xd6, 0x20, 0xd7, 0x20, + 0xd8, 0x20, 0xd9, 0x20, 0xda, 0x20, 0xdb, 0x20, + 0xdc, 0x20, 0xdd, 0x20, 0xde, 0x20, 0xdf, 0x20, + 0xe0, 0x20, 0xe1, 0x20, 0xe2, 0x20, 0xe3, 0x20, + 0xe4, 0x20, 0xe5, 0x20, 0xe6, 0x20, 0xe7, 0x20, + 0xe8, 0x20, 0xe9, 0x20, 0xea, 0x20, 0xeb, 0x20, + 0xec, 0x20, 0xed, 0x20, 0xee, 0x20, 0xef, 0x20, + 0xf0, 0x20, 0xf1, 0x20, 0xf2, 0x20, 0xf3, 0x20, + 0xf4, 0x20, 0xf5, 0x20, 0xf6, 0x20, 0xf7, 0x20, + 0xf8, 0x20, 0xf9, 0x20, 0xfa, 0x20, 0xfb, 0x20, + 0xfc, 0x20, 0xfd, 0x20, 0xfe, 0x20, 0xff, 0x20, + 0x00, 0x21, 0x01, 0x21, 0x02, 0x21, 0x03, 0x21, + 0x04, 0x21, 0x05, 0x21, 0x06, 0x21, 0x07, 0x21, + 0x08, 0x21, 0x09, 0x21, 0x0a, 0x21, 0x0b, 0x21, + 0x0c, 0x21, 0x0d, 0x21, 0x0e, 0x21, 0x0f, 0x21, + 0x10, 0x21, 0x11, 0x21, 0x12, 0x21, 0x13, 0x21, + 0x14, 0x21, 0x15, 0x21, 0x16, 0x21, 0x17, 0x21, + 0x18, 0x21, 0x19, 0x21, 0x1a, 0x21, 0x1b, 0x21, + 0x1c, 0x21, 0x1d, 0x21, 0x1e, 0x21, 0x1f, 0x21, + 0x20, 0x21, 0x21, 0x21, 0x22, 0x21, 0x23, 0x21, + 0x24, 0x21, 0x25, 0x21, 0x26, 0x21, 0x27, 0x21, + 0x28, 0x21, 0x29, 0x21, 0x2a, 0x21, 0x2b, 0x21, + 0x2c, 0x21, 0x2d, 0x21, 0x2e, 0x21, 0x2f, 0x21, + 0x30, 0x21, 0x31, 0x21, 0x32, 0x21, 0x33, 0x21, + 0x34, 0x21, 0x35, 0x21, 0x36, 0x21, 0x37, 0x21, + 0x38, 0x21, 0x39, 0x21, 0x3a, 0x21, 0x3b, 0x21, + 0x3c, 0x21, 0x3d, 0x21, 0x3e, 0x21, 0x3f, 0x21, + 0x40, 0x21, 0x41, 0x21, 0x42, 0x21, 0x43, 0x21, + 0x44, 0x21, 0x45, 0x21, 0x46, 0x21, 0x47, 0x21, + 0x48, 0x21, 0x49, 0x21, 0x4a, 0x21, 0x4b, 0x21, + 0x4c, 0x21, 0x4d, 0x21, 0x32, 0x21, 0x4f, 0x21, + 0x50, 0x21, 0x51, 0x21, 0x52, 0x21, 0x53, 0x21, + 0x54, 0x21, 0x55, 0x21, 0x56, 0x21, 0x57, 0x21, + 0x58, 0x21, 0x59, 0x21, 0x5a, 0x21, 0x5b, 0x21, + 0x5c, 0x21, 0x5d, 0x21, 0x5e, 0x21, 0x5f, 0x21, + 0x60, 0x21, 0x61, 0x21, 0x62, 0x21, 0x63, 0x21, + 0x64, 0x21, 0x65, 0x21, 0x66, 0x21, 0x67, 0x21, + 0x68, 0x21, 0x69, 0x21, 0x6a, 0x21, 0x6b, 0x21, + 0x6c, 0x21, 0x6d, 0x21, 0x6e, 0x21, 0x6f, 0x21, + 0x60, 0x21, 0x61, 0x21, 0x62, 0x21, 0x63, 0x21, + 0x64, 0x21, 0x65, 0x21, 0x66, 0x21, 0x67, 0x21, + 0x68, 0x21, 0x69, 0x21, 0x6a, 0x21, 0x6b, 0x21, + 0x6c, 0x21, 0x6d, 0x21, 0x6e, 0x21, 0x6f, 0x21, + 0x80, 0x21, 0x81, 0x21, 0x82, 0x21, 0x83, 0x21, + 0x83, 0x21, 0xff, 0xff, 0x4b, 0x03, 0xb6, 0x24, + 0xb7, 0x24, 0xb8, 0x24, 0xb9, 0x24, 0xba, 0x24, + 0xbb, 0x24, 0xbc, 0x24, 0xbd, 0x24, 0xbe, 0x24, + 0xbf, 0x24, 0xc0, 0x24, 0xc1, 0x24, 0xc2, 0x24, + 0xc3, 0x24, 0xc4, 0x24, 0xc5, 0x24, 0xc6, 0x24, + 0xc7, 0x24, 0xc8, 0x24, 0xc9, 0x24, 0xca, 0x24, + 0xcb, 0x24, 0xcc, 0x24, 0xcd, 0x24, 0xce, 0x24, + 0xcf, 0x24, 0xff, 0xff, 0x46, 0x07, 0x00, 0x2c, + 0x01, 0x2c, 0x02, 0x2c, 0x03, 0x2c, 0x04, 0x2c, + 0x05, 0x2c, 0x06, 0x2c, 0x07, 0x2c, 0x08, 0x2c, + 0x09, 0x2c, 0x0a, 0x2c, 0x0b, 0x2c, 0x0c, 0x2c, + 0x0d, 0x2c, 0x0e, 0x2c, 0x0f, 0x2c, 0x10, 0x2c, + 0x11, 0x2c, 0x12, 0x2c, 0x13, 0x2c, 0x14, 0x2c, + 0x15, 0x2c, 0x16, 0x2c, 0x17, 0x2c, 0x18, 0x2c, + 0x19, 0x2c, 0x1a, 0x2c, 0x1b, 0x2c, 0x1c, 0x2c, + 0x1d, 0x2c, 0x1e, 0x2c, 0x1f, 0x2c, 0x20, 0x2c, + 0x21, 0x2c, 0x22, 0x2c, 0x23, 0x2c, 0x24, 0x2c, + 0x25, 0x2c, 0x26, 0x2c, 0x27, 0x2c, 0x28, 0x2c, + 0x29, 0x2c, 0x2a, 0x2c, 0x2b, 0x2c, 0x2c, 0x2c, + 0x2d, 0x2c, 0x2e, 0x2c, 0x5f, 0x2c, 0x60, 0x2c, + 0x60, 0x2c, 0x62, 0x2c, 0x63, 0x2c, 0x64, 0x2c, + 0x65, 0x2c, 0x66, 0x2c, 0x67, 0x2c, 0x67, 0x2c, + 0x69, 0x2c, 0x69, 0x2c, 0x6b, 0x2c, 0x6b, 0x2c, + 0x6d, 0x2c, 0x6e, 0x2c, 0x6f, 0x2c, 0x70, 0x2c, + 0x71, 0x2c, 0x72, 0x2c, 0x73, 0x2c, 0x74, 0x2c, + 0x75, 0x2c, 0x75, 0x2c, 0x77, 0x2c, 0x78, 0x2c, + 0x79, 0x2c, 0x7a, 0x2c, 0x7b, 0x2c, 0x7c, 0x2c, + 0x7d, 0x2c, 0x7e, 0x2c, 0x7f, 0x2c, 0x80, 0x2c, + 0x80, 0x2c, 0x82, 0x2c, 0x82, 0x2c, 0x84, 0x2c, + 0x84, 0x2c, 0x86, 0x2c, 0x86, 0x2c, 0x88, 0x2c, + 0x88, 0x2c, 0x8a, 0x2c, 0x8a, 0x2c, 0x8c, 0x2c, + 0x8c, 0x2c, 0x8e, 0x2c, 0x8e, 0x2c, 0x90, 0x2c, + 0x90, 0x2c, 0x92, 0x2c, 0x92, 0x2c, 0x94, 0x2c, + 0x94, 0x2c, 0x96, 0x2c, 0x96, 0x2c, 0x98, 0x2c, + 0x98, 0x2c, 0x9a, 0x2c, 0x9a, 0x2c, 0x9c, 0x2c, + 0x9c, 0x2c, 0x9e, 0x2c, 0x9e, 0x2c, 0xa0, 0x2c, + 0xa0, 0x2c, 0xa2, 0x2c, 0xa2, 0x2c, 0xa4, 0x2c, + 0xa4, 0x2c, 0xa6, 0x2c, 0xa6, 0x2c, 0xa8, 0x2c, + 0xa8, 0x2c, 0xaa, 0x2c, 0xaa, 0x2c, 0xac, 0x2c, + 0xac, 0x2c, 0xae, 0x2c, 0xae, 0x2c, 0xb0, 0x2c, + 0xb0, 0x2c, 0xb2, 0x2c, 0xb2, 0x2c, 0xb4, 0x2c, + 0xb4, 0x2c, 0xb6, 0x2c, 0xb6, 0x2c, 0xb8, 0x2c, + 0xb8, 0x2c, 0xba, 0x2c, 0xba, 0x2c, 0xbc, 0x2c, + 0xbc, 0x2c, 0xbe, 0x2c, 0xbe, 0x2c, 0xc0, 0x2c, + 0xc0, 0x2c, 0xc2, 0x2c, 0xc2, 0x2c, 0xc4, 0x2c, + 0xc4, 0x2c, 0xc6, 0x2c, 0xc6, 0x2c, 0xc8, 0x2c, + 0xc8, 0x2c, 0xca, 0x2c, 0xca, 0x2c, 0xcc, 0x2c, + 0xcc, 0x2c, 0xce, 0x2c, 0xce, 0x2c, 0xd0, 0x2c, + 0xd0, 0x2c, 0xd2, 0x2c, 0xd2, 0x2c, 0xd4, 0x2c, + 0xd4, 0x2c, 0xd6, 0x2c, 0xd6, 0x2c, 0xd8, 0x2c, + 0xd8, 0x2c, 0xda, 0x2c, 0xda, 0x2c, 0xdc, 0x2c, + 0xdc, 0x2c, 0xde, 0x2c, 0xde, 0x2c, 0xe0, 0x2c, + 0xe0, 0x2c, 0xe2, 0x2c, 0xe2, 0x2c, 0xe4, 0x2c, + 0xe5, 0x2c, 0xe6, 0x2c, 0xe7, 0x2c, 0xe8, 0x2c, + 0xe9, 0x2c, 0xea, 0x2c, 0xeb, 0x2c, 0xec, 0x2c, + 0xed, 0x2c, 0xee, 0x2c, 0xef, 0x2c, 0xf0, 0x2c, + 0xf1, 0x2c, 0xf2, 0x2c, 0xf3, 0x2c, 0xf4, 0x2c, + 0xf5, 0x2c, 0xf6, 0x2c, 0xf7, 0x2c, 0xf8, 0x2c, + 0xf9, 0x2c, 0xfa, 0x2c, 0xfb, 0x2c, 0xfc, 0x2c, + 0xfd, 0x2c, 0xfe, 0x2c, 0xff, 0x2c, 0xa0, 0x10, + 0xa1, 0x10, 0xa2, 0x10, 0xa3, 0x10, 0xa4, 0x10, + 0xa5, 0x10, 0xa6, 0x10, 0xa7, 0x10, 0xa8, 0x10, + 0xa9, 0x10, 0xaa, 0x10, 0xab, 0x10, 0xac, 0x10, + 0xad, 0x10, 0xae, 0x10, 0xaf, 0x10, 0xb0, 0x10, + 0xb1, 0x10, 0xb2, 0x10, 0xb3, 0x10, 0xb4, 0x10, + 0xb5, 0x10, 0xb6, 0x10, 0xb7, 0x10, 0xb8, 0x10, + 0xb9, 0x10, 0xba, 0x10, 0xbb, 0x10, 0xbc, 0x10, + 0xbd, 0x10, 0xbe, 0x10, 0xbf, 0x10, 0xc0, 0x10, + 0xc1, 0x10, 0xc2, 0x10, 0xc3, 0x10, 0xc4, 0x10, + 0xc5, 0x10, 0xff, 0xff, 0x1b, 0xd2, 0x21, 0xff, + 0x22, 0xff, 0x23, 0xff, 0x24, 0xff, 0x25, 0xff, + 0x26, 0xff, 0x27, 0xff, 0x28, 0xff, 0x29, 0xff, + 0x2a, 0xff, 0x2b, 0xff, 0x2c, 0xff, 0x2d, 0xff, + 0x2e, 0xff, 0x2f, 0xff, 0x30, 0xff, 0x31, 0xff, + 0x32, 0xff, 0x33, 0xff, 0x34, 0xff, 0x35, 0xff, + 0x36, 0xff, 0x37, 0xff, 0x38, 0xff, 0x39, 0xff, + 0x3a, 0xff, 0x5b, 0xff, 0x5c, 0xff, 0x5d, 0xff, + 0x5e, 0xff, 0x5f, 0xff, 0x60, 0xff, 0x61, 0xff, + 0x62, 0xff, 0x63, 0xff, 0x64, 0xff, 0x65, 0xff, + 0x66, 0xff, 0x67, 0xff, 0x68, 0xff, 0x69, 0xff, + 0x6a, 0xff, 0x6b, 0xff, 0x6c, 0xff, 0x6d, 0xff, + 0x6e, 0xff, 0x6f, 0xff, 0x70, 0xff, 0x71, 0xff, + 0x72, 0xff, 0x73, 0xff, 0x74, 0xff, 0x75, 0xff, + 0x76, 0xff, 0x77, 0xff, 0x78, 0xff, 0x79, 0xff, + 0x7a, 0xff, 0x7b, 0xff, 0x7c, 0xff, 0x7d, 0xff, + 0x7e, 0xff, 0x7f, 0xff, 0x80, 0xff, 0x81, 0xff, + 0x82, 0xff, 0x83, 0xff, 0x84, 0xff, 0x85, 0xff, + 0x86, 0xff, 0x87, 0xff, 0x88, 0xff, 0x89, 0xff, + 0x8a, 0xff, 0x8b, 0xff, 0x8c, 0xff, 0x8d, 0xff, + 0x8e, 0xff, 0x8f, 0xff, 0x90, 0xff, 0x91, 0xff, + 0x92, 0xff, 0x93, 0xff, 0x94, 0xff, 0x95, 0xff, + 0x96, 0xff, 0x97, 0xff, 0x98, 0xff, 0x99, 0xff, + 0x9a, 0xff, 0x9b, 0xff, 0x9c, 0xff, 0x9d, 0xff, + 0x9e, 0xff, 0x9f, 0xff, 0xa0, 0xff, 0xa1, 0xff, + 0xa2, 0xff, 0xa3, 0xff, 0xa4, 0xff, 0xa5, 0xff, + 0xa6, 0xff, 0xa7, 0xff, 0xa8, 0xff, 0xa9, 0xff, + 0xaa, 0xff, 0xab, 0xff, 0xac, 0xff, 0xad, 0xff, + 0xae, 0xff, 0xaf, 0xff, 0xb0, 0xff, 0xb1, 0xff, + 0xb2, 0xff, 0xb3, 0xff, 0xb4, 0xff, 0xb5, 0xff, + 0xb6, 0xff, 0xb7, 0xff, 0xb8, 0xff, 0xb9, 0xff, + 0xba, 0xff, 0xbb, 0xff, 0xbc, 0xff, 0xbd, 0xff, + 0xbe, 0xff, 0xbf, 0xff, 0xc0, 0xff, 0xc1, 0xff, + 0xc2, 0xff, 0xc3, 0xff, 0xc4, 0xff, 0xc5, 0xff, + 0xc6, 0xff, 0xc7, 0xff, 0xc8, 0xff, 0xc9, 0xff, + 0xca, 0xff, 0xcb, 0xff, 0xcc, 0xff, 0xcd, 0xff, + 0xce, 0xff, 0xcf, 0xff, 0xd0, 0xff, 0xd1, 0xff, + 0xd2, 0xff, 0xd3, 0xff, 0xd4, 0xff, 0xd5, 0xff, + 0xd6, 0xff, 0xd7, 0xff, 0xd8, 0xff, 0xd9, 0xff, + 0xda, 0xff, 0xdb, 0xff, 0xdc, 0xff, 0xdd, 0xff, + 0xde, 0xff, 0xdf, 0xff, 0xe0, 0xff, 0xe1, 0xff, + 0xe2, 0xff, 0xe3, 0xff, 0xe4, 0xff, 0xe5, 0xff, + 0xe6, 0xff, 0xe7, 0xff, 0xe8, 0xff, 0xe9, 0xff, + 0xea, 0xff, 0xeb, 0xff, 0xec, 0xff, 0xed, 0xff, + 0xee, 0xff, 0xef, 0xff, 0xf0, 0xff, 0xf1, 0xff, + 0xf2, 0xff, 0xf3, 0xff, 0xf4, 0xff, 0xf5, 0xff, + 0xf6, 0xff, 0xf7, 0xff, 0xf8, 0xff, 0xf9, 0xff, + 0xfa, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfd, 0xff, + 0xfe, 0xff, 0xff, 0xff +}; diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uctc.h b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uctc.h new file mode 100644 index 0000000..bd5ebb2 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uctc.h @@ -0,0 +1,30 @@ +/* + uctc.h (30.10.10) + Upper Case Table declaration. + + Free exFAT implementation. + Copyright (C) 2011-2018 Andrew Nayenko + + 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. +*/ + +#ifndef MKFS_UCTC_H_INCLUDED +#define MKFS_UCTC_H_INCLUDED + +#include + +extern uint8_t upcase_table[5836]; + +#endif /* ifndef MKFS_UCTC_H_INCLUDED */ diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/vbr.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/vbr.c new file mode 100644 index 0000000..e40081f --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/vbr.c @@ -0,0 +1,148 @@ +/* + vbr.c (09.11.10) + Volume Boot Record creation code. + + Free exFAT implementation. + Copyright (C) 2011-2018 Andrew Nayenko + + 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. +*/ + +#include "vbr.h" +#include "fat.h" +#include "cbm.h" +#include "uct.h" +#include "rootdir.h" +#include + +static off_t vbr_alignment(void) +{ + return get_sector_size(); +} + +static off_t vbr_size(void) +{ + return 12 * get_sector_size(); +} + +static void init_sb(struct exfat_super_block* sb) +{ + uint32_t clusters_max; + uint32_t fat_sectors; + + clusters_max = get_volume_size() / get_cluster_size(); + fat_sectors = DIV_ROUND_UP((off_t) clusters_max * sizeof(cluster_t), + get_sector_size()); + + memset(sb, 0, sizeof(struct exfat_super_block)); + sb->jump[0] = 0xeb; + sb->jump[1] = 0x76; + sb->jump[2] = 0x90; + memcpy(sb->oem_name, "EXFAT ", sizeof(sb->oem_name)); + sb->sector_start = cpu_to_le64(get_first_sector()); + sb->sector_count = cpu_to_le64(get_volume_size() / get_sector_size()); + sb->fat_sector_start = cpu_to_le32( + fat.get_alignment() / get_sector_size()); + sb->fat_sector_count = cpu_to_le32(ROUND_UP( + le32_to_cpu(sb->fat_sector_start) + fat_sectors, + 1 << get_spc_bits()) - + le32_to_cpu(sb->fat_sector_start)); + sb->cluster_sector_start = cpu_to_le32( + get_position(&cbm) / get_sector_size()); + sb->cluster_count = cpu_to_le32(clusters_max - + ((le32_to_cpu(sb->fat_sector_start) + + le32_to_cpu(sb->fat_sector_count)) >> get_spc_bits())); + sb->rootdir_cluster = cpu_to_le32( + (get_position(&rootdir) - get_position(&cbm)) / get_cluster_size() + + EXFAT_FIRST_DATA_CLUSTER); + sb->volume_serial = cpu_to_le32(get_volume_serial()); + sb->version.major = 1; + sb->version.minor = 0; + sb->volume_state = cpu_to_le16(0); + sb->sector_bits = get_sector_bits(); + sb->spc_bits = get_spc_bits(); + sb->fat_count = 1; + sb->drive_no = 0x80; + sb->allocated_percent = 0; + sb->boot_signature = cpu_to_le16(0xaa55); +} + +static int vbr_write(struct exfat_dev* dev) +{ + struct exfat_super_block sb; + uint32_t checksum; + le32_t* sector = malloc(get_sector_size()); + size_t i; + + if (sector == NULL) + { + exfat_error("failed to allocate sector-sized block of memory"); + return 1; + } + + init_sb(&sb); + if (exfat_write(dev, &sb, sizeof(struct exfat_super_block)) < 0) + { + free(sector); + exfat_error("failed to write super block sector"); + return 1; + } + checksum = exfat_vbr_start_checksum(&sb, sizeof(struct exfat_super_block)); + + memset(sector, 0, get_sector_size()); + sector[get_sector_size() / sizeof(sector[0]) - 1] = + cpu_to_le32(0xaa550000); + for (i = 0; i < 8; i++) + { + if (exfat_write(dev, sector, get_sector_size()) < 0) + { + free(sector); + exfat_error("failed to write a sector with boot signature"); + return 1; + } + checksum = exfat_vbr_add_checksum(sector, get_sector_size(), checksum); + } + + memset(sector, 0, get_sector_size()); + for (i = 0; i < 2; i++) + { + if (exfat_write(dev, sector, get_sector_size()) < 0) + { + free(sector); + exfat_error("failed to write an empty sector"); + return 1; + } + checksum = exfat_vbr_add_checksum(sector, get_sector_size(), checksum); + } + + for (i = 0; i < get_sector_size() / sizeof(sector[0]); i++) + sector[i] = cpu_to_le32(checksum); + if (exfat_write(dev, sector, get_sector_size()) < 0) + { + free(sector); + exfat_error("failed to write checksum sector"); + return 1; + } + + free(sector); + return 0; +} + +const struct fs_object vbr = +{ + .get_alignment = vbr_alignment, + .get_size = vbr_size, + .write = vbr_write, +}; diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/vbr.h b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/vbr.h new file mode 100644 index 0000000..c1f59a6 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/vbr.h @@ -0,0 +1,30 @@ +/* + vbr.h (09.11.10) + Volume Boot Record creation code. + + Free exFAT implementation. + Copyright (C) 2011-2018 Andrew Nayenko + + 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. +*/ + +#ifndef MKFS_VBR_H_INCLUDED +#define MKFS_VBR_H_INCLUDED + +#include "mkexfat.h" + +extern const struct fs_object vbr; + +#endif /* ifndef MKFS_VBR_H_INCLUDED */ diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/API.txt b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/API.txt new file mode 100644 index 0000000..61fc164 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/API.txt @@ -0,0 +1,22 @@ +File IO Lib API +-=-=-=-=-=-=-=-=- + +void fl_init(void) + + Called to initialize FAT IO library. + This should be called prior to any other functions. + +void fl_attach_locks(void (*lock)(void), void (*unlock)(void)) + + [Optional] File system thread safety locking functions. + For thread safe operation, you should provide lock() and unlock() functions. + Note that locking primitive used must support recursive locking, i.e lock() called within an already ‘locked’ region. + +int fl_attach_media(fn_diskio_read rd, fn_diskio_write wr) + + This function is used to attach system specific disk/media access functions. + This should be done subsequent to calling fl_init() and fl_attach_locks() (if locking required). + +void fl_shutdown(void) + + Shutdown the FAT IO library. This purges any un-saved data back to disk. diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/COPYRIGHT.txt b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/COPYRIGHT.txt new file mode 100644 index 0000000..4335f7f --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/COPYRIGHT.txt @@ -0,0 +1,345 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/Configuration.txt b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/Configuration.txt new file mode 100644 index 0000000..9ec576e --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/Configuration.txt @@ -0,0 +1,53 @@ +File IO Lib Options +-=-=-=-=-=-=-=-=-=- + +See defines in fat_opts.h: + +FATFS_IS_LITTLE_ENDIAN [1/0] + Which endian is your system? Set to 1 for little endian, 0 for big endian. + +FATFS_MAX_LONG_FILENAME [260] + By default, 260 characters (max LFN length). Increase this to support greater path depths. + +FATFS_MAX_OPEN_FILES + The more files you wish to have concurrently open, the greater this number should be. + This increases the number of FL_FILE file structures in the library, each of these is around 1K in size (assuming 512 byte sectors). + +FAT_BUFFER_SECTORS + Minimum is 1, more increases performance. + This defines how many FAT sectors can be buffered per FAT_BUFFER entry. + +FAT_BUFFERS + Minimum is 1, more increases performance. + This defines how many FAT buffer entries are available. + Memory usage is FAT_BUFFERS * FAT_BUFFER_SECTORS * FAT_SECTOR_SIZE + +FATFS_INC_WRITE_SUPPORT + Support file write functionality. + +FAT_SECTOR_SIZE + Sector size used by buffers. Most likely to be 512 bytes (standard for ATA/IDE). + +FAT_PRINTF + A define that allows the File IO library to print to console/stdout. + Provide your own printf function if printf not available. + +FAT_CLUSTER_CACHE_ENTRIES + Size of cluster chain cache (can be undefined if not required). + Mem used = FAT_CLUSTER_CACHE_ENTRIES * 4 * 2 + Improves access speed considerably. + +FATFS_INC_LFN_SUPPORT [1/0] + Enable/Disable support for long filenames. + +FATFS_DIR_LIST_SUPPORT [1/0] + Include support for directory listing. + +FATFS_INC_TIME_DATE_SUPPORT [1/0] + Use time/date functions provided by time.h to update creation & modification timestamps. + +FATFS_INC_FORMAT_SUPPORT + Include support for formatting disks (FAT16 only). + +FAT_PRINTF_NOINC_STDIO + Disable use of printf & inclusion of stdio.h diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/History.txt b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/History.txt new file mode 100644 index 0000000..58958f4 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/History.txt @@ -0,0 +1,24 @@ +Revision History +-=-=-=-=-=-=-=-=- +v2.6.11 - Fix compilation with GCC on 64-bit machines +v2.6.10 - Added support for FAT32 format. +V2.6.9 - Added support for time & date handling. +V2.6.8 - Fixed error with FSINFO sector write. +V2.6.7 - Added fgets(). + Fixed C warnings, removed dependancy on some string.h functions. +V2.6.6 – Massive read + write performance improvements. +V2.6.5 – Bug fixes for big endian systems. +V2.6.4 – Further bug fixes and performance improvements for write operations. +V2.6.3 – Peformance improvements, FAT16 formatting support. Various bug fixes. +V2.6 - Basic support for FAT16 added (18-04-10). +V2.5 - Code cleaned up. Many bugs fixed. Thread safety functions added. +V2.x - Write support added as well as better stdio like API. +V1.0 - Rewrite of all code to enable multiple files to be opened and provides a + better file API. + Also better string matching, and generally better C code than origonal + version. +V0.1c - Fetch_ID_Max_LBA() function added to retrieve Drive infomation and stoping + the drive reads from addressing a sector that is out of range. +V0.1b - fopen(), fgetc(), fopenDIR() using new software stack for IDE and FAT32 + access. +V0.1a - First release (27/12/03); fopen(), fgetc() unbuffered reads. diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/License.txt b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/License.txt new file mode 100644 index 0000000..c7fb0cc --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/License.txt @@ -0,0 +1,10 @@ +FAT File IO Library License +-=-=-=-=-=-=-=-=-=-=-=-=-=- + +This versions license: GPL + +If you include GPL software in your project, you must release the source code of that project too. + +If you would like a version with a more permissive license for use in closed source commercial applications please contact me for details. + +Email: admin@ultra-embedded.com diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/Media Access API.txt b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/Media Access API.txt new file mode 100644 index 0000000..45eede0 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/Media Access API.txt @@ -0,0 +1,40 @@ +Media Access API +-=-=-=-=-=-=-=-=- + +int media_read(uint32 sector, uint8 *buffer, uint32 sector_count) + +Params: + Sector: 32-bit sector number + Buffer: Target buffer to read n sectors of data into. + Sector_count: Number of sectors to read. + +Return: + int, 1 = success, 0 = failure. + +Description: + Application/target specific disk/media read function. + Sector number (sectors are usually 512 byte pages) to read. + +Media Write API + +int media_write(uint32 sector, uint8 *buffer, uint32 sector_count) + +Params: + Sector: 32-bit sector number + Buffer: Target buffer to write n sectors of data from. + Sector_count: Number of sectors to write. + +Return: + int, 1 = success, 0 = failure. + +Description: + Application/target specific disk/media write function. + Sector number (sectors are usually 512 byte pages) to write to. + +File IO Library Linkage + Use the following API to attach the media IO functions to the File IO library. + + int fl_attach_media(fn_diskio_read rd, fn_diskio_write wr) + + + diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_access.c b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_access.c new file mode 100644 index 0000000..f55bd59 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_access.c @@ -0,0 +1,904 @@ +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// FAT16/32 File IO Library +// V2.6 +// Ultra-Embedded.com +// Copyright 2003 - 2012 +// +// Email: admin@ultra-embedded.com +// +// License: GPL +// If you would like a version with a more permissive license for use in +// closed source commercial applications please contact me for details. +//----------------------------------------------------------------------------- +// +// This file is part of FAT File IO Library. +// +// FAT File IO Library 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. +// +// FAT File IO 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FAT File IO Library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +#include +#include "fat_defs.h" +#include "fat_access.h" +#include "fat_table.h" +#include "fat_write.h" +#include "fat_string.h" +#include "fat_misc.h" + +//----------------------------------------------------------------------------- +// fatfs_init: Load FAT Parameters +//----------------------------------------------------------------------------- +int fatfs_init(struct fatfs *fs) +{ + uint8 num_of_fats; + uint16 reserved_sectors; + uint32 FATSz; + uint32 root_dir_sectors; + uint32 total_sectors; + uint32 data_sectors; + uint32 count_of_clusters; + uint8 valid_partition = 0; + + fs->currentsector.address = FAT32_INVALID_CLUSTER; + fs->currentsector.dirty = 0; + + fs->next_free_cluster = 0; // Invalid + + fatfs_fat_init(fs); + + // Make sure we have a read function (write function is optional) + if (!fs->disk_io.read_media) + return FAT_INIT_MEDIA_ACCESS_ERROR; + + // MBR: Sector 0 on the disk + // NOTE: Some removeable media does not have this. + + // Load MBR (LBA 0) into the 512 byte buffer + if (!fs->disk_io.read_media(0, fs->currentsector.sector, 1)) + return FAT_INIT_MEDIA_ACCESS_ERROR; + + // Make Sure 0x55 and 0xAA are at end of sector + // (this should be the case regardless of the MBR or boot sector) + if (fs->currentsector.sector[SIGNATURE_POSITION] != 0x55 || fs->currentsector.sector[SIGNATURE_POSITION+1] != 0xAA) + return FAT_INIT_INVALID_SIGNATURE; + + // Now check again using the access function to prove endian conversion function + if (GET_16BIT_WORD(fs->currentsector.sector, SIGNATURE_POSITION) != SIGNATURE_VALUE) + return FAT_INIT_ENDIAN_ERROR; + + // Verify packed structures + if (sizeof(struct fat_dir_entry) != FAT_DIR_ENTRY_SIZE) + return FAT_INIT_STRUCT_PACKING; + + // Check the partition type code + switch(fs->currentsector.sector[PARTITION1_TYPECODE_LOCATION]) + { + case 0x0B: + case 0x06: + case 0x0C: + case 0x0E: + case 0x0F: + case 0x05: + valid_partition = 1; + break; + case 0x00: + valid_partition = 0; + break; + default: + if (fs->currentsector.sector[PARTITION1_TYPECODE_LOCATION] <= 0x06) + valid_partition = 1; + break; + } + + // Read LBA Begin for the file system + if (valid_partition) + fs->lba_begin = GET_32BIT_WORD(fs->currentsector.sector, PARTITION1_LBA_BEGIN_LOCATION); + // Else possibly MBR less disk + else + fs->lba_begin = 0; + + // Load Volume 1 table into sector buffer + // (We may already have this in the buffer if MBR less drive!) + if (!fs->disk_io.read_media(fs->lba_begin, fs->currentsector.sector, 1)) + return FAT_INIT_MEDIA_ACCESS_ERROR; + + // Make sure there are 512 bytes per cluster + if (GET_16BIT_WORD(fs->currentsector.sector, 0x0B) != FAT_SECTOR_SIZE) + return FAT_INIT_INVALID_SECTOR_SIZE; + + // Load Parameters of FAT partition + fs->sectors_per_cluster = fs->currentsector.sector[BPB_SECPERCLUS]; + reserved_sectors = GET_16BIT_WORD(fs->currentsector.sector, BPB_RSVDSECCNT); + num_of_fats = fs->currentsector.sector[BPB_NUMFATS]; + fs->root_entry_count = GET_16BIT_WORD(fs->currentsector.sector, BPB_ROOTENTCNT); + + if(GET_16BIT_WORD(fs->currentsector.sector, BPB_FATSZ16) != 0) + fs->fat_sectors = GET_16BIT_WORD(fs->currentsector.sector, BPB_FATSZ16); + else + fs->fat_sectors = GET_32BIT_WORD(fs->currentsector.sector, BPB_FAT32_FATSZ32); + + // For FAT32 (which this may be) + fs->rootdir_first_cluster = GET_32BIT_WORD(fs->currentsector.sector, BPB_FAT32_ROOTCLUS); + fs->fs_info_sector = GET_16BIT_WORD(fs->currentsector.sector, BPB_FAT32_FSINFO); + + // For FAT16 (which this may be), rootdir_first_cluster is actuall rootdir_first_sector + fs->rootdir_first_sector = reserved_sectors + (num_of_fats * fs->fat_sectors); + fs->rootdir_sectors = ((fs->root_entry_count * 32) + (FAT_SECTOR_SIZE - 1)) / FAT_SECTOR_SIZE; + + // First FAT LBA address + fs->fat_begin_lba = fs->lba_begin + reserved_sectors; + + // The address of the first data cluster on this volume + fs->cluster_begin_lba = fs->fat_begin_lba + (num_of_fats * fs->fat_sectors); + + if (GET_16BIT_WORD(fs->currentsector.sector, 0x1FE) != 0xAA55) // This signature should be AA55 + return FAT_INIT_INVALID_SIGNATURE; + + // Calculate the root dir sectors + root_dir_sectors = ((GET_16BIT_WORD(fs->currentsector.sector, BPB_ROOTENTCNT) * 32) + (GET_16BIT_WORD(fs->currentsector.sector, BPB_BYTSPERSEC) - 1)) / GET_16BIT_WORD(fs->currentsector.sector, BPB_BYTSPERSEC); + + if(GET_16BIT_WORD(fs->currentsector.sector, BPB_FATSZ16) != 0) + FATSz = GET_16BIT_WORD(fs->currentsector.sector, BPB_FATSZ16); + else + FATSz = GET_32BIT_WORD(fs->currentsector.sector, BPB_FAT32_FATSZ32); + + if(GET_16BIT_WORD(fs->currentsector.sector, BPB_TOTSEC16) != 0) + total_sectors = GET_16BIT_WORD(fs->currentsector.sector, BPB_TOTSEC16); + else + total_sectors = GET_32BIT_WORD(fs->currentsector.sector, BPB_TOTSEC32); + + data_sectors = total_sectors - (GET_16BIT_WORD(fs->currentsector.sector, BPB_RSVDSECCNT) + (fs->currentsector.sector[BPB_NUMFATS] * FATSz) + root_dir_sectors); + + // Find out which version of FAT this is... + if (fs->sectors_per_cluster != 0) + { + count_of_clusters = data_sectors / fs->sectors_per_cluster; + + if(count_of_clusters < 4085) + // Volume is FAT12 + return FAT_INIT_WRONG_FILESYS_TYPE; + else if(count_of_clusters < 65525) + { + // Clear this FAT32 specific param + fs->rootdir_first_cluster = 0; + + // Volume is FAT16 + fs->fat_type = FAT_TYPE_16; + return FAT_INIT_OK; + } + else + { + // Volume is FAT32 + fs->fat_type = FAT_TYPE_32; + return FAT_INIT_OK; + } + } + else + return FAT_INIT_WRONG_FILESYS_TYPE; +} +//----------------------------------------------------------------------------- +// fatfs_lba_of_cluster: This function converts a cluster number into a sector / +// LBA number. +//----------------------------------------------------------------------------- +uint32 fatfs_lba_of_cluster(struct fatfs *fs, uint32 Cluster_Number) +{ + if (fs->fat_type == FAT_TYPE_16) + return (fs->cluster_begin_lba + (fs->root_entry_count * 32 / FAT_SECTOR_SIZE) + ((Cluster_Number-2) * fs->sectors_per_cluster)); + else + return ((fs->cluster_begin_lba + ((Cluster_Number-2)*fs->sectors_per_cluster))); +} +//----------------------------------------------------------------------------- +// fatfs_sector_read: +//----------------------------------------------------------------------------- +int fatfs_sector_read(struct fatfs *fs, uint32 lba, uint8 *target, uint32 count) +{ + return fs->disk_io.read_media(lba, target, count); +} +//----------------------------------------------------------------------------- +// fatfs_sector_write: +//----------------------------------------------------------------------------- +int fatfs_sector_write(struct fatfs *fs, uint32 lba, uint8 *target, uint32 count) +{ + return fs->disk_io.write_media(lba, target, count); +} +//----------------------------------------------------------------------------- +// fatfs_sector_reader: From the provided startcluster and sector offset +// Returns True if success, returns False if not (including if read out of range) +//----------------------------------------------------------------------------- +int fatfs_sector_reader(struct fatfs *fs, uint32 start_cluster, uint32 offset, uint8 *target) +{ + uint32 sector_to_read = 0; + uint32 cluster_to_read = 0; + uint32 cluster_chain = 0; + uint32 i; + uint32 lba; + + // FAT16 Root directory + if (fs->fat_type == FAT_TYPE_16 && start_cluster == 0) + { + if (offset < fs->rootdir_sectors) + lba = fs->lba_begin + fs->rootdir_first_sector + offset; + else + return 0; + } + // FAT16/32 Other + else + { + // Set start of cluster chain to initial value + cluster_chain = start_cluster; + + // Find parameters + cluster_to_read = offset / fs->sectors_per_cluster; + sector_to_read = offset - (cluster_to_read*fs->sectors_per_cluster); + + // Follow chain to find cluster to read + for (i=0; idisk_io.read_media(lba, target, 1); + // Else read sector if not already loaded + else if (lba != fs->currentsector.address) + { + fs->currentsector.address = lba; + return fs->disk_io.read_media(fs->currentsector.address, fs->currentsector.sector, 1); + } + else + return 1; +} +//----------------------------------------------------------------------------- +// fatfs_read_sector: Read from the provided cluster and sector offset +// Returns True if success, returns False if not +//----------------------------------------------------------------------------- +int fatfs_read_sector(struct fatfs *fs, uint32 cluster, uint32 sector, uint8 *target) +{ + // FAT16 Root directory + if (fs->fat_type == FAT_TYPE_16 && cluster == 0) + { + uint32 lba; + + // In FAT16, there are a limited amount of sectors in root dir! + if (sector < fs->rootdir_sectors) + lba = fs->lba_begin + fs->rootdir_first_sector + sector; + else + return 0; + + // User target buffer passed in + if (target) + { + // Read from disk + return fs->disk_io.read_media(lba, target, 1); + } + else + { + // Calculate read address + fs->currentsector.address = lba; + + // Read from disk + return fs->disk_io.read_media(fs->currentsector.address, fs->currentsector.sector, 1); + } + } + // FAT16/32 Other + else + { + // User target buffer passed in + if (target) + { + // Calculate read address + uint32 lba = fatfs_lba_of_cluster(fs, cluster) + sector; + + // Read from disk + return fs->disk_io.read_media(lba, target, 1); + } + else + { + // Calculate write address + fs->currentsector.address = fatfs_lba_of_cluster(fs, cluster)+sector; + + // Read from disk + return fs->disk_io.read_media(fs->currentsector.address, fs->currentsector.sector, 1); + } + } +} +//----------------------------------------------------------------------------- +// fatfs_write_sector: Write to the provided cluster and sector offset +// Returns True if success, returns False if not +//----------------------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +int fatfs_write_sector(struct fatfs *fs, uint32 cluster, uint32 sector, uint8 *target) +{ + // No write access? + if (!fs->disk_io.write_media) + return 0; + + // FAT16 Root directory + if (fs->fat_type == FAT_TYPE_16 && cluster == 0) + { + uint32 lba; + + // In FAT16 we cannot extend the root dir! + if (sector < fs->rootdir_sectors) + lba = fs->lba_begin + fs->rootdir_first_sector + sector; + else + return 0; + + // User target buffer passed in + if (target) + { + // Write to disk + return fs->disk_io.write_media(lba, target, 1); + } + else + { + // Calculate write address + fs->currentsector.address = lba; + + // Write to disk + return fs->disk_io.write_media(fs->currentsector.address, fs->currentsector.sector, 1); + } + } + // FAT16/32 Other + else + { + // User target buffer passed in + if (target) + { + // Calculate write address + uint32 lba = fatfs_lba_of_cluster(fs, cluster) + sector; + + // Write to disk + return fs->disk_io.write_media(lba, target, 1); + } + else + { + // Calculate write address + fs->currentsector.address = fatfs_lba_of_cluster(fs, cluster)+sector; + + // Write to disk + return fs->disk_io.write_media(fs->currentsector.address, fs->currentsector.sector, 1); + } + } +} +#endif +//----------------------------------------------------------------------------- +// fatfs_show_details: Show the details about the filesystem +//----------------------------------------------------------------------------- +void fatfs_show_details(struct fatfs *fs) +{ + FAT_PRINTF(("FAT details:\r\n")); + FAT_PRINTF((" Type =%s", (fs->fat_type == FAT_TYPE_32) ? "FAT32": "FAT16")); + FAT_PRINTF((" Root Dir First Cluster = %x\r\n", fs->rootdir_first_cluster)); + FAT_PRINTF((" FAT Begin LBA = 0x%x\r\n",fs->fat_begin_lba)); + FAT_PRINTF((" Cluster Begin LBA = 0x%x\r\n",fs->cluster_begin_lba)); + FAT_PRINTF((" Sectors Per Cluster = %d\r\n", fs->sectors_per_cluster)); +} +//----------------------------------------------------------------------------- +// fatfs_get_root_cluster: Get the root dir cluster +//----------------------------------------------------------------------------- +uint32 fatfs_get_root_cluster(struct fatfs *fs) +{ + // NOTE: On FAT16 this will be 0 which has a special meaning... + return fs->rootdir_first_cluster; +} +//------------------------------------------------------------- +// fatfs_get_file_entry: Find the file entry for a filename +//------------------------------------------------------------- +uint32 fatfs_get_file_entry(struct fatfs *fs, uint32 Cluster, char *name_to_find, struct fat_dir_entry *sfEntry) +{ + uint8 item=0; + uint16 recordoffset = 0; + uint8 i=0; + int x=0; + char *long_filename = NULL; + char short_filename[13]; + struct lfn_cache lfn; + int dotRequired = 0; + struct fat_dir_entry *directoryEntry; + + fatfs_lfn_cache_init(&lfn, 1); + + // Main cluster following loop + while (1) + { + // Read sector + if (fatfs_sector_reader(fs, Cluster, x++, 0)) // If sector read was successfull + { + // Analyse Sector + for (item = 0; item < FAT_DIR_ENTRIES_PER_SECTOR; item++) + { + // Create the multiplier for sector access + recordoffset = FAT_DIR_ENTRY_SIZE * item; + + // Overlay directory entry over buffer + directoryEntry = (struct fat_dir_entry*)(fs->currentsector.sector+recordoffset); + +#if FATFS_INC_LFN_SUPPORT + // Long File Name Text Found + if (fatfs_entry_lfn_text(directoryEntry) ) + fatfs_lfn_cache_entry(&lfn, fs->currentsector.sector+recordoffset); + + // If Invalid record found delete any long file name information collated + else if (fatfs_entry_lfn_invalid(directoryEntry) ) + fatfs_lfn_cache_init(&lfn, 0); + + // Normal SFN Entry and Long text exists + else if (fatfs_entry_lfn_exists(&lfn, directoryEntry) ) + { + long_filename = fatfs_lfn_cache_get(&lfn); + + // Compare names to see if they match + if (fatfs_compare_names(long_filename, name_to_find)) + { + memcpy(sfEntry,directoryEntry,sizeof(struct fat_dir_entry)); + return 1; + } + + fatfs_lfn_cache_init(&lfn, 0); + } + else +#endif + // Normal Entry, only 8.3 Text + if (fatfs_entry_sfn_only(directoryEntry) ) + { + memset(short_filename, 0, sizeof(short_filename)); + + // Copy name to string + for (i=0; i<8; i++) + short_filename[i] = directoryEntry->Name[i]; + + // Extension + dotRequired = 0; + for (i=8; i<11; i++) + { + short_filename[i+1] = directoryEntry->Name[i]; + if (directoryEntry->Name[i] != ' ') + dotRequired = 1; + } + + // Dot only required if extension present + if (dotRequired) + { + // If not . or .. entry + if (short_filename[0]!='.') + short_filename[8] = '.'; + else + short_filename[8] = ' '; + } + else + short_filename[8] = ' '; + + // Compare names to see if they match + if (fatfs_compare_names(short_filename, name_to_find)) + { + memcpy(sfEntry,directoryEntry,sizeof(struct fat_dir_entry)); + return 1; + } + + fatfs_lfn_cache_init(&lfn, 0); + } + } // End of if + } + else + break; + } // End of while loop + + return 0; +} +//------------------------------------------------------------- +// fatfs_sfn_exists: Check if a short filename exists. +// NOTE: shortname is XXXXXXXXYYY not XXXXXXXX.YYY +//------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +int fatfs_sfn_exists(struct fatfs *fs, uint32 Cluster, char *shortname) +{ + uint8 item=0; + uint16 recordoffset = 0; + int x=0; + struct fat_dir_entry *directoryEntry; + + // Main cluster following loop + while (1) + { + // Read sector + if (fatfs_sector_reader(fs, Cluster, x++, 0)) // If sector read was successfull + { + // Analyse Sector + for (item = 0; item < FAT_DIR_ENTRIES_PER_SECTOR; item++) + { + // Create the multiplier for sector access + recordoffset = FAT_DIR_ENTRY_SIZE * item; + + // Overlay directory entry over buffer + directoryEntry = (struct fat_dir_entry*)(fs->currentsector.sector+recordoffset); + +#if FATFS_INC_LFN_SUPPORT + // Long File Name Text Found + if (fatfs_entry_lfn_text(directoryEntry) ) + ; + + // If Invalid record found delete any long file name information collated + else if (fatfs_entry_lfn_invalid(directoryEntry) ) + ; + else +#endif + // Normal Entry, only 8.3 Text + if (fatfs_entry_sfn_only(directoryEntry) ) + { + if (strncmp((const char*)directoryEntry->Name, shortname, 11)==0) + return 1; + } + } // End of if + } + else + break; + } // End of while loop + + return 0; +} +#endif +//------------------------------------------------------------- +// fatfs_update_timestamps: Update date/time details +//------------------------------------------------------------- +#if FATFS_INC_TIME_DATE_SUPPORT +int fatfs_update_timestamps(struct fat_dir_entry *directoryEntry, int create, int modify, int access) +{ + time_t time_now; + struct tm * time_info; + uint16 fat_time; + uint16 fat_date; + + // Get system time + time(&time_now); + + // Convert to local time + time_info = localtime(&time_now); + + // Convert time to FAT format + fat_time = fatfs_convert_to_fat_time(time_info->tm_hour, time_info->tm_min, time_info->tm_sec); + + // Convert date to FAT format + fat_date = fatfs_convert_to_fat_date(time_info->tm_mday, time_info->tm_mon + 1, time_info->tm_year + 1900); + + // Update requested fields + if (create) + { + directoryEntry->CrtTime[1] = fat_time >> 8; + directoryEntry->CrtTime[0] = fat_time >> 0; + directoryEntry->CrtDate[1] = fat_date >> 8; + directoryEntry->CrtDate[0] = fat_date >> 0; + } + + if (modify) + { + directoryEntry->WrtTime[1] = fat_time >> 8; + directoryEntry->WrtTime[0] = fat_time >> 0; + directoryEntry->WrtDate[1] = fat_date >> 8; + directoryEntry->WrtDate[0] = fat_date >> 0; + } + + if (access) + { + directoryEntry->LstAccDate[1] = fat_time >> 8; + directoryEntry->LstAccDate[0] = fat_time >> 0; + directoryEntry->LstAccDate[1] = fat_date >> 8; + directoryEntry->LstAccDate[0] = fat_date >> 0; + } + + return 1; +} +#endif +//------------------------------------------------------------- +// fatfs_update_file_length: Find a SFN entry and update it +// NOTE: shortname is XXXXXXXXYYY not XXXXXXXX.YYY +//------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +int fatfs_update_file_length(struct fatfs *fs, uint32 Cluster, char *shortname, uint32 fileLength) +{ + uint8 item=0; + uint16 recordoffset = 0; + int x=0; + struct fat_dir_entry *directoryEntry; + + // No write access? + if (!fs->disk_io.write_media) + return 0; + + // Main cluster following loop + while (1) + { + // Read sector + if (fatfs_sector_reader(fs, Cluster, x++, 0)) // If sector read was successfull + { + // Analyse Sector + for (item = 0; item < FAT_DIR_ENTRIES_PER_SECTOR; item++) + { + // Create the multiplier for sector access + recordoffset = FAT_DIR_ENTRY_SIZE * item; + + // Overlay directory entry over buffer + directoryEntry = (struct fat_dir_entry*)(fs->currentsector.sector+recordoffset); + +#if FATFS_INC_LFN_SUPPORT + // Long File Name Text Found + if (fatfs_entry_lfn_text(directoryEntry) ) + ; + + // If Invalid record found delete any long file name information collated + else if (fatfs_entry_lfn_invalid(directoryEntry) ) + ; + + // Normal Entry, only 8.3 Text + else +#endif + if (fatfs_entry_sfn_only(directoryEntry) ) + { + if (strncmp((const char*)directoryEntry->Name, shortname, 11)==0) + { + directoryEntry->FileSize = FAT_HTONL(fileLength); + +#if FATFS_INC_TIME_DATE_SUPPORT + // Update access / modify time & date + fatfs_update_timestamps(directoryEntry, 0, 1, 1); +#endif + + // Update sfn entry + memcpy((uint8*)(fs->currentsector.sector+recordoffset), (uint8*)directoryEntry, sizeof(struct fat_dir_entry)); + + // Write sector back + return fs->disk_io.write_media(fs->currentsector.address, fs->currentsector.sector, 1); + } + } + } // End of if + } + else + break; + } // End of while loop + + return 0; +} +#endif +//------------------------------------------------------------- +// fatfs_mark_file_deleted: Find a SFN entry and mark if as deleted +// NOTE: shortname is XXXXXXXXYYY not XXXXXXXX.YYY +//------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +int fatfs_mark_file_deleted(struct fatfs *fs, uint32 Cluster, char *shortname) +{ + uint8 item=0; + uint16 recordoffset = 0; + int x=0; + struct fat_dir_entry *directoryEntry; + + // No write access? + if (!fs->disk_io.write_media) + return 0; + + // Main cluster following loop + while (1) + { + // Read sector + if (fatfs_sector_reader(fs, Cluster, x++, 0)) // If sector read was successfull + { + // Analyse Sector + for (item = 0; item < FAT_DIR_ENTRIES_PER_SECTOR; item++) + { + // Create the multiplier for sector access + recordoffset = FAT_DIR_ENTRY_SIZE * item; + + // Overlay directory entry over buffer + directoryEntry = (struct fat_dir_entry*)(fs->currentsector.sector+recordoffset); + +#if FATFS_INC_LFN_SUPPORT + // Long File Name Text Found + if (fatfs_entry_lfn_text(directoryEntry) ) + ; + + // If Invalid record found delete any long file name information collated + else if (fatfs_entry_lfn_invalid(directoryEntry) ) + ; + + // Normal Entry, only 8.3 Text + else +#endif + if (fatfs_entry_sfn_only(directoryEntry) ) + { + if (strncmp((const char *)directoryEntry->Name, shortname, 11)==0) + { + // Mark as deleted + directoryEntry->Name[0] = FILE_HEADER_DELETED; + +#if FATFS_INC_TIME_DATE_SUPPORT + // Update access / modify time & date + fatfs_update_timestamps(directoryEntry, 0, 1, 1); +#endif + + // Update sfn entry + memcpy((uint8*)(fs->currentsector.sector+recordoffset), (uint8*)directoryEntry, sizeof(struct fat_dir_entry)); + + // Write sector back + return fs->disk_io.write_media(fs->currentsector.address, fs->currentsector.sector, 1); + } + } + } // End of if + } + else + break; + } // End of while loop + + return 0; +} +#endif +//----------------------------------------------------------------------------- +// fatfs_list_directory_start: Initialise a directory listing procedure +//----------------------------------------------------------------------------- +#if FATFS_DIR_LIST_SUPPORT +void fatfs_list_directory_start(struct fatfs *fs, struct fs_dir_list_status *dirls, uint32 StartCluster) +{ + dirls->cluster = StartCluster; + dirls->sector = 0; + dirls->offset = 0; +} +#endif +//----------------------------------------------------------------------------- +// fatfs_list_directory_next: Get the next entry in the directory. +// Returns: 1 = found, 0 = end of listing +//----------------------------------------------------------------------------- +#if FATFS_DIR_LIST_SUPPORT +int fatfs_list_directory_next(struct fatfs *fs, struct fs_dir_list_status *dirls, struct fs_dir_ent *entry) +{ + uint8 i,item; + uint16 recordoffset; + struct fat_dir_entry *directoryEntry; + char *long_filename = NULL; + char short_filename[13]; + struct lfn_cache lfn; + int dotRequired = 0; + int result = 0; + + // Initialise LFN cache first + fatfs_lfn_cache_init(&lfn, 0); + + while (1) + { + // If data read OK + if (fatfs_sector_reader(fs, dirls->cluster, dirls->sector, 0)) + { + // Maximum of 16 directory entries + for (item = dirls->offset; item < FAT_DIR_ENTRIES_PER_SECTOR; item++) + { + // Increase directory offset + recordoffset = FAT_DIR_ENTRY_SIZE * item; + + // Overlay directory entry over buffer + directoryEntry = (struct fat_dir_entry*)(fs->currentsector.sector+recordoffset); + +#if FATFS_INC_LFN_SUPPORT + // Long File Name Text Found + if ( fatfs_entry_lfn_text(directoryEntry) ) + fatfs_lfn_cache_entry(&lfn, fs->currentsector.sector+recordoffset); + + // If Invalid record found delete any long file name information collated + else if ( fatfs_entry_lfn_invalid(directoryEntry) ) + fatfs_lfn_cache_init(&lfn, 0); + + // Normal SFN Entry and Long text exists + else if (fatfs_entry_lfn_exists(&lfn, directoryEntry) ) + { + // Get text + long_filename = fatfs_lfn_cache_get(&lfn); + strncpy(entry->filename, long_filename, FATFS_MAX_LONG_FILENAME-1); + + if (fatfs_entry_is_dir(directoryEntry)) + entry->is_dir = 1; + else + entry->is_dir = 0; + +#if FATFS_INC_TIME_DATE_SUPPORT + // Get time / dates + entry->create_time = ((uint16)directoryEntry->CrtTime[1] << 8) | directoryEntry->CrtTime[0]; + entry->create_date = ((uint16)directoryEntry->CrtDate[1] << 8) | directoryEntry->CrtDate[0]; + entry->access_date = ((uint16)directoryEntry->LstAccDate[1] << 8) | directoryEntry->LstAccDate[0]; + entry->write_time = ((uint16)directoryEntry->WrtTime[1] << 8) | directoryEntry->WrtTime[0]; + entry->write_date = ((uint16)directoryEntry->WrtDate[1] << 8) | directoryEntry->WrtDate[0]; +#endif + + entry->size = FAT_HTONL(directoryEntry->FileSize); + entry->cluster = (FAT_HTONS(directoryEntry->FstClusHI)<<16) | FAT_HTONS(directoryEntry->FstClusLO); + + // Next starting position + dirls->offset = item + 1; + result = 1; + return 1; + } + // Normal Entry, only 8.3 Text + else +#endif + if ( fatfs_entry_sfn_only(directoryEntry) ) + { + fatfs_lfn_cache_init(&lfn, 0); + + memset(short_filename, 0, sizeof(short_filename)); + + // Copy name to string + for (i=0; i<8; i++) + short_filename[i] = directoryEntry->Name[i]; + + // Extension + dotRequired = 0; + for (i=8; i<11; i++) + { + short_filename[i+1] = directoryEntry->Name[i]; + if (directoryEntry->Name[i] != ' ') + dotRequired = 1; + } + + // Dot only required if extension present + if (dotRequired) + { + // If not . or .. entry + if (short_filename[0]!='.') + short_filename[8] = '.'; + else + short_filename[8] = ' '; + } + else + short_filename[8] = ' '; + + fatfs_get_sfn_display_name(entry->filename, short_filename); + + if (fatfs_entry_is_dir(directoryEntry)) + entry->is_dir = 1; + else + entry->is_dir = 0; + +#if FATFS_INC_TIME_DATE_SUPPORT + // Get time / dates + entry->create_time = ((uint16)directoryEntry->CrtTime[1] << 8) | directoryEntry->CrtTime[0]; + entry->create_date = ((uint16)directoryEntry->CrtDate[1] << 8) | directoryEntry->CrtDate[0]; + entry->access_date = ((uint16)directoryEntry->LstAccDate[1] << 8) | directoryEntry->LstAccDate[0]; + entry->write_time = ((uint16)directoryEntry->WrtTime[1] << 8) | directoryEntry->WrtTime[0]; + entry->write_date = ((uint16)directoryEntry->WrtDate[1] << 8) | directoryEntry->WrtDate[0]; +#endif + + entry->size = FAT_HTONL(directoryEntry->FileSize); + entry->cluster = (FAT_HTONS(directoryEntry->FstClusHI)<<16) | FAT_HTONS(directoryEntry->FstClusLO); + + // Next starting position + dirls->offset = item + 1; + result = 1; + return 1; + } + }// end of for + + // If reached end of the dir move onto next sector + dirls->sector++; + dirls->offset = 0; + } + else + break; + } + + return result; +} +#endif diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_access.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_access.h new file mode 100644 index 0000000..1752387 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_access.h @@ -0,0 +1,133 @@ +#ifndef __FAT_ACCESS_H__ +#define __FAT_ACCESS_H__ + +#include "fat_defs.h" +#include "fat_opts.h" + +//----------------------------------------------------------------------------- +// Defines +//----------------------------------------------------------------------------- +#define FAT_INIT_OK 0 +#define FAT_INIT_MEDIA_ACCESS_ERROR (-1) +#define FAT_INIT_INVALID_SECTOR_SIZE (-2) +#define FAT_INIT_INVALID_SIGNATURE (-3) +#define FAT_INIT_ENDIAN_ERROR (-4) +#define FAT_INIT_WRONG_FILESYS_TYPE (-5) +#define FAT_INIT_WRONG_PARTITION_TYPE (-6) +#define FAT_INIT_STRUCT_PACKING (-7) + +#define FAT_DIR_ENTRIES_PER_SECTOR (FAT_SECTOR_SIZE / FAT_DIR_ENTRY_SIZE) + +//----------------------------------------------------------------------------- +// Function Pointers +//----------------------------------------------------------------------------- +typedef int (*fn_diskio_read) (uint32 sector, uint8 *buffer, uint32 sector_count); +typedef int (*fn_diskio_write)(uint32 sector, uint8 *buffer, uint32 sector_count); + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- +struct disk_if +{ + // User supplied function pointers for disk IO + fn_diskio_read read_media; + fn_diskio_write write_media; +}; + +// Forward declaration +struct fat_buffer; + +struct fat_buffer +{ + uint8 sector[FAT_SECTOR_SIZE * FAT_BUFFER_SECTORS]; + uint32 address; + int dirty; + uint8 * ptr; + + // Next in chain of sector buffers + struct fat_buffer *next; +}; + +typedef enum eFatType +{ + FAT_TYPE_16, + FAT_TYPE_32 +} tFatType; + +struct fatfs +{ + // Filesystem globals + uint8 sectors_per_cluster; + uint32 cluster_begin_lba; + uint32 rootdir_first_cluster; + uint32 rootdir_first_sector; + uint32 rootdir_sectors; + uint32 fat_begin_lba; + uint16 fs_info_sector; + uint32 lba_begin; + uint32 fat_sectors; + uint32 next_free_cluster; + uint16 root_entry_count; + uint16 reserved_sectors; + uint8 num_of_fats; + tFatType fat_type; + + // Disk/Media API + struct disk_if disk_io; + + // [Optional] Thread Safety + void (*fl_lock)(void); + void (*fl_unlock)(void); + + // Working buffer + struct fat_buffer currentsector; + + // FAT Buffer + struct fat_buffer *fat_buffer_head; + struct fat_buffer fat_buffers[FAT_BUFFERS]; +}; + +struct fs_dir_list_status +{ + uint32 sector; + uint32 cluster; + uint8 offset; +}; + +struct fs_dir_ent +{ + char filename[FATFS_MAX_LONG_FILENAME]; + uint8 is_dir; + uint32 cluster; + uint32 size; + +#if FATFS_INC_TIME_DATE_SUPPORT + uint16 access_date; + uint16 write_time; + uint16 write_date; + uint16 create_date; + uint16 create_time; +#endif +}; + +//----------------------------------------------------------------------------- +// Prototypes +//----------------------------------------------------------------------------- +int fatfs_init(struct fatfs *fs); +uint32 fatfs_lba_of_cluster(struct fatfs *fs, uint32 Cluster_Number); +int fatfs_sector_reader(struct fatfs *fs, uint32 Startcluster, uint32 offset, uint8 *target); +int fatfs_sector_read(struct fatfs *fs, uint32 lba, uint8 *target, uint32 count); +int fatfs_sector_write(struct fatfs *fs, uint32 lba, uint8 *target, uint32 count); +int fatfs_read_sector(struct fatfs *fs, uint32 cluster, uint32 sector, uint8 *target); +int fatfs_write_sector(struct fatfs *fs, uint32 cluster, uint32 sector, uint8 *target); +void fatfs_show_details(struct fatfs *fs); +uint32 fatfs_get_root_cluster(struct fatfs *fs); +uint32 fatfs_get_file_entry(struct fatfs *fs, uint32 Cluster, char *nametofind, struct fat_dir_entry *sfEntry); +int fatfs_sfn_exists(struct fatfs *fs, uint32 Cluster, char *shortname); +int fatfs_update_file_length(struct fatfs *fs, uint32 Cluster, char *shortname, uint32 fileLength); +int fatfs_mark_file_deleted(struct fatfs *fs, uint32 Cluster, char *shortname); +void fatfs_list_directory_start(struct fatfs *fs, struct fs_dir_list_status *dirls, uint32 StartCluster); +int fatfs_list_directory_next(struct fatfs *fs, struct fs_dir_list_status *dirls, struct fs_dir_ent *entry); +int fatfs_update_timestamps(struct fat_dir_entry *directoryEntry, int create, int modify, int access); + +#endif diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_cache.c b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_cache.c new file mode 100644 index 0000000..de77e6a --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_cache.c @@ -0,0 +1,91 @@ +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// FAT16/32 File IO Library +// V2.6 +// Ultra-Embedded.com +// Copyright 2003 - 2012 +// +// Email: admin@ultra-embedded.com +// +// License: GPL +// If you would like a version with a more permissive license for use in +// closed source commercial applications please contact me for details. +//----------------------------------------------------------------------------- +// +// This file is part of FAT File IO Library. +// +// FAT File IO Library 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. +// +// FAT File IO 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FAT File IO Library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +#include +#include "fat_cache.h" + +// Per file cluster chain caching used to improve performance. +// This does not have to be enabled for architectures with low +// memory space. + +//----------------------------------------------------------------------------- +// fatfs_cache_init: +//----------------------------------------------------------------------------- +int fatfs_cache_init(struct fatfs *fs, FL_FILE *file) +{ +#ifdef FAT_CLUSTER_CACHE_ENTRIES + int i; + + for (i=0;icluster_cache_idx[i] = 0xFFFFFFFF; // Not used + file->cluster_cache_data[i] = 0; + } +#endif + + return 1; +} +//----------------------------------------------------------------------------- +// fatfs_cache_get_next_cluster: +//----------------------------------------------------------------------------- +int fatfs_cache_get_next_cluster(struct fatfs *fs, FL_FILE *file, uint32 clusterIdx, uint32 *pNextCluster) +{ +#ifdef FAT_CLUSTER_CACHE_ENTRIES + uint32 slot = clusterIdx % FAT_CLUSTER_CACHE_ENTRIES; + + if (file->cluster_cache_idx[slot] == clusterIdx) + { + *pNextCluster = file->cluster_cache_data[slot]; + return 1; + } +#endif + + return 0; +} +//----------------------------------------------------------------------------- +// fatfs_cache_set_next_cluster: +//----------------------------------------------------------------------------- +int fatfs_cache_set_next_cluster(struct fatfs *fs, FL_FILE *file, uint32 clusterIdx, uint32 nextCluster) +{ +#ifdef FAT_CLUSTER_CACHE_ENTRIES + uint32 slot = clusterIdx % FAT_CLUSTER_CACHE_ENTRIES; + + if (file->cluster_cache_idx[slot] == clusterIdx) + file->cluster_cache_data[slot] = nextCluster; + else + { + file->cluster_cache_idx[slot] = clusterIdx; + file->cluster_cache_data[slot] = nextCluster; + } +#endif + + return 1; +} diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_cache.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_cache.h new file mode 100644 index 0000000..348d5d3 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_cache.h @@ -0,0 +1,13 @@ +#ifndef __FAT_CACHE_H__ +#define __FAT_CACHE_H__ + +#include "fat_filelib.h" + +//----------------------------------------------------------------------------- +// Prototypes +//----------------------------------------------------------------------------- +int fatfs_cache_init(struct fatfs *fs, FL_FILE *file); +int fatfs_cache_get_next_cluster(struct fatfs *fs, FL_FILE *file, uint32 clusterIdx, uint32 *pNextCluster); +int fatfs_cache_set_next_cluster(struct fatfs *fs, FL_FILE *file, uint32 clusterIdx, uint32 nextCluster); + +#endif diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_defs.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_defs.h new file mode 100644 index 0000000..5fe8d6a --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_defs.h @@ -0,0 +1,128 @@ +#ifndef __FAT_DEFS_H__ +#define __FAT_DEFS_H__ + +#include "fat_opts.h" +#include "fat_types.h" + +//----------------------------------------------------------------------------- +// FAT32 Offsets +// Name Offset +//----------------------------------------------------------------------------- + +// Boot Sector +#define BS_JMPBOOT 0 // Length = 3 +#define BS_OEMNAME 3 // Length = 8 +#define BPB_BYTSPERSEC 11 // Length = 2 +#define BPB_SECPERCLUS 13 // Length = 1 +#define BPB_RSVDSECCNT 14 // Length = 2 +#define BPB_NUMFATS 16 // Length = 1 +#define BPB_ROOTENTCNT 17 // Length = 2 +#define BPB_TOTSEC16 19 // Length = 2 +#define BPB_MEDIA 21 // Length = 1 +#define BPB_FATSZ16 22 // Length = 2 +#define BPB_SECPERTRK 24 // Length = 2 +#define BPB_NUMHEADS 26 // Length = 2 +#define BPB_HIDDSEC 28 // Length = 4 +#define BPB_TOTSEC32 32 // Length = 4 + +// FAT 12/16 +#define BS_FAT_DRVNUM 36 // Length = 1 +#define BS_FAT_BOOTSIG 38 // Length = 1 +#define BS_FAT_VOLID 39 // Length = 4 +#define BS_FAT_VOLLAB 43 // Length = 11 +#define BS_FAT_FILSYSTYPE 54 // Length = 8 + +// FAT 32 +#define BPB_FAT32_FATSZ32 36 // Length = 4 +#define BPB_FAT32_EXTFLAGS 40 // Length = 2 +#define BPB_FAT32_FSVER 42 // Length = 2 +#define BPB_FAT32_ROOTCLUS 44 // Length = 4 +#define BPB_FAT32_FSINFO 48 // Length = 2 +#define BPB_FAT32_BKBOOTSEC 50 // Length = 2 +#define BS_FAT32_DRVNUM 64 // Length = 1 +#define BS_FAT32_BOOTSIG 66 // Length = 1 +#define BS_FAT32_VOLID 67 // Length = 4 +#define BS_FAT32_VOLLAB 71 // Length = 11 +#define BS_FAT32_FILSYSTYPE 82 // Length = 8 + +//----------------------------------------------------------------------------- +// FAT Types +//----------------------------------------------------------------------------- +#define FAT_TYPE_FAT12 1 +#define FAT_TYPE_FAT16 2 +#define FAT_TYPE_FAT32 3 + +//----------------------------------------------------------------------------- +// FAT32 Specific Statics +//----------------------------------------------------------------------------- +#define SIGNATURE_POSITION 510 +#define SIGNATURE_VALUE 0xAA55 +#define PARTITION1_TYPECODE_LOCATION 450 +#define FAT32_TYPECODE1 0x0B +#define FAT32_TYPECODE2 0x0C +#define PARTITION1_LBA_BEGIN_LOCATION 454 +#define PARTITION1_SIZE_LOCATION 458 + +#define FAT_DIR_ENTRY_SIZE 32 +#define FAT_SFN_SIZE_FULL 11 +#define FAT_SFN_SIZE_PARTIAL 8 + +//----------------------------------------------------------------------------- +// FAT32 File Attributes and Types +//----------------------------------------------------------------------------- +#define FILE_ATTR_READ_ONLY 0x01 +#define FILE_ATTR_HIDDEN 0x02 +#define FILE_ATTR_SYSTEM 0x04 +#define FILE_ATTR_SYSHID 0x06 +#define FILE_ATTR_VOLUME_ID 0x08 +#define FILE_ATTR_DIRECTORY 0x10 +#define FILE_ATTR_ARCHIVE 0x20 +#define FILE_ATTR_LFN_TEXT 0x0F +#define FILE_HEADER_BLANK 0x00 +#define FILE_HEADER_DELETED 0xE5 +#define FILE_TYPE_DIR 0x10 +#define FILE_TYPE_FILE 0x20 + +//----------------------------------------------------------------------------- +// Time / Date details +//----------------------------------------------------------------------------- +#define FAT_TIME_HOURS_SHIFT 11 +#define FAT_TIME_HOURS_MASK 0x1F +#define FAT_TIME_MINUTES_SHIFT 5 +#define FAT_TIME_MINUTES_MASK 0x3F +#define FAT_TIME_SECONDS_SHIFT 0 +#define FAT_TIME_SECONDS_MASK 0x1F +#define FAT_TIME_SECONDS_SCALE 2 +#define FAT_DATE_YEAR_SHIFT 9 +#define FAT_DATE_YEAR_MASK 0x7F +#define FAT_DATE_MONTH_SHIFT 5 +#define FAT_DATE_MONTH_MASK 0xF +#define FAT_DATE_DAY_SHIFT 0 +#define FAT_DATE_DAY_MASK 0x1F +#define FAT_DATE_YEAR_OFFSET 1980 + +//----------------------------------------------------------------------------- +// Other Defines +//----------------------------------------------------------------------------- +#define FAT32_LAST_CLUSTER 0xFFFFFFFF +#define FAT32_INVALID_CLUSTER 0xFFFFFFFF + +STRUCT_PACK_BEGIN +struct fat_dir_entry STRUCT_PACK +{ + uint8 Name[11]; + uint8 Attr; + uint8 NTRes; + uint8 CrtTimeTenth; + uint8 CrtTime[2]; + uint8 CrtDate[2]; + uint8 LstAccDate[2]; + uint16 FstClusHI; + uint8 WrtTime[2]; + uint8 WrtDate[2]; + uint16 FstClusLO; + uint32 FileSize; +} STRUCT_PACKED; +STRUCT_PACK_END + +#endif diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_filelib.c b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_filelib.c new file mode 100644 index 0000000..2c4a236 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_filelib.c @@ -0,0 +1,1603 @@ +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// FAT16/32 File IO Library +// V2.6 +// Ultra-Embedded.com +// Copyright 2003 - 2012 +// +// Email: admin@ultra-embedded.com +// +// License: GPL +// If you would like a version with a more permissive license for use in +// closed source commercial applications please contact me for details. +//----------------------------------------------------------------------------- +// +// This file is part of FAT File IO Library. +// +// FAT File IO Library 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. +// +// FAT File IO 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FAT File IO Library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +#include +#include +#include "fat_defs.h" +#include "fat_access.h" +#include "fat_table.h" +#include "fat_write.h" +#include "fat_misc.h" +#include "fat_string.h" +#include "fat_filelib.h" +#include "fat_cache.h" + +//----------------------------------------------------------------------------- +// Locals +//----------------------------------------------------------------------------- +static FL_FILE _files[FATFS_MAX_OPEN_FILES]; +static int _filelib_init = 0; +static int _filelib_valid = 0; +static struct fatfs _fs; +static struct fat_list _open_file_list; +static struct fat_list _free_file_list; + +//----------------------------------------------------------------------------- +// Macros +//----------------------------------------------------------------------------- + +// Macro for checking if file lib is initialised +#define CHECK_FL_INIT() { if (_filelib_init==0) fl_init(); } + +#define FL_LOCK(a) do { if ((a)->fl_lock) (a)->fl_lock(); } while (0) +#define FL_UNLOCK(a) do { if ((a)->fl_unlock) (a)->fl_unlock(); } while (0) + +//----------------------------------------------------------------------------- +// Local Functions +//----------------------------------------------------------------------------- +static void _fl_init(); + +//----------------------------------------------------------------------------- +// _allocate_file: Find a slot in the open files buffer for a new file +//----------------------------------------------------------------------------- +static FL_FILE* _allocate_file(void) +{ + // Allocate free file + struct fat_node *node = fat_list_pop_head(&_free_file_list); + + // Add to open list + if (node) + fat_list_insert_last(&_open_file_list, node); + + return fat_list_entry(node, FL_FILE, list_node); +} +//----------------------------------------------------------------------------- +// _check_file_open: Returns true if the file is already open +//----------------------------------------------------------------------------- +static int _check_file_open(FL_FILE* file) +{ + struct fat_node *node; + + // Compare open files + fat_list_for_each(&_open_file_list, node) + { + FL_FILE* openFile = fat_list_entry(node, FL_FILE, list_node); + + // If not the current file + if (openFile != file) + { + // Compare path and name + if ( (fatfs_compare_names(openFile->path,file->path)) && (fatfs_compare_names(openFile->filename,file->filename)) ) + return 1; + } + } + + return 0; +} +//----------------------------------------------------------------------------- +// _free_file: Free open file handle +//----------------------------------------------------------------------------- +static void _free_file(FL_FILE* file) +{ + // Remove from open list + fat_list_remove(&_open_file_list, &file->list_node); + + // Add to free list + fat_list_insert_last(&_free_file_list, &file->list_node); +} + +//----------------------------------------------------------------------------- +// Low Level +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// _open_directory: Cycle through path string to find the start cluster +// address of the highest subdir. +//----------------------------------------------------------------------------- +static int _open_directory(char *path, uint32 *pathCluster) +{ + int levels; + int sublevel; + char currentfolder[FATFS_MAX_LONG_FILENAME]; + struct fat_dir_entry sfEntry; + uint32 startcluster; + + // Set starting cluster to root cluster + startcluster = fatfs_get_root_cluster(&_fs); + + // Find number of levels + levels = fatfs_total_path_levels(path); + + // Cycle through each level and get the start sector + for (sublevel=0;sublevel<(levels+1);sublevel++) + { + if (fatfs_get_substring(path, sublevel, currentfolder, sizeof(currentfolder)) == -1) + return 0; + + // Find clusteraddress for folder (currentfolder) + if (fatfs_get_file_entry(&_fs, startcluster, currentfolder,&sfEntry)) + { + // Check entry is folder + if (fatfs_entry_is_dir(&sfEntry)) + startcluster = ((FAT_HTONS((uint32)sfEntry.FstClusHI))<<16) + FAT_HTONS(sfEntry.FstClusLO); + else + return 0; + } + else + return 0; + } + + *pathCluster = startcluster; + return 1; +} +//----------------------------------------------------------------------------- +// _create_directory: Cycle through path string and create the end directory +//----------------------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +static int _create_directory(char *path) +{ + FL_FILE* file; + struct fat_dir_entry sfEntry; + char shortFilename[FAT_SFN_SIZE_FULL]; + int tailNum = 0; + int i; + + // Allocate a new file handle + file = _allocate_file(); + if (!file) + return 0; + + // Clear filename + memset(file->path, '\0', sizeof(file->path)); + memset(file->filename, '\0', sizeof(file->filename)); + + // Split full path into filename and directory path + if (fatfs_split_path((char*)path, file->path, sizeof(file->path), file->filename, sizeof(file->filename)) == -1) + { + _free_file(file); + return 0; + } + + // Check if file already open + if (_check_file_open(file)) + { + _free_file(file); + return 0; + } + + // If file is in the root dir + if (file->path[0] == 0) + file->parentcluster = fatfs_get_root_cluster(&_fs); + else + { + // Find parent directory start cluster + if (!_open_directory(file->path, &file->parentcluster)) + { + _free_file(file); + return 0; + } + } + + // Check if same filename exists in directory + if (fatfs_get_file_entry(&_fs, file->parentcluster, file->filename,&sfEntry) == 1) + { + _free_file(file); + return 0; + } + + file->startcluster = 0; + + // Create the file space for the folder (at least one clusters worth!) + if (!fatfs_allocate_free_space(&_fs, 1, &file->startcluster, 1)) + { + _free_file(file); + return 0; + } + + // Erase new directory cluster + memset(file->file_data_sector, 0x00, FAT_SECTOR_SIZE); + for (i=0;i<_fs.sectors_per_cluster;i++) + { + if (!fatfs_write_sector(&_fs, file->startcluster, i, file->file_data_sector)) + { + _free_file(file); + return 0; + } + } + +#if FATFS_INC_LFN_SUPPORT + + // Generate a short filename & tail + tailNum = 0; + do + { + // Create a standard short filename (without tail) + fatfs_lfn_create_sfn(shortFilename, file->filename); + + // If second hit or more, generate a ~n tail + if (tailNum != 0) + fatfs_lfn_generate_tail((char*)file->shortfilename, shortFilename, tailNum); + // Try with no tail if first entry + else + memcpy(file->shortfilename, shortFilename, FAT_SFN_SIZE_FULL); + + // Check if entry exists already or not + if (fatfs_sfn_exists(&_fs, file->parentcluster, (char*)file->shortfilename) == 0) + break; + + tailNum++; + } + while (tailNum < 9999); + + // We reached the max number of duplicate short file names (unlikely!) + if (tailNum == 9999) + { + // Delete allocated space + fatfs_free_cluster_chain(&_fs, file->startcluster); + + _free_file(file); + return 0; + } +#else + // Create a standard short filename (without tail) + if (!fatfs_lfn_create_sfn(shortFilename, file->filename)) + { + // Delete allocated space + fatfs_free_cluster_chain(&_fs, file->startcluster); + + _free_file(file); + return 0; + } + + // Copy to SFN space + memcpy(file->shortfilename, shortFilename, FAT_SFN_SIZE_FULL); + + // Check if entry exists already + if (fatfs_sfn_exists(&_fs, file->parentcluster, (char*)file->shortfilename)) + { + // Delete allocated space + fatfs_free_cluster_chain(&_fs, file->startcluster); + + _free_file(file); + return 0; + } +#endif + + // Add file to disk + if (!fatfs_add_file_entry(&_fs, file->parentcluster, (char*)file->filename, (char*)file->shortfilename, file->startcluster, 0, 1)) + { + // Delete allocated space + fatfs_free_cluster_chain(&_fs, file->startcluster); + + _free_file(file); + return 0; + } + + // General + file->filelength = 0; + file->bytenum = 0; + file->file_data_address = 0xFFFFFFFF; + file->file_data_dirty = 0; + file->filelength_changed = 0; + + // Quick lookup for next link in the chain + file->last_fat_lookup.ClusterIdx = 0xFFFFFFFF; + file->last_fat_lookup.CurrentCluster = 0xFFFFFFFF; + + fatfs_fat_purge(&_fs); + + _free_file(file); + return 1; +} +#endif +//----------------------------------------------------------------------------- +// _open_file: Open a file for reading +//----------------------------------------------------------------------------- +static FL_FILE* _open_file(const char *path) +{ + FL_FILE* file; + struct fat_dir_entry sfEntry; + + // Allocate a new file handle + file = _allocate_file(); + if (!file) + return NULL; + + // Clear filename + memset(file->path, '\0', sizeof(file->path)); + memset(file->filename, '\0', sizeof(file->filename)); + + // Split full path into filename and directory path + if (fatfs_split_path((char*)path, file->path, sizeof(file->path), file->filename, sizeof(file->filename)) == -1) + { + _free_file(file); + return NULL; + } + + // Check if file already open + if (_check_file_open(file)) + { + _free_file(file); + return NULL; + } + + // If file is in the root dir + if (file->path[0]==0) + file->parentcluster = fatfs_get_root_cluster(&_fs); + else + { + // Find parent directory start cluster + if (!_open_directory(file->path, &file->parentcluster)) + { + _free_file(file); + return NULL; + } + } + + // Using dir cluster address search for filename + if (fatfs_get_file_entry(&_fs, file->parentcluster, file->filename,&sfEntry)) + // Make sure entry is file not dir! + if (fatfs_entry_is_file(&sfEntry)) + { + // Initialise file details + memcpy(file->shortfilename, sfEntry.Name, FAT_SFN_SIZE_FULL); + file->filelength = FAT_HTONL(sfEntry.FileSize); + file->bytenum = 0; + file->startcluster = ((FAT_HTONS((uint32)sfEntry.FstClusHI))<<16) + FAT_HTONS(sfEntry.FstClusLO); + file->file_data_address = 0xFFFFFFFF; + file->file_data_dirty = 0; + file->filelength_changed = 0; + + // Quick lookup for next link in the chain + file->last_fat_lookup.ClusterIdx = 0xFFFFFFFF; + file->last_fat_lookup.CurrentCluster = 0xFFFFFFFF; + + fatfs_cache_init(&_fs, file); + + fatfs_fat_purge(&_fs); + + return file; + } + + _free_file(file); + return NULL; +} +//----------------------------------------------------------------------------- +// _create_file: Create a new file +//----------------------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +static FL_FILE* _create_file(const char *filename) +{ + FL_FILE* file; + struct fat_dir_entry sfEntry; + char shortFilename[FAT_SFN_SIZE_FULL]; + int tailNum = 0; + + // No write access? + if (!_fs.disk_io.write_media) + return NULL; + + // Allocate a new file handle + file = _allocate_file(); + if (!file) + return NULL; + + // Clear filename + memset(file->path, '\0', sizeof(file->path)); + memset(file->filename, '\0', sizeof(file->filename)); + + // Split full path into filename and directory path + if (fatfs_split_path((char*)filename, file->path, sizeof(file->path), file->filename, sizeof(file->filename)) == -1) + { + _free_file(file); + return NULL; + } + + // Check if file already open + if (_check_file_open(file)) + { + _free_file(file); + return NULL; + } + + // If file is in the root dir + if (file->path[0] == 0) + file->parentcluster = fatfs_get_root_cluster(&_fs); + else + { + // Find parent directory start cluster + if (!_open_directory(file->path, &file->parentcluster)) + { + _free_file(file); + return NULL; + } + } + + // Check if same filename exists in directory + if (fatfs_get_file_entry(&_fs, file->parentcluster, file->filename,&sfEntry) == 1) + { + _free_file(file); + return NULL; + } + + file->startcluster = 0; + + // Create the file space for the file (at least one clusters worth!) + if (!fatfs_allocate_free_space(&_fs, 1, &file->startcluster, 1)) + { + _free_file(file); + return NULL; + } + +#if FATFS_INC_LFN_SUPPORT + // Generate a short filename & tail + tailNum = 0; + do + { + // Create a standard short filename (without tail) + fatfs_lfn_create_sfn(shortFilename, file->filename); + + // If second hit or more, generate a ~n tail + if (tailNum != 0) + fatfs_lfn_generate_tail((char*)file->shortfilename, shortFilename, tailNum); + // Try with no tail if first entry + else + memcpy(file->shortfilename, shortFilename, FAT_SFN_SIZE_FULL); + + // Check if entry exists already or not + if (fatfs_sfn_exists(&_fs, file->parentcluster, (char*)file->shortfilename) == 0) + break; + + tailNum++; + } + while (tailNum < 9999); + + // We reached the max number of duplicate short file names (unlikely!) + if (tailNum == 9999) + { + // Delete allocated space + fatfs_free_cluster_chain(&_fs, file->startcluster); + + _free_file(file); + return NULL; + } +#else + // Create a standard short filename (without tail) + if (!fatfs_lfn_create_sfn(shortFilename, file->filename)) + { + // Delete allocated space + fatfs_free_cluster_chain(&_fs, file->startcluster); + + _free_file(file); + return NULL; + } + + // Copy to SFN space + memcpy(file->shortfilename, shortFilename, FAT_SFN_SIZE_FULL); + + // Check if entry exists already + if (fatfs_sfn_exists(&_fs, file->parentcluster, (char*)file->shortfilename)) + { + // Delete allocated space + fatfs_free_cluster_chain(&_fs, file->startcluster); + + _free_file(file); + return NULL; + } +#endif + + // Add file to disk + if (!fatfs_add_file_entry(&_fs, file->parentcluster, (char*)file->filename, (char*)file->shortfilename, file->startcluster, 0, 0)) + { + // Delete allocated space + fatfs_free_cluster_chain(&_fs, file->startcluster); + + _free_file(file); + return NULL; + } + + // General + file->filelength = 0; + file->bytenum = 0; + file->file_data_address = 0xFFFFFFFF; + file->file_data_dirty = 0; + file->filelength_changed = 0; + + // Quick lookup for next link in the chain + file->last_fat_lookup.ClusterIdx = 0xFFFFFFFF; + file->last_fat_lookup.CurrentCluster = 0xFFFFFFFF; + + fatfs_cache_init(&_fs, file); + + fatfs_fat_purge(&_fs); + + return file; +} +#endif +//----------------------------------------------------------------------------- +// _read_sectors: Read sector(s) from disk to file +//----------------------------------------------------------------------------- +static uint32 _read_sectors(FL_FILE* file, uint32 offset, uint8 *buffer, uint32 count) +{ + uint32 Sector = 0; + uint32 ClusterIdx = 0; + uint32 Cluster = 0; + uint32 i; + uint32 lba; + + // Find cluster index within file & sector with cluster + ClusterIdx = offset / _fs.sectors_per_cluster; + Sector = offset - (ClusterIdx * _fs.sectors_per_cluster); + + // Limit number of sectors read to the number remaining in this cluster + if ((Sector + count) > _fs.sectors_per_cluster) + count = _fs.sectors_per_cluster - Sector; + + // Quick lookup for next link in the chain + if (ClusterIdx == file->last_fat_lookup.ClusterIdx) + Cluster = file->last_fat_lookup.CurrentCluster; + // Else walk the chain + else + { + // Starting from last recorded cluster? + if (ClusterIdx && ClusterIdx == file->last_fat_lookup.ClusterIdx + 1) + { + i = file->last_fat_lookup.ClusterIdx; + Cluster = file->last_fat_lookup.CurrentCluster; + } + // Start searching from the beginning.. + else + { + // Set start of cluster chain to initial value + i = 0; + Cluster = file->startcluster; + } + + // Follow chain to find cluster to read + for ( ;ilast_fat_lookup.CurrentCluster = Cluster; + file->last_fat_lookup.ClusterIdx = ClusterIdx; + } + } + + // If end of cluster chain then return false + if (Cluster == FAT32_LAST_CLUSTER) + return 0; + + // Calculate sector address + lba = fatfs_lba_of_cluster(&_fs, Cluster) + Sector; + + // Read sector of file + if (fatfs_sector_read(&_fs, lba, buffer, count)) + return count; + else + return 0; +} + +//----------------------------------------------------------------------------- +// External API +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// fl_init: Initialise library +//----------------------------------------------------------------------------- +void fl_init(void) +{ + int i; + + fat_list_init(&_free_file_list); + fat_list_init(&_open_file_list); + + // Add all file objects to free list + for (i=0;iflags = flags; + + FL_UNLOCK(&_fs); + return file; +} +//----------------------------------------------------------------------------- +// _write_sectors: Write sector(s) to disk +//----------------------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +static uint32 _write_sectors(FL_FILE* file, uint32 offset, uint8 *buf, uint32 count) +{ + uint32 SectorNumber = 0; + uint32 ClusterIdx = 0; + uint32 Cluster = 0; + uint32 LastCluster = FAT32_LAST_CLUSTER; + uint32 i; + uint32 lba; + uint32 TotalWriteCount = count; + + // Find values for Cluster index & sector within cluster + ClusterIdx = offset / _fs.sectors_per_cluster; + SectorNumber = offset - (ClusterIdx * _fs.sectors_per_cluster); + + // Limit number of sectors written to the number remaining in this cluster + if ((SectorNumber + count) > _fs.sectors_per_cluster) + count = _fs.sectors_per_cluster - SectorNumber; + + // Quick lookup for next link in the chain + if (ClusterIdx == file->last_fat_lookup.ClusterIdx) + Cluster = file->last_fat_lookup.CurrentCluster; + // Else walk the chain + else + { + // Starting from last recorded cluster? + if (ClusterIdx && ClusterIdx == file->last_fat_lookup.ClusterIdx + 1) + { + i = file->last_fat_lookup.ClusterIdx; + Cluster = file->last_fat_lookup.CurrentCluster; + } + // Start searching from the beginning.. + else + { + // Set start of cluster chain to initial value + i = 0; + Cluster = file->startcluster; + } + + // Follow chain to find cluster to read + for ( ;ilast_fat_lookup.CurrentCluster = Cluster; + file->last_fat_lookup.ClusterIdx = ClusterIdx; + } + + // Calculate write address + lba = fatfs_lba_of_cluster(&_fs, Cluster) + SectorNumber; + + if (fatfs_sector_write(&_fs, lba, buf, count)) + return count; + else + return 0; +} +#endif +//----------------------------------------------------------------------------- +// fl_fflush: Flush un-written data to the file +//----------------------------------------------------------------------------- +int fl_fflush(void *f) +{ +#if FATFS_INC_WRITE_SUPPORT + FL_FILE *file = (FL_FILE *)f; + + // If first call to library, initialise + CHECK_FL_INIT(); + + if (file) + { + FL_LOCK(&_fs); + + // If some write data still in buffer + if (file->file_data_dirty) + { + // Write back current sector before loading next + if (_write_sectors(file, file->file_data_address, file->file_data_sector, 1)) + file->file_data_dirty = 0; + } + + FL_UNLOCK(&_fs); + } +#endif + return 0; +} +//----------------------------------------------------------------------------- +// fl_fclose: Close an open file +//----------------------------------------------------------------------------- +void fl_fclose(void *f) +{ + FL_FILE *file = (FL_FILE *)f; + + // If first call to library, initialise + CHECK_FL_INIT(); + + if (file) + { + FL_LOCK(&_fs); + + // Flush un-written data to file + fl_fflush(f); + + // File size changed? + if (file->filelength_changed) + { +#if FATFS_INC_WRITE_SUPPORT + // Update filesize in directory + fatfs_update_file_length(&_fs, file->parentcluster, (char*)file->shortfilename, file->filelength); +#endif + file->filelength_changed = 0; + } + + file->bytenum = 0; + file->filelength = 0; + file->startcluster = 0; + file->file_data_address = 0xFFFFFFFF; + file->file_data_dirty = 0; + file->filelength_changed = 0; + + // Free file handle + _free_file(file); + + fatfs_fat_purge(&_fs); + + FL_UNLOCK(&_fs); + } +} +//----------------------------------------------------------------------------- +// fl_fgetc: Get a character in the stream +//----------------------------------------------------------------------------- +int fl_fgetc(void *f) +{ + int res; + uint8 data = 0; + + res = fl_fread(&data, 1, 1, f); + if (res == 1) + return (int)data; + else + return res; +} +//----------------------------------------------------------------------------- +// fl_fgets: Get a string from a stream +//----------------------------------------------------------------------------- +char *fl_fgets(char *s, int n, void *f) +{ + int idx = 0; + + // Space for null terminator? + if (n > 0) + { + // While space (+space for null terminator) + while (idx < (n-1)) + { + int ch = fl_fgetc(f); + + // EOF / Error? + if (ch < 0) + break; + + // Store character read from stream + s[idx++] = (char)ch; + + // End of line? + if (ch == '\n') + break; + } + + if (idx > 0) + s[idx] = '\0'; + } + + return (idx > 0) ? s : 0; +} +//----------------------------------------------------------------------------- +// fl_fread: Read a block of data from the file +//----------------------------------------------------------------------------- +int fl_fread(void * buffer, int size, int length, void *f ) +{ + uint32 sector; + uint32 offset; + int copyCount; + int count = size * length; + int bytesRead = 0; + + FL_FILE *file = (FL_FILE *)f; + + // If first call to library, initialise + CHECK_FL_INIT(); + + if (buffer==NULL || file==NULL) + return -1; + + // No read permissions + if (!(file->flags & FILE_READ)) + return -1; + + // Nothing to be done + if (!count) + return 0; + + // Check if read starts past end of file + if (file->bytenum >= file->filelength) + return -1; + + // Limit to file size + if ( (file->bytenum + count) > file->filelength ) + count = file->filelength - file->bytenum; + + // Calculate start sector + sector = file->bytenum / FAT_SECTOR_SIZE; + + // Offset to start copying data from first sector + offset = file->bytenum % FAT_SECTOR_SIZE; + + while (bytesRead < count) + { + // Read whole sector, read from media directly into target buffer + if ((offset == 0) && ((count - bytesRead) >= FAT_SECTOR_SIZE)) + { + // Read as many sectors as possible into target buffer + uint32 sectorsRead = _read_sectors(file, sector, (uint8*)((uint8*)buffer + bytesRead), (count - bytesRead) / FAT_SECTOR_SIZE); + if (sectorsRead) + { + // We have upto one sector to copy + copyCount = FAT_SECTOR_SIZE * sectorsRead; + + // Move onto next sector and reset copy offset + sector+= sectorsRead; + offset = 0; + } + else + break; + } + else + { + // Do we need to re-read the sector? + if (file->file_data_address != sector) + { + // Flush un-written data to file + if (file->file_data_dirty) + fl_fflush(file); + + // Get LBA of sector offset within file + if (!_read_sectors(file, sector, file->file_data_sector, 1)) + // Read failed - out of range (probably) + break; + + file->file_data_address = sector; + file->file_data_dirty = 0; + } + + // We have upto one sector to copy + copyCount = FAT_SECTOR_SIZE - offset; + + // Only require some of this sector? + if (copyCount > (count - bytesRead)) + copyCount = (count - bytesRead); + + // Copy to application buffer + memcpy( (uint8*)((uint8*)buffer + bytesRead), (uint8*)(file->file_data_sector + offset), copyCount); + + // Move onto next sector and reset copy offset + sector++; + offset = 0; + } + + // Increase total read count + bytesRead += copyCount; + + // Increment file pointer + file->bytenum += copyCount; + } + + return bytesRead; +} +//----------------------------------------------------------------------------- +// fl_fseek: Seek to a specific place in the file +//----------------------------------------------------------------------------- +int fl_fseek( void *f, long offset, int origin ) +{ + FL_FILE *file = (FL_FILE *)f; + int res = -1; + + // If first call to library, initialise + CHECK_FL_INIT(); + + if (!file) + return -1; + + if (origin == SEEK_END && offset != 0) + return -1; + + FL_LOCK(&_fs); + + // Invalidate file buffer + file->file_data_address = 0xFFFFFFFF; + file->file_data_dirty = 0; + + if (origin == SEEK_SET) + { + file->bytenum = (uint32)offset; + + if (file->bytenum > file->filelength) + file->bytenum = file->filelength; + + res = 0; + } + else if (origin == SEEK_CUR) + { + // Positive shift + if (offset >= 0) + { + file->bytenum += offset; + + if (file->bytenum > file->filelength) + file->bytenum = file->filelength; + } + // Negative shift + else + { + // Make shift positive + offset = -offset; + + // Limit to negative shift to start of file + if ((uint32)offset > file->bytenum) + file->bytenum = 0; + else + file->bytenum-= offset; + } + + res = 0; + } + else if (origin == SEEK_END) + { + file->bytenum = file->filelength; + res = 0; + } + else + res = -1; + + FL_UNLOCK(&_fs); + + return res; +} +//----------------------------------------------------------------------------- +// fl_fgetpos: Get the current file position +//----------------------------------------------------------------------------- +int fl_fgetpos(void *f , uint32 * position) +{ + FL_FILE *file = (FL_FILE *)f; + + if (!file) + return -1; + + FL_LOCK(&_fs); + + // Get position + *position = file->bytenum; + + FL_UNLOCK(&_fs); + + return 0; +} +//----------------------------------------------------------------------------- +// fl_ftell: Get the current file position +//----------------------------------------------------------------------------- +long fl_ftell(void *f) +{ + uint32 pos = 0; + + fl_fgetpos(f, &pos); + + return (long)pos; +} +//----------------------------------------------------------------------------- +// fl_feof: Is the file pointer at the end of the stream? +//----------------------------------------------------------------------------- +int fl_feof(void *f) +{ + FL_FILE *file = (FL_FILE *)f; + int res; + + if (!file) + return -1; + + FL_LOCK(&_fs); + + if (file->bytenum == file->filelength) + res = EOF; + else + res = 0; + + FL_UNLOCK(&_fs); + + return res; +} +//----------------------------------------------------------------------------- +// fl_fputc: Write a character to the stream +//----------------------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +int fl_fputc(int c, void *f) +{ + uint8 data = (uint8)c; + int res; + + res = fl_fwrite(&data, 1, 1, f); + if (res == 1) + return c; + else + return res; +} +#endif +//----------------------------------------------------------------------------- +// fl_fwrite: Write a block of data to the stream +//----------------------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +int fl_fwrite(const void * data, int size, int count, void *f ) +{ + FL_FILE *file = (FL_FILE *)f; + uint32 sector; + uint32 offset; + uint32 length = (size*count); + uint8 *buffer = (uint8 *)data; + uint32 bytesWritten = 0; + uint32 copyCount; + + // If first call to library, initialise + CHECK_FL_INIT(); + + if (!file) + return -1; + + FL_LOCK(&_fs); + + // No write permissions + if (!(file->flags & FILE_WRITE)) + { + FL_UNLOCK(&_fs); + return -1; + } + + // Append writes to end of file + if (file->flags & FILE_APPEND) + file->bytenum = file->filelength; + // Else write to current position + + // Calculate start sector + sector = file->bytenum / FAT_SECTOR_SIZE; + + // Offset to start copying data from first sector + offset = file->bytenum % FAT_SECTOR_SIZE; + + while (bytesWritten < length) + { + // Whole sector or more to be written? + if ((offset == 0) && ((length - bytesWritten) >= FAT_SECTOR_SIZE)) + { + uint32 sectorsWrote; + + // Buffered sector, flush back to disk + if (file->file_data_address != 0xFFFFFFFF) + { + // Flush un-written data to file + if (file->file_data_dirty) + fl_fflush(file); + + file->file_data_address = 0xFFFFFFFF; + file->file_data_dirty = 0; + } + + // Write as many sectors as possible + sectorsWrote = _write_sectors(file, sector, (uint8*)(buffer + bytesWritten), (length - bytesWritten) / FAT_SECTOR_SIZE); + copyCount = FAT_SECTOR_SIZE * sectorsWrote; + + // Increase total read count + bytesWritten += copyCount; + + // Increment file pointer + file->bytenum += copyCount; + + // Move onto next sector and reset copy offset + sector+= sectorsWrote; + offset = 0; + + if (!sectorsWrote) + break; + } + else + { + // We have upto one sector to copy + copyCount = FAT_SECTOR_SIZE - offset; + + // Only require some of this sector? + if (copyCount > (length - bytesWritten)) + copyCount = (length - bytesWritten); + + // Do we need to read a new sector? + if (file->file_data_address != sector) + { + // Flush un-written data to file + if (file->file_data_dirty) + fl_fflush(file); + + // If we plan to overwrite the whole sector, we don't need to read it first! + if (copyCount != FAT_SECTOR_SIZE) + { + // NOTE: This does not have succeed; if last sector of file + // reached, no valid data will be read in, but write will + // allocate some more space for new data. + + // Get LBA of sector offset within file + if (!_read_sectors(file, sector, file->file_data_sector, 1)) + memset(file->file_data_sector, 0x00, FAT_SECTOR_SIZE); + } + + file->file_data_address = sector; + file->file_data_dirty = 0; + } + + // Copy from application buffer into sector buffer + memcpy((uint8*)(file->file_data_sector + offset), (uint8*)(buffer + bytesWritten), copyCount); + + // Mark buffer as dirty + file->file_data_dirty = 1; + + // Increase total read count + bytesWritten += copyCount; + + // Increment file pointer + file->bytenum += copyCount; + + // Move onto next sector and reset copy offset + sector++; + offset = 0; + } + } + + // Write increased extent of the file? + if (file->bytenum > file->filelength) + { + // Increase file size to new point + file->filelength = file->bytenum; + + // We are changing the file length and this + // will need to be writen back at some point + file->filelength_changed = 1; + } + +#if FATFS_INC_TIME_DATE_SUPPORT + // If time & date support is enabled, always force directory entry to be + // written in-order to update file modify / access time & date. + file->filelength_changed = 1; +#endif + + FL_UNLOCK(&_fs); + + return (size*count); +} +#endif +//----------------------------------------------------------------------------- +// fl_fputs: Write a character string to the stream +//----------------------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +int fl_fputs(const char * str, void *f) +{ + int len = (int)strlen(str); + int res = fl_fwrite(str, 1, len, f); + + if (res == len) + return len; + else + return res; +} +#endif +//----------------------------------------------------------------------------- +// fl_remove: Remove a file from the filesystem +//----------------------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +int fl_remove( const char * filename ) +{ + FL_FILE* file; + int res = -1; + + FL_LOCK(&_fs); + + // Use read_file as this will check if the file is already open! + file = fl_fopen((char*)filename, "r"); + if (file) + { + // Delete allocated space + if (fatfs_free_cluster_chain(&_fs, file->startcluster)) + { + // Remove directory entries + if (fatfs_mark_file_deleted(&_fs, file->parentcluster, (char*)file->shortfilename)) + { + // Close the file handle (this should not write anything to the file + // as we have not changed the file since opening it!) + fl_fclose(file); + + res = 0; + } + } + } + + FL_UNLOCK(&_fs); + + return res; +} +#endif +//----------------------------------------------------------------------------- +// fl_createdirectory: Create a directory based on a path +//----------------------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +int fl_createdirectory(const char *path) +{ + int res; + + // If first call to library, initialise + CHECK_FL_INIT(); + + FL_LOCK(&_fs); + res =_create_directory((char*)path); + FL_UNLOCK(&_fs); + + return res; +} +#endif +//----------------------------------------------------------------------------- +// fl_listdirectory: List a directory based on a path +//----------------------------------------------------------------------------- +#if FATFS_DIR_LIST_SUPPORT +void fl_listdirectory(const char *path) +{ + FL_DIR dirstat; + + // If first call to library, initialise + CHECK_FL_INIT(); + + FL_LOCK(&_fs); + + FAT_PRINTF(("\r\nDirectory %s\r\n", path)); + + if (fl_opendir(path, &dirstat)) + { + struct fs_dir_ent dirent; + + while (fl_readdir(&dirstat, &dirent) == 0) + { +#if FATFS_INC_TIME_DATE_SUPPORT + int d,m,y,h,mn,s; + fatfs_convert_from_fat_time(dirent.write_time, &h,&m,&s); + fatfs_convert_from_fat_date(dirent.write_date, &d,&mn,&y); + FAT_PRINTF(("%02d/%02d/%04d %02d:%02d ", d,mn,y,h,m)); +#endif + + if (dirent.is_dir) + { + FAT_PRINTF(("%s \r\n", dirent.filename)); + } + else + { + FAT_PRINTF(("%s [%d bytes]\r\n", dirent.filename, dirent.size)); + } + } + + fl_closedir(&dirstat); + } + + FL_UNLOCK(&_fs); +} +#endif +//----------------------------------------------------------------------------- +// fl_opendir: Opens a directory for listing +//----------------------------------------------------------------------------- +#if FATFS_DIR_LIST_SUPPORT +FL_DIR* fl_opendir(const char* path, FL_DIR *dir) +{ + int levels; + int res = 1; + uint32 cluster = FAT32_INVALID_CLUSTER; + + // If first call to library, initialise + CHECK_FL_INIT(); + + FL_LOCK(&_fs); + + levels = fatfs_total_path_levels((char*)path) + 1; + + // If path is in the root dir + if (levels == 0) + cluster = fatfs_get_root_cluster(&_fs); + // Find parent directory start cluster + else + res = _open_directory((char*)path, &cluster); + + if (res) + fatfs_list_directory_start(&_fs, dir, cluster); + + FL_UNLOCK(&_fs); + + return cluster != FAT32_INVALID_CLUSTER ? dir : 0; +} +#endif +//----------------------------------------------------------------------------- +// fl_readdir: Get next item in directory +//----------------------------------------------------------------------------- +#if FATFS_DIR_LIST_SUPPORT +int fl_readdir(FL_DIR *dirls, fl_dirent *entry) +{ + int res = 0; + + // If first call to library, initialise + CHECK_FL_INIT(); + + FL_LOCK(&_fs); + + res = fatfs_list_directory_next(&_fs, dirls, entry); + + FL_UNLOCK(&_fs); + + return res ? 0 : -1; +} +#endif +//----------------------------------------------------------------------------- +// fl_closedir: Close directory after listing +//----------------------------------------------------------------------------- +#if FATFS_DIR_LIST_SUPPORT +int fl_closedir(FL_DIR* dir) +{ + // Not used + return 0; +} +#endif +//----------------------------------------------------------------------------- +// fl_is_dir: Is this a directory? +//----------------------------------------------------------------------------- +#if FATFS_DIR_LIST_SUPPORT +int fl_is_dir(const char *path) +{ + int res = 0; + FL_DIR dir; + + if (fl_opendir(path, &dir)) + { + res = 1; + fl_closedir(&dir); + } + + return res; +} +#endif +//----------------------------------------------------------------------------- +// fl_format: Format a partition with either FAT16 or FAT32 based on size +//----------------------------------------------------------------------------- +#if FATFS_INC_FORMAT_SUPPORT +int fl_format(uint32 volume_sectors, const char *name) +{ + return fatfs_format(&_fs, volume_sectors, name); +} +#endif /*FATFS_INC_FORMAT_SUPPORT*/ +//----------------------------------------------------------------------------- +// fl_get_fs: +//----------------------------------------------------------------------------- +#ifdef FATFS_INC_TEST_HOOKS +struct fatfs* fl_get_fs(void) +{ + return &_fs; +} +#endif diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_filelib.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_filelib.h new file mode 100644 index 0000000..a40a28f --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_filelib.h @@ -0,0 +1,146 @@ +#ifndef __FAT_FILELIB_H__ +#define __FAT_FILELIB_H__ + +#include "fat_opts.h" +#include "fat_access.h" +#include "fat_list.h" + +//----------------------------------------------------------------------------- +// Defines +//----------------------------------------------------------------------------- +#ifndef SEEK_CUR + #define SEEK_CUR 1 +#endif + +#ifndef SEEK_END + #define SEEK_END 2 +#endif + +#ifndef SEEK_SET + #define SEEK_SET 0 +#endif + +#ifndef EOF + #define EOF (-1) +#endif + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- +struct sFL_FILE; + +struct cluster_lookup +{ + uint32 ClusterIdx; + uint32 CurrentCluster; +}; + +typedef struct sFL_FILE +{ + uint32 parentcluster; + uint32 startcluster; + uint32 bytenum; + uint32 filelength; + int filelength_changed; + char path[FATFS_MAX_LONG_FILENAME]; + char filename[FATFS_MAX_LONG_FILENAME]; + uint8 shortfilename[11]; + +#ifdef FAT_CLUSTER_CACHE_ENTRIES + uint32 cluster_cache_idx[FAT_CLUSTER_CACHE_ENTRIES]; + uint32 cluster_cache_data[FAT_CLUSTER_CACHE_ENTRIES]; +#endif + + // Cluster Lookup + struct cluster_lookup last_fat_lookup; + + // Read/Write sector buffer + uint8 file_data_sector[FAT_SECTOR_SIZE]; + uint32 file_data_address; + int file_data_dirty; + + // File fopen flags + uint8 flags; +#define FILE_READ (1 << 0) +#define FILE_WRITE (1 << 1) +#define FILE_APPEND (1 << 2) +#define FILE_BINARY (1 << 3) +#define FILE_ERASE (1 << 4) +#define FILE_CREATE (1 << 5) + + struct fat_node list_node; +} FL_FILE; + +//----------------------------------------------------------------------------- +// Prototypes +//----------------------------------------------------------------------------- + +// External +void fl_init(void); +void fl_attach_locks(void (*lock)(void), void (*unlock)(void)); +int fl_attach_media(fn_diskio_read rd, fn_diskio_write wr); +void fl_shutdown(void); + +// Standard API +void* fl_fopen(const char *path, const char *modifiers); +void fl_fclose(void *file); +int fl_fflush(void *file); +int fl_fgetc(void *file); +char * fl_fgets(char *s, int n, void *f); +int fl_fputc(int c, void *file); +int fl_fputs(const char * str, void *file); +int fl_fwrite(const void * data, int size, int count, void *file ); +int fl_fread(void * data, int size, int count, void *file ); +int fl_fseek(void *file , long offset , int origin ); +int fl_fgetpos(void *file , uint32 * position); +long fl_ftell(void *f); +int fl_feof(void *f); +int fl_remove(const char * filename); + +// Equivelant dirent.h +typedef struct fs_dir_list_status FL_DIR; +typedef struct fs_dir_ent fl_dirent; + +FL_DIR* fl_opendir(const char* path, FL_DIR *dir); +int fl_readdir(FL_DIR *dirls, fl_dirent *entry); +int fl_closedir(FL_DIR* dir); + +// Extensions +void fl_listdirectory(const char *path); +int fl_createdirectory(const char *path); +int fl_is_dir(const char *path); + +int fl_format(uint32 volume_sectors, const char *name); + +// Test hooks +#ifdef FATFS_INC_TEST_HOOKS +struct fatfs* fl_get_fs(void); +#endif + +//----------------------------------------------------------------------------- +// Stdio file I/O names +//----------------------------------------------------------------------------- +#ifdef USE_FILELIB_STDIO_COMPAT_NAMES + +#define FILE FL_FILE + +#define fopen(a,b) fl_fopen(a, b) +#define fclose(a) fl_fclose(a) +#define fflush(a) fl_fflush(a) +#define fgetc(a) fl_fgetc(a) +#define fgets(a,b,c) fl_fgets(a, b, c) +#define fputc(a,b) fl_fputc(a, b) +#define fputs(a,b) fl_fputs(a, b) +#define fwrite(a,b,c,d) fl_fwrite(a, b, c, d) +#define fread(a,b,c,d) fl_fread(a, b, c, d) +#define fseek(a,b,c) fl_fseek(a, b, c) +#define fgetpos(a,b) fl_fgetpos(a, b) +#define ftell(a) fl_ftell(a) +#define feof(a) fl_feof(a) +#define remove(a) fl_remove(a) +#define mkdir(a) fl_createdirectory(a) +#define rmdir(a) 0 + +#endif + +#endif diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_format.c b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_format.c new file mode 100644 index 0000000..d067f37 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_format.c @@ -0,0 +1,532 @@ +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// FAT16/32 File IO Library +// V2.6 +// Ultra-Embedded.com +// Copyright 2003 - 2012 +// +// Email: admin@ultra-embedded.com +// +// License: GPL +// If you would like a version with a more permissive license for use in +// closed source commercial applications please contact me for details. +//----------------------------------------------------------------------------- +// +// This file is part of FAT File IO Library. +// +// FAT File IO Library 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. +// +// FAT File IO 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FAT File IO Library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +#include +#include "fat_defs.h" +#include "fat_access.h" +#include "fat_table.h" +#include "fat_write.h" +#include "fat_string.h" +#include "fat_misc.h" +#include "fat_format.h" + +#if FATFS_INC_FORMAT_SUPPORT + +//----------------------------------------------------------------------------- +// Tables +//----------------------------------------------------------------------------- +struct sec_per_clus_table +{ + uint32 sectors; + uint8 sectors_per_cluster; +}; + +struct sec_per_clus_table _cluster_size_table16[] = +{ + { 32680, 2}, // 16MB - 1K + { 262144, 4}, // 128MB - 2K + { 524288, 8}, // 256MB - 4K + { 1048576, 16}, // 512MB - 8K + { 2097152, 32}, // 1GB - 16K + { 4194304, 64}, // 2GB - 32K + { 8388608, 128},// 2GB - 64K [Warning only supported by Windows XP onwards] + { 0 , 0 } // Invalid +}; + +struct sec_per_clus_table _cluster_size_table32[] = +{ + { 532480, 1}, // 260MB - 512b + { 16777216, 8}, // 8GB - 4K + { 33554432, 16}, // 16GB - 8K + { 67108864, 32}, // 32GB - 16K + { 0xFFFFFFFF, 64},// >32GB - 32K + { 0 , 0 } // Invalid +}; + +//----------------------------------------------------------------------------- +// fatfs_calc_cluster_size: Calculate what cluster size should be used +//----------------------------------------------------------------------------- +static uint8 fatfs_calc_cluster_size(uint32 sectors, int is_fat32) +{ + int i; + + if (!is_fat32) + { + for (i=0; _cluster_size_table16[i].sectors_per_cluster != 0;i++) + if (sectors <= _cluster_size_table16[i].sectors) + return _cluster_size_table16[i].sectors_per_cluster; + } + else + { + for (i=0; _cluster_size_table32[i].sectors_per_cluster != 0;i++) + if (sectors <= _cluster_size_table32[i].sectors) + return _cluster_size_table32[i].sectors_per_cluster; + } + + return 0; +} +//----------------------------------------------------------------------------- +// fatfs_erase_sectors: Erase a number of sectors +//----------------------------------------------------------------------------- +static int fatfs_erase_sectors(struct fatfs *fs, uint32 lba, int count) +{ + int i; + + // Zero sector first + memset(fs->currentsector.sector, 0, FAT_SECTOR_SIZE); + + for (i=0;idisk_io.write_media(lba + i, fs->currentsector.sector, 1)) + return 0; + + return 1; +} +//----------------------------------------------------------------------------- +// fatfs_create_boot_sector: Create the boot sector +//----------------------------------------------------------------------------- +static int fatfs_create_boot_sector(struct fatfs *fs, uint32 boot_sector_lba, uint32 vol_sectors, const char *name, int is_fat32) +{ + uint32 total_clusters; + int i; + + // Zero sector initially + memset(fs->currentsector.sector, 0, FAT_SECTOR_SIZE); + + // OEM Name & Jump Code + fs->currentsector.sector[0] = 0xEB; + fs->currentsector.sector[1] = 0x3C; + fs->currentsector.sector[2] = 0x90; + fs->currentsector.sector[3] = 0x4D; + fs->currentsector.sector[4] = 0x53; + fs->currentsector.sector[5] = 0x44; + fs->currentsector.sector[6] = 0x4F; + fs->currentsector.sector[7] = 0x53; + fs->currentsector.sector[8] = 0x35; + fs->currentsector.sector[9] = 0x2E; + fs->currentsector.sector[10] = 0x30; + + // Bytes per sector + fs->currentsector.sector[11] = (FAT_SECTOR_SIZE >> 0) & 0xFF; + fs->currentsector.sector[12] = (FAT_SECTOR_SIZE >> 8) & 0xFF; + + // Get sectors per cluster size for the disk + fs->sectors_per_cluster = fatfs_calc_cluster_size(vol_sectors, is_fat32); + if (!fs->sectors_per_cluster) + return 0; // Invalid disk size + + // Sectors per cluster + fs->currentsector.sector[13] = fs->sectors_per_cluster; + + // Reserved Sectors + if (!is_fat32) + fs->reserved_sectors = 8; + else + fs->reserved_sectors = 32; + fs->currentsector.sector[14] = (fs->reserved_sectors >> 0) & 0xFF; + fs->currentsector.sector[15] = (fs->reserved_sectors >> 8) & 0xFF; + + // Number of FATS + fs->num_of_fats = 2; + fs->currentsector.sector[16] = fs->num_of_fats; + + // Max entries in root dir (FAT16 only) + if (!is_fat32) + { + fs->root_entry_count = 512; + fs->currentsector.sector[17] = (fs->root_entry_count >> 0) & 0xFF; + fs->currentsector.sector[18] = (fs->root_entry_count >> 8) & 0xFF; + } + else + { + fs->root_entry_count = 0; + fs->currentsector.sector[17] = 0; + fs->currentsector.sector[18] = 0; + } + + // [FAT16] Total sectors (use FAT32 count instead) + fs->currentsector.sector[19] = 0x00; + fs->currentsector.sector[20] = 0x00; + + // Media type + fs->currentsector.sector[21] = 0xF8; + + + // FAT16 BS Details + if (!is_fat32) + { + // Count of sectors used by the FAT table (FAT16 only) + total_clusters = (vol_sectors / fs->sectors_per_cluster) + 1; + fs->fat_sectors = (total_clusters/(FAT_SECTOR_SIZE/2)) + 1; + fs->currentsector.sector[22] = (uint8)((fs->fat_sectors >> 0) & 0xFF); + fs->currentsector.sector[23] = (uint8)((fs->fat_sectors >> 8) & 0xFF); + + // Sectors per track + fs->currentsector.sector[24] = 0x00; + fs->currentsector.sector[25] = 0x00; + + // Heads + fs->currentsector.sector[26] = 0x00; + fs->currentsector.sector[27] = 0x00; + + // Hidden sectors + fs->currentsector.sector[28] = 0x20; + fs->currentsector.sector[29] = 0x00; + fs->currentsector.sector[30] = 0x00; + fs->currentsector.sector[31] = 0x00; + + // Total sectors for this volume + fs->currentsector.sector[32] = (uint8)((vol_sectors>>0)&0xFF); + fs->currentsector.sector[33] = (uint8)((vol_sectors>>8)&0xFF); + fs->currentsector.sector[34] = (uint8)((vol_sectors>>16)&0xFF); + fs->currentsector.sector[35] = (uint8)((vol_sectors>>24)&0xFF); + + // Drive number + fs->currentsector.sector[36] = 0x00; + + // Reserved + fs->currentsector.sector[37] = 0x00; + + // Boot signature + fs->currentsector.sector[38] = 0x29; + + // Volume ID + fs->currentsector.sector[39] = 0x12; + fs->currentsector.sector[40] = 0x34; + fs->currentsector.sector[41] = 0x56; + fs->currentsector.sector[42] = 0x78; + + // Volume name + for (i=0;i<11;i++) + { + if (i < (int)strlen(name)) + fs->currentsector.sector[i+43] = name[i]; + else + fs->currentsector.sector[i+43] = ' '; + } + + // File sys type + fs->currentsector.sector[54] = 'F'; + fs->currentsector.sector[55] = 'A'; + fs->currentsector.sector[56] = 'T'; + fs->currentsector.sector[57] = '1'; + fs->currentsector.sector[58] = '6'; + fs->currentsector.sector[59] = ' '; + fs->currentsector.sector[60] = ' '; + fs->currentsector.sector[61] = ' '; + + // Signature + fs->currentsector.sector[510] = 0x55; + fs->currentsector.sector[511] = 0xAA; + } + // FAT32 BS Details + else + { + // Count of sectors used by the FAT table (FAT16 only) + fs->currentsector.sector[22] = 0; + fs->currentsector.sector[23] = 0; + + // Sectors per track (default) + fs->currentsector.sector[24] = 0x3F; + fs->currentsector.sector[25] = 0x00; + + // Heads (default) + fs->currentsector.sector[26] = 0xFF; + fs->currentsector.sector[27] = 0x00; + + // Hidden sectors + fs->currentsector.sector[28] = 0x00; + fs->currentsector.sector[29] = 0x00; + fs->currentsector.sector[30] = 0x00; + fs->currentsector.sector[31] = 0x00; + + // Total sectors for this volume + fs->currentsector.sector[32] = (uint8)((vol_sectors>>0)&0xFF); + fs->currentsector.sector[33] = (uint8)((vol_sectors>>8)&0xFF); + fs->currentsector.sector[34] = (uint8)((vol_sectors>>16)&0xFF); + fs->currentsector.sector[35] = (uint8)((vol_sectors>>24)&0xFF); + + total_clusters = (vol_sectors / fs->sectors_per_cluster) + 1; + fs->fat_sectors = (total_clusters/(FAT_SECTOR_SIZE/4)) + 1; + + // BPB_FATSz32 + fs->currentsector.sector[36] = (uint8)((fs->fat_sectors>>0)&0xFF); + fs->currentsector.sector[37] = (uint8)((fs->fat_sectors>>8)&0xFF); + fs->currentsector.sector[38] = (uint8)((fs->fat_sectors>>16)&0xFF); + fs->currentsector.sector[39] = (uint8)((fs->fat_sectors>>24)&0xFF); + + // BPB_ExtFlags + fs->currentsector.sector[40] = 0; + fs->currentsector.sector[41] = 0; + + // BPB_FSVer + fs->currentsector.sector[42] = 0; + fs->currentsector.sector[43] = 0; + + // BPB_RootClus + fs->currentsector.sector[44] = (uint8)((fs->rootdir_first_cluster>>0)&0xFF); + fs->currentsector.sector[45] = (uint8)((fs->rootdir_first_cluster>>8)&0xFF); + fs->currentsector.sector[46] = (uint8)((fs->rootdir_first_cluster>>16)&0xFF); + fs->currentsector.sector[47] = (uint8)((fs->rootdir_first_cluster>>24)&0xFF); + + // BPB_FSInfo + fs->currentsector.sector[48] = (uint8)((fs->fs_info_sector>>0)&0xFF); + fs->currentsector.sector[49] = (uint8)((fs->fs_info_sector>>8)&0xFF); + + // BPB_BkBootSec + fs->currentsector.sector[50] = 6; + fs->currentsector.sector[51] = 0; + + // Drive number + fs->currentsector.sector[64] = 0x00; + + // Boot signature + fs->currentsector.sector[66] = 0x29; + + // Volume ID + fs->currentsector.sector[67] = 0x12; + fs->currentsector.sector[68] = 0x34; + fs->currentsector.sector[69] = 0x56; + fs->currentsector.sector[70] = 0x78; + + // Volume name + for (i=0;i<11;i++) + { + if (i < (int)strlen(name)) + fs->currentsector.sector[i+71] = name[i]; + else + fs->currentsector.sector[i+71] = ' '; + } + + // File sys type + fs->currentsector.sector[82] = 'F'; + fs->currentsector.sector[83] = 'A'; + fs->currentsector.sector[84] = 'T'; + fs->currentsector.sector[85] = '3'; + fs->currentsector.sector[86] = '2'; + fs->currentsector.sector[87] = ' '; + fs->currentsector.sector[88] = ' '; + fs->currentsector.sector[89] = ' '; + + // Signature + fs->currentsector.sector[510] = 0x55; + fs->currentsector.sector[511] = 0xAA; + } + + if (fs->disk_io.write_media(boot_sector_lba, fs->currentsector.sector, 1)) + return 1; + else + return 0; +} +//----------------------------------------------------------------------------- +// fatfs_create_fsinfo_sector: Create the FSInfo sector (FAT32) +//----------------------------------------------------------------------------- +static int fatfs_create_fsinfo_sector(struct fatfs *fs, uint32 sector_lba) +{ + // Zero sector initially + memset(fs->currentsector.sector, 0, FAT_SECTOR_SIZE); + + // FSI_LeadSig + fs->currentsector.sector[0] = 0x52; + fs->currentsector.sector[1] = 0x52; + fs->currentsector.sector[2] = 0x61; + fs->currentsector.sector[3] = 0x41; + + // FSI_StrucSig + fs->currentsector.sector[484] = 0x72; + fs->currentsector.sector[485] = 0x72; + fs->currentsector.sector[486] = 0x41; + fs->currentsector.sector[487] = 0x61; + + // FSI_Free_Count + fs->currentsector.sector[488] = 0xFF; + fs->currentsector.sector[489] = 0xFF; + fs->currentsector.sector[490] = 0xFF; + fs->currentsector.sector[491] = 0xFF; + + // FSI_Nxt_Free + fs->currentsector.sector[492] = 0xFF; + fs->currentsector.sector[493] = 0xFF; + fs->currentsector.sector[494] = 0xFF; + fs->currentsector.sector[495] = 0xFF; + + // Signature + fs->currentsector.sector[510] = 0x55; + fs->currentsector.sector[511] = 0xAA; + + if (fs->disk_io.write_media(sector_lba, fs->currentsector.sector, 1)) + return 1; + else + return 0; +} +//----------------------------------------------------------------------------- +// fatfs_erase_fat: Erase FAT table using fs details in fs struct +//----------------------------------------------------------------------------- +static int fatfs_erase_fat(struct fatfs *fs, int is_fat32) +{ + uint32 i; + + // Zero sector initially + memset(fs->currentsector.sector, 0, FAT_SECTOR_SIZE); + + // Initialise default allocate / reserved clusters + if (!is_fat32) + { + SET_16BIT_WORD(fs->currentsector.sector, 0, 0xFFF8); + SET_16BIT_WORD(fs->currentsector.sector, 2, 0xFFFF); + } + else + { + SET_32BIT_WORD(fs->currentsector.sector, 0, 0x0FFFFFF8); + SET_32BIT_WORD(fs->currentsector.sector, 4, 0xFFFFFFFF); + SET_32BIT_WORD(fs->currentsector.sector, 8, 0x0FFFFFFF); + } + + if (!fs->disk_io.write_media(fs->fat_begin_lba + 0, fs->currentsector.sector, 1)) + return 0; + + // Zero remaining FAT sectors + memset(fs->currentsector.sector, 0, FAT_SECTOR_SIZE); + for (i=1;ifat_sectors*fs->num_of_fats;i++) + if (!fs->disk_io.write_media(fs->fat_begin_lba + i, fs->currentsector.sector, 1)) + return 0; + + return 1; +} +//----------------------------------------------------------------------------- +// fatfs_format_fat16: Format a FAT16 partition +//----------------------------------------------------------------------------- +int fatfs_format_fat16(struct fatfs *fs, uint32 volume_sectors, const char *name) +{ + fs->currentsector.address = FAT32_INVALID_CLUSTER; + fs->currentsector.dirty = 0; + + fs->next_free_cluster = 0; // Invalid + + fatfs_fat_init(fs); + + // Make sure we have read + write functions + if (!fs->disk_io.read_media || !fs->disk_io.write_media) + return FAT_INIT_MEDIA_ACCESS_ERROR; + + // Volume is FAT16 + fs->fat_type = FAT_TYPE_16; + + // Not valid for FAT16 + fs->fs_info_sector = 0; + fs->rootdir_first_cluster = 0; + + // Sector 0: Boot sector + // NOTE: We don't need an MBR, it is a waste of a good sector! + fs->lba_begin = 0; + if (!fatfs_create_boot_sector(fs, fs->lba_begin, volume_sectors, name, 0)) + return 0; + + // For FAT16 (which this may be), rootdir_first_cluster is actuall rootdir_first_sector + fs->rootdir_first_sector = fs->reserved_sectors + (fs->num_of_fats * fs->fat_sectors); + fs->rootdir_sectors = ((fs->root_entry_count * 32) + (FAT_SECTOR_SIZE - 1)) / FAT_SECTOR_SIZE; + + // First FAT LBA address + fs->fat_begin_lba = fs->lba_begin + fs->reserved_sectors; + + // The address of the first data cluster on this volume + fs->cluster_begin_lba = fs->fat_begin_lba + (fs->num_of_fats * fs->fat_sectors); + + // Initialise FAT sectors + if (!fatfs_erase_fat(fs, 0)) + return 0; + + // Erase Root directory + if (!fatfs_erase_sectors(fs, fs->lba_begin + fs->rootdir_first_sector, fs->rootdir_sectors)) + return 0; + + return 1; +} +//----------------------------------------------------------------------------- +// fatfs_format_fat32: Format a FAT32 partition +//----------------------------------------------------------------------------- +int fatfs_format_fat32(struct fatfs *fs, uint32 volume_sectors, const char *name) +{ + fs->currentsector.address = FAT32_INVALID_CLUSTER; + fs->currentsector.dirty = 0; + + fs->next_free_cluster = 0; // Invalid + + fatfs_fat_init(fs); + + // Make sure we have read + write functions + if (!fs->disk_io.read_media || !fs->disk_io.write_media) + return FAT_INIT_MEDIA_ACCESS_ERROR; + + // Volume is FAT32 + fs->fat_type = FAT_TYPE_32; + + // Basic defaults for normal FAT32 partitions + fs->fs_info_sector = 1; + fs->rootdir_first_cluster = 2; + + // Sector 0: Boot sector + // NOTE: We don't need an MBR, it is a waste of a good sector! + fs->lba_begin = 0; + if (!fatfs_create_boot_sector(fs, fs->lba_begin, volume_sectors, name, 1)) + return 0; + + // First FAT LBA address + fs->fat_begin_lba = fs->lba_begin + fs->reserved_sectors; + + // The address of the first data cluster on this volume + fs->cluster_begin_lba = fs->fat_begin_lba + (fs->num_of_fats * fs->fat_sectors); + + // Initialise FSInfo sector + if (!fatfs_create_fsinfo_sector(fs, fs->fs_info_sector)) + return 0; + + // Initialise FAT sectors + if (!fatfs_erase_fat(fs, 1)) + return 0; + + // Erase Root directory + if (!fatfs_erase_sectors(fs, fatfs_lba_of_cluster(fs, fs->rootdir_first_cluster), fs->sectors_per_cluster)) + return 0; + + return 1; +} +//----------------------------------------------------------------------------- +// fatfs_format: Format a partition with either FAT16 or FAT32 based on size +//----------------------------------------------------------------------------- +int fatfs_format(struct fatfs *fs, uint32 volume_sectors, const char *name) +{ + // 2GB - 32K limit for safe behaviour for FAT16 + if (volume_sectors <= 4194304) + return fatfs_format_fat16(fs, volume_sectors, name); + else + return fatfs_format_fat32(fs, volume_sectors, name); +} +#endif /*FATFS_INC_FORMAT_SUPPORT*/ diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_format.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_format.h new file mode 100644 index 0000000..a8a6bba --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_format.h @@ -0,0 +1,15 @@ +#ifndef __FAT_FORMAT_H__ +#define __FAT_FORMAT_H__ + +#include "fat_defs.h" +#include "fat_opts.h" +#include "fat_access.h" + +//----------------------------------------------------------------------------- +// Prototypes +//----------------------------------------------------------------------------- +int fatfs_format(struct fatfs *fs, uint32 volume_sectors, const char *name); +int fatfs_format_fat16(struct fatfs *fs, uint32 volume_sectors, const char *name); +int fatfs_format_fat32(struct fatfs *fs, uint32 volume_sectors, const char *name); + +#endif diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_list.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_list.h new file mode 100644 index 0000000..bd386ef --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_list.h @@ -0,0 +1,161 @@ +#ifndef __FAT_LIST_H__ +#define __FAT_LIST_H__ + +#ifndef FAT_ASSERT + #define FAT_ASSERT(x) +#endif + +#ifndef FAT_INLINE + #define FAT_INLINE +#endif + +//----------------------------------------------------------------- +// Types +//----------------------------------------------------------------- +struct fat_list; + +struct fat_node +{ + struct fat_node *previous; + struct fat_node *next; +}; + +struct fat_list +{ + struct fat_node *head; + struct fat_node *tail; +}; + +//----------------------------------------------------------------- +// Macros +//----------------------------------------------------------------- +#define fat_list_entry(p, t, m) p ? ((t *)((char *)(p)-(char*)(&((t *)0)->m))) : 0 +#define fat_list_next(l, p) (p)->next +#define fat_list_prev(l, p) (p)->previous +#define fat_list_first(l) (l)->head +#define fat_list_last(l) (l)->tail +#define fat_list_for_each(l, p) for ((p) = (l)->head; (p); (p) = (p)->next) + +//----------------------------------------------------------------- +// Inline Functions +//----------------------------------------------------------------- + +//----------------------------------------------------------------- +// fat_list_init: +//----------------------------------------------------------------- +static FAT_INLINE void fat_list_init(struct fat_list *list) +{ + FAT_ASSERT(list); + + list->head = list->tail = 0; +} +//----------------------------------------------------------------- +// fat_list_remove: +//----------------------------------------------------------------- +static FAT_INLINE void fat_list_remove(struct fat_list *list, struct fat_node *node) +{ + FAT_ASSERT(list); + FAT_ASSERT(node); + + if(!node->previous) + list->head = node->next; + else + node->previous->next = node->next; + + if(!node->next) + list->tail = node->previous; + else + node->next->previous = node->previous; +} +//----------------------------------------------------------------- +// fat_list_insert_after: +//----------------------------------------------------------------- +static FAT_INLINE void fat_list_insert_after(struct fat_list *list, struct fat_node *node, struct fat_node *new_node) +{ + FAT_ASSERT(list); + FAT_ASSERT(node); + FAT_ASSERT(new_node); + + new_node->previous = node; + new_node->next = node->next; + if (!node->next) + list->tail = new_node; + else + node->next->previous = new_node; + node->next = new_node; +} +//----------------------------------------------------------------- +// fat_list_insert_before: +//----------------------------------------------------------------- +static FAT_INLINE void fat_list_insert_before(struct fat_list *list, struct fat_node *node, struct fat_node *new_node) +{ + FAT_ASSERT(list); + FAT_ASSERT(node); + FAT_ASSERT(new_node); + + new_node->previous = node->previous; + new_node->next = node; + if (!node->previous) + list->head = new_node; + else + node->previous->next = new_node; + node->previous = new_node; +} +//----------------------------------------------------------------- +// fat_list_insert_first: +//----------------------------------------------------------------- +static FAT_INLINE void fat_list_insert_first(struct fat_list *list, struct fat_node *node) +{ + FAT_ASSERT(list); + FAT_ASSERT(node); + + if (!list->head) + { + list->head = node; + list->tail = node; + node->previous = 0; + node->next = 0; + } + else + fat_list_insert_before(list, list->head, node); +} +//----------------------------------------------------------------- +// fat_list_insert_last: +//----------------------------------------------------------------- +static FAT_INLINE void fat_list_insert_last(struct fat_list *list, struct fat_node *node) +{ + FAT_ASSERT(list); + FAT_ASSERT(node); + + if (!list->tail) + fat_list_insert_first(list, node); + else + fat_list_insert_after(list, list->tail, node); +} +//----------------------------------------------------------------- +// fat_list_is_empty: +//----------------------------------------------------------------- +static FAT_INLINE int fat_list_is_empty(struct fat_list *list) +{ + FAT_ASSERT(list); + + return !list->head; +} +//----------------------------------------------------------------- +// fat_list_pop_head: +//----------------------------------------------------------------- +static FAT_INLINE struct fat_node * fat_list_pop_head(struct fat_list *list) +{ + struct fat_node * node; + + FAT_ASSERT(list); + + node = fat_list_first(list); + if (node) + fat_list_remove(list, node); + + return node; +} + +#endif + diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_misc.c b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_misc.c new file mode 100644 index 0000000..cbf6f08 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_misc.c @@ -0,0 +1,505 @@ +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// FAT16/32 File IO Library +// V2.6 +// Ultra-Embedded.com +// Copyright 2003 - 2012 +// +// Email: admin@ultra-embedded.com +// +// License: GPL +// If you would like a version with a more permissive license for use in +// closed source commercial applications please contact me for details. +//----------------------------------------------------------------------------- +// +// This file is part of FAT File IO Library. +// +// FAT File IO Library 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. +// +// FAT File IO 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FAT File IO Library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +#include +#include +#include "fat_misc.h" + +//----------------------------------------------------------------------------- +// fatfs_lfn_cache_init: Clear long file name cache +//----------------------------------------------------------------------------- +void fatfs_lfn_cache_init(struct lfn_cache *lfn, int wipeTable) +{ + int i = 0; + + lfn->no_of_strings = 0; + +#if FATFS_INC_LFN_SUPPORT + + // Zero out buffer also + if (wipeTable) + for (i=0;iString[i], 0x00, MAX_LFN_ENTRY_LENGTH); +#endif +} +//----------------------------------------------------------------------------- +// fatfs_lfn_cache_entry - Function extracts long file name text from sector +// at a specific offset +//----------------------------------------------------------------------------- +#if FATFS_INC_LFN_SUPPORT +void fatfs_lfn_cache_entry(struct lfn_cache *lfn, uint8 *entryBuffer) +{ + uint8 LFNIndex, i; + LFNIndex = entryBuffer[0] & 0x1F; + + // Limit file name to cache size! + if (LFNIndex > MAX_LONGFILENAME_ENTRIES) + return ; + + // This is an error condition + if (LFNIndex == 0) + return ; + + if (lfn->no_of_strings == 0) + lfn->no_of_strings = LFNIndex; + + lfn->String[LFNIndex-1][0] = entryBuffer[1]; + lfn->String[LFNIndex-1][1] = entryBuffer[3]; + lfn->String[LFNIndex-1][2] = entryBuffer[5]; + lfn->String[LFNIndex-1][3] = entryBuffer[7]; + lfn->String[LFNIndex-1][4] = entryBuffer[9]; + lfn->String[LFNIndex-1][5] = entryBuffer[0x0E]; + lfn->String[LFNIndex-1][6] = entryBuffer[0x10]; + lfn->String[LFNIndex-1][7] = entryBuffer[0x12]; + lfn->String[LFNIndex-1][8] = entryBuffer[0x14]; + lfn->String[LFNIndex-1][9] = entryBuffer[0x16]; + lfn->String[LFNIndex-1][10] = entryBuffer[0x18]; + lfn->String[LFNIndex-1][11] = entryBuffer[0x1C]; + lfn->String[LFNIndex-1][12] = entryBuffer[0x1E]; + + for (i=0; iString[LFNIndex-1][i]==0xFF) + lfn->String[LFNIndex-1][i] = 0x20; // Replace with spaces +} +#endif +//----------------------------------------------------------------------------- +// fatfs_lfn_cache_get: Get a reference to the long filename +//----------------------------------------------------------------------------- +#if FATFS_INC_LFN_SUPPORT +char* fatfs_lfn_cache_get(struct lfn_cache *lfn) +{ + // Null terminate long filename + if (lfn->no_of_strings == MAX_LONGFILENAME_ENTRIES) + lfn->Null = '\0'; + else if (lfn->no_of_strings) + lfn->String[lfn->no_of_strings][0] = '\0'; + else + lfn->String[0][0] = '\0'; + + return (char*)&lfn->String[0][0]; +} +#endif +//----------------------------------------------------------------------------- +// fatfs_entry_lfn_text: If LFN text entry found +//----------------------------------------------------------------------------- +#if FATFS_INC_LFN_SUPPORT +int fatfs_entry_lfn_text(struct fat_dir_entry *entry) +{ + if ((entry->Attr & FILE_ATTR_LFN_TEXT) == FILE_ATTR_LFN_TEXT) + return 1; + else + return 0; +} +#endif +//----------------------------------------------------------------------------- +// fatfs_entry_lfn_invalid: If SFN found not relating to LFN +//----------------------------------------------------------------------------- +#if FATFS_INC_LFN_SUPPORT +int fatfs_entry_lfn_invalid(struct fat_dir_entry *entry) +{ + if ( (entry->Name[0]==FILE_HEADER_BLANK) || + (entry->Name[0]==FILE_HEADER_DELETED)|| + (entry->Attr==FILE_ATTR_VOLUME_ID) || + (entry->Attr & FILE_ATTR_SYSHID) ) + return 1; + else + return 0; +} +#endif +//----------------------------------------------------------------------------- +// fatfs_entry_lfn_exists: If LFN exists and correlation SFN found +//----------------------------------------------------------------------------- +#if FATFS_INC_LFN_SUPPORT +int fatfs_entry_lfn_exists(struct lfn_cache *lfn, struct fat_dir_entry *entry) +{ + if ( (entry->Attr!=FILE_ATTR_LFN_TEXT) && + (entry->Name[0]!=FILE_HEADER_BLANK) && + (entry->Name[0]!=FILE_HEADER_DELETED) && + (entry->Attr!=FILE_ATTR_VOLUME_ID) && + (!(entry->Attr&FILE_ATTR_SYSHID)) && + (lfn->no_of_strings) ) + return 1; + else + return 0; +} +#endif +//----------------------------------------------------------------------------- +// fatfs_entry_sfn_only: If SFN only exists +//----------------------------------------------------------------------------- +int fatfs_entry_sfn_only(struct fat_dir_entry *entry) +{ + if ( (entry->Attr!=FILE_ATTR_LFN_TEXT) && + (entry->Name[0]!=FILE_HEADER_BLANK) && + (entry->Name[0]!=FILE_HEADER_DELETED) && + (entry->Attr!=FILE_ATTR_VOLUME_ID) && + (!(entry->Attr&FILE_ATTR_SYSHID)) ) + return 1; + else + return 0; +} +// TODO: FILE_ATTR_SYSHID ?!?!??! +//----------------------------------------------------------------------------- +// fatfs_entry_is_dir: Returns 1 if a directory +//----------------------------------------------------------------------------- +int fatfs_entry_is_dir(struct fat_dir_entry *entry) +{ + if (entry->Attr & FILE_TYPE_DIR) + return 1; + else + return 0; +} +//----------------------------------------------------------------------------- +// fatfs_entry_is_file: Returns 1 is a file entry +//----------------------------------------------------------------------------- +int fatfs_entry_is_file(struct fat_dir_entry *entry) +{ + if (entry->Attr & FILE_TYPE_FILE) + return 1; + else + return 0; +} +//----------------------------------------------------------------------------- +// fatfs_lfn_entries_required: Calculate number of 13 characters entries +//----------------------------------------------------------------------------- +#if FATFS_INC_LFN_SUPPORT +int fatfs_lfn_entries_required(char *filename) +{ + int length = (int)strlen(filename); + + if (length) + return (length + MAX_LFN_ENTRY_LENGTH - 1) / MAX_LFN_ENTRY_LENGTH; + else + return 0; +} +#endif +//----------------------------------------------------------------------------- +// fatfs_filename_to_lfn: +//----------------------------------------------------------------------------- +#if FATFS_INC_LFN_SUPPORT +void fatfs_filename_to_lfn(char *filename, uint8 *buffer, int entry, uint8 sfnChk) +{ + int i; + int nameIndexes[MAX_LFN_ENTRY_LENGTH] = {1,3,5,7,9,0x0E,0x10,0x12,0x14,0x16,0x18,0x1C,0x1E}; + + // 13 characters entries + int length = (int)strlen(filename); + int entriesRequired = fatfs_lfn_entries_required(filename); + + // Filename offset + int start = entry * MAX_LFN_ENTRY_LENGTH; + + // Initialise to zeros + memset(buffer, 0x00, FAT_DIR_ENTRY_SIZE); + + // LFN entry number + buffer[0] = (uint8)(((entriesRequired-1)==entry)?(0x40|(entry+1)):(entry+1)); + + // LFN flag + buffer[11] = 0x0F; + + // Checksum of short filename + buffer[13] = sfnChk; + + // Copy to buffer + for (i=0;iName[i] = shortfilename[i]; + + // Unless we have a RTC we might as well set these to 1980 + entry->CrtTimeTenth = 0x00; + entry->CrtTime[1] = entry->CrtTime[0] = 0x00; + entry->CrtDate[1] = 0x00; + entry->CrtDate[0] = 0x20; + entry->LstAccDate[1] = 0x00; + entry->LstAccDate[0] = 0x20; + entry->WrtTime[1] = entry->WrtTime[0] = 0x00; + entry->WrtDate[1] = 0x00; + entry->WrtDate[0] = 0x20; + + if (!dir) + entry->Attr = FILE_TYPE_FILE; + else + entry->Attr = FILE_TYPE_DIR; + + entry->NTRes = 0x00; + + entry->FstClusHI = FAT_HTONS((uint16)((startCluster>>16) & 0xFFFF)); + entry->FstClusLO = FAT_HTONS((uint16)((startCluster>>0) & 0xFFFF)); + entry->FileSize = FAT_HTONL(size); +} +#endif +//----------------------------------------------------------------------------- +// fatfs_lfn_create_sfn: Create a padded SFN +//----------------------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +int fatfs_lfn_create_sfn(char *sfn_output, char *filename) +{ + int i; + int dotPos = -1; + char ext[3]; + int pos; + int len = (int)strlen(filename); + + // Invalid to start with . + if (filename[0]=='.') + return 0; + + memset(sfn_output, ' ', FAT_SFN_SIZE_FULL); + memset(ext, ' ', 3); + + // Find dot seperator + for (i = 0; i< len; i++) + { + if (filename[i]=='.') + dotPos = i; + } + + // Extract extensions + if (dotPos!=-1) + { + // Copy first three chars of extension + for (i = (dotPos+1); i < (dotPos+1+3); i++) + if (i= 'a' && filename[i] <= 'z') + sfn_output[pos++] = filename[i] - 'a' + 'A'; + else + sfn_output[pos++] = filename[i]; + } + + // Fill upto 8 characters + if (pos==FAT_SFN_SIZE_PARTIAL) + break; + } + + // Add extension part + for (i=FAT_SFN_SIZE_PARTIAL;i= 'a' && ext[i-FAT_SFN_SIZE_PARTIAL] <= 'z') + sfn_output[i] = ext[i-FAT_SFN_SIZE_PARTIAL] - 'a' + 'A'; + else + sfn_output[i] = ext[i-FAT_SFN_SIZE_PARTIAL]; + } + + return 1; +} +//----------------------------------------------------------------------------- +// fatfs_itoa: +//----------------------------------------------------------------------------- +static void fatfs_itoa(uint32 num, char *s) +{ + char* cp; + char outbuf[12]; + const char digits[] = "0123456789ABCDEF"; + + // Build string backwards + cp = outbuf; + do + { + *cp++ = digits[(int)(num % 10)]; + } + while ((num /= 10) > 0); + + *cp-- = 0; + + // Copy in forwards + while (cp >= outbuf) + *s++ = *cp--; + + *s = 0; +} +#endif +//----------------------------------------------------------------------------- +// fatfs_lfn_generate_tail: +// sfn_input = Input short filename, spaced format & in upper case +// sfn_output = Output short filename with tail +//----------------------------------------------------------------------------- +#if FATFS_INC_LFN_SUPPORT +#if FATFS_INC_WRITE_SUPPORT +int fatfs_lfn_generate_tail(char *sfn_output, char *sfn_input, uint32 tailNum) +{ + int tail_chars; + char tail_str[12]; + + if (tailNum > 99999) + return 0; + + // Convert to number + memset(tail_str, 0x00, sizeof(tail_str)); + tail_str[0] = '~'; + fatfs_itoa(tailNum, tail_str+1); + + // Copy in base filename + memcpy(sfn_output, sfn_input, FAT_SFN_SIZE_FULL); + + // Overwrite with tail + tail_chars = (int)strlen(tail_str); + memcpy(sfn_output+(FAT_SFN_SIZE_PARTIAL-tail_chars), tail_str, tail_chars); + + return 1; +} +#endif +#endif +//----------------------------------------------------------------------------- +// fatfs_convert_from_fat_time: Convert FAT time to h/m/s +//----------------------------------------------------------------------------- +#if FATFS_INC_TIME_DATE_SUPPORT +void fatfs_convert_from_fat_time(uint16 fat_time, int *hours, int *minutes, int *seconds) +{ + *hours = (fat_time >> FAT_TIME_HOURS_SHIFT) & FAT_TIME_HOURS_MASK; + *minutes = (fat_time >> FAT_TIME_MINUTES_SHIFT) & FAT_TIME_MINUTES_MASK; + *seconds = (fat_time >> FAT_TIME_SECONDS_SHIFT) & FAT_TIME_SECONDS_MASK; + *seconds = *seconds * FAT_TIME_SECONDS_SCALE; +} +//----------------------------------------------------------------------------- +// fatfs_convert_from_fat_date: Convert FAT date to d/m/y +//----------------------------------------------------------------------------- +void fatfs_convert_from_fat_date(uint16 fat_date, int *day, int *month, int *year) +{ + *day = (fat_date >> FAT_DATE_DAY_SHIFT) & FAT_DATE_DAY_MASK; + *month = (fat_date >> FAT_DATE_MONTH_SHIFT) & FAT_DATE_MONTH_MASK; + *year = (fat_date >> FAT_DATE_YEAR_SHIFT) & FAT_DATE_YEAR_MASK; + *year = *year + FAT_DATE_YEAR_OFFSET; +} +//----------------------------------------------------------------------------- +// fatfs_convert_to_fat_time: Convert h/m/s to FAT time +//----------------------------------------------------------------------------- +uint16 fatfs_convert_to_fat_time(int hours, int minutes, int seconds) +{ + uint16 fat_time = 0; + + // Most FAT times are to a resolution of 2 seconds + seconds /= FAT_TIME_SECONDS_SCALE; + + fat_time = (hours & FAT_TIME_HOURS_MASK) << FAT_TIME_HOURS_SHIFT; + fat_time|= (minutes & FAT_TIME_MINUTES_MASK) << FAT_TIME_MINUTES_SHIFT; + fat_time|= (seconds & FAT_TIME_SECONDS_MASK) << FAT_TIME_SECONDS_SHIFT; + + return fat_time; +} +//----------------------------------------------------------------------------- +// fatfs_convert_to_fat_date: Convert d/m/y to FAT date +//----------------------------------------------------------------------------- +uint16 fatfs_convert_to_fat_date(int day, int month, int year) +{ + uint16 fat_date = 0; + + // FAT dates are relative to 1980 + if (year >= FAT_DATE_YEAR_OFFSET) + year -= FAT_DATE_YEAR_OFFSET; + + fat_date = (day & FAT_DATE_DAY_MASK) << FAT_DATE_DAY_SHIFT; + fat_date|= (month & FAT_DATE_MONTH_MASK) << FAT_DATE_MONTH_SHIFT; + fat_date|= (year & FAT_DATE_YEAR_MASK) << FAT_DATE_YEAR_SHIFT; + + return fat_date; +} +#endif +//----------------------------------------------------------------------------- +// fatfs_print_sector: +//----------------------------------------------------------------------------- +#ifdef FATFS_DEBUG +void fatfs_print_sector(uint32 sector, uint8 *data) +{ + int i; + int j; + + FAT_PRINTF(("Sector %d:\n", sector)); + + for (i=0;i 31 && ch < 127) + { + FAT_PRINTF(("%c", ch)); + } + else + { + FAT_PRINTF((".")); + } + } + + FAT_PRINTF(("\n")); + } + } +} +#endif diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_misc.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_misc.h new file mode 100644 index 0000000..0c02634 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_misc.h @@ -0,0 +1,63 @@ +#ifndef __FAT_MISC_H__ +#define __FAT_MISC_H__ + +#include "fat_defs.h" +#include "fat_opts.h" + +//----------------------------------------------------------------------------- +// Defines +//----------------------------------------------------------------------------- +#define MAX_LONGFILENAME_ENTRIES 20 +#define MAX_LFN_ENTRY_LENGTH 13 + +//----------------------------------------------------------------------------- +// Macros +//----------------------------------------------------------------------------- +#define GET_32BIT_WORD(buffer, location) ( ((uint32)buffer[location+3]<<24) + ((uint32)buffer[location+2]<<16) + ((uint32)buffer[location+1]<<8) + (uint32)buffer[location+0] ) +#define GET_16BIT_WORD(buffer, location) ( ((uint16)buffer[location+1]<<8) + (uint16)buffer[location+0] ) + +#define SET_32BIT_WORD(buffer, location, value) { buffer[location+0] = (uint8)((value)&0xFF); \ + buffer[location+1] = (uint8)((value>>8)&0xFF); \ + buffer[location+2] = (uint8)((value>>16)&0xFF); \ + buffer[location+3] = (uint8)((value>>24)&0xFF); } + +#define SET_16BIT_WORD(buffer, location, value) { buffer[location+0] = (uint8)((value)&0xFF); \ + buffer[location+1] = (uint8)((value>>8)&0xFF); } + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- +struct lfn_cache +{ +#if FATFS_INC_LFN_SUPPORT + // Long File Name Structure (max 260 LFN length) + uint8 String[MAX_LONGFILENAME_ENTRIES][MAX_LFN_ENTRY_LENGTH]; + uint8 Null; +#endif + uint8 no_of_strings; +}; + +//----------------------------------------------------------------------------- +// Prototypes +//----------------------------------------------------------------------------- +void fatfs_lfn_cache_init(struct lfn_cache *lfn, int wipeTable); +void fatfs_lfn_cache_entry(struct lfn_cache *lfn, uint8 *entryBuffer); +char* fatfs_lfn_cache_get(struct lfn_cache *lfn); +int fatfs_entry_lfn_text(struct fat_dir_entry *entry); +int fatfs_entry_lfn_invalid(struct fat_dir_entry *entry); +int fatfs_entry_lfn_exists(struct lfn_cache *lfn, struct fat_dir_entry *entry); +int fatfs_entry_sfn_only(struct fat_dir_entry *entry); +int fatfs_entry_is_dir(struct fat_dir_entry *entry); +int fatfs_entry_is_file(struct fat_dir_entry *entry); +int fatfs_lfn_entries_required(char *filename); +void fatfs_filename_to_lfn(char *filename, uint8 *buffer, int entry, uint8 sfnChk); +void fatfs_sfn_create_entry(char *shortfilename, uint32 size, uint32 startCluster, struct fat_dir_entry *entry, int dir); +int fatfs_lfn_create_sfn(char *sfn_output, char *filename); +int fatfs_lfn_generate_tail(char *sfn_output, char *sfn_input, uint32 tailNum); +void fatfs_convert_from_fat_time(uint16 fat_time, int *hours, int *minutes, int *seconds); +void fatfs_convert_from_fat_date(uint16 fat_date, int *day, int *month, int *year); +uint16 fatfs_convert_to_fat_time(int hours, int minutes, int seconds); +uint16 fatfs_convert_to_fat_date(int day, int month, int year); +void fatfs_print_sector(uint32 sector, uint8 *data); + +#endif diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_opts.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_opts.h new file mode 100644 index 0000000..6db158c --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_opts.h @@ -0,0 +1,83 @@ +#ifndef __FAT_OPTS_H__ +#define __FAT_OPTS_H__ + +#ifdef FATFS_USE_CUSTOM_OPTS_FILE + #include "fat_custom.h" +#endif + +//------------------------------------------------------------- +// Configuration +//------------------------------------------------------------- + +// Is the processor little endian (1) or big endian (0) +#ifndef FATFS_IS_LITTLE_ENDIAN + #define FATFS_IS_LITTLE_ENDIAN 1 +#endif + +// Max filename Length +#ifndef FATFS_MAX_LONG_FILENAME + #define FATFS_MAX_LONG_FILENAME 260 +#endif + +// Max open files (reduce to lower memory requirements) +#ifndef FATFS_MAX_OPEN_FILES + #define FATFS_MAX_OPEN_FILES 2 +#endif + +// Number of sectors per FAT_BUFFER (min 1) +#ifndef FAT_BUFFER_SECTORS + #define FAT_BUFFER_SECTORS 1 +#endif + +// Max FAT sectors to buffer (min 1) +// (mem used is FAT_BUFFERS * FAT_BUFFER_SECTORS * FAT_SECTOR_SIZE) +#ifndef FAT_BUFFERS + #define FAT_BUFFERS 1 +#endif + +// Size of cluster chain cache (can be undefined) +// Mem used = FAT_CLUSTER_CACHE_ENTRIES * 4 * 2 +// Improves access speed considerably +//#define FAT_CLUSTER_CACHE_ENTRIES 128 + +// Include support for writing files (1 / 0)? +#ifndef FATFS_INC_WRITE_SUPPORT + #define FATFS_INC_WRITE_SUPPORT 1 +#endif + +// Support long filenames (1 / 0)? +// (if not (0) only 8.3 format is supported) +#ifndef FATFS_INC_LFN_SUPPORT + #define FATFS_INC_LFN_SUPPORT 1 +#endif + +// Support directory listing (1 / 0)? +#ifndef FATFS_DIR_LIST_SUPPORT + #define FATFS_DIR_LIST_SUPPORT 1 +#endif + +// Support time/date (1 / 0)? +#ifndef FATFS_INC_TIME_DATE_SUPPORT + #define FATFS_INC_TIME_DATE_SUPPORT 0 +#endif + +// Include support for formatting disks (1 / 0)? +#ifndef FATFS_INC_FORMAT_SUPPORT + #define FATFS_INC_FORMAT_SUPPORT 0 +#endif + +// Sector size used +#define FAT_SECTOR_SIZE 512 + +// Printf output (directory listing / debug) +#ifndef FAT_PRINTF + void ventoy_syslog_printf(const char *Fmt, ...); + #define FAT_PRINTF(a) ventoy_syslog_printf a +#endif + +// Time/Date support requires time.h +#if FATFS_INC_TIME_DATE_SUPPORT + #include +#endif + +#endif diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_string.c b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_string.c new file mode 100644 index 0000000..f7206ce --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_string.c @@ -0,0 +1,514 @@ +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// FAT16/32 File IO Library +// V2.6 +// Ultra-Embedded.com +// Copyright 2003 - 2012 +// +// Email: admin@ultra-embedded.com +// +// License: GPL +// If you would like a version with a more permissive license for use in +// closed source commercial applications please contact me for details. +//----------------------------------------------------------------------------- +// +// This file is part of FAT File IO Library. +// +// FAT File IO Library 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. +// +// FAT File IO 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FAT File IO Library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +#include +#include +#include "fat_string.h" + +//----------------------------------------------------------------------------- +// fatfs_total_path_levels: Take a filename and path and count the sub levels +// of folders. E.g. C:\folder\file.zip = 1 level +// Acceptable input formats are: +// c:\folder\file.zip +// /dev/etc/samba.conf +// Returns: -1 = Error, 0 or more = Ok +//----------------------------------------------------------------------------- +int fatfs_total_path_levels(char *path) +{ + int levels = 0; + char expectedchar; + + if (!path) + return -1; + + // Acceptable formats: + // c:\folder\file.zip + // /dev/etc/samba.conf + if (*path == '/') + { + expectedchar = '/'; + path++; + } + else if (path[1] == ':' || path[2] == '\\') + { + expectedchar = '\\'; + path += 3; + } + else + return -1; + + // Count levels in path string + while (*path) + { + // Fast forward through actual subdir text to next slash + for (; *path; ) + { + // If slash detected escape from for loop + if (*path == expectedchar) { path++; break; } + path++; + } + + // Increase number of subdirs founds + levels++; + } + + // Subtract the file itself + return levels-1; +} +//----------------------------------------------------------------------------- +// fatfs_get_substring: Get a substring from 'path' which contains the folder +// (or file) at the specified level. +// E.g. C:\folder\file.zip : Level 0 = C:\folder, Level 1 = file.zip +// Returns: -1 = Error, 0 = Ok +//----------------------------------------------------------------------------- +int fatfs_get_substring(char *path, int levelreq, char *output, int max_len) +{ + int i; + int pathlen=0; + int levels=0; + int copypnt=0; + char expectedchar; + + if (!path || max_len <= 0) + return -1; + + // Acceptable formats: + // c:\folder\file.zip + // /dev/etc/samba.conf + if (*path == '/') + { + expectedchar = '/'; + path++; + } + else if (path[1] == ':' || path[2] == '\\') + { + expectedchar = '\\'; + path += 3; + } + else + return -1; + + // Get string length of path + pathlen = (int)strlen (path); + + // Loop through the number of times as characters in 'path' + for (i = 0; i path = C:\folder filename = file.zip +// E.g. C:\file.zip -> path = [blank] filename = file.zip +//----------------------------------------------------------------------------- +int fatfs_split_path(char *full_path, char *path, int max_path, char *filename, int max_filename) +{ + int strindex; + + // Count the levels to the filepath + int levels = fatfs_total_path_levels(full_path); + if (levels == -1) + return -1; + + // Get filename part of string + if (fatfs_get_substring(full_path, levels, filename, max_filename) != 0) + return -1; + + // If root file + if (levels == 0) + path[0] = '\0'; + else + { + strindex = (int)strlen(full_path) - (int)strlen(filename); + if (strindex > max_path) + strindex = max_path; + + memcpy(path, full_path, strindex); + path[strindex-1] = '\0'; + } + + return 0; +} +//----------------------------------------------------------------------------- +// FileString_StrCmpNoCase: Compare two strings case with case sensitivity +//----------------------------------------------------------------------------- +static int FileString_StrCmpNoCase(char *s1, char *s2, int n) +{ + int diff; + char a,b; + + while (n--) + { + a = *s1; + b = *s2; + + // Make lower case if uppercase + if ((a>='A') && (a<='Z')) + a+= 32; + if ((b>='A') && (b<='Z')) + b+= 32; + + diff = a - b; + + // If different + if (diff) + return diff; + + // If run out of strings + if ( (*s1 == 0) || (*s2 == 0) ) + break; + + s1++; + s2++; + } + return 0; +} +//----------------------------------------------------------------------------- +// FileString_GetExtension: Get index to extension within filename +// Returns -1 if not found or index otherwise +//----------------------------------------------------------------------------- +static int FileString_GetExtension(char *str) +{ + int dotPos = -1; + char *strSrc = str; + + // Find last '.' in string (if at all) + while (*strSrc) + { + if (*strSrc=='.') + dotPos = (int)(strSrc-str); + + strSrc++; + } + + return dotPos; +} +//----------------------------------------------------------------------------- +// FileString_TrimLength: Get length of string excluding trailing spaces +// Returns -1 if not found or index otherwise +//----------------------------------------------------------------------------- +static int FileString_TrimLength(char *str, int strLen) +{ + int length = strLen; + char *strSrc = str+strLen-1; + + // Find last non white space + while (strLen != 0) + { + if (*strSrc == ' ') + length = (int)(strSrc - str); + else + break; + + strSrc--; + strLen--; + } + + return length; +} +//----------------------------------------------------------------------------- +// fatfs_compare_names: Compare two filenames (without copying or changing origonals) +// Returns 1 if match, 0 if not +//----------------------------------------------------------------------------- +int fatfs_compare_names(char* strA, char* strB) +{ + char *ext1 = NULL; + char *ext2 = NULL; + int ext1Pos, ext2Pos; + int file1Len, file2Len; + + // Get both files extension + ext1Pos = FileString_GetExtension(strA); + ext2Pos = FileString_GetExtension(strB); + + // NOTE: Extension position can be different for matching + // filename if trailing space are present before it! + // Check that if one has an extension, so does the other + if ((ext1Pos==-1) && (ext2Pos!=-1)) + return 0; + if ((ext2Pos==-1) && (ext1Pos!=-1)) + return 0; + + // If they both have extensions, compare them + if (ext1Pos!=-1) + { + // Set pointer to start of extension + ext1 = strA+ext1Pos+1; + ext2 = strB+ext2Pos+1; + + // Verify that the file extension lengths match! + if (strlen(ext1) != strlen(ext2)) + return 0; + + // If they dont match + if (FileString_StrCmpNoCase(ext1, ext2, (int)strlen(ext1))!=0) + return 0; + + // Filelength is upto extensions + file1Len = ext1Pos; + file2Len = ext2Pos; + } + // No extensions + else + { + // Filelength is actual filelength + file1Len = (int)strlen(strA); + file2Len = (int)strlen(strB); + } + + // Find length without trailing spaces (before ext) + file1Len = FileString_TrimLength(strA, file1Len); + file2Len = FileString_TrimLength(strB, file2Len); + + // Check the file lengths match + if (file1Len!=file2Len) + return 0; + + // Compare main part of filenames + if (FileString_StrCmpNoCase(strA, strB, file1Len)!=0) + return 0; + else + return 1; +} +//----------------------------------------------------------------------------- +// fatfs_string_ends_with_slash: Does the string end with a slash (\ or /) +//----------------------------------------------------------------------------- +int fatfs_string_ends_with_slash(char *path) +{ + if (path) + { + while (*path) + { + // Last character? + if (!(*(path+1))) + { + if (*path == '\\' || *path == '/') + return 1; + } + + path++; + } + } + + return 0; +} +//----------------------------------------------------------------------------- +// fatfs_get_sfn_display_name: Get display name for SFN entry +//----------------------------------------------------------------------------- +int fatfs_get_sfn_display_name(char* out, char* in) +{ + int len = 0; + while (*in && len <= 11) + { + char a = *in++; + + if (a == ' ') + continue; + // Make lower case if uppercase + else if ((a>='A') && (a<='Z')) + a+= 32; + + *out++ = a; + len++; + } + + *out = '\0'; + return 1; +} +//----------------------------------------------------------------------------- +// fatfs_get_extension: Get extension of filename passed in 'filename'. +// Returned extension is always lower case. +// Returns: 1 if ok, 0 if not. +//----------------------------------------------------------------------------- +int fatfs_get_extension(char* filename, char* out, int maxlen) +{ + int len = 0; + + // Get files extension offset + int ext_pos = FileString_GetExtension(filename); + + if (ext_pos > 0 && out && maxlen) + { + filename += ext_pos + 1; + + while (*filename && len < (maxlen-1)) + { + char a = *filename++; + + // Make lowercase if uppercase + if ((a>='A') && (a<='Z')) + a+= 32; + + *out++ = a; + len++; + } + + *out = '\0'; + return 1; + } + + return 0; +} +//----------------------------------------------------------------------------- +// fatfs_create_path_string: Append path & filename to create file path string. +// Returns: 1 if ok, 0 if not. +//----------------------------------------------------------------------------- +int fatfs_create_path_string(char* path, char *filename, char* out, int maxlen) +{ + int len = 0; + char last = 0; + char seperator = '/'; + + if (path && filename && out && maxlen > 0) + { + while (*path && len < (maxlen-2)) + { + last = *path++; + if (last == '\\') + seperator = '\\'; + *out++ = last; + len++; + } + + // Add a seperator if trailing one not found + if (last != '\\' && last != '/') + *out++ = seperator; + + while (*filename && len < (maxlen-1)) + { + *out++ = *filename++; + len++; + } + + *out = '\0'; + + return 1; + } + + return 0; +} +//----------------------------------------------------------------------------- +// Test Bench +//----------------------------------------------------------------------------- +#ifdef FAT_STRING_TESTBENCH +void main(void) +{ + char output[255]; + char output2[255]; + + assert(fatfs_total_path_levels("C:\\folder\\file.zip") == 1); + assert(fatfs_total_path_levels("C:\\file.zip") == 0); + assert(fatfs_total_path_levels("C:\\folder\\folder2\\file.zip") == 2); + assert(fatfs_total_path_levels("C:\\") == -1); + assert(fatfs_total_path_levels("") == -1); + assert(fatfs_total_path_levels("/dev/etc/file.zip") == 2); + assert(fatfs_total_path_levels("/dev/file.zip") == 1); + + assert(fatfs_get_substring("C:\\folder\\file.zip", 0, output, sizeof(output)) == 0); + assert(strcmp(output, "folder") == 0); + + assert(fatfs_get_substring("C:\\folder\\file.zip", 1, output, sizeof(output)) == 0); + assert(strcmp(output, "file.zip") == 0); + + assert(fatfs_get_substring("/dev/etc/file.zip", 0, output, sizeof(output)) == 0); + assert(strcmp(output, "dev") == 0); + + assert(fatfs_get_substring("/dev/etc/file.zip", 1, output, sizeof(output)) == 0); + assert(strcmp(output, "etc") == 0); + + assert(fatfs_get_substring("/dev/etc/file.zip", 2, output, sizeof(output)) == 0); + assert(strcmp(output, "file.zip") == 0); + + assert(fatfs_split_path("C:\\folder\\file.zip", output, sizeof(output), output2, sizeof(output2)) == 0); + assert(strcmp(output, "C:\\folder") == 0); + assert(strcmp(output2, "file.zip") == 0); + + assert(fatfs_split_path("C:\\file.zip", output, sizeof(output), output2, sizeof(output2)) == 0); + assert(output[0] == 0); + assert(strcmp(output2, "file.zip") == 0); + + assert(fatfs_split_path("/dev/etc/file.zip", output, sizeof(output), output2, sizeof(output2)) == 0); + assert(strcmp(output, "/dev/etc") == 0); + assert(strcmp(output2, "file.zip") == 0); + + assert(FileString_GetExtension("C:\\file.zip") == strlen("C:\\file")); + assert(FileString_GetExtension("C:\\file.zip.ext") == strlen("C:\\file.zip")); + assert(FileString_GetExtension("C:\\file.zip.") == strlen("C:\\file.zip")); + + assert(FileString_TrimLength("C:\\file.zip", strlen("C:\\file.zip")) == strlen("C:\\file.zip")); + assert(FileString_TrimLength("C:\\file.zip ", strlen("C:\\file.zip ")) == strlen("C:\\file.zip")); + assert(FileString_TrimLength(" ", strlen(" ")) == 0); + + assert(fatfs_compare_names("C:\\file.ext", "C:\\file.ext") == 1); + assert(fatfs_compare_names("C:\\file2.ext", "C:\\file.ext") == 0); + assert(fatfs_compare_names("C:\\file .ext", "C:\\file.ext") == 1); + assert(fatfs_compare_names("C:\\file .ext", "C:\\file2.ext") == 0); + + assert(fatfs_string_ends_with_slash("C:\\folder") == 0); + assert(fatfs_string_ends_with_slash("C:\\folder\\") == 1); + assert(fatfs_string_ends_with_slash("/path") == 0); + assert(fatfs_string_ends_with_slash("/path/a") == 0); + assert(fatfs_string_ends_with_slash("/path/") == 1); + + assert(fatfs_get_extension("/mypath/file.wav", output, 4) == 1); + assert(strcmp(output, "wav") == 0); + assert(fatfs_get_extension("/mypath/file.WAV", output, 4) == 1); + assert(strcmp(output, "wav") == 0); + assert(fatfs_get_extension("/mypath/file.zip", output, 4) == 1); + assert(strcmp(output, "ext") != 0); + + assert(fatfs_create_path_string("/mydir1", "myfile.txt", output, sizeof(output)) == 1); + assert(strcmp(output, "/mydir1/myfile.txt") == 0); + assert(fatfs_create_path_string("/mydir2/", "myfile2.txt", output, sizeof(output)) == 1); + assert(strcmp(output, "/mydir2/myfile2.txt") == 0); + assert(fatfs_create_path_string("C:\\mydir3", "myfile3.txt", output, sizeof(output)) == 1); + assert(strcmp(output, "C:\\mydir3\\myfile3.txt") == 0); +} +#endif diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_string.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_string.h new file mode 100644 index 0000000..90ca8e0 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_string.h @@ -0,0 +1,20 @@ +#ifndef __FILESTRING_H__ +#define __FILESTRING_H__ + +//----------------------------------------------------------------------------- +// Prototypes +//----------------------------------------------------------------------------- +int fatfs_total_path_levels(char *path); +int fatfs_get_substring(char *Path, int levelreq, char *output, int max_len); +int fatfs_split_path(char *FullPath, char *Path, int max_path, char *FileName, int max_filename); +int fatfs_compare_names(char* strA, char* strB); +int fatfs_string_ends_with_slash(char *path); +int fatfs_get_sfn_display_name(char* out, char* in); +int fatfs_get_extension(char* filename, char* out, int maxlen); +int fatfs_create_path_string(char* path, char *filename, char* out, int maxlen); + +#ifndef NULL + #define NULL 0 +#endif + +#endif diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_table.c b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_table.c new file mode 100644 index 0000000..8d05d3b --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_table.c @@ -0,0 +1,478 @@ +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// FAT16/32 File IO Library +// V2.6 +// Ultra-Embedded.com +// Copyright 2003 - 2012 +// +// Email: admin@ultra-embedded.com +// +// License: GPL +// If you would like a version with a more permissive license for use in +// closed source commercial applications please contact me for details. +//----------------------------------------------------------------------------- +// +// This file is part of FAT File IO Library. +// +// FAT File IO Library 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. +// +// FAT File IO 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FAT File IO Library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +#include +#include "fat_defs.h" +#include "fat_access.h" +#include "fat_table.h" + +#ifndef FAT_BUFFERS + #define FAT_BUFFERS 1 +#endif + +#ifndef FAT_BUFFER_SECTORS + #define FAT_BUFFER_SECTORS 1 +#endif + +#if FAT_BUFFERS < 1 || FAT_BUFFER_SECTORS < 1 + #error "FAT_BUFFERS & FAT_BUFFER_SECTORS must be at least 1" +#endif + +//----------------------------------------------------------------------------- +// FAT Sector Buffer +//----------------------------------------------------------------------------- +#define FAT32_GET_32BIT_WORD(pbuf, location) ( GET_32BIT_WORD(pbuf->ptr, location) ) +#define FAT32_SET_32BIT_WORD(pbuf, location, value) { SET_32BIT_WORD(pbuf->ptr, location, value); pbuf->dirty = 1; } +#define FAT16_GET_16BIT_WORD(pbuf, location) ( GET_16BIT_WORD(pbuf->ptr, location) ) +#define FAT16_SET_16BIT_WORD(pbuf, location, value) { SET_16BIT_WORD(pbuf->ptr, location, value); pbuf->dirty = 1; } + +//----------------------------------------------------------------------------- +// fatfs_fat_init: +//----------------------------------------------------------------------------- +void fatfs_fat_init(struct fatfs *fs) +{ + int i; + + // FAT buffer chain head + fs->fat_buffer_head = NULL; + + for (i=0;ifat_buffers[i].address = FAT32_INVALID_CLUSTER; + fs->fat_buffers[i].dirty = 0; + memset(fs->fat_buffers[i].sector, 0x00, sizeof(fs->fat_buffers[i].sector)); + fs->fat_buffers[i].ptr = NULL; + + // Add to head of queue + fs->fat_buffers[i].next = fs->fat_buffer_head; + fs->fat_buffer_head = &fs->fat_buffers[i]; + } +} +//----------------------------------------------------------------------------- +// fatfs_fat_writeback: Writeback 'dirty' FAT sectors to disk +//----------------------------------------------------------------------------- +static int fatfs_fat_writeback(struct fatfs *fs, struct fat_buffer *pcur) +{ + if (pcur) + { + // Writeback sector if changed + if (pcur->dirty) + { + if (fs->disk_io.write_media) + { + uint32 sectors = FAT_BUFFER_SECTORS; + uint32 offset = pcur->address - fs->fat_begin_lba; + + // Limit to sectors used for the FAT + if ((offset + FAT_BUFFER_SECTORS) <= fs->fat_sectors) + sectors = FAT_BUFFER_SECTORS; + else + sectors = fs->fat_sectors - offset; + + if (!fs->disk_io.write_media(pcur->address, pcur->sector, sectors)) + return 0; + } + + pcur->dirty = 0; + } + + return 1; + } + else + return 0; +} +//----------------------------------------------------------------------------- +// fatfs_fat_read_sector: Read a FAT sector +//----------------------------------------------------------------------------- +static struct fat_buffer *fatfs_fat_read_sector(struct fatfs *fs, uint32 sector) +{ + struct fat_buffer *last = NULL; + struct fat_buffer *pcur = fs->fat_buffer_head; + + // Itterate through sector buffer list + while (pcur) + { + // Sector within this buffer? + if ((sector >= pcur->address) && (sector < (pcur->address + FAT_BUFFER_SECTORS))) + break; + + // End of list? + if (pcur->next == NULL) + { + // Remove buffer from list + if (last) + last->next = NULL; + // We the first and last buffer in the chain? + else + fs->fat_buffer_head = NULL; + } + + last = pcur; + pcur = pcur->next; + } + + // We found the sector already in FAT buffer chain + if (pcur) + { + pcur->ptr = (uint8 *)(pcur->sector + ((sector - pcur->address) * FAT_SECTOR_SIZE)); + return pcur; + } + + // Else, we removed the last item from the list + pcur = last; + + // Add to start of sector buffer list (now newest sector) + pcur->next = fs->fat_buffer_head; + fs->fat_buffer_head = pcur; + + // Writeback sector if changed + if (pcur->dirty) + if (!fatfs_fat_writeback(fs, pcur)) + return 0; + + // Address is now new sector + pcur->address = sector; + + // Read next sector + if (!fs->disk_io.read_media(pcur->address, pcur->sector, FAT_BUFFER_SECTORS)) + { + // Read failed, invalidate buffer address + pcur->address = FAT32_INVALID_CLUSTER; + return NULL; + } + + pcur->ptr = pcur->sector; + return pcur; +} +//----------------------------------------------------------------------------- +// fatfs_fat_purge: Purge 'dirty' FAT sectors to disk +//----------------------------------------------------------------------------- +int fatfs_fat_purge(struct fatfs *fs) +{ + struct fat_buffer *pcur = fs->fat_buffer_head; + + // Itterate through sector buffer list + while (pcur) + { + // Writeback sector if changed + if (pcur->dirty) + if (!fatfs_fat_writeback(fs, pcur)) + return 0; + + pcur = pcur->next; + } + + return 1; +} + +//----------------------------------------------------------------------------- +// General FAT Table Operations +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// fatfs_find_next_cluster: Return cluster number of next cluster in chain by +// reading FAT table and traversing it. Return 0xffffffff for end of chain. +//----------------------------------------------------------------------------- +uint32 fatfs_find_next_cluster(struct fatfs *fs, uint32 current_cluster) +{ + uint32 fat_sector_offset, position; + uint32 nextcluster; + struct fat_buffer *pbuf; + + // Why is '..' labelled with cluster 0 when it should be 2 ?? + if (current_cluster == 0) + current_cluster = 2; + + // Find which sector of FAT table to read + if (fs->fat_type == FAT_TYPE_16) + fat_sector_offset = current_cluster / 256; + else + fat_sector_offset = current_cluster / 128; + + // Read FAT sector into buffer + pbuf = fatfs_fat_read_sector(fs, fs->fat_begin_lba+fat_sector_offset); + if (!pbuf) + return (FAT32_LAST_CLUSTER); + + if (fs->fat_type == FAT_TYPE_16) + { + // Find 32 bit entry of current sector relating to cluster number + position = (current_cluster - (fat_sector_offset * 256)) * 2; + + // Read Next Clusters value from Sector Buffer + nextcluster = FAT16_GET_16BIT_WORD(pbuf, (uint16)position); + + // If end of chain found + if (nextcluster >= 0xFFF8 && nextcluster <= 0xFFFF) + return (FAT32_LAST_CLUSTER); + } + else + { + // Find 32 bit entry of current sector relating to cluster number + position = (current_cluster - (fat_sector_offset * 128)) * 4; + + // Read Next Clusters value from Sector Buffer + nextcluster = FAT32_GET_32BIT_WORD(pbuf, (uint16)position); + + // Mask out MS 4 bits (its 28bit addressing) + nextcluster = nextcluster & 0x0FFFFFFF; + + // If end of chain found + if (nextcluster >= 0x0FFFFFF8 && nextcluster <= 0x0FFFFFFF) + return (FAT32_LAST_CLUSTER); + } + + // Else return next cluster + return (nextcluster); +} +//----------------------------------------------------------------------------- +// fatfs_set_fs_info_next_free_cluster: Write the next free cluster to the FSINFO table +//----------------------------------------------------------------------------- +void fatfs_set_fs_info_next_free_cluster(struct fatfs *fs, uint32 newValue) +{ + if (fs->fat_type == FAT_TYPE_16) + ; + else + { + // Load sector to change it + struct fat_buffer *pbuf = fatfs_fat_read_sector(fs, fs->lba_begin+fs->fs_info_sector); + if (!pbuf) + return ; + + // Change + FAT32_SET_32BIT_WORD(pbuf, 492, newValue); + fs->next_free_cluster = newValue; + + // Write back FSINFO sector to disk + if (fs->disk_io.write_media) + fs->disk_io.write_media(pbuf->address, pbuf->sector, 1); + + // Invalidate cache entry + pbuf->address = FAT32_INVALID_CLUSTER; + pbuf->dirty = 0; + } +} +//----------------------------------------------------------------------------- +// fatfs_find_blank_cluster: Find a free cluster entry by reading the FAT +//----------------------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +int fatfs_find_blank_cluster(struct fatfs *fs, uint32 start_cluster, uint32 *free_cluster) +{ + uint32 fat_sector_offset, position; + uint32 nextcluster; + uint32 current_cluster = start_cluster; + struct fat_buffer *pbuf; + + do + { + // Find which sector of FAT table to read + if (fs->fat_type == FAT_TYPE_16) + fat_sector_offset = current_cluster / 256; + else + fat_sector_offset = current_cluster / 128; + + if ( fat_sector_offset < fs->fat_sectors) + { + // Read FAT sector into buffer + pbuf = fatfs_fat_read_sector(fs, fs->fat_begin_lba+fat_sector_offset); + if (!pbuf) + return 0; + + if (fs->fat_type == FAT_TYPE_16) + { + // Find 32 bit entry of current sector relating to cluster number + position = (current_cluster - (fat_sector_offset * 256)) * 2; + + // Read Next Clusters value from Sector Buffer + nextcluster = FAT16_GET_16BIT_WORD(pbuf, (uint16)position); + } + else + { + // Find 32 bit entry of current sector relating to cluster number + position = (current_cluster - (fat_sector_offset * 128)) * 4; + + // Read Next Clusters value from Sector Buffer + nextcluster = FAT32_GET_32BIT_WORD(pbuf, (uint16)position); + + // Mask out MS 4 bits (its 28bit addressing) + nextcluster = nextcluster & 0x0FFFFFFF; + } + + if (nextcluster !=0 ) + current_cluster++; + } + else + // Otherwise, run out of FAT sectors to check... + return 0; + } + while (nextcluster != 0x0); + + // Found blank entry + *free_cluster = current_cluster; + return 1; +} +#endif +//----------------------------------------------------------------------------- +// fatfs_fat_set_cluster: Set a cluster link in the chain. NOTE: Immediate +// write (slow). +//----------------------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +int fatfs_fat_set_cluster(struct fatfs *fs, uint32 cluster, uint32 next_cluster) +{ + struct fat_buffer *pbuf; + uint32 fat_sector_offset, position; + + // Find which sector of FAT table to read + if (fs->fat_type == FAT_TYPE_16) + fat_sector_offset = cluster / 256; + else + fat_sector_offset = cluster / 128; + + // Read FAT sector into buffer + pbuf = fatfs_fat_read_sector(fs, fs->fat_begin_lba+fat_sector_offset); + if (!pbuf) + return 0; + + if (fs->fat_type == FAT_TYPE_16) + { + // Find 16 bit entry of current sector relating to cluster number + position = (cluster - (fat_sector_offset * 256)) * 2; + + // Write Next Clusters value to Sector Buffer + FAT16_SET_16BIT_WORD(pbuf, (uint16)position, ((uint16)next_cluster)); + } + else + { + // Find 32 bit entry of current sector relating to cluster number + position = (cluster - (fat_sector_offset * 128)) * 4; + + // Write Next Clusters value to Sector Buffer + FAT32_SET_32BIT_WORD(pbuf, (uint16)position, next_cluster); + } + + return 1; +} +#endif +//----------------------------------------------------------------------------- +// fatfs_free_cluster_chain: Follow a chain marking each element as free +//----------------------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +int fatfs_free_cluster_chain(struct fatfs *fs, uint32 start_cluster) +{ + uint32 last_cluster; + uint32 next_cluster = start_cluster; + + // Loop until end of chain + while ( (next_cluster != FAT32_LAST_CLUSTER) && (next_cluster != 0x00000000) ) + { + last_cluster = next_cluster; + + // Find next link + next_cluster = fatfs_find_next_cluster(fs, next_cluster); + + // Clear last link + fatfs_fat_set_cluster(fs, last_cluster, 0x00000000); + } + + return 1; +} +#endif +//----------------------------------------------------------------------------- +// fatfs_fat_add_cluster_to_chain: Follow a chain marking and then add a new entry +// to the current tail. +//----------------------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +int fatfs_fat_add_cluster_to_chain(struct fatfs *fs, uint32 start_cluster, uint32 newEntry) +{ + uint32 last_cluster = FAT32_LAST_CLUSTER; + uint32 next_cluster = start_cluster; + + if (start_cluster == FAT32_LAST_CLUSTER) + return 0; + + // Loop until end of chain + while ( next_cluster != FAT32_LAST_CLUSTER ) + { + last_cluster = next_cluster; + + // Find next link + next_cluster = fatfs_find_next_cluster(fs, next_cluster); + if (!next_cluster) + return 0; + } + + // Add link in for new cluster + fatfs_fat_set_cluster(fs, last_cluster, newEntry); + + // Mark new cluster as end of chain + fatfs_fat_set_cluster(fs, newEntry, FAT32_LAST_CLUSTER); + + return 1; +} +#endif +//----------------------------------------------------------------------------- +// fatfs_count_free_clusters: +//----------------------------------------------------------------------------- +uint32 fatfs_count_free_clusters(struct fatfs *fs) +{ + uint32 i,j; + uint32 count = 0; + struct fat_buffer *pbuf; + + for (i = 0; i < fs->fat_sectors; i++) + { + // Read FAT sector into buffer + pbuf = fatfs_fat_read_sector(fs, fs->fat_begin_lba + i); + if (!pbuf) + break; + + for (j = 0; j < FAT_SECTOR_SIZE; ) + { + if (fs->fat_type == FAT_TYPE_16) + { + if (FAT16_GET_16BIT_WORD(pbuf, (uint16)j) == 0) + count++; + + j += 2; + } + else + { + if (FAT32_GET_32BIT_WORD(pbuf, (uint16)j) == 0) + count++; + + j += 4; + } + } + } + + return count; +} diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_table.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_table.h new file mode 100644 index 0000000..ead75f3 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_table.h @@ -0,0 +1,20 @@ +#ifndef __FAT_TABLE_H__ +#define __FAT_TABLE_H__ + +#include "fat_opts.h" +#include "fat_misc.h" + +//----------------------------------------------------------------------------- +// Prototypes +//----------------------------------------------------------------------------- +void fatfs_fat_init(struct fatfs *fs); +int fatfs_fat_purge(struct fatfs *fs); +uint32 fatfs_find_next_cluster(struct fatfs *fs, uint32 current_cluster); +void fatfs_set_fs_info_next_free_cluster(struct fatfs *fs, uint32 newValue); +int fatfs_find_blank_cluster(struct fatfs *fs, uint32 start_cluster, uint32 *free_cluster); +int fatfs_fat_set_cluster(struct fatfs *fs, uint32 cluster, uint32 next_cluster); +int fatfs_fat_add_cluster_to_chain(struct fatfs *fs, uint32 start_cluster, uint32 newEntry); +int fatfs_free_cluster_chain(struct fatfs *fs, uint32 start_cluster); +uint32 fatfs_count_free_clusters(struct fatfs *fs); + +#endif diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_types.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_types.h new file mode 100644 index 0000000..5e2cca8 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_types.h @@ -0,0 +1,69 @@ +#ifndef __FAT_TYPES_H__ +#define __FAT_TYPES_H__ + +// Detect 64-bit compilation on GCC +#if defined(__GNUC__) && defined(__SIZEOF_LONG__) + #if __SIZEOF_LONG__ == 8 + #define FATFS_DEF_UINT32_AS_INT + #endif +#endif + +//------------------------------------------------------------- +// System specific types +//------------------------------------------------------------- +#ifndef FATFS_NO_DEF_TYPES + typedef unsigned char uint8; + typedef unsigned short uint16; + + // If compiling on a 64-bit machine, use int as 32-bits + #ifdef FATFS_DEF_UINT32_AS_INT + typedef unsigned int uint32; + // Else for 32-bit machines & embedded systems, use long... + #else + typedef unsigned long uint32; + #endif +#endif + +#ifndef NULL + #define NULL 0 +#endif + +//------------------------------------------------------------- +// Endian Macros +//------------------------------------------------------------- +// FAT is little endian so big endian systems need to swap words + +// Little Endian - No swap required +#if FATFS_IS_LITTLE_ENDIAN == 1 + + #define FAT_HTONS(n) (n) + #define FAT_HTONL(n) (n) + +// Big Endian - Swap required +#else + + #define FAT_HTONS(n) ((((uint16)((n) & 0xff)) << 8) | (((n) & 0xff00) >> 8)) + #define FAT_HTONL(n) (((((uint32)(n) & 0xFF)) << 24) | \ + ((((uint32)(n) & 0xFF00)) << 8) | \ + ((((uint32)(n) & 0xFF0000)) >> 8) | \ + ((((uint32)(n) & 0xFF000000)) >> 24)) + +#endif + +//------------------------------------------------------------- +// Structure Packing Compile Options +//------------------------------------------------------------- +#ifdef __GNUC__ + #define STRUCT_PACK + #define STRUCT_PACK_BEGIN + #define STRUCT_PACK_END + #define STRUCT_PACKED __attribute__ ((packed)) +#else + // Other compilers may require other methods of packing structures + #define STRUCT_PACK + #define STRUCT_PACK_BEGIN + #define STRUCT_PACK_END + #define STRUCT_PACKED +#endif + +#endif diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_write.c b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_write.c new file mode 100644 index 0000000..0718cb1 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_write.c @@ -0,0 +1,373 @@ +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// FAT16/32 File IO Library +// V2.6 +// Ultra-Embedded.com +// Copyright 2003 - 2012 +// +// Email: admin@ultra-embedded.com +// +// License: GPL +// If you would like a version with a more permissive license for use in +// closed source commercial applications please contact me for details. +//----------------------------------------------------------------------------- +// +// This file is part of FAT File IO Library. +// +// FAT File IO Library 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. +// +// FAT File IO 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FAT File IO Library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +#include +#include "fat_defs.h" +#include "fat_access.h" +#include "fat_table.h" +#include "fat_write.h" +#include "fat_string.h" +#include "fat_misc.h" + +#if FATFS_INC_WRITE_SUPPORT +//----------------------------------------------------------------------------- +// fatfs_add_free_space: Allocate another cluster of free space to the end +// of a files cluster chain. +//----------------------------------------------------------------------------- +int fatfs_add_free_space(struct fatfs *fs, uint32 *startCluster, uint32 clusters) +{ + uint32 i; + uint32 nextcluster; + uint32 start = *startCluster; + + // Set the next free cluster hint to unknown + if (fs->next_free_cluster != FAT32_LAST_CLUSTER) + fatfs_set_fs_info_next_free_cluster(fs, FAT32_LAST_CLUSTER); + + for (i=0;irootdir_first_cluster, &nextcluster)) + { + // Point last to this + fatfs_fat_set_cluster(fs, start, nextcluster); + + // Point this to end of file + fatfs_fat_set_cluster(fs, nextcluster, FAT32_LAST_CLUSTER); + + // Adjust argument reference + start = nextcluster; + if (i == 0) + *startCluster = nextcluster; + } + else + return 0; + } + + return 1; +} +//----------------------------------------------------------------------------- +// fatfs_allocate_free_space: Add an ammount of free space to a file either from +// 'startCluster' if newFile = false, or allocating a new start to the chain if +// newFile = true. +//----------------------------------------------------------------------------- +int fatfs_allocate_free_space(struct fatfs *fs, int newFile, uint32 *startCluster, uint32 size) +{ + uint32 clusterSize; + uint32 clusterCount; + uint32 nextcluster; + + if (size==0) + return 0; + + // Set the next free cluster hint to unknown + if (fs->next_free_cluster != FAT32_LAST_CLUSTER) + fatfs_set_fs_info_next_free_cluster(fs, FAT32_LAST_CLUSTER); + + // Work out size and clusters + clusterSize = fs->sectors_per_cluster * FAT_SECTOR_SIZE; + clusterCount = (size / clusterSize); + + // If any left over + if (size-(clusterSize*clusterCount)) + clusterCount++; + + // Allocated first link in the chain if a new file + if (newFile) + { + if (!fatfs_find_blank_cluster(fs, fs->rootdir_first_cluster, &nextcluster)) + return 0; + + // If this is all that is needed then all done + if (clusterCount==1) + { + fatfs_fat_set_cluster(fs, nextcluster, FAT32_LAST_CLUSTER); + *startCluster = nextcluster; + return 1; + } + } + // Allocate from end of current chain (startCluster is end of chain) + else + nextcluster = *startCluster; + + if (!fatfs_add_free_space(fs, &nextcluster, clusterCount)) + return 0; + + return 1; +} +//----------------------------------------------------------------------------- +// fatfs_find_free_dir_offset: Find a free space in the directory for a new entry +// which takes up 'entryCount' blocks (or allocate some more) +//----------------------------------------------------------------------------- +static int fatfs_find_free_dir_offset(struct fatfs *fs, uint32 dirCluster, int entryCount, uint32 *pSector, uint8 *pOffset) +{ + struct fat_dir_entry *directoryEntry; + uint8 item=0; + uint16 recordoffset = 0; + uint8 i=0; + int x=0; + int possible_spaces = 0; + int start_recorded = 0; + + // No entries required? + if (entryCount == 0) + return 0; + + // Main cluster following loop + while (1) + { + // Read sector + if (fatfs_sector_reader(fs, dirCluster, x++, 0)) + { + // Analyse Sector + for (item = 0; item < FAT_DIR_ENTRIES_PER_SECTOR; item++) + { + // Create the multiplier for sector access + recordoffset = FAT_DIR_ENTRY_SIZE * item; + + // Overlay directory entry over buffer + directoryEntry = (struct fat_dir_entry*)(fs->currentsector.sector+recordoffset); + + // LFN Entry + if (fatfs_entry_lfn_text(directoryEntry)) + { + // First entry? + if (possible_spaces == 0) + { + // Store start + *pSector = x-1; + *pOffset = item; + start_recorded = 1; + } + + // Increment the count in-case the file turns + // out to be deleted... + possible_spaces++; + } + // SFN Entry + else + { + // Has file been deleted? + if (fs->currentsector.sector[recordoffset] == FILE_HEADER_DELETED) + { + // First entry? + if (possible_spaces == 0) + { + // Store start + *pSector = x-1; + *pOffset = item; + start_recorded = 1; + } + + possible_spaces++; + + // We have found enough space? + if (possible_spaces >= entryCount) + return 1; + + // Else continue counting until we find a valid entry! + } + // Is the file entry empty? + else if (fs->currentsector.sector[recordoffset] == FILE_HEADER_BLANK) + { + // First entry? + if (possible_spaces == 0) + { + // Store start + *pSector = x-1; + *pOffset = item; + start_recorded = 1; + } + + // Increment the blank entries count + possible_spaces++; + + // We have found enough space? + if (possible_spaces >= entryCount) + return 1; + } + // File entry is valid + else + { + // Reset all flags + possible_spaces = 0; + start_recorded = 0; + } + } + } // End of for + } // End of if + // Run out of free space in the directory, allocate some more + else + { + uint32 newCluster; + + // Get a new cluster for directory + if (!fatfs_find_blank_cluster(fs, fs->rootdir_first_cluster, &newCluster)) + return 0; + + // Add cluster to end of directory tree + if (!fatfs_fat_add_cluster_to_chain(fs, dirCluster, newCluster)) + return 0; + + // Erase new directory cluster + memset(fs->currentsector.sector, 0x00, FAT_SECTOR_SIZE); + for (i=0;isectors_per_cluster;i++) + { + if (!fatfs_write_sector(fs, newCluster, i, 0)) + return 0; + } + + // If non of the name fitted on previous sectors + if (!start_recorded) + { + // Store start + *pSector = (x-1); + *pOffset = 0; + start_recorded = 1; + } + + return 1; + } + } // End of while loop + + return 0; +} +//----------------------------------------------------------------------------- +// fatfs_add_file_entry: Add a directory entry to a location found by FindFreeOffset +//----------------------------------------------------------------------------- +int fatfs_add_file_entry(struct fatfs *fs, uint32 dirCluster, char *filename, char *shortfilename, uint32 startCluster, uint32 size, int dir) +{ + uint8 item=0; + uint16 recordoffset = 0; + uint8 i=0; + uint32 x=0; + int entryCount; + struct fat_dir_entry shortEntry; + int dirtySector = 0; + + uint32 dirSector = 0; + uint8 dirOffset = 0; + int foundEnd = 0; + + uint8 checksum; + uint8 *pSname; + + // No write access? + if (!fs->disk_io.write_media) + return 0; + +#if FATFS_INC_LFN_SUPPORT + // How many LFN entries are required? + // NOTE: We always request one LFN even if it would fit in a SFN! + entryCount = fatfs_lfn_entries_required(filename); + if (!entryCount) + return 0; +#else + entryCount = 0; +#endif + + // Find space in the directory for this filename (or allocate some more) + // NOTE: We need to find space for at least the LFN + SFN (or just the SFN if LFNs not supported). + if (!fatfs_find_free_dir_offset(fs, dirCluster, entryCount + 1, &dirSector, &dirOffset)) + return 0; + + // Generate checksum of short filename + pSname = (uint8*)shortfilename; + checksum = 0; + for (i=11; i!=0; i--) checksum = ((checksum & 1) ? 0x80 : 0) + (checksum >> 1) + *pSname++; + + // Start from current sector where space was found! + x = dirSector; + + // Main cluster following loop + while (1) + { + // Read sector + if (fatfs_sector_reader(fs, dirCluster, x++, 0)) + { + // Analyse Sector + for (item = 0; item < FAT_DIR_ENTRIES_PER_SECTOR; item++) + { + // Create the multiplier for sector access + recordoffset = FAT_DIR_ENTRY_SIZE * item; + + // If the start position for the entry has been found + if (foundEnd==0) + if ( (dirSector==(x-1)) && (dirOffset==item) ) + foundEnd = 1; + + // Start adding filename + if (foundEnd) + { + if (entryCount==0) + { + // Short filename + fatfs_sfn_create_entry(shortfilename, size, startCluster, &shortEntry, dir); + +#if FATFS_INC_TIME_DATE_SUPPORT + // Update create, access & modify time & date + fatfs_update_timestamps(&shortEntry, 1, 1, 1); +#endif + + memcpy(&fs->currentsector.sector[recordoffset], &shortEntry, sizeof(shortEntry)); + + // Writeback + return fs->disk_io.write_media(fs->currentsector.address, fs->currentsector.sector, 1); + } +#if FATFS_INC_LFN_SUPPORT + else + { + entryCount--; + + // Copy entry to directory buffer + fatfs_filename_to_lfn(filename, &fs->currentsector.sector[recordoffset], entryCount, checksum); + dirtySector = 1; + } +#endif + } + } // End of if + + // Write back to disk before loading another sector + if (dirtySector) + { + if (!fs->disk_io.write_media(fs->currentsector.address, fs->currentsector.sector, 1)) + return 0; + + dirtySector = 0; + } + } + else + return 0; + } // End of while loop + + return 0; +} +#endif diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_write.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_write.h new file mode 100644 index 0000000..5558a86 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_write.h @@ -0,0 +1,14 @@ +#ifndef __FAT_WRITE_H__ +#define __FAT_WRITE_H__ + +#include "fat_defs.h" +#include "fat_opts.h" + +//----------------------------------------------------------------------------- +// Prototypes +//----------------------------------------------------------------------------- +int fatfs_add_file_entry(struct fatfs *fs, uint32 dirCluster, char *filename, char *shortfilename, uint32 startCluster, uint32 size, int dir); +int fatfs_add_free_space(struct fatfs *fs, uint32 *startCluster, uint32 clusters); +int fatfs_allocate_free_space(struct fatfs *fs, int newFile, uint32 *startCluster, uint32 size); + +#endif diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/version.txt b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/version.txt new file mode 100644 index 0000000..5a00a98 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/version.txt @@ -0,0 +1 @@ +2.6.11 diff --git a/LinuxGUI/Ventoy2Disk/Lib/libhttp/buildlib.sh b/LinuxGUI/Ventoy2Disk/Lib/libhttp/buildlib.sh new file mode 100644 index 0000000..07c542f --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/libhttp/buildlib.sh @@ -0,0 +1,46 @@ +#!/bin/sh + +# https://github.com/lammertb/libhttp/archive/v1.8.tar.gz + + +# rm -rf include +# rm -rf lib +# mkdir include +# mkdir lib + +# rm -rf libhttp-1.8 +# tar xf libhttp-1.8.tar.gz +# cd libhttp-1.8 +# cp -a include/civetweb.h ../include/ + + +# cd .. +# rm -rf libhttp-1.8 +# tar xf libhttp-1.8.tar.gz +# cd libhttp-1.8 +# make lib COPT="-DNDEBUG -DNO_CGI -DNO_CACHING -DNO_SSL -DSQLITE_DISABLE_LFS -DSSL_ALREADY_INITIALIZED" +# cp -a libcivetweb.a ../lib/libcivetweb_64.a + + + +# cd .. +# rm -rf libhttp-1.8 +# tar xf libhttp-1.8.tar.gz +# cd libhttp-1.8 +# make lib COPT="-m32 -DNDEBUG -DNO_CGI -DNO_CACHING -DNO_SSL -DSQLITE_DISABLE_LFS -DSSL_ALREADY_INITIALIZED" +# cp -a libcivetweb.a ../lib/libcivetweb_32.a + + + +# cd .. +# rm -rf libhttp-1.8 +# tar xf libhttp-1.8.tar.gz +# cd libhttp-1.8 +# make lib CC=aarch64-linux-gnu-gcc COPT="-DNDEBUG -DNO_CGI -DNO_CACHING -DNO_SSL -DSQLITE_DISABLE_LFS -DSSL_ALREADY_INITIALIZED" +# cp -a libcivetweb.a ../lib/libcivetweb_aa64.a + + +# cd .. +# rm -rf libhttp-1.8 + + diff --git a/LinuxGUI/Ventoy2Disk/Lib/libhttp/include/civetweb.c b/LinuxGUI/Ventoy2Disk/Lib/libhttp/include/civetweb.c new file mode 100644 index 0000000..98130f5 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/libhttp/include/civetweb.c @@ -0,0 +1,13145 @@ +/* Copyright (c) 2013-2016 the Civetweb developers + * Copyright (c) 2004-2013 Sergey Lyubka + * + * 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. + */ + + +#if defined(_WIN32) +#if !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS /* Disable deprecation warning in VS2005 */ +#endif +#ifndef _WIN32_WINNT /* defined for tdm-gcc so we can use getnameinfo */ +#define _WIN32_WINNT 0x0501 +#endif +#else +#if defined(__GNUC__) && !defined(_GNU_SOURCE) +#define _GNU_SOURCE /* for setgroups() */ +#endif +#if defined(__linux__) && !defined(_XOPEN_SOURCE) +#define _XOPEN_SOURCE 600 /* For flockfile() on Linux */ +#endif +#ifndef _LARGEFILE_SOURCE +#define _LARGEFILE_SOURCE /* For fseeko(), ftello() */ +#endif +#ifndef _FILE_OFFSET_BITS +#define _FILE_OFFSET_BITS 64 /* Use 64-bit file offsets by default */ +#endif +#ifndef __STDC_FORMAT_MACROS +#define __STDC_FORMAT_MACROS /* wants this for C++ */ +#endif +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS /* C++ wants that for INT64_MAX */ +#endif +#ifdef __sun +#define __EXTENSIONS__ /* to expose flockfile and friends in stdio.h */ +#define __inline inline /* not recognized on older compiler versions */ +#endif +#endif + +#if defined(USE_LUA) && defined(USE_WEBSOCKET) +#define USE_TIMERS +#endif + +#if defined(_MSC_VER) +/* 'type cast' : conversion from 'int' to 'HANDLE' of greater size */ +#pragma warning(disable : 4306) +/* conditional expression is constant: introduced by FD_SET(..) */ +#pragma warning(disable : 4127) +/* non-constant aggregate initializer: issued due to missing C99 support */ +#pragma warning(disable : 4204) +/* padding added after data member */ +#pragma warning(disable : 4820) +/* not defined as a preprocessor macro, replacing with '0' for '#if/#elif' */ +#pragma warning(disable : 4668) +/* no function prototype given: converting '()' to '(void)' */ +#pragma warning(disable : 4255) +/* function has been selected for automatic inline expansion */ +#pragma warning(disable : 4711) +#endif + + +/* This code uses static_assert to check some conditions. + * Unfortunately some compilers still do not support it, so we have a + * replacement function here. */ +#if defined(_MSC_VER) && (_MSC_VER >= 1600) +#define mg_static_assert static_assert +#elif defined(__cplusplus) && (__cplusplus >= 201103L) +#define mg_static_assert static_assert +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) +#define mg_static_assert _Static_assert +#else +char static_assert_replacement[1]; +#define mg_static_assert(cond, txt) \ + extern char static_assert_replacement[(cond) ? 1 : -1] +#endif + +mg_static_assert(sizeof(int) == 4 || sizeof(int) == 8, + "int data type size check"); +mg_static_assert(sizeof(void *) == 4 || sizeof(void *) == 8, + "pointer data type size check"); +mg_static_assert(sizeof(void *) >= sizeof(int), "data type size check"); +/* mg_static_assert(sizeof(size_t) == 4 || sizeof(size_t) == 8, "size_t data + * type size check"); */ + +/* DTL -- including winsock2.h works better if lean and mean */ +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif + +#if defined(__SYMBIAN32__) +#define NO_SSL /* SSL is not supported */ +#define NO_CGI /* CGI is not supported */ +#define PATH_MAX FILENAME_MAX +#endif /* __SYMBIAN32__ */ + + +/* Include the header file here, so the CivetWeb interface is defined for the + * entire implementation, including the following forward definitions. */ +#include "civetweb.h" + + +#ifndef IGNORE_UNUSED_RESULT +#define IGNORE_UNUSED_RESULT(a) ((void)((a) && 1)) +#endif + +#ifndef _WIN32_WCE /* Some ANSI #includes are not available on Windows CE */ +#include +#include +#include +#include +#include +#endif /* !_WIN32_WCE */ + +#ifdef __MACH__ + +#define CLOCK_MONOTONIC (1) +#define CLOCK_REALTIME (2) + +#include +#include +#include +#include +#include + + +/* clock_gettime is not implemented on OSX */ +int clock_gettime(int clk_id, struct timespec *t); + +int +clock_gettime(int clk_id, struct timespec *t) +{ + memset(t, 0, sizeof(*t)); + if (clk_id == CLOCK_REALTIME) { + struct timeval now; + int rv = gettimeofday(&now, NULL); + if (rv) { + return rv; + } + t->tv_sec = now.tv_sec; + t->tv_nsec = now.tv_usec * 1000; + return 0; + + } else if (clk_id == CLOCK_MONOTONIC) { + static uint64_t clock_start_time = 0; + static mach_timebase_info_data_t timebase_ifo = {0, 0}; + + uint64_t now = mach_absolute_time(); + + if (clock_start_time == 0) { + kern_return_t mach_status = mach_timebase_info(&timebase_ifo); +#if defined(DEBUG) + assert(mach_status == KERN_SUCCESS); +#else + /* appease "unused variable" warning for release builds */ + (void)mach_status; +#endif + clock_start_time = now; + } + + now = (uint64_t)((double)(now - clock_start_time) + * (double)timebase_ifo.numer + / (double)timebase_ifo.denom); + + t->tv_sec = now / 1000000000; + t->tv_nsec = now % 1000000000; + return 0; + } + return -1; /* EINVAL - Clock ID is unknown */ +} +#endif + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#ifndef MAX_WORKER_THREADS +#define MAX_WORKER_THREADS (1024 * 64) +#endif +#ifndef SOCKET_TIMEOUT_QUANTUM +#define SOCKET_TIMEOUT_QUANTUM (10000) +#endif + +mg_static_assert(MAX_WORKER_THREADS >= 1, + "worker threads must be a positive number"); + +#if defined(_WIN32) \ + && !defined(__SYMBIAN32__) /* WINDOWS / UNIX include block */ +#include +#include /* DTL add for SO_EXCLUSIVE */ +#include + +typedef const char *SOCK_OPT_TYPE; + +#if !defined(PATH_MAX) +#define PATH_MAX (MAX_PATH) +#endif + +#if !defined(PATH_MAX) +#define PATH_MAX (4096) +#endif + +mg_static_assert(PATH_MAX >= 1, "path length must be a positive number"); + +#ifndef _IN_PORT_T +#ifndef in_port_t +#define in_port_t u_short +#endif +#endif + +#ifndef _WIN32_WCE +#include +#include +#include +#else /* _WIN32_WCE */ +#define NO_CGI /* WinCE has no pipes */ + +typedef long off_t; + +#define errno ((int)(GetLastError())) +#define strerror(x) (_ultoa(x, (char *)_alloca(sizeof(x) * 3), 10)) +#endif /* _WIN32_WCE */ + +#define MAKEUQUAD(lo, hi) \ + ((uint64_t)(((uint32_t)(lo)) | ((uint64_t)((uint32_t)(hi))) << 32)) +#define RATE_DIFF (10000000) /* 100 nsecs */ +#define EPOCH_DIFF (MAKEUQUAD(0xd53e8000, 0x019db1de)) +#define SYS2UNIX_TIME(lo, hi) \ + ((time_t)((MAKEUQUAD((lo), (hi)) - EPOCH_DIFF) / RATE_DIFF)) + +/* Visual Studio 6 does not know __func__ or __FUNCTION__ + * The rest of MS compilers use __FUNCTION__, not C99 __func__ + * Also use _strtoui64 on modern M$ compilers */ +#if defined(_MSC_VER) +#if (_MSC_VER < 1300) +#define STRX(x) #x +#define STR(x) STRX(x) +#define __func__ __FILE__ ":" STR(__LINE__) +#define strtoull(x, y, z) ((unsigned __int64)_atoi64(x)) +#define strtoll(x, y, z) (_atoi64(x)) +#else +#define __func__ __FUNCTION__ +#define strtoull(x, y, z) (_strtoui64(x, y, z)) +#define strtoll(x, y, z) (_strtoi64(x, y, z)) +#endif +#endif /* _MSC_VER */ + +#define ERRNO ((int)(GetLastError())) +#define NO_SOCKLEN_T + +#if defined(_WIN64) || defined(__MINGW64__) +#define SSL_LIB "ssleay64.dll" +#define CRYPTO_LIB "libeay64.dll" +#else +#define SSL_LIB "ssleay32.dll" +#define CRYPTO_LIB "libeay32.dll" +#endif + +#define O_NONBLOCK (0) +#ifndef W_OK +#define W_OK (2) /* http://msdn.microsoft.com/en-us/library/1w06ktdy.aspx */ +#endif +#if !defined(EWOULDBLOCK) +#define EWOULDBLOCK WSAEWOULDBLOCK +#endif /* !EWOULDBLOCK */ +#define _POSIX_ +#define INT64_FMT "I64d" +#define UINT64_FMT "I64u" + +#define WINCDECL __cdecl +#define SHUT_RD (0) +#define SHUT_WR (1) +#define SHUT_BOTH (2) +#define vsnprintf_impl _vsnprintf +#define access _access +#define mg_sleep(x) (Sleep(x)) + +#define pipe(x) _pipe(x, MG_BUF_LEN, _O_BINARY) +#ifndef popen +#define popen(x, y) (_popen(x, y)) +#endif +#ifndef pclose +#define pclose(x) (_pclose(x)) +#endif +#define close(x) (_close(x)) +#define dlsym(x, y) (GetProcAddress((HINSTANCE)(x), (y))) +#define RTLD_LAZY (0) +#define fseeko(x, y, z) (_lseeki64(_fileno(x), (y), (z)) == -1 ? -1 : 0) +#define fdopen(x, y) (_fdopen((x), (y))) +#define write(x, y, z) (_write((x), (y), (unsigned)z)) +#define read(x, y, z) (_read((x), (y), (unsigned)z)) +#define flockfile(x) (EnterCriticalSection(&global_log_file_lock)) +#define funlockfile(x) (LeaveCriticalSection(&global_log_file_lock)) +#define sleep(x) (Sleep((x)*1000)) +#define rmdir(x) (_rmdir(x)) +#define timegm(x) (_mkgmtime(x)) + +#if !defined(fileno) +#define fileno(x) (_fileno(x)) +#endif /* !fileno MINGW #defines fileno */ + +typedef HANDLE pthread_mutex_t; +typedef DWORD pthread_key_t; +typedef HANDLE pthread_t; +typedef struct { + CRITICAL_SECTION threadIdSec; + int waitingthreadcount; /* The number of threads queued. */ + pthread_t *waitingthreadhdls; /* The thread handles. */ +} pthread_cond_t; + +#ifndef __clockid_t_defined +typedef DWORD clockid_t; +#endif +#ifndef CLOCK_MONOTONIC +#define CLOCK_MONOTONIC (1) +#endif +#ifndef CLOCK_REALTIME +#define CLOCK_REALTIME (2) +#endif + +#if defined(_MSC_VER) && (_MSC_VER >= 1900) +#define _TIMESPEC_DEFINED +#endif +#ifndef _TIMESPEC_DEFINED +struct timespec { + time_t tv_sec; /* seconds */ + long tv_nsec; /* nanoseconds */ +}; +#endif + +#define pid_t HANDLE /* MINGW typedefs pid_t to int. Using #define here. */ + +static int pthread_mutex_lock(pthread_mutex_t *); +static int pthread_mutex_unlock(pthread_mutex_t *); +static void path_to_unicode(const struct mg_connection *conn, + const char *path, + wchar_t *wbuf, + size_t wbuf_len); +struct file; +static const char * +mg_fgets(char *buf, size_t size, struct file *filep, char **p); + + +#if defined(HAVE_STDINT) +#include +#else +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +typedef unsigned __int64 uint64_t; +typedef __int64 int64_t; +#define INT64_MAX (9223372036854775807) +#endif /* HAVE_STDINT */ + +/* POSIX dirent interface */ +struct dirent { + char d_name[PATH_MAX]; +}; + +typedef struct DIR { + HANDLE handle; + WIN32_FIND_DATAW info; + struct dirent result; +} DIR; + +#if defined(_WIN32) && !defined(POLLIN) +#ifndef HAVE_POLL +struct pollfd { + SOCKET fd; + short events; + short revents; +}; +#define POLLIN (0x0300) +#endif +#endif + +/* Mark required libraries */ +#if defined(_MSC_VER) +#pragma comment(lib, "Ws2_32.lib") +#endif + +#else /* defined(_WIN32) && !defined(__SYMBIAN32__) - WINDOWS / UNIX include \ + block */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +typedef const void *SOCK_OPT_TYPE; + +#if defined(ANDROID) +typedef unsigned short int in_port_t; +#endif + +#include +#include +#include +#include +#define vsnprintf_impl vsnprintf + +#if !defined(NO_SSL_DL) && !defined(NO_SSL) +#include +#endif +#include +#if defined(__MACH__) +#define SSL_LIB "libssl.dylib" +#define CRYPTO_LIB "libcrypto.dylib" +#else +#if !defined(SSL_LIB) +#define SSL_LIB "libssl.so" +#endif +#if !defined(CRYPTO_LIB) +#define CRYPTO_LIB "libcrypto.so" +#endif +#endif +#ifndef O_BINARY +#define O_BINARY (0) +#endif /* O_BINARY */ +#define closesocket(a) (close(a)) +#define mg_mkdir(conn, path, mode) (mkdir(path, mode)) +#define mg_remove(conn, x) (remove(x)) +#define mg_sleep(x) (usleep((x)*1000)) +#define mg_opendir(conn, x) (opendir(x)) +#define mg_closedir(x) (closedir(x)) +#define mg_readdir(x) (readdir(x)) +#define ERRNO (errno) +#define INVALID_SOCKET (-1) +#define INT64_FMT PRId64 +#define UINT64_FMT PRIu64 +typedef int SOCKET; +#define WINCDECL + +#if defined(__hpux) +/* HPUX 11 does not have monotonic, fall back to realtime */ +#ifndef CLOCK_MONOTONIC +#define CLOCK_MONOTONIC CLOCK_REALTIME +#endif + +/* HPUX defines socklen_t incorrectly as size_t which is 64bit on + * Itanium. Without defining _XOPEN_SOURCE or _XOPEN_SOURCE_EXTENDED + * the prototypes use int* rather than socklen_t* which matches the + * actual library expectation. When called with the wrong size arg + * accept() returns a zero client inet addr and check_acl() always + * fails. Since socklen_t is widely used below, just force replace + * their typedef with int. - DTL + */ +#define socklen_t int +#endif /* hpux */ + +#endif /* defined(_WIN32) && !defined(__SYMBIAN32__) - WINDOWS / UNIX include \ + block */ + +/* va_copy should always be a macro, C99 and C++11 - DTL */ +#ifndef va_copy +#define va_copy(x, y) ((x) = (y)) +#endif + +#ifdef _WIN32 +/* Create substitutes for POSIX functions in Win32. */ + +#if defined(__MINGW32__) +/* Show no warning in case system functions are not used. */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" +#endif + + +static CRITICAL_SECTION global_log_file_lock; +static DWORD +pthread_self(void) +{ + return GetCurrentThreadId(); +} + + +static int +pthread_key_create( + pthread_key_t *key, + void (*_ignored)(void *) /* destructor not supported for Windows */ + ) +{ + (void)_ignored; + + if ((key != 0)) { + *key = TlsAlloc(); + return (*key != TLS_OUT_OF_INDEXES) ? 0 : -1; + } + return -2; +} + + +static int +pthread_key_delete(pthread_key_t key) +{ + return TlsFree(key) ? 0 : 1; +} + + +static int +pthread_setspecific(pthread_key_t key, void *value) +{ + return TlsSetValue(key, value) ? 0 : 1; +} + + +static void * +pthread_getspecific(pthread_key_t key) +{ + return TlsGetValue(key); +} + +#if defined(__MINGW32__) +/* Enable unused function warning again */ +#pragma GCC diagnostic pop +#endif + +static struct pthread_mutex_undefined_struct *pthread_mutex_attr = NULL; +#else +static pthread_mutexattr_t pthread_mutex_attr; +#endif /* _WIN32 */ + + +#define PASSWORDS_FILE_NAME ".htpasswd" +#define CGI_ENVIRONMENT_SIZE (4096) +#define MAX_CGI_ENVIR_VARS (256) +#define MG_BUF_LEN (8192) + +#ifndef MAX_REQUEST_SIZE +#define MAX_REQUEST_SIZE (16384) +#endif + +mg_static_assert(MAX_REQUEST_SIZE >= 256, + "request size length must be a positive number"); + +#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0])) + +#if !defined(DEBUG_TRACE) +#if defined(DEBUG) + + +static void DEBUG_TRACE_FUNC(const char *func, + unsigned line, + PRINTF_FORMAT_STRING(const char *fmt), + ...) PRINTF_ARGS(3, 4); + +static void +DEBUG_TRACE_FUNC(const char *func, unsigned line, const char *fmt, ...) +{ + va_list args; + flockfile(stdout); + printf("*** %lu.%p.%s.%u: ", + (unsigned long)time(NULL), + (void *)pthread_self(), + func, + line); + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); + putchar('\n'); + fflush(stdout); + funlockfile(stdout); +} + +#define DEBUG_TRACE(fmt, ...) \ + DEBUG_TRACE_FUNC(__func__, __LINE__, fmt, __VA_ARGS__) + +#else +#define DEBUG_TRACE(fmt, ...) \ + do { \ + } while (0) +#endif /* DEBUG */ +#endif /* DEBUG_TRACE */ + +#if defined(MEMORY_DEBUGGING) +unsigned long mg_memory_debug_blockCount = 0; +unsigned long mg_memory_debug_totalMemUsed = 0; + + +static void * +mg_malloc_ex(size_t size, const char *file, unsigned line) +{ + void *data = malloc(size + sizeof(size_t)); + void *memory = 0; + char mallocStr[256]; + + if (data) { + *(size_t *)data = size; + mg_memory_debug_totalMemUsed += size; + mg_memory_debug_blockCount++; + memory = (void *)(((char *)data) + sizeof(size_t)); + } + + sprintf(mallocStr, + "MEM: %p %5lu alloc %7lu %4lu --- %s:%u\n", + memory, + (unsigned long)size, + mg_memory_debug_totalMemUsed, + mg_memory_debug_blockCount, + file, + line); +#if defined(_WIN32) + OutputDebugStringA(mallocStr); +#else + DEBUG_TRACE("%s", mallocStr); +#endif + + return memory; +} + + +static void * +mg_calloc_ex(size_t count, size_t size, const char *file, unsigned line) +{ + void *data = mg_malloc_ex(size * count, file, line); + if (data) { + memset(data, 0, size); + } + return data; +} + + +static void +mg_free_ex(void *memory, const char *file, unsigned line) +{ + char mallocStr[256]; + void *data = (void *)(((char *)memory) - sizeof(size_t)); + size_t size; + + if (memory) { + size = *(size_t *)data; + mg_memory_debug_totalMemUsed -= size; + mg_memory_debug_blockCount--; + sprintf(mallocStr, + "MEM: %p %5lu free %7lu %4lu --- %s:%u\n", + memory, + (unsigned long)size, + mg_memory_debug_totalMemUsed, + mg_memory_debug_blockCount, + file, + line); +#if defined(_WIN32) + OutputDebugStringA(mallocStr); +#else + DEBUG_TRACE("%s", mallocStr); +#endif + + free(data); + } +} + + +static void * +mg_realloc_ex(void *memory, size_t newsize, const char *file, unsigned line) +{ + char mallocStr[256]; + void *data; + void *_realloc; + size_t oldsize; + + if (newsize) { + if (memory) { + data = (void *)(((char *)memory) - sizeof(size_t)); + oldsize = *(size_t *)data; + _realloc = realloc(data, newsize + sizeof(size_t)); + if (_realloc) { + data = _realloc; + mg_memory_debug_totalMemUsed -= oldsize; + sprintf(mallocStr, + "MEM: %p %5lu r-free %7lu %4lu --- %s:%u\n", + memory, + (unsigned long)oldsize, + mg_memory_debug_totalMemUsed, + mg_memory_debug_blockCount, + file, + line); +#if defined(_WIN32) + OutputDebugStringA(mallocStr); +#else + DEBUG_TRACE("%s", mallocStr); +#endif + mg_memory_debug_totalMemUsed += newsize; + sprintf(mallocStr, + "MEM: %p %5lu r-alloc %7lu %4lu --- %s:%u\n", + memory, + (unsigned long)newsize, + mg_memory_debug_totalMemUsed, + mg_memory_debug_blockCount, + file, + line); +#if defined(_WIN32) + OutputDebugStringA(mallocStr); +#else + DEBUG_TRACE("%s", mallocStr); +#endif + *(size_t *)data = newsize; + data = (void *)(((char *)data) + sizeof(size_t)); + } else { +#if defined(_WIN32) + OutputDebugStringA("MEM: realloc failed\n"); +#else + DEBUG_TRACE("%s", "MEM: realloc failed\n"); +#endif + return _realloc; + } + } else { + data = mg_malloc_ex(newsize, file, line); + } + } else { + data = 0; + mg_free_ex(memory, file, line); + } + + return data; +} + +#define mg_malloc(a) mg_malloc_ex(a, __FILE__, __LINE__) +#define mg_calloc(a, b) mg_calloc_ex(a, b, __FILE__, __LINE__) +#define mg_realloc(a, b) mg_realloc_ex(a, b, __FILE__, __LINE__) +#define mg_free(a) mg_free_ex(a, __FILE__, __LINE__) + +#else + +static __inline void * +mg_malloc(size_t a) +{ + return malloc(a); +} + +static __inline void * +mg_calloc(size_t a, size_t b) +{ + return calloc(a, b); +} + +static __inline void * +mg_realloc(void *a, size_t b) +{ + return realloc(a, b); +} + +static __inline void +mg_free(void *a) +{ + free(a); +} + +#endif + + +static void mg_vsnprintf(const struct mg_connection *conn, + int *truncated, + char *buf, + size_t buflen, + const char *fmt, + va_list ap); + +static void mg_snprintf(const struct mg_connection *conn, + int *truncated, + char *buf, + size_t buflen, + PRINTF_FORMAT_STRING(const char *fmt), + ...) PRINTF_ARGS(5, 6); + +/* This following lines are just meant as a reminder to use the mg-functions + * for memory management */ +#ifdef malloc +#undef malloc +#endif +#ifdef calloc +#undef calloc +#endif +#ifdef realloc +#undef realloc +#endif +#ifdef free +#undef free +#endif +#ifdef snprintf +#undef snprintf +#endif +#ifdef vsnprintf +#undef vsnprintf +#endif +#define malloc DO_NOT_USE_THIS_FUNCTION__USE_mg_malloc +#define calloc DO_NOT_USE_THIS_FUNCTION__USE_mg_calloc +#define realloc DO_NOT_USE_THIS_FUNCTION__USE_mg_realloc +#define free DO_NOT_USE_THIS_FUNCTION__USE_mg_free +#define snprintf DO_NOT_USE_THIS_FUNCTION__USE_mg_snprintf +#ifdef _WIN32 /* vsnprintf must not be used in any system, * \ + * but this define only works well for Windows. */ +#define vsnprintf DO_NOT_USE_THIS_FUNCTION__USE_mg_vsnprintf +#endif + +#define MD5_STATIC static +#include "md5.inl" + +/* Darwin prior to 7.0 and Win32 do not have socklen_t */ +#ifdef NO_SOCKLEN_T +typedef int socklen_t; +#endif /* NO_SOCKLEN_T */ +#define _DARWIN_UNLIMITED_SELECT + +#define IP_ADDR_STR_LEN (50) /* IPv6 hex string is 46 chars */ + +#if !defined(MSG_NOSIGNAL) +#define MSG_NOSIGNAL (0) +#endif + +#if !defined(SOMAXCONN) +#define SOMAXCONN (100) +#endif + +/* Size of the accepted socket queue */ +#if !defined(MGSQLEN) +#define MGSQLEN (20) +#endif + +#if defined(NO_SSL_DL) +#include +#include +#include +#include +#include +#else +/* SSL loaded dynamically from DLL. + * I put the prototypes here to be independent from OpenSSL source + * installation. */ + +typedef struct ssl_st SSL; +typedef struct ssl_method_st SSL_METHOD; +typedef struct ssl_ctx_st SSL_CTX; +typedef struct x509_store_ctx_st X509_STORE_CTX; + +#define SSL_CTRL_OPTIONS (32) +#define SSL_CTRL_CLEAR_OPTIONS (77) +#define SSL_CTRL_SET_ECDH_AUTO (94) + +#define SSL_VERIFY_NONE (0) +#define SSL_VERIFY_PEER (1) +#define SSL_VERIFY_FAIL_IF_NO_PEER_CERT (2) +#define SSL_VERIFY_CLIENT_ONCE (4) +#define SSL_OP_ALL ((long)(0x80000BFFUL)) +#define SSL_OP_NO_SSLv2 (0x01000000L) +#define SSL_OP_NO_SSLv3 (0x02000000L) +#define SSL_OP_NO_TLSv1 (0x04000000L) +#define SSL_OP_NO_TLSv1_2 (0x08000000L) +#define SSL_OP_NO_TLSv1_1 (0x10000000L) +#define SSL_OP_SINGLE_DH_USE (0x00100000L) + +struct ssl_func { + const char *name; /* SSL function name */ + void (*ptr)(void); /* Function pointer */ +}; + +#define SSL_free (*(void (*)(SSL *))ssl_sw[0].ptr) +#define SSL_accept (*(int (*)(SSL *))ssl_sw[1].ptr) +#define SSL_connect (*(int (*)(SSL *))ssl_sw[2].ptr) +#define SSL_read (*(int (*)(SSL *, void *, int))ssl_sw[3].ptr) +#define SSL_write (*(int (*)(SSL *, const void *, int))ssl_sw[4].ptr) +#define SSL_get_error (*(int (*)(SSL *, int))ssl_sw[5].ptr) +#define SSL_set_fd (*(int (*)(SSL *, SOCKET))ssl_sw[6].ptr) +#define SSL_new (*(SSL * (*)(SSL_CTX *))ssl_sw[7].ptr) +#define SSL_CTX_new (*(SSL_CTX * (*)(SSL_METHOD *))ssl_sw[8].ptr) +#define SSLv23_server_method (*(SSL_METHOD * (*)(void))ssl_sw[9].ptr) +#define SSL_library_init (*(int (*)(void))ssl_sw[10].ptr) +#define SSL_CTX_use_PrivateKey_file \ + (*(int (*)(SSL_CTX *, const char *, int))ssl_sw[11].ptr) +#define SSL_CTX_use_certificate_file \ + (*(int (*)(SSL_CTX *, const char *, int))ssl_sw[12].ptr) +#define SSL_CTX_set_default_passwd_cb \ + (*(void (*)(SSL_CTX *, mg_callback_t))ssl_sw[13].ptr) +#define SSL_CTX_free (*(void (*)(SSL_CTX *))ssl_sw[14].ptr) +#define SSL_load_error_strings (*(void (*)(void))ssl_sw[15].ptr) +#define SSL_CTX_use_certificate_chain_file \ + (*(int (*)(SSL_CTX *, const char *))ssl_sw[16].ptr) +#define SSLv23_client_method (*(SSL_METHOD * (*)(void))ssl_sw[17].ptr) +#define SSL_pending (*(int (*)(SSL *))ssl_sw[18].ptr) +#define SSL_CTX_set_verify \ + (*(void (*)(SSL_CTX *, \ + int, \ + int (*verify_callback)(int, X509_STORE_CTX *)))ssl_sw[19].ptr) +#define SSL_shutdown (*(int (*)(SSL *))ssl_sw[20].ptr) +#define SSL_CTX_load_verify_locations \ + (*(int (*)(SSL_CTX *, const char *, const char *))ssl_sw[21].ptr) +#define SSL_CTX_set_default_verify_paths (*(int (*)(SSL_CTX *))ssl_sw[22].ptr) +#define SSL_CTX_set_verify_depth (*(void (*)(SSL_CTX *, int))ssl_sw[23].ptr) +#define SSL_get_peer_certificate (*(X509 * (*)(SSL *))ssl_sw[24].ptr) +#define SSL_get_version (*(const char *(*)(SSL *))ssl_sw[25].ptr) +#define SSL_get_current_cipher (*(SSL_CIPHER * (*)(SSL *))ssl_sw[26].ptr) +#define SSL_CIPHER_get_name \ + (*(const char *(*)(const SSL_CIPHER *))ssl_sw[27].ptr) +#define SSL_CTX_check_private_key (*(int (*)(SSL_CTX *))ssl_sw[28].ptr) +#define SSL_CTX_set_session_id_context \ + (*(int (*)(SSL_CTX *, const unsigned char *, unsigned int))ssl_sw[29].ptr) +#define SSL_CTX_ctrl (*(long (*)(SSL_CTX *, int, long, void *))ssl_sw[30].ptr) +#define SSL_CTX_set_cipher_list \ + (*(int (*)(SSL_CTX *, const char *))ssl_sw[31].ptr) +#define SSL_CTX_set_options(ctx, op) \ + SSL_CTX_ctrl((ctx), SSL_CTRL_OPTIONS, (op), NULL) +#define SSL_CTX_clear_options(ctx, op) \ + SSL_CTX_ctrl((ctx), SSL_CTRL_CLEAR_OPTIONS, (op), NULL) +#define SSL_CTX_set_ecdh_auto(ctx, onoff) \ + SSL_CTX_ctrl(ctx, SSL_CTRL_SET_ECDH_AUTO, onoff, NULL) + +#define CRYPTO_num_locks (*(int (*)(void))crypto_sw[0].ptr) +#define CRYPTO_set_locking_callback \ + (*(void (*)(void (*)(int, int, const char *, int)))crypto_sw[1].ptr) +#define CRYPTO_set_id_callback \ + (*(void (*)(unsigned long (*)(void)))crypto_sw[2].ptr) +#define ERR_get_error (*(unsigned long (*)(void))crypto_sw[3].ptr) +#define ERR_error_string (*(char *(*)(unsigned long, char *))crypto_sw[4].ptr) +#define ERR_remove_state (*(void (*)(unsigned long))crypto_sw[5].ptr) +#define ERR_free_strings (*(void (*)(void))crypto_sw[6].ptr) +#define ENGINE_cleanup (*(void (*)(void))crypto_sw[7].ptr) +#define CONF_modules_unload (*(void (*)(int))crypto_sw[8].ptr) +#define CRYPTO_cleanup_all_ex_data (*(void (*)(void))crypto_sw[9].ptr) +#define EVP_cleanup (*(void (*)(void))crypto_sw[10].ptr) + + +/* set_ssl_option() function updates this array. + * It loads SSL library dynamically and changes NULLs to the actual addresses + * of respective functions. The macros above (like SSL_connect()) are really + * just calling these functions indirectly via the pointer. */ +static struct ssl_func ssl_sw[] = {{"SSL_free", NULL}, + {"SSL_accept", NULL}, + {"SSL_connect", NULL}, + {"SSL_read", NULL}, + {"SSL_write", NULL}, + {"SSL_get_error", NULL}, + {"SSL_set_fd", NULL}, + {"SSL_new", NULL}, + {"SSL_CTX_new", NULL}, + {"SSLv23_server_method", NULL}, + {"SSL_library_init", NULL}, + {"SSL_CTX_use_PrivateKey_file", NULL}, + {"SSL_CTX_use_certificate_file", NULL}, + {"SSL_CTX_set_default_passwd_cb", NULL}, + {"SSL_CTX_free", NULL}, + {"SSL_load_error_strings", NULL}, + {"SSL_CTX_use_certificate_chain_file", NULL}, + {"SSLv23_client_method", NULL}, + {"SSL_pending", NULL}, + {"SSL_CTX_set_verify", NULL}, + {"SSL_shutdown", NULL}, + {"SSL_CTX_load_verify_locations", NULL}, + {"SSL_CTX_set_default_verify_paths", NULL}, + {"SSL_CTX_set_verify_depth", NULL}, + {"SSL_get_peer_certificate", NULL}, + {"SSL_get_version", NULL}, + {"SSL_get_current_cipher", NULL}, + {"SSL_CIPHER_get_name", NULL}, + {"SSL_CTX_check_private_key", NULL}, + {"SSL_CTX_set_session_id_context", NULL}, + {"SSL_CTX_ctrl", NULL}, + {"SSL_CTX_set_cipher_list", NULL}, + {NULL, NULL}}; + + +/* Similar array as ssl_sw. These functions could be located in different + * lib. */ +#if !defined(NO_SSL) +static struct ssl_func crypto_sw[] = {{"CRYPTO_num_locks", NULL}, + {"CRYPTO_set_locking_callback", NULL}, + {"CRYPTO_set_id_callback", NULL}, + {"ERR_get_error", NULL}, + {"ERR_error_string", NULL}, + {"ERR_remove_state", NULL}, + {"ERR_free_strings", NULL}, + {"ENGINE_cleanup", NULL}, + {"CONF_modules_unload", NULL}, + {"CRYPTO_cleanup_all_ex_data", NULL}, + {"EVP_cleanup", NULL}, + {NULL, NULL}}; +#endif /* NO_SSL */ +#endif /* NO_SSL_DL */ + + +#if !defined(NO_CACHING) +static const char *month_names[] = {"Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec"}; +#endif /* !NO_CACHING */ + +/* Unified socket address. For IPv6 support, add IPv6 address structure in the + * union u. */ +union usa { + struct sockaddr sa; + struct sockaddr_in sin; +#if defined(USE_IPV6) + struct sockaddr_in6 sin6; +#endif +}; + +/* Describes a string (chunk of memory). */ +struct vec { + const char *ptr; + size_t len; +}; + +struct file { + uint64_t size; + time_t last_modified; + FILE *fp; + const char *membuf; /* Non-NULL if file data is in memory */ + int is_directory; + int gzipped; /* set to 1 if the content is gzipped + * in which case we need a content-encoding: gzip header */ +}; + +#define STRUCT_FILE_INITIALIZER \ + { \ + (uint64_t)0, (time_t)0, (FILE *)NULL, (const char *)NULL, 0, 0 \ + } + +/* Describes listening socket, or socket which was accept()-ed by the master + * thread and queued for future handling by the worker thread. */ +struct socket { + SOCKET sock; /* Listening socket */ + union usa lsa; /* Local socket address */ + union usa rsa; /* Remote socket address */ + unsigned char is_ssl; /* Is port SSL-ed */ + unsigned char ssl_redir; /* Is port supposed to redirect everything to SSL + * port */ +}; + +/* NOTE(lsm): this enum shoulds be in sync with the config_options below. */ +enum { + CGI_EXTENSIONS, + CGI_ENVIRONMENT, + PUT_DELETE_PASSWORDS_FILE, + CGI_INTERPRETER, + PROTECT_URI, + AUTHENTICATION_DOMAIN, + SSI_EXTENSIONS, + THROTTLE, + ACCESS_LOG_FILE, + ENABLE_DIRECTORY_LISTING, + ERROR_LOG_FILE, + GLOBAL_PASSWORDS_FILE, + INDEX_FILES, + ENABLE_KEEP_ALIVE, + ACCESS_CONTROL_LIST, + EXTRA_MIME_TYPES, + LISTENING_PORTS, + DOCUMENT_ROOT, + SSL_CERTIFICATE, + NUM_THREADS, + RUN_AS_USER, + REWRITE, + HIDE_FILES, + REQUEST_TIMEOUT, + SSL_DO_VERIFY_PEER, + SSL_CA_PATH, + SSL_CA_FILE, + SSL_VERIFY_DEPTH, + SSL_DEFAULT_VERIFY_PATHS, + SSL_CIPHER_LIST, + SSL_PROTOCOL_VERSION, + SSL_SHORT_TRUST, +#if defined(USE_WEBSOCKET) + WEBSOCKET_TIMEOUT, +#endif + DECODE_URL, + +#if defined(USE_LUA) + LUA_PRELOAD_FILE, + LUA_SCRIPT_EXTENSIONS, + LUA_SERVER_PAGE_EXTENSIONS, +#endif +#if defined(USE_DUKTAPE) + DUKTAPE_SCRIPT_EXTENSIONS, +#endif + +#if defined(USE_WEBSOCKET) + WEBSOCKET_ROOT, +#endif +#if defined(USE_LUA) && defined(USE_WEBSOCKET) + LUA_WEBSOCKET_EXTENSIONS, +#endif + ACCESS_CONTROL_ALLOW_ORIGIN, + ERROR_PAGES, + CONFIG_TCP_NODELAY, /* Prepended CONFIG_ to avoid conflict with the + * socket option typedef TCP_NODELAY. */ +#if !defined(NO_CACHING) + STATIC_FILE_MAX_AGE, +#endif + + NUM_OPTIONS +}; + + +/* Config option name, config types, default value */ +static struct mg_option config_options[] = { + {"cgi_pattern", CONFIG_TYPE_EXT_PATTERN, "**.cgi$|**.pl$|**.php$"}, + {"cgi_environment", CONFIG_TYPE_STRING, NULL}, + {"put_delete_auth_file", CONFIG_TYPE_FILE, NULL}, + {"cgi_interpreter", CONFIG_TYPE_FILE, NULL}, + {"protect_uri", CONFIG_TYPE_STRING, NULL}, + {"authentication_domain", CONFIG_TYPE_STRING, "mydomain.com"}, + {"ssi_pattern", CONFIG_TYPE_EXT_PATTERN, "**.shtml$|**.shtm$"}, + {"throttle", CONFIG_TYPE_STRING, NULL}, + {"access_log_file", CONFIG_TYPE_FILE, NULL}, + {"enable_directory_listing", CONFIG_TYPE_BOOLEAN, "yes"}, + {"error_log_file", CONFIG_TYPE_FILE, NULL}, + {"global_auth_file", CONFIG_TYPE_FILE, NULL}, + {"index_files", + CONFIG_TYPE_STRING, +#ifdef USE_LUA + "index.xhtml,index.html,index.htm,index.lp,index.lsp,index.lua,index.cgi," + "index.shtml,index.php"}, +#else + "index.xhtml,index.html,index.htm,index.cgi,index.shtml,index.php"}, +#endif + {"enable_keep_alive", CONFIG_TYPE_BOOLEAN, "no"}, + {"access_control_list", CONFIG_TYPE_STRING, NULL}, + {"extra_mime_types", CONFIG_TYPE_STRING, NULL}, + {"listening_ports", CONFIG_TYPE_STRING, "8080"}, + {"document_root", CONFIG_TYPE_DIRECTORY, NULL}, + {"ssl_certificate", CONFIG_TYPE_FILE, NULL}, + {"num_threads", CONFIG_TYPE_NUMBER, "50"}, + {"run_as_user", CONFIG_TYPE_STRING, NULL}, + {"url_rewrite_patterns", CONFIG_TYPE_STRING, NULL}, + {"hide_files_patterns", CONFIG_TYPE_EXT_PATTERN, NULL}, + {"request_timeout_ms", CONFIG_TYPE_NUMBER, "30000"}, + {"ssl_verify_peer", CONFIG_TYPE_BOOLEAN, "no"}, + {"ssl_ca_path", CONFIG_TYPE_DIRECTORY, NULL}, + {"ssl_ca_file", CONFIG_TYPE_FILE, NULL}, + {"ssl_verify_depth", CONFIG_TYPE_NUMBER, "9"}, + {"ssl_default_verify_paths", CONFIG_TYPE_BOOLEAN, "yes"}, + {"ssl_cipher_list", CONFIG_TYPE_STRING, NULL}, + {"ssl_protocol_version", CONFIG_TYPE_NUMBER, "0"}, + {"ssl_short_trust", CONFIG_TYPE_BOOLEAN, "no"}, +#if defined(USE_WEBSOCKET) + {"websocket_timeout_ms", CONFIG_TYPE_NUMBER, "30000"}, +#endif + {"decode_url", CONFIG_TYPE_BOOLEAN, "yes"}, + +#if defined(USE_LUA) + {"lua_preload_file", CONFIG_TYPE_FILE, NULL}, + {"lua_script_pattern", CONFIG_TYPE_EXT_PATTERN, "**.lua$"}, + {"lua_server_page_pattern", CONFIG_TYPE_EXT_PATTERN, "**.lp$|**.lsp$"}, +#endif +#if defined(USE_DUKTAPE) + /* The support for duktape is still in alpha version state. + * The name of this config option might change. */ + {"duktape_script_pattern", CONFIG_TYPE_EXT_PATTERN, "**.ssjs$"}, +#endif + +#if defined(USE_WEBSOCKET) + {"websocket_root", CONFIG_TYPE_DIRECTORY, NULL}, +#endif +#if defined(USE_LUA) && defined(USE_WEBSOCKET) + {"lua_websocket_pattern", CONFIG_TYPE_EXT_PATTERN, "**.lua$"}, +#endif + {"access_control_allow_origin", CONFIG_TYPE_STRING, "*"}, + {"error_pages", CONFIG_TYPE_DIRECTORY, NULL}, + {"tcp_nodelay", CONFIG_TYPE_NUMBER, "0"}, +#if !defined(NO_CACHING) + {"static_file_max_age", CONFIG_TYPE_NUMBER, "3600"}, +#endif + + {NULL, CONFIG_TYPE_UNKNOWN, NULL}}; + +/* Check if the config_options and the corresponding enum have compatible + * sizes. */ +mg_static_assert((sizeof(config_options) / sizeof(config_options[0])) + == (NUM_OPTIONS + 1), + "config_options and enum not sync"); + +enum { REQUEST_HANDLER, WEBSOCKET_HANDLER, AUTH_HANDLER }; + +struct mg_handler_info { + /* Name/Pattern of the URI. */ + char *uri; + size_t uri_len; + + /* handler type */ + int handler_type; + + /* Handler for http/https or authorization requests. */ + mg_request_handler handler; + + /* Handler for ws/wss (websocket) requests. */ + mg_websocket_connect_handler connect_handler; + mg_websocket_ready_handler ready_handler; + mg_websocket_data_handler data_handler; + mg_websocket_close_handler close_handler; + + /* Handler for authorization requests */ + mg_authorization_handler auth_handler; + + /* User supplied argument for the handler function. */ + void *cbdata; + + /* next handler in a linked list */ + struct mg_handler_info *next; +}; + +struct mg_context { + volatile int stop_flag; /* Should we stop event loop */ + SSL_CTX *ssl_ctx; /* SSL context */ + char *config[NUM_OPTIONS]; /* Civetweb configuration parameters */ + struct mg_callbacks callbacks; /* User-defined callback function */ + void *user_data; /* User-defined data */ + int context_type; /* 1 = server context, 2 = client context */ + + struct socket *listening_sockets; + in_port_t *listening_ports; + unsigned int num_listening_sockets; + + volatile int + running_worker_threads; /* Number of currently running worker threads */ + pthread_mutex_t thread_mutex; /* Protects (max|num)_threads */ + pthread_cond_t thread_cond; /* Condvar for tracking workers terminations */ + + struct socket queue[MGSQLEN]; /* Accepted sockets */ + volatile int sq_head; /* Head of the socket queue */ + volatile int sq_tail; /* Tail of the socket queue */ + pthread_cond_t sq_full; /* Signaled when socket is produced */ + pthread_cond_t sq_empty; /* Signaled when socket is consumed */ + pthread_t masterthreadid; /* The master thread ID */ + unsigned int + cfg_worker_threads; /* The number of configured worker threads. */ + pthread_t *workerthreadids; /* The worker thread IDs */ + + time_t start_time; /* Server start time, used for authentication */ + uint64_t auth_nonce_mask; /* Mask for all nonce values */ + pthread_mutex_t nonce_mutex; /* Protects nonce_count */ + unsigned long nonce_count; /* Used nonces, used for authentication */ + + char *systemName; /* What operating system is running */ + + /* linked list of uri handlers */ + struct mg_handler_info *handlers; + +#if defined(USE_LUA) && defined(USE_WEBSOCKET) + /* linked list of shared lua websockets */ + struct mg_shared_lua_websocket_list *shared_lua_websockets; +#endif + +#ifdef USE_TIMERS + struct ttimers *timers; +#endif +}; + + +struct mg_connection { + struct mg_request_info request_info; + struct mg_context *ctx; + SSL *ssl; /* SSL descriptor */ + SSL_CTX *client_ssl_ctx; /* SSL context for client connections */ + struct socket client; /* Connected client */ + time_t conn_birth_time; /* Time (wall clock) when connection was + * established */ + struct timespec req_time; /* Time (since system start) when the request + * was received */ + int64_t num_bytes_sent; /* Total bytes sent to client */ + int64_t content_len; /* Content-Length header value */ + int64_t consumed_content; /* How many bytes of content have been read */ + int is_chunked; /* Transfer-Encoding is chunked: 0=no, 1=yes: + * data available, 2: all data read */ + size_t chunk_remainder; /* Unread data from the last chunk */ + char *buf; /* Buffer for received data */ + char *path_info; /* PATH_INFO part of the URL */ + + int must_close; /* 1 if connection must be closed */ + int in_error_handler; /* 1 if in handler for user defined error + * pages */ + int internal_error; /* 1 if an error occured while processing the + * request */ + + int buf_size; /* Buffer size */ + int request_len; /* Size of the request + headers in a buffer */ + int data_len; /* Total size of data in a buffer */ + int status_code; /* HTTP reply status code, e.g. 200 */ + int throttle; /* Throttling, bytes/sec. <= 0 means no + * throttle */ + time_t last_throttle_time; /* Last time throttled data was sent */ + int64_t last_throttle_bytes; /* Bytes sent this second */ + pthread_mutex_t mutex; /* Used by mg_(un)lock_connection to ensure + * atomic transmissions for websockets */ +#if defined(USE_LUA) && defined(USE_WEBSOCKET) + void *lua_websocket_state; /* Lua_State for a websocket connection */ +#endif +}; + + +static pthread_key_t sTlsKey; /* Thread local storage index */ +static int sTlsInit = 0; +static int thread_idx_max = 0; + + +struct mg_workerTLS { + int is_master; + unsigned long thread_idx; +#if defined(_WIN32) && !defined(__SYMBIAN32__) + HANDLE pthread_cond_helper_mutex; +#endif +}; + +/* Directory entry */ +struct de { + struct mg_connection *conn; + char *file_name; + struct file file; +}; + + +#if defined(USE_WEBSOCKET) +static int is_websocket_protocol(const struct mg_connection *conn); +#else +#define is_websocket_protocol(conn) (0) +#endif + + +static int +mg_atomic_inc(volatile int *addr) +{ + int ret; +#if defined(_WIN32) && !defined(__SYMBIAN32__) + /* Depending on the SDK, this function uses either + * (volatile unsigned int *) or (volatile LONG *), + * so whatever you use, the other SDK is likely to raise a warning. */ + ret = InterlockedIncrement((volatile long *)addr); +#elif defined(__GNUC__) \ + && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 0))) + ret = __sync_add_and_fetch(addr, 1); +#else + ret = (++(*addr)); +#endif + return ret; +} + + +static int +mg_atomic_dec(volatile int *addr) +{ + int ret; +#if defined(_WIN32) && !defined(__SYMBIAN32__) + /* Depending on the SDK, this function uses either + * (volatile unsigned int *) or (volatile LONG *), + * so whatever you use, the other SDK is likely to raise a warning. */ + ret = InterlockedDecrement((volatile long *)addr); +#elif defined(__GNUC__) \ + && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 0))) + ret = __sync_sub_and_fetch(addr, 1); +#else + ret = (--(*addr)); +#endif + return ret; +} + +#if !defined(NO_THREAD_NAME) +#if defined(_WIN32) && defined(_MSC_VER) +/* Set the thread name for debugging purposes in Visual Studio + * http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx + */ +#pragma pack(push, 8) +typedef struct tagTHREADNAME_INFO { + DWORD dwType; /* Must be 0x1000. */ + LPCSTR szName; /* Pointer to name (in user addr space). */ + DWORD dwThreadID; /* Thread ID (-1=caller thread). */ + DWORD dwFlags; /* Reserved for future use, must be zero. */ +} THREADNAME_INFO; +#pragma pack(pop) +#elif defined(__linux__) +#include +#include +#endif + + +static void +mg_set_thread_name(const char *name) +{ + char threadName[16 + 1]; /* 16 = Max. thread length in Linux/OSX/.. */ + + mg_snprintf( + NULL, NULL, threadName, sizeof(threadName), "civetweb-%s", name); + +#if defined(_WIN32) +#if defined(_MSC_VER) + /* Windows and Visual Studio Compiler */ + __try + { + THREADNAME_INFO info; + info.dwType = 0x1000; + info.szName = threadName; + info.dwThreadID = ~0U; + info.dwFlags = 0; + + RaiseException(0x406D1388, + 0, + sizeof(info) / sizeof(ULONG_PTR), + (ULONG_PTR *)&info); + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + } +#elif defined(__MINGW32__) +/* No option known to set thread name for MinGW */ +#endif +#elif defined(__GLIBC__) \ + && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 12))) + /* pthread_setname_np first appeared in glibc in version 2.12*/ + (void)pthread_setname_np(pthread_self(), threadName); +#elif defined(__linux__) + /* on linux we can use the old prctl function */ + (void)prctl(PR_SET_NAME, threadName, 0, 0, 0); +#endif +} +#else /* !defined(NO_THREAD_NAME) */ +void +mg_set_thread_name(const char *threadName) +{ +} +#endif + + +#if defined(MG_LEGACY_INTERFACE) +const char ** +mg_get_valid_option_names(void) +{ + /* This function is deprecated. Use mg_get_valid_options instead. */ + static const char * + data[2 * sizeof(config_options) / sizeof(config_options[0])] = {0}; + int i; + + for (i = 0; config_options[i].name != NULL; i++) { + data[i * 2] = config_options[i].name; + data[i * 2 + 1] = config_options[i].default_value; + } + + return data; +} +#endif + + +const struct mg_option * +mg_get_valid_options(void) +{ + return config_options; +} + + +static int +is_file_in_memory(const struct mg_connection *conn, + const char *path, + struct file *filep) +{ + size_t size = 0; + if (!conn || !filep) { + return 0; + } + + if (conn->ctx->callbacks.open_file) { + filep->membuf = conn->ctx->callbacks.open_file(conn, path, &size); + if (filep->membuf != NULL) { + /* NOTE: override filep->size only on success. Otherwise, it might + * break constructs like if (!mg_stat() || !mg_fopen()) ... */ + filep->size = size; + } + } + + return filep->membuf != NULL; +} + + +static int +is_file_opened(const struct file *filep) +{ + if (!filep) { + return 0; + } + + return filep->membuf != NULL || filep->fp != NULL; +} + + +/* mg_fopen will open a file either in memory or on the disk. + * The input parameter path is a string in UTF-8 encoding. + * The input parameter mode is the same as for fopen. + * Either fp or membuf will be set in the output struct filep. + * The function returns 1 on success, 0 on error. */ +static int +mg_fopen(const struct mg_connection *conn, + const char *path, + const char *mode, + struct file *filep) +{ + struct stat st; + + if (!filep) { + return 0; + } + + /* TODO (high): mg_fopen should only open a file, while mg_stat should + * only get the file status. They should not work on different members of + * the same structure (bad cohesion). */ + memset(filep, 0, sizeof(*filep)); + + if (stat(path, &st) == 0) { + filep->size = (uint64_t)(st.st_size); + } + + if (!is_file_in_memory(conn, path, filep)) { +#ifdef _WIN32 + wchar_t wbuf[PATH_MAX], wmode[20]; + path_to_unicode(conn, path, wbuf, ARRAY_SIZE(wbuf)); + MultiByteToWideChar(CP_UTF8, 0, mode, -1, wmode, ARRAY_SIZE(wmode)); + filep->fp = _wfopen(wbuf, wmode); +#else + /* Linux et al already use unicode. No need to convert. */ + filep->fp = fopen(path, mode); +#endif + } + + return is_file_opened(filep); +} + + +static void +mg_fclose(struct file *filep) +{ + if (filep != NULL && filep->fp != NULL) { + fclose(filep->fp); + } +} + + +static void +mg_strlcpy(register char *dst, register const char *src, size_t n) +{ + for (; *src != '\0' && n > 1; n--) { + *dst++ = *src++; + } + *dst = '\0'; +} + + +static int +lowercase(const char *s) +{ + return tolower(*(const unsigned char *)s); +} + + +int +mg_strncasecmp(const char *s1, const char *s2, size_t len) +{ + int diff = 0; + + if (len > 0) { + do { + diff = lowercase(s1++) - lowercase(s2++); + } while (diff == 0 && s1[-1] != '\0' && --len > 0); + } + + return diff; +} + + +int +mg_strcasecmp(const char *s1, const char *s2) +{ + int diff; + + do { + diff = lowercase(s1++) - lowercase(s2++); + } while (diff == 0 && s1[-1] != '\0'); + + return diff; +} + + +static char * +mg_strndup(const char *ptr, size_t len) +{ + char *p; + + if ((p = (char *)mg_malloc(len + 1)) != NULL) { + mg_strlcpy(p, ptr, len + 1); + } + + return p; +} + + +static char * +mg_strdup(const char *str) +{ + return mg_strndup(str, strlen(str)); +} + + +static const char * +mg_strcasestr(const char *big_str, const char *small_str) +{ + size_t i, big_len = strlen(big_str), small_len = strlen(small_str); + + if (big_len >= small_len) { + for (i = 0; i <= (big_len - small_len); i++) { + if (mg_strncasecmp(big_str + i, small_str, small_len) == 0) { + return big_str + i; + } + } + } + + return NULL; +} + + +/* Return null terminated string of given maximum length. + * Report errors if length is exceeded. */ +static void +mg_vsnprintf(const struct mg_connection *conn, + int *truncated, + char *buf, + size_t buflen, + const char *fmt, + va_list ap) +{ + int n, ok; + + if (buflen == 0) { + return; + } + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wformat-nonliteral" +/* Using fmt as a non-literal is intended here, since it is mostly called + * indirectly by mg_snprintf */ +#endif + + n = (int)vsnprintf_impl(buf, buflen, fmt, ap); + ok = (n >= 0) && ((size_t)n < buflen); + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + + if (ok) { + if (truncated) { + *truncated = 0; + } + } else { + if (truncated) { + *truncated = 1; + } + mg_cry(conn, + "truncating vsnprintf buffer: [%.*s]", + (int)((buflen > 200) ? 200 : (buflen - 1)), + buf); + n = (int)buflen - 1; + } + buf[n] = '\0'; +} + + +static void +mg_snprintf(const struct mg_connection *conn, + int *truncated, + char *buf, + size_t buflen, + const char *fmt, + ...) +{ + va_list ap; + + va_start(ap, fmt); + mg_vsnprintf(conn, truncated, buf, buflen, fmt, ap); + va_end(ap); +} + + +static int +get_option_index(const char *name) +{ + int i; + + for (i = 0; config_options[i].name != NULL; i++) { + if (strcmp(config_options[i].name, name) == 0) { + return i; + } + } + return -1; +} + + +const char * +mg_get_option(const struct mg_context *ctx, const char *name) +{ + int i; + if ((i = get_option_index(name)) == -1) { + return NULL; + } else if (!ctx || ctx->config[i] == NULL) { + return ""; + } else { + return ctx->config[i]; + } +} + + +struct mg_context * +mg_get_context(const struct mg_connection *conn) +{ + return (conn == NULL) ? (struct mg_context *)NULL : (conn->ctx); +} + + +void * +mg_get_user_data(const struct mg_context *ctx) +{ + return (ctx == NULL) ? NULL : ctx->user_data; +} + + +void +mg_set_user_connection_data(struct mg_connection *conn, void *data) +{ + if (conn != NULL) { + conn->request_info.conn_data = data; + } +} + + +void * +mg_get_user_connection_data(const struct mg_connection *conn) +{ + if (conn != NULL) { + return conn->request_info.conn_data; + } + return NULL; +} + + +size_t +mg_get_ports(const struct mg_context *ctx, size_t size, int *ports, int *ssl) +{ + size_t i; + if (!ctx) { + return 0; + } + for (i = 0; i < size && i < ctx->num_listening_sockets; i++) { + ssl[i] = ctx->listening_sockets[i].is_ssl; + ports[i] = ctx->listening_ports[i]; + } + return i; +} + + +int +mg_get_server_ports(const struct mg_context *ctx, + int size, + struct mg_server_ports *ports) +{ + int i, cnt = 0; + + if (size <= 0) { + return -1; + } + memset(ports, 0, sizeof(*ports) * (size_t)size); + if (!ctx) { + return -1; + } + if (!ctx->listening_sockets || !ctx->listening_ports) { + return -1; + } + + for (i = 0; (i < size) && (i < (int)ctx->num_listening_sockets); i++) { + + ports[cnt].port = ctx->listening_ports[i]; + ports[cnt].is_ssl = ctx->listening_sockets[i].is_ssl; + ports[cnt].is_redirect = ctx->listening_sockets[i].ssl_redir; + + if (ctx->listening_sockets[i].lsa.sa.sa_family == AF_INET) { + /* IPv4 */ + ports[cnt].protocol = 1; + cnt++; + } else if (ctx->listening_sockets[i].lsa.sa.sa_family == AF_INET6) { + /* IPv6 */ + ports[cnt].protocol = 3; + cnt++; + } + } + + return cnt; +} + + +static void +sockaddr_to_string(char *buf, size_t len, const union usa *usa) +{ + buf[0] = '\0'; + + if (!usa) { + return; + } + + if (usa->sa.sa_family == AF_INET) { + getnameinfo(&usa->sa, + sizeof(usa->sin), + buf, + (unsigned)len, + NULL, + 0, + NI_NUMERICHOST); + } +#if defined(USE_IPV6) + else if (usa->sa.sa_family == AF_INET6) { + getnameinfo(&usa->sa, + sizeof(usa->sin6), + buf, + (unsigned)len, + NULL, + 0, + NI_NUMERICHOST); + } +#endif +} + + +/* Convert time_t to a string. According to RFC2616, Sec 14.18, this must be + * included in all responses other than 100, 101, 5xx. */ +static void +gmt_time_string(char *buf, size_t buf_len, time_t *t) +{ + struct tm *tm; + + tm = ((t != NULL) ? gmtime(t) : NULL); + if (tm != NULL) { + strftime(buf, buf_len, "%a, %d %b %Y %H:%M:%S GMT", tm); + } else { + mg_strlcpy(buf, "Thu, 01 Jan 1970 00:00:00 GMT", buf_len); + buf[buf_len - 1] = '\0'; + } +} + + +/* difftime for struct timespec. Return value is in seconds. */ +static double +mg_difftimespec(const struct timespec *ts_now, const struct timespec *ts_before) +{ + return (double)(ts_now->tv_nsec - ts_before->tv_nsec) * 1.0E-9 + + (double)(ts_now->tv_sec - ts_before->tv_sec); +} + + +/* Print error message to the opened error log stream. */ +void +mg_cry(const struct mg_connection *conn, const char *fmt, ...) +{ + char buf[MG_BUF_LEN], src_addr[IP_ADDR_STR_LEN]; + va_list ap; + struct file fi; + time_t timestamp; + + va_start(ap, fmt); + IGNORE_UNUSED_RESULT(vsnprintf_impl(buf, sizeof(buf), fmt, ap)); + va_end(ap); + buf[sizeof(buf) - 1] = 0; + + if (!conn) { + puts(buf); + return; + } + + /* Do not lock when getting the callback value, here and below. + * I suppose this is fine, since function cannot disappear in the + * same way string option can. */ + if ((conn->ctx->callbacks.log_message == NULL) + || (conn->ctx->callbacks.log_message(conn, buf) == 0)) { + + if (conn->ctx->config[ERROR_LOG_FILE] != NULL) { + if (mg_fopen(conn, conn->ctx->config[ERROR_LOG_FILE], "a+", &fi) + == 0) { + fi.fp = NULL; + } + } else { + fi.fp = NULL; + } + + if (fi.fp != NULL) { + flockfile(fi.fp); + timestamp = time(NULL); + + sockaddr_to_string(src_addr, sizeof(src_addr), &conn->client.rsa); + fprintf(fi.fp, + "[%010lu] [error] [client %s] ", + (unsigned long)timestamp, + src_addr); + + if (conn->request_info.request_method != NULL) { + fprintf(fi.fp, + "%s %s: ", + conn->request_info.request_method, + conn->request_info.request_uri); + } + + fprintf(fi.fp, "%s", buf); + fputc('\n', fi.fp); + fflush(fi.fp); + funlockfile(fi.fp); + mg_fclose(&fi); + } + } +} + + +/* Return fake connection structure. Used for logging, if connection + * is not applicable at the moment of logging. */ +static struct mg_connection * +fc(struct mg_context *ctx) +{ + static struct mg_connection fake_connection; + fake_connection.ctx = ctx; + return &fake_connection; +} + + +const char * +mg_version(void) +{ + return CIVETWEB_VERSION; +} + + +const struct mg_request_info * +mg_get_request_info(const struct mg_connection *conn) +{ + if (!conn) { + return NULL; + } + return &conn->request_info; +} + + +/* Skip the characters until one of the delimiters characters found. + * 0-terminate resulting word. Skip the delimiter and following whitespaces. + * Advance pointer to buffer to the next word. Return found 0-terminated word. + * Delimiters can be quoted with quotechar. */ +static char * +skip_quoted(char **buf, + const char *delimiters, + const char *whitespace, + char quotechar) +{ + char *p, *begin_word, *end_word, *end_whitespace; + + begin_word = *buf; + end_word = begin_word + strcspn(begin_word, delimiters); + + /* Check for quotechar */ + if (end_word > begin_word) { + p = end_word - 1; + while (*p == quotechar) { + /* While the delimiter is quoted, look for the next delimiter. */ + /* This happens, e.g., in calls from parse_auth_header, + * if the user name contains a " character. */ + + /* If there is anything beyond end_word, copy it. */ + if (*end_word != '\0') { + size_t end_off = strcspn(end_word + 1, delimiters); + memmove(p, end_word, end_off + 1); + p += end_off; /* p must correspond to end_word - 1 */ + end_word += end_off + 1; + } else { + *p = '\0'; + break; + } + } + for (p++; p < end_word; p++) { + *p = '\0'; + } + } + + if (*end_word == '\0') { + *buf = end_word; + } else { + end_whitespace = end_word + 1 + strspn(end_word + 1, whitespace); + + for (p = end_word; p < end_whitespace; p++) { + *p = '\0'; + } + + *buf = end_whitespace; + } + + return begin_word; +} + + +/* Simplified version of skip_quoted without quote char + * and whitespace == delimiters */ +static char * +skip(char **buf, const char *delimiters) +{ + return skip_quoted(buf, delimiters, delimiters, 0); +} + + +/* Return HTTP header value, or NULL if not found. */ +static const char * +get_header(const struct mg_request_info *ri, const char *name) +{ + int i; + if (ri) { + for (i = 0; i < ri->num_headers; i++) { + if (!mg_strcasecmp(name, ri->http_headers[i].name)) { + return ri->http_headers[i].value; + } + } + } + + return NULL; +} + + +const char * +mg_get_header(const struct mg_connection *conn, const char *name) +{ + if (!conn) { + return NULL; + } + + return get_header(&conn->request_info, name); +} + + +/* A helper function for traversing a comma separated list of values. + * It returns a list pointer shifted to the next value, or NULL if the end + * of the list found. + * Value is stored in val vector. If value has form "x=y", then eq_val + * vector is initialized to point to the "y" part, and val vector length + * is adjusted to point only to "x". */ +static const char * +next_option(const char *list, struct vec *val, struct vec *eq_val) +{ + int end; + +reparse: + if (val == NULL || list == NULL || *list == '\0') { + /* End of the list */ + list = NULL; + } else { + /* Skip over leading LWS */ + while (*list == ' ' || *list == '\t') + list++; + + val->ptr = list; + if ((list = strchr(val->ptr, ',')) != NULL) { + /* Comma found. Store length and shift the list ptr */ + val->len = ((size_t)(list - val->ptr)); + list++; + } else { + /* This value is the last one */ + list = val->ptr + strlen(val->ptr); + val->len = ((size_t)(list - val->ptr)); + } + + /* Adjust length for trailing LWS */ + end = (int)val->len - 1; + while (end >= 0 && (val->ptr[end] == ' ' || val->ptr[end] == '\t')) + end--; + val->len = (size_t)(end + 1); + + if (val->len == 0) { + /* Ignore any empty entries. */ + goto reparse; + } + + if (eq_val != NULL) { + /* Value has form "x=y", adjust pointers and lengths + * so that val points to "x", and eq_val points to "y". */ + eq_val->len = 0; + eq_val->ptr = (const char *)memchr(val->ptr, '=', val->len); + if (eq_val->ptr != NULL) { + eq_val->ptr++; /* Skip over '=' character */ + eq_val->len = ((size_t)(val->ptr - eq_val->ptr)) + val->len; + val->len = ((size_t)(eq_val->ptr - val->ptr)) - 1; + } + } + } + + return list; +} + +/* A helper function for checking if a comma separated list of values contains + * the given option (case insensitvely). + * 'header' can be NULL, in which case false is returned. */ +static int +header_has_option(const char *header, const char *option) +{ + struct vec opt_vec; + struct vec eq_vec; + + assert(option != NULL); + assert(option[0] != '\0'); + + while ((header = next_option(header, &opt_vec, &eq_vec)) != NULL) { + if (mg_strncasecmp(option, opt_vec.ptr, opt_vec.len) == 0) + return 1; + } + + return 0; +} + +/* Perform case-insensitive match of string against pattern */ +static int +match_prefix(const char *pattern, size_t pattern_len, const char *str) +{ + const char *or_str; + size_t i; + int j, len, res; + + if ((or_str = (const char *)memchr(pattern, '|', pattern_len)) != NULL) { + res = match_prefix(pattern, (size_t)(or_str - pattern), str); + return res > 0 ? res : match_prefix(or_str + 1, + (size_t)((pattern + pattern_len) + - (or_str + 1)), + str); + } + + for (i = 0, j = 0; i < pattern_len; i++, j++) { + if (pattern[i] == '?' && str[j] != '\0') { + continue; + } else if (pattern[i] == '$') { + return str[j] == '\0' ? j : -1; + } else if (pattern[i] == '*') { + i++; + if (pattern[i] == '*') { + i++; + len = (int)strlen(str + j); + } else { + len = (int)strcspn(str + j, "/"); + } + if (i == pattern_len) { + return j + len; + } + do { + res = match_prefix(pattern + i, pattern_len - i, str + j + len); + } while (res == -1 && len-- > 0); + return res == -1 ? -1 : j + res + len; + } else if (lowercase(&pattern[i]) != lowercase(&str[j])) { + return -1; + } + } + return j; +} + + +/* HTTP 1.1 assumes keep alive if "Connection:" header is not set + * This function must tolerate situations when connection info is not + * set up, for example if request parsing failed. */ +static int +should_keep_alive(const struct mg_connection *conn) +{ + if (conn != NULL) { + const char *http_version = conn->request_info.http_version; + const char *header = mg_get_header(conn, "Connection"); + if (conn->must_close || conn->internal_error || conn->status_code == 401 + || mg_strcasecmp(conn->ctx->config[ENABLE_KEEP_ALIVE], "yes") != 0 + || (header != NULL && !header_has_option(header, "keep-alive")) + || (header == NULL && http_version + && 0 != strcmp(http_version, "1.1"))) { + return 0; + } + return 1; + } + return 0; +} + + +static int +should_decode_url(const struct mg_connection *conn) +{ + if (!conn || !conn->ctx) { + return 0; + } + + return (mg_strcasecmp(conn->ctx->config[DECODE_URL], "yes") == 0); +} + + +static const char * +suggest_connection_header(const struct mg_connection *conn) +{ + return should_keep_alive(conn) ? "keep-alive" : "close"; +} + + +static int +send_no_cache_header(struct mg_connection *conn) +{ + /* Send all current and obsolete cache opt-out directives. */ + return mg_printf(conn, + "Cache-Control: no-cache, no-store, " + "must-revalidate, private, max-age=0\r\n" + "Pragma: no-cache\r\n" + "Expires: 0\r\n"); +} + + +static int +send_static_cache_header(struct mg_connection *conn) +{ +#if !defined(NO_CACHING) + /* Read the server config to check how long a file may be cached. + * The configuration is in seconds. */ + int max_age = atoi(conn->ctx->config[STATIC_FILE_MAX_AGE]); + if (max_age <= 0) { + /* 0 means "do not cache". All values <0 are reserved + * and may be used differently in the future. */ + /* If a file should not be cached, do not only send + * max-age=0, but also pragmas and Expires headers. */ + return send_no_cache_header(conn); + } + + /* Use "Cache-Control: max-age" instead of "Expires" header. + * Reason: see https://www.mnot.net/blog/2007/05/15/expires_max-age */ + /* See also https://www.mnot.net/cache_docs/ */ + /* According to RFC 2616, Section 14.21, caching times should not exceed + * one year. A year with 365 days corresponds to 31536000 seconds, a leap + * year to 31622400 seconds. For the moment, we just send whatever has + * been configured, still the behavior for >1 year should be considered + * as undefined. */ + return mg_printf(conn, "Cache-Control: max-age=%u\r\n", (unsigned)max_age); +#else /* NO_CACHING */ + return send_no_cache_header(conn); +#endif /* !NO_CACHING */ +} + + +static void handle_file_based_request(struct mg_connection *conn, + const char *path, + struct file *filep); + +static int +mg_stat(struct mg_connection *conn, const char *path, struct file *filep); + + +const char * +mg_get_response_code_text(struct mg_connection *conn, int response_code) +{ + /* See IANA HTTP status code assignment: + * http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml + */ + + switch (response_code) { + /* RFC2616 Section 10.1 - Informational 1xx */ + case 100: + return "Continue"; /* RFC2616 Section 10.1.1 */ + case 101: + return "Switching Protocols"; /* RFC2616 Section 10.1.2 */ + case 102: + return "Processing"; /* RFC2518 Section 10.1 */ + + /* RFC2616 Section 10.2 - Successful 2xx */ + case 200: + return "OK"; /* RFC2616 Section 10.2.1 */ + case 201: + return "Created"; /* RFC2616 Section 10.2.2 */ + case 202: + return "Accepted"; /* RFC2616 Section 10.2.3 */ + case 203: + return "Non-Authoritative Information"; /* RFC2616 Section 10.2.4 */ + case 204: + return "No Content"; /* RFC2616 Section 10.2.5 */ + case 205: + return "Reset Content"; /* RFC2616 Section 10.2.6 */ + case 206: + return "Partial Content"; /* RFC2616 Section 10.2.7 */ + case 207: + return "Multi-Status"; /* RFC2518 Section 10.2, RFC4918 Section 11.1 */ + case 208: + return "Already Reported"; /* RFC5842 Section 7.1 */ + + case 226: + return "IM used"; /* RFC3229 Section 10.4.1 */ + + /* RFC2616 Section 10.3 - Redirection 3xx */ + case 300: + return "Multiple Choices"; /* RFC2616 Section 10.3.1 */ + case 301: + return "Moved Permanently"; /* RFC2616 Section 10.3.2 */ + case 302: + return "Found"; /* RFC2616 Section 10.3.3 */ + case 303: + return "See Other"; /* RFC2616 Section 10.3.4 */ + case 304: + return "Not Modified"; /* RFC2616 Section 10.3.5 */ + case 305: + return "Use Proxy"; /* RFC2616 Section 10.3.6 */ + case 307: + return "Temporary Redirect"; /* RFC2616 Section 10.3.8 */ + case 308: + return "Permanent Redirect"; /* RFC7238 Section 3 */ + + /* RFC2616 Section 10.4 - Client Error 4xx */ + case 400: + return "Bad Request"; /* RFC2616 Section 10.4.1 */ + case 401: + return "Unauthorized"; /* RFC2616 Section 10.4.2 */ + case 402: + return "Payment Required"; /* RFC2616 Section 10.4.3 */ + case 403: + return "Forbidden"; /* RFC2616 Section 10.4.4 */ + case 404: + return "Not Found"; /* RFC2616 Section 10.4.5 */ + case 405: + return "Method Not Allowed"; /* RFC2616 Section 10.4.6 */ + case 406: + return "Not Acceptable"; /* RFC2616 Section 10.4.7 */ + case 407: + return "Proxy Authentication Required"; /* RFC2616 Section 10.4.8 */ + case 408: + return "Request Time-out"; /* RFC2616 Section 10.4.9 */ + case 409: + return "Conflict"; /* RFC2616 Section 10.4.10 */ + case 410: + return "Gone"; /* RFC2616 Section 10.4.11 */ + case 411: + return "Length Required"; /* RFC2616 Section 10.4.12 */ + case 412: + return "Precondition Failed"; /* RFC2616 Section 10.4.13 */ + case 413: + return "Request Entity Too Large"; /* RFC2616 Section 10.4.14 */ + case 414: + return "Request-URI Too Large"; /* RFC2616 Section 10.4.15 */ + case 415: + return "Unsupported Media Type"; /* RFC2616 Section 10.4.16 */ + case 416: + return "Requested range not satisfiable"; /* RFC2616 Section 10.4.17 */ + case 417: + return "Expectation Failed"; /* RFC2616 Section 10.4.18 */ + + case 421: + return "Misdirected Request"; /* RFC7540 Section 9.1.2 */ + case 422: + return "Unproccessable entity"; /* RFC2518 Section 10.3, RFC4918 + * Section 11.2 */ + case 423: + return "Locked"; /* RFC2518 Section 10.4, RFC4918 Section 11.3 */ + case 424: + return "Failed Dependency"; /* RFC2518 Section 10.5, RFC4918 + * Section 11.4 */ + + case 426: + return "Upgrade Required"; /* RFC 2817 Section 4 */ + + case 428: + return "Precondition Required"; /* RFC 6585, Section 3 */ + case 429: + return "Too Many Requests"; /* RFC 6585, Section 4 */ + + case 431: + return "Request Header Fields Too Large"; /* RFC 6585, Section 5 */ + + case 451: + return "Unavailable For Legal Reasons"; /* draft-tbray-http-legally-restricted-status-05, + * Section 3 */ + + /* RFC2616 Section 10.5 - Server Error 5xx */ + case 500: + return "Internal Server Error"; /* RFC2616 Section 10.5.1 */ + case 501: + return "Not Implemented"; /* RFC2616 Section 10.5.2 */ + case 502: + return "Bad Gateway"; /* RFC2616 Section 10.5.3 */ + case 503: + return "Service Unavailable"; /* RFC2616 Section 10.5.4 */ + case 504: + return "Gateway Time-out"; /* RFC2616 Section 10.5.5 */ + case 505: + return "HTTP Version not supported"; /* RFC2616 Section 10.5.6 */ + case 506: + return "Variant Also Negotiates"; /* RFC 2295, Section 8.1 */ + case 507: + return "Insufficient Storage"; /* RFC2518 Section 10.6, RFC4918 + * Section 11.5 */ + case 508: + return "Loop Detected"; /* RFC5842 Section 7.1 */ + + case 510: + return "Not Extended"; /* RFC 2774, Section 7 */ + case 511: + return "Network Authentication Required"; /* RFC 6585, Section 6 */ + + /* Other status codes, not shown in the IANA HTTP status code assignment. + * E.g., "de facto" standards due to common use, ... */ + case 418: + return "I am a teapot"; /* RFC2324 Section 2.3.2 */ + case 419: + return "Authentication Timeout"; /* common use */ + case 420: + return "Enhance Your Calm"; /* common use */ + case 440: + return "Login Timeout"; /* common use */ + case 509: + return "Bandwidth Limit Exceeded"; /* common use */ + + default: + /* This error code is unknown. This should not happen. */ + if (conn) { + mg_cry(conn, "Unknown HTTP response code: %u", response_code); + } + + /* Return at least a category according to RFC 2616 Section 10. */ + if (response_code >= 100 && response_code < 200) { + /* Unknown informational status code */ + return "Information"; + } + if (response_code >= 200 && response_code < 300) { + /* Unknown success code */ + return "Success"; + } + if (response_code >= 300 && response_code < 400) { + /* Unknown redirection code */ + return "Redirection"; + } + if (response_code >= 400 && response_code < 500) { + /* Unknown request error code */ + return "Client Error"; + } + if (response_code >= 500 && response_code < 600) { + /* Unknown server error code */ + return "Server Error"; + } + + /* Response code not even within reasonable range */ + return ""; + } +} + + +static void send_http_error(struct mg_connection *, + int, + PRINTF_FORMAT_STRING(const char *fmt), + ...) PRINTF_ARGS(3, 4); + +static void +send_http_error(struct mg_connection *conn, int status, const char *fmt, ...) +{ + char buf[MG_BUF_LEN]; + va_list ap; + int len, i, page_handler_found, scope, truncated; + char date[64]; + time_t curtime = time(NULL); + const char *error_handler = NULL; + struct file error_page_file = STRUCT_FILE_INITIALIZER; + const char *error_page_file_ext, *tstr; + + const char *status_text = mg_get_response_code_text(conn, status); + + if (conn == NULL) { + return; + } + + conn->status_code = status; + if (conn->in_error_handler || conn->ctx->callbacks.http_error == NULL + || conn->ctx->callbacks.http_error(conn, status)) { + if (!conn->in_error_handler) { + /* Send user defined error pages, if defined */ + error_handler = conn->ctx->config[ERROR_PAGES]; + error_page_file_ext = conn->ctx->config[INDEX_FILES]; + page_handler_found = 0; + if (error_handler != NULL) { + for (scope = 1; (scope <= 3) && !page_handler_found; scope++) { + switch (scope) { + case 1: /* Handler for specific error, e.g. 404 error */ + mg_snprintf(conn, + &truncated, + buf, + sizeof(buf) - 32, + "%serror%03u.", + error_handler, + status); + break; + case 2: /* Handler for error group, e.g., 5xx error handler + * for all server errors (500-599) */ + mg_snprintf(conn, + &truncated, + buf, + sizeof(buf) - 32, + "%serror%01uxx.", + error_handler, + status / 100); + break; + default: /* Handler for all errors */ + mg_snprintf(conn, + &truncated, + buf, + sizeof(buf) - 32, + "%serror.", + error_handler); + break; + } + + /* String truncation in buf may only occur if error_handler + * is too long. This string is from the config, not from a + * client. */ + (void)truncated; + + len = (int)strlen(buf); + + tstr = strchr(error_page_file_ext, '.'); + + while (tstr) { + for (i = 1; i < 32 && tstr[i] != 0 && tstr[i] != ','; + i++) + buf[len + i - 1] = tstr[i]; + buf[len + i - 1] = 0; + if (mg_stat(conn, buf, &error_page_file)) { + page_handler_found = 1; + break; + } + tstr = strchr(tstr + i, '.'); + } + } + } + + if (page_handler_found) { + conn->in_error_handler = 1; + handle_file_based_request(conn, buf, &error_page_file); + conn->in_error_handler = 0; + return; + } + } + + /* No custom error page. Send default error page. */ + gmt_time_string(date, sizeof(date), &curtime); + + conn->must_close = 1; + mg_printf(conn, "HTTP/1.1 %d %s\r\n", status, status_text); + send_no_cache_header(conn); + mg_printf(conn, + "Date: %s\r\n" + "Connection: close\r\n\r\n", + date); + + /* Errors 1xx, 204 and 304 MUST NOT send a body */ + if (status > 199 && status != 204 && status != 304) { + + mg_printf(conn, "Error %d: %s\n", status, status_text); + + if (fmt != NULL) { + va_start(ap, fmt); + mg_vsnprintf(conn, NULL, buf, sizeof(buf), fmt, ap); + va_end(ap); + mg_write(conn, buf, strlen(buf)); + DEBUG_TRACE("Error %i - [%s]", status, buf); + } + + } else { + /* No body allowed. Close the connection. */ + DEBUG_TRACE("Error %i", status); + } + } +} + +#if defined(_WIN32) && !defined(__SYMBIAN32__) +/* Create substitutes for POSIX functions in Win32. */ + +#if defined(__MINGW32__) +/* Show no warning in case system functions are not used. */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" +#endif + + +static int +pthread_mutex_init(pthread_mutex_t *mutex, void *unused) +{ + (void)unused; + *mutex = CreateMutex(NULL, FALSE, NULL); + return *mutex == NULL ? -1 : 0; +} + + +static int +pthread_mutex_destroy(pthread_mutex_t *mutex) +{ + return CloseHandle(*mutex) == 0 ? -1 : 0; +} + + +static int +pthread_mutex_lock(pthread_mutex_t *mutex) +{ + return WaitForSingleObject(*mutex, INFINITE) == WAIT_OBJECT_0 ? 0 : -1; +} + + +#ifdef ENABLE_UNUSED_PTHREAD_FUNCTIONS +static int +pthread_mutex_trylock(pthread_mutex_t *mutex) +{ + switch (WaitForSingleObject(*mutex, 0)) { + case WAIT_OBJECT_0: + return 0; + case WAIT_TIMEOUT: + return -2; /* EBUSY */ + } + return -1; +} +#endif + + +static int +pthread_mutex_unlock(pthread_mutex_t *mutex) +{ + return ReleaseMutex(*mutex) == 0 ? -1 : 0; +} + + +#ifndef WIN_PTHREADS_TIME_H +static int +clock_gettime(clockid_t clk_id, struct timespec *tp) +{ + FILETIME ft; + ULARGE_INTEGER li; + BOOL ok = FALSE; + double d; + static double perfcnt_per_sec = 0.0; + + if (tp) { + memset(tp, 0, sizeof(*tp)); + if (clk_id == CLOCK_REALTIME) { + GetSystemTimeAsFileTime(&ft); + li.LowPart = ft.dwLowDateTime; + li.HighPart = ft.dwHighDateTime; + li.QuadPart -= 116444736000000000; /* 1.1.1970 in filedate */ + tp->tv_sec = (time_t)(li.QuadPart / 10000000); + tp->tv_nsec = (long)(li.QuadPart % 10000000) * 100; + ok = TRUE; + } else if (clk_id == CLOCK_MONOTONIC) { + if (perfcnt_per_sec == 0.0) { + QueryPerformanceFrequency((LARGE_INTEGER *)&li); + perfcnt_per_sec = 1.0 / li.QuadPart; + } + if (perfcnt_per_sec != 0.0) { + QueryPerformanceCounter((LARGE_INTEGER *)&li); + d = li.QuadPart * perfcnt_per_sec; + tp->tv_sec = (time_t)d; + d -= tp->tv_sec; + tp->tv_nsec = (long)(d * 1.0E9); + ok = TRUE; + } + } + } + + return ok ? 0 : -1; +} +#endif + + +static int +pthread_cond_init(pthread_cond_t *cv, const void *unused) +{ + (void)unused; + InitializeCriticalSection(&cv->threadIdSec); + cv->waitingthreadcount = 0; + cv->waitingthreadhdls = + (pthread_t *)mg_calloc(MAX_WORKER_THREADS, sizeof(pthread_t)); + return (cv->waitingthreadhdls != NULL) ? 0 : -1; +} + + +static int +pthread_cond_timedwait(pthread_cond_t *cv, + pthread_mutex_t *mutex, + const struct timespec *abstime) +{ + struct mg_workerTLS *tls = + (struct mg_workerTLS *)pthread_getspecific(sTlsKey); + int ok; + struct timespec tsnow; + int64_t nsnow, nswaitabs, nswaitrel; + DWORD mswaitrel; + + EnterCriticalSection(&cv->threadIdSec); + assert(cv->waitingthreadcount < MAX_WORKER_THREADS); + cv->waitingthreadhdls[cv->waitingthreadcount] = + tls->pthread_cond_helper_mutex; + cv->waitingthreadcount++; + LeaveCriticalSection(&cv->threadIdSec); + + if (abstime) { + clock_gettime(CLOCK_REALTIME, &tsnow); + nsnow = (((int64_t)tsnow.tv_sec) * 1000000000) + tsnow.tv_nsec; + nswaitabs = + (((int64_t)abstime->tv_sec) * 1000000000) + abstime->tv_nsec; + nswaitrel = nswaitabs - nsnow; + if (nswaitrel < 0) { + nswaitrel = 0; + } + mswaitrel = (DWORD)(nswaitrel / 1000000); + } else { + mswaitrel = INFINITE; + } + + pthread_mutex_unlock(mutex); + ok = (WAIT_OBJECT_0 + == WaitForSingleObject(tls->pthread_cond_helper_mutex, mswaitrel)); + pthread_mutex_lock(mutex); + + return ok ? 0 : -1; +} + + +static int +pthread_cond_wait(pthread_cond_t *cv, pthread_mutex_t *mutex) +{ + return pthread_cond_timedwait(cv, mutex, NULL); +} + + +static int +pthread_cond_signal(pthread_cond_t *cv) +{ + int i; + HANDLE wkup = NULL; + BOOL ok = FALSE; + + EnterCriticalSection(&cv->threadIdSec); + if (cv->waitingthreadcount) { + wkup = cv->waitingthreadhdls[0]; + ok = SetEvent(wkup); + + for (i = 1; i < cv->waitingthreadcount; i++) { + cv->waitingthreadhdls[i - 1] = cv->waitingthreadhdls[i]; + } + cv->waitingthreadcount--; + + assert(ok); + } + LeaveCriticalSection(&cv->threadIdSec); + + return ok ? 0 : 1; +} + + +static int +pthread_cond_broadcast(pthread_cond_t *cv) +{ + EnterCriticalSection(&cv->threadIdSec); + while (cv->waitingthreadcount) { + pthread_cond_signal(cv); + } + LeaveCriticalSection(&cv->threadIdSec); + + return 0; +} + + +static int +pthread_cond_destroy(pthread_cond_t *cv) +{ + EnterCriticalSection(&cv->threadIdSec); + assert(cv->waitingthreadcount == 0); + mg_free(cv->waitingthreadhdls); + cv->waitingthreadhdls = 0; + LeaveCriticalSection(&cv->threadIdSec); + DeleteCriticalSection(&cv->threadIdSec); + + return 0; +} + + +#if defined(__MINGW32__) +/* Enable unused function warning again */ +#pragma GCC diagnostic pop +#endif + + +/* For Windows, change all slashes to backslashes in path names. */ +static void +change_slashes_to_backslashes(char *path) +{ + int i; + + for (i = 0; path[i] != '\0'; i++) { + if (path[i] == '/') { + path[i] = '\\'; + } + + /* remove double backslash (check i > 0 to preserve UNC paths, + * like \\server\file.txt) */ + if ((path[i] == '\\') && (i > 0)) { + while (path[i + 1] == '\\' || path[i + 1] == '/') { + (void)memmove(path + i + 1, path + i + 2, strlen(path + i + 1)); + } + } + } +} + + +static int +mg_wcscasecmp(const wchar_t *s1, const wchar_t *s2) +{ + int diff; + + do { + diff = tolower(*s1) - tolower(*s2); + s1++; + s2++; + } while (diff == 0 && s1[-1] != '\0'); + + return diff; +} + + +/* Encode 'path' which is assumed UTF-8 string, into UNICODE string. + * wbuf and wbuf_len is a target buffer and its length. */ +static void +path_to_unicode(const struct mg_connection *conn, + const char *path, + wchar_t *wbuf, + size_t wbuf_len) +{ + char buf[PATH_MAX], buf2[PATH_MAX]; + wchar_t wbuf2[MAX_PATH + 1]; + DWORD long_len, err; + int (*fcompare)(const wchar_t *, const wchar_t *) = mg_wcscasecmp; + + mg_strlcpy(buf, path, sizeof(buf)); + change_slashes_to_backslashes(buf); + + /* Convert to Unicode and back. If doubly-converted string does not + * match the original, something is fishy, reject. */ + memset(wbuf, 0, wbuf_len * sizeof(wchar_t)); + MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, (int)wbuf_len); + WideCharToMultiByte( + CP_UTF8, 0, wbuf, (int)wbuf_len, buf2, sizeof(buf2), NULL, NULL); + if (strcmp(buf, buf2) != 0) { + wbuf[0] = L'\0'; + } + + /* TODO: Add a configuration to switch between case sensitive and + * case insensitive URIs for Windows server. */ + /* + if (conn) { + if (conn->ctx->config[WINDOWS_CASE_SENSITIVE]) { + fcompare = wcscmp; + } + } + */ + (void)conn; /* conn is currently unused */ + + /* Only accept a full file path, not a Windows short (8.3) path. */ + memset(wbuf2, 0, ARRAY_SIZE(wbuf2) * sizeof(wchar_t)); + long_len = GetLongPathNameW(wbuf, wbuf2, ARRAY_SIZE(wbuf2) - 1); + if (long_len == 0) { + err = GetLastError(); + if (err == ERROR_FILE_NOT_FOUND) { + /* File does not exist. This is not always a problem here. */ + return; + } + } + if ((long_len >= ARRAY_SIZE(wbuf2)) || (fcompare(wbuf, wbuf2) != 0)) { + /* Short name is used. */ + wbuf[0] = L'\0'; + } +} + + +#if defined(_WIN32_WCE) +/* Create substitutes for POSIX functions in Win32. */ + +#if defined(__MINGW32__) +/* Show no warning in case system functions are not used. */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" +#endif + + +static time_t +time(time_t *ptime) +{ + time_t t; + SYSTEMTIME st; + FILETIME ft; + + GetSystemTime(&st); + SystemTimeToFileTime(&st, &ft); + t = SYS2UNIX_TIME(ft.dwLowDateTime, ft.dwHighDateTime); + + if (ptime != NULL) { + *ptime = t; + } + + return t; +} + + +static struct tm * +localtime(const time_t *ptime, struct tm *ptm) +{ + int64_t t = ((int64_t)*ptime) * RATE_DIFF + EPOCH_DIFF; + FILETIME ft, lft; + SYSTEMTIME st; + TIME_ZONE_INFORMATION tzinfo; + + if (ptm == NULL) { + return NULL; + } + + *(int64_t *)&ft = t; + FileTimeToLocalFileTime(&ft, &lft); + FileTimeToSystemTime(&lft, &st); + ptm->tm_year = st.wYear - 1900; + ptm->tm_mon = st.wMonth - 1; + ptm->tm_wday = st.wDayOfWeek; + ptm->tm_mday = st.wDay; + ptm->tm_hour = st.wHour; + ptm->tm_min = st.wMinute; + ptm->tm_sec = st.wSecond; + ptm->tm_yday = 0; /* hope nobody uses this */ + ptm->tm_isdst = + GetTimeZoneInformation(&tzinfo) == TIME_ZONE_ID_DAYLIGHT ? 1 : 0; + + return ptm; +} + + +static struct tm * +gmtime(const time_t *ptime, struct tm *ptm) +{ + /* FIXME(lsm): fix this. */ + return localtime(ptime, ptm); +} + + +static size_t +strftime(char *dst, size_t dst_size, const char *fmt, const struct tm *tm) +{ + (void)mg_snprintf(NULL, dst, dst_size, "implement strftime() for WinCE"); + return 0; +} + + +#if defined(__MINGW32__) +/* Enable unused function warning again */ +#pragma GCC diagnostic pop +#endif + +#endif + + +/* Windows happily opens files with some garbage at the end of file name. + * For example, fopen("a.cgi ", "r") on Windows successfully opens + * "a.cgi", despite one would expect an error back. + * This function returns non-0 if path ends with some garbage. */ +static int +path_cannot_disclose_cgi(const char *path) +{ + static const char *allowed_last_characters = "_-"; + int last = path[strlen(path) - 1]; + return isalnum(last) || strchr(allowed_last_characters, last) != NULL; +} + + +static int +mg_stat(struct mg_connection *conn, const char *path, struct file *filep) +{ + wchar_t wbuf[PATH_MAX]; + WIN32_FILE_ATTRIBUTE_DATA info; + time_t creation_time; + + if (!filep) { + return 0; + } + memset(filep, 0, sizeof(*filep)); + + if (conn && is_file_in_memory(conn, path, filep)) { + /* filep->is_directory = 0; filep->gzipped = 0; .. already done by + * memset */ + filep->last_modified = time(NULL); + /* last_modified = now ... assumes the file may change during runtime, + * so every mg_fopen call may return different data */ + /* last_modified = conn->ctx.start_time; + * May be used it the data does not change during runtime. This allows + * browser caching. Since we do not know, we have to assume the file + * in memory may change. */ + return 1; + } + + path_to_unicode(conn, path, wbuf, ARRAY_SIZE(wbuf)); + if (GetFileAttributesExW(wbuf, GetFileExInfoStandard, &info) != 0) { + filep->size = MAKEUQUAD(info.nFileSizeLow, info.nFileSizeHigh); + filep->last_modified = + SYS2UNIX_TIME(info.ftLastWriteTime.dwLowDateTime, + info.ftLastWriteTime.dwHighDateTime); + + /* On Windows, the file creation time can be higher than the + * modification time, e.g. when a file is copied. + * Since the Last-Modified timestamp is used for caching + * it should be based on the most recent timestamp. */ + creation_time = SYS2UNIX_TIME(info.ftCreationTime.dwLowDateTime, + info.ftCreationTime.dwHighDateTime); + if (creation_time > filep->last_modified) { + filep->last_modified = creation_time; + } + + filep->is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; + /* If file name is fishy, reset the file structure and return + * error. + * Note it is important to reset, not just return the error, cause + * functions like is_file_opened() check the struct. */ + if (!filep->is_directory && !path_cannot_disclose_cgi(path)) { + memset(filep, 0, sizeof(*filep)); + return 0; + } + + return 1; + } + + return 0; +} + + +static int +mg_remove(const struct mg_connection *conn, const char *path) +{ + wchar_t wbuf[PATH_MAX]; + path_to_unicode(conn, path, wbuf, ARRAY_SIZE(wbuf)); + return DeleteFileW(wbuf) ? 0 : -1; +} + + +static int +mg_mkdir(const struct mg_connection *conn, const char *path, int mode) +{ + wchar_t wbuf[PATH_MAX]; + (void)mode; + path_to_unicode(conn, path, wbuf, ARRAY_SIZE(wbuf)); + return CreateDirectoryW(wbuf, NULL) ? 0 : -1; +} + + +/* Create substitutes for POSIX functions in Win32. */ + +#if defined(__MINGW32__) +/* Show no warning in case system functions are not used. */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" +#endif + + +/* Implementation of POSIX opendir/closedir/readdir for Windows. */ +static DIR * +mg_opendir(const struct mg_connection *conn, const char *name) +{ + DIR *dir = NULL; + wchar_t wpath[PATH_MAX]; + DWORD attrs; + + if (name == NULL) { + SetLastError(ERROR_BAD_ARGUMENTS); + } else if ((dir = (DIR *)mg_malloc(sizeof(*dir))) == NULL) { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + } else { + path_to_unicode(conn, name, wpath, ARRAY_SIZE(wpath)); + attrs = GetFileAttributesW(wpath); + if (attrs != 0xFFFFFFFF && ((attrs & FILE_ATTRIBUTE_DIRECTORY) + == FILE_ATTRIBUTE_DIRECTORY)) { + (void)wcscat(wpath, L"\\*"); + dir->handle = FindFirstFileW(wpath, &dir->info); + dir->result.d_name[0] = '\0'; + } else { + mg_free(dir); + dir = NULL; + } + } + + return dir; +} + + +static int +mg_closedir(DIR *dir) +{ + int result = 0; + + if (dir != NULL) { + if (dir->handle != INVALID_HANDLE_VALUE) + result = FindClose(dir->handle) ? 0 : -1; + + mg_free(dir); + } else { + result = -1; + SetLastError(ERROR_BAD_ARGUMENTS); + } + + return result; +} + + +static struct dirent * +mg_readdir(DIR *dir) +{ + struct dirent *result = 0; + + if (dir) { + if (dir->handle != INVALID_HANDLE_VALUE) { + result = &dir->result; + (void)WideCharToMultiByte(CP_UTF8, + 0, + dir->info.cFileName, + -1, + result->d_name, + sizeof(result->d_name), + NULL, + NULL); + + if (!FindNextFileW(dir->handle, &dir->info)) { + (void)FindClose(dir->handle); + dir->handle = INVALID_HANDLE_VALUE; + } + + } else { + SetLastError(ERROR_FILE_NOT_FOUND); + } + } else { + SetLastError(ERROR_BAD_ARGUMENTS); + } + + return result; +} + + +#ifndef HAVE_POLL +static int +poll(struct pollfd *pfd, unsigned int n, int milliseconds) +{ + struct timeval tv; + fd_set set; + unsigned int i; + int result; + SOCKET maxfd = 0; + + memset(&tv, 0, sizeof(tv)); + tv.tv_sec = milliseconds / 1000; + tv.tv_usec = (milliseconds % 1000) * 1000; + FD_ZERO(&set); + + for (i = 0; i < n; i++) { + FD_SET((SOCKET)pfd[i].fd, &set); + pfd[i].revents = 0; + + if (pfd[i].fd > maxfd) { + maxfd = pfd[i].fd; + } + } + + if ((result = select((int)maxfd + 1, &set, NULL, NULL, &tv)) > 0) { + for (i = 0; i < n; i++) { + if (FD_ISSET(pfd[i].fd, &set)) { + pfd[i].revents = POLLIN; + } + } + } + + return result; +} +#endif /* HAVE_POLL */ + +#if defined(__MINGW32__) +/* Enable unused function warning again */ +#pragma GCC diagnostic pop +#endif + + +static void +set_close_on_exec(SOCKET sock, struct mg_connection *conn /* may be null */) +{ + (void)conn; /* Unused. */ + (void)SetHandleInformation((HANDLE)(intptr_t)sock, HANDLE_FLAG_INHERIT, 0); +} + + +int +mg_start_thread(mg_thread_func_t f, void *p) +{ +#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) + /* Compile-time option to control stack size, e.g. -DUSE_STACK_SIZE=16384 + */ + return ((_beginthread((void(__cdecl *)(void *))f, USE_STACK_SIZE, p) + == ((uintptr_t)(-1L))) + ? -1 + : 0); +#else + return ( + (_beginthread((void(__cdecl *)(void *))f, 0, p) == ((uintptr_t)(-1L))) + ? -1 + : 0); +#endif /* defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) */ +} + + +/* Start a thread storing the thread context. */ +static int +mg_start_thread_with_id(unsigned(__stdcall *f)(void *), + void *p, + pthread_t *threadidptr) +{ + uintptr_t uip; + HANDLE threadhandle; + int result = -1; + + uip = _beginthreadex(NULL, 0, (unsigned(__stdcall *)(void *))f, p, 0, NULL); + threadhandle = (HANDLE)uip; + if ((uip != (uintptr_t)(-1L)) && (threadidptr != NULL)) { + *threadidptr = threadhandle; + result = 0; + } + + return result; +} + + +/* Wait for a thread to finish. */ +static int +mg_join_thread(pthread_t threadid) +{ + int result; + DWORD dwevent; + + result = -1; + dwevent = WaitForSingleObject(threadid, INFINITE); + if (dwevent == WAIT_FAILED) { + DEBUG_TRACE("WaitForSingleObject() failed, error %d", ERRNO); + } else { + if (dwevent == WAIT_OBJECT_0) { + CloseHandle(threadid); + result = 0; + } + } + + return result; +} + +#if !defined(NO_SSL_DL) +/* Create substitutes for POSIX functions in Win32. */ + +#if defined(__MINGW32__) +/* Show no warning in case system functions are not used. */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" +#endif + + +static HANDLE +dlopen(const char *dll_name, int flags) +{ + wchar_t wbuf[PATH_MAX]; + (void)flags; + path_to_unicode(NULL, dll_name, wbuf, ARRAY_SIZE(wbuf)); + return LoadLibraryW(wbuf); +} + + +static int +dlclose(void *handle) +{ + int result; + + if (FreeLibrary((HMODULE)handle) != 0) { + result = 0; + } else { + result = -1; + } + + return result; +} + + +#if defined(__MINGW32__) +/* Enable unused function warning again */ +#pragma GCC diagnostic pop +#endif + +#endif + + +#if !defined(NO_CGI) +#define SIGKILL (0) + +static int +kill(pid_t pid, int sig_num) +{ + (void)TerminateProcess((HANDLE)pid, (UINT)sig_num); + (void)CloseHandle((HANDLE)pid); + return 0; +} + + +static void +trim_trailing_whitespaces(char *s) +{ + char *e = s + strlen(s) - 1; + while (e > s && isspace(*(unsigned char *)e)) { + *e-- = '\0'; + } +} + + +static pid_t +spawn_process(struct mg_connection *conn, + const char *prog, + char *envblk, + char *envp[], + int fdin[2], + int fdout[2], + int fderr[2], + const char *dir) +{ + HANDLE me; + char *p, *interp, full_interp[PATH_MAX], full_dir[PATH_MAX], + cmdline[PATH_MAX], buf[PATH_MAX]; + int truncated; + struct file file = STRUCT_FILE_INITIALIZER; + STARTUPINFOA si; + PROCESS_INFORMATION pi = {0}; + + (void)envp; + + memset(&si, 0, sizeof(si)); + si.cb = sizeof(si); + + si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; + si.wShowWindow = SW_HIDE; + + me = GetCurrentProcess(); + DuplicateHandle(me, + (HANDLE)_get_osfhandle(fdin[0]), + me, + &si.hStdInput, + 0, + TRUE, + DUPLICATE_SAME_ACCESS); + DuplicateHandle(me, + (HANDLE)_get_osfhandle(fdout[1]), + me, + &si.hStdOutput, + 0, + TRUE, + DUPLICATE_SAME_ACCESS); + DuplicateHandle(me, + (HANDLE)_get_osfhandle(fderr[1]), + me, + &si.hStdError, + 0, + TRUE, + DUPLICATE_SAME_ACCESS); + + /* Mark handles that should not be inherited. See + * https://msdn.microsoft.com/en-us/library/windows/desktop/ms682499%28v=vs.85%29.aspx + */ + SetHandleInformation((HANDLE)_get_osfhandle(fdin[1]), + HANDLE_FLAG_INHERIT, + 0); + SetHandleInformation((HANDLE)_get_osfhandle(fdout[0]), + HANDLE_FLAG_INHERIT, + 0); + SetHandleInformation((HANDLE)_get_osfhandle(fderr[0]), + HANDLE_FLAG_INHERIT, + 0); + + /* If CGI file is a script, try to read the interpreter line */ + interp = conn->ctx->config[CGI_INTERPRETER]; + if (interp == NULL) { + buf[0] = buf[1] = '\0'; + + /* Read the first line of the script into the buffer */ + mg_snprintf( + conn, &truncated, cmdline, sizeof(cmdline), "%s/%s", dir, prog); + + if (truncated) { + pi.hProcess = (pid_t)-1; + goto spawn_cleanup; + } + + if (mg_fopen(conn, cmdline, "r", &file)) { + p = (char *)file.membuf; + mg_fgets(buf, sizeof(buf), &file, &p); + mg_fclose(&file); + buf[sizeof(buf) - 1] = '\0'; + } + + if (buf[0] == '#' && buf[1] == '!') { + trim_trailing_whitespaces(buf + 2); + } else { + buf[2] = '\0'; + } + interp = buf + 2; + } + + if (interp[0] != '\0') { + GetFullPathNameA(interp, sizeof(full_interp), full_interp, NULL); + interp = full_interp; + } + GetFullPathNameA(dir, sizeof(full_dir), full_dir, NULL); + + if (interp[0] != '\0') { + mg_snprintf(conn, + &truncated, + cmdline, + sizeof(cmdline), + "\"%s\" \"%s\\%s\"", + interp, + full_dir, + prog); + } else { + mg_snprintf(conn, + &truncated, + cmdline, + sizeof(cmdline), + "\"%s\\%s\"", + full_dir, + prog); + } + + if (truncated) { + pi.hProcess = (pid_t)-1; + goto spawn_cleanup; + } + + DEBUG_TRACE("Running [%s]", cmdline); + if (CreateProcessA(NULL, + cmdline, + NULL, + NULL, + TRUE, + CREATE_NEW_PROCESS_GROUP, + envblk, + NULL, + &si, + &pi) == 0) { + mg_cry( + conn, "%s: CreateProcess(%s): %ld", __func__, cmdline, (long)ERRNO); + pi.hProcess = (pid_t)-1; + /* goto spawn_cleanup; */ + } + +spawn_cleanup: + (void)CloseHandle(si.hStdOutput); + (void)CloseHandle(si.hStdError); + (void)CloseHandle(si.hStdInput); + if (pi.hThread != NULL) { + (void)CloseHandle(pi.hThread); + } + + return (pid_t)pi.hProcess; +} +#endif /* !NO_CGI */ + + +static int +set_non_blocking_mode(SOCKET sock) +{ + unsigned long on = 1; + return ioctlsocket(sock, (long)FIONBIO, &on); +} + +#else + +static int +mg_stat(struct mg_connection *conn, const char *path, struct file *filep) +{ + struct stat st; + if (!filep) { + return 0; + } + memset(filep, 0, sizeof(*filep)); + + if (conn && is_file_in_memory(conn, path, filep)) { + return 1; + } + + if (0 == stat(path, &st)) { + filep->size = (uint64_t)(st.st_size); + filep->last_modified = st.st_mtime; + filep->is_directory = S_ISDIR(st.st_mode); + return 1; + } + + return 0; +} + + +static void +set_close_on_exec(SOCKET fd, struct mg_connection *conn /* may be null */) +{ + if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) { + if (conn) { + mg_cry(conn, + "%s: fcntl(F_SETFD FD_CLOEXEC) failed: %s", + __func__, + strerror(ERRNO)); + } + } +} + + +int +mg_start_thread(mg_thread_func_t func, void *param) +{ + pthread_t thread_id; + pthread_attr_t attr; + int result; + + (void)pthread_attr_init(&attr); + (void)pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + +#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) + /* Compile-time option to control stack size, + * e.g. -DUSE_STACK_SIZE=16384 */ + (void)pthread_attr_setstacksize(&attr, USE_STACK_SIZE); +#endif /* defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) */ + + result = pthread_create(&thread_id, &attr, func, param); + pthread_attr_destroy(&attr); + + return result; +} + + +/* Start a thread storing the thread context. */ +static int +mg_start_thread_with_id(mg_thread_func_t func, + void *param, + pthread_t *threadidptr) +{ + pthread_t thread_id; + pthread_attr_t attr; + int result; + + (void)pthread_attr_init(&attr); + +#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) + /* Compile-time option to control stack size, + * e.g. -DUSE_STACK_SIZE=16384 */ + (void)pthread_attr_setstacksize(&attr, USE_STACK_SIZE); +#endif /* defined(USE_STACK_SIZE) && USE_STACK_SIZE > 1 */ + + result = pthread_create(&thread_id, &attr, func, param); + pthread_attr_destroy(&attr); + if ((result == 0) && (threadidptr != NULL)) { + *threadidptr = thread_id; + } + return result; +} + + +/* Wait for a thread to finish. */ +static int +mg_join_thread(pthread_t threadid) +{ + int result; + + result = pthread_join(threadid, NULL); + return result; +} + + +#ifndef NO_CGI +static pid_t +spawn_process(struct mg_connection *conn, + const char *prog, + char *envblk, + char *envp[], + int fdin[2], + int fdout[2], + int fderr[2], + const char *dir) +{ + pid_t pid; + const char *interp; + + (void)envblk; + + if (conn == NULL) { + return 0; + } + + if ((pid = fork()) == -1) { + /* Parent */ + send_http_error(conn, + 500, + "Error: Creating CGI process\nfork(): %s", + strerror(ERRNO)); + } else if (pid == 0) { + /* Child */ + if (chdir(dir) != 0) { + mg_cry(conn, "%s: chdir(%s): %s", __func__, dir, strerror(ERRNO)); + } else if (dup2(fdin[0], 0) == -1) { + mg_cry(conn, + "%s: dup2(%d, 0): %s", + __func__, + fdin[0], + strerror(ERRNO)); + } else if (dup2(fdout[1], 1) == -1) { + mg_cry(conn, + "%s: dup2(%d, 1): %s", + __func__, + fdout[1], + strerror(ERRNO)); + } else if (dup2(fderr[1], 2) == -1) { + mg_cry(conn, + "%s: dup2(%d, 2): %s", + __func__, + fderr[1], + strerror(ERRNO)); + } else { + /* Keep stderr and stdout in two different pipes. + * Stdout will be sent back to the client, + * stderr should go into a server error log. */ + (void)close(fdin[0]); + (void)close(fdout[1]); + (void)close(fderr[1]); + + /* Close write end fdin and read end fdout and fderr */ + (void)close(fdin[1]); + (void)close(fdout[0]); + (void)close(fderr[0]); + + /* After exec, all signal handlers are restored to their default + * values, with one exception of SIGCHLD. According to + * POSIX.1-2001 and Linux's implementation, SIGCHLD's handler will + * leave unchanged after exec if it was set to be ignored. Restore + * it to default action. */ + signal(SIGCHLD, SIG_DFL); + + interp = conn->ctx->config[CGI_INTERPRETER]; + if (interp == NULL) { + (void)execle(prog, prog, NULL, envp); + mg_cry(conn, + "%s: execle(%s): %s", + __func__, + prog, + strerror(ERRNO)); + } else { + (void)execle(interp, interp, prog, NULL, envp); + mg_cry(conn, + "%s: execle(%s %s): %s", + __func__, + interp, + prog, + strerror(ERRNO)); + } + } + exit(EXIT_FAILURE); + } + + return pid; +} +#endif /* !NO_CGI */ + + +static int +set_non_blocking_mode(SOCKET sock) +{ + int flags; + + flags = fcntl(sock, F_GETFL, 0); + (void)fcntl(sock, F_SETFL, flags | O_NONBLOCK); + + return 0; +} +#endif /* _WIN32 */ +/* End of initial operating system specific define block. */ + + +/* Get a random number (independent of C rand function) */ +static uint64_t +get_random(void) +{ + static uint64_t lfsr = 0; /* Linear feedback shift register */ + static uint64_t lcg = 0; /* Linear congruential generator */ + struct timespec now; + + memset(&now, 0, sizeof(now)); + clock_gettime(CLOCK_MONOTONIC, &now); + + if (lfsr == 0) { + /* lfsr will be only 0 if has not been initialized, + * so this code is called only once. */ + lfsr = (((uint64_t)now.tv_sec) << 21) ^ ((uint64_t)now.tv_nsec) + ^ ((uint64_t)(ptrdiff_t)&now) ^ (((uint64_t)time(NULL)) << 33); + lcg = (((uint64_t)now.tv_sec) << 25) + (uint64_t)now.tv_nsec + + (uint64_t)(ptrdiff_t)&now; + } else { + /* Get the next step of both random number generators. */ + lfsr = (lfsr >> 1) + | ((((lfsr >> 0) ^ (lfsr >> 1) ^ (lfsr >> 3) ^ (lfsr >> 4)) & 1) + << 63); + lcg = lcg * 6364136223846793005 + 1442695040888963407; + } + + /* Combining two pseudo-random number generators and a high resolution part + * of the current server time will make it hard (impossible?) to guess the + * next number. */ + return (lfsr ^ lcg ^ (uint64_t)now.tv_nsec); +} + + +/* Write data to the IO channel - opened file descriptor, socket or SSL + * descriptor. Return number of bytes written. */ +static int +push(struct mg_context *ctx, + FILE *fp, + SOCKET sock, + SSL *ssl, + const char *buf, + int len, + double timeout) +{ + struct timespec start, now; + int n, err; + +#ifdef _WIN32 + typedef int len_t; +#else + typedef size_t len_t; +#endif + + if (timeout > 0) { + memset(&start, 0, sizeof(start)); + memset(&now, 0, sizeof(now)); + clock_gettime(CLOCK_MONOTONIC, &start); + } + + if (ctx == NULL) { + return -1; + } + +#ifdef NO_SSL + if (ssl) { + return -1; + } +#endif + + do { + +#ifndef NO_SSL + if (ssl != NULL) { + n = SSL_write(ssl, buf, len); + if (n <= 0) { + err = SSL_get_error(ssl, n); + if ((err == 5 /* SSL_ERROR_SYSCALL */) && (n == -1)) { + err = ERRNO; + } else { + DEBUG_TRACE("SSL_write() failed, error %d", err); + return -1; + } + } else { + err = 0; + } + } else +#endif + if (fp != NULL) { + n = (int)fwrite(buf, 1, (size_t)len, fp); + if (ferror(fp)) { + n = -1; + err = ERRNO; + } else { + err = 0; + } + } else { + n = (int)send(sock, buf, (len_t)len, MSG_NOSIGNAL); + err = (n < 0) ? ERRNO : 0; + } + + if (ctx->stop_flag) { + return -1; + } + + if ((n > 0) || (n == 0 && len == 0)) { + /* some data has been read, or no data was requested */ + return n; + } + if (n == 0) { + /* shutdown of the socket at client side */ + return -1; + } + if (n < 0) { + /* socket error - check errno */ + DEBUG_TRACE("send() failed, error %d", err); + + /* TODO: error handling depending on the error code. + * These codes are different between Windows and Linux. + */ + return -1; + } + + /* This code is not reached in the moment. + * ==> Fix the TODOs above first. */ + + if (timeout > 0) { + clock_gettime(CLOCK_MONOTONIC, &now); + } + + } while ((timeout <= 0) || (mg_difftimespec(&now, &start) <= timeout)); + + (void)err; /* Avoid unused warning if NO_SSL is set and DEBUG_TRACE is not + used */ + + return -1; +} + + +static int64_t +push_all(struct mg_context *ctx, + FILE *fp, + SOCKET sock, + SSL *ssl, + const char *buf, + int64_t len) +{ + double timeout = -1.0; + int64_t n, nwritten = 0; + + if (ctx == NULL) { + return -1; + } + + if (ctx->config[REQUEST_TIMEOUT]) { + timeout = atoi(ctx->config[REQUEST_TIMEOUT]) / 1000.0; + } + + while (len > 0 && ctx->stop_flag == 0) { + n = push(ctx, fp, sock, ssl, buf + nwritten, (int)len, timeout); + if (n < 0) { + if (nwritten == 0) { + nwritten = n; /* Propagate the error */ + } + break; + } else if (n == 0) { + break; /* No more data to write */ + } else { + nwritten += n; + len -= n; + } + } + + return nwritten; +} + + +/* Read from IO channel - opened file descriptor, socket, or SSL descriptor. + * Return negative value on error, or number of bytes read on success. */ +static int +pull(FILE *fp, struct mg_connection *conn, char *buf, int len, double timeout) +{ + int nread, err; + struct timespec start, now; + +#ifdef _WIN32 + typedef int len_t; +#else + typedef size_t len_t; +#endif + + if (timeout > 0) { + memset(&start, 0, sizeof(start)); + memset(&now, 0, sizeof(now)); + clock_gettime(CLOCK_MONOTONIC, &start); + } + + do { + if (fp != NULL) { + /* Use read() instead of fread(), because if we're reading from the + * CGI pipe, fread() may block until IO buffer is filled up. We + * cannot afford to block and must pass all read bytes immediately + * to the client. */ + nread = (int)read(fileno(fp), buf, (size_t)len); + err = (nread < 0) ? ERRNO : 0; + +#ifndef NO_SSL + } else if (conn->ssl != NULL) { + nread = SSL_read(conn->ssl, buf, len); + if (nread <= 0) { + err = SSL_get_error(conn->ssl, nread); + if ((err == 5 /* SSL_ERROR_SYSCALL */) && (nread == -1)) { + err = ERRNO; + } else { + DEBUG_TRACE("SSL_read() failed, error %d", err); + return -1; + } + } else { + err = 0; + } +#endif + + } else { + nread = (int)recv(conn->client.sock, buf, (len_t)len, 0); + err = (nread < 0) ? ERRNO : 0; + } + + if (conn->ctx->stop_flag) { + return -1; + } + + if ((nread > 0) || (nread == 0 && len == 0)) { + /* some data has been read, or no data was requested */ + return nread; + } + if (nread == 0) { + /* shutdown of the socket at client side */ + return -1; + } + if (nread < 0) { +/* socket error - check errno */ +#ifdef _WIN32 + if (err == WSAEWOULDBLOCK) { + /* standard case if called from close_socket_gracefully */ + return -1; + } else if (err == WSAETIMEDOUT) { + /* timeout is handled by the while loop */ + } else { + DEBUG_TRACE("recv() failed, error %d", err); + return -1; + } +#else + /* TODO: POSIX returns either EAGAIN or EWOULDBLOCK in both cases, + * if the timeout is reached and if the socket was set to non- + * blocking in close_socket_gracefully, so we can not distinguish + * here. We have to wait for the timeout in both cases for now. + */ + if (err == EAGAIN || err == EWOULDBLOCK || err == EINTR) { + /* EAGAIN/EWOULDBLOCK: + * standard case if called from close_socket_gracefully + * => should return -1 */ + /* or timeout occured + * => the code must stay in the while loop */ + + /* EINTR can be generated on a socket with a timeout set even + * when SA_RESTART is effective for all relevant signals + * (see signal(7)). + * => stay in the while loop */ + } else { + DEBUG_TRACE("recv() failed, error %d", err); + return -1; + } +#endif + } + if (timeout > 0) { + clock_gettime(CLOCK_MONOTONIC, &now); + } + } while ((timeout <= 0) || (mg_difftimespec(&now, &start) <= timeout)); + + /* Timeout occured, but no data available. */ + return -1; +} + + +static int +pull_all(FILE *fp, struct mg_connection *conn, char *buf, int len) +{ + int n, nread = 0; + double timeout = -1.0; + + if (conn->ctx->config[REQUEST_TIMEOUT]) { + timeout = atoi(conn->ctx->config[REQUEST_TIMEOUT]) / 1000.0; + } + + while (len > 0 && conn->ctx->stop_flag == 0) { + n = pull(fp, conn, buf + nread, len, timeout); + if (n < 0) { + if (nread == 0) { + nread = n; /* Propagate the error */ + } + break; + } else if (n == 0) { + break; /* No more data to read */ + } else { + conn->consumed_content += n; + nread += n; + len -= n; + } + } + + return nread; +} + + +static void +discard_unread_request_data(struct mg_connection *conn) +{ + char buf[MG_BUF_LEN]; + size_t to_read; + int nread; + + if (conn == NULL) { + return; + } + + to_read = sizeof(buf); + + if (conn->is_chunked) { + /* Chunked encoding: 1=chunk not read completely, 2=chunk read + * completely */ + while (conn->is_chunked == 1) { + nread = mg_read(conn, buf, to_read); + if (nread <= 0) { + break; + } + } + + } else { + /* Not chunked: content length is known */ + while (conn->consumed_content < conn->content_len) { + if (to_read + > (size_t)(conn->content_len - conn->consumed_content)) { + to_read = (size_t)(conn->content_len - conn->consumed_content); + } + + nread = mg_read(conn, buf, to_read); + if (nread <= 0) { + break; + } + } + } +} + + +static int +mg_read_inner(struct mg_connection *conn, void *buf, size_t len) +{ + int64_t n, buffered_len, nread; + int64_t len64 = + (int64_t)(len > INT_MAX ? INT_MAX : len); /* since the return value is + * int, we may not read more + * bytes */ + const char *body; + + if (conn == NULL) { + return 0; + } + + /* If Content-Length is not set for a PUT or POST request, read until + * socket is closed */ + if (conn->consumed_content == 0 && conn->content_len == -1) { + conn->content_len = INT64_MAX; + conn->must_close = 1; + } + + nread = 0; + if (conn->consumed_content < conn->content_len) { + /* Adjust number of bytes to read. */ + int64_t left_to_read = conn->content_len - conn->consumed_content; + if (left_to_read < len64) { + /* Do not read more than the total content length of the request. + */ + len64 = left_to_read; + } + + /* Return buffered data */ + buffered_len = (int64_t)(conn->data_len) - (int64_t)conn->request_len + - conn->consumed_content; + if (buffered_len > 0) { + if (len64 < buffered_len) { + buffered_len = len64; + } + body = conn->buf + conn->request_len + conn->consumed_content; + memcpy(buf, body, (size_t)buffered_len); + len64 -= buffered_len; + conn->consumed_content += buffered_len; + nread += buffered_len; + buf = (char *)buf + buffered_len; + } + + /* We have returned all buffered data. Read new data from the remote + * socket. + */ + if ((n = pull_all(NULL, conn, (char *)buf, (int)len64)) >= 0) { + nread += n; + } else { + nread = (nread > 0 ? nread : n); + } + } + return (int)nread; +} + + +static char +mg_getc(struct mg_connection *conn) +{ + char c; + if (conn == NULL) { + return 0; + } + conn->content_len++; + if (mg_read_inner(conn, &c, 1) <= 0) { + return (char)0; + } + return c; +} + + +int +mg_read(struct mg_connection *conn, void *buf, size_t len) +{ + if (len > INT_MAX) { + len = INT_MAX; + } + + if (conn == NULL) { + return 0; + } + + if (conn->is_chunked) { + size_t all_read = 0; + + while (len > 0) { + + if (conn->is_chunked == 2) { + /* No more data left to read */ + return 0; + } + + if (conn->chunk_remainder) { + /* copy from the remainder of the last received chunk */ + long read_ret; + size_t read_now = + ((conn->chunk_remainder > len) ? (len) + : (conn->chunk_remainder)); + + conn->content_len += (int)read_now; + read_ret = + mg_read_inner(conn, (char *)buf + all_read, read_now); + all_read += (size_t)read_ret; + + conn->chunk_remainder -= read_now; + len -= read_now; + + if (conn->chunk_remainder == 0) { + /* the rest of the data in the current chunk has been read + */ + if ((mg_getc(conn) != '\r') || (mg_getc(conn) != '\n')) { + /* Protocol violation */ + return -1; + } + } + + } else { + /* fetch a new chunk */ + int i = 0; + char lenbuf[64]; + char *end = 0; + unsigned long chunkSize = 0; + + for (i = 0; i < ((int)sizeof(lenbuf) - 1); i++) { + lenbuf[i] = mg_getc(conn); + if (i > 0 && lenbuf[i] == '\r' && lenbuf[i - 1] != '\r') { + continue; + } + if (i > 1 && lenbuf[i] == '\n' && lenbuf[i - 1] == '\r') { + lenbuf[i + 1] = 0; + chunkSize = strtoul(lenbuf, &end, 16); + if (chunkSize == 0) { + /* regular end of content */ + conn->is_chunked = 2; + } + break; + } + if (!isalnum(lenbuf[i])) { + /* illegal character for chunk length */ + return -1; + } + } + if ((end == NULL) || (*end != '\r')) { + /* chunksize not set correctly */ + return -1; + } + if (chunkSize == 0) { + break; + } + + conn->chunk_remainder = chunkSize; + } + } + + return (int)all_read; + } + return mg_read_inner(conn, buf, len); +} + + +int +mg_write(struct mg_connection *conn, const void *buf, size_t len) +{ + time_t now; + int64_t n, total, allowed; + + if (conn == NULL) { + return 0; + } + + if (conn->throttle > 0) { + if ((now = time(NULL)) != conn->last_throttle_time) { + conn->last_throttle_time = now; + conn->last_throttle_bytes = 0; + } + allowed = conn->throttle - conn->last_throttle_bytes; + if (allowed > (int64_t)len) { + allowed = (int64_t)len; + } + if ((total = push_all(conn->ctx, + NULL, + conn->client.sock, + conn->ssl, + (const char *)buf, + (int64_t)allowed)) == allowed) { + buf = (const char *)buf + total; + conn->last_throttle_bytes += total; + while (total < (int64_t)len && conn->ctx->stop_flag == 0) { + allowed = conn->throttle > (int64_t)len - total + ? (int64_t)len - total + : conn->throttle; + if ((n = push_all(conn->ctx, + NULL, + conn->client.sock, + conn->ssl, + (const char *)buf, + (int64_t)allowed)) != allowed) { + break; + } + sleep(1); + conn->last_throttle_bytes = allowed; + conn->last_throttle_time = time(NULL); + buf = (const char *)buf + n; + total += n; + } + } + } else { + total = push_all(conn->ctx, + NULL, + conn->client.sock, + conn->ssl, + (const char *)buf, + (int64_t)len); + } + return (int)total; +} + + +/* Alternative alloc_vprintf() for non-compliant C runtimes */ +static int +alloc_vprintf2(char **buf, const char *fmt, va_list ap) +{ + va_list ap_copy; + size_t size = MG_BUF_LEN / 4; + int len = -1; + + *buf = NULL; + while (len < 0) { + if (*buf) { + mg_free(*buf); + } + + size *= 4; + *buf = (char *)mg_malloc(size); + if (!*buf) { + break; + } + + va_copy(ap_copy, ap); + len = vsnprintf_impl(*buf, size - 1, fmt, ap_copy); + va_end(ap_copy); + (*buf)[size - 1] = 0; + } + + return len; +} + + +/* Print message to buffer. If buffer is large enough to hold the message, + * return buffer. If buffer is to small, allocate large enough buffer on heap, + * and return allocated buffer. */ +static int +alloc_vprintf(char **out_buf, + char *prealloc_buf, + size_t prealloc_size, + const char *fmt, + va_list ap) +{ + va_list ap_copy; + int len; + + /* Windows is not standard-compliant, and vsnprintf() returns -1 if + * buffer is too small. Also, older versions of msvcrt.dll do not have + * _vscprintf(). However, if size is 0, vsnprintf() behaves correctly. + * Therefore, we make two passes: on first pass, get required message + * length. + * On second pass, actually print the message. */ + va_copy(ap_copy, ap); + len = vsnprintf_impl(NULL, 0, fmt, ap_copy); + va_end(ap_copy); + + if (len < 0) { + /* C runtime is not standard compliant, vsnprintf() returned -1. + * Switch to alternative code path that uses incremental allocations. + */ + va_copy(ap_copy, ap); + len = alloc_vprintf2(out_buf, fmt, ap); + va_end(ap_copy); + + } else if ((size_t)(len) >= prealloc_size) { + /* The pre-allocated buffer not large enough. */ + /* Allocate a new buffer. */ + *out_buf = (char *)mg_malloc((size_t)(len) + 1); + if (!*out_buf) { + /* Allocation failed. Return -1 as "out of memory" error. */ + return -1; + } + /* Buffer allocation successful. Store the string there. */ + va_copy(ap_copy, ap); + IGNORE_UNUSED_RESULT( + vsnprintf_impl(*out_buf, (size_t)(len) + 1, fmt, ap_copy)); + va_end(ap_copy); + + } else { + /* The pre-allocated buffer is large enough. + * Use it to store the string and return the address. */ + va_copy(ap_copy, ap); + IGNORE_UNUSED_RESULT( + vsnprintf_impl(prealloc_buf, prealloc_size, fmt, ap_copy)); + va_end(ap_copy); + *out_buf = prealloc_buf; + } + + return len; +} + + +static int +mg_vprintf(struct mg_connection *conn, const char *fmt, va_list ap) +{ + char mem[MG_BUF_LEN]; + char *buf = NULL; + int len; + + if ((len = alloc_vprintf(&buf, mem, sizeof(mem), fmt, ap)) > 0) { + len = mg_write(conn, buf, (size_t)len); + } + if (buf != mem && buf != NULL) { + mg_free(buf); + } + + return len; +} + + +int +mg_printf(struct mg_connection *conn, const char *fmt, ...) +{ + va_list ap; + int result; + + va_start(ap, fmt); + result = mg_vprintf(conn, fmt, ap); + va_end(ap); + + return result; +} + + +int +mg_url_decode(const char *src, + int src_len, + char *dst, + int dst_len, + int is_form_url_encoded) +{ + int i, j, a, b; +#define HEXTOI(x) (isdigit(x) ? x - '0' : x - 'W') + + for (i = j = 0; i < src_len && j < dst_len - 1; i++, j++) { + if (i < src_len - 2 && src[i] == '%' + && isxdigit(*(const unsigned char *)(src + i + 1)) + && isxdigit(*(const unsigned char *)(src + i + 2))) { + a = tolower(*(const unsigned char *)(src + i + 1)); + b = tolower(*(const unsigned char *)(src + i + 2)); + dst[j] = (char)((HEXTOI(a) << 4) | HEXTOI(b)); + i += 2; + } else if (is_form_url_encoded && src[i] == '+') { + dst[j] = ' '; + } else { + dst[j] = src[i]; + } + } + + dst[j] = '\0'; /* Null-terminate the destination */ + + return i >= src_len ? j : -1; +} + + +int +mg_get_var(const char *data, + size_t data_len, + const char *name, + char *dst, + size_t dst_len) +{ + return mg_get_var2(data, data_len, name, dst, dst_len, 0); +} + + +int +mg_get_var2(const char *data, + size_t data_len, + const char *name, + char *dst, + size_t dst_len, + size_t occurrence) +{ + const char *p, *e, *s; + size_t name_len; + int len; + + if (dst == NULL || dst_len == 0) { + len = -2; + } else if (data == NULL || name == NULL || data_len == 0) { + len = -1; + dst[0] = '\0'; + } else { + name_len = strlen(name); + e = data + data_len; + len = -1; + dst[0] = '\0'; + + /* data is "var1=val1&var2=val2...". Find variable first */ + for (p = data; p + name_len < e; p++) { + if ((p == data || p[-1] == '&') && p[name_len] == '=' + && !mg_strncasecmp(name, p, name_len) && 0 == occurrence--) { + /* Point p to variable value */ + p += name_len + 1; + + /* Point s to the end of the value */ + s = (const char *)memchr(p, '&', (size_t)(e - p)); + if (s == NULL) { + s = e; + } + /* assert(s >= p); */ + if (s < p) { + return -3; + } + + /* Decode variable into destination buffer */ + len = mg_url_decode(p, (int)(s - p), dst, (int)dst_len, 1); + + /* Redirect error code from -1 to -2 (destination buffer too + * small). */ + if (len == -1) { + len = -2; + } + break; + } + } + } + + return len; +} + + +int +mg_get_cookie(const char *cookie_header, + const char *var_name, + char *dst, + size_t dst_size) +{ + const char *s, *p, *end; + int name_len, len = -1; + + if (dst == NULL || dst_size == 0) { + len = -2; + } else if (var_name == NULL || (s = cookie_header) == NULL) { + len = -1; + dst[0] = '\0'; + } else { + name_len = (int)strlen(var_name); + end = s + strlen(s); + dst[0] = '\0'; + + for (; (s = mg_strcasestr(s, var_name)) != NULL; s += name_len) { + if (s[name_len] == '=') { + s += name_len + 1; + if ((p = strchr(s, ' ')) == NULL) { + p = end; + } + if (p[-1] == ';') { + p--; + } + if (*s == '"' && p[-1] == '"' && p > s + 1) { + s++; + p--; + } + if ((size_t)(p - s) < dst_size) { + len = (int)(p - s); + mg_strlcpy(dst, s, (size_t)len + 1); + } else { + len = -3; + } + break; + } + } + } + return len; +} + + +#if defined(USE_WEBSOCKET) || defined(USE_LUA) +static void +base64_encode(const unsigned char *src, int src_len, char *dst) +{ + static const char *b64 = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + int i, j, a, b, c; + + for (i = j = 0; i < src_len; i += 3) { + a = src[i]; + b = i + 1 >= src_len ? 0 : src[i + 1]; + c = i + 2 >= src_len ? 0 : src[i + 2]; + + dst[j++] = b64[a >> 2]; + dst[j++] = b64[((a & 3) << 4) | (b >> 4)]; + if (i + 1 < src_len) { + dst[j++] = b64[(b & 15) << 2 | (c >> 6)]; + } + if (i + 2 < src_len) { + dst[j++] = b64[c & 63]; + } + } + while (j % 4 != 0) { + dst[j++] = '='; + } + dst[j++] = '\0'; +} +#endif + + +#if defined(USE_LUA) +static unsigned char +b64reverse(char letter) +{ + if (letter >= 'A' && letter <= 'Z') { + return letter - 'A'; + } + if (letter >= 'a' && letter <= 'z') { + return letter - 'a' + 26; + } + if (letter >= '0' && letter <= '9') { + return letter - '0' + 52; + } + if (letter == '+') { + return 62; + } + if (letter == '/') { + return 63; + } + if (letter == '=') { + return 255; /* normal end */ + } + return 254; /* error */ +} + + +static int +base64_decode(const unsigned char *src, int src_len, char *dst, size_t *dst_len) +{ + int i; + unsigned char a, b, c, d; + + *dst_len = 0; + + for (i = 0; i < src_len; i += 4) { + a = b64reverse(src[i]); + if (a >= 254) { + return i; + } + + b = b64reverse(i + 1 >= src_len ? 0 : src[i + 1]); + if (b >= 254) { + return i + 1; + } + + c = b64reverse(i + 2 >= src_len ? 0 : src[i + 2]); + if (c == 254) { + return i + 2; + } + + d = b64reverse(i + 3 >= src_len ? 0 : src[i + 3]); + if (d == 254) { + return i + 3; + } + + dst[(*dst_len)++] = (a << 2) + (b >> 4); + if (c != 255) { + dst[(*dst_len)++] = (b << 4) + (c >> 2); + if (d != 255) { + dst[(*dst_len)++] = (c << 6) + d; + } + } + } + return -1; +} +#endif + + +static int +is_put_or_delete_method(const struct mg_connection *conn) +{ + if (conn) { + const char *s = conn->request_info.request_method; + return s != NULL && (!strcmp(s, "PUT") || !strcmp(s, "DELETE") + || !strcmp(s, "MKCOL") || !strcmp(s, "PATCH")); + } + return 0; +} + + +static void +interpret_uri(struct mg_connection *conn, /* in: request (must be valid) */ + char *filename, /* out: filename */ + size_t filename_buf_len, /* in: size of filename buffer */ + struct file *filep, /* out: file structure */ + int *is_found, /* out: file is found (directly) */ + int *is_script_resource, /* out: handled by a script? */ + int *is_websocket_request, /* out: websocket connetion? */ + int *is_put_or_delete_request /* out: put/delete a file? */ + ) +{ +/* TODO (high): Restructure this function */ + +#if !defined(NO_FILES) + const char *uri = conn->request_info.local_uri; + const char *root = conn->ctx->config[DOCUMENT_ROOT]; + const char *rewrite; + struct vec a, b; + int match_len; + char gz_path[PATH_MAX]; + char const *accept_encoding; + int truncated; +#if !defined(NO_CGI) || defined(USE_LUA) + char *p; +#endif +#else + (void)filename_buf_len; /* unused if NO_FILES is defined */ +#endif + + memset(filep, 0, sizeof(*filep)); + *filename = 0; + *is_found = 0; + *is_script_resource = 0; + *is_put_or_delete_request = is_put_or_delete_method(conn); + +#if defined(USE_WEBSOCKET) + *is_websocket_request = is_websocket_protocol(conn); +#if !defined(NO_FILES) + if (*is_websocket_request && conn->ctx->config[WEBSOCKET_ROOT]) { + root = conn->ctx->config[WEBSOCKET_ROOT]; + } +#endif /* !NO_FILES */ +#else /* USE_WEBSOCKET */ + *is_websocket_request = 0; +#endif /* USE_WEBSOCKET */ + +#if !defined(NO_FILES) + /* Note that root == NULL is a regular use case here. This occurs, + * if all requests are handled by callbacks, so the WEBSOCKET_ROOT + * config is not required. */ + if (root == NULL) { + /* all file related outputs have already been set to 0, just return + */ + return; + } + + /* Using buf_len - 1 because memmove() for PATH_INFO may shift part + * of the path one byte on the right. + * If document_root is NULL, leave the file empty. */ + mg_snprintf( + conn, &truncated, filename, filename_buf_len - 1, "%s%s", root, uri); + + if (truncated) { + goto interpret_cleanup; + } + + rewrite = conn->ctx->config[REWRITE]; + while ((rewrite = next_option(rewrite, &a, &b)) != NULL) { + if ((match_len = match_prefix(a.ptr, a.len, uri)) > 0) { + mg_snprintf(conn, + &truncated, + filename, + filename_buf_len - 1, + "%.*s%s", + (int)b.len, + b.ptr, + uri + match_len); + break; + } + } + + if (truncated) { + goto interpret_cleanup; + } + + /* Local file path and name, corresponding to requested URI + * is now stored in "filename" variable. */ + if (mg_stat(conn, filename, filep)) { +#if !defined(NO_CGI) || defined(USE_LUA) || defined(USE_DUKTAPE) + /* File exists. Check if it is a script type. */ + if (0 +#if !defined(NO_CGI) + || match_prefix(conn->ctx->config[CGI_EXTENSIONS], + strlen(conn->ctx->config[CGI_EXTENSIONS]), + filename) > 0 +#endif +#if defined(USE_LUA) + || match_prefix(conn->ctx->config[LUA_SCRIPT_EXTENSIONS], + strlen(conn->ctx->config[LUA_SCRIPT_EXTENSIONS]), + filename) > 0 +#endif +#if defined(USE_DUKTAPE) + || match_prefix(conn->ctx->config[DUKTAPE_SCRIPT_EXTENSIONS], + strlen( + conn->ctx->config[DUKTAPE_SCRIPT_EXTENSIONS]), + filename) > 0 +#endif + ) { + /* The request addresses a CGI script or a Lua script. The URI + * corresponds to the script itself (like /path/script.cgi), + * and there is no additional resource path + * (like /path/script.cgi/something). + * Requests that modify (replace or delete) a resource, like + * PUT and DELETE requests, should replace/delete the script + * file. + * Requests that read or write from/to a resource, like GET and + * POST requests, should call the script and return the + * generated response. */ + *is_script_resource = !*is_put_or_delete_request; + } +#endif /* !defined(NO_CGI) || defined(USE_LUA) || defined(USE_DUKTAPE) */ + *is_found = 1; + return; + } + + /* If we can't find the actual file, look for the file + * with the same name but a .gz extension. If we find it, + * use that and set the gzipped flag in the file struct + * to indicate that the response need to have the content- + * encoding: gzip header. + * We can only do this if the browser declares support. */ + if ((accept_encoding = mg_get_header(conn, "Accept-Encoding")) != NULL) { + if (strstr(accept_encoding, "gzip") != NULL) { + mg_snprintf( + conn, &truncated, gz_path, sizeof(gz_path), "%s.gz", filename); + + if (truncated) { + goto interpret_cleanup; + } + + if (mg_stat(conn, gz_path, filep)) { + if (filep) { + filep->gzipped = 1; + *is_found = 1; + } + /* Currently gz files can not be scripts. */ + return; + } + } + } + +#if !defined(NO_CGI) || defined(USE_LUA) || defined(USE_DUKTAPE) + /* Support PATH_INFO for CGI scripts. */ + for (p = filename + strlen(filename); p > filename + 1; p--) { + if (*p == '/') { + *p = '\0'; + if ((0 +#if !defined(NO_CGI) + || match_prefix(conn->ctx->config[CGI_EXTENSIONS], + strlen(conn->ctx->config[CGI_EXTENSIONS]), + filename) > 0 +#endif +#if defined(USE_LUA) + || match_prefix(conn->ctx->config[LUA_SCRIPT_EXTENSIONS], + strlen( + conn->ctx->config[LUA_SCRIPT_EXTENSIONS]), + filename) > 0 +#endif +#if defined(USE_DUKTAPE) + || match_prefix( + conn->ctx->config[DUKTAPE_SCRIPT_EXTENSIONS], + strlen(conn->ctx->config[DUKTAPE_SCRIPT_EXTENSIONS]), + filename) > 0 +#endif + ) && mg_stat(conn, filename, filep)) { + /* Shift PATH_INFO block one character right, e.g. + * "/x.cgi/foo/bar\x00" => "/x.cgi\x00/foo/bar\x00" + * conn->path_info is pointing to the local variable "path" + * declared in handle_request(), so PATH_INFO is not valid + * after handle_request returns. */ + conn->path_info = p + 1; + memmove(p + 2, p + 1, strlen(p + 1) + 1); /* +1 is for + * trailing \0 */ + p[1] = '/'; + *is_script_resource = 1; + break; + } else { + *p = '/'; + } + } + } +#endif /* !defined(NO_CGI) || defined(USE_LUA) || defined(USE_DUKTAPE) */ +#endif /* !defined(NO_FILES) */ + return; + +#if !defined(NO_FILES) +/* Reset all outputs */ +interpret_cleanup: + memset(filep, 0, sizeof(*filep)); + *filename = 0; + *is_found = 0; + *is_script_resource = 0; + *is_websocket_request = 0; + *is_put_or_delete_request = 0; +#endif /* !defined(NO_FILES) */ +} + + +/* Check whether full request is buffered. Return: + * -1 if request is malformed + * 0 if request is not yet fully buffered + * >0 actual request length, including last \r\n\r\n */ +static int +get_request_len(const char *buf, int buflen) +{ + const char *s, *e; + int len = 0; + + for (s = buf, e = s + buflen - 1; len <= 0 && s < e; s++) + /* Control characters are not allowed but >=128 is. */ + if (!isprint(*(const unsigned char *)s) && *s != '\r' && *s != '\n' + && *(const unsigned char *)s < 128) { + len = -1; + break; /* [i_a] abort scan as soon as one malformed character is + * found; */ + /* don't let subsequent \r\n\r\n win us over anyhow */ + } else if (s[0] == '\n' && s[1] == '\n') { + len = (int)(s - buf) + 2; + } else if (s[0] == '\n' && &s[1] < e && s[1] == '\r' && s[2] == '\n') { + len = (int)(s - buf) + 3; + } + + return len; +} + + +#if !defined(NO_CACHING) +/* Convert month to the month number. Return -1 on error, or month number */ +static int +get_month_index(const char *s) +{ + size_t i; + + for (i = 0; i < ARRAY_SIZE(month_names); i++) { + if (!strcmp(s, month_names[i])) { + return (int)i; + } + } + + return -1; +} + + +/* Parse UTC date-time string, and return the corresponding time_t value. */ +static time_t +parse_date_string(const char *datetime) +{ + char month_str[32] = {0}; + int second, minute, hour, day, month, year; + time_t result = (time_t)0; + struct tm tm; + + if ((sscanf(datetime, + "%d/%3s/%d %d:%d:%d", + &day, + month_str, + &year, + &hour, + &minute, + &second) == 6) || (sscanf(datetime, + "%d %3s %d %d:%d:%d", + &day, + month_str, + &year, + &hour, + &minute, + &second) == 6) + || (sscanf(datetime, + "%*3s, %d %3s %d %d:%d:%d", + &day, + month_str, + &year, + &hour, + &minute, + &second) == 6) || (sscanf(datetime, + "%d-%3s-%d %d:%d:%d", + &day, + month_str, + &year, + &hour, + &minute, + &second) == 6)) { + month = get_month_index(month_str); + if ((month >= 0) && (year >= 1970)) { + memset(&tm, 0, sizeof(tm)); + tm.tm_year = year - 1900; + tm.tm_mon = month; + tm.tm_mday = day; + tm.tm_hour = hour; + tm.tm_min = minute; + tm.tm_sec = second; + result = timegm(&tm); + } + } + + return result; +} +#endif /* !NO_CACHING */ + + +/* Protect against directory disclosure attack by removing '..', + * excessive '/' and '\' characters */ +static void +remove_double_dots_and_double_slashes(char *s) +{ + char *p = s; + + while (*s != '\0') { + *p++ = *s++; + if (s[-1] == '/' || s[-1] == '\\') { + /* Skip all following slashes, backslashes and double-dots */ + while (s[0] != '\0') { + if (s[0] == '/' || s[0] == '\\') { + s++; + } else if (s[0] == '.' && s[1] == '.') { + s += 2; + } else { + break; + } + } + } + } + *p = '\0'; +} + + +static const struct { + const char *extension; + size_t ext_len; + const char *mime_type; +} builtin_mime_types[] = { + /* IANA registered MIME types (http://www.iana.org/assignments/media-types) + * application types */ + {".doc", 4, "application/msword"}, + {".eps", 4, "application/postscript"}, + {".exe", 4, "application/octet-stream"}, + {".js", 3, "application/javascript"}, + {".json", 5, "application/json"}, + {".pdf", 4, "application/pdf"}, + {".ps", 3, "application/postscript"}, + {".rtf", 4, "application/rtf"}, + {".xhtml", 6, "application/xhtml+xml"}, + {".xsl", 4, "application/xml"}, + {".xslt", 5, "application/xml"}, + + /* fonts */ + {".ttf", 4, "application/font-sfnt"}, + {".cff", 4, "application/font-sfnt"}, + {".otf", 4, "application/font-sfnt"}, + {".aat", 4, "application/font-sfnt"}, + {".sil", 4, "application/font-sfnt"}, + {".pfr", 4, "application/font-tdpfr"}, + {".woff", 5, "application/font-woff"}, + + /* audio */ + {".mp3", 4, "audio/mpeg"}, + {".oga", 4, "audio/ogg"}, + {".ogg", 4, "audio/ogg"}, + + /* image */ + {".gif", 4, "image/gif"}, + {".ief", 4, "image/ief"}, + {".jpeg", 5, "image/jpeg"}, + {".jpg", 4, "image/jpeg"}, + {".jpm", 4, "image/jpm"}, + {".jpx", 4, "image/jpx"}, + {".png", 4, "image/png"}, + {".svg", 4, "image/svg+xml"}, + {".tif", 4, "image/tiff"}, + {".tiff", 5, "image/tiff"}, + + /* model */ + {".wrl", 4, "model/vrml"}, + + /* text */ + {".css", 4, "text/css"}, + {".csv", 4, "text/csv"}, + {".htm", 4, "text/html"}, + {".html", 5, "text/html"}, + {".sgm", 4, "text/sgml"}, + {".shtm", 5, "text/html"}, + {".shtml", 6, "text/html"}, + {".txt", 4, "text/plain"}, + {".xml", 4, "text/xml"}, + + /* video */ + {".mov", 4, "video/quicktime"}, + {".mp4", 4, "video/mp4"}, + {".mpeg", 5, "video/mpeg"}, + {".mpg", 4, "video/mpeg"}, + {".ogv", 4, "video/ogg"}, + {".qt", 3, "video/quicktime"}, + + /* not registered types + * (http://reference.sitepoint.com/html/mime-types-full, + * http://www.hansenb.pdx.edu/DMKB/dict/tutorials/mime_typ.php, ..) */ + {".arj", 4, "application/x-arj-compressed"}, + {".gz", 3, "application/x-gunzip"}, + {".rar", 4, "application/x-arj-compressed"}, + {".swf", 4, "application/x-shockwave-flash"}, + {".tar", 4, "application/x-tar"}, + {".tgz", 4, "application/x-tar-gz"}, + {".torrent", 8, "application/x-bittorrent"}, + {".ppt", 4, "application/x-mspowerpoint"}, + {".xls", 4, "application/x-msexcel"}, + {".zip", 4, "application/x-zip-compressed"}, + {".aac", + 4, + "audio/aac"}, /* http://en.wikipedia.org/wiki/Advanced_Audio_Coding */ + {".aif", 4, "audio/x-aif"}, + {".m3u", 4, "audio/x-mpegurl"}, + {".mid", 4, "audio/x-midi"}, + {".ra", 3, "audio/x-pn-realaudio"}, + {".ram", 4, "audio/x-pn-realaudio"}, + {".wav", 4, "audio/x-wav"}, + {".bmp", 4, "image/bmp"}, + {".ico", 4, "image/x-icon"}, + {".pct", 4, "image/x-pct"}, + {".pict", 5, "image/pict"}, + {".rgb", 4, "image/x-rgb"}, + {".webm", 5, "video/webm"}, /* http://en.wikipedia.org/wiki/WebM */ + {".asf", 4, "video/x-ms-asf"}, + {".avi", 4, "video/x-msvideo"}, + {".m4v", 4, "video/x-m4v"}, + {NULL, 0, NULL}}; + + +const char * +mg_get_builtin_mime_type(const char *path) +{ + const char *ext; + size_t i, path_len; + + path_len = strlen(path); + + for (i = 0; builtin_mime_types[i].extension != NULL; i++) { + ext = path + (path_len - builtin_mime_types[i].ext_len); + if (path_len > builtin_mime_types[i].ext_len + && mg_strcasecmp(ext, builtin_mime_types[i].extension) == 0) { + return builtin_mime_types[i].mime_type; + } + } + + return "text/plain"; +} + + +/* Look at the "path" extension and figure what mime type it has. + * Store mime type in the vector. */ +static void +get_mime_type(struct mg_context *ctx, const char *path, struct vec *vec) +{ + struct vec ext_vec, mime_vec; + const char *list, *ext; + size_t path_len; + + path_len = strlen(path); + + if (ctx == NULL || vec == NULL) { + return; + } + + /* Scan user-defined mime types first, in case user wants to + * override default mime types. */ + list = ctx->config[EXTRA_MIME_TYPES]; + while ((list = next_option(list, &ext_vec, &mime_vec)) != NULL) { + /* ext now points to the path suffix */ + ext = path + path_len - ext_vec.len; + if (mg_strncasecmp(ext, ext_vec.ptr, ext_vec.len) == 0) { + *vec = mime_vec; + return; + } + } + + vec->ptr = mg_get_builtin_mime_type(path); + vec->len = strlen(vec->ptr); +} + + +/* Stringify binary data. Output buffer must be twice as big as input, + * because each byte takes 2 bytes in string representation */ +static void +bin2str(char *to, const unsigned char *p, size_t len) +{ + static const char *hex = "0123456789abcdef"; + + for (; len--; p++) { + *to++ = hex[p[0] >> 4]; + *to++ = hex[p[0] & 0x0f]; + } + *to = '\0'; +} + + +/* Return stringified MD5 hash for list of strings. Buffer must be 33 bytes. */ +char * +mg_md5(char buf[33], ...) +{ + md5_byte_t hash[16]; + const char *p; + va_list ap; + md5_state_t ctx; + + md5_init(&ctx); + + va_start(ap, buf); + while ((p = va_arg(ap, const char *)) != NULL) { + md5_append(&ctx, (const md5_byte_t *)p, strlen(p)); + } + va_end(ap); + + md5_finish(&ctx, hash); + bin2str(buf, hash, sizeof(hash)); + return buf; +} + + +/* Check the user's password, return 1 if OK */ +static int +check_password(const char *method, + const char *ha1, + const char *uri, + const char *nonce, + const char *nc, + const char *cnonce, + const char *qop, + const char *response) +{ + char ha2[32 + 1], expected_response[32 + 1]; + + /* Some of the parameters may be NULL */ + if (method == NULL || nonce == NULL || nc == NULL || cnonce == NULL + || qop == NULL + || response == NULL) { + return 0; + } + + /* NOTE(lsm): due to a bug in MSIE, we do not compare the URI */ + if (strlen(response) != 32) { + return 0; + } + + mg_md5(ha2, method, ":", uri, NULL); + mg_md5(expected_response, + ha1, + ":", + nonce, + ":", + nc, + ":", + cnonce, + ":", + qop, + ":", + ha2, + NULL); + + return mg_strcasecmp(response, expected_response) == 0; +} + + +/* Use the global passwords file, if specified by auth_gpass option, + * or search for .htpasswd in the requested directory. */ +static void +open_auth_file(struct mg_connection *conn, const char *path, struct file *filep) +{ + if (conn != NULL && conn->ctx != NULL) { + char name[PATH_MAX]; + const char *p, *e, *gpass = conn->ctx->config[GLOBAL_PASSWORDS_FILE]; + struct file file = STRUCT_FILE_INITIALIZER; + int truncated; + + if (gpass != NULL) { + /* Use global passwords file */ + if (!mg_fopen(conn, gpass, "r", filep)) { +#ifdef DEBUG + mg_cry(conn, "fopen(%s): %s", gpass, strerror(ERRNO)); +#endif + } + /* Important: using local struct file to test path for is_directory + * flag. If filep is used, mg_stat() makes it appear as if auth file + * was opened. */ + } else if (mg_stat(conn, path, &file) && file.is_directory) { + mg_snprintf(conn, + &truncated, + name, + sizeof(name), + "%s/%s", + path, + PASSWORDS_FILE_NAME); + + if (truncated || !mg_fopen(conn, name, "r", filep)) { +#ifdef DEBUG + mg_cry(conn, "fopen(%s): %s", name, strerror(ERRNO)); +#endif + } + } else { + /* Try to find .htpasswd in requested directory. */ + for (p = path, e = p + strlen(p) - 1; e > p; e--) { + if (e[0] == '/') { + break; + } + } + mg_snprintf(conn, + &truncated, + name, + sizeof(name), + "%.*s/%s", + (int)(e - p), + p, + PASSWORDS_FILE_NAME); + + if (truncated || !mg_fopen(conn, name, "r", filep)) { +#ifdef DEBUG + mg_cry(conn, "fopen(%s): %s", name, strerror(ERRNO)); +#endif + } + } + } +} + + +/* Parsed Authorization header */ +struct ah { + char *user, *uri, *cnonce, *response, *qop, *nc, *nonce; +}; + + +/* Return 1 on success. Always initializes the ah structure. */ +static int +parse_auth_header(struct mg_connection *conn, + char *buf, + size_t buf_size, + struct ah *ah) +{ + char *name, *value, *s; + const char *auth_header; + uint64_t nonce; + + if (!ah || !conn) { + return 0; + } + + (void)memset(ah, 0, sizeof(*ah)); + if ((auth_header = mg_get_header(conn, "Authorization")) == NULL + || mg_strncasecmp(auth_header, "Digest ", 7) != 0) { + return 0; + } + + /* Make modifiable copy of the auth header */ + (void)mg_strlcpy(buf, auth_header + 7, buf_size); + s = buf; + + /* Parse authorization header */ + for (;;) { + /* Gobble initial spaces */ + while (isspace(*(unsigned char *)s)) { + s++; + } + name = skip_quoted(&s, "=", " ", 0); + /* Value is either quote-delimited, or ends at first comma or space. */ + if (s[0] == '\"') { + s++; + value = skip_quoted(&s, "\"", " ", '\\'); + if (s[0] == ',') { + s++; + } + } else { + value = skip_quoted(&s, ", ", " ", 0); /* IE uses commas, FF uses + * spaces */ + } + if (*name == '\0') { + break; + } + + if (!strcmp(name, "username")) { + ah->user = value; + } else if (!strcmp(name, "cnonce")) { + ah->cnonce = value; + } else if (!strcmp(name, "response")) { + ah->response = value; + } else if (!strcmp(name, "uri")) { + ah->uri = value; + } else if (!strcmp(name, "qop")) { + ah->qop = value; + } else if (!strcmp(name, "nc")) { + ah->nc = value; + } else if (!strcmp(name, "nonce")) { + ah->nonce = value; + } + } + +#ifndef NO_NONCE_CHECK + /* Read the nonce from the response. */ + if (ah->nonce == NULL) { + return 0; + } + s = NULL; + nonce = strtoull(ah->nonce, &s, 10); + if ((s == NULL) || (*s != 0)) { + return 0; + } + + /* Convert the nonce from the client to a number. */ + nonce ^= conn->ctx->auth_nonce_mask; + + /* The converted number corresponds to the time the nounce has been + * created. This should not be earlier than the server start. */ + /* Server side nonce check is valuable in all situations but one: + * if the server restarts frequently, but the client should not see + * that, so the server should accept nonces from previous starts. */ + /* However, the reasonable default is to not accept a nonce from a + * previous start, so if anyone changed the access rights between + * two restarts, a new login is required. */ + if (nonce < (uint64_t)conn->ctx->start_time) { + /* nonce is from a previous start of the server and no longer valid + * (replay attack?) */ + return 0; + } + /* Check if the nonce is too high, so it has not (yet) been used by the + * server. */ + if (nonce >= ((uint64_t)conn->ctx->start_time + conn->ctx->nonce_count)) { + return 0; + } +#endif + + /* CGI needs it as REMOTE_USER */ + if (ah->user != NULL) { + conn->request_info.remote_user = mg_strdup(ah->user); + } else { + return 0; + } + + return 1; +} + + +static const char * +mg_fgets(char *buf, size_t size, struct file *filep, char **p) +{ + const char *eof; + size_t len; + const char *memend; + + if (!filep) { + return NULL; + } + + if (filep->membuf != NULL && *p != NULL) { + memend = (const char *)&filep->membuf[filep->size]; + /* Search for \n from p till the end of stream */ + eof = (char *)memchr(*p, '\n', (size_t)(memend - *p)); + if (eof != NULL) { + eof += 1; /* Include \n */ + } else { + eof = memend; /* Copy remaining data */ + } + len = (size_t)(eof - *p) > size - 1 ? size - 1 : (size_t)(eof - *p); + memcpy(buf, *p, len); + buf[len] = '\0'; + *p += len; + return len ? eof : NULL; + } else if (filep->fp != NULL) { + return fgets(buf, (int)size, filep->fp); + } else { + return NULL; + } +} + +struct read_auth_file_struct { + struct mg_connection *conn; + struct ah ah; + char *domain; + char buf[256 + 256 + 40]; + char *f_user; + char *f_domain; + char *f_ha1; +}; + + +static int +read_auth_file(struct file *filep, struct read_auth_file_struct *workdata) +{ + char *p; + int is_authorized = 0; + struct file fp; + size_t l; + + if (!filep || !workdata) { + return 0; + } + + /* Loop over passwords file */ + p = (char *)filep->membuf; + while (mg_fgets(workdata->buf, sizeof(workdata->buf), filep, &p) != NULL) { + l = strlen(workdata->buf); + while (l > 0) { + if (isspace(workdata->buf[l - 1]) + || iscntrl(workdata->buf[l - 1])) { + l--; + workdata->buf[l] = 0; + } else + break; + } + if (l < 1) { + continue; + } + + workdata->f_user = workdata->buf; + + if (workdata->f_user[0] == ':') { + /* user names may not contain a ':' and may not be empty, + * so lines starting with ':' may be used for a special purpose */ + if (workdata->f_user[1] == '#') { + /* :# is a comment */ + continue; + } else if (!strncmp(workdata->f_user + 1, "include=", 8)) { + if (mg_fopen(workdata->conn, workdata->f_user + 9, "r", &fp)) { + is_authorized = read_auth_file(&fp, workdata); + mg_fclose(&fp); + } else { + mg_cry(workdata->conn, + "%s: cannot open authorization file: %s", + __func__, + workdata->buf); + } + continue; + } + /* everything is invalid for the moment (might change in the + * future) */ + mg_cry(workdata->conn, + "%s: syntax error in authorization file: %s", + __func__, + workdata->buf); + continue; + } + + workdata->f_domain = strchr(workdata->f_user, ':'); + if (workdata->f_domain == NULL) { + mg_cry(workdata->conn, + "%s: syntax error in authorization file: %s", + __func__, + workdata->buf); + continue; + } + *(workdata->f_domain) = 0; + (workdata->f_domain)++; + + workdata->f_ha1 = strchr(workdata->f_domain, ':'); + if (workdata->f_ha1 == NULL) { + mg_cry(workdata->conn, + "%s: syntax error in authorization file: %s", + __func__, + workdata->buf); + continue; + } + *(workdata->f_ha1) = 0; + (workdata->f_ha1)++; + + if (!strcmp(workdata->ah.user, workdata->f_user) + && !strcmp(workdata->domain, workdata->f_domain)) { + return check_password(workdata->conn->request_info.request_method, + workdata->f_ha1, + workdata->ah.uri, + workdata->ah.nonce, + workdata->ah.nc, + workdata->ah.cnonce, + workdata->ah.qop, + workdata->ah.response); + } + } + + return is_authorized; +} + + +/* Authorize against the opened passwords file. Return 1 if authorized. */ +static int +authorize(struct mg_connection *conn, struct file *filep) +{ + struct read_auth_file_struct workdata; + char buf[MG_BUF_LEN]; + + if (!conn || !conn->ctx) { + return 0; + } + + memset(&workdata, 0, sizeof(workdata)); + workdata.conn = conn; + + if (!parse_auth_header(conn, buf, sizeof(buf), &workdata.ah)) { + return 0; + } + workdata.domain = conn->ctx->config[AUTHENTICATION_DOMAIN]; + + return read_auth_file(filep, &workdata); +} + + +/* Return 1 if request is authorised, 0 otherwise. */ +static int +check_authorization(struct mg_connection *conn, const char *path) +{ + char fname[PATH_MAX]; + struct vec uri_vec, filename_vec; + const char *list; + struct file file = STRUCT_FILE_INITIALIZER; + int authorized = 1, truncated; + + if (!conn || !conn->ctx) { + return 0; + } + + list = conn->ctx->config[PROTECT_URI]; + while ((list = next_option(list, &uri_vec, &filename_vec)) != NULL) { + if (!memcmp(conn->request_info.local_uri, uri_vec.ptr, uri_vec.len)) { + mg_snprintf(conn, + &truncated, + fname, + sizeof(fname), + "%.*s", + (int)filename_vec.len, + filename_vec.ptr); + + if (truncated || !mg_fopen(conn, fname, "r", &file)) { + mg_cry(conn, + "%s: cannot open %s: %s", + __func__, + fname, + strerror(errno)); + } + break; + } + } + + if (!is_file_opened(&file)) { + open_auth_file(conn, path, &file); + } + + if (is_file_opened(&file)) { + authorized = authorize(conn, &file); + mg_fclose(&file); + } + + return authorized; +} + + +static void +send_authorization_request(struct mg_connection *conn) +{ + char date[64]; + time_t curtime = time(NULL); + + if (conn && conn->ctx) { + uint64_t nonce = (uint64_t)(conn->ctx->start_time); + + (void)pthread_mutex_lock(&conn->ctx->nonce_mutex); + nonce += conn->ctx->nonce_count; + ++conn->ctx->nonce_count; + (void)pthread_mutex_unlock(&conn->ctx->nonce_mutex); + + nonce ^= conn->ctx->auth_nonce_mask; + conn->status_code = 401; + conn->must_close = 1; + + gmt_time_string(date, sizeof(date), &curtime); + + mg_printf(conn, "HTTP/1.1 401 Unauthorized\r\n"); + send_no_cache_header(conn); + mg_printf(conn, + "Date: %s\r\n" + "Connection: %s\r\n" + "Content-Length: 0\r\n" + "WWW-Authenticate: Digest qop=\"auth\", realm=\"%s\", " + "nonce=\"%" UINT64_FMT "\"\r\n\r\n", + date, + suggest_connection_header(conn), + conn->ctx->config[AUTHENTICATION_DOMAIN], + nonce); + } +} + + +#if !defined(NO_FILES) +static int +is_authorized_for_put(struct mg_connection *conn) +{ + if (conn) { + struct file file = STRUCT_FILE_INITIALIZER; + const char *passfile = conn->ctx->config[PUT_DELETE_PASSWORDS_FILE]; + int ret = 0; + + if (passfile != NULL && mg_fopen(conn, passfile, "r", &file)) { + ret = authorize(conn, &file); + mg_fclose(&file); + } + + return ret; + } + return 0; +} +#endif + + +int +mg_modify_passwords_file(const char *fname, + const char *domain, + const char *user, + const char *pass) +{ + int found, i; + char line[512], u[512] = "", d[512] = "", ha1[33], tmp[PATH_MAX + 8]; + FILE *fp, *fp2; + + found = 0; + fp = fp2 = NULL; + + /* Regard empty password as no password - remove user record. */ + if (pass != NULL && pass[0] == '\0') { + pass = NULL; + } + + /* Other arguments must not be empty */ + if (fname == NULL || domain == NULL || user == NULL) { + return 0; + } + + /* Using the given file format, user name and domain must not contain ':' + */ + if (strchr(user, ':') != NULL) { + return 0; + } + if (strchr(domain, ':') != NULL) { + return 0; + } + + /* Do not allow control characters like newline in user name and domain. + * Do not allow excessively long names either. */ + for (i = 0; i < 255 && user[i] != 0; i++) { + if (iscntrl(user[i])) { + return 0; + } + } + if (user[i]) { + return 0; + } + for (i = 0; i < 255 && domain[i] != 0; i++) { + if (iscntrl(domain[i])) { + return 0; + } + } + if (domain[i]) { + return 0; + } + + /* The maximum length of the path to the password file is limited */ + if ((strlen(fname) + 4) >= PATH_MAX) { + return 0; + } + + /* Create a temporary file name. Length has been checked before. */ + strcpy(tmp, fname); + strcat(tmp, ".tmp"); + + /* Create the file if does not exist */ + /* Use of fopen here is OK, since fname is only ASCII */ + if ((fp = fopen(fname, "a+")) != NULL) { + (void)fclose(fp); + } + + /* Open the given file and temporary file */ + if ((fp = fopen(fname, "r")) == NULL) { + return 0; + } else if ((fp2 = fopen(tmp, "w+")) == NULL) { + fclose(fp); + return 0; + } + + /* Copy the stuff to temporary file */ + while (fgets(line, sizeof(line), fp) != NULL) { + if (sscanf(line, "%255[^:]:%255[^:]:%*s", u, d) != 2) { + continue; + } + u[255] = 0; + d[255] = 0; + + if (!strcmp(u, user) && !strcmp(d, domain)) { + found++; + if (pass != NULL) { + mg_md5(ha1, user, ":", domain, ":", pass, NULL); + fprintf(fp2, "%s:%s:%s\n", user, domain, ha1); + } + } else { + fprintf(fp2, "%s", line); + } + } + + /* If new user, just add it */ + if (!found && pass != NULL) { + mg_md5(ha1, user, ":", domain, ":", pass, NULL); + fprintf(fp2, "%s:%s:%s\n", user, domain, ha1); + } + + /* Close files */ + fclose(fp); + fclose(fp2); + + /* Put the temp file in place of real file */ + IGNORE_UNUSED_RESULT(remove(fname)); + IGNORE_UNUSED_RESULT(rename(tmp, fname)); + + return 1; +} + + +static int +is_valid_port(unsigned long port) +{ + return port < 0xffff; +} + + +static int +mg_inet_pton(int af, const char *src, void *dst, size_t dstlen) +{ + struct addrinfo hints, *res, *ressave; + int func_ret = 0; + int gai_ret; + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = af; + + gai_ret = getaddrinfo(src, NULL, &hints, &res); + if (gai_ret != 0) { + /* gai_strerror could be used to convert gai_ret to a string */ + /* POSIX return values: see + * http://pubs.opengroup.org/onlinepubs/9699919799/functions/freeaddrinfo.html + */ + /* Windows return values: see + * https://msdn.microsoft.com/en-us/library/windows/desktop/ms738520%28v=vs.85%29.aspx + */ + return 0; + } + + ressave = res; + + while (res) { + if (dstlen >= res->ai_addrlen) { + memcpy(dst, res->ai_addr, res->ai_addrlen); + func_ret = 1; + } + res = res->ai_next; + } + + freeaddrinfo(ressave); + return func_ret; +} + + +static int +connect_socket(struct mg_context *ctx /* may be NULL */, + const char *host, + int port, + int use_ssl, + char *ebuf, + size_t ebuf_len, + SOCKET *sock /* output: socket, must not be NULL */, + union usa *sa /* output: socket address, must not be NULL */ + ) +{ + int ip_ver = 0; + *sock = INVALID_SOCKET; + memset(sa, 0, sizeof(*sa)); + + if (ebuf_len > 0) { + *ebuf = 0; + } + + if (host == NULL) { + mg_snprintf(NULL, + NULL, /* No truncation check for ebuf */ + ebuf, + ebuf_len, + "%s", + "NULL host"); + return 0; + } + + if (port < 0 || !is_valid_port((unsigned)port)) { + mg_snprintf(NULL, + NULL, /* No truncation check for ebuf */ + ebuf, + ebuf_len, + "%s", + "invalid port"); + return 0; + } + + if (use_ssl && (SSLv23_client_method == NULL)) { + mg_snprintf(NULL, + NULL, /* No truncation check for ebuf */ + ebuf, + ebuf_len, + "%s", + "SSL is not initialized"); + return 0; + } + + if (mg_inet_pton(AF_INET, host, &sa->sin, sizeof(sa->sin))) { + sa->sin.sin_port = htons((uint16_t)port); + ip_ver = 4; +#ifdef USE_IPV6 + } else if (mg_inet_pton(AF_INET6, host, &sa->sin6, sizeof(sa->sin6))) { + sa->sin6.sin6_port = htons((uint16_t)port); + ip_ver = 6; + } else if (host[0] == '[') { + /* While getaddrinfo on Windows will work with [::1], + * getaddrinfo on Linux only works with ::1 (without []). */ + size_t l = strlen(host + 1); + char *h = l > 1 ? mg_strdup(host + 1) : NULL; + if (h) { + h[l - 1] = 0; + if (mg_inet_pton(AF_INET6, h, &sa->sin6, sizeof(sa->sin6))) { + sa->sin6.sin6_port = htons((uint16_t)port); + ip_ver = 6; + } + mg_free(h); + } +#endif + } + + if (ip_ver == 0) { + mg_snprintf(NULL, + NULL, /* No truncation check for ebuf */ + ebuf, + ebuf_len, + "%s", + "host not found"); + return 0; + } + + if (ip_ver == 4) { + *sock = socket(PF_INET, SOCK_STREAM, 0); + } +#ifdef USE_IPV6 + else if (ip_ver == 6) { + *sock = socket(PF_INET6, SOCK_STREAM, 0); + } +#endif + + if (*sock == INVALID_SOCKET) { + mg_snprintf(NULL, + NULL, /* No truncation check for ebuf */ + ebuf, + ebuf_len, + "socket(): %s", + strerror(ERRNO)); + return 0; + } + + set_close_on_exec(*sock, fc(ctx)); + + if ((ip_ver == 4) + && (connect(*sock, (struct sockaddr *)&sa->sin, sizeof(sa->sin)) + == 0)) { + /* connected with IPv4 */ + return 1; + } + +#ifdef USE_IPV6 + if ((ip_ver == 6) + && (connect(*sock, (struct sockaddr *)&sa->sin6, sizeof(sa->sin6)) + == 0)) { + /* connected with IPv6 */ + return 1; + } +#endif + + /* Not connected */ + mg_snprintf(NULL, + NULL, /* No truncation check for ebuf */ + ebuf, + ebuf_len, + "connect(%s:%d): %s", + host, + port, + strerror(ERRNO)); + closesocket(*sock); + *sock = INVALID_SOCKET; + return 0; +} + + +int +mg_url_encode(const char *src, char *dst, size_t dst_len) +{ + static const char *dont_escape = "._-$,;~()"; + static const char *hex = "0123456789abcdef"; + char *pos = dst; + const char *end = dst + dst_len - 1; + + for (; *src != '\0' && pos < end; src++, pos++) { + if (isalnum(*(const unsigned char *)src) + || strchr(dont_escape, *(const unsigned char *)src) != NULL) { + *pos = *src; + } else if (pos + 2 < end) { + pos[0] = '%'; + pos[1] = hex[(*(const unsigned char *)src) >> 4]; + pos[2] = hex[(*(const unsigned char *)src) & 0xf]; + pos += 2; + } else { + break; + } + } + + *pos = '\0'; + return (*src == '\0') ? (int)(pos - dst) : -1; +} + + +static void +print_dir_entry(struct de *de) +{ + char size[64], mod[64], href[PATH_MAX]; + struct tm *tm; + + if (de->file.is_directory) { + mg_snprintf(de->conn, + NULL, /* Buffer is big enough */ + size, + sizeof(size), + "%s", + "[DIRECTORY]"); + } else { + /* We use (signed) cast below because MSVC 6 compiler cannot + * convert unsigned __int64 to double. Sigh. */ + if (de->file.size < 1024) { + mg_snprintf(de->conn, + NULL, /* Buffer is big enough */ + size, + sizeof(size), + "%d", + (int)de->file.size); + } else if (de->file.size < 0x100000) { + mg_snprintf(de->conn, + NULL, /* Buffer is big enough */ + size, + sizeof(size), + "%.1fk", + (double)de->file.size / 1024.0); + } else if (de->file.size < 0x40000000) { + mg_snprintf(de->conn, + NULL, /* Buffer is big enough */ + size, + sizeof(size), + "%.1fM", + (double)de->file.size / 1048576); + } else { + mg_snprintf(de->conn, + NULL, /* Buffer is big enough */ + size, + sizeof(size), + "%.1fG", + (double)de->file.size / 1073741824); + } + } + + /* Note: mg_snprintf will not cause a buffer overflow above. + * So, string truncation checks are not required here. */ + + tm = localtime(&de->file.last_modified); + if (tm != NULL) { + strftime(mod, sizeof(mod), "%d-%b-%Y %H:%M", tm); + } else { + mg_strlcpy(mod, "01-Jan-1970 00:00", sizeof(mod)); + mod[sizeof(mod) - 1] = '\0'; + } + mg_url_encode(de->file_name, href, sizeof(href)); + de->conn->num_bytes_sent += + mg_printf(de->conn, + "%s%s" + " %s  %s\n", + de->conn->request_info.local_uri, + href, + de->file.is_directory ? "/" : "", + de->file_name, + de->file.is_directory ? "/" : "", + mod, + size); +} + + +/* This function is called from send_directory() and used for + * sorting directory entries by size, or name, or modification time. + * On windows, __cdecl specification is needed in case if project is built + * with __stdcall convention. qsort always requires __cdels callback. */ +static int WINCDECL +compare_dir_entries(const void *p1, const void *p2) +{ + if (p1 && p2) { + const struct de *a = (const struct de *)p1, *b = (const struct de *)p2; + const char *query_string = a->conn->request_info.query_string; + int cmp_result = 0; + + if (query_string == NULL) { + query_string = "na"; + } + + if (a->file.is_directory && !b->file.is_directory) { + return -1; /* Always put directories on top */ + } else if (!a->file.is_directory && b->file.is_directory) { + return 1; /* Always put directories on top */ + } else if (*query_string == 'n') { + cmp_result = strcmp(a->file_name, b->file_name); + } else if (*query_string == 's') { + cmp_result = a->file.size == b->file.size + ? 0 + : a->file.size > b->file.size ? 1 : -1; + } else if (*query_string == 'd') { + cmp_result = + (a->file.last_modified == b->file.last_modified) + ? 0 + : ((a->file.last_modified > b->file.last_modified) ? 1 + : -1); + } + + return query_string[1] == 'd' ? -cmp_result : cmp_result; + } + return 0; +} + + +static int +must_hide_file(struct mg_connection *conn, const char *path) +{ + if (conn && conn->ctx) { + const char *pw_pattern = "**" PASSWORDS_FILE_NAME "$"; + const char *pattern = conn->ctx->config[HIDE_FILES]; + return match_prefix(pw_pattern, strlen(pw_pattern), path) > 0 + || (pattern != NULL + && match_prefix(pattern, strlen(pattern), path) > 0); + } + return 0; +} + + +static int +scan_directory(struct mg_connection *conn, + const char *dir, + void *data, + void (*cb)(struct de *, void *)) +{ + char path[PATH_MAX]; + struct dirent *dp; + DIR *dirp; + struct de de; + int truncated; + + if ((dirp = mg_opendir(conn, dir)) == NULL) { + return 0; + } else { + de.conn = conn; + + while ((dp = mg_readdir(dirp)) != NULL) { + /* Do not show current dir and hidden files */ + if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..") + || must_hide_file(conn, dp->d_name)) { + continue; + } + + mg_snprintf( + conn, &truncated, path, sizeof(path), "%s/%s", dir, dp->d_name); + + /* If we don't memset stat structure to zero, mtime will have + * garbage and strftime() will segfault later on in + * print_dir_entry(). memset is required only if mg_stat() + * fails. For more details, see + * http://code.google.com/p/mongoose/issues/detail?id=79 */ + memset(&de.file, 0, sizeof(de.file)); + + if (truncated) { + /* If the path is not complete, skip processing. */ + continue; + } + + if (!mg_stat(conn, path, &de.file)) { + mg_cry(conn, + "%s: mg_stat(%s) failed: %s", + __func__, + path, + strerror(ERRNO)); + } + de.file_name = dp->d_name; + cb(&de, data); + } + (void)mg_closedir(dirp); + } + return 1; +} + + +#if !defined(NO_FILES) +static int +remove_directory(struct mg_connection *conn, const char *dir) +{ + char path[PATH_MAX]; + struct dirent *dp; + DIR *dirp; + struct de de; + int truncated; + int ok = 1; + + if ((dirp = mg_opendir(conn, dir)) == NULL) { + return 0; + } else { + de.conn = conn; + + while ((dp = mg_readdir(dirp)) != NULL) { + /* Do not show current dir (but show hidden files as they will + * also be removed) */ + if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) { + continue; + } + + mg_snprintf( + conn, &truncated, path, sizeof(path), "%s/%s", dir, dp->d_name); + + /* If we don't memset stat structure to zero, mtime will have + * garbage and strftime() will segfault later on in + * print_dir_entry(). memset is required only if mg_stat() + * fails. For more details, see + * http://code.google.com/p/mongoose/issues/detail?id=79 */ + memset(&de.file, 0, sizeof(de.file)); + + if (truncated) { + /* Do not delete anything shorter */ + ok = 0; + continue; + } + + if (!mg_stat(conn, path, &de.file)) { + mg_cry(conn, + "%s: mg_stat(%s) failed: %s", + __func__, + path, + strerror(ERRNO)); + ok = 0; + } + if (de.file.membuf == NULL) { + /* file is not in memory */ + if (de.file.is_directory) { + if (remove_directory(conn, path) == 0) { + ok = 0; + } + } else { + if (mg_remove(conn, path) == 0) { + ok = 0; + } + } + } else { + /* file is in memory. It can not be deleted. */ + ok = 0; + } + } + (void)mg_closedir(dirp); + + IGNORE_UNUSED_RESULT(rmdir(dir)); + } + + return ok; +} +#endif + + +struct dir_scan_data { + struct de *entries; + unsigned int num_entries; + unsigned int arr_size; +}; + + +/* Behaves like realloc(), but frees original pointer on failure */ +static void * +realloc2(void *ptr, size_t size) +{ + void *new_ptr = mg_realloc(ptr, size); + if (new_ptr == NULL) { + mg_free(ptr); + } + return new_ptr; +} + + +static void +dir_scan_callback(struct de *de, void *data) +{ + struct dir_scan_data *dsd = (struct dir_scan_data *)data; + + if (dsd->entries == NULL || dsd->num_entries >= dsd->arr_size) { + dsd->arr_size *= 2; + dsd->entries = + (struct de *)realloc2(dsd->entries, + dsd->arr_size * sizeof(dsd->entries[0])); + } + if (dsd->entries == NULL) { + /* TODO(lsm, low): propagate an error to the caller */ + dsd->num_entries = 0; + } else { + dsd->entries[dsd->num_entries].file_name = mg_strdup(de->file_name); + dsd->entries[dsd->num_entries].file = de->file; + dsd->entries[dsd->num_entries].conn = de->conn; + dsd->num_entries++; + } +} + + +static void +handle_directory_request(struct mg_connection *conn, const char *dir) +{ + unsigned int i; + int sort_direction; + struct dir_scan_data data = {NULL, 0, 128}; + char date[64]; + time_t curtime = time(NULL); + + if (!scan_directory(conn, dir, &data, dir_scan_callback)) { + send_http_error(conn, + 500, + "Error: Cannot open directory\nopendir(%s): %s", + dir, + strerror(ERRNO)); + return; + } + + gmt_time_string(date, sizeof(date), &curtime); + + if (!conn) { + return; + } + + sort_direction = conn->request_info.query_string != NULL + && conn->request_info.query_string[1] == 'd' + ? 'a' + : 'd'; + + conn->must_close = 1; + mg_printf(conn, "HTTP/1.1 200 OK\r\n"); + send_static_cache_header(conn); + mg_printf(conn, + "Date: %s\r\n" + "Connection: close\r\n" + "Content-Type: text/html; charset=utf-8\r\n\r\n", + date); + + conn->num_bytes_sent += + mg_printf(conn, + "Index of %s" + "" + "

Index of %s

"
+	              ""
+	              ""
+	              ""
+	              "",
+	              conn->request_info.local_uri,
+	              conn->request_info.local_uri,
+	              sort_direction,
+	              sort_direction,
+	              sort_direction);
+
+	/* Print first entry - link to a parent directory */
+	conn->num_bytes_sent +=
+	    mg_printf(conn,
+	              ""
+	              "\n",
+	              conn->request_info.local_uri,
+	              "..",
+	              "Parent directory",
+	              "-",
+	              "-");
+
+	/* Sort and print directory entries */
+	if (data.entries != NULL) {
+		qsort(data.entries,
+		      (size_t)data.num_entries,
+		      sizeof(data.entries[0]),
+		      compare_dir_entries);
+		for (i = 0; i < data.num_entries; i++) {
+			print_dir_entry(&data.entries[i]);
+			mg_free(data.entries[i].file_name);
+		}
+		mg_free(data.entries);
+	}
+
+	conn->num_bytes_sent += mg_printf(conn, "%s", "
NameModifiedSize

%s %s  %s
"); + conn->status_code = 200; +} + + +/* Send len bytes from the opened file to the client. */ +static void +send_file_data(struct mg_connection *conn, + struct file *filep, + int64_t offset, + int64_t len) +{ + char buf[MG_BUF_LEN]; + int to_read, num_read, num_written; + int64_t size; + + if (!filep || !conn) { + return; + } + + /* Sanity check the offset */ + size = filep->size > INT64_MAX ? INT64_MAX : (int64_t)(filep->size); + offset = offset < 0 ? 0 : offset > size ? size : offset; + + if (len > 0 && filep->membuf != NULL && size > 0) { + /* file stored in memory */ + if (len > size - offset) { + len = size - offset; + } + mg_write(conn, filep->membuf + offset, (size_t)len); + } else if (len > 0 && filep->fp != NULL) { +/* file stored on disk */ +#if defined(__linux__) + /* sendfile is only available for Linux */ + if (conn->throttle == 0 && conn->ssl == 0) { + off_t sf_offs = (off_t)offset; + ssize_t sf_sent; + int sf_file = fileno(filep->fp); + int loop_cnt = 0; + + do { + /* 2147479552 (0x7FFFF000) is a limit found by experiment on + * 64 bit Linux (2^31 minus one memory page of 4k?). */ + size_t sf_tosend = + (size_t)((len < 0x7FFFF000) ? len : 0x7FFFF000); + sf_sent = + sendfile(conn->client.sock, sf_file, &sf_offs, sf_tosend); + if (sf_sent > 0) { + conn->num_bytes_sent += sf_sent; + len -= sf_sent; + offset += sf_sent; + } else if (loop_cnt == 0) { + /* This file can not be sent using sendfile. + * This might be the case for pseudo-files in the + * /sys/ and /proc/ file system. + * Use the regular user mode copy code instead. */ + break; + } else if (sf_sent == 0) { + /* No error, but 0 bytes sent. May be EOF? */ + return; + } + loop_cnt++; + + } while ((len > 0) && (sf_sent >= 0)); + + if (sf_sent > 0) { + return; /* OK */ + } + + /* sf_sent<0 means error, thus fall back to the classic way */ + /* This is always the case, if sf_file is not a "normal" file, + * e.g., for sending data from the output of a CGI process. */ + offset = (int64_t)sf_offs; + } +#endif + if ((offset > 0) && (fseeko(filep->fp, offset, SEEK_SET) != 0)) { + mg_cry(conn, "%s: fseeko() failed: %s", __func__, strerror(ERRNO)); + send_http_error( + conn, + 500, + "%s", + "Error: Unable to access file at requested position."); + } else { + while (len > 0) { + /* Calculate how much to read from the file in the buffer */ + to_read = sizeof(buf); + if ((int64_t)to_read > len) { + to_read = (int)len; + } + + /* Read from file, exit the loop on error */ + if ((num_read = (int)fread(buf, 1, (size_t)to_read, filep->fp)) + <= 0) { + break; + } + + /* Send read bytes to the client, exit the loop on error */ + if ((num_written = mg_write(conn, buf, (size_t)num_read)) + != num_read) { + break; + } + + /* Both read and were successful, adjust counters */ + conn->num_bytes_sent += num_written; + len -= num_written; + } + } + } +} + + +static int +parse_range_header(const char *header, int64_t *a, int64_t *b) +{ + return sscanf(header, "bytes=%" INT64_FMT "-%" INT64_FMT, a, b); +} + + +static void +construct_etag(char *buf, size_t buf_len, const struct file *filep) +{ + if (filep != NULL && buf != NULL) { + mg_snprintf(NULL, + NULL, /* All calls to construct_etag use 64 byte buffer */ + buf, + buf_len, + "\"%lx.%" INT64_FMT "\"", + (unsigned long)filep->last_modified, + filep->size); + } +} + + +static void +fclose_on_exec(struct file *filep, struct mg_connection *conn) +{ + if (filep != NULL && filep->fp != NULL) { +#ifdef _WIN32 + (void)conn; /* Unused. */ +#else + if (fcntl(fileno(filep->fp), F_SETFD, FD_CLOEXEC) != 0) { + mg_cry(conn, + "%s: fcntl(F_SETFD FD_CLOEXEC) failed: %s", + __func__, + strerror(ERRNO)); + } +#endif + } +} + + +static void +handle_static_file_request(struct mg_connection *conn, + const char *path, + struct file *filep, + const char *mime_type) +{ + char date[64], lm[64], etag[64]; + char range[128]; /* large enough, so there will be no overflow */ + const char *msg = "OK", *hdr; + time_t curtime = time(NULL); + int64_t cl, r1, r2; + struct vec mime_vec; + int n, truncated; + char gz_path[PATH_MAX]; + const char *encoding = ""; + const char *cors1, *cors2, *cors3; + + if (conn == NULL || conn->ctx == NULL || filep == NULL) { + return; + } + + if (mime_type == NULL) { + get_mime_type(conn->ctx, path, &mime_vec); + } else { + mime_vec.ptr = mime_type; + mime_vec.len = strlen(mime_type); + } + if (filep->size > INT64_MAX) { + send_http_error(conn, + 500, + "Error: File size is too large to send\n%" INT64_FMT, + filep->size); + } + cl = (int64_t)filep->size; + conn->status_code = 200; + range[0] = '\0'; + + /* if this file is in fact a pre-gzipped file, rewrite its filename + * it's important to rewrite the filename after resolving + * the mime type from it, to preserve the actual file's type */ + if (filep->gzipped) { + mg_snprintf(conn, &truncated, gz_path, sizeof(gz_path), "%s.gz", path); + + if (truncated) { + send_http_error(conn, + 500, + "Error: Path of zipped file too long (%s)", + path); + return; + } + + path = gz_path; + encoding = "Content-Encoding: gzip\r\n"; + } + + if (!mg_fopen(conn, path, "rb", filep)) { + send_http_error(conn, + 500, + "Error: Cannot open file\nfopen(%s): %s", + path, + strerror(ERRNO)); + return; + } + + fclose_on_exec(filep, conn); + + /* If Range: header specified, act accordingly */ + r1 = r2 = 0; + hdr = mg_get_header(conn, "Range"); + if (hdr != NULL && (n = parse_range_header(hdr, &r1, &r2)) > 0 && r1 >= 0 + && r2 >= 0) { + /* actually, range requests don't play well with a pre-gzipped + * file (since the range is specified in the uncompressed space) */ + if (filep->gzipped) { + send_http_error( + conn, + 501, + "%s", + "Error: Range requests in gzipped files are not supported"); + mg_fclose(filep); + return; + } + conn->status_code = 206; + cl = n == 2 ? (r2 > cl ? cl : r2) - r1 + 1 : cl - r1; + mg_snprintf(conn, + NULL, /* range buffer is big enough */ + range, + sizeof(range), + "Content-Range: bytes " + "%" INT64_FMT "-%" INT64_FMT "/%" INT64_FMT "\r\n", + r1, + r1 + cl - 1, + filep->size); + msg = "Partial Content"; + } + + hdr = mg_get_header(conn, "Origin"); + if (hdr) { + /* Cross-origin resource sharing (CORS), see + * http://www.html5rocks.com/en/tutorials/cors/, + * http://www.html5rocks.com/static/images/cors_server_flowchart.png - + * preflight is not supported for files. */ + cors1 = "Access-Control-Allow-Origin: "; + cors2 = conn->ctx->config[ACCESS_CONTROL_ALLOW_ORIGIN]; + cors3 = "\r\n"; + } else { + cors1 = cors2 = cors3 = ""; + } + + /* Prepare Etag, Date, Last-Modified headers. Must be in UTC, according to + * http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3 */ + gmt_time_string(date, sizeof(date), &curtime); + gmt_time_string(lm, sizeof(lm), &filep->last_modified); + construct_etag(etag, sizeof(etag), filep); + + (void)mg_printf(conn, + "HTTP/1.1 %d %s\r\n" + "%s%s%s" + "Date: %s\r\n", + conn->status_code, + msg, + cors1, + cors2, + cors3, + date); + send_static_cache_header(conn); + (void)mg_printf(conn, + "Last-Modified: %s\r\n" + "Etag: %s\r\n" + "Content-Type: %.*s\r\n" + "Content-Length: %" INT64_FMT "\r\n" + "Connection: %s\r\n" + "Accept-Ranges: bytes\r\n" + "%s%s\r\n", + lm, + etag, + (int)mime_vec.len, + mime_vec.ptr, + cl, + suggest_connection_header(conn), + range, + encoding); + + if (strcmp(conn->request_info.request_method, "HEAD") != 0) { + send_file_data(conn, filep, r1, cl); + } + mg_fclose(filep); +} + + +void +mg_send_file(struct mg_connection *conn, const char *path) +{ + mg_send_mime_file(conn, path, NULL); +} + + +void +mg_send_mime_file(struct mg_connection *conn, + const char *path, + const char *mime_type) +{ + struct file file = STRUCT_FILE_INITIALIZER; + if (mg_stat(conn, path, &file)) { + if (file.is_directory) { + if (!conn) { + return; + } + if (!mg_strcasecmp(conn->ctx->config[ENABLE_DIRECTORY_LISTING], + "yes")) { + handle_directory_request(conn, path); + } else { + send_http_error(conn, + 403, + "%s", + "Error: Directory listing denied"); + } + } else { + handle_static_file_request(conn, path, &file, mime_type); + } + } else { + send_http_error(conn, 404, "%s", "Error: File not found"); + } +} + + +/* For a given PUT path, create all intermediate subdirectories. + * Return 0 if the path itself is a directory. + * Return 1 if the path leads to a file. + * Return -1 for if the path is too long. + * Return -2 if path can not be created. +*/ +static int +put_dir(struct mg_connection *conn, const char *path) +{ + char buf[PATH_MAX]; + const char *s, *p; + struct file file = STRUCT_FILE_INITIALIZER; + size_t len; + int res = 1; + + for (s = p = path + 2; (p = strchr(s, '/')) != NULL; s = ++p) { + len = (size_t)(p - path); + if (len >= sizeof(buf)) { + /* path too long */ + res = -1; + break; + } + memcpy(buf, path, len); + buf[len] = '\0'; + + /* Try to create intermediate directory */ + DEBUG_TRACE("mkdir(%s)", buf); + if (!mg_stat(conn, buf, &file) && mg_mkdir(conn, buf, 0755) != 0) { + /* path does not exixt and can not be created */ + res = -2; + break; + } + + /* Is path itself a directory? */ + if (p[1] == '\0') { + res = 0; + } + } + + return res; +} + + +static void +remove_bad_file(const struct mg_connection *conn, const char *path) +{ + int r = mg_remove(conn, path); + if (r != 0) { + mg_cry(conn, "%s: Cannot remove invalid file %s", __func__, path); + } +} + + +long long +mg_store_body(struct mg_connection *conn, const char *path) +{ + char buf[MG_BUF_LEN]; + long long len = 0; + int ret, n; + struct file fi; + + if (conn->consumed_content != 0) { + mg_cry(conn, "%s: Contents already consumed", __func__); + return -11; + } + + ret = put_dir(conn, path); + if (ret < 0) { + /* -1 for path too long, + * -2 for path can not be created. */ + return ret; + } + if (ret != 1) { + /* Return 0 means, path itself is a directory. */ + return 0; + } + + if (mg_fopen(conn, path, "w", &fi) == 0) { + return -12; + } + + ret = mg_read(conn, buf, sizeof(buf)); + while (ret > 0) { + n = (int)fwrite(buf, 1, (size_t)ret, fi.fp); + if (n != ret) { + mg_fclose(&fi); + remove_bad_file(conn, path); + return -13; + } + ret = mg_read(conn, buf, sizeof(buf)); + } + + /* TODO: mg_fclose should return an error, + * and every caller should check and handle it. */ + if (fclose(fi.fp) != 0) { + remove_bad_file(conn, path); + return -14; + } + + return len; +} + + +/* Parse HTTP headers from the given buffer, advance buffer to the point + * where parsing stopped. */ +static void +parse_http_headers(char **buf, struct mg_request_info *ri) +{ + int i; + + if (!ri) { + return; + } + + ri->num_headers = 0; + + for (i = 0; i < (int)ARRAY_SIZE(ri->http_headers); i++) { + char *dp = *buf; + while ((*dp != ':') && (*dp != '\r') && (*dp != 0)) { + dp++; + } + if (!*dp) { + /* neither : nor \r\n. This is not a valid field. */ + break; + } + if (*dp == '\r') { + if (dp[1] == '\n') { + /* \r\n */ + ri->http_headers[i].name = *buf; + ri->http_headers[i].value = 0; + *buf = dp; + } else { + /* stray \r. This is not valid. */ + break; + } + } else { + /* (*dp == ':') */ + *dp = 0; + ri->http_headers[i].name = *buf; + do { + dp++; + } while (*dp == ' '); + + ri->http_headers[i].value = dp; + *buf = strstr(dp, "\r\n"); + } + + ri->num_headers = i + 1; + if (*buf) { + (*buf)[0] = 0; + (*buf)[1] = 0; + *buf += 2; + } else { + *buf = dp; + break; + } + + if (*buf[0] == '\r') { + /* This is the end of the header */ + break; + } + } +} + + +static int +is_valid_http_method(const char *method) +{ + return !strcmp(method, "GET") /* HTTP (RFC 2616) */ + || !strcmp(method, "POST") /* HTTP (RFC 2616) */ + || !strcmp(method, "HEAD") /* HTTP (RFC 2616) */ + || !strcmp(method, "PUT") /* HTTP (RFC 2616) */ + || !strcmp(method, "DELETE") /* HTTP (RFC 2616) */ + || !strcmp(method, "OPTIONS") /* HTTP (RFC 2616) */ + /* TRACE method (RFC 2616) is not supported for security reasons */ + || !strcmp(method, "CONNECT") /* HTTP (RFC 2616) */ + + || !strcmp(method, "PROPFIND") /* WEBDAV (RFC 2518) */ + || !strcmp(method, "MKCOL") /* WEBDAV (RFC 2518) */ + + /* Unsupported WEBDAV Methods: */ + /* PROPPATCH, COPY, MOVE, LOCK, UNLOCK (RFC 2518) */ + /* + 11 methods from RFC 3253 */ + /* ORDERPATCH (RFC 3648) */ + /* ACL (RFC 3744) */ + /* SEARCH (RFC 5323) */ + /* + MicroSoft extensions + * https://msdn.microsoft.com/en-us/library/aa142917.aspx */ + + /* PATCH method only allowed for CGI/Lua/LSP and callbacks. */ + || !strcmp(method, "PATCH"); /* PATCH method (RFC 5789) */ +} + + +/* Parse HTTP request, fill in mg_request_info structure. + * This function modifies the buffer by NUL-terminating + * HTTP request components, header names and header values. */ +static int +parse_http_message(char *buf, int len, struct mg_request_info *ri) +{ + int is_request, request_length; + + if (!ri) { + return 0; + } + + request_length = get_request_len(buf, len); + + if (request_length > 0) { + /* Reset attributes. DO NOT TOUCH is_ssl, remote_ip, remote_addr, + * remote_port */ + ri->remote_user = ri->request_method = ri->request_uri = + ri->http_version = NULL; + ri->num_headers = 0; + + buf[request_length - 1] = '\0'; + + /* RFC says that all initial whitespaces should be ingored */ + while (*buf != '\0' && isspace(*(unsigned char *)buf)) { + buf++; + } + ri->request_method = skip(&buf, " "); + ri->request_uri = skip(&buf, " "); + ri->http_version = skip(&buf, "\r\n"); + + /* HTTP message could be either HTTP request or HTTP response, e.g. + * "GET / HTTP/1.0 ...." or "HTTP/1.0 200 OK ..." */ + is_request = is_valid_http_method(ri->request_method); + if ((is_request && memcmp(ri->http_version, "HTTP/", 5) != 0) + || (!is_request && memcmp(ri->request_method, "HTTP/", 5) != 0)) { + request_length = -1; + } else { + if (is_request) { + ri->http_version += 5; + } + parse_http_headers(&buf, ri); + } + } + return request_length; +} + + +/* Keep reading the input (either opened file descriptor fd, or socket sock, + * or SSL descriptor ssl) into buffer buf, until \r\n\r\n appears in the + * buffer (which marks the end of HTTP request). Buffer buf may already + * have some data. The length of the data is stored in nread. + * Upon every read operation, increase nread by the number of bytes read. */ +static int +read_request(FILE *fp, + struct mg_connection *conn, + char *buf, + int bufsiz, + int *nread) +{ + int request_len, n = 0; + struct timespec last_action_time; + double request_timeout; + + if (!conn) { + return 0; + } + + memset(&last_action_time, 0, sizeof(last_action_time)); + + if (conn->ctx->config[REQUEST_TIMEOUT]) { + /* value of request_timeout is in seconds, config in milliseconds */ + request_timeout = atof(conn->ctx->config[REQUEST_TIMEOUT]) / 1000.0; + } else { + request_timeout = -1.0; + } + + request_len = get_request_len(buf, *nread); + + /* first time reading from this connection */ + clock_gettime(CLOCK_MONOTONIC, &last_action_time); + + while ( + (conn->ctx->stop_flag == 0) && (*nread < bufsiz) && (request_len == 0) + && ((mg_difftimespec(&last_action_time, &(conn->req_time)) + <= request_timeout) || (request_timeout < 0)) + && ((n = pull(fp, conn, buf + *nread, bufsiz - *nread, request_timeout)) + > 0)) { + *nread += n; + /* assert(*nread <= bufsiz); */ + if (*nread > bufsiz) { + return -2; + } + request_len = get_request_len(buf, *nread); + if (request_timeout > 0.0) { + clock_gettime(CLOCK_MONOTONIC, &last_action_time); + } + } + + return (request_len <= 0 && n <= 0) ? -1 : request_len; +} + +#if !defined(NO_FILES) +/* For given directory path, substitute it to valid index file. + * Return 1 if index file has been found, 0 if not found. + * If the file is found, it's stats is returned in stp. */ +static int +substitute_index_file(struct mg_connection *conn, + char *path, + size_t path_len, + struct file *filep) +{ + if (conn && conn->ctx) { + const char *list = conn->ctx->config[INDEX_FILES]; + struct file file = STRUCT_FILE_INITIALIZER; + struct vec filename_vec; + size_t n = strlen(path); + int found = 0; + + /* The 'path' given to us points to the directory. Remove all trailing + * directory separator characters from the end of the path, and + * then append single directory separator character. */ + while (n > 0 && path[n - 1] == '/') { + n--; + } + path[n] = '/'; + + /* Traverse index files list. For each entry, append it to the given + * path and see if the file exists. If it exists, break the loop */ + while ((list = next_option(list, &filename_vec, NULL)) != NULL) { + /* Ignore too long entries that may overflow path buffer */ + if (filename_vec.len > path_len - (n + 2)) { + continue; + } + + /* Prepare full path to the index file */ + mg_strlcpy(path + n + 1, filename_vec.ptr, filename_vec.len + 1); + + /* Does it exist? */ + if (mg_stat(conn, path, &file)) { + /* Yes it does, break the loop */ + *filep = file; + found = 1; + break; + } + } + + /* If no index file exists, restore directory path */ + if (!found) { + path[n] = '\0'; + } + + return found; + } + return 0; +} +#endif + + +#if !defined(NO_CACHING) +/* Return True if we should reply 304 Not Modified. */ +static int +is_not_modified(const struct mg_connection *conn, const struct file *filep) +{ + char etag[64]; + const char *ims = mg_get_header(conn, "If-Modified-Since"); + const char *inm = mg_get_header(conn, "If-None-Match"); + construct_etag(etag, sizeof(etag), filep); + if (!filep) { + return 0; + } + return (inm != NULL && !mg_strcasecmp(etag, inm)) + || (ims != NULL && (filep->last_modified <= parse_date_string(ims))); +} +#endif /* !NO_CACHING */ + + +#if !defined(NO_CGI) || !defined(NO_FILES) +static int +forward_body_data(struct mg_connection *conn, FILE *fp, SOCKET sock, SSL *ssl) +{ + const char *expect, *body; + char buf[MG_BUF_LEN]; + int to_read, nread, success = 0; + int64_t buffered_len; + double timeout = -1.0; + + if (!conn) { + return 0; + } + if (conn->ctx->config[REQUEST_TIMEOUT]) { + timeout = atoi(conn->ctx->config[REQUEST_TIMEOUT]) / 1000.0; + } + + expect = mg_get_header(conn, "Expect"); + /* assert(fp != NULL); */ + if (!fp) { + send_http_error(conn, 500, "%s", "Error: NULL File"); + return 0; + } + + if (conn->content_len == -1 && !conn->is_chunked) { + /* Content length is not specified by the client. */ + send_http_error(conn, + 411, + "%s", + "Error: Client did not specify content length"); + } else if ((expect != NULL) + && (mg_strcasecmp(expect, "100-continue") != 0)) { + /* Client sent an "Expect: xyz" header and xyz is not 100-continue. */ + send_http_error(conn, + 417, + "Error: Can not fulfill expectation %s", + expect); + } else { + if (expect != NULL) { + (void)mg_printf(conn, "%s", "HTTP/1.1 100 Continue\r\n\r\n"); + conn->status_code = 100; + } else { + conn->status_code = 200; + } + + buffered_len = (int64_t)(conn->data_len) - (int64_t)conn->request_len + - conn->consumed_content; + + /* assert(buffered_len >= 0); */ + /* assert(conn->consumed_content == 0); */ + + if ((buffered_len < 0) || (conn->consumed_content != 0)) { + send_http_error(conn, 500, "%s", "Error: Size mismatch"); + return 0; + } + + if (buffered_len > 0) { + if ((int64_t)buffered_len > conn->content_len) { + buffered_len = (int)conn->content_len; + } + body = conn->buf + conn->request_len + conn->consumed_content; + push_all(conn->ctx, fp, sock, ssl, body, (int64_t)buffered_len); + conn->consumed_content += buffered_len; + } + + nread = 0; + while (conn->consumed_content < conn->content_len) { + to_read = sizeof(buf); + if ((int64_t)to_read > conn->content_len - conn->consumed_content) { + to_read = (int)(conn->content_len - conn->consumed_content); + } + nread = pull(NULL, conn, buf, to_read, timeout); + if (nread <= 0 + || push_all(conn->ctx, fp, sock, ssl, buf, nread) != nread) { + break; + } + conn->consumed_content += nread; + } + + if (conn->consumed_content == conn->content_len) { + success = (nread >= 0); + } + + /* Each error code path in this function must send an error */ + if (!success) { + /* NOTE: Maybe some data has already been sent. */ + /* TODO (low): If some data has been sent, a correct error + * reply can no longer be sent, so just close the connection */ + send_http_error(conn, 500, "%s", ""); + } + } + + return success; +} +#endif + +#if !defined(NO_CGI) +/* This structure helps to create an environment for the spawned CGI program. + * Environment is an array of "VARIABLE=VALUE\0" ASCIIZ strings, + * last element must be NULL. + * However, on Windows there is a requirement that all these VARIABLE=VALUE\0 + * strings must reside in a contiguous buffer. The end of the buffer is + * marked by two '\0' characters. + * We satisfy both worlds: we create an envp array (which is vars), all + * entries are actually pointers inside buf. */ +struct cgi_environment { + struct mg_connection *conn; + /* Data block */ + char *buf; /* Environment buffer */ + size_t buflen; /* Space available in buf */ + size_t bufused; /* Space taken in buf */ + /* Index block */ + char **var; /* char **envp */ + size_t varlen; /* Number of variables available in var */ + size_t varused; /* Number of variables stored in var */ +}; + + +static void addenv(struct cgi_environment *env, + PRINTF_FORMAT_STRING(const char *fmt), + ...) PRINTF_ARGS(2, 3); + +/* Append VARIABLE=VALUE\0 string to the buffer, and add a respective + * pointer into the vars array. Assumes env != NULL and fmt != NULL. */ +static void +addenv(struct cgi_environment *env, const char *fmt, ...) +{ + size_t n, space; + int truncated; + char *added; + va_list ap; + + /* Calculate how much space is left in the buffer */ + space = (env->buflen - env->bufused); + + /* Calculate an estimate for the required space */ + n = strlen(fmt) + 2 + 128; + + do { + if (space <= n) { + /* Allocate new buffer */ + n = env->buflen + CGI_ENVIRONMENT_SIZE; + added = (char *)mg_realloc(env->buf, n); + if (!added) { + /* Out of memory */ + mg_cry(env->conn, + "%s: Cannot allocate memory for CGI variable [%s]", + __func__, + fmt); + return; + } + env->buf = added; + env->buflen = n; + space = (env->buflen - env->bufused); + } + + /* Make a pointer to the free space int the buffer */ + added = env->buf + env->bufused; + + /* Copy VARIABLE=VALUE\0 string into the free space */ + va_start(ap, fmt); + mg_vsnprintf(env->conn, &truncated, added, (size_t)space, fmt, ap); + va_end(ap); + + /* Do not add truncated strings to the environment */ + if (truncated) { + /* Reallocate the buffer */ + space = 0; + n = 1; + } + } while (truncated); + + /* Calculate number of bytes added to the environment */ + n = strlen(added) + 1; + env->bufused += n; + + /* Now update the variable index */ + space = (env->varlen - env->varused); + if (space < 2) { + mg_cry(env->conn, + "%s: Cannot register CGI variable [%s]", + __func__, + fmt); + return; + } + + /* Append a pointer to the added string into the envp array */ + env->var[env->varused] = added; + env->varused++; +} + + +static void +prepare_cgi_environment(struct mg_connection *conn, + const char *prog, + struct cgi_environment *env) +{ + const char *s; + struct vec var_vec; + char *p, src_addr[IP_ADDR_STR_LEN], http_var_name[128]; + int i, truncated; + + if (conn == NULL || prog == NULL || env == NULL) { + return; + } + + env->conn = conn; + env->buflen = CGI_ENVIRONMENT_SIZE; + env->bufused = 0; + env->buf = (char *)mg_malloc(env->buflen); + env->varlen = MAX_CGI_ENVIR_VARS; + env->varused = 0; + env->var = (char **)mg_malloc(env->buflen * sizeof(char *)); + + addenv(env, "SERVER_NAME=%s", conn->ctx->config[AUTHENTICATION_DOMAIN]); + addenv(env, "SERVER_ROOT=%s", conn->ctx->config[DOCUMENT_ROOT]); + addenv(env, "DOCUMENT_ROOT=%s", conn->ctx->config[DOCUMENT_ROOT]); + addenv(env, "SERVER_SOFTWARE=%s/%s", "Civetweb", mg_version()); + + /* Prepare the environment block */ + addenv(env, "%s", "GATEWAY_INTERFACE=CGI/1.1"); + addenv(env, "%s", "SERVER_PROTOCOL=HTTP/1.1"); + addenv(env, "%s", "REDIRECT_STATUS=200"); /* For PHP */ + +#if defined(USE_IPV6) + if (conn->client.lsa.sa.sa_family == AF_INET6) { + addenv(env, "SERVER_PORT=%d", ntohs(conn->client.lsa.sin6.sin6_port)); + } else +#endif + { + addenv(env, "SERVER_PORT=%d", ntohs(conn->client.lsa.sin.sin_port)); + } + + sockaddr_to_string(src_addr, sizeof(src_addr), &conn->client.rsa); + addenv(env, "REMOTE_ADDR=%s", src_addr); + + addenv(env, "REQUEST_METHOD=%s", conn->request_info.request_method); + addenv(env, "REMOTE_PORT=%d", conn->request_info.remote_port); + + addenv(env, "REQUEST_URI=%s", conn->request_info.request_uri); + addenv(env, "LOCAL_URI=%s", conn->request_info.local_uri); + + /* SCRIPT_NAME */ + addenv(env, + "SCRIPT_NAME=%.*s", + (int)strlen(conn->request_info.local_uri) + - ((conn->path_info == NULL) ? 0 : (int)strlen(conn->path_info)), + conn->request_info.local_uri); + + addenv(env, "SCRIPT_FILENAME=%s", prog); + if (conn->path_info == NULL) { + addenv(env, "PATH_TRANSLATED=%s", conn->ctx->config[DOCUMENT_ROOT]); + } else { + addenv(env, + "PATH_TRANSLATED=%s%s", + conn->ctx->config[DOCUMENT_ROOT], + conn->path_info); + } + + addenv(env, "HTTPS=%s", conn->ssl == NULL ? "off" : "on"); + + if ((s = mg_get_header(conn, "Content-Type")) != NULL) { + addenv(env, "CONTENT_TYPE=%s", s); + } + if (conn->request_info.query_string != NULL) { + addenv(env, "QUERY_STRING=%s", conn->request_info.query_string); + } + if ((s = mg_get_header(conn, "Content-Length")) != NULL) { + addenv(env, "CONTENT_LENGTH=%s", s); + } + if ((s = getenv("PATH")) != NULL) { + addenv(env, "PATH=%s", s); + } + if (conn->path_info != NULL) { + addenv(env, "PATH_INFO=%s", conn->path_info); + } + + if (conn->status_code > 0) { + /* CGI error handler should show the status code */ + addenv(env, "STATUS=%d", conn->status_code); + } + +#if defined(_WIN32) + if ((s = getenv("COMSPEC")) != NULL) { + addenv(env, "COMSPEC=%s", s); + } + if ((s = getenv("SYSTEMROOT")) != NULL) { + addenv(env, "SYSTEMROOT=%s", s); + } + if ((s = getenv("SystemDrive")) != NULL) { + addenv(env, "SystemDrive=%s", s); + } + if ((s = getenv("ProgramFiles")) != NULL) { + addenv(env, "ProgramFiles=%s", s); + } + if ((s = getenv("ProgramFiles(x86)")) != NULL) { + addenv(env, "ProgramFiles(x86)=%s", s); + } +#else + if ((s = getenv("LD_LIBRARY_PATH")) != NULL) { + addenv(env, "LD_LIBRARY_PATH=%s", s); + } +#endif /* _WIN32 */ + + if ((s = getenv("PERLLIB")) != NULL) { + addenv(env, "PERLLIB=%s", s); + } + + if (conn->request_info.remote_user != NULL) { + addenv(env, "REMOTE_USER=%s", conn->request_info.remote_user); + addenv(env, "%s", "AUTH_TYPE=Digest"); + } + + /* Add all headers as HTTP_* variables */ + for (i = 0; i < conn->request_info.num_headers; i++) { + + (void)mg_snprintf(conn, + &truncated, + http_var_name, + sizeof(http_var_name), + "HTTP_%s", + conn->request_info.http_headers[i].name); + + if (truncated) { + mg_cry(conn, + "%s: HTTP header variable too long [%s]", + __func__, + conn->request_info.http_headers[i].name); + continue; + } + + /* Convert variable name into uppercase, and change - to _ */ + for (p = http_var_name; *p != '\0'; p++) { + if (*p == '-') { + *p = '_'; + } + *p = (char)toupper(*(unsigned char *)p); + } + + addenv(env, + "%s=%s", + http_var_name, + conn->request_info.http_headers[i].value); + } + + /* Add user-specified variables */ + s = conn->ctx->config[CGI_ENVIRONMENT]; + while ((s = next_option(s, &var_vec, NULL)) != NULL) { + addenv(env, "%.*s", (int)var_vec.len, var_vec.ptr); + } + + env->var[env->varused] = NULL; + env->buf[env->bufused] = '\0'; +} + + +static void +handle_cgi_request(struct mg_connection *conn, const char *prog) +{ + char *buf; + size_t buflen; + int headers_len, data_len, i, truncated; + int fdin[2] = {-1, -1}, fdout[2] = {-1, -1}, fderr[2] = {-1, -1}; + const char *status, *status_text, *connection_state; + char *pbuf, dir[PATH_MAX], *p; + struct mg_request_info ri; + struct cgi_environment blk; + FILE *in = NULL, *out = NULL, *err = NULL; + struct file fout = STRUCT_FILE_INITIALIZER; + pid_t pid = (pid_t)-1; + + if (conn == NULL) { + return; + } + + buf = NULL; + buflen = 16384; + prepare_cgi_environment(conn, prog, &blk); + + /* CGI must be executed in its own directory. 'dir' must point to the + * directory containing executable program, 'p' must point to the + * executable program name relative to 'dir'. */ + (void)mg_snprintf(conn, &truncated, dir, sizeof(dir), "%s", prog); + + if (truncated) { + mg_cry(conn, "Error: CGI program \"%s\": Path too long", prog); + send_http_error(conn, 500, "Error: %s", "CGI path too long"); + goto done; + } + + if ((p = strrchr(dir, '/')) != NULL) { + *p++ = '\0'; + } else { + dir[0] = '.', dir[1] = '\0'; + p = (char *)prog; + } + + if (pipe(fdin) != 0 || pipe(fdout) != 0 || pipe(fderr) != 0) { + status = strerror(ERRNO); + mg_cry(conn, + "Error: CGI program \"%s\": Can not create CGI pipes: %s", + prog, + status); + send_http_error(conn, 500, "Error: Cannot create CGI pipe: %s", status); + goto done; + } + + pid = spawn_process(conn, p, blk.buf, blk.var, fdin, fdout, fderr, dir); + + if (pid == (pid_t)-1) { + status = strerror(ERRNO); + mg_cry(conn, + "Error: CGI program \"%s\": Can not spawn CGI process: %s", + prog, + status); + send_http_error(conn, + 500, + "Error: Cannot spawn CGI process [%s]: %s", + prog, + status); + goto done; + } + + /* Make sure child closes all pipe descriptors. It must dup them to 0,1 */ + set_close_on_exec((SOCKET)fdin[0], conn); /* stdin read */ + set_close_on_exec((SOCKET)fdout[1], conn); /* stdout write */ + set_close_on_exec((SOCKET)fderr[1], conn); /* stderr write */ + set_close_on_exec((SOCKET)fdin[1], conn); /* stdin write */ + set_close_on_exec((SOCKET)fdout[0], conn); /* stdout read */ + set_close_on_exec((SOCKET)fderr[0], conn); /* stderr read */ + + /* Parent closes only one side of the pipes. + * If we don't mark them as closed, close() attempt before + * return from this function throws an exception on Windows. + * Windows does not like when closed descriptor is closed again. */ + (void)close(fdin[0]); + (void)close(fdout[1]); + (void)close(fderr[1]); + fdin[0] = fdout[1] = fderr[1] = -1; + + if ((in = fdopen(fdin[1], "wb")) == NULL) { + status = strerror(ERRNO); + mg_cry(conn, + "Error: CGI program \"%s\": Can not open stdin: %s", + prog, + status); + send_http_error(conn, + 500, + "Error: CGI can not open fdin\nfopen: %s", + status); + goto done; + } + + if ((out = fdopen(fdout[0], "rb")) == NULL) { + status = strerror(ERRNO); + mg_cry(conn, + "Error: CGI program \"%s\": Can not open stdout: %s", + prog, + status); + send_http_error(conn, + 500, + "Error: CGI can not open fdout\nfopen: %s", + status); + goto done; + } + + if ((err = fdopen(fderr[0], "rb")) == NULL) { + status = strerror(ERRNO); + mg_cry(conn, + "Error: CGI program \"%s\": Can not open stderr: %s", + prog, + status); + send_http_error(conn, + 500, + "Error: CGI can not open fdout\nfopen: %s", + status); + goto done; + } + + setbuf(in, NULL); + setbuf(out, NULL); + setbuf(err, NULL); + fout.fp = out; + + if ((conn->request_info.content_length > 0) || conn->is_chunked) { + /* This is a POST/PUT request, or another request with body data. */ + if (!forward_body_data(conn, in, INVALID_SOCKET, NULL)) { + /* Error sending the body data */ + mg_cry(conn, + "Error: CGI program \"%s\": Forward body data failed", + prog); + goto done; + } + } + + /* Close so child gets an EOF. */ + fclose(in); + in = NULL; + fdin[1] = -1; + + /* Now read CGI reply into a buffer. We need to set correct + * status code, thus we need to see all HTTP headers first. + * Do not send anything back to client, until we buffer in all + * HTTP headers. */ + data_len = 0; + buf = (char *)mg_malloc(buflen); + if (buf == NULL) { + send_http_error(conn, + 500, + "Error: Not enough memory for CGI buffer (%u bytes)", + (unsigned int)buflen); + mg_cry(conn, + "Error: CGI program \"%s\": Not enough memory for buffer (%u " + "bytes)", + prog, + (unsigned int)buflen); + goto done; + } + headers_len = read_request(out, conn, buf, (int)buflen, &data_len); + if (headers_len <= 0) { + + /* Could not parse the CGI response. Check if some error message on + * stderr. */ + i = pull_all(err, conn, buf, (int)buflen); + if (i > 0) { + mg_cry(conn, + "Error: CGI program \"%s\" sent error " + "message: [%.*s]", + prog, + i, + buf); + send_http_error(conn, + 500, + "Error: CGI program \"%s\" sent error " + "message: [%.*s]", + prog, + i, + buf); + } else { + mg_cry(conn, + "Error: CGI program sent malformed or too big " + "(>%u bytes) HTTP headers: [%.*s]", + (unsigned)buflen, + data_len, + buf); + + send_http_error(conn, + 500, + "Error: CGI program sent malformed or too big " + "(>%u bytes) HTTP headers: [%.*s]", + (unsigned)buflen, + data_len, + buf); + } + + goto done; + } + pbuf = buf; + buf[headers_len - 1] = '\0'; + parse_http_headers(&pbuf, &ri); + + /* Make up and send the status line */ + status_text = "OK"; + if ((status = get_header(&ri, "Status")) != NULL) { + conn->status_code = atoi(status); + status_text = status; + while (isdigit(*(const unsigned char *)status_text) + || *status_text == ' ') { + status_text++; + } + } else if (get_header(&ri, "Location") != NULL) { + conn->status_code = 302; + } else { + conn->status_code = 200; + } + connection_state = get_header(&ri, "Connection"); + if (!header_has_option(connection_state, "keep-alive")) { + conn->must_close = 1; + } + (void)mg_printf(conn, "HTTP/1.1 %d %s\r\n", conn->status_code, status_text); + + /* Send headers */ + for (i = 0; i < ri.num_headers; i++) { + mg_printf(conn, + "%s: %s\r\n", + ri.http_headers[i].name, + ri.http_headers[i].value); + } + mg_write(conn, "\r\n", 2); + + /* Send chunk of data that may have been read after the headers */ + conn->num_bytes_sent += + mg_write(conn, buf + headers_len, (size_t)(data_len - headers_len)); + + /* Read the rest of CGI output and send to the client */ + send_file_data(conn, &fout, 0, INT64_MAX); + +done: + mg_free(blk.var); + mg_free(blk.buf); + + if (pid != (pid_t)-1) { + kill(pid, SIGKILL); +#if !defined(_WIN32) + { + int st; + while (waitpid(pid, &st, 0) != -1) + ; /* clean zombies */ + } +#endif + } + if (fdin[0] != -1) { + close(fdin[0]); + } + if (fdout[1] != -1) { + close(fdout[1]); + } + + if (in != NULL) { + fclose(in); + } else if (fdin[1] != -1) { + close(fdin[1]); + } + + if (out != NULL) { + fclose(out); + } else if (fdout[0] != -1) { + close(fdout[0]); + } + + if (err != NULL) { + fclose(err); + } else if (fderr[0] != -1) { + close(fderr[0]); + } + + if (buf != NULL) { + mg_free(buf); + } +} +#endif /* !NO_CGI */ + + +#if !defined(NO_FILES) +static void +mkcol(struct mg_connection *conn, const char *path) +{ + int rc, body_len; + struct de de; + char date[64]; + time_t curtime = time(NULL); + + if (conn == NULL) { + return; + } + + /* TODO (mid): Check the send_http_error situations in this function */ + + memset(&de.file, 0, sizeof(de.file)); + if (!mg_stat(conn, path, &de.file)) { + mg_cry(conn, + "%s: mg_stat(%s) failed: %s", + __func__, + path, + strerror(ERRNO)); + } + + if (de.file.last_modified) { + /* TODO (high): This check does not seem to make any sense ! */ + send_http_error( + conn, 405, "Error: mkcol(%s): %s", path, strerror(ERRNO)); + return; + } + + body_len = conn->data_len - conn->request_len; + if (body_len > 0) { + send_http_error( + conn, 415, "Error: mkcol(%s): %s", path, strerror(ERRNO)); + return; + } + + rc = mg_mkdir(conn, path, 0755); + + if (rc == 0) { + conn->status_code = 201; + gmt_time_string(date, sizeof(date), &curtime); + mg_printf(conn, + "HTTP/1.1 %d Created\r\n" + "Date: %s\r\n", + conn->status_code, + date); + send_static_cache_header(conn); + mg_printf(conn, + "Content-Length: 0\r\n" + "Connection: %s\r\n\r\n", + suggest_connection_header(conn)); + } else if (rc == -1) { + if (errno == EEXIST) { + send_http_error( + conn, 405, "Error: mkcol(%s): %s", path, strerror(ERRNO)); + } else if (errno == EACCES) { + send_http_error( + conn, 403, "Error: mkcol(%s): %s", path, strerror(ERRNO)); + } else if (errno == ENOENT) { + send_http_error( + conn, 409, "Error: mkcol(%s): %s", path, strerror(ERRNO)); + } else { + send_http_error(conn, 500, "fopen(%s): %s", path, strerror(ERRNO)); + } + } +} + + +static void +put_file(struct mg_connection *conn, const char *path) +{ + struct file file = STRUCT_FILE_INITIALIZER; + const char *range; + int64_t r1, r2; + int rc; + char date[64]; + time_t curtime = time(NULL); + + if (conn == NULL) { + return; + } + + if (mg_stat(conn, path, &file)) { + /* File already exists */ + conn->status_code = 200; + + if (file.is_directory) { + /* This is an already existing directory, + * so there is nothing to do for the server. */ + rc = 0; + + } else { + /* File exists and is not a directory. */ + /* Can it be replaced? */ + + if (file.membuf != NULL) { + /* This is an "in-memory" file, that can not be replaced */ + send_http_error( + conn, + 405, + "Error: Put not possible\nReplacing %s is not supported", + path); + return; + } + + /* Check if the server may write this file */ + if (access(path, W_OK) == 0) { + /* Access granted */ + conn->status_code = 200; + rc = 1; + } else { + send_http_error( + conn, + 403, + "Error: Put not possible\nReplacing %s is not allowed", + path); + return; + } + } + } else { + /* File should be created */ + conn->status_code = 201; + rc = put_dir(conn, path); + } + + if (rc == 0) { + /* put_dir returns 0 if path is a directory */ + gmt_time_string(date, sizeof(date), &curtime); + mg_printf(conn, + "HTTP/1.1 %d %s\r\n", + conn->status_code, + mg_get_response_code_text(NULL, conn->status_code)); + send_no_cache_header(conn); + mg_printf(conn, + "Date: %s\r\n" + "Content-Length: 0\r\n" + "Connection: %s\r\n\r\n", + date, + suggest_connection_header(conn)); + + /* Request to create a directory has been fulfilled successfully. + * No need to put a file. */ + return; + } + + if (rc == -1) { + /* put_dir returns -1 if the path is too long */ + send_http_error(conn, + 414, + "Error: Path too long\nput_dir(%s): %s", + path, + strerror(ERRNO)); + return; + } + + if (rc == -2) { + /* put_dir returns -2 if the directory can not be created */ + send_http_error(conn, + 500, + "Error: Can not create directory\nput_dir(%s): %s", + path, + strerror(ERRNO)); + return; + } + + /* A file should be created or overwritten. */ + if (!mg_fopen(conn, path, "wb+", &file) || file.fp == NULL) { + mg_fclose(&file); + send_http_error(conn, + 500, + "Error: Can not create file\nfopen(%s): %s", + path, + strerror(ERRNO)); + return; + } + + fclose_on_exec(&file, conn); + range = mg_get_header(conn, "Content-Range"); + r1 = r2 = 0; + if (range != NULL && parse_range_header(range, &r1, &r2) > 0) { + conn->status_code = 206; /* Partial content */ + fseeko(file.fp, r1, SEEK_SET); + } + + if (!forward_body_data(conn, file.fp, INVALID_SOCKET, NULL)) { + /* forward_body_data failed. + * The error code has already been sent to the client, + * and conn->status_code is already set. */ + mg_fclose(&file); + return; + } + + gmt_time_string(date, sizeof(date), &curtime); + mg_printf(conn, + "HTTP/1.1 %d %s\r\n", + conn->status_code, + mg_get_response_code_text(NULL, conn->status_code)); + send_no_cache_header(conn); + mg_printf(conn, + "Date: %s\r\n" + "Content-Length: 0\r\n" + "Connection: %s\r\n\r\n", + date, + suggest_connection_header(conn)); + + mg_fclose(&file); +} + + +static void +delete_file(struct mg_connection *conn, const char *path) +{ + struct de de; + memset(&de.file, 0, sizeof(de.file)); + if (!mg_stat(conn, path, &de.file)) { + /* mg_stat returns 0 if the file does not exist */ + send_http_error(conn, + 404, + "Error: Cannot delete file\nFile %s not found", + path); + return; + } + + if (de.file.membuf != NULL) { + /* the file is cached in memory */ + send_http_error( + conn, + 405, + "Error: Delete not possible\nDeleting %s is not supported", + path); + return; + } + + if (de.file.is_directory) { + if (remove_directory(conn, path)) { + /* Delete is successful: Return 204 without content. */ + send_http_error(conn, 204, "%s", ""); + } else { + /* Delete is not successful: Return 500 (Server error). */ + send_http_error(conn, 500, "Error: Could not delete %s", path); + } + return; + } + + /* This is an existing file (not a directory). + * Check if write permission is granted. */ + if (access(path, W_OK) != 0) { + /* File is read only */ + send_http_error( + conn, + 403, + "Error: Delete not possible\nDeleting %s is not allowed", + path); + return; + } + + /* Try to delete it. */ + if (mg_remove(conn, path) == 0) { + /* Delete was successful: Return 204 without content. */ + send_http_error(conn, 204, "%s", ""); + } else { + /* Delete not successful (file locked). */ + send_http_error(conn, + 423, + "Error: Cannot delete file\nremove(%s): %s", + path, + strerror(ERRNO)); + } +} +#endif /* !NO_FILES */ + + +static void +send_ssi_file(struct mg_connection *, const char *, struct file *, int); + + +static void +do_ssi_include(struct mg_connection *conn, + const char *ssi, + char *tag, + int include_level) +{ + char file_name[MG_BUF_LEN], path[512], *p; + struct file file = STRUCT_FILE_INITIALIZER; + size_t len; + int truncated = 0; + + if (conn == NULL) { + return; + } + + /* sscanf() is safe here, since send_ssi_file() also uses buffer + * of size MG_BUF_LEN to get the tag. So strlen(tag) is + * always < MG_BUF_LEN. */ + if (sscanf(tag, " virtual=\"%511[^\"]\"", file_name) == 1) { + /* File name is relative to the webserver root */ + file_name[511] = 0; + (void)mg_snprintf(conn, + &truncated, + path, + sizeof(path), + "%s/%s", + conn->ctx->config[DOCUMENT_ROOT], + file_name); + + } else if (sscanf(tag, " abspath=\"%511[^\"]\"", file_name) == 1) { + /* File name is relative to the webserver working directory + * or it is absolute system path */ + file_name[511] = 0; + (void) + mg_snprintf(conn, &truncated, path, sizeof(path), "%s", file_name); + + } else if (sscanf(tag, " file=\"%511[^\"]\"", file_name) == 1 + || sscanf(tag, " \"%511[^\"]\"", file_name) == 1) { + /* File name is relative to the currect document */ + file_name[511] = 0; + (void)mg_snprintf(conn, &truncated, path, sizeof(path), "%s", ssi); + + if (!truncated) { + if ((p = strrchr(path, '/')) != NULL) { + p[1] = '\0'; + } + len = strlen(path); + (void)mg_snprintf(conn, + &truncated, + path + len, + sizeof(path) - len, + "%s", + file_name); + } + + } else { + mg_cry(conn, "Bad SSI #include: [%s]", tag); + return; + } + + if (truncated) { + mg_cry(conn, "SSI #include path length overflow: [%s]", tag); + return; + } + + if (!mg_fopen(conn, path, "rb", &file)) { + mg_cry(conn, + "Cannot open SSI #include: [%s]: fopen(%s): %s", + tag, + path, + strerror(ERRNO)); + } else { + fclose_on_exec(&file, conn); + if (match_prefix(conn->ctx->config[SSI_EXTENSIONS], + strlen(conn->ctx->config[SSI_EXTENSIONS]), + path) > 0) { + send_ssi_file(conn, path, &file, include_level + 1); + } else { + send_file_data(conn, &file, 0, INT64_MAX); + } + mg_fclose(&file); + } +} + + +#if !defined(NO_POPEN) +static void +do_ssi_exec(struct mg_connection *conn, char *tag) +{ + char cmd[1024] = ""; + struct file file = STRUCT_FILE_INITIALIZER; + + if (sscanf(tag, " \"%1023[^\"]\"", cmd) != 1) { + mg_cry(conn, "Bad SSI #exec: [%s]", tag); + } else { + cmd[1023] = 0; + if ((file.fp = popen(cmd, "r")) == NULL) { + mg_cry(conn, "Cannot SSI #exec: [%s]: %s", cmd, strerror(ERRNO)); + } else { + send_file_data(conn, &file, 0, INT64_MAX); + pclose(file.fp); + } + } +} +#endif /* !NO_POPEN */ + + +static int +mg_fgetc(struct file *filep, int offset) +{ + if (filep == NULL) { + return EOF; + } + if (filep->membuf != NULL && offset >= 0 + && ((unsigned int)(offset)) < filep->size) { + return ((const unsigned char *)filep->membuf)[offset]; + } else if (filep->fp != NULL) { + return fgetc(filep->fp); + } else { + return EOF; + } +} + + +static void +send_ssi_file(struct mg_connection *conn, + const char *path, + struct file *filep, + int include_level) +{ + char buf[MG_BUF_LEN]; + int ch, offset, len, in_ssi_tag; + + if (include_level > 10) { + mg_cry(conn, "SSI #include level is too deep (%s)", path); + return; + } + + in_ssi_tag = len = offset = 0; + while ((ch = mg_fgetc(filep, offset)) != EOF) { + if (in_ssi_tag && ch == '>') { + in_ssi_tag = 0; + buf[len++] = (char)ch; + buf[len] = '\0'; + /* assert(len <= (int) sizeof(buf)); */ + if (len > (int)sizeof(buf)) { + break; + } + if (len < 6 || memcmp(buf, " + + + EnvironmentId + {666f325e-a9c7-45d6-a820-626289f99bab} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + true + Builtin.Questionable + + true + Builtin.DefaultTidyAndClazy + 2 + + + + true + + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.12.9 GCC 64bit + Desktop Qt 5.12.9 GCC 64bit + qt.qt5.5129.gcc_64_kit + 0 + 0 + 0 + + true + 0 + /home/panda/build-Ventoy2Disk-Desktop_Qt_5_12_9_GCC_64bit-Debug + /home/panda/build-Ventoy2Disk-Desktop_Qt_5_12_9_GCC_64bit-Debug + + + true + QtProjectManager.QMakeBuildStep + + false + + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + 2 + 2 + + + true + 2 + /home/panda/build-Ventoy2Disk-Desktop_Qt_5_12_9_GCC_64bit-Release + /home/panda/build-Ventoy2Disk-Desktop_Qt_5_12_9_GCC_64bit-Release + + + true + QtProjectManager.QMakeBuildStep + + false + + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + 0 + 2 + + + true + 0 + /home/panda/build-Ventoy2Disk-Desktop_Qt_5_12_9_GCC_64bit-Profile + /home/panda/build-Ventoy2Disk-Desktop_Qt_5_12_9_GCC_64bit-Profile + + + true + QtProjectManager.QMakeBuildStep + + false + + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + 0 + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:/home/panda/Ventoy2Disk/Ventoy2Disk.pro + /home/panda/Ventoy2Disk/Ventoy2Disk.pro + + false + + false + true + true + false + false + true + /home/panda/Desktop/ventoy-1.0.52-linux/ventoy-1.0.52 + /home/panda/build-Ventoy2Disk-Desktop_Qt_5_12_9_GCC_64bit-Debug + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/LinuxGUI/Ventoy2Disk/QT/build/Makefile b/LinuxGUI/Ventoy2Disk/QT/build/Makefile new file mode 100644 index 0000000..40d4a53 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/QT/build/Makefile @@ -0,0 +1,1760 @@ +############################################################################# +# Makefile for building: Ventoy2Disk +# Generated by qmake (3.1) (Qt 5.9.0) +# Project: ../Ventoy2Disk/Ventoy2Disk.pro +# Template: app +# Command: /home/panda/Qt5.9.0/5.9/gcc_64/bin/qmake -o Makefile ../Ventoy2Disk/Ventoy2Disk.pro -spec linux-g++ +############################################################################# + +MAKEFILE = Makefile + +####### Compiler, tools and options + +CC = gcc +CXX = g++ +DEFINES = -DQT_DEPRECATED_WARNINGS -DSTATIC=static -DINIT= -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB +CFLAGS = -pipe -O2 -Wall -W -D_REENTRANT -fPIC $(DEFINES) +CXXFLAGS = -pipe -O2 -std=gnu++11 -Wall -W -D_REENTRANT -fPIC $(DEFINES) +INCPATH = -I../Ventoy2Disk -I. -I../../Ventoy2Disk/Core -I../../Ventoy2Disk/Web -I../../Ventoy2Disk/QT -I../../Ventoy2Disk/Include -I../../Ventoy2Disk/Lib/libhttp/include -I/home/panda/Ventoy2Disk/Lib/fat_io_lib/include -I../../Ventoy2Disk/Lib/xz-embedded/linux/include -I../../Ventoy2Disk/Lib/xz-embedded/linux/include/linux -I../../Ventoy2Disk/Lib/xz-embedded/userspace -I../../Ventoy2Disk/Lib/exfat/src/libexfat -I../../Ventoy2Disk/Lib/fat_io_lib -I../../Qt5.9.0/5.9/gcc_64/include -I../../Qt5.9.0/5.9/gcc_64/include/QtWidgets -I../../Qt5.9.0/5.9/gcc_64/include/QtGui -I../../Qt5.9.0/5.9/gcc_64/include/QtCore -I. -isystem /usr/include/libdrm -I. -I../../Qt5.9.0/5.9/gcc_64/mkspecs/linux-g++ +QMAKE = /home/panda/Qt5.9.0/5.9/gcc_64/bin/qmake +DEL_FILE = rm -f +CHK_DIR_EXISTS= test -d +MKDIR = mkdir -p +COPY = cp -f +COPY_FILE = cp -f +COPY_DIR = cp -f -R +INSTALL_FILE = install -m 644 -p +INSTALL_PROGRAM = install -m 755 -p +INSTALL_DIR = cp -f -R +QINSTALL_FILE = /home/panda/Qt5.9.0/5.9/gcc_64/bin/qmake -install qinstall file +QINSTALL_PROGRAM = /home/panda/Qt5.9.0/5.9/gcc_64/bin/qmake -install qinstall program +QINSTALL_DIR = /home/panda/Qt5.9.0/5.9/gcc_64/bin/qmake -install qinstall directory +DEL_FILE = rm -f +SYMLINK = ln -f -s +DEL_DIR = rmdir +MOVE = mv -f +TAR = tar -cf +COMPRESS = gzip -9f +DISTNAME = Ventoy2Disk1.0.0 +DISTDIR = /home/panda/590/build-Ventoy2Disk-Desktop_Qt_5_9_0_GCC_64bit-Release/.tmp/Ventoy2Disk1.0.0 +LINK = g++ +LFLAGS = -Wl,-O1 -Wl,-rpath,/home/panda/Qt5.9.0/5.9/gcc_64/lib +LIBS = $(SUBLIBS) -L/home/panda/Qt5.9.0/5.9/gcc_64/lib -lQt5Widgets -lQt5Gui -lQt5Core -lGL -lpthread +AR = ar cqs +RANLIB = +SED = sed +STRIP = strip + +####### Output directory + +OBJECTS_DIR = ./ + +####### Files + +SOURCES = ../Ventoy2Disk/Core/ventoy_crc32.c \ + ../Ventoy2Disk/Core/ventoy_disk.c \ + ../Ventoy2Disk/Core/ventoy_json.c \ + ../Ventoy2Disk/Core/ventoy_log.c \ + ../Ventoy2Disk/Core/ventoy_md5.c \ + ../Ventoy2Disk/Core/ventoy_util.c \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/cluster.c \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/io.c \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/lookup.c \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/mount.c \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/node.c \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/repair.c \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/time.c \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/utf.c \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/utils.c \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/cbm.c \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/fat.c \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.c \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat_main.c \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/rootdir.c \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/uct.c \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/uctc.c \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/vbr.c \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_access.c \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_cache.c \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_filelib.c \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_format.c \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_misc.c \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_string.c \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_table.c \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_write.c \ + ../Ventoy2Disk/Lib/xz-embedded/linux/lib/decompress_unxz.c \ + ../Ventoy2Disk/QT/refresh_icon_data.c \ + ../Ventoy2Disk/QT/secure_icon_data.c \ + ../Ventoy2Disk/QT/ventoy_qt_stub.c \ + ../Ventoy2Disk/Web/ventoy_http.c \ + ../Ventoy2Disk/main.cpp \ + ../Ventoy2Disk/partcfgdialog.cpp \ + ../Ventoy2Disk/ventoy2diskwindow.cpp moc_partcfgdialog.cpp \ + moc_ventoy2diskwindow.cpp +OBJECTS = ventoy_crc32.o \ + ventoy_disk.o \ + ventoy_json.o \ + ventoy_log.o \ + ventoy_md5.o \ + ventoy_util.o \ + cluster.o \ + io.o \ + lookup.o \ + mount.o \ + node.o \ + repair.o \ + time.o \ + utf.o \ + utils.o \ + cbm.o \ + fat.o \ + mkexfat.o \ + mkexfat_main.o \ + rootdir.o \ + uct.o \ + uctc.o \ + vbr.o \ + fat_access.o \ + fat_cache.o \ + fat_filelib.o \ + fat_format.o \ + fat_misc.o \ + fat_string.o \ + fat_table.o \ + fat_write.o \ + decompress_unxz.o \ + refresh_icon_data.o \ + secure_icon_data.o \ + ventoy_qt_stub.o \ + ventoy_http.o \ + main.o \ + partcfgdialog.o \ + ventoy2diskwindow.o \ + moc_partcfgdialog.o \ + moc_ventoy2diskwindow.o +DIST = ../Ventoy2Disk/Lib/fat_io_lib/API.txt \ + ../Ventoy2Disk/Lib/fat_io_lib/COPYRIGHT.txt \ + ../Ventoy2Disk/Lib/fat_io_lib/Configuration.txt \ + ../Ventoy2Disk/Lib/fat_io_lib/History.txt \ + ../Ventoy2Disk/Lib/fat_io_lib/License.txt \ + ../Ventoy2Disk/Lib/fat_io_lib/Media \ + ../Ventoy2Disk/Access \ + ../Ventoy2Disk/API.txt \ + ../Ventoy2Disk/Lib/fat_io_lib/version.txt \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/spec_pre.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/common/unix.conf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/common/linux.conf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/common/sanitize.conf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/common/gcc-base.conf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/common/gcc-base-unix.conf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/common/g++-base.conf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/common/g++-unix.conf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/qconfig.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3danimation.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3danimation_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dcore.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dcore_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dextras.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dextras_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dinput.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dinput_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dlogic.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dlogic_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquick.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquick_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquickanimation.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquickanimation_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquickextras.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquickextras_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquickinput.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquickinput_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquickrender.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquickrender_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquickscene2d.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquickscene2d_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3drender.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3drender_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_accessibility_support_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_bluetooth.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_bluetooth_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_bootstrap_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_charts.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_charts_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_concurrent.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_concurrent_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_core.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_core_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_datavisualization.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_datavisualization_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_dbus.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_dbus_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_designer.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_designer_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_designercomponents_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_devicediscovery_support_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_egl_support_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_eglfsdeviceintegration_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_eventdispatcher_support_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_fb_support_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_fontdatabase_support_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_gamepad.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_gamepad_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_glx_support_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_gui.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_gui_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_help.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_help_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_input_support_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_kms_support_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_linuxaccessibility_support_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_location.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_location_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_multimedia.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_multimedia_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_multimediawidgets.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_multimediawidgets_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_network.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_network_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_nfc.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_nfc_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_opengl.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_opengl_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_openglextensions.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_openglextensions_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_packetprotocol_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_platformcompositor_support_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_positioning.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_positioning_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_printsupport.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_printsupport_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_qml.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_qml_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_qmldebug_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_qmldevtools_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_qmltest.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_qmltest_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_qtmultimediaquicktools_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_quick.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_quick_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_quickcontrols2.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_quickcontrols2_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_quickparticles_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_quicktemplates2_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_quickwidgets.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_quickwidgets_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_scxml.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_scxml_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_sensors.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_sensors_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_serialbus.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_serialbus_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_serialport.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_serialport_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_service_support_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_sql.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_sql_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_svg.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_svg_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_testlib.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_testlib_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_theme_support_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_uiplugin.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_uitools.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_uitools_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webchannel.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webchannel_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webengine.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webengine_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webenginecore.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webenginecore_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webenginecoreheaders_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webenginewidgets.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webenginewidgets_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_websockets.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_websockets_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webview.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webview_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_widgets.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_widgets_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_x11extras.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_x11extras_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_xcb_qpa_lib_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_xml.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_xml_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_xmlpatterns.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_xmlpatterns_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/qt_functions.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/qt_config.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/linux-g++/qmake.conf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/spec_post.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/exclusive_builds.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/toolchain.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/default_pre.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/resolve_config.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/default_post.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/warn_on.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/qt.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/resources.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/moc.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/unix/opengl.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/uic.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/unix/thread.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/qmake_use.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/file_copies.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/testcase_targets.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/exceptions.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/yacc.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/lex.prf \ + ../Ventoy2Disk/Ventoy2Disk.pro ../Ventoy2Disk/Core/ventoy_define.h \ + ../Ventoy2Disk/Core/ventoy_disk.h \ + ../Ventoy2Disk/Core/ventoy_json.h \ + ../Ventoy2Disk/Core/ventoy_util.h \ + ../Ventoy2Disk/Include/Ventoy2Disk.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/byteorder.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/compiler.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/config.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/exfat.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/exfatfs.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/platform.h \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/cbm.h \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/fat.h \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.h \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/rootdir.h \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/uct.h \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/uctc.h \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/vbr.h \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_access.h \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_cache.h \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_defs.h \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_filelib.h \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_format.h \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_list.h \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_misc.h \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_opts.h \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_string.h \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_table.h \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_types.h \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_write.h \ + ../Ventoy2Disk/Lib/libhttp/include/civetweb.h \ + ../Ventoy2Disk/Lib/libhttp/include/handle_form.inl \ + ../Ventoy2Disk/Lib/libhttp/include/md5.inl \ + ../Ventoy2Disk/Lib/libhttp/include/mod_duktape.inl \ + ../Ventoy2Disk/Lib/libhttp/include/mod_lua.inl \ + ../Ventoy2Disk/Lib/libhttp/include/timer.inl \ + ../Ventoy2Disk/QT/ventoy_qt.h \ + ../Ventoy2Disk/Web/ventoy_http.h \ + ../Ventoy2Disk/partcfgdialog.h \ + ../Ventoy2Disk/ventoy2diskwindow.h ../Ventoy2Disk/Core/ventoy_crc32.c \ + ../Ventoy2Disk/Core/ventoy_disk.c \ + ../Ventoy2Disk/Core/ventoy_json.c \ + ../Ventoy2Disk/Core/ventoy_log.c \ + ../Ventoy2Disk/Core/ventoy_md5.c \ + ../Ventoy2Disk/Core/ventoy_util.c \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/cluster.c \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/io.c \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/lookup.c \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/mount.c \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/node.c \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/repair.c \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/time.c \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/utf.c \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/utils.c \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/cbm.c \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/fat.c \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.c \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat_main.c \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/rootdir.c \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/uct.c \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/uctc.c \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/vbr.c \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_access.c \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_cache.c \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_filelib.c \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_format.c \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_misc.c \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_string.c \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_table.c \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_write.c \ + ../Ventoy2Disk/Lib/xz-embedded/linux/lib/decompress_unxz.c \ + ../Ventoy2Disk/QT/refresh_icon_data.c \ + ../Ventoy2Disk/QT/secure_icon_data.c \ + ../Ventoy2Disk/QT/ventoy_qt_stub.c \ + ../Ventoy2Disk/Web/ventoy_http.c \ + ../Ventoy2Disk/main.cpp \ + ../Ventoy2Disk/partcfgdialog.cpp \ + ../Ventoy2Disk/ventoy2diskwindow.cpp +QMAKE_TARGET = Ventoy2Disk +DESTDIR = +TARGET = Ventoy2Disk + + +first: all +####### Build rules + +$(TARGET): ui_partcfgdialog.h ui_ventoy2diskwindow.h $(OBJECTS) + $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJCOMP) $(LIBS) + +Makefile: ../Ventoy2Disk/Ventoy2Disk.pro ../../Qt5.9.0/5.9/gcc_64/mkspecs/linux-g++/qmake.conf ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/spec_pre.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/common/unix.conf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/common/linux.conf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/common/sanitize.conf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/common/gcc-base.conf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/common/gcc-base-unix.conf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/common/g++-base.conf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/common/g++-unix.conf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/qconfig.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3danimation.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3danimation_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dcore.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dcore_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dextras.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dextras_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dinput.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dinput_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dlogic.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dlogic_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquick.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquick_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquickanimation.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquickanimation_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquickextras.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquickextras_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquickinput.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquickinput_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquickrender.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquickrender_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquickscene2d.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquickscene2d_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3drender.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3drender_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_accessibility_support_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_bluetooth.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_bluetooth_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_bootstrap_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_charts.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_charts_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_concurrent.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_concurrent_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_core.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_core_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_datavisualization.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_datavisualization_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_dbus.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_dbus_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_designer.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_designer_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_designercomponents_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_devicediscovery_support_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_egl_support_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_eglfsdeviceintegration_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_eventdispatcher_support_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_fb_support_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_fontdatabase_support_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_gamepad.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_gamepad_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_glx_support_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_gui.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_gui_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_help.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_help_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_input_support_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_kms_support_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_linuxaccessibility_support_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_location.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_location_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_multimedia.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_multimedia_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_multimediawidgets.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_multimediawidgets_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_network.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_network_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_nfc.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_nfc_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_opengl.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_opengl_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_openglextensions.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_openglextensions_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_packetprotocol_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_platformcompositor_support_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_positioning.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_positioning_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_printsupport.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_printsupport_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_qml.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_qml_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_qmldebug_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_qmldevtools_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_qmltest.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_qmltest_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_qtmultimediaquicktools_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_quick.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_quick_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_quickcontrols2.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_quickcontrols2_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_quickparticles_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_quicktemplates2_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_quickwidgets.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_quickwidgets_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_scxml.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_scxml_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_sensors.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_sensors_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_serialbus.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_serialbus_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_serialport.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_serialport_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_service_support_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_sql.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_sql_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_svg.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_svg_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_testlib.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_testlib_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_theme_support_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_uiplugin.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_uitools.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_uitools_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webchannel.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webchannel_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webengine.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webengine_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webenginecore.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webenginecore_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webenginecoreheaders_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webenginewidgets.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webenginewidgets_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_websockets.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_websockets_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webview.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webview_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_widgets.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_widgets_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_x11extras.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_x11extras_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_xcb_qpa_lib_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_xml.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_xml_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_xmlpatterns.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_xmlpatterns_private.pri \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/qt_functions.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/qt_config.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/linux-g++/qmake.conf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/spec_post.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/exclusive_builds.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/toolchain.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/default_pre.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/resolve_config.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/default_post.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/warn_on.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/qt.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/resources.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/moc.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/unix/opengl.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/uic.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/unix/thread.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/qmake_use.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/file_copies.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/testcase_targets.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/exceptions.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/yacc.prf \ + ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/lex.prf \ + ../Ventoy2Disk/Ventoy2Disk.pro \ + ../../Qt5.9.0/5.9/gcc_64/lib/libQt5Widgets.prl \ + ../../Qt5.9.0/5.9/gcc_64/lib/libQt5Gui.prl \ + ../../Qt5.9.0/5.9/gcc_64/lib/libQt5Core.prl + $(QMAKE) -o Makefile ../Ventoy2Disk/Ventoy2Disk.pro -spec linux-g++ +../../Qt5.9.0/5.9/gcc_64/mkspecs/features/spec_pre.prf: +../../Qt5.9.0/5.9/gcc_64/mkspecs/common/unix.conf: +../../Qt5.9.0/5.9/gcc_64/mkspecs/common/linux.conf: +../../Qt5.9.0/5.9/gcc_64/mkspecs/common/sanitize.conf: +../../Qt5.9.0/5.9/gcc_64/mkspecs/common/gcc-base.conf: +../../Qt5.9.0/5.9/gcc_64/mkspecs/common/gcc-base-unix.conf: +../../Qt5.9.0/5.9/gcc_64/mkspecs/common/g++-base.conf: +../../Qt5.9.0/5.9/gcc_64/mkspecs/common/g++-unix.conf: +../../Qt5.9.0/5.9/gcc_64/mkspecs/qconfig.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3danimation.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3danimation_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dcore.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dcore_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dextras.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dextras_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dinput.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dinput_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dlogic.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dlogic_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquick.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquick_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquickanimation.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquickanimation_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquickextras.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquickextras_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquickinput.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquickinput_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquickrender.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquickrender_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquickscene2d.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3dquickscene2d_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3drender.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_3drender_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_accessibility_support_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_bluetooth.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_bluetooth_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_bootstrap_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_charts.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_charts_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_concurrent.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_concurrent_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_core.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_core_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_datavisualization.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_datavisualization_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_dbus.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_dbus_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_designer.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_designer_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_designercomponents_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_devicediscovery_support_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_egl_support_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_eglfsdeviceintegration_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_eventdispatcher_support_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_fb_support_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_fontdatabase_support_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_gamepad.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_gamepad_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_glx_support_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_gui.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_gui_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_help.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_help_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_input_support_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_kms_support_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_linuxaccessibility_support_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_location.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_location_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_multimedia.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_multimedia_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_multimediawidgets.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_multimediawidgets_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_network.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_network_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_nfc.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_nfc_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_opengl.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_opengl_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_openglextensions.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_openglextensions_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_packetprotocol_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_platformcompositor_support_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_positioning.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_positioning_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_printsupport.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_printsupport_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_qml.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_qml_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_qmldebug_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_qmldevtools_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_qmltest.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_qmltest_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_qtmultimediaquicktools_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_quick.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_quick_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_quickcontrols2.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_quickcontrols2_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_quickparticles_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_quicktemplates2_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_quickwidgets.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_quickwidgets_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_scxml.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_scxml_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_sensors.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_sensors_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_serialbus.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_serialbus_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_serialport.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_serialport_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_service_support_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_sql.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_sql_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_svg.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_svg_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_testlib.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_testlib_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_theme_support_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_uiplugin.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_uitools.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_uitools_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webchannel.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webchannel_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webengine.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webengine_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webenginecore.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webenginecore_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webenginecoreheaders_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webenginewidgets.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webenginewidgets_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_websockets.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_websockets_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webview.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_webview_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_widgets.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_widgets_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_x11extras.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_x11extras_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_xcb_qpa_lib_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_xml.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_xml_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_xmlpatterns.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/modules/qt_lib_xmlpatterns_private.pri: +../../Qt5.9.0/5.9/gcc_64/mkspecs/features/qt_functions.prf: +../../Qt5.9.0/5.9/gcc_64/mkspecs/features/qt_config.prf: +../../Qt5.9.0/5.9/gcc_64/mkspecs/linux-g++/qmake.conf: +../../Qt5.9.0/5.9/gcc_64/mkspecs/features/spec_post.prf: +../../Qt5.9.0/5.9/gcc_64/mkspecs/features/exclusive_builds.prf: +../../Qt5.9.0/5.9/gcc_64/mkspecs/features/toolchain.prf: +../../Qt5.9.0/5.9/gcc_64/mkspecs/features/default_pre.prf: +../../Qt5.9.0/5.9/gcc_64/mkspecs/features/resolve_config.prf: +../../Qt5.9.0/5.9/gcc_64/mkspecs/features/default_post.prf: +../../Qt5.9.0/5.9/gcc_64/mkspecs/features/warn_on.prf: +../../Qt5.9.0/5.9/gcc_64/mkspecs/features/qt.prf: +../../Qt5.9.0/5.9/gcc_64/mkspecs/features/resources.prf: +../../Qt5.9.0/5.9/gcc_64/mkspecs/features/moc.prf: +../../Qt5.9.0/5.9/gcc_64/mkspecs/features/unix/opengl.prf: +../../Qt5.9.0/5.9/gcc_64/mkspecs/features/uic.prf: +../../Qt5.9.0/5.9/gcc_64/mkspecs/features/unix/thread.prf: +../../Qt5.9.0/5.9/gcc_64/mkspecs/features/qmake_use.prf: +../../Qt5.9.0/5.9/gcc_64/mkspecs/features/file_copies.prf: +../../Qt5.9.0/5.9/gcc_64/mkspecs/features/testcase_targets.prf: +../../Qt5.9.0/5.9/gcc_64/mkspecs/features/exceptions.prf: +../../Qt5.9.0/5.9/gcc_64/mkspecs/features/yacc.prf: +../../Qt5.9.0/5.9/gcc_64/mkspecs/features/lex.prf: +../Ventoy2Disk/Ventoy2Disk.pro: +../../Qt5.9.0/5.9/gcc_64/lib/libQt5Widgets.prl: +../../Qt5.9.0/5.9/gcc_64/lib/libQt5Gui.prl: +../../Qt5.9.0/5.9/gcc_64/lib/libQt5Core.prl: +qmake: FORCE + @$(QMAKE) -o Makefile ../Ventoy2Disk/Ventoy2Disk.pro -spec linux-g++ + +qmake_all: FORCE + + +all: Makefile $(TARGET) + +dist: distdir FORCE + (cd `dirname $(DISTDIR)` && $(TAR) $(DISTNAME).tar $(DISTNAME) && $(COMPRESS) $(DISTNAME).tar) && $(MOVE) `dirname $(DISTDIR)`/$(DISTNAME).tar.gz . && $(DEL_FILE) -r $(DISTDIR) + +distdir: FORCE + @test -d $(DISTDIR) || mkdir -p $(DISTDIR) + $(COPY_FILE) --parents $(DIST) $(DISTDIR)/ + $(COPY_FILE) --parents ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/data/dummy.cpp $(DISTDIR)/ + $(COPY_FILE) --parents ../Ventoy2Disk/Core/ventoy_define.h ../Ventoy2Disk/Core/ventoy_disk.h ../Ventoy2Disk/Core/ventoy_json.h ../Ventoy2Disk/Core/ventoy_util.h ../Ventoy2Disk/Include/Ventoy2Disk.h ../Ventoy2Disk/Lib/exfat/src/libexfat/byteorder.h ../Ventoy2Disk/Lib/exfat/src/libexfat/compiler.h ../Ventoy2Disk/Lib/exfat/src/libexfat/config.h ../Ventoy2Disk/Lib/exfat/src/libexfat/exfat.h ../Ventoy2Disk/Lib/exfat/src/libexfat/exfatfs.h ../Ventoy2Disk/Lib/exfat/src/libexfat/platform.h ../Ventoy2Disk/Lib/exfat/src/mkfs/cbm.h ../Ventoy2Disk/Lib/exfat/src/mkfs/fat.h ../Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.h ../Ventoy2Disk/Lib/exfat/src/mkfs/rootdir.h ../Ventoy2Disk/Lib/exfat/src/mkfs/uct.h ../Ventoy2Disk/Lib/exfat/src/mkfs/uctc.h ../Ventoy2Disk/Lib/exfat/src/mkfs/vbr.h ../Ventoy2Disk/Lib/fat_io_lib/fat_access.h ../Ventoy2Disk/Lib/fat_io_lib/fat_cache.h ../Ventoy2Disk/Lib/fat_io_lib/fat_defs.h ../Ventoy2Disk/Lib/fat_io_lib/fat_filelib.h ../Ventoy2Disk/Lib/fat_io_lib/fat_format.h ../Ventoy2Disk/Lib/fat_io_lib/fat_list.h ../Ventoy2Disk/Lib/fat_io_lib/fat_misc.h ../Ventoy2Disk/Lib/fat_io_lib/fat_opts.h ../Ventoy2Disk/Lib/fat_io_lib/fat_string.h ../Ventoy2Disk/Lib/fat_io_lib/fat_table.h ../Ventoy2Disk/Lib/fat_io_lib/fat_types.h ../Ventoy2Disk/Lib/fat_io_lib/fat_write.h ../Ventoy2Disk/Lib/libhttp/include/civetweb.h ../Ventoy2Disk/Lib/libhttp/include/handle_form.inl ../Ventoy2Disk/Lib/libhttp/include/md5.inl ../Ventoy2Disk/Lib/libhttp/include/mod_duktape.inl ../Ventoy2Disk/Lib/libhttp/include/mod_lua.inl ../Ventoy2Disk/Lib/libhttp/include/timer.inl ../Ventoy2Disk/QT/ventoy_qt.h ../Ventoy2Disk/Web/ventoy_http.h ../Ventoy2Disk/partcfgdialog.h ../Ventoy2Disk/ventoy2diskwindow.h $(DISTDIR)/ + $(COPY_FILE) --parents ../Ventoy2Disk/Core/ventoy_crc32.c ../Ventoy2Disk/Core/ventoy_disk.c ../Ventoy2Disk/Core/ventoy_json.c ../Ventoy2Disk/Core/ventoy_log.c ../Ventoy2Disk/Core/ventoy_md5.c ../Ventoy2Disk/Core/ventoy_util.c ../Ventoy2Disk/Lib/exfat/src/libexfat/cluster.c ../Ventoy2Disk/Lib/exfat/src/libexfat/io.c ../Ventoy2Disk/Lib/exfat/src/libexfat/lookup.c ../Ventoy2Disk/Lib/exfat/src/libexfat/mount.c ../Ventoy2Disk/Lib/exfat/src/libexfat/node.c ../Ventoy2Disk/Lib/exfat/src/libexfat/repair.c ../Ventoy2Disk/Lib/exfat/src/libexfat/time.c ../Ventoy2Disk/Lib/exfat/src/libexfat/utf.c ../Ventoy2Disk/Lib/exfat/src/libexfat/utils.c ../Ventoy2Disk/Lib/exfat/src/mkfs/cbm.c ../Ventoy2Disk/Lib/exfat/src/mkfs/fat.c ../Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.c ../Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat_main.c ../Ventoy2Disk/Lib/exfat/src/mkfs/rootdir.c ../Ventoy2Disk/Lib/exfat/src/mkfs/uct.c ../Ventoy2Disk/Lib/exfat/src/mkfs/uctc.c ../Ventoy2Disk/Lib/exfat/src/mkfs/vbr.c ../Ventoy2Disk/Lib/fat_io_lib/fat_access.c ../Ventoy2Disk/Lib/fat_io_lib/fat_cache.c ../Ventoy2Disk/Lib/fat_io_lib/fat_filelib.c ../Ventoy2Disk/Lib/fat_io_lib/fat_format.c ../Ventoy2Disk/Lib/fat_io_lib/fat_misc.c ../Ventoy2Disk/Lib/fat_io_lib/fat_string.c ../Ventoy2Disk/Lib/fat_io_lib/fat_table.c ../Ventoy2Disk/Lib/fat_io_lib/fat_write.c ../Ventoy2Disk/Lib/xz-embedded/linux/lib/decompress_unxz.c ../Ventoy2Disk/QT/refresh_icon_data.c ../Ventoy2Disk/QT/secure_icon_data.c ../Ventoy2Disk/QT/ventoy_qt_stub.c ../Ventoy2Disk/Web/ventoy_http.c ../Ventoy2Disk/main.cpp ../Ventoy2Disk/partcfgdialog.cpp ../Ventoy2Disk/ventoy2diskwindow.cpp $(DISTDIR)/ + $(COPY_FILE) --parents ../Ventoy2Disk/partcfgdialog.ui ../Ventoy2Disk/ventoy2diskwindow.ui $(DISTDIR)/ + + +clean: compiler_clean + -$(DEL_FILE) $(OBJECTS) + -$(DEL_FILE) *~ core *.core + + +distclean: clean + -$(DEL_FILE) $(TARGET) + -$(DEL_FILE) .qmake.stash + -$(DEL_FILE) Makefile + + +####### Sub-libraries + +mocclean: compiler_moc_header_clean compiler_moc_source_clean + +mocables: compiler_moc_header_make_all compiler_moc_source_make_all + +check: first + +benchmark: first + +compiler_rcc_make_all: +compiler_rcc_clean: +compiler_moc_predefs_make_all: moc_predefs.h +compiler_moc_predefs_clean: + -$(DEL_FILE) moc_predefs.h +moc_predefs.h: ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/data/dummy.cpp + g++ -pipe -O2 -std=gnu++11 -Wall -W -dM -E -o moc_predefs.h ../../Qt5.9.0/5.9/gcc_64/mkspecs/features/data/dummy.cpp + +compiler_moc_header_make_all: moc_partcfgdialog.cpp moc_ventoy2diskwindow.cpp +compiler_moc_header_clean: + -$(DEL_FILE) moc_partcfgdialog.cpp moc_ventoy2diskwindow.cpp +moc_partcfgdialog.cpp: ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/QDialog \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qdialog.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qtwidgetsglobal.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qtguiglobal.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qglobal.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qconfig-bootstrapped.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qconfig.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qtcore-config.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qsystemdetection.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qprocessordetection.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qcompilerdetection.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qtypeinfo.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qsysinfo.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qlogging.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qflags.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qatomic.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qbasicatomic.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qatomic_bootstrap.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qgenericatomic.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qatomic_cxx11.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qatomic_msvc.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qglobalstatic.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qmutex.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qnumeric.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qversiontagging.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qtgui-config.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qtwidgets-config.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qwidget.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qwindowdefs.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qobjectdefs.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qnamespace.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qobjectdefs_impl.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qwindowdefs_win.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qobject.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qstring.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qchar.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qbytearray.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qrefcount.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qarraydata.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qstringbuilder.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qlist.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qalgorithms.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qiterator.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qhashfunctions.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qpair.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qbytearraylist.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qstringlist.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qregexp.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qstringmatcher.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qcoreevent.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qscopedpointer.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qmetatype.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qvarlengtharray.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qcontainerfwd.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qobject_impl.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qmargins.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qpaintdevice.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qrect.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qsize.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qpoint.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qpalette.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qcolor.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qrgb.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qrgba64.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qbrush.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qvector.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qmatrix.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qpolygon.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qregion.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qdatastream.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qiodevice.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qline.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qtransform.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qpainterpath.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qimage.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qpixelformat.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qpixmap.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qsharedpointer.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qshareddata.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qhash.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qsharedpointer_impl.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qfont.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qfontmetrics.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qfontinfo.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qsizepolicy.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qcursor.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qkeysequence.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qevent.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qvariant.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qmap.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qdebug.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qtextstream.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qlocale.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qset.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qcontiguouscache.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qurl.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qurlquery.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qfile.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qfiledevice.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qvector2d.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qtouchdevice.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/QJsonObject \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qjsonobject.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qjsonvalue.h \ + ../Ventoy2Disk/partcfgdialog.h \ + moc_predefs.h \ + ../../Qt5.9.0/5.9/gcc_64/bin/moc + /home/panda/Qt5.9.0/5.9/gcc_64/bin/moc $(DEFINES) --include ./moc_predefs.h -I/home/panda/Qt5.9.0/5.9/gcc_64/mkspecs/linux-g++ -I/home/panda/590/Ventoy2Disk -I/home/panda/Ventoy2Disk/Core -I/home/panda/Ventoy2Disk/Web -I/home/panda/Ventoy2Disk/QT -I/home/panda/Ventoy2Disk/Include -I/home/panda/Ventoy2Disk/Lib/libhttp/include -I/home/panda/Ventoy2Disk/Lib/fat_io_lib/include -I/home/panda/Ventoy2Disk/Lib/xz-embedded/linux/include -I/home/panda/Ventoy2Disk/Lib/xz-embedded/linux/include/linux -I/home/panda/Ventoy2Disk/Lib/xz-embedded/userspace -I/home/panda/Ventoy2Disk/Lib/exfat/src/libexfat -I/home/panda/Ventoy2Disk/Lib/fat_io_lib -I/home/panda/Qt5.9.0/5.9/gcc_64/include -I/home/panda/Qt5.9.0/5.9/gcc_64/include/QtWidgets -I/home/panda/Qt5.9.0/5.9/gcc_64/include/QtGui -I/home/panda/Qt5.9.0/5.9/gcc_64/include/QtCore -I. -I/usr/include/c++/8 -I/usr/include/x86_64-linux-gnu/c++/8 -I/usr/include/c++/8/backward -I/usr/lib/gcc/x86_64-linux-gnu/8/include -I/usr/local/include -I/usr/lib/gcc/x86_64-linux-gnu/8/include-fixed -I/usr/include/x86_64-linux-gnu -I/usr/include ../Ventoy2Disk/partcfgdialog.h -o moc_partcfgdialog.cpp + +moc_ventoy2diskwindow.cpp: ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/QMainWindow \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qmainwindow.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qtwidgetsglobal.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qtguiglobal.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qglobal.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qconfig-bootstrapped.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qconfig.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qtcore-config.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qsystemdetection.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qprocessordetection.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qcompilerdetection.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qtypeinfo.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qsysinfo.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qlogging.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qflags.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qatomic.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qbasicatomic.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qatomic_bootstrap.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qgenericatomic.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qatomic_cxx11.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qatomic_msvc.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qglobalstatic.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qmutex.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qnumeric.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qversiontagging.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qtgui-config.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qtwidgets-config.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qwidget.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qwindowdefs.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qobjectdefs.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qnamespace.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qobjectdefs_impl.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qwindowdefs_win.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qobject.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qstring.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qchar.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qbytearray.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qrefcount.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qarraydata.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qstringbuilder.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qlist.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qalgorithms.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qiterator.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qhashfunctions.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qpair.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qbytearraylist.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qstringlist.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qregexp.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qstringmatcher.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qcoreevent.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qscopedpointer.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qmetatype.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qvarlengtharray.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qcontainerfwd.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qobject_impl.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qmargins.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qpaintdevice.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qrect.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qsize.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qpoint.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qpalette.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qcolor.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qrgb.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qrgba64.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qbrush.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qvector.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qmatrix.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qpolygon.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qregion.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qdatastream.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qiodevice.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qline.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qtransform.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qpainterpath.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qimage.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qpixelformat.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qpixmap.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qsharedpointer.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qshareddata.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qhash.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qsharedpointer_impl.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qfont.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qfontmetrics.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qfontinfo.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qsizepolicy.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qcursor.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qkeysequence.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qevent.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qvariant.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qmap.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qdebug.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qtextstream.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qlocale.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qset.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qcontiguouscache.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qurl.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qurlquery.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qfile.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qfiledevice.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qvector2d.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qtouchdevice.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qtabwidget.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qicon.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/QActionGroup \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qactiongroup.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qaction.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/QJsonDocument \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qjsondocument.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qjsonvalue.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/QFile \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/QJsonObject \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qjsonobject.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/QJsonArray \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qjsonarray.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/QVector \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/QtGlobal \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/QDebug \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/QCloseEvent \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/QThread \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qthread.h \ + ../Ventoy2Disk/partcfgdialog.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/QDialog \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qdialog.h \ + ../Ventoy2Disk/ventoy2diskwindow.h \ + moc_predefs.h \ + ../../Qt5.9.0/5.9/gcc_64/bin/moc + /home/panda/Qt5.9.0/5.9/gcc_64/bin/moc $(DEFINES) --include ./moc_predefs.h -I/home/panda/Qt5.9.0/5.9/gcc_64/mkspecs/linux-g++ -I/home/panda/590/Ventoy2Disk -I/home/panda/Ventoy2Disk/Core -I/home/panda/Ventoy2Disk/Web -I/home/panda/Ventoy2Disk/QT -I/home/panda/Ventoy2Disk/Include -I/home/panda/Ventoy2Disk/Lib/libhttp/include -I/home/panda/Ventoy2Disk/Lib/fat_io_lib/include -I/home/panda/Ventoy2Disk/Lib/xz-embedded/linux/include -I/home/panda/Ventoy2Disk/Lib/xz-embedded/linux/include/linux -I/home/panda/Ventoy2Disk/Lib/xz-embedded/userspace -I/home/panda/Ventoy2Disk/Lib/exfat/src/libexfat -I/home/panda/Ventoy2Disk/Lib/fat_io_lib -I/home/panda/Qt5.9.0/5.9/gcc_64/include -I/home/panda/Qt5.9.0/5.9/gcc_64/include/QtWidgets -I/home/panda/Qt5.9.0/5.9/gcc_64/include/QtGui -I/home/panda/Qt5.9.0/5.9/gcc_64/include/QtCore -I. -I/usr/include/c++/8 -I/usr/include/x86_64-linux-gnu/c++/8 -I/usr/include/c++/8/backward -I/usr/lib/gcc/x86_64-linux-gnu/8/include -I/usr/local/include -I/usr/lib/gcc/x86_64-linux-gnu/8/include-fixed -I/usr/include/x86_64-linux-gnu -I/usr/include ../Ventoy2Disk/ventoy2diskwindow.h -o moc_ventoy2diskwindow.cpp + +compiler_moc_source_make_all: +compiler_moc_source_clean: +compiler_uic_make_all: ui_partcfgdialog.h ui_ventoy2diskwindow.h +compiler_uic_clean: + -$(DEL_FILE) ui_partcfgdialog.h ui_ventoy2diskwindow.h +ui_partcfgdialog.h: ../Ventoy2Disk/partcfgdialog.ui \ + ../../Qt5.9.0/5.9/gcc_64/bin/uic + /home/panda/Qt5.9.0/5.9/gcc_64/bin/uic ../Ventoy2Disk/partcfgdialog.ui -o ui_partcfgdialog.h + +ui_ventoy2diskwindow.h: ../Ventoy2Disk/ventoy2diskwindow.ui \ + ../../Qt5.9.0/5.9/gcc_64/bin/uic + /home/panda/Qt5.9.0/5.9/gcc_64/bin/uic ../Ventoy2Disk/ventoy2diskwindow.ui -o ui_ventoy2diskwindow.h + +compiler_yacc_decl_make_all: +compiler_yacc_decl_clean: +compiler_yacc_impl_make_all: +compiler_yacc_impl_clean: +compiler_lex_make_all: +compiler_lex_clean: +compiler_clean: compiler_moc_predefs_clean compiler_moc_header_clean compiler_uic_clean + +####### Compile + +ventoy_crc32.o: ../Ventoy2Disk/Core/ventoy_crc32.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ventoy_crc32.o ../Ventoy2Disk/Core/ventoy_crc32.c + +ventoy_disk.o: ../Ventoy2Disk/Core/ventoy_disk.c ../../Ventoy2Disk/Core/ventoy_define.h \ + ../../Ventoy2Disk/Core/ventoy_disk.h \ + ../../Ventoy2Disk/Core/ventoy_util.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_filelib.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_opts.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_access.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_defs.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_types.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_list.h + $(CC) -c $(CFLAGS) $(INCPATH) -o ventoy_disk.o ../Ventoy2Disk/Core/ventoy_disk.c + +ventoy_json.o: ../Ventoy2Disk/Core/ventoy_json.c ../../Ventoy2Disk/Core/ventoy_define.h \ + ../../Ventoy2Disk/Core/ventoy_util.h \ + ../../Ventoy2Disk/Core/ventoy_json.h + $(CC) -c $(CFLAGS) $(INCPATH) -o ventoy_json.o ../Ventoy2Disk/Core/ventoy_json.c + +ventoy_log.o: ../Ventoy2Disk/Core/ventoy_log.c ../../Ventoy2Disk/Core/ventoy_define.h + $(CC) -c $(CFLAGS) $(INCPATH) -o ventoy_log.o ../Ventoy2Disk/Core/ventoy_log.c + +ventoy_md5.o: ../Ventoy2Disk/Core/ventoy_md5.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ventoy_md5.o ../Ventoy2Disk/Core/ventoy_md5.c + +ventoy_util.o: ../Ventoy2Disk/Core/ventoy_util.c ../../Ventoy2Disk/Core/ventoy_define.h \ + ../../Ventoy2Disk/Core/ventoy_util.h + $(CC) -c $(CFLAGS) $(INCPATH) -o ventoy_util.o ../Ventoy2Disk/Core/ventoy_util.c + +cluster.o: ../Ventoy2Disk/Lib/exfat/src/libexfat/cluster.c ../Ventoy2Disk/Lib/exfat/src/libexfat/exfat.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/config.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/compiler.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/exfatfs.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/byteorder.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/platform.h + $(CC) -c $(CFLAGS) $(INCPATH) -o cluster.o ../Ventoy2Disk/Lib/exfat/src/libexfat/cluster.c + +io.o: ../Ventoy2Disk/Lib/exfat/src/libexfat/io.c ../Ventoy2Disk/Lib/exfat/src/libexfat/exfat.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/config.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/compiler.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/exfatfs.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/byteorder.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/platform.h + $(CC) -c $(CFLAGS) $(INCPATH) -o io.o ../Ventoy2Disk/Lib/exfat/src/libexfat/io.c + +lookup.o: ../Ventoy2Disk/Lib/exfat/src/libexfat/lookup.c ../Ventoy2Disk/Lib/exfat/src/libexfat/exfat.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/config.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/compiler.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/exfatfs.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/byteorder.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/platform.h + $(CC) -c $(CFLAGS) $(INCPATH) -o lookup.o ../Ventoy2Disk/Lib/exfat/src/libexfat/lookup.c + +mount.o: ../Ventoy2Disk/Lib/exfat/src/libexfat/mount.c ../Ventoy2Disk/Lib/exfat/src/libexfat/exfat.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/config.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/compiler.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/exfatfs.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/byteorder.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/platform.h + $(CC) -c $(CFLAGS) $(INCPATH) -o mount.o ../Ventoy2Disk/Lib/exfat/src/libexfat/mount.c + +node.o: ../Ventoy2Disk/Lib/exfat/src/libexfat/node.c ../Ventoy2Disk/Lib/exfat/src/libexfat/exfat.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/config.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/compiler.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/exfatfs.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/byteorder.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/platform.h + $(CC) -c $(CFLAGS) $(INCPATH) -o node.o ../Ventoy2Disk/Lib/exfat/src/libexfat/node.c + +repair.o: ../Ventoy2Disk/Lib/exfat/src/libexfat/repair.c ../Ventoy2Disk/Lib/exfat/src/libexfat/exfat.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/config.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/compiler.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/exfatfs.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/byteorder.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/platform.h + $(CC) -c $(CFLAGS) $(INCPATH) -o repair.o ../Ventoy2Disk/Lib/exfat/src/libexfat/repair.c + +time.o: ../Ventoy2Disk/Lib/exfat/src/libexfat/time.c ../Ventoy2Disk/Lib/exfat/src/libexfat/exfat.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/config.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/compiler.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/exfatfs.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/byteorder.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/platform.h + $(CC) -c $(CFLAGS) $(INCPATH) -o time.o ../Ventoy2Disk/Lib/exfat/src/libexfat/time.c + +utf.o: ../Ventoy2Disk/Lib/exfat/src/libexfat/utf.c ../Ventoy2Disk/Lib/exfat/src/libexfat/exfat.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/config.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/compiler.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/exfatfs.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/byteorder.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/platform.h + $(CC) -c $(CFLAGS) $(INCPATH) -o utf.o ../Ventoy2Disk/Lib/exfat/src/libexfat/utf.c + +utils.o: ../Ventoy2Disk/Lib/exfat/src/libexfat/utils.c ../Ventoy2Disk/Lib/exfat/src/libexfat/exfat.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/config.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/compiler.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/exfatfs.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/byteorder.h \ + ../Ventoy2Disk/Lib/exfat/src/libexfat/platform.h + $(CC) -c $(CFLAGS) $(INCPATH) -o utils.o ../Ventoy2Disk/Lib/exfat/src/libexfat/utils.c + +cbm.o: ../Ventoy2Disk/Lib/exfat/src/mkfs/cbm.c ../Ventoy2Disk/Lib/exfat/src/mkfs/cbm.h \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/exfat.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/config.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/compiler.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/exfatfs.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/byteorder.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/platform.h \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/fat.h \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/uct.h \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/rootdir.h + $(CC) -c $(CFLAGS) $(INCPATH) -o cbm.o ../Ventoy2Disk/Lib/exfat/src/mkfs/cbm.c + +fat.o: ../Ventoy2Disk/Lib/exfat/src/mkfs/fat.c ../Ventoy2Disk/Lib/exfat/src/mkfs/fat.h \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/exfat.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/config.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/compiler.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/exfatfs.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/byteorder.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/platform.h \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/cbm.h \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/uct.h \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/rootdir.h + $(CC) -c $(CFLAGS) $(INCPATH) -o fat.o ../Ventoy2Disk/Lib/exfat/src/mkfs/fat.c + +mkexfat.o: ../Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.c ../Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/exfat.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/config.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/compiler.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/exfatfs.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/byteorder.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/platform.h + $(CC) -c $(CFLAGS) $(INCPATH) -o mkexfat.o ../Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.c + +mkexfat_main.o: ../Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat_main.c ../Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/exfat.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/config.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/compiler.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/exfatfs.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/byteorder.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/platform.h \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/vbr.h \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/fat.h \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/cbm.h \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/uct.h \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/rootdir.h + $(CC) -c $(CFLAGS) $(INCPATH) -o mkexfat_main.o ../Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat_main.c + +rootdir.o: ../Ventoy2Disk/Lib/exfat/src/mkfs/rootdir.c ../Ventoy2Disk/Lib/exfat/src/mkfs/rootdir.h \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/exfat.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/config.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/compiler.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/exfatfs.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/byteorder.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/platform.h \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/uct.h \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/cbm.h \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/uctc.h + $(CC) -c $(CFLAGS) $(INCPATH) -o rootdir.o ../Ventoy2Disk/Lib/exfat/src/mkfs/rootdir.c + +uct.o: ../Ventoy2Disk/Lib/exfat/src/mkfs/uct.c ../Ventoy2Disk/Lib/exfat/src/mkfs/uct.h \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/exfat.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/config.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/compiler.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/exfatfs.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/byteorder.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/platform.h \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/uctc.h + $(CC) -c $(CFLAGS) $(INCPATH) -o uct.o ../Ventoy2Disk/Lib/exfat/src/mkfs/uct.c + +uctc.o: ../Ventoy2Disk/Lib/exfat/src/mkfs/uctc.c ../Ventoy2Disk/Lib/exfat/src/mkfs/uctc.h + $(CC) -c $(CFLAGS) $(INCPATH) -o uctc.o ../Ventoy2Disk/Lib/exfat/src/mkfs/uctc.c + +vbr.o: ../Ventoy2Disk/Lib/exfat/src/mkfs/vbr.c ../Ventoy2Disk/Lib/exfat/src/mkfs/vbr.h \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/exfat.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/config.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/compiler.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/exfatfs.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/byteorder.h \ + ../../Ventoy2Disk/Lib/exfat/src/libexfat/platform.h \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/fat.h \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/cbm.h \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/uct.h \ + ../Ventoy2Disk/Lib/exfat/src/mkfs/rootdir.h + $(CC) -c $(CFLAGS) $(INCPATH) -o vbr.o ../Ventoy2Disk/Lib/exfat/src/mkfs/vbr.c + +fat_access.o: ../Ventoy2Disk/Lib/fat_io_lib/fat_access.c ../../Ventoy2Disk/Lib/fat_io_lib/fat_defs.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_opts.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_types.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_access.h \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_table.h \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_misc.h \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_write.h \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_string.h + $(CC) -c $(CFLAGS) $(INCPATH) -o fat_access.o ../Ventoy2Disk/Lib/fat_io_lib/fat_access.c + +fat_cache.o: ../Ventoy2Disk/Lib/fat_io_lib/fat_cache.c ../Ventoy2Disk/Lib/fat_io_lib/fat_cache.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_filelib.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_opts.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_access.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_defs.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_types.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_list.h + $(CC) -c $(CFLAGS) $(INCPATH) -o fat_cache.o ../Ventoy2Disk/Lib/fat_io_lib/fat_cache.c + +fat_filelib.o: ../Ventoy2Disk/Lib/fat_io_lib/fat_filelib.c ../../Ventoy2Disk/Lib/fat_io_lib/fat_defs.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_opts.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_types.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_access.h \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_table.h \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_misc.h \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_write.h \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_string.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_filelib.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_list.h \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_cache.h + $(CC) -c $(CFLAGS) $(INCPATH) -o fat_filelib.o ../Ventoy2Disk/Lib/fat_io_lib/fat_filelib.c + +fat_format.o: ../Ventoy2Disk/Lib/fat_io_lib/fat_format.c ../../Ventoy2Disk/Lib/fat_io_lib/fat_defs.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_opts.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_types.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_access.h \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_table.h \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_misc.h \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_write.h \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_string.h \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_format.h + $(CC) -c $(CFLAGS) $(INCPATH) -o fat_format.o ../Ventoy2Disk/Lib/fat_io_lib/fat_format.c + +fat_misc.o: ../Ventoy2Disk/Lib/fat_io_lib/fat_misc.c ../Ventoy2Disk/Lib/fat_io_lib/fat_misc.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_defs.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_opts.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_types.h + $(CC) -c $(CFLAGS) $(INCPATH) -o fat_misc.o ../Ventoy2Disk/Lib/fat_io_lib/fat_misc.c + +fat_string.o: ../Ventoy2Disk/Lib/fat_io_lib/fat_string.c ../Ventoy2Disk/Lib/fat_io_lib/fat_string.h + $(CC) -c $(CFLAGS) $(INCPATH) -o fat_string.o ../Ventoy2Disk/Lib/fat_io_lib/fat_string.c + +fat_table.o: ../Ventoy2Disk/Lib/fat_io_lib/fat_table.c ../../Ventoy2Disk/Lib/fat_io_lib/fat_defs.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_opts.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_types.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_access.h \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_table.h \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_misc.h + $(CC) -c $(CFLAGS) $(INCPATH) -o fat_table.o ../Ventoy2Disk/Lib/fat_io_lib/fat_table.c + +fat_write.o: ../Ventoy2Disk/Lib/fat_io_lib/fat_write.c ../../Ventoy2Disk/Lib/fat_io_lib/fat_defs.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_opts.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_types.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_access.h \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_table.h \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_misc.h \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_write.h \ + ../Ventoy2Disk/Lib/fat_io_lib/fat_string.h + $(CC) -c $(CFLAGS) $(INCPATH) -o fat_write.o ../Ventoy2Disk/Lib/fat_io_lib/fat_write.c + +decompress_unxz.o: ../Ventoy2Disk/Lib/xz-embedded/linux/lib/decompress_unxz.c ../../Ventoy2Disk/Lib/xz-embedded/linux/include/linux/xz.h \ + ../Ventoy2Disk/Lib/xz-embedded/linux/lib/xz/xz_private.h \ + ../../Ventoy2Disk/Lib/xz-embedded/userspace/xz_config.h \ + ../Ventoy2Disk/Lib/xz-embedded/linux/lib/xz/xz_crc32.c \ + ../Ventoy2Disk/Lib/xz-embedded/linux/lib/xz/xz_dec_stream.c \ + ../Ventoy2Disk/Lib/xz-embedded/linux/lib/xz/xz_stream.h \ + ../Ventoy2Disk/Lib/xz-embedded/linux/lib/xz/xz_dec_lzma2.c \ + ../Ventoy2Disk/Lib/xz-embedded/linux/lib/xz/xz_lzma2.h \ + ../Ventoy2Disk/Lib/xz-embedded/linux/lib/xz/xz_dec_bcj.c + $(CC) -c $(CFLAGS) $(INCPATH) -o decompress_unxz.o ../Ventoy2Disk/Lib/xz-embedded/linux/lib/decompress_unxz.c + +refresh_icon_data.o: ../Ventoy2Disk/QT/refresh_icon_data.c + $(CC) -c $(CFLAGS) $(INCPATH) -o refresh_icon_data.o ../Ventoy2Disk/QT/refresh_icon_data.c + +secure_icon_data.o: ../Ventoy2Disk/QT/secure_icon_data.c + $(CC) -c $(CFLAGS) $(INCPATH) -o secure_icon_data.o ../Ventoy2Disk/QT/secure_icon_data.c + +ventoy_qt_stub.o: ../Ventoy2Disk/QT/ventoy_qt_stub.c ../../Ventoy2Disk/Core/ventoy_define.h \ + ../../Ventoy2Disk/Core/ventoy_json.h \ + ../../Ventoy2Disk/Core/ventoy_util.h \ + ../../Ventoy2Disk/Core/ventoy_disk.h \ + ../../Ventoy2Disk/Web/ventoy_http.h \ + ../../Ventoy2Disk/Lib/libhttp/include/civetweb.h + $(CC) -c $(CFLAGS) $(INCPATH) -o ventoy_qt_stub.o ../Ventoy2Disk/QT/ventoy_qt_stub.c + +ventoy_http.o: ../Ventoy2Disk/Web/ventoy_http.c ../../Ventoy2Disk/Core/ventoy_define.h \ + ../../Ventoy2Disk/Core/ventoy_json.h \ + ../../Ventoy2Disk/Core/ventoy_util.h \ + ../../Ventoy2Disk/Core/ventoy_disk.h \ + ../../Ventoy2Disk/Web/ventoy_http.h \ + ../../Ventoy2Disk/Lib/libhttp/include/civetweb.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_filelib.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_opts.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_access.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_defs.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_types.h \ + ../../Ventoy2Disk/Lib/fat_io_lib/fat_list.h + $(CC) -c $(CFLAGS) $(INCPATH) -o ventoy_http.o ../Ventoy2Disk/Web/ventoy_http.c + +main.o: ../Ventoy2Disk/main.cpp ../Ventoy2Disk/ventoy2diskwindow.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/QMainWindow \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qmainwindow.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qtwidgetsglobal.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qtguiglobal.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qglobal.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qconfig-bootstrapped.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qconfig.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qtcore-config.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qsystemdetection.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qprocessordetection.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qcompilerdetection.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qtypeinfo.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qsysinfo.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qlogging.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qflags.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qatomic.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qbasicatomic.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qatomic_bootstrap.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qgenericatomic.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qatomic_cxx11.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qatomic_msvc.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qglobalstatic.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qmutex.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qnumeric.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qversiontagging.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qtgui-config.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qtwidgets-config.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qwidget.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qwindowdefs.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qobjectdefs.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qnamespace.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qobjectdefs_impl.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qwindowdefs_win.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qobject.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qstring.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qchar.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qbytearray.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qrefcount.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qarraydata.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qstringbuilder.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qlist.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qalgorithms.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qiterator.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qhashfunctions.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qpair.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qbytearraylist.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qstringlist.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qregexp.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qstringmatcher.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qcoreevent.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qscopedpointer.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qmetatype.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qvarlengtharray.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qcontainerfwd.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qobject_impl.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qmargins.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qpaintdevice.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qrect.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qsize.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qpoint.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qpalette.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qcolor.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qrgb.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qrgba64.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qbrush.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qvector.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qmatrix.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qpolygon.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qregion.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qdatastream.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qiodevice.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qline.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qtransform.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qpainterpath.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qimage.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qpixelformat.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qpixmap.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qsharedpointer.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qshareddata.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qhash.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qsharedpointer_impl.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qfont.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qfontmetrics.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qfontinfo.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qsizepolicy.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qcursor.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qkeysequence.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qevent.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qvariant.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qmap.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qdebug.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qtextstream.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qlocale.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qset.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qcontiguouscache.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qurl.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qurlquery.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qfile.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qfiledevice.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qvector2d.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qtouchdevice.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qtabwidget.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qicon.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/QActionGroup \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qactiongroup.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qaction.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/QJsonDocument \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qjsondocument.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qjsonvalue.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/QFile \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/QJsonObject \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qjsonobject.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/QJsonArray \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qjsonarray.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/QVector \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/QtGlobal \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/QDebug \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/QCloseEvent \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/QThread \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qthread.h \ + ../Ventoy2Disk/partcfgdialog.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/QDialog \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qdialog.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/QApplication \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qapplication.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qcoreapplication.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qeventloop.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qdesktopwidget.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qguiapplication.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qinputmethod.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/QMessageBox \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qmessagebox.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/QFileInfo \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qfileinfo.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/QStyle \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qstyle.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/QDesktopWidget \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/QPixmap \ + ../../Ventoy2Disk/Core/ventoy_define.h \ + ../../Ventoy2Disk/Core/ventoy_util.h \ + ../../Ventoy2Disk/QT/ventoy_qt.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o main.o ../Ventoy2Disk/main.cpp + +partcfgdialog.o: ../Ventoy2Disk/partcfgdialog.cpp ../Ventoy2Disk/partcfgdialog.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/QDialog \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qdialog.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qtwidgetsglobal.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qtguiglobal.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qglobal.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qconfig-bootstrapped.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qconfig.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qtcore-config.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qsystemdetection.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qprocessordetection.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qcompilerdetection.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qtypeinfo.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qsysinfo.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qlogging.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qflags.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qatomic.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qbasicatomic.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qatomic_bootstrap.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qgenericatomic.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qatomic_cxx11.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qatomic_msvc.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qglobalstatic.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qmutex.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qnumeric.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qversiontagging.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qtgui-config.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qtwidgets-config.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qwidget.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qwindowdefs.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qobjectdefs.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qnamespace.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qobjectdefs_impl.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qwindowdefs_win.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qobject.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qstring.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qchar.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qbytearray.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qrefcount.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qarraydata.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qstringbuilder.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qlist.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qalgorithms.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qiterator.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qhashfunctions.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qpair.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qbytearraylist.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qstringlist.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qregexp.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qstringmatcher.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qcoreevent.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qscopedpointer.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qmetatype.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qvarlengtharray.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qcontainerfwd.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qobject_impl.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qmargins.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qpaintdevice.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qrect.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qsize.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qpoint.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qpalette.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qcolor.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qrgb.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qrgba64.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qbrush.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qvector.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qmatrix.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qpolygon.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qregion.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qdatastream.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qiodevice.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qline.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qtransform.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qpainterpath.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qimage.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qpixelformat.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qpixmap.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qsharedpointer.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qshareddata.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qhash.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qsharedpointer_impl.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qfont.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qfontmetrics.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qfontinfo.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qsizepolicy.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qcursor.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qkeysequence.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qevent.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qvariant.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qmap.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qdebug.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qtextstream.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qlocale.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qset.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qcontiguouscache.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qurl.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qurlquery.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qfile.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qfiledevice.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qvector2d.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qtouchdevice.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/QJsonObject \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qjsonobject.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qjsonvalue.h \ + ui_partcfgdialog.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/QDebug \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/QMessageBox \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qmessagebox.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o partcfgdialog.o ../Ventoy2Disk/partcfgdialog.cpp + +ventoy2diskwindow.o: ../Ventoy2Disk/ventoy2diskwindow.cpp ../Ventoy2Disk/ventoy2diskwindow.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/QMainWindow \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qmainwindow.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qtwidgetsglobal.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qtguiglobal.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qglobal.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qconfig-bootstrapped.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qconfig.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qtcore-config.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qsystemdetection.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qprocessordetection.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qcompilerdetection.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qtypeinfo.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qsysinfo.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qlogging.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qflags.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qatomic.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qbasicatomic.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qatomic_bootstrap.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qgenericatomic.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qatomic_cxx11.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qatomic_msvc.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qglobalstatic.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qmutex.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qnumeric.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qversiontagging.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qtgui-config.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qtwidgets-config.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qwidget.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qwindowdefs.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qobjectdefs.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qnamespace.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qobjectdefs_impl.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qwindowdefs_win.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qobject.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qstring.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qchar.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qbytearray.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qrefcount.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qarraydata.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qstringbuilder.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qlist.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qalgorithms.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qiterator.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qhashfunctions.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qpair.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qbytearraylist.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qstringlist.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qregexp.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qstringmatcher.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qcoreevent.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qscopedpointer.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qmetatype.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qvarlengtharray.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qcontainerfwd.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qobject_impl.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qmargins.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qpaintdevice.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qrect.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qsize.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qpoint.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qpalette.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qcolor.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qrgb.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qrgba64.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qbrush.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qvector.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qmatrix.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qpolygon.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qregion.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qdatastream.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qiodevice.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qline.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qtransform.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qpainterpath.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qimage.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qpixelformat.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qpixmap.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qsharedpointer.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qshareddata.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qhash.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qsharedpointer_impl.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qfont.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qfontmetrics.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qfontinfo.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qsizepolicy.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qcursor.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qkeysequence.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qevent.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qvariant.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qmap.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qdebug.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qtextstream.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qlocale.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qset.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qcontiguouscache.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qurl.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qurlquery.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qfile.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qfiledevice.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qvector2d.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qtouchdevice.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qtabwidget.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/qicon.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/QActionGroup \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qactiongroup.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qaction.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/QJsonDocument \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qjsondocument.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qjsonvalue.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/QFile \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/QJsonObject \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qjsonobject.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/QJsonArray \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qjsonarray.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/QVector \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/QtGlobal \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/QDebug \ + ../../Qt5.9.0/5.9/gcc_64/include/QtGui/QCloseEvent \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/QThread \ + ../../Qt5.9.0/5.9/gcc_64/include/QtCore/qthread.h \ + ../Ventoy2Disk/partcfgdialog.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/QDialog \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qdialog.h \ + ui_ventoy2diskwindow.h \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/QMessageBox \ + ../../Qt5.9.0/5.9/gcc_64/include/QtWidgets/qmessagebox.h \ + ../../Ventoy2Disk/Core/ventoy_define.h \ + ../../Ventoy2Disk/Core/ventoy_util.h \ + ../../Ventoy2Disk/Core/ventoy_disk.h \ + ../../Ventoy2Disk/Core/ventoy_json.h \ + ../../Ventoy2Disk/Web/ventoy_http.h \ + ../../Ventoy2Disk/Lib/libhttp/include/civetweb.h \ + ../../Ventoy2Disk/QT/ventoy_qt.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ventoy2diskwindow.o ../Ventoy2Disk/ventoy2diskwindow.cpp + +moc_partcfgdialog.o: moc_partcfgdialog.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_partcfgdialog.o moc_partcfgdialog.cpp + +moc_ventoy2diskwindow.o: moc_ventoy2diskwindow.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_ventoy2diskwindow.o moc_ventoy2diskwindow.cpp + +####### Install + +install_target: first FORCE + @test -d $(INSTALL_ROOT)/opt/Ventoy2Disk/bin || mkdir -p $(INSTALL_ROOT)/opt/Ventoy2Disk/bin + -$(QINSTALL_PROGRAM) $(QMAKE_TARGET) $(INSTALL_ROOT)/opt/Ventoy2Disk/bin/$(QMAKE_TARGET) + -$(STRIP) $(INSTALL_ROOT)/opt/Ventoy2Disk/bin/$(QMAKE_TARGET) + +uninstall_target: FORCE + -$(DEL_FILE) $(INSTALL_ROOT)/opt/Ventoy2Disk/bin/$(QMAKE_TARGET) + -$(DEL_DIR) $(INSTALL_ROOT)/opt/Ventoy2Disk/bin/ + + +install: install_target FORCE + +uninstall: uninstall_target FORCE + +FORCE: + diff --git a/LinuxGUI/Ventoy2Disk/QT/build/moc_partcfgdialog.cpp b/LinuxGUI/Ventoy2Disk/QT/build/moc_partcfgdialog.cpp new file mode 100644 index 0000000..5bd328b --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/QT/build/moc_partcfgdialog.cpp @@ -0,0 +1,124 @@ +/**************************************************************************** +** Meta object code from reading C++ file 'partcfgdialog.h' +** +** Created by: The Qt Meta Object Compiler version 67 (Qt 5.9.0) +** +** WARNING! All changes made in this file will be lost! +*****************************************************************************/ + +#include "../partcfgdialog.h" +#include +#include +#if !defined(Q_MOC_OUTPUT_REVISION) +#error "The header file 'partcfgdialog.h' doesn't include ." +#elif Q_MOC_OUTPUT_REVISION != 67 +#error "This file was generated using the moc from 5.9.0. It" +#error "cannot be used with the include files from this version of Qt." +#error "(The moc has changed too much.)" +#endif + +QT_BEGIN_MOC_NAMESPACE +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED +struct qt_meta_stringdata_PartCfgDialog_t { + QByteArrayData data[6]; + char stringdata0[97]; +}; +#define QT_MOC_LITERAL(idx, ofs, len) \ + Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \ + qptrdiff(offsetof(qt_meta_stringdata_PartCfgDialog_t, stringdata0) + ofs \ + - idx * sizeof(QByteArrayData)) \ + ) +static const qt_meta_stringdata_PartCfgDialog_t qt_meta_stringdata_PartCfgDialog = { + { +QT_MOC_LITERAL(0, 0, 13), // "PartCfgDialog" +QT_MOC_LITERAL(1, 14, 23), // "on_pushButtonOK_clicked" +QT_MOC_LITERAL(2, 38, 0), // "" +QT_MOC_LITERAL(3, 39, 27), // "on_pushButtonCancel_clicked" +QT_MOC_LITERAL(4, 67, 24), // "on_checkBox_stateChanged" +QT_MOC_LITERAL(5, 92, 4) // "arg1" + + }, + "PartCfgDialog\0on_pushButtonOK_clicked\0" + "\0on_pushButtonCancel_clicked\0" + "on_checkBox_stateChanged\0arg1" +}; +#undef QT_MOC_LITERAL + +static const uint qt_meta_data_PartCfgDialog[] = { + + // content: + 7, // revision + 0, // classname + 0, 0, // classinfo + 3, 14, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + 0, // flags + 0, // signalCount + + // slots: name, argc, parameters, tag, flags + 1, 0, 29, 2, 0x08 /* Private */, + 3, 0, 30, 2, 0x08 /* Private */, + 4, 1, 31, 2, 0x08 /* Private */, + + // slots: parameters + QMetaType::Void, + QMetaType::Void, + QMetaType::Void, QMetaType::Int, 5, + + 0 // eod +}; + +void PartCfgDialog::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +{ + if (_c == QMetaObject::InvokeMetaMethod) { + PartCfgDialog *_t = static_cast(_o); + Q_UNUSED(_t) + switch (_id) { + case 0: _t->on_pushButtonOK_clicked(); break; + case 1: _t->on_pushButtonCancel_clicked(); break; + case 2: _t->on_checkBox_stateChanged((*reinterpret_cast< int(*)>(_a[1]))); break; + default: ; + } + } +} + +const QMetaObject PartCfgDialog::staticMetaObject = { + { &QDialog::staticMetaObject, qt_meta_stringdata_PartCfgDialog.data, + qt_meta_data_PartCfgDialog, qt_static_metacall, nullptr, nullptr} +}; + + +const QMetaObject *PartCfgDialog::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject; +} + +void *PartCfgDialog::qt_metacast(const char *_clname) +{ + if (!_clname) return nullptr; + if (!strcmp(_clname, qt_meta_stringdata_PartCfgDialog.stringdata0)) + return static_cast(const_cast< PartCfgDialog*>(this)); + return QDialog::qt_metacast(_clname); +} + +int PartCfgDialog::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QDialog::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + if (_id < 3) + qt_static_metacall(this, _c, _id, _a); + _id -= 3; + } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) { + if (_id < 3) + *reinterpret_cast(_a[0]) = -1; + _id -= 3; + } + return _id; +} +QT_WARNING_POP +QT_END_MOC_NAMESPACE diff --git a/LinuxGUI/Ventoy2Disk/QT/build/moc_predefs.h b/LinuxGUI/Ventoy2Disk/QT/build/moc_predefs.h new file mode 100644 index 0000000..868c52f --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/QT/build/moc_predefs.h @@ -0,0 +1,375 @@ +#define __DBL_MIN_EXP__ (-1021) +#define __FLT32X_MAX_EXP__ 1024 +#define __cpp_attributes 200809 +#define __UINT_LEAST16_MAX__ 0xffff +#define __ATOMIC_ACQUIRE 2 +#define __FLT128_MAX_10_EXP__ 4932 +#define __FLT_MIN__ 1.17549435082228750796873653722224568e-38F +#define __GCC_IEC_559_COMPLEX 2 +#define __UINT_LEAST8_TYPE__ unsigned char +#define __SIZEOF_FLOAT80__ 16 +#define __INTMAX_C(c) c ## L +#define __CHAR_BIT__ 8 +#define __UINT8_MAX__ 0xff +#define __WINT_MAX__ 0xffffffffU +#define __FLT32_MIN_EXP__ (-125) +#define __cpp_static_assert 200410 +#define __ORDER_LITTLE_ENDIAN__ 1234 +#define __SIZE_MAX__ 0xffffffffffffffffUL +#define __WCHAR_MAX__ 0x7fffffff +#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1 +#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1 +#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1 +#define __DBL_DENORM_MIN__ double(4.94065645841246544176568792868221372e-324L) +#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1 +#define __GCC_ATOMIC_CHAR_LOCK_FREE 2 +#define __GCC_IEC_559 2 +#define __FLT32X_DECIMAL_DIG__ 17 +#define __FLT_EVAL_METHOD__ 0 +#define __unix__ 1 +#define __cpp_binary_literals 201304 +#define __FLT64_DECIMAL_DIG__ 17 +#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2 +#define __x86_64 1 +#define __cpp_variadic_templates 200704 +#define __UINT_FAST64_MAX__ 0xffffffffffffffffUL +#define __SIG_ATOMIC_TYPE__ int +#define __DBL_MIN_10_EXP__ (-307) +#define __FINITE_MATH_ONLY__ 0 +#define __GNUC_PATCHLEVEL__ 0 +#define __FLT32_HAS_DENORM__ 1 +#define __UINT_FAST8_MAX__ 0xff +#define __has_include(STR) __has_include__(STR) +#define __DEC64_MAX_EXP__ 385 +#define __INT8_C(c) c +#define __INT_LEAST8_WIDTH__ 8 +#define __UINT_LEAST64_MAX__ 0xffffffffffffffffUL +#define __SHRT_MAX__ 0x7fff +#define __LDBL_MAX__ 1.18973149535723176502126385303097021e+4932L +#define __FLT64X_MAX_10_EXP__ 4932 +#define __UINT_LEAST8_MAX__ 0xff +#define __GCC_ATOMIC_BOOL_LOCK_FREE 2 +#define __FLT128_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966F128 +#define __UINTMAX_TYPE__ long unsigned int +#define __linux 1 +#define __DEC32_EPSILON__ 1E-6DF +#define __FLT_EVAL_METHOD_TS_18661_3__ 0 +#define __OPTIMIZE__ 1 +#define __unix 1 +#define __UINT32_MAX__ 0xffffffffU +#define __GXX_EXPERIMENTAL_CXX0X__ 1 +#define __LDBL_MAX_EXP__ 16384 +#define __FLT128_MIN_EXP__ (-16381) +#define __WINT_MIN__ 0U +#define __linux__ 1 +#define __FLT128_MIN_10_EXP__ (-4931) +#define __INT_LEAST16_WIDTH__ 16 +#define __SCHAR_MAX__ 0x7f +#define __FLT128_MANT_DIG__ 113 +#define __WCHAR_MIN__ (-__WCHAR_MAX__ - 1) +#define __INT64_C(c) c ## L +#define __DBL_DIG__ 15 +#define __GCC_ATOMIC_POINTER_LOCK_FREE 2 +#define __FLT64X_MANT_DIG__ 64 +#define __SIZEOF_INT__ 4 +#define __SIZEOF_POINTER__ 8 +#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2 +#define __USER_LABEL_PREFIX__ +#define __FLT64X_EPSILON__ 1.08420217248550443400745280086994171e-19F64x +#define __STDC_HOSTED__ 1 +#define __LDBL_HAS_INFINITY__ 1 +#define __FLT32_DIG__ 6 +#define __FLT_EPSILON__ 1.19209289550781250000000000000000000e-7F +#define __GXX_WEAK__ 1 +#define __SHRT_WIDTH__ 16 +#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L +#define __DEC32_MAX__ 9.999999E96DF +#define __cpp_threadsafe_static_init 200806 +#define __FLT64X_DENORM_MIN__ 3.64519953188247460252840593361941982e-4951F64x +#define __FLT32X_HAS_INFINITY__ 1 +#define __INT32_MAX__ 0x7fffffff +#define __INT_WIDTH__ 32 +#define __SIZEOF_LONG__ 8 +#define __STDC_IEC_559__ 1 +#define __STDC_ISO_10646__ 201706L +#define __UINT16_C(c) c +#define __PTRDIFF_WIDTH__ 64 +#define __DECIMAL_DIG__ 21 +#define __FLT64_EPSILON__ 2.22044604925031308084726333618164062e-16F64 +#define __gnu_linux__ 1 +#define __INTMAX_WIDTH__ 64 +#define __FLT64_MIN_EXP__ (-1021) +#define __has_include_next(STR) __has_include_next__(STR) +#define __FLT64X_MIN_10_EXP__ (-4931) +#define __LDBL_HAS_QUIET_NAN__ 1 +#define __FLT64_MANT_DIG__ 53 +#define __GNUC__ 8 +#define __GXX_RTTI 1 +#define __MMX__ 1 +#define __cpp_delegating_constructors 200604 +#define __FLT_HAS_DENORM__ 1 +#define __SIZEOF_LONG_DOUBLE__ 16 +#define __BIGGEST_ALIGNMENT__ 16 +#define __STDC_UTF_16__ 1 +#define __FLT64_MAX_10_EXP__ 308 +#define __FLT32_HAS_INFINITY__ 1 +#define __DBL_MAX__ double(1.79769313486231570814527423731704357e+308L) +#define __cpp_raw_strings 200710 +#define __INT_FAST32_MAX__ 0x7fffffffffffffffL +#define __DBL_HAS_INFINITY__ 1 +#define __DEC32_MIN_EXP__ (-94) +#define __INTPTR_WIDTH__ 64 +#define __FLT32X_HAS_DENORM__ 1 +#define __INT_FAST16_TYPE__ long int +#define __LDBL_HAS_DENORM__ 1 +#define __cplusplus 201103L +#define __cpp_ref_qualifiers 200710 +#define __DEC128_MAX__ 9.999999999999999999999999999999999E6144DL +#define __INT_LEAST32_MAX__ 0x7fffffff +#define __DEC32_MIN__ 1E-95DF +#define __DEPRECATED 1 +#define __cpp_rvalue_references 200610 +#define __DBL_MAX_EXP__ 1024 +#define __WCHAR_WIDTH__ 32 +#define __FLT32_MAX__ 3.40282346638528859811704183484516925e+38F32 +#define __DEC128_EPSILON__ 1E-33DL +#define __SSE2_MATH__ 1 +#define __ATOMIC_HLE_RELEASE 131072 +#define __PTRDIFF_MAX__ 0x7fffffffffffffffL +#define __amd64 1 +#define __ATOMIC_HLE_ACQUIRE 65536 +#define __FLT32_HAS_QUIET_NAN__ 1 +#define __GNUG__ 8 +#define __LONG_LONG_MAX__ 0x7fffffffffffffffLL +#define __SIZEOF_SIZE_T__ 8 +#define __cpp_rvalue_reference 200610 +#define __cpp_nsdmi 200809 +#define __FLT64X_MIN_EXP__ (-16381) +#define __SIZEOF_WINT_T__ 4 +#define __LONG_LONG_WIDTH__ 64 +#define __cpp_initializer_lists 200806 +#define __FLT32_MAX_EXP__ 128 +#define __cpp_hex_float 201603 +#define __GCC_HAVE_DWARF2_CFI_ASM 1 +#define __GXX_ABI_VERSION 1013 +#define __FLT128_HAS_INFINITY__ 1 +#define __FLT_MIN_EXP__ (-125) +#define __cpp_lambdas 200907 +#define __FLT64X_HAS_QUIET_NAN__ 1 +#define __INT_FAST64_TYPE__ long int +#define __FLT64_DENORM_MIN__ 4.94065645841246544176568792868221372e-324F64 +#define __DBL_MIN__ double(2.22507385850720138309023271733240406e-308L) +#define __LP64__ 1 +#define __FLT32X_EPSILON__ 2.22044604925031308084726333618164062e-16F32x +#define __DECIMAL_BID_FORMAT__ 1 +#define __FLT64_MIN_10_EXP__ (-307) +#define __FLT64X_DECIMAL_DIG__ 21 +#define __DEC128_MIN__ 1E-6143DL +#define __REGISTER_PREFIX__ +#define __UINT16_MAX__ 0xffff +#define __DBL_HAS_DENORM__ 1 +#define __FLT32_MIN__ 1.17549435082228750796873653722224568e-38F32 +#define __UINT8_TYPE__ unsigned char +#define __FLT_MANT_DIG__ 24 +#define __LDBL_DECIMAL_DIG__ 21 +#define __VERSION__ "8.3.0" +#define __UINT64_C(c) c ## UL +#define __cpp_unicode_characters 200704 +#define _STDC_PREDEF_H 1 +#define __GCC_ATOMIC_INT_LOCK_FREE 2 +#define __FLT128_MAX_EXP__ 16384 +#define __FLT32_MANT_DIG__ 24 +#define __FLOAT_WORD_ORDER__ __ORDER_LITTLE_ENDIAN__ +#define __STDC_IEC_559_COMPLEX__ 1 +#define __FLT128_HAS_DENORM__ 1 +#define __FLT128_DIG__ 33 +#define __SCHAR_WIDTH__ 8 +#define __INT32_C(c) c +#define __DEC64_EPSILON__ 1E-15DD +#define __ORDER_PDP_ENDIAN__ 3412 +#define __DEC128_MIN_EXP__ (-6142) +#define __FLT32_MAX_10_EXP__ 38 +#define __INT_FAST32_TYPE__ long int +#define __UINT_LEAST16_TYPE__ short unsigned int +#define __FLT64X_HAS_INFINITY__ 1 +#define unix 1 +#define __INT16_MAX__ 0x7fff +#define __cpp_rtti 199711 +#define __SIZE_TYPE__ long unsigned int +#define __UINT64_MAX__ 0xffffffffffffffffUL +#define __FLT64X_DIG__ 18 +#define __INT8_TYPE__ signed char +#define __ELF__ 1 +#define __GCC_ASM_FLAG_OUTPUTS__ 1 +#define __FLT_RADIX__ 2 +#define __INT_LEAST16_TYPE__ short int +#define __LDBL_EPSILON__ 1.08420217248550443400745280086994171e-19L +#define __UINTMAX_C(c) c ## UL +#define __GLIBCXX_BITSIZE_INT_N_0 128 +#define __k8 1 +#define __SIG_ATOMIC_MAX__ 0x7fffffff +#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2 +#define __SIZEOF_PTRDIFF_T__ 8 +#define __FLT32X_MANT_DIG__ 53 +#define __x86_64__ 1 +#define __FLT32X_MIN_EXP__ (-1021) +#define __DEC32_SUBNORMAL_MIN__ 0.000001E-95DF +#define __INT_FAST16_MAX__ 0x7fffffffffffffffL +#define __FLT64_DIG__ 15 +#define __UINT_FAST32_MAX__ 0xffffffffffffffffUL +#define __UINT_LEAST64_TYPE__ long unsigned int +#define __FLT_HAS_QUIET_NAN__ 1 +#define __FLT_MAX_10_EXP__ 38 +#define __LONG_MAX__ 0x7fffffffffffffffL +#define __FLT64X_HAS_DENORM__ 1 +#define __DEC128_SUBNORMAL_MIN__ 0.000000000000000000000000000000001E-6143DL +#define __FLT_HAS_INFINITY__ 1 +#define __cpp_unicode_literals 200710 +#define __UINT_FAST16_TYPE__ long unsigned int +#define __DEC64_MAX__ 9.999999999999999E384DD +#define __INT_FAST32_WIDTH__ 64 +#define __CHAR16_TYPE__ short unsigned int +#define __PRAGMA_REDEFINE_EXTNAME 1 +#define __SIZE_WIDTH__ 64 +#define __SEG_FS 1 +#define __INT_LEAST16_MAX__ 0x7fff +#define __DEC64_MANT_DIG__ 16 +#define __INT64_MAX__ 0x7fffffffffffffffL +#define __UINT_LEAST32_MAX__ 0xffffffffU +#define __SEG_GS 1 +#define __FLT32_DENORM_MIN__ 1.40129846432481707092372958328991613e-45F32 +#define __GCC_ATOMIC_LONG_LOCK_FREE 2 +#define __SIG_ATOMIC_WIDTH__ 32 +#define __INT_LEAST64_TYPE__ long int +#define __INT16_TYPE__ short int +#define __INT_LEAST8_TYPE__ signed char +#define __DEC32_MAX_EXP__ 97 +#define __INT_FAST8_MAX__ 0x7f +#define __FLT128_MAX__ 1.18973149535723176508575932662800702e+4932F128 +#define __INTPTR_MAX__ 0x7fffffffffffffffL +#define linux 1 +#define __cpp_range_based_for 200907 +#define __FLT64_HAS_QUIET_NAN__ 1 +#define __FLT32_MIN_10_EXP__ (-37) +#define __SSE2__ 1 +#define __EXCEPTIONS 1 +#define __LDBL_MANT_DIG__ 64 +#define __DBL_HAS_QUIET_NAN__ 1 +#define __FLT64_HAS_INFINITY__ 1 +#define __FLT64X_MAX__ 1.18973149535723176502126385303097021e+4932F64x +#define __SIG_ATOMIC_MIN__ (-__SIG_ATOMIC_MAX__ - 1) +#define __code_model_small__ 1 +#define __k8__ 1 +#define __INTPTR_TYPE__ long int +#define __UINT16_TYPE__ short unsigned int +#define __WCHAR_TYPE__ int +#define __SIZEOF_FLOAT__ 4 +#define __UINTPTR_MAX__ 0xffffffffffffffffUL +#define __INT_FAST64_WIDTH__ 64 +#define __DEC64_MIN_EXP__ (-382) +#define __cpp_decltype 200707 +#define __FLT32_DECIMAL_DIG__ 9 +#define __INT_FAST64_MAX__ 0x7fffffffffffffffL +#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1 +#define __FLT_DIG__ 6 +#define __FLT64X_MAX_EXP__ 16384 +#define __UINT_FAST64_TYPE__ long unsigned int +#define __INT_MAX__ 0x7fffffff +#define __amd64__ 1 +#define __INT64_TYPE__ long int +#define __FLT_MAX_EXP__ 128 +#define __ORDER_BIG_ENDIAN__ 4321 +#define __DBL_MANT_DIG__ 53 +#define __cpp_inheriting_constructors 201511 +#define __SIZEOF_FLOAT128__ 16 +#define __INT_LEAST64_MAX__ 0x7fffffffffffffffL +#define __DEC64_MIN__ 1E-383DD +#define __WINT_TYPE__ unsigned int +#define __UINT_LEAST32_TYPE__ unsigned int +#define __SIZEOF_SHORT__ 2 +#define __SSE__ 1 +#define __LDBL_MIN_EXP__ (-16381) +#define __FLT64_MAX__ 1.79769313486231570814527423731704357e+308F64 +#define __WINT_WIDTH__ 32 +#define __INT_LEAST8_MAX__ 0x7f +#define __FLT32X_MAX_10_EXP__ 308 +#define __SIZEOF_INT128__ 16 +#define __LDBL_MAX_10_EXP__ 4932 +#define __ATOMIC_RELAXED 0 +#define __DBL_EPSILON__ double(2.22044604925031308084726333618164062e-16L) +#define __FLT128_MIN__ 3.36210314311209350626267781732175260e-4932F128 +#define _LP64 1 +#define __UINT8_C(c) c +#define __FLT64_MAX_EXP__ 1024 +#define __INT_LEAST32_TYPE__ int +#define __SIZEOF_WCHAR_T__ 4 +#define __FLT128_HAS_QUIET_NAN__ 1 +#define __INT_FAST8_TYPE__ signed char +#define __FLT64X_MIN__ 3.36210314311209350626267781732175260e-4932F64x +#define __GNUC_STDC_INLINE__ 1 +#define __FLT64_HAS_DENORM__ 1 +#define __FLT32_EPSILON__ 1.19209289550781250000000000000000000e-7F32 +#define __DBL_DECIMAL_DIG__ 17 +#define __STDC_UTF_32__ 1 +#define __INT_FAST8_WIDTH__ 8 +#define __FXSR__ 1 +#define __DEC_EVAL_METHOD__ 2 +#define __FLT32X_MAX__ 1.79769313486231570814527423731704357e+308F32x +#define __cpp_runtime_arrays 198712 +#define __UINT64_TYPE__ long unsigned int +#define __UINT32_C(c) c ## U +#define __INTMAX_MAX__ 0x7fffffffffffffffL +#define __cpp_alias_templates 200704 +#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ +#define __FLT_DENORM_MIN__ 1.40129846432481707092372958328991613e-45F +#define __INT8_MAX__ 0x7f +#define __LONG_WIDTH__ 64 +#define __UINT_FAST32_TYPE__ long unsigned int +#define __CHAR32_TYPE__ unsigned int +#define __FLT_MAX__ 3.40282346638528859811704183484516925e+38F +#define __cpp_constexpr 200704 +#define __INT32_TYPE__ int +#define __SIZEOF_DOUBLE__ 8 +#define __cpp_exceptions 199711 +#define __FLT_MIN_10_EXP__ (-37) +#define __FLT64_MIN__ 2.22507385850720138309023271733240406e-308F64 +#define __INT_LEAST32_WIDTH__ 32 +#define __INTMAX_TYPE__ long int +#define __DEC128_MAX_EXP__ 6145 +#define __FLT32X_HAS_QUIET_NAN__ 1 +#define __ATOMIC_CONSUME 1 +#define __GNUC_MINOR__ 3 +#define __GLIBCXX_TYPE_INT_N_0 __int128 +#define __INT_FAST16_WIDTH__ 64 +#define __UINTMAX_MAX__ 0xffffffffffffffffUL +#define __DEC32_MANT_DIG__ 7 +#define __FLT32X_DENORM_MIN__ 4.94065645841246544176568792868221372e-324F32x +#define __DBL_MAX_10_EXP__ 308 +#define __LDBL_DENORM_MIN__ 3.64519953188247460252840593361941982e-4951L +#define __INT16_C(c) c +#define __STDC__ 1 +#define __FLT32X_DIG__ 15 +#define __PTRDIFF_TYPE__ long int +#define __ATOMIC_SEQ_CST 5 +#define __UINT32_TYPE__ unsigned int +#define __FLT32X_MIN_10_EXP__ (-307) +#define __UINTPTR_TYPE__ long unsigned int +#define __DEC64_SUBNORMAL_MIN__ 0.000000000000001E-383DD +#define __DEC128_MANT_DIG__ 34 +#define __LDBL_MIN_10_EXP__ (-4931) +#define __FLT128_EPSILON__ 1.92592994438723585305597794258492732e-34F128 +#define __SSE_MATH__ 1 +#define __SIZEOF_LONG_LONG__ 8 +#define __cpp_user_defined_literals 200809 +#define __FLT128_DECIMAL_DIG__ 36 +#define __GCC_ATOMIC_LLONG_LOCK_FREE 2 +#define __FLT32X_MIN__ 2.22507385850720138309023271733240406e-308F32x +#define __LDBL_DIG__ 18 +#define __FLT_DECIMAL_DIG__ 9 +#define __UINT_FAST16_MAX__ 0xffffffffffffffffUL +#define __GCC_ATOMIC_SHORT_LOCK_FREE 2 +#define __INT_LEAST64_WIDTH__ 64 +#define __UINT_FAST8_TYPE__ unsigned char +#define _GNU_SOURCE 1 +#define __ATOMIC_ACQ_REL 4 +#define __ATOMIC_RELEASE 3 diff --git a/LinuxGUI/Ventoy2Disk/QT/build/moc_ventoy2diskwindow.cpp b/LinuxGUI/Ventoy2Disk/QT/build/moc_ventoy2diskwindow.cpp new file mode 100644 index 0000000..f04103e --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/QT/build/moc_ventoy2diskwindow.cpp @@ -0,0 +1,294 @@ +/**************************************************************************** +** Meta object code from reading C++ file 'ventoy2diskwindow.h' +** +** Created by: The Qt Meta Object Compiler version 67 (Qt 5.9.0) +** +** WARNING! All changes made in this file will be lost! +*****************************************************************************/ + +#include "../ventoy2diskwindow.h" +#include +#include +#if !defined(Q_MOC_OUTPUT_REVISION) +#error "The header file 'ventoy2diskwindow.h' doesn't include ." +#elif Q_MOC_OUTPUT_REVISION != 67 +#error "This file was generated using the moc from 5.9.0. It" +#error "cannot be used with the include files from this version of Qt." +#error "(The moc has changed too much.)" +#endif + +QT_BEGIN_MOC_NAMESPACE +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED +struct qt_meta_stringdata_MyQThread_t { + QByteArrayData data[5]; + char stringdata0[33]; +}; +#define QT_MOC_LITERAL(idx, ofs, len) \ + Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \ + qptrdiff(offsetof(qt_meta_stringdata_MyQThread_t, stringdata0) + ofs \ + - idx * sizeof(QByteArrayData)) \ + ) +static const qt_meta_stringdata_MyQThread_t qt_meta_stringdata_MyQThread = { + { +QT_MOC_LITERAL(0, 0, 9), // "MyQThread" +QT_MOC_LITERAL(1, 10, 12), // "thread_event" +QT_MOC_LITERAL(2, 23, 0), // "" +QT_MOC_LITERAL(3, 24, 3), // "msg" +QT_MOC_LITERAL(4, 28, 4) // "data" + + }, + "MyQThread\0thread_event\0\0msg\0data" +}; +#undef QT_MOC_LITERAL + +static const uint qt_meta_data_MyQThread[] = { + + // content: + 7, // revision + 0, // classname + 0, 0, // classinfo + 1, 14, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + 0, // flags + 1, // signalCount + + // signals: name, argc, parameters, tag, flags + 1, 2, 19, 2, 0x06 /* Public */, + + // signals: parameters + QMetaType::Void, QMetaType::Int, QMetaType::Int, 3, 4, + + 0 // eod +}; + +void MyQThread::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +{ + if (_c == QMetaObject::InvokeMetaMethod) { + MyQThread *_t = static_cast(_o); + Q_UNUSED(_t) + switch (_id) { + case 0: _t->thread_event((*reinterpret_cast< int(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2]))); break; + default: ; + } + } else if (_c == QMetaObject::IndexOfMethod) { + int *result = reinterpret_cast(_a[0]); + void **func = reinterpret_cast(_a[1]); + { + typedef void (MyQThread::*_t)(int , int ); + if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&MyQThread::thread_event)) { + *result = 0; + return; + } + } + } +} + +const QMetaObject MyQThread::staticMetaObject = { + { &QThread::staticMetaObject, qt_meta_stringdata_MyQThread.data, + qt_meta_data_MyQThread, qt_static_metacall, nullptr, nullptr} +}; + + +const QMetaObject *MyQThread::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject; +} + +void *MyQThread::qt_metacast(const char *_clname) +{ + if (!_clname) return nullptr; + if (!strcmp(_clname, qt_meta_stringdata_MyQThread.stringdata0)) + return static_cast(const_cast< MyQThread*>(this)); + return QThread::qt_metacast(_clname); +} + +int MyQThread::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QThread::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + if (_id < 1) + qt_static_metacall(this, _c, _id, _a); + _id -= 1; + } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) { + if (_id < 1) + *reinterpret_cast(_a[0]) = -1; + _id -= 1; + } + return _id; +} + +// SIGNAL 0 +void MyQThread::thread_event(int _t1, int _t2) +{ + void *_a[] = { nullptr, const_cast(reinterpret_cast(&_t1)), const_cast(reinterpret_cast(&_t2)) }; + QMetaObject::activate(this, &staticMetaObject, 0, _a); +} +struct qt_meta_stringdata_Ventoy2DiskWindow_t { + QByteArrayData data[19]; + char stringdata0[367]; +}; +#define QT_MOC_LITERAL(idx, ofs, len) \ + Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \ + qptrdiff(offsetof(qt_meta_stringdata_Ventoy2DiskWindow_t, stringdata0) + ofs \ + - idx * sizeof(QByteArrayData)) \ + ) +static const qt_meta_stringdata_Ventoy2DiskWindow_t qt_meta_stringdata_Ventoy2DiskWindow = { + { +QT_MOC_LITERAL(0, 0, 17), // "Ventoy2DiskWindow" +QT_MOC_LITERAL(1, 18, 12), // "thread_event" +QT_MOC_LITERAL(2, 31, 0), // "" +QT_MOC_LITERAL(3, 32, 3), // "msg" +QT_MOC_LITERAL(4, 36, 4), // "data" +QT_MOC_LITERAL(5, 41, 23), // "part_style_check_action" +QT_MOC_LITERAL(6, 65, 8), // "QAction*" +QT_MOC_LITERAL(7, 74, 3), // "act" +QT_MOC_LITERAL(8, 78, 17), // "lang_check_action" +QT_MOC_LITERAL(9, 96, 24), // "on_ButtonInstall_clicked" +QT_MOC_LITERAL(10, 121, 23), // "on_ButtonUpdate_clicked" +QT_MOC_LITERAL(11, 145, 24), // "on_ButtonRefresh_clicked" +QT_MOC_LITERAL(12, 170, 37), // "on_comboBoxDevice_currentInde..." +QT_MOC_LITERAL(13, 208, 5), // "index" +QT_MOC_LITERAL(14, 214, 42), // "on_actionPartition_Configurat..." +QT_MOC_LITERAL(15, 257, 31), // "on_actionClear_Ventoy_triggered" +QT_MOC_LITERAL(16, 289, 33), // "on_actionShow_All_Devices_tog..." +QT_MOC_LITERAL(17, 323, 4), // "arg1" +QT_MOC_LITERAL(18, 328, 38) // "on_actionSecure_Boot_Support_..." + + }, + "Ventoy2DiskWindow\0thread_event\0\0msg\0" + "data\0part_style_check_action\0QAction*\0" + "act\0lang_check_action\0on_ButtonInstall_clicked\0" + "on_ButtonUpdate_clicked\0" + "on_ButtonRefresh_clicked\0" + "on_comboBoxDevice_currentIndexChanged\0" + "index\0on_actionPartition_Configuration_triggered\0" + "on_actionClear_Ventoy_triggered\0" + "on_actionShow_All_Devices_toggled\0" + "arg1\0on_actionSecure_Boot_Support_triggered" +}; +#undef QT_MOC_LITERAL + +static const uint qt_meta_data_Ventoy2DiskWindow[] = { + + // content: + 7, // revision + 0, // classname + 0, 0, // classinfo + 11, 14, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + 0, // flags + 0, // signalCount + + // slots: name, argc, parameters, tag, flags + 1, 2, 69, 2, 0x08 /* Private */, + 5, 1, 74, 2, 0x08 /* Private */, + 8, 1, 77, 2, 0x08 /* Private */, + 9, 0, 80, 2, 0x08 /* Private */, + 10, 0, 81, 2, 0x08 /* Private */, + 11, 0, 82, 2, 0x08 /* Private */, + 12, 1, 83, 2, 0x08 /* Private */, + 14, 0, 86, 2, 0x08 /* Private */, + 15, 0, 87, 2, 0x08 /* Private */, + 16, 1, 88, 2, 0x08 /* Private */, + 18, 0, 91, 2, 0x08 /* Private */, + + // slots: parameters + QMetaType::Void, QMetaType::Int, QMetaType::Int, 3, 4, + QMetaType::Void, 0x80000000 | 6, 7, + QMetaType::Void, 0x80000000 | 6, 7, + QMetaType::Void, + QMetaType::Void, + QMetaType::Void, + QMetaType::Void, QMetaType::Int, 13, + QMetaType::Void, + QMetaType::Void, + QMetaType::Void, QMetaType::Bool, 17, + QMetaType::Void, + + 0 // eod +}; + +void Ventoy2DiskWindow::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +{ + if (_c == QMetaObject::InvokeMetaMethod) { + Ventoy2DiskWindow *_t = static_cast(_o); + Q_UNUSED(_t) + switch (_id) { + case 0: _t->thread_event((*reinterpret_cast< int(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2]))); break; + case 1: _t->part_style_check_action((*reinterpret_cast< QAction*(*)>(_a[1]))); break; + case 2: _t->lang_check_action((*reinterpret_cast< QAction*(*)>(_a[1]))); break; + case 3: _t->on_ButtonInstall_clicked(); break; + case 4: _t->on_ButtonUpdate_clicked(); break; + case 5: _t->on_ButtonRefresh_clicked(); break; + case 6: _t->on_comboBoxDevice_currentIndexChanged((*reinterpret_cast< int(*)>(_a[1]))); break; + case 7: _t->on_actionPartition_Configuration_triggered(); break; + case 8: _t->on_actionClear_Ventoy_triggered(); break; + case 9: _t->on_actionShow_All_Devices_toggled((*reinterpret_cast< bool(*)>(_a[1]))); break; + case 10: _t->on_actionSecure_Boot_Support_triggered(); break; + default: ; + } + } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) { + switch (_id) { + default: *reinterpret_cast(_a[0]) = -1; break; + case 1: + switch (*reinterpret_cast(_a[1])) { + default: *reinterpret_cast(_a[0]) = -1; break; + case 0: + *reinterpret_cast(_a[0]) = qRegisterMetaType< QAction* >(); break; + } + break; + case 2: + switch (*reinterpret_cast(_a[1])) { + default: *reinterpret_cast(_a[0]) = -1; break; + case 0: + *reinterpret_cast(_a[0]) = qRegisterMetaType< QAction* >(); break; + } + break; + } + } +} + +const QMetaObject Ventoy2DiskWindow::staticMetaObject = { + { &QMainWindow::staticMetaObject, qt_meta_stringdata_Ventoy2DiskWindow.data, + qt_meta_data_Ventoy2DiskWindow, qt_static_metacall, nullptr, nullptr} +}; + + +const QMetaObject *Ventoy2DiskWindow::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject; +} + +void *Ventoy2DiskWindow::qt_metacast(const char *_clname) +{ + if (!_clname) return nullptr; + if (!strcmp(_clname, qt_meta_stringdata_Ventoy2DiskWindow.stringdata0)) + return static_cast(const_cast< Ventoy2DiskWindow*>(this)); + return QMainWindow::qt_metacast(_clname); +} + +int Ventoy2DiskWindow::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QMainWindow::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + if (_id < 11) + qt_static_metacall(this, _c, _id, _a); + _id -= 11; + } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) { + if (_id < 11) + qt_static_metacall(this, _c, _id, _a); + _id -= 11; + } + return _id; +} +QT_WARNING_POP +QT_END_MOC_NAMESPACE diff --git a/LinuxGUI/Ventoy2Disk/QT/build/ui_partcfgdialog.h b/LinuxGUI/Ventoy2Disk/QT/build/ui_partcfgdialog.h new file mode 100644 index 0000000..e0244c9 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/QT/build/ui_partcfgdialog.h @@ -0,0 +1,113 @@ +/******************************************************************************** +** Form generated from reading UI file 'partcfgdialog.ui' +** +** Created by: Qt User Interface Compiler version 5.9.0 +** +** WARNING! All changes made in this file will be lost when recompiling UI file! +********************************************************************************/ + +#ifndef UI_PARTCFGDIALOG_H +#define UI_PARTCFGDIALOG_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class Ui_PartCfgDialog +{ +public: + QPushButton *pushButtonOK; + QPushButton *pushButtonCancel; + QGroupBox *groupBox; + QCheckBox *checkBox; + QGroupBox *groupBox_2; + QLineEdit *lineEdit; + QGroupBox *groupBox_3; + QComboBox *comboBox; + QGroupBox *groupBox_4; + QCheckBox *checkBox_2; + + void setupUi(QDialog *PartCfgDialog) + { + if (PartCfgDialog->objectName().isEmpty()) + PartCfgDialog->setObjectName(QStringLiteral("PartCfgDialog")); + PartCfgDialog->resize(420, 258); + pushButtonOK = new QPushButton(PartCfgDialog); + pushButtonOK->setObjectName(QStringLiteral("pushButtonOK")); + pushButtonOK->setGeometry(QRect(90, 210, 90, 30)); + pushButtonCancel = new QPushButton(PartCfgDialog); + pushButtonCancel->setObjectName(QStringLiteral("pushButtonCancel")); + pushButtonCancel->setGeometry(QRect(230, 210, 90, 30)); + groupBox = new QGroupBox(PartCfgDialog); + groupBox->setObjectName(QStringLiteral("groupBox")); + groupBox->setGeometry(QRect(10, 0, 400, 61)); + checkBox = new QCheckBox(groupBox); + checkBox->setObjectName(QStringLiteral("checkBox")); + checkBox->setGeometry(QRect(10, 20, 381, 41)); + checkBox->setAutoRepeatInterval(0); + groupBox_2 = new QGroupBox(PartCfgDialog); + groupBox_2->setObjectName(QStringLiteral("groupBox_2")); + groupBox_2->setGeometry(QRect(10, 60, 200, 61)); + lineEdit = new QLineEdit(groupBox_2); + lineEdit->setObjectName(QStringLiteral("lineEdit")); + lineEdit->setGeometry(QRect(10, 30, 181, 26)); + lineEdit->setMaxLength(14); + groupBox_3 = new QGroupBox(PartCfgDialog); + groupBox_3->setObjectName(QStringLiteral("groupBox_3")); + groupBox_3->setGeometry(QRect(210, 60, 200, 60)); + comboBox = new QComboBox(groupBox_3); + comboBox->setObjectName(QStringLiteral("comboBox")); + comboBox->setGeometry(QRect(10, 30, 181, 26)); + groupBox_4 = new QGroupBox(PartCfgDialog); + groupBox_4->setObjectName(QStringLiteral("groupBox_4")); + groupBox_4->setGeometry(QRect(10, 120, 401, 61)); + checkBox_2 = new QCheckBox(groupBox_4); + checkBox_2->setObjectName(QStringLiteral("checkBox_2")); + checkBox_2->setGeometry(QRect(10, 30, 381, 24)); + checkBox_2->setChecked(true); + + retranslateUi(PartCfgDialog); + + comboBox->setCurrentIndex(1); + + + QMetaObject::connectSlotsByName(PartCfgDialog); + } // setupUi + + void retranslateUi(QDialog *PartCfgDialog) + { + PartCfgDialog->setWindowTitle(QApplication::translate("PartCfgDialog", "Partition Configuration", Q_NULLPTR)); + pushButtonOK->setText(QApplication::translate("PartCfgDialog", "OK", Q_NULLPTR)); + pushButtonCancel->setText(QApplication::translate("PartCfgDialog", "Cancel", Q_NULLPTR)); + groupBox->setTitle(QString()); + checkBox->setText(QApplication::translate("PartCfgDialog", "Preserve some space at the end of the disk", Q_NULLPTR)); + groupBox_2->setTitle(QString()); + groupBox_3->setTitle(QString()); + comboBox->clear(); + comboBox->insertItems(0, QStringList() + << QApplication::translate("PartCfgDialog", "MB", Q_NULLPTR) + << QApplication::translate("PartCfgDialog", "GB", Q_NULLPTR) + ); + groupBox_4->setTitle(QString()); + checkBox_2->setText(QApplication::translate("PartCfgDialog", "Align partitions with 4KB", Q_NULLPTR)); + } // retranslateUi + +}; + +namespace Ui { + class PartCfgDialog: public Ui_PartCfgDialog {}; +} // namespace Ui + +QT_END_NAMESPACE + +#endif // UI_PARTCFGDIALOG_H diff --git a/LinuxGUI/Ventoy2Disk/QT/build/ui_ventoy2diskwindow.h b/LinuxGUI/Ventoy2Disk/QT/build/ui_ventoy2diskwindow.h new file mode 100644 index 0000000..57eceef --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/QT/build/ui_ventoy2diskwindow.h @@ -0,0 +1,202 @@ +/******************************************************************************** +** Form generated from reading UI file 'ventoy2diskwindow.ui' +** +** Created by: Qt User Interface Compiler version 5.9.0 +** +** WARNING! All changes made in this file will be lost when recompiling UI file! +********************************************************************************/ + +#ifndef UI_VENTOY2DISKWINDOW_H +#define UI_VENTOY2DISKWINDOW_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class Ui_Ventoy2DiskWindow +{ +public: + QAction *actionSecure_Boot_Support; + QAction *actionMBR; + QAction *actionGPT; + QAction *actionPartition_Configuration; + QAction *actionClear_Ventoy; + QAction *actionShow_All_Devices; + QWidget *centralwidget; + QGroupBox *groupBoxDevice; + QComboBox *comboBoxDevice; + QPushButton *ButtonRefresh; + QGroupBox *groupBoxVentoyLocal; + QLabel *labelVentoyLocalVer; + QLabel *labelVentoyLocalPartStyle; + QLabel *labelVentoyLocalSecure; + QGroupBox *groupBoxVentoyDevice; + QLabel *labelVentoyDeviceVer; + QLabel *labelVentoyDevicePartStyle; + QLabel *labelVentoyDeviceSecure; + QGroupBox *groupBoxStatus; + QProgressBar *progressBar; + QPushButton *ButtonInstall; + QPushButton *ButtonUpdate; + QMenuBar *menubar; + QMenu *menuOption; + QMenu *menuPartition_Style; + QMenu *menuLanguage; + + void setupUi(QMainWindow *Ventoy2DiskWindow) + { + if (Ventoy2DiskWindow->objectName().isEmpty()) + Ventoy2DiskWindow->setObjectName(QStringLiteral("Ventoy2DiskWindow")); + Ventoy2DiskWindow->resize(441, 367); + actionSecure_Boot_Support = new QAction(Ventoy2DiskWindow); + actionSecure_Boot_Support->setObjectName(QStringLiteral("actionSecure_Boot_Support")); + actionSecure_Boot_Support->setCheckable(true); + actionMBR = new QAction(Ventoy2DiskWindow); + actionMBR->setObjectName(QStringLiteral("actionMBR")); + actionMBR->setCheckable(true); + actionGPT = new QAction(Ventoy2DiskWindow); + actionGPT->setObjectName(QStringLiteral("actionGPT")); + actionGPT->setCheckable(true); + actionPartition_Configuration = new QAction(Ventoy2DiskWindow); + actionPartition_Configuration->setObjectName(QStringLiteral("actionPartition_Configuration")); + actionClear_Ventoy = new QAction(Ventoy2DiskWindow); + actionClear_Ventoy->setObjectName(QStringLiteral("actionClear_Ventoy")); + actionShow_All_Devices = new QAction(Ventoy2DiskWindow); + actionShow_All_Devices->setObjectName(QStringLiteral("actionShow_All_Devices")); + actionShow_All_Devices->setCheckable(true); + centralwidget = new QWidget(Ventoy2DiskWindow); + centralwidget->setObjectName(QStringLiteral("centralwidget")); + groupBoxDevice = new QGroupBox(centralwidget); + groupBoxDevice->setObjectName(QStringLiteral("groupBoxDevice")); + groupBoxDevice->setGeometry(QRect(10, 10, 421, 80)); + comboBoxDevice = new QComboBox(groupBoxDevice); + comboBoxDevice->setObjectName(QStringLiteral("comboBoxDevice")); + comboBoxDevice->setGeometry(QRect(10, 40, 361, 26)); + ButtonRefresh = new QPushButton(groupBoxDevice); + ButtonRefresh->setObjectName(QStringLiteral("ButtonRefresh")); + ButtonRefresh->setGeometry(QRect(380, 37, 30, 30)); + QIcon icon; + icon.addFile(QStringLiteral("../refresh.ico"), QSize(), QIcon::Normal, QIcon::Off); + ButtonRefresh->setIcon(icon); + ButtonRefresh->setIconSize(QSize(24, 24)); + groupBoxVentoyLocal = new QGroupBox(centralwidget); + groupBoxVentoyLocal->setObjectName(QStringLiteral("groupBoxVentoyLocal")); + groupBoxVentoyLocal->setGeometry(QRect(10, 100, 205, 80)); + groupBoxVentoyLocal->setAlignment(Qt::AlignCenter); + labelVentoyLocalVer = new QLabel(groupBoxVentoyLocal); + labelVentoyLocalVer->setObjectName(QStringLiteral("labelVentoyLocalVer")); + labelVentoyLocalVer->setGeometry(QRect(30, 30, 135, 41)); + labelVentoyLocalVer->setAlignment(Qt::AlignCenter); + labelVentoyLocalPartStyle = new QLabel(groupBoxVentoyLocal); + labelVentoyLocalPartStyle->setObjectName(QStringLiteral("labelVentoyLocalPartStyle")); + labelVentoyLocalPartStyle->setGeometry(QRect(172, 60, 31, 18)); + labelVentoyLocalSecure = new QLabel(groupBoxVentoyLocal); + labelVentoyLocalSecure->setObjectName(QStringLiteral("labelVentoyLocalSecure")); + labelVentoyLocalSecure->setGeometry(QRect(12, 36, 21, 31)); + labelVentoyLocalSecure->setPixmap(QPixmap(QString::fromUtf8("../secure.ico"))); + groupBoxVentoyDevice = new QGroupBox(centralwidget); + groupBoxVentoyDevice->setObjectName(QStringLiteral("groupBoxVentoyDevice")); + groupBoxVentoyDevice->setGeometry(QRect(225, 100, 205, 80)); + groupBoxVentoyDevice->setAlignment(Qt::AlignCenter); + labelVentoyDeviceVer = new QLabel(groupBoxVentoyDevice); + labelVentoyDeviceVer->setObjectName(QStringLiteral("labelVentoyDeviceVer")); + labelVentoyDeviceVer->setGeometry(QRect(30, 30, 135, 41)); + labelVentoyDeviceVer->setAlignment(Qt::AlignCenter); + labelVentoyDevicePartStyle = new QLabel(groupBoxVentoyDevice); + labelVentoyDevicePartStyle->setObjectName(QStringLiteral("labelVentoyDevicePartStyle")); + labelVentoyDevicePartStyle->setGeometry(QRect(172, 60, 31, 18)); + labelVentoyDeviceSecure = new QLabel(groupBoxVentoyDevice); + labelVentoyDeviceSecure->setObjectName(QStringLiteral("labelVentoyDeviceSecure")); + labelVentoyDeviceSecure->setGeometry(QRect(12, 36, 21, 31)); + labelVentoyDeviceSecure->setPixmap(QPixmap(QString::fromUtf8("../secure.ico"))); + groupBoxStatus = new QGroupBox(centralwidget); + groupBoxStatus->setObjectName(QStringLiteral("groupBoxStatus")); + groupBoxStatus->setGeometry(QRect(10, 190, 421, 61)); + progressBar = new QProgressBar(groupBoxStatus); + progressBar->setObjectName(QStringLiteral("progressBar")); + progressBar->setGeometry(QRect(10, 30, 401, 23)); + progressBar->setValue(0); + progressBar->setTextVisible(false); + ButtonInstall = new QPushButton(centralwidget); + ButtonInstall->setObjectName(QStringLiteral("ButtonInstall")); + ButtonInstall->setGeometry(QRect(90, 275, 101, 41)); + ButtonUpdate = new QPushButton(centralwidget); + ButtonUpdate->setObjectName(QStringLiteral("ButtonUpdate")); + ButtonUpdate->setGeometry(QRect(250, 275, 101, 41)); + Ventoy2DiskWindow->setCentralWidget(centralwidget); + menubar = new QMenuBar(Ventoy2DiskWindow); + menubar->setObjectName(QStringLiteral("menubar")); + menubar->setGeometry(QRect(0, 0, 441, 23)); + menuOption = new QMenu(menubar); + menuOption->setObjectName(QStringLiteral("menuOption")); + menuPartition_Style = new QMenu(menuOption); + menuPartition_Style->setObjectName(QStringLiteral("menuPartition_Style")); + menuLanguage = new QMenu(menubar); + menuLanguage->setObjectName(QStringLiteral("menuLanguage")); + Ventoy2DiskWindow->setMenuBar(menubar); + + menubar->addAction(menuOption->menuAction()); + menubar->addAction(menuLanguage->menuAction()); + menuOption->addAction(actionSecure_Boot_Support); + menuOption->addAction(menuPartition_Style->menuAction()); + menuOption->addAction(actionPartition_Configuration); + menuOption->addAction(actionClear_Ventoy); + menuOption->addAction(actionShow_All_Devices); + menuPartition_Style->addAction(actionMBR); + menuPartition_Style->addAction(actionGPT); + + retranslateUi(Ventoy2DiskWindow); + + QMetaObject::connectSlotsByName(Ventoy2DiskWindow); + } // setupUi + + void retranslateUi(QMainWindow *Ventoy2DiskWindow) + { + Ventoy2DiskWindow->setWindowTitle(QApplication::translate("Ventoy2DiskWindow", "Ventoy2Disk", Q_NULLPTR)); + actionSecure_Boot_Support->setText(QApplication::translate("Ventoy2DiskWindow", "Secure Boot Support", Q_NULLPTR)); + actionMBR->setText(QApplication::translate("Ventoy2DiskWindow", "MBR", Q_NULLPTR)); + actionGPT->setText(QApplication::translate("Ventoy2DiskWindow", "GPT", Q_NULLPTR)); + actionPartition_Configuration->setText(QApplication::translate("Ventoy2DiskWindow", "Partition Configuration", Q_NULLPTR)); + actionClear_Ventoy->setText(QApplication::translate("Ventoy2DiskWindow", "Clear Ventoy", Q_NULLPTR)); + actionShow_All_Devices->setText(QApplication::translate("Ventoy2DiskWindow", "Show All Devices", Q_NULLPTR)); + groupBoxDevice->setTitle(QApplication::translate("Ventoy2DiskWindow", "Device", Q_NULLPTR)); + ButtonRefresh->setText(QString()); + groupBoxVentoyLocal->setTitle(QApplication::translate("Ventoy2DiskWindow", "Ventoy In Package", Q_NULLPTR)); + labelVentoyLocalVer->setText(QApplication::translate("Ventoy2DiskWindow", "

1.0.53

", Q_NULLPTR)); + labelVentoyLocalPartStyle->setText(QApplication::translate("Ventoy2DiskWindow", "

MBR

", Q_NULLPTR)); + labelVentoyLocalSecure->setText(QString()); + groupBoxVentoyDevice->setTitle(QApplication::translate("Ventoy2DiskWindow", "Ventoy In Device", Q_NULLPTR)); + labelVentoyDeviceVer->setText(QApplication::translate("Ventoy2DiskWindow", "

1.0.52

", Q_NULLPTR)); + labelVentoyDevicePartStyle->setText(QApplication::translate("Ventoy2DiskWindow", "

GPT

", Q_NULLPTR)); + labelVentoyDeviceSecure->setText(QString()); + groupBoxStatus->setTitle(QApplication::translate("Ventoy2DiskWindow", "Status: REDAY", Q_NULLPTR)); + progressBar->setFormat(QString()); + ButtonInstall->setText(QApplication::translate("Ventoy2DiskWindow", "Install", Q_NULLPTR)); + ButtonUpdate->setText(QApplication::translate("Ventoy2DiskWindow", "Update", Q_NULLPTR)); + menuOption->setTitle(QApplication::translate("Ventoy2DiskWindow", "Option", Q_NULLPTR)); + menuPartition_Style->setTitle(QApplication::translate("Ventoy2DiskWindow", "Partition Style", Q_NULLPTR)); + menuLanguage->setTitle(QApplication::translate("Ventoy2DiskWindow", "Language", Q_NULLPTR)); + } // retranslateUi + +}; + +namespace Ui { + class Ventoy2DiskWindow: public Ui_Ventoy2DiskWindow {}; +} // namespace Ui + +QT_END_NAMESPACE + +#endif // UI_VENTOY2DISKWINDOW_H diff --git a/LinuxGUI/Ventoy2Disk/QT/main.cpp b/LinuxGUI/Ventoy2Disk/QT/main.cpp new file mode 100644 index 0000000..60e6281 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/QT/main.cpp @@ -0,0 +1,121 @@ +#include "ventoy2diskwindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern "C" { +#include "ventoy_define.h" +#include "ventoy_util.h" +#include "ventoy_qt.h" +} + +using namespace std; + +char g_log_file[4096]; +char g_ini_file[4096]; + +int main(int argc, char *argv[]) +{ + int ret; + long long size; + QApplication a(argc, argv); + Ventoy2DiskWindow w; + +#ifdef QT_CHECK_EUID + if (geteuid() != 0) + { + QMessageBox::critical(NULL, "Error", "Permission denied!\nPlease run with root privileges."); + return 1; + } +#endif + + if (!QFileInfo::exists("./boot/boot.img")) + { + QString curdir = a.applicationDirPath(); + int index = curdir.indexOf("/tool/"); + + if (index >= 0) + { + QDir::setCurrent(curdir.left(index)); + } + else + { + QDir::setCurrent(curdir); + } + } + + if (!QFileInfo::exists("./boot/boot.img")) + { + QMessageBox::critical(NULL, "Error", "Please run under the correct directory."); + return 1; + } + + ventoy_log_init(); + + snprintf(g_log_file, sizeof(g_log_file), "./log.txt"); + snprintf(g_ini_file, sizeof(g_ini_file), "./Ventoy2Disk.ini"); + for (int i = 0; i < argc; i++) + { + if (argv[i] && argv[i + 1] && strcmp(argv[i], "-l") == 0) + { + snprintf(g_log_file, sizeof(g_log_file), "%s", argv[i + 1]); + } + else if (argv[i] && argv[i + 1] && strcmp(argv[i], "-i") == 0) + { + snprintf(g_ini_file, sizeof(g_ini_file), "%s", argv[i + 1]); + } + } + + QFileInfo Info(g_log_file); + size = (long long)Info.size(); + if (size >= 4 * SIZE_1MB) + { + QFile::remove(g_log_file); + } + + vlog("===================================================\n"); + vlog("===== Ventoy2Disk %s powered by QT %s =====\n", ventoy_get_local_version(), qVersion()); + vlog("===================================================\n"); + vlog("log file is <%s> lastsize:%lld\n", g_log_file, (long long)size); + vlog("ini file is <%s>\n", g_ini_file); + + ventoy_disk_init(); + ventoy_http_init(); + + w.setGeometry(QStyle::alignedRect(Qt::LeftToRight, + Qt::AlignCenter, + w.size(), + a.desktop()->availableGeometry())); + + QPixmap pix; + QIcon icon; + int len; + const uchar *data; + + data = (const uchar *)get_window_icon_raw_data(&len); + pix.loadFromData(data, len); + icon.addPixmap(pix); + w.setWindowIcon(icon); + + w.show(); + w.setFixedSize(w.size()); + + ret = a.exec(); + + ventoy_disk_exit(); + ventoy_http_exit(); + + vlog("######## Ventoy2Disk QT %s exit ########\n", ventoy_get_local_version()); + + /* log exit must at the end */ + ventoy_log_exit(); + + return ret; +} diff --git a/LinuxGUI/Ventoy2Disk/QT/partcfgdialog.cpp b/LinuxGUI/Ventoy2Disk/QT/partcfgdialog.cpp new file mode 100644 index 0000000..c232b8a --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/QT/partcfgdialog.cpp @@ -0,0 +1,101 @@ +#include "partcfgdialog.h" +#include "ui_partcfgdialog.h" +#include +#include + +PartCfgDialog::PartCfgDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::PartCfgDialog) +{ + reserve = false; + unit = 1; + align = true; + valuestr = ""; + resvalue = 0; + + ui->setupUi(this); + + ui->lineEdit->setEnabled(false); + ui->comboBox->setEnabled(false); +} + +PartCfgDialog::~PartCfgDialog() +{ + delete ui; +} + +void PartCfgDialog::update_ui_status() +{ + ui->checkBox->setChecked(reserve); + ui->lineEdit->setEnabled(reserve); + ui->comboBox->setEnabled(reserve); + ui->checkBox_2->setChecked(align); +} + +void PartCfgDialog::update_language_ui(QJsonObject &obj) +{ + ui->checkBox->setText(_LANG_STR("STR_PRESERVE_SPACE")); + ui->checkBox_2->setText(_LANG_STR("STR_PART_ALIGN_4KB")); + ui->pushButtonOK->setText(_LANG_STR("STR_BTN_OK")); + ui->pushButtonCancel->setText(_LANG_STR("STR_BTN_CANCEL")); + + invalid_value = _LANG_STR("STR_SPACE_VAL_INVALID"); + err_title = _LANG_STR("STR_ERROR"); +} + +void PartCfgDialog::on_pushButtonOK_clicked() +{ + if (ui->checkBox->isChecked()) + { + QString str = ui->lineEdit->text(); + + if (str.isEmpty()) + { + QMessageBox::critical(NULL, err_title, invalid_value); + return; + } + + for (int i = 0; i < str.size(); i++) + { + if (str[i] < '0' || str[i] > '9') + { + QMessageBox::critical(NULL, err_title, invalid_value); + return; + } + } + + valuestr = str; + resvalue = str.toLongLong(); + reserve = true; + } + else + { + reserve = false; + } + + align = ui->checkBox_2->isChecked(); + unit = ui->comboBox->currentIndex(); + + accept(); +} + +void PartCfgDialog::on_pushButtonCancel_clicked() +{ + reject(); +} + +void PartCfgDialog::on_checkBox_stateChanged(int arg1) +{ + (void)arg1; + + if (ui->checkBox->isChecked()) + { + ui->lineEdit->setEnabled(true); + ui->comboBox->setEnabled(true); + } + else + { + ui->lineEdit->setEnabled(false); + ui->comboBox->setEnabled(false); + } +} diff --git a/LinuxGUI/Ventoy2Disk/QT/partcfgdialog.h b/LinuxGUI/Ventoy2Disk/QT/partcfgdialog.h new file mode 100644 index 0000000..c57a9ae --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/QT/partcfgdialog.h @@ -0,0 +1,44 @@ +#ifndef PARTCFGDIALOG_H +#define PARTCFGDIALOG_H + +#include +#include + +namespace Ui { +class PartCfgDialog; +} + +class PartCfgDialog : public QDialog +{ + Q_OBJECT + +public: + + bool reserve; + int unit; + bool align; + QString valuestr; + qint64 resvalue; + + QString invalid_value; + QString err_title; + void update_ui_status(); + void update_language_ui(QJsonObject &obj); + + explicit PartCfgDialog(QWidget *parent = nullptr); + ~PartCfgDialog(); + +private slots: + void on_pushButtonOK_clicked(); + + void on_pushButtonCancel_clicked(); + + void on_checkBox_stateChanged(int arg1); + +private: + Ui::PartCfgDialog *ui; +}; + +#define _LANG_STR(id) obj.value(id).toString() + +#endif // PARTCFGDIALOG_H diff --git a/LinuxGUI/Ventoy2Disk/QT/partcfgdialog.ui b/LinuxGUI/Ventoy2Disk/QT/partcfgdialog.ui new file mode 100644 index 0000000..fd131b8 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/QT/partcfgdialog.ui @@ -0,0 +1,165 @@ + + + PartCfgDialog + + + + 0 + 0 + 420 + 258 + + + + Partition Configuration + + + + + 90 + 210 + 90 + 30 + + + + OK + + + + + + 230 + 210 + 90 + 30 + + + + Cancel + + + + + + 10 + 10 + 400 + 51 + + + + + + + + + 10 + 10 + 381 + 41 + + + + Preserve some space at the end of the disk + + + 0 + + + + + + + 10 + 60 + 200 + 60 + + + + + + + + + 10 + 20 + 181 + 26 + + + + 14 + + + + + + + 210 + 60 + 200 + 60 + + + + + + + + + 10 + 20 + 181 + 26 + + + + 1 + + + + MB + + + + + GB + + + + + + + + 10 + 130 + 401 + 51 + + + + + + + + + 10 + 18 + 381 + 24 + + + + Align partitions with 4KB + + + true + + + + + + + diff --git a/LinuxGUI/Ventoy2Disk/QT/refresh_icon_data.c b/LinuxGUI/Ventoy2Disk/QT/refresh_icon_data.c new file mode 100644 index 0000000..0b678ff --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/QT/refresh_icon_data.c @@ -0,0 +1,300 @@ +/****************************************************************************** + * refresh_icon_data.c + * + * Copyright (c) 2021, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include +#include + +static unsigned char refresh_icon_hexData[4286] = { + 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x20, 0x20, 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0xA8, 0x10, + 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x27, + 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x0C, 0xA6, 0xBE, + 0x32, 0x2D, 0xA6, 0xBE, 0x32, 0x54, 0xA6, 0xBE, 0x32, 0x72, 0xA6, 0xBE, 0x32, 0x81, 0xA6, 0xBE, + 0x32, 0x81, 0xA6, 0xBE, 0x32, 0x72, 0xA6, 0xBE, 0x32, 0x54, 0xA6, 0xBE, 0x32, 0x2D, 0xA6, 0xBE, + 0x32, 0x0C, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x21, 0xA6, 0xBE, 0x32, 0x72, 0xA6, 0xBE, 0x32, 0xBF, 0xA6, 0xBE, + 0x32, 0xEB, 0xA6, 0xBE, 0x32, 0xFC, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFC, 0xA6, 0xBE, 0x32, 0xEB, 0xA6, 0xBE, + 0x32, 0xBF, 0xA6, 0xBE, 0x32, 0x72, 0xA6, 0xBE, 0x32, 0x21, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x10, 0xA6, 0xBE, + 0x32, 0x71, 0xA6, 0xBE, 0x32, 0xD9, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xDA, 0xA6, 0xBE, 0x32, 0x71, 0xA6, 0xBE, + 0x32, 0x10, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x29, 0xA6, 0xBE, 0x32, 0xB2, 0xA6, 0xBE, + 0x32, 0xFE, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xA5, 0xBD, 0x30, 0xFF, 0xA5, 0xBD, 0x2F, 0xFF, 0xA5, 0xBD, + 0x2F, 0xFF, 0xA5, 0xBD, 0x2F, 0xFF, 0xA5, 0xBE, 0x31, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFE, 0xA6, 0xBE, + 0x32, 0xB2, 0xA6, 0xBE, 0x32, 0x29, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x35, 0xA6, 0xBE, 0x32, 0xCF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA5, 0xBD, 0x30, 0xFF, 0xA5, 0xBE, + 0x31, 0xFF, 0xAC, 0xC3, 0x40, 0xFF, 0xB7, 0xCA, 0x59, 0xFF, 0xBF, 0xD0, 0x6B, 0xFF, 0xC0, 0xD1, + 0x6E, 0xFF, 0xBA, 0xCD, 0x60, 0xFF, 0xAF, 0xC5, 0x48, 0xFF, 0xA7, 0xBF, 0x34, 0xFF, 0xA5, 0xBD, + 0x2F, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xCF, 0xA6, 0xBE, 0x32, 0x35, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x29, 0xA6, 0xBE, 0x32, 0xCF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xB5, 0xC9, 0x54, 0xFF, 0xD4, 0xE0, + 0x9D, 0xFF, 0xED, 0xF2, 0xD6, 0xFF, 0xF9, 0xFB, 0xF1, 0xFF, 0xFD, 0xFD, 0xFA, 0xFF, 0xFD, 0xFE, + 0xFB, 0xFF, 0xFB, 0xFC, 0xF5, 0xFF, 0xF2, 0xF6, 0xE1, 0xFF, 0xDD, 0xE6, 0xB1, 0xFF, 0xBD, 0xCF, + 0x67, 0xFF, 0xA7, 0xBF, 0x35, 0xFF, 0xA5, 0xBE, 0x30, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xCF, 0xA6, 0xBE, 0x32, 0x29, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x10, 0xA6, 0xBE, + 0x32, 0xB2, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x31, 0xFF, 0xA8, 0xC0, 0x37, 0xFF, 0xCB, 0xD9, 0x87, 0xFF, 0xF4, 0xF7, 0xE6, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0xFB, + 0xF4, 0xFF, 0xD9, 0xE4, 0xA8, 0xFF, 0xAF, 0xC4, 0x46, 0xFF, 0xA5, 0xBD, 0x30, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xB2, 0xA6, 0xBE, + 0x32, 0x10, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x71, 0xA6, 0xBE, + 0x32, 0xFE, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xA9, 0xC0, + 0x38, 0xFF, 0xD5, 0xE0, 0x9D, 0xFF, 0xFD, 0xFE, 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, + 0xFD, 0xFF, 0xEE, 0xF3, 0xD9, 0xFF, 0xD9, 0xE3, 0xA8, 0xFF, 0xCC, 0xDA, 0x8A, 0xFF, 0xCA, 0xD8, + 0x85, 0xFF, 0xD3, 0xDF, 0x99, 0xFF, 0xE6, 0xEC, 0xC4, 0xFF, 0xFA, 0xFB, 0xF3, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xED, 0xC7, 0xFF, 0xB1, 0xC6, 0x4C, 0xFF, 0xA5, 0xBD, + 0x30, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFE, 0xA6, 0xBE, + 0x32, 0x71, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x21, 0xA6, 0xBE, 0x32, 0xDA, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xCD, 0xDB, + 0x8C, 0xFF, 0xFD, 0xFE, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xF7, 0xE7, 0xFF, 0xCB, 0xD9, + 0x87, 0xFF, 0xAE, 0xC3, 0x43, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xA4, 0xBD, 0x2F, 0xFF, 0xA4, 0xBD, + 0x2E, 0xFF, 0xA5, 0xBD, 0x2F, 0xFF, 0xA9, 0xC0, 0x38, 0xFF, 0xBD, 0xCF, 0x66, 0xFF, 0xE8, 0xEE, + 0xC9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE4, 0xEB, 0xC1, 0xFF, 0xAD, 0xC3, + 0x41, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xDA, 0xA6, 0xBE, 0x32, 0x21, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBD, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x72, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA5, 0xBD, 0x2F, 0xFF, 0xA4, 0xBC, 0x2D, 0xFF, 0xB8, 0xCB, 0x5C, 0xFF, 0xF6, 0xF9, + 0xEB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0xF5, 0xDF, 0xFF, 0xBA, 0xCD, 0x60, 0xFF, 0xA4, 0xBD, + 0x2E, 0xFF, 0xA5, 0xBE, 0x31, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA5, 0xBD, 0x2F, 0xFF, 0xAE, 0xC4, + 0x44, 0xFF, 0xE2, 0xE9, 0xBB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0xD6, + 0x7E, 0xFF, 0xA5, 0xBD, 0x2F, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0x72, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x0C, 0xA6, 0xBE, 0x32, 0xC0, 0xA6, 0xBE, 0x32, 0xFF, 0xA9, 0xC0, + 0x39, 0xFF, 0xC8, 0xD7, 0x80, 0xFF, 0xD0, 0xDC, 0x92, 0xFF, 0xE7, 0xEE, 0xC8, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE6, 0xED, 0xC5, 0xFF, 0xCC, 0xDA, 0x8A, 0xFF, 0xB0, 0xC5, + 0x49, 0xFF, 0xA5, 0xBE, 0x31, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA5, 0xBD, + 0x30, 0xFF, 0xB0, 0xC6, 0x4A, 0xFF, 0xE3, 0xEA, 0xBE, 0xFF, 0xEA, 0xEF, 0xCE, 0xFF, 0xB8, 0xCB, + 0x5C, 0xFF, 0xA5, 0xBD, 0x30, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xBF, 0xA6, 0xBE, 0x32, 0x0C, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x2E, 0xA6, 0xBE, 0x32, 0xEB, 0xA6, 0xBE, 0x32, 0xFF, 0xA8, 0xC0, + 0x37, 0xFF, 0xE0, 0xE8, 0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0xF6, 0xE3, 0xFF, 0xB3, 0xC7, + 0x4F, 0xFF, 0xA5, 0xBD, 0x30, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xAA, 0xC1, 0x3A, 0xFF, 0xAB, 0xC1, 0x3D, 0xFF, 0xA6, 0xBE, + 0x31, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xEB, 0xA6, 0xBE, 0x32, 0x2D, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x54, 0xA6, 0xBE, 0x32, 0xFC, 0xA6, 0xBE, 0x32, 0xFF, 0xA5, 0xBD, + 0x30, 0xFF, 0xB6, 0xCA, 0x58, 0xFF, 0xF4, 0xF7, 0xE6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xFE, 0xFB, 0xFF, 0xC9, 0xD8, 0x84, 0xFF, 0xA5, 0xBD, + 0x30, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA5, 0xBE, 0x31, 0xFF, 0xA5, 0xBD, 0x2F, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFC, 0xA6, 0xBE, 0x32, 0x54, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x72, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA5, 0xBE, 0x30, 0xFF, 0xCD, 0xDB, 0x8C, 0xFF, 0xFE, 0xFE, 0xFD, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE2, 0xEA, 0xBC, 0xFF, 0xAA, 0xC1, 0x3A, 0xFF, 0xA6, 0xBE, + 0x31, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xAB, 0xC2, 0x3E, 0xFF, 0xBB, 0xCE, 0x63, 0xFF, 0xA7, 0xBF, + 0x35, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0x72, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x81, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xAB, 0xC2, 0x3E, 0xFF, 0xE6, 0xED, 0xC5, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF5, 0xF8, 0xE8, 0xFF, 0xB7, 0xCB, 0x5A, 0xFF, 0xA5, 0xBD, 0x30, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA5, 0xBE, 0x31, 0xFF, 0xCE, 0xDB, 0x8F, 0xFF, 0xF7, 0xF9, 0xEC, 0xFF, 0xBD, 0xCF, + 0x67, 0xFF, 0xA5, 0xBD, 0x2F, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0x81, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x81, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA5, 0xBD, 0x2F, 0xFF, 0xBB, 0xCD, 0x63, 0xFF, 0xF6, 0xF8, + 0xEA, 0xFF, 0xCE, 0xDB, 0x8F, 0xFF, 0xA5, 0xBE, 0x31, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA5, 0xBD, + 0x30, 0xFF, 0xB7, 0xCB, 0x5A, 0xFF, 0xF5, 0xF8, 0xE8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE8, 0xEE, + 0xC9, 0xFF, 0xAC, 0xC2, 0x40, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0x81, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x72, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA7, 0xBF, 0x34, 0xFF, 0xBA, 0xCD, + 0x60, 0xFF, 0xAB, 0xC2, 0x3E, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xAA, 0xC1, + 0x3A, 0xFF, 0xE2, 0xEA, 0xBC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFE, 0xFF, 0xCF, 0xDC, 0x90, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0x72, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x54, 0xA6, 0xBE, 0x32, 0xFC, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA5, 0xBD, + 0x2F, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA5, 0xBD, 0x30, 0xFF, 0xC9, 0xD8, + 0x84, 0xFF, 0xFD, 0xFE, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF5, 0xF8, 0xE9, 0xFF, 0xB8, 0xCB, 0x5B, 0xFF, 0xA5, 0xBD, 0x30, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFC, 0xA6, 0xBE, 0x32, 0x54, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x2E, 0xA6, 0xBE, 0x32, 0xEB, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xA9, 0xC0, + 0x38, 0xFF, 0xA8, 0xBF, 0x37, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA5, 0xBD, 0x30, 0xFF, 0xB2, 0xC7, 0x4F, 0xFF, 0xF2, 0xF6, + 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE2, 0xE9, 0xBB, 0xFF, 0xA9, 0xC0, 0x38, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xEB, 0xA6, 0xBE, 0x32, 0x2D, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x0C, 0xA6, 0xBE, 0x32, 0xC0, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA5, 0xBD, 0x30, 0xFF, 0xB5, 0xC9, 0x54, 0xFF, 0xE4, 0xEB, + 0xC1, 0xFF, 0xDF, 0xE8, 0xB5, 0xFF, 0xAF, 0xC5, 0x47, 0xFF, 0xA5, 0xBD, 0x30, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA5, 0xBE, 0x31, 0xFF, 0xAF, 0xC5, 0x47, 0xFF, 0xCA, 0xD8, + 0x85, 0xFF, 0xE2, 0xE9, 0xBB, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE9, 0xEF, + 0xCD, 0xFF, 0xCE, 0xDB, 0x8F, 0xFF, 0xC7, 0xD6, 0x7E, 0xFF, 0xA9, 0xC0, 0x39, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xBF, 0xA6, 0xBE, 0x32, 0x0C, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBD, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x73, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA5, 0xBD, 0x2F, 0xFF, 0xC6, 0xD6, 0x7C, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xE8, 0xB5, 0xFF, 0xAC, 0xC3, 0x40, 0xFF, 0xA5, 0xBD, + 0x2F, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xA4, 0xBD, 0x2E, 0xFF, 0xB5, 0xC9, + 0x55, 0xFF, 0xED, 0xF2, 0xD6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFB, 0xF1, 0xFF, 0xBC, 0xCE, + 0x65, 0xFF, 0xA4, 0xBC, 0x2C, 0xFF, 0xA5, 0xBD, 0x2F, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0x72, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x21, 0xA6, 0xBE, 0x32, 0xDA, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xAE, 0xC4, 0x44, 0xFF, 0xE6, 0xED, + 0xC6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE4, 0xEB, 0xC1, 0xFF, 0xB9, 0xCC, + 0x5E, 0xFF, 0xA7, 0xBF, 0x35, 0xFF, 0xA5, 0xBD, 0x2F, 0xFF, 0xA4, 0xBD, 0x2E, 0xFF, 0xA4, 0xBD, + 0x2E, 0xFF, 0xA5, 0xBD, 0x2F, 0xFF, 0xAB, 0xC1, 0x3D, 0xFF, 0xC5, 0xD5, 0x79, 0xFF, 0xF1, 0xF5, + 0xDE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xD3, 0xDF, 0x99, 0xFF, 0xA7, 0xBE, + 0x33, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xDA, 0xA6, 0xBE, 0x32, 0x21, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x72, 0xA6, 0xBE, + 0x32, 0xFE, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA5, 0xBD, 0x30, 0xFF, 0xB3, 0xC8, + 0x51, 0xFF, 0xE9, 0xEF, 0xCD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xFA, + 0xEE, 0xFF, 0xE1, 0xE9, 0xBA, 0xFF, 0xCD, 0xDB, 0x8C, 0xFF, 0xC4, 0xD4, 0x78, 0xFF, 0xC6, 0xD6, + 0x7C, 0xFF, 0xD3, 0xDF, 0x9A, 0xFF, 0xE9, 0xEF, 0xCD, 0xFF, 0xFC, 0xFD, 0xF9, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFE, 0xFF, 0xFE, 0xFF, 0xDB, 0xE4, 0xAB, 0xFF, 0xAA, 0xC1, 0x3C, 0xFF, 0xA6, 0xBE, + 0x31, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFE, 0xA6, 0xBE, + 0x32, 0x71, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x10, 0xA6, 0xBE, + 0x32, 0xB3, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA5, 0xBD, + 0x30, 0xFF, 0xB1, 0xC6, 0x4B, 0xFF, 0xDD, 0xE6, 0xB2, 0xFF, 0xFC, 0xFD, 0xF8, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, + 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xFA, + 0xEE, 0xFF, 0xD1, 0xDE, 0x96, 0xFF, 0xAA, 0xC1, 0x3C, 0xFF, 0xA5, 0xBE, 0x31, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xB2, 0xA6, 0xBE, + 0x32, 0x10, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x29, 0xA6, 0xBE, 0x32, 0xCF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA5, 0xBD, 0x30, 0xFF, 0xA9, 0xC0, 0x38, 0xFF, 0xC1, 0xD2, 0x71, 0xFF, 0xE2, 0xEA, + 0xBC, 0xFF, 0xF5, 0xF8, 0xE9, 0xFF, 0xFD, 0xFD, 0xFA, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFE, 0xFF, + 0xFE, 0xFF, 0xFB, 0xFC, 0xF7, 0xFF, 0xF2, 0xF5, 0xE1, 0xFF, 0xDB, 0xE5, 0xAC, 0xFF, 0xB9, 0xCC, + 0x5F, 0xFF, 0xA6, 0xBE, 0x33, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xCF, 0xA6, 0xBE, 0x32, 0x29, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x35, 0xA6, 0xBE, 0x32, 0xCF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x31, 0xFF, 0xA5, 0xBD, 0x2F, 0xFF, 0xA8, 0xBF, + 0x36, 0xFF, 0xB3, 0xC7, 0x4F, 0xFF, 0xBF, 0xD0, 0x6B, 0xFF, 0xC5, 0xD5, 0x7A, 0xFF, 0xC4, 0xD4, + 0x78, 0xFF, 0xBC, 0xCE, 0x64, 0xFF, 0xB0, 0xC5, 0x48, 0xFF, 0xA6, 0xBE, 0x33, 0xFF, 0xA5, 0xBD, + 0x30, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xCF, 0xA6, 0xBE, 0x32, 0x35, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x29, 0xA6, 0xBE, 0x32, 0xB2, 0xA6, 0xBE, + 0x32, 0xFE, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA5, 0xBD, 0x30, 0xFF, 0xA5, 0xBD, 0x2F, 0xFF, 0xA4, 0xBD, 0x2E, 0xFF, 0xA4, 0xBD, + 0x2E, 0xFF, 0xA5, 0xBD, 0x2F, 0xFF, 0xA5, 0xBE, 0x31, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFE, 0xA6, 0xBE, + 0x32, 0xB3, 0xA6, 0xBE, 0x32, 0x29, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x10, 0xA6, 0xBE, + 0x32, 0x71, 0xA6, 0xBE, 0x32, 0xDA, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xDA, 0xA6, 0xBE, 0x32, 0x72, 0xA6, 0xBE, + 0x32, 0x10, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x21, 0xA6, 0xBE, 0x32, 0x72, 0xA6, 0xBE, 0x32, 0xBF, 0xA6, 0xBE, + 0x32, 0xEB, 0xA6, 0xBE, 0x32, 0xFC, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, + 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFF, 0xA6, 0xBE, 0x32, 0xFC, 0xA6, 0xBE, 0x32, 0xEB, 0xA6, 0xBE, + 0x32, 0xC0, 0xA6, 0xBE, 0x32, 0x73, 0xA6, 0xBE, 0x32, 0x21, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x0C, 0xA6, 0xBE, + 0x32, 0x2D, 0xA6, 0xBE, 0x32, 0x54, 0xA6, 0xBE, 0x32, 0x72, 0xA6, 0xBE, 0x32, 0x81, 0xA6, 0xBE, + 0x32, 0x81, 0xA6, 0xBE, 0x32, 0x72, 0xA6, 0xBE, 0x32, 0x54, 0xA6, 0xBE, 0x32, 0x2E, 0xA6, 0xBE, + 0x32, 0x0C, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBD, 0x31, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, + 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0xA6, 0xBE, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, + 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x00, 0x0F, 0xE0, 0x00, + 0x00, 0x07, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, + 0x00, 0x01, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x07, 0xF0, 0x00, + 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x1F, 0xFE, 0x00, 0x00, 0x7F, 0xFF, 0x80, 0x01, 0xFF +}; + +void *get_refresh_icon_raw_data(int *len) +{ + *len = (int)sizeof(refresh_icon_hexData); + return refresh_icon_hexData; +} + diff --git a/LinuxGUI/Ventoy2Disk/QT/secure_icon_data.c b/LinuxGUI/Ventoy2Disk/QT/secure_icon_data.c new file mode 100644 index 0000000..d72c847 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/QT/secure_icon_data.c @@ -0,0 +1,91 @@ +/****************************************************************************** + * secure_icon_data.c + * + * Copyright (c) 2021, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include +#include + +static unsigned char secure_icon_hexData[958] = { + 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x0D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xA8, 0x03, + 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x03, 0x00, 0x00, 0x46, 0x5C, + 0x00, 0x00, 0x46, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8C, + 0xFB, 0x01, 0x00, 0x8C, 0xFB, 0x2E, 0x00, 0x8C, 0xFB, 0x52, 0x00, 0x8C, 0xFB, 0x53, 0x00, 0x8C, + 0xFB, 0x53, 0x00, 0x8C, 0xFB, 0x53, 0x00, 0x8C, 0xFB, 0x53, 0x00, 0x8C, 0xFB, 0x53, 0x00, 0x8C, + 0xFB, 0x53, 0x00, 0x8C, 0xFB, 0x53, 0x00, 0x8C, 0xFB, 0x52, 0x00, 0x8C, 0xFB, 0x2E, 0x00, 0x8C, + 0xFB, 0x01, 0x00, 0x8C, 0xFB, 0x3E, 0x00, 0x8C, 0xFB, 0xDA, 0x00, 0x8C, 0xFB, 0xF8, 0x00, 0x8C, + 0xFB, 0xF7, 0x00, 0x8C, 0xFB, 0xF7, 0x00, 0x8C, 0xFB, 0xF7, 0x00, 0x8C, 0xFB, 0xF7, 0x00, 0x8C, + 0xFB, 0xF7, 0x00, 0x8C, 0xFB, 0xF7, 0x00, 0x8C, 0xFB, 0xF7, 0x00, 0x8C, 0xFB, 0xF8, 0x00, 0x8C, + 0xFB, 0xDA, 0x00, 0x8C, 0xFB, 0x3E, 0x00, 0x8C, 0xFB, 0x78, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0x78, 0x00, 0x8C, 0xFB, 0x7B, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0x7B, 0x00, 0x8C, + 0xFB, 0x7A, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x86, 0xF1, 0xFF, 0x00, 0x7C, 0xDF, 0xFF, 0x00, 0x86, 0xF1, 0xFF, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, + 0xFB, 0x7A, 0x00, 0x8C, 0xFB, 0x7A, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x8C, 0xFC, 0xFF, 0x00, 0x7C, 0xDF, 0xFF, 0x00, 0x6C, 0xC4, 0xFF, 0x00, 0x7C, + 0xDF, 0xFF, 0x00, 0x8C, 0xFC, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0x7A, 0x00, 0x8C, 0xFB, 0x7A, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x87, 0xF2, 0xFF, 0x00, 0x7D, + 0xE1, 0xFF, 0x00, 0x87, 0xF2, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0x7A, 0x00, 0x8C, 0xFB, 0x7B, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x8C, 0xFC, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0x7B, 0x00, 0x8C, + 0xFB, 0x77, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, + 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, 0xFB, 0xFF, 0x00, 0x8C, + 0xFB, 0x77, 0x00, 0x8C, 0xFB, 0x3A, 0x00, 0x8C, 0xFB, 0xD4, 0x01, 0x8B, 0xF9, 0xF7, 0x03, 0x89, + 0xF3, 0xFF, 0x01, 0x8B, 0xF8, 0xF8, 0x00, 0x8C, 0xFB, 0xF4, 0x00, 0x8C, 0xFB, 0xF4, 0x00, 0x8C, + 0xFB, 0xF4, 0x01, 0x8B, 0xF8, 0xF8, 0x03, 0x89, 0xF3, 0xFF, 0x01, 0x8B, 0xF9, 0xF7, 0x00, 0x8C, + 0xFB, 0xD4, 0x00, 0x8C, 0xFB, 0x3A, 0x00, 0x8C, 0xFB, 0x00, 0x00, 0x93, 0xFF, 0x1E, 0x1D, 0x6B, + 0xA9, 0x6B, 0x32, 0x54, 0x6F, 0xF6, 0x22, 0x65, 0x9A, 0x7D, 0x00, 0x90, 0xFF, 0x39, 0x00, 0x8C, + 0xFB, 0x3C, 0x00, 0x90, 0xFF, 0x39, 0x22, 0x65, 0x9A, 0x7D, 0x32, 0x54, 0x6F, 0xF6, 0x1D, 0x6B, + 0xA9, 0x6B, 0x00, 0x93, 0xFF, 0x1E, 0x00, 0x8C, 0xFB, 0x00, 0x00, 0x8C, 0xFB, 0x00, 0x2A, 0x5D, + 0x85, 0x00, 0x46, 0x3D, 0x36, 0x3A, 0x43, 0x41, 0x3F, 0xF3, 0x45, 0x3F, 0x3A, 0x58, 0x26, 0x62, + 0x91, 0x00, 0x00, 0x8D, 0xFD, 0x00, 0x26, 0x62, 0x91, 0x00, 0x45, 0x3F, 0x3A, 0x58, 0x43, 0x41, + 0x3F, 0xF3, 0x46, 0x3D, 0x36, 0x3A, 0x2A, 0x5D, 0x85, 0x00, 0x00, 0x8C, 0xFB, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x42, 0x42, 0x00, 0x42, 0x42, 0x42, 0x27, 0x42, 0x42, 0x42, 0xE9, 0x42, 0x42, + 0x42, 0x94, 0x42, 0x42, 0x42, 0x01, 0x42, 0x42, 0x42, 0x00, 0x42, 0x42, 0x42, 0x01, 0x42, 0x42, + 0x42, 0x94, 0x42, 0x42, 0x42, 0xE9, 0x42, 0x42, 0x42, 0x27, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x00, 0x42, 0x42, 0x42, 0x04, 0x42, 0x42, + 0x42, 0x96, 0x42, 0x42, 0x42, 0xF5, 0x42, 0x42, 0x42, 0x8E, 0x42, 0x42, 0x42, 0x53, 0x42, 0x42, + 0x42, 0x8E, 0x42, 0x42, 0x42, 0xF5, 0x42, 0x42, 0x42, 0x96, 0x42, 0x42, 0x42, 0x04, 0x42, 0x42, + 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x00, 0x42, 0x42, + 0x42, 0x00, 0x42, 0x42, 0x42, 0x16, 0x42, 0x42, 0x42, 0x96, 0x42, 0x42, 0x42, 0xE9, 0x42, 0x42, + 0x42, 0xF3, 0x42, 0x42, 0x42, 0xE9, 0x42, 0x42, 0x42, 0x96, 0x42, 0x42, 0x42, 0x16, 0x42, 0x42, + 0x42, 0x00, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, + 0x42, 0x00, 0x42, 0x42, 0x42, 0x00, 0x42, 0x42, 0x42, 0x00, 0x42, 0x42, 0x42, 0x05, 0x42, 0x42, + 0x42, 0x31, 0x42, 0x42, 0x42, 0x4B, 0x42, 0x42, 0x42, 0x31, 0x42, 0x42, 0x42, 0x05, 0x42, 0x42, + 0x42, 0x00, 0x42, 0x42, 0x42, 0x00, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, + 0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x80, 0x08, 0x00, 0x00 +}; + +void *get_secure_icon_raw_data(int *len) +{ + *len = (int)sizeof(secure_icon_hexData); + return secure_icon_hexData; +} diff --git a/LinuxGUI/Ventoy2Disk/QT/ventoy2diskwindow.cpp b/LinuxGUI/Ventoy2Disk/QT/ventoy2diskwindow.cpp new file mode 100644 index 0000000..3615e3b --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/QT/ventoy2diskwindow.cpp @@ -0,0 +1,891 @@ +#include "ventoy2diskwindow.h" +#include "ui_ventoy2diskwindow.h" +#include "partcfgdialog.h" + +#include + +extern "C" { +#include "ventoy_define.h" +#include "ventoy_util.h" +#include "ventoy_disk.h" +#include "ventoy_json.h" +#include "ventoy_http.h" +#include "ventoy_qt.h" +} + +MyQThread::MyQThread(QObject *parent) : QThread(parent) +{ + m_index = -1; + m_type = 0; + m_running = false; +} + +void MyQThread::install_run() +{ + int ret = 0; + int pos = 0; + int buflen = 0; + int percent = 0; + char buf[1024]; + char dec[64]; + char out[256]; + char disk_name[32]; + ventoy_disk *cur; + + vlog("install run %d ...\n", m_index); + + cur = g_disk_list + m_index; + snprintf(disk_name, sizeof(disk_name), "%s", cur->disk_name); + snprintf(dec, sizeof(dec), "%llu", (unsigned long long)m_reserve_space); + + buflen = sizeof(buf); + VTOY_JSON_FMT_BEGIN(pos, buf, buflen); + VTOY_JSON_FMT_OBJ_BEGIN(); + VTOY_JSON_FMT_STRN("method", "install"); + VTOY_JSON_FMT_STRN("disk", disk_name); + VTOY_JSON_FMT_STRN("reserve_space", dec); + VTOY_JSON_FMT_UINT("partstyle", ventoy_code_get_cur_part_style()); + VTOY_JSON_FMT_UINT("secure_boot", m_secureboot); + VTOY_JSON_FMT_UINT("align_4kb", m_align4K); + VTOY_JSON_FMT_OBJ_END(); + VTOY_JSON_FMT_END(pos); + + out[0] = 0; + ventoy_func_handler(buf, out, sizeof(out)); + vlog("func handler install <%s>\n", out); + + if (strstr(out, "success")) + { + while (percent != 100) + { + percent = ventoy_code_get_percent(); + emit thread_event(THREAD_MSG_PROGRESS_BAR, percent); + msleep(50); + } + + ret = ventoy_code_get_result(); + ventoy_code_refresh_device(); + cur = NULL; + } + else + { + ret = 1; + } + + emit thread_event(THREAD_MSG_INSTALL_FINISH, ret); + m_running = false; +} + +void MyQThread::update_run() +{ + int ret = 0; + int percent = 0; + char buf[1024]; + char out[256]; + char disk_name[32]; + ventoy_disk *cur; + + vlog("install run %d ...\n", m_index); + + cur = g_disk_list + m_index; + snprintf(disk_name, sizeof(disk_name), "%s", cur->disk_name); + snprintf(buf, sizeof(buf), "{\"method\":\"update\",\"disk\":\"%s\",\"secure_boot\":%d}", disk_name, m_secureboot); + + out[0] = 0; + ventoy_func_handler(buf, out, sizeof(out)); + vlog("func handler update <%s>\n", out); + + if (strstr(out, "success")) + { + while (percent != 100) + { + percent = ventoy_code_get_percent(); + emit thread_event(THREAD_MSG_PROGRESS_BAR, percent); + msleep(50); + } + + ret = ventoy_code_get_result(); + ventoy_code_refresh_device(); + cur = NULL; + } + else + { + ret = 1; + } + + emit thread_event(THREAD_MSG_UPDATE_FINISH, ret); + m_running = false; +} + +void MyQThread::run() +{ + if (THREAD_TYPE_INSTALL == m_type) + { + install_run(); + } + else if (THREAD_TYPE_UPDATE == m_type) + { + update_run(); + } + else + { + + } +} + + +Ventoy2DiskWindow::Ventoy2DiskWindow(QWidget *parent) + : QMainWindow(parent) + , ui(new Ui::Ventoy2DiskWindow) +{ + m_partcfg = new PartCfgDialog(); + m_part_group = new QActionGroup(this); + m_lang_group = new QActionGroup(this); + m_thread = new MyQThread(this); + + ui->setupUi(this); +} + +Ventoy2DiskWindow::~Ventoy2DiskWindow() +{ + delete m_partcfg; + delete m_part_group; + delete m_lang_group; + delete m_thread; + delete ui; +} + +bool LangCompare(const QString &s1, const QString &s2) +{ + if (true == s1.startsWith("Chinese Simplified") && false == s2.startsWith("Chinese Simplified")) + { + return true; + } + else if (false == s1.startsWith("Chinese Simplified") && true == s2.startsWith("Chinese Simplified")) + { + return false; + } + else + { + return s1 < s2; + } +} + +int Ventoy2DiskWindow::lang_string(const QString &id, QString &str) +{ + QString cur = ventoy_code_get_cur_language(); + + for (QJsonArray::iterator p = m_lang_array.begin(); p != m_lang_array.end(); p++) + { + if (p->toObject().value("name") == cur) + { + str = p->toObject().value(id).toString(); + str = str.replace("#@", "\r\n"); + return 0; + } + } + + return 1; +} + +void Ventoy2DiskWindow::update_ui_language() +{ + QString dev; + QJsonObject obj; + QString cur = ventoy_code_get_cur_language(); + + for (QJsonArray::iterator p = m_lang_array.begin(); p != m_lang_array.end(); p++) + { + if (p->toObject().value("name") == cur) + { + obj = p->toObject(); + break; + } + } + + ui->menuOption->setTitle(_LANG_STR("STR_MENU_OPTION")); + ui->actionSecure_Boot_Support->setText(_LANG_STR("STR_MENU_SECURE_BOOT")); + ui->menuPartition_Style->setTitle(_LANG_STR("STR_MENU_PART_STYLE")); + ui->actionPartition_Configuration->setText(_LANG_STR("STR_MENU_PART_CFG")); + ui->actionClear_Ventoy->setText(_LANG_STR("STR_MENU_CLEAR")); + ui->actionShow_All_Devices->setText(_LANG_STR("STR_SHOW_ALL_DEV")); + + dev = _LANG_STR("STR_DEVICE"); + if (m_partcfg->reserve) + { + QString str; + str.sprintf(" [ -%lld%s ]", (long long)m_partcfg->resvalue, m_partcfg->unit ? "GB" : "MB"); + ui->groupBoxDevice->setTitle(dev + str); + } + else + { + ui->groupBoxDevice->setTitle(dev); + } + + ui->groupBoxVentoyLocal->setTitle(_LANG_STR("STR_LOCAL_VER")); + ui->groupBoxVentoyDevice->setTitle(_LANG_STR("STR_DISK_VER")); + ui->groupBoxStatus->setTitle(_LANG_STR("STR_STATUS")); + ui->ButtonInstall->setText(_LANG_STR("STR_INSTALL")); + ui->ButtonUpdate->setText(_LANG_STR("STR_UPDATE")); + m_partcfg->update_language_ui(obj); + m_partcfg->setWindowTitle(_LANG_STR("STR_MENU_PART_CFG")); +} + +void Ventoy2DiskWindow::lang_check_action(QAction *act) +{ + ventoy_code_set_cur_language(act->text().toStdString().c_str()); + update_ui_language(); +} + +void Ventoy2DiskWindow::LoadLanguages() +{ + QString curlang = ventoy_code_get_cur_language(); + if (curlang.isEmpty()) + { + QString LANG = qgetenv("LANG"); + if (LANG.startsWith("zh_CN")) + { + ventoy_code_set_cur_language("Chinese Simplified (简体中文)"); + } + else + { + ventoy_code_set_cur_language("English (English)"); + } + curlang = ventoy_code_get_cur_language(); + } + + + QFile inFile("./tool/languages.json"); + inFile.open(QIODevice::ReadOnly|QIODevice::Text); + QByteArray data = inFile.readAll(); + inFile.close(); + + QJsonParseError errorPtr; + QJsonDocument doc = QJsonDocument::fromJson(data, &errorPtr); + + m_lang_array = doc.array(); + QVector List; + for (QJsonArray::iterator p = m_lang_array.begin(); p != m_lang_array.end(); p++) + { + List.push_back(p->toObject().value("name").toString()); + } + + connect(m_lang_group, SIGNAL(triggered(QAction *)), this, SLOT(lang_check_action(QAction *))); + + std::sort(List.begin(), List.end(), LangCompare); + + for (QVector::iterator p = List.begin(); p != List.end(); p++) + { + QAction *action = new QAction(*p, m_lang_group); + action->setCheckable(true); + + if (p->compare(curlang) == 0) + { + action->setChecked(true); + m_lang_group->triggered(action); + } + + ui->menuLanguage->addAction(action); + } + + +} + +void Ventoy2DiskWindow::part_style_check_action(QAction *action) +{ + int style = 0; + + if (action->text() == "MBR") + { + style = 0; + ui->labelVentoyLocalPartStyle->setText("MBR"); + } + else + { + style = 1; + ui->labelVentoyLocalPartStyle->setText("GPT"); + } + + if (style != ventoy_code_get_cur_part_style()) + { + ventoy_code_set_cur_part_style(style); + } +} + +static ventoy_disk *select_active_dev(const QString &select, int *activeid) +{ + int i; + int alldev = ventoy_code_get_cur_show_all(); + ventoy_disk *cur = NULL; + + /* find the match one */ + if (!select.isEmpty()) + { + for (i = 0; i < g_disk_num; i++) + { + cur = g_disk_list + i; + if (alldev == 0 && cur->type != VTOY_DEVICE_USB) + { + continue; + } + + if (select.compare(cur->disk_name) == 0) + { + *activeid = i; + return cur; + } + } + } + + /* find the first one that installed with Ventoy */ + for (i = 0; i < g_disk_num; i++) + { + cur = g_disk_list + i; + if (alldev == 0 && cur->type != VTOY_DEVICE_USB) + { + continue; + } + + if (cur->vtoydata.ventoy_valid) + { + *activeid = i; + return cur; + } + } + + /* find the first USB interface device */ + for (i = 0; i < g_disk_num; i++) + { + cur = g_disk_list + i; + if (alldev == 0 && cur->type != VTOY_DEVICE_USB) + { + continue; + } + + if (cur->type == VTOY_DEVICE_USB) + { + *activeid = i; + return cur; + } + } + + /* use the first one */ + for (i = 0; i < g_disk_num; i++) + { + cur = g_disk_list + i; + if (alldev == 0 && cur->type != VTOY_DEVICE_USB) + { + continue; + } + + *activeid = i; + return cur; + } + + return NULL; +} + + +void Ventoy2DiskWindow::FillDeviceList(const QString &select) +{ + int active; + int count = 0; + int alldev = ventoy_code_get_cur_show_all(); + ventoy_disk *cur; + + ui->comboBoxDevice->clear(); + + for (int i = 0; i < g_disk_num; i++) + { + cur = g_disk_list + i; + + if (alldev == 0 && cur->type != VTOY_DEVICE_USB) + { + continue; + } + + QString item; + item.sprintf("%s [%s] %s", cur->disk_name, cur->human_readable_size, cur->disk_model); + ui->comboBoxDevice->addItem(item); + count++; + } + + cur = select_active_dev(select, &active); + if (cur) + { + vlog("combox count:%d, active:%s id:%d\n", count, cur->disk_name, active); + ui->ButtonInstall->setEnabled(true); + ui->ButtonUpdate->setEnabled(cur->vtoydata.ventoy_valid); + ui->comboBoxDevice->setCurrentIndex(active); + } + else + { + vlog("combox count:%d, no active id\n", count); + ui->ButtonInstall->setEnabled(false); + ui->ButtonUpdate->setEnabled(false); + } +} + + +void Ventoy2DiskWindow::OnInitWindow(void) +{ + int len; + const uchar *data; + QIcon icon; + QPixmap pix1; + QPixmap pix2; + char ver[512]; + + ui->labelVentoyLocalSecure->hide(); + + m_part_group->addAction(ui->actionMBR); + m_part_group->addAction(ui->actionGPT); + connect(m_part_group, SIGNAL(triggered(QAction *)), this, SLOT(part_style_check_action(QAction *))); + + if (ventoy_code_get_cur_part_style()) + { + ui->actionGPT->setChecked(true); + m_part_group->triggered(ui->actionGPT); + } + else + { + ui->actionMBR->setChecked(true); + m_part_group->triggered(ui->actionMBR); + } + + snprintf(ver, sizeof(ver), VERSION_FMT, ventoy_get_local_version()); + ui->labelVentoyLocalVer->setText(QApplication::translate("Ventoy2DiskWindow", ver, nullptr)); + + LoadLanguages(); + + data = (const uchar *)get_refresh_icon_raw_data(&len); + pix1.loadFromData(data, len); + icon.addPixmap(pix1); + ui->ButtonRefresh->setIcon(icon); + + data = (const uchar *)get_secure_icon_raw_data(&len); + pix2.loadFromData(data, len); + ui->labelVentoyLocalSecure->setPixmap(pix2); + ui->labelVentoyDeviceSecure->setPixmap(pix2); + + ui->labelVentoyDeviceSecure->setHidden(true); + ui->labelVentoyDeviceVer->setText(""); + ui->labelVentoyDevicePartStyle->setText(""); + + ui->actionSecure_Boot_Support->trigger(); + + ui->actionShow_All_Devices->setChecked(ventoy_code_get_cur_show_all()); + + connect(m_thread, &MyQThread::thread_event, this, &Ventoy2DiskWindow::thread_event); + + FillDeviceList(""); +} + +void Ventoy2DiskWindow::showEvent(QShowEvent *ev) +{ + QMainWindow::showEvent(ev); + OnInitWindow(); +} + +void Ventoy2DiskWindow::on_ButtonInstall_clicked() +{ + int index; + quint64 size = 0, space = 0; + ventoy_disk *cur; + QString title_warn, title_err, msg; + + lang_string("STR_ERROR", title_err); + lang_string("STR_WARNING", title_warn); + + if (m_thread->m_running || ventoy_code_is_busy()) + { + lang_string("STR_WAIT_PROCESS", msg); + QMessageBox::warning(NULL, title_warn, msg); + return; + } + + index = ui->comboBoxDevice->currentIndex(); + if (index < 0 || index > g_disk_num) + { + vlog("Invalid combobox current index %d\n", index); + return; + } + + cur = g_disk_list + index; + + if (cur->is4kn) + { + lang_string("STR_4KN_UNSUPPORTED", msg); + QMessageBox::critical(NULL, title_err, msg); + return; + } + + if (ventoy_code_get_cur_part_style() == 0 && cur->size_in_byte > 2199023255552ULL) + { + lang_string("STR_DISK_2TB_MBR_ERROR", msg); + QMessageBox::critical(NULL, title_err, msg); + return; + } + + if (m_partcfg->reserve) + { + size = cur->size_in_byte / SIZE_1MB; + space = m_partcfg->resvalue; + if (m_partcfg->unit == 1) + { + space = m_partcfg->resvalue * 1024; + } + + if (size <= space || (size - space) <= VTOYEFI_PART_BYTES / SIZE_1MB) + { + lang_string("STR_SPACE_VAL_INVALID", msg); + QMessageBox::critical(NULL, title_err, msg); + vlog("reserved space too big.\n"); + return; + } + } + + lang_string("STR_INSTALL_TIP", msg); + if (QMessageBox::Yes != QMessageBox::warning(NULL, title_warn, msg, QMessageBox::Yes | QMessageBox::No, QMessageBox::No)) + { + return; + } + + lang_string("STR_INSTALL_TIP2", msg); + if (QMessageBox::Yes != QMessageBox::warning(NULL, title_warn, msg, QMessageBox::Yes | QMessageBox::No, QMessageBox::No)) + { + return; + } + + ui->ButtonRefresh->setEnabled(false); + ui->ButtonInstall->setEnabled(false); + ui->ButtonRefresh->setEnabled(false); + + m_thread->m_type = THREAD_TYPE_INSTALL; + m_thread->m_index = index; + m_thread->m_reserve_space = space * SIZE_1MB; + m_thread->m_secureboot = ui->actionSecure_Boot_Support->isChecked(); + m_thread->m_align4K = m_partcfg->align; + m_thread->m_running = true; + + m_thread->start(); +} + +void Ventoy2DiskWindow::on_ButtonUpdate_clicked() +{ + int index; + ventoy_disk *cur; + QString title_info, title_warn, title_err, msg; + + lang_string("STR_ERROR", title_err); + lang_string("STR_WARNING", title_warn); + lang_string("STR_INFO", title_info); + + if (m_thread->m_running || ventoy_code_is_busy()) + { + lang_string("STR_WAIT_PROCESS", msg); + QMessageBox::warning(NULL, title_warn, msg); + return; + } + + index = ui->comboBoxDevice->currentIndex(); + if (index < 0 || index > g_disk_num) + { + vlog("Invalid combobox current index %d\n", index); + return; + } + + cur = g_disk_list + index; + if (cur->vtoydata.ventoy_valid == 0) + { + vlog("invalid ventoy version"); + return; + } + + lang_string("STR_UPDATE_TIP", msg); + if (QMessageBox::Yes != QMessageBox::information(NULL, title_info, msg, QMessageBox::Yes | QMessageBox::No, QMessageBox::No)) + { + return; + } + + ui->ButtonRefresh->setEnabled(false); + ui->ButtonInstall->setEnabled(false); + ui->ButtonRefresh->setEnabled(false); + + m_thread->m_type = THREAD_TYPE_UPDATE; + m_thread->m_index = index; + m_thread->m_secureboot = ui->actionSecure_Boot_Support->isChecked(); + + m_thread->m_running = true; + m_thread->start(); +} + +void Ventoy2DiskWindow::on_ButtonRefresh_clicked() +{ + QString title_warn, msg; + + if (m_thread->m_running || ventoy_code_is_busy()) + { + lang_string("STR_WARNING", title_warn); + lang_string("STR_WAIT_PROCESS", msg); + QMessageBox::warning(NULL, title_warn, msg); + return; + } + + ventoy_code_refresh_device(); + FillDeviceList(""); +} + +void Ventoy2DiskWindow::on_comboBoxDevice_currentIndexChanged(int index) +{ + char ver[512]; + ventoy_disk *cur; + + ui->labelVentoyDeviceSecure->setHidden(true); + ui->labelVentoyDeviceVer->setText(""); + ui->labelVentoyDevicePartStyle->setText(""); + + if (index < 0 || index > g_disk_num) + { + vlog("invalid combobox index %d\n", index); + return; + } + + cur = g_disk_list + index; + if (cur->vtoydata.ventoy_valid) + { + if (cur->vtoydata.secure_boot_flag) + { + ui->labelVentoyDeviceSecure->setHidden(false); + } + else + { + ui->labelVentoyDeviceSecure->setHidden(true); + } + + if ((int)(ui->actionSecure_Boot_Support->isChecked()) != cur->vtoydata.secure_boot_flag) + { + ui->actionSecure_Boot_Support->trigger(); + } + + snprintf(ver, sizeof(ver), VERSION_FMT, cur->vtoydata.ventoy_ver); + ui->labelVentoyDeviceVer->setText(QApplication::translate("Ventoy2DiskWindow", ver, nullptr)); + ui->labelVentoyDevicePartStyle->setText(cur->vtoydata.partition_style ? "GPT" : "MBR"); + } + else + { + if (!(ui->actionSecure_Boot_Support->isChecked())) + { + ui->actionSecure_Boot_Support->trigger(); + } + } +} + +void Ventoy2DiskWindow::on_actionPartition_Configuration_triggered() +{ + m_partcfg->update_ui_status(); + if (QDialog::Accepted == m_partcfg->exec()) + { + QString str; + QString dev; + lang_string("STR_DEVICE", dev); + + if (m_partcfg->reserve) + { + str.sprintf(" [ -%lld%s ]", (long long)m_partcfg->resvalue, m_partcfg->unit ? "GB" : "MB"); + ui->groupBoxDevice->setTitle(dev + str); + } + else + { + ui->groupBoxDevice->setTitle(dev); + } + } +} + +void Ventoy2DiskWindow::on_actionClear_Ventoy_triggered() +{ + int ret; + int index; + ventoy_disk *cur; + QString title_err, title_warn, title_info, msg; + char disk_name[64]; + char buf[256]; + char out[256]; + + lang_string("STR_ERROR", title_err); + lang_string("STR_WARNING", title_warn); + lang_string("STR_INFO", title_info); + + if (m_thread->m_running || ventoy_code_is_busy()) + { + lang_string("STR_WAIT_PROCESS", msg); + QMessageBox::warning(NULL, title_warn, msg); + return; + } + + index = ui->comboBoxDevice->currentIndex(); + if (index < 0 || index > g_disk_num) + { + vlog("Invalid combobox current index %d\n", index); + return; + } + + cur = g_disk_list + index; + + lang_string("STR_INSTALL_TIP", msg); + if (QMessageBox::Yes != QMessageBox::warning(NULL, title_warn, msg, QMessageBox::Yes | QMessageBox::No, QMessageBox::No)) + { + return; + } + + lang_string("STR_INSTALL_TIP2", msg); + if (QMessageBox::Yes != QMessageBox::warning(NULL, title_warn, msg, QMessageBox::Yes | QMessageBox::No, QMessageBox::No)) + { + return; + } + + snprintf(disk_name, sizeof(disk_name), "%s", cur->disk_name); + snprintf(buf, sizeof(buf), "{\"method\":\"clean\",\"disk\":\"%s\"}", disk_name); + + out[0] = 0; + ventoy_func_handler(buf, out, sizeof(out)); + vlog("func handler clean <%s>\n", out); + + if (strstr(out, "success")) + { + ret = ventoy_code_get_result(); + ventoy_code_refresh_device(); + cur = NULL; + } + else + { + ret = 1; + } + + if (ret == 0) + { + lang_string("STR_CLEAR_SUCCESS", msg); + QMessageBox::information(NULL, title_info, msg); + } + else + { + lang_string("STR_CLEAR_FAILED", msg); + QMessageBox::critical(NULL, title_err, msg); + } + + FillDeviceList(disk_name); +} + +void Ventoy2DiskWindow::on_actionShow_All_Devices_toggled(bool arg1) +{ + ventoy_code_set_cur_show_all(arg1); + FillDeviceList(""); +} + + +void Ventoy2DiskWindow::closeEvent(QCloseEvent *event) +{ + vlog("On closeEvent ...\n"); + + if (m_thread->m_running) + { + QString title; + QString msg; + + lang_string("STR_WARNING", title); + lang_string("STR_WAIT_PROCESS", msg); + QMessageBox::warning(NULL, title, msg); + + event->ignore(); + return; + } + + ventoy_code_save_cfg(); + + event->accept(); +} + +void Ventoy2DiskWindow::on_actionSecure_Boot_Support_triggered() +{ + ui->labelVentoyLocalSecure->setHidden(!(ui->actionSecure_Boot_Support->isChecked())); +} + +void Ventoy2DiskWindow::set_percent(int percent) +{ + int index; + QString status, radio; + + ui->progressBar->setValue(percent); + + lang_string("STR_STATUS", status); + + if (percent == 0) + { + ui->groupBoxStatus->setTitle(status); + } + else + { + index = status.indexOf("-"); + radio.sprintf("%d%%", percent); + ui->groupBoxStatus->setTitle(status.left(index + 2) + radio); + } +} + +void Ventoy2DiskWindow::thread_event(int msg, int data) +{ + char disk_name[32]; + QString title_err, title_info, tipmsg; + + if (msg == THREAD_MSG_PROGRESS_BAR) + { + set_percent(data); + } + else if (msg == THREAD_MSG_INSTALL_FINISH) + { + lang_string("STR_ERROR", title_err); + lang_string("STR_INFO", title_info); + + if (data == 0) + { + lang_string("STR_INSTALL_SUCCESS", tipmsg); + QMessageBox::information(NULL, title_info, tipmsg); + } + else + { + lang_string("STR_INSTALL_FAILED", tipmsg); + QMessageBox::critical(NULL, title_err, tipmsg); + } + + set_percent(0); + ui->ButtonRefresh->setEnabled(true); + ui->ButtonInstall->setEnabled(true); + ui->ButtonRefresh->setEnabled(true); + + snprintf(disk_name, sizeof(disk_name), "%s", g_disk_list[m_thread->m_index].disk_name); + FillDeviceList(disk_name); + } + else if (msg == THREAD_MSG_UPDATE_FINISH) + { + lang_string("STR_ERROR", title_err); + lang_string("STR_INFO", title_info); + + if (data == 0) + { + lang_string("STR_UPDATE_SUCCESS", tipmsg); + QMessageBox::information(NULL, title_info, tipmsg); + } + else + { + lang_string("STR_UPDATE_FAILED", tipmsg); + QMessageBox::critical(NULL, title_err, tipmsg); + } + + set_percent(0); + ui->ButtonRefresh->setEnabled(true); + ui->ButtonInstall->setEnabled(true); + ui->ButtonRefresh->setEnabled(true); + + snprintf(disk_name, sizeof(disk_name), "%s", g_disk_list[m_thread->m_index].disk_name); + FillDeviceList(disk_name); + } +} diff --git a/LinuxGUI/Ventoy2Disk/QT/ventoy2diskwindow.h b/LinuxGUI/Ventoy2Disk/QT/ventoy2diskwindow.h new file mode 100644 index 0000000..4a3be00 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/QT/ventoy2diskwindow.h @@ -0,0 +1,105 @@ +#ifndef VENTOY2DISKWINDOW_H +#define VENTOY2DISKWINDOW_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "partcfgdialog.h" + +QT_BEGIN_NAMESPACE +namespace Ui { class Ventoy2DiskWindow; } +QT_END_NAMESPACE + +#define THREAD_TYPE_INSTALL 1 +#define THREAD_TYPE_UPDATE 2 + +#define THREAD_MSG_PROGRESS_BAR 1 +#define THREAD_MSG_INSTALL_FINISH 2 +#define THREAD_MSG_UPDATE_FINISH 3 + +class MyQThread : public QThread +{ + Q_OBJECT +public: + quint64 m_reserve_space; + int m_index; + int m_type; + int m_secureboot; + int m_align4K; + bool m_running; + void install_run(); + void update_run(); + + explicit MyQThread(QObject *parent = nullptr); +protected: + void run(); +signals: + void thread_event(int msg, int data); +public slots: +}; + + +class Ventoy2DiskWindow : public QMainWindow +{ + Q_OBJECT + +public: + Ventoy2DiskWindow(QWidget *parent = nullptr); + ~Ventoy2DiskWindow(); + + QActionGroup *m_part_group; + QActionGroup *m_lang_group; + QJsonArray m_lang_array; + PartCfgDialog *m_partcfg; + MyQThread *m_thread; + + void FillDeviceList(const QString &select); + void OnInitWindow(void); + void LoadLanguages(); + int lang_string(const QString &id, QString &str); + void update_ui_language(); + void set_percent(int percent); +protected: + void showEvent(QShowEvent *ev); + void closeEvent(QCloseEvent *event); + +private slots: + + void thread_event(int msg, int data); + void part_style_check_action(QAction *act); + void lang_check_action(QAction *act); + + void on_ButtonInstall_clicked(); + + void on_ButtonUpdate_clicked(); + + void on_ButtonRefresh_clicked(); + + void on_comboBoxDevice_currentIndexChanged(int index); + + void on_actionPartition_Configuration_triggered(); + + void on_actionClear_Ventoy_triggered(); + + void on_actionShow_All_Devices_toggled(bool arg1); + + void on_actionSecure_Boot_Support_triggered(); + +private: + Ui::Ventoy2DiskWindow *ui; + + +}; + +#define _LANG_STR(id) obj.value(id).toString() +#define VERSION_FMT "

%s

" + +#endif // VENTOY2DISKWINDOW_H diff --git a/LinuxGUI/Ventoy2Disk/QT/ventoy2diskwindow.ui b/LinuxGUI/Ventoy2Disk/QT/ventoy2diskwindow.ui new file mode 100644 index 0000000..bb6da84 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/QT/ventoy2diskwindow.ui @@ -0,0 +1,323 @@ + + + Ventoy2DiskWindow + + + + 0 + 0 + 441 + 367 + + + + Ventoy2Disk + + + + + + 10 + 10 + 421 + 80 + + + + Device + + + + + 10 + 40 + 361 + 26 + + + + + + + 380 + 37 + 30 + 30 + + + + + + + + ../refresh.ico../refresh.ico + + + + 24 + 24 + + + + + + + + 10 + 100 + 205 + 80 + + + + Ventoy In Package + + + Qt::AlignCenter + + + + + 30 + 30 + 135 + 41 + + + + <html><head/><body><p><span style=" font-size:20pt; font-weight:600; color:#ff0000;">1.0.53</span></p></body></html> + + + Qt::AlignCenter + + + + + + 172 + 60 + 31 + 18 + + + + <html><head/><body><p>MBR</p></body></html> + + + + + + 12 + 36 + 21 + 31 + + + + + + + ../secure.ico + + + + + + + 225 + 100 + 205 + 80 + + + + Ventoy In Device + + + Qt::AlignCenter + + + + + 30 + 30 + 135 + 41 + + + + <html><head/><body><p><span style=" font-size:20pt; font-weight:600; color:#ff0000;">1.0.52</span></p></body></html> + + + Qt::AlignCenter + + + + + + 172 + 60 + 31 + 18 + + + + <html><head/><body><p>GPT</p></body></html> + + + + + + 12 + 36 + 21 + 31 + + + + + + + ../secure.ico + + + + + + + 10 + 190 + 421 + 61 + + + + Status: REDAY + + + + + 10 + 30 + 401 + 23 + + + + 0 + + + false + + + + + + + + + + 90 + 275 + 101 + 41 + + + + Install + + + + + + 250 + 275 + 101 + 41 + + + + Update + + + + + + + 0 + 0 + 441 + 23 + + + + + Option + + + + Partition Style + + + + + + + + + + + + + Language + + + + + + + + true + + + Secure Boot Support + + + + + true + + + MBR + + + + + true + + + GPT + + + + + Partition Configuration + + + + + Clear Ventoy + + + + + true + + + Show All Devices + + + + + + diff --git a/LinuxGUI/Ventoy2Disk/QT/ventoy_qt.h b/LinuxGUI/Ventoy2Disk/QT/ventoy_qt.h new file mode 100644 index 0000000..6179d8b --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/QT/ventoy_qt.h @@ -0,0 +1,47 @@ +/****************************************************************************** + * ventoy_qt.h + * + * Copyright (c) 2021, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ +#ifndef __VENTOY_QT_H__ +#define __VENTOY_QT_H__ + +int ventoy_disk_init(void); +void ventoy_disk_exit(void); +int ventoy_http_init(void); +void ventoy_http_exit(void); +int ventoy_log_init(void); +void ventoy_log_exit(void); +void *get_refresh_icon_raw_data(int *len); +void *get_secure_icon_raw_data(int *len); +void *get_window_icon_raw_data(int *len); +int ventoy_func_handler(const char *jsonstr, char *jsonbuf, int buflen); +const char * ventoy_code_get_cur_language(void); +int ventoy_code_get_cur_part_style(void); +void ventoy_code_set_cur_part_style(int style); +int ventoy_code_get_cur_show_all(void); +void ventoy_code_set_cur_show_all(int show_all); +void ventoy_code_set_cur_language(const char *lang); +void ventoy_code_save_cfg(void); +void ventoy_code_refresh_device(void); +int ventoy_code_is_busy(void); +int ventoy_code_get_percent(void); +int ventoy_code_get_result(void); + +#endif /* __VENTOY_QT_H__ */ + + diff --git a/LinuxGUI/Ventoy2Disk/QT/ventoy_qt_stub.c b/LinuxGUI/Ventoy2Disk/QT/ventoy_qt_stub.c new file mode 100644 index 0000000..cee209d --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/QT/ventoy_qt_stub.c @@ -0,0 +1,600 @@ +/****************************************************************************** + * ventoy_qt_stub.c + * + * Copyright (c) 2021, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +struct mg_context * +mg_start(const struct mg_callbacks *callbacks, + void *user_data, + const char **options) +{ + (void)callbacks; + (void)user_data; + (void)options; + + return NULL; +} + +void mg_stop(struct mg_context *ctx) +{ + (void)ctx; +} + +int mg_read(struct mg_connection *conn, void *buf, size_t len) +{ + (void)conn; + (void)buf; + (void)len; + return 0; +} + + +const struct mg_request_info * mg_get_request_info(const struct mg_connection *conn) +{ + (void)conn; + return NULL; +} + +int mg_start_thread(mg_thread_func_t func, void *param) +{ + pthread_t thread_id; + pthread_attr_t attr; + int result; + + (void)pthread_attr_init(&attr); + (void)pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + +#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) + /* Compile-time option to control stack size, + * e.g. -DUSE_STACK_SIZE=16384 */ + (void)pthread_attr_setstacksize(&attr, USE_STACK_SIZE); +#endif /* defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) */ + + result = pthread_create(&thread_id, &attr, func, param); + pthread_attr_destroy(&attr); + + return result; +} + +int mg_printf(struct mg_connection *conn, const char *fmt, ...) +{ + (void)conn; + (void)fmt; + + return 0; +} + +static unsigned char window_icon_hexData[] = { + 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0xAA, 0x69, 0x71, + 0xDE, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4D, 0x41, 0x00, 0x00, 0xAF, 0xC8, 0x37, 0x05, 0x8A, + 0xE9, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4D, 0x00, 0x00, 0x7A, 0x26, 0x00, 0x00, 0x80, + 0x84, 0x00, 0x00, 0xFA, 0x00, 0x00, 0x00, 0x80, 0xE8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xEA, + 0x60, 0x00, 0x00, 0x3A, 0x98, 0x00, 0x00, 0x17, 0x70, 0x9C, 0xBA, 0x51, 0x3C, 0x00, 0x00, 0x00, + 0x06, 0x62, 0x4B, 0x47, 0x44, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xA0, 0xBD, 0xA7, 0x93, 0x00, + 0x00, 0x00, 0x07, 0x74, 0x49, 0x4D, 0x45, 0x07, 0xE4, 0x03, 0x17, 0x04, 0x10, 0x05, 0xF6, 0xCE, + 0xA8, 0xC0, 0x00, 0x00, 0x1C, 0x68, 0x49, 0x44, 0x41, 0x54, 0x78, 0xDA, 0xCD, 0x9B, 0x79, 0x94, + 0x1D, 0x57, 0x7D, 0xE7, 0x3F, 0xF7, 0xDE, 0xAA, 0x7A, 0xFB, 0xEB, 0xD7, 0xBB, 0xA4, 0x56, 0xCB, + 0xDA, 0x6C, 0x59, 0xB6, 0x64, 0x83, 0x91, 0x17, 0xBC, 0xE1, 0x0D, 0x2F, 0x04, 0x1B, 0xB0, 0x43, + 0x3C, 0x40, 0x32, 0x43, 0x4E, 0x38, 0x19, 0x87, 0x43, 0x26, 0x03, 0x84, 0x98, 0xC9, 0x1C, 0x98, + 0x93, 0x70, 0x48, 0x72, 0x66, 0x58, 0x86, 0x81, 0x10, 0x0E, 0x06, 0xC6, 0x21, 0xC1, 0x83, 0xC1, + 0x36, 0x18, 0xDB, 0x6C, 0xC6, 0x60, 0xB0, 0x65, 0xBC, 0x1B, 0x5B, 0x8B, 0x6D, 0x59, 0x92, 0xB5, + 0x75, 0x5B, 0x52, 0xAB, 0xD7, 0xB7, 0x56, 0xD5, 0x5D, 0xE6, 0x8F, 0xAA, 0xF7, 0xF4, 0xBA, 0xD5, + 0xF2, 0xC2, 0x92, 0x99, 0x3A, 0xE7, 0xD7, 0xF5, 0x96, 0x7A, 0x75, 0x7F, 0xDF, 0xEF, 0x6F, 0xB9, + 0xBF, 0xFB, 0xBB, 0xD5, 0x82, 0xDF, 0xD1, 0x61, 0x8C, 0x45, 0x7D, 0x70, 0x9A, 0xFD, 0x7F, 0x57, + 0x61, 0x57, 0xD5, 0x31, 0x17, 0x39, 0x9C, 0x83, 0xD8, 0xC1, 0xEF, 0xAF, 0x1A, 0xE6, 0xC9, 0x23, + 0x13, 0x41, 0x55, 0xA3, 0xB4, 0x75, 0xD2, 0x93, 0xB8, 0xBC, 0x27, 0xCC, 0xA6, 0x7E, 0x19, 0xDD, + 0xBA, 0x5B, 0xBB, 0xBC, 0x07, 0x02, 0x28, 0x78, 0x82, 0xD1, 0xA2, 0x60, 0x6D, 0x59, 0x52, 0x8F, + 0x1D, 0xC5, 0x40, 0xFE, 0xD6, 0xF5, 0x14, 0xBF, 0xED, 0x1B, 0x3E, 0xBC, 0x67, 0x92, 0x3C, 0x9A, + 0x03, 0xAE, 0x44, 0x84, 0xC7, 0xDB, 0x56, 0xFA, 0x3C, 0x3A, 0x61, 0x7A, 0x26, 0x43, 0x96, 0x59, + 0xEB, 0xD6, 0x6A, 0xC7, 0x09, 0x16, 0x46, 0x05, 0xF4, 0x03, 0x79, 0x01, 0xBE, 0x03, 0x03, 0x34, + 0x81, 0x19, 0x21, 0x18, 0xF3, 0x05, 0x7B, 0x95, 0x10, 0xBB, 0x8A, 0x3E, 0xFB, 0xCE, 0x1B, 0x56, + 0xD3, 0x77, 0xEC, 0x89, 0x4D, 0x5E, 0x5A, 0xFA, 0x5C, 0x9D, 0x59, 0xF2, 0xAC, 0x72, 0x87, 0x39, + 0x71, 0xD5, 0x09, 0xFF, 0x7F, 0x11, 0xF0, 0xD3, 0x17, 0x67, 0xC9, 0xA1, 0x99, 0xB0, 0x39, 0xBE, + 0x19, 0xE6, 0x78, 0x5F, 0xA1, 0xD1, 0x17, 0x4B, 0xFF, 0x8C, 0x96, 0x11, 0x17, 0x59, 0xC7, 0xD9, + 0xC6, 0xB1, 0xCE, 0x41, 0x9F, 0x14, 0xE4, 0x3C, 0x89, 0x54, 0x02, 0x94, 0x48, 0x14, 0x70, 0x80, + 0x75, 0x60, 0x8E, 0x4A, 0x53, 0xC0, 0x9C, 0x27, 0xD8, 0x2D, 0x04, 0x8F, 0x67, 0x24, 0xF7, 0x07, + 0xE8, 0x47, 0x2E, 0x52, 0xDF, 0x19, 0xBF, 0x3B, 0xBC, 0xD6, 0x55, 0x44, 0xC8, 0x6E, 0xBF, 0xCC, + 0x99, 0xCD, 0x3D, 0x9C, 0xB2, 0x76, 0xD5, 0xFF, 0x5B, 0x02, 0x7E, 0xBE, 0x6B, 0x92, 0x3E, 0xD1, + 0x64, 0x8F, 0xA9, 0x70, 0xF5, 0x89, 0x05, 0xBE, 0xBF, 0xBB, 0xB1, 0xAA, 0xE5, 0xD4, 0xD5, 0x06, + 0xF1, 0x76, 0xE3, 0xC4, 0xEB, 0x8D, 0xA3, 0x22, 0x05, 0xE4, 0x3C, 0x41, 0xD1, 0x83, 0xAC, 0x27, + 0x08, 0x24, 0xC8, 0x14, 0x7C, 0x9B, 0x80, 0x36, 0x09, 0xDA, 0x41, 0x4B, 0x3B, 0xEA, 0x1A, 0x1A, + 0xDA, 0x61, 0x1C, 0x28, 0x41, 0xC3, 0x13, 0xEE, 0x79, 0x0F, 0xEE, 0xC9, 0x48, 0x73, 0xC7, 0x3A, + 0x6F, 0x66, 0xCB, 0x56, 0x3D, 0xA0, 0x4F, 0xC8, 0x69, 0xE6, 0xB4, 0xE4, 0xFC, 0x91, 0xEC, 0xBF, + 0x3D, 0x01, 0x8F, 0xFE, 0x6A, 0x2B, 0xBB, 0x4B, 0xEB, 0xA9, 0x98, 0x39, 0x76, 0xDB, 0x0A, 0xAB, + 0xBC, 0xEA, 0xB2, 0x3A, 0xFE, 0xBB, 0x0D, 0xF2, 0xDF, 0x6B, 0xCB, 0x29, 0x91, 0x75, 0x4A, 0x20, + 0xA8, 0x64, 0x04, 0xBD, 0x19, 0x41, 0xCE, 0x13, 0x2C, 0x16, 0xC1, 0xEE, 0x38, 0x8A, 0x38, 0x20, + 0x34, 0x30, 0x1B, 0x39, 0xA6, 0x42, 0x8B, 0x76, 0x90, 0x91, 0x10, 0x48, 0xF6, 0x79, 0xC2, 0xDD, + 0x9E, 0xF7, 0xF8, 0xCA, 0xE5, 0x37, 0xFB, 0xDB, 0xEF, 0x7B, 0x6F, 0xCC, 0x25, 0xA3, 0x9A, 0xA7, + 0x0E, 0x29, 0xCE, 0x58, 0x92, 0xFB, 0xB7, 0x21, 0xE0, 0x91, 0xFD, 0x73, 0x9C, 0x55, 0xAE, 0xF2, + 0x9D, 0xC3, 0x15, 0x86, 0x5D, 0x35, 0xFB, 0x12, 0xA5, 0xAB, 0x62, 0x27, 0x3F, 0xA8, 0x11, 0xE7, + 0xB6, 0x0C, 0x2A, 0x32, 0x8E, 0x9E, 0x40, 0xB0, 0xAC, 0xA0, 0x28, 0x78, 0xA2, 0x33, 0x8A, 0x7B, + 0x8D, 0xE3, 0xB4, 0x95, 0x0B, 0x8D, 0xE3, 0x50, 0xD3, 0x72, 0xA4, 0x65, 0x51, 0x42, 0x50, 0xF0, + 0xC0, 0x97, 0xE2, 0xD9, 0x8C, 0x74, 0xFF, 0x34, 0x98, 0x71, 0xDF, 0xD8, 0xDF, 0x10, 0x53, 0xEB, + 0x8A, 0x9A, 0x99, 0x58, 0x72, 0xD1, 0x8A, 0xFC, 0xEF, 0x96, 0x80, 0x7B, 0x76, 0xD6, 0xE9, 0x0F, + 0x0C, 0x4F, 0xCD, 0x78, 0xAC, 0xC8, 0x9B, 0xD1, 0xAA, 0x96, 0x1F, 0x8E, 0x91, 0xEF, 0x6D, 0x69, + 0xD7, 0x53, 0xD7, 0x09, 0xC4, 0xD1, 0xA2, 0x62, 0x28, 0x2F, 0x51, 0x42, 0xBC, 0x66, 0xD0, 0xC7, + 0x3F, 0x1C, 0xD3, 0xA1, 0x63, 0x6F, 0xD5, 0x10, 0x19, 0x47, 0xD1, 0x97, 0xE4, 0x7D, 0x11, 0x65, + 0x25, 0xDF, 0xCF, 0x7A, 0x7C, 0xE2, 0xA1, 0xC9, 0xE0, 0xC9, 0x2B, 0x07, 0x1A, 0xB4, 0x2C, 0xBC, + 0x79, 0x55, 0xF1, 0x77, 0x43, 0xC0, 0x3D, 0xCF, 0xCF, 0x90, 0x55, 0xF0, 0xAB, 0x39, 0x9F, 0x35, + 0x25, 0x77, 0x66, 0x4D, 0x8B, 0x7F, 0x88, 0x0C, 0x17, 0xD7, 0x62, 0x27, 0x1A, 0xDA, 0xE1, 0x2B, + 0xC1, 0xEA, 0x1E, 0x45, 0x7F, 0x4E, 0x26, 0xC0, 0x7F, 0x7B, 0xE8, 0x13, 0x65, 0x05, 0xD4, 0x63, + 0xC7, 0xAE, 0x19, 0x43, 0x2D, 0x76, 0xE4, 0x3D, 0x41, 0x29, 0x10, 0xE4, 0x3D, 0xB1, 0xBD, 0xA0, + 0xDC, 0xC7, 0x2E, 0xAC, 0x34, 0xEE, 0x7C, 0x6A, 0xCE, 0x37, 0xA1, 0x15, 0x5C, 0xBE, 0xA6, 0xFC, + 0xDB, 0x25, 0xE0, 0x7B, 0xCF, 0xCD, 0x90, 0x53, 0x8E, 0xB7, 0x6C, 0xAF, 0xF0, 0x8D, 0x75, 0xF5, + 0x37, 0x37, 0x0D, 0x9F, 0x69, 0x6A, 0xB7, 0xA1, 0x1A, 0x39, 0x5A, 0xC6, 0xE1, 0x29, 0xC1, 0x89, + 0x15, 0x8F, 0xFE, 0x9C, 0xE4, 0x77, 0x80, 0xBD, 0x73, 0x48, 0xA0, 0x16, 0x3B, 0x76, 0x4C, 0x6B, + 0xEA, 0xDA, 0x91, 0x51, 0x82, 0x1E, 0x5F, 0x52, 0x0A, 0xC4, 0xE1, 0x82, 0xE7, 0xFE, 0xE6, 0x94, + 0x5C, 0xFD, 0xA6, 0xFD, 0x61, 0x10, 0x87, 0x16, 0xAE, 0x5A, 0x5B, 0xF9, 0xED, 0x10, 0x70, 0xCF, + 0x73, 0x53, 0x64, 0x14, 0xFC, 0x7C, 0xAA, 0xC0, 0x86, 0x52, 0x78, 0x45, 0xC3, 0x88, 0x2F, 0xD4, + 0x22, 0xB7, 0x76, 0x2E, 0xB2, 0xC4, 0xD6, 0x81, 0x10, 0xAC, 0x2C, 0x7B, 0x8C, 0x94, 0xD4, 0xEF, + 0x08, 0xF6, 0x02, 0xA5, 0x05, 0x4C, 0xB5, 0x2C, 0x3B, 0xA6, 0x35, 0xDA, 0x3A, 0x7C, 0x29, 0x28, + 0x07, 0x92, 0xDE, 0xAC, 0x9C, 0x2B, 0x2A, 0xF7, 0xF1, 0x8D, 0xF9, 0xD9, 0x7F, 0xDC, 0xD3, 0xCA, + 0xE9, 0xD8, 0x49, 0xAE, 0x3C, 0xF1, 0xE5, 0x49, 0x78, 0x45, 0x02, 0x7E, 0xB6, 0x65, 0x0F, 0x85, + 0x5C, 0x86, 0x87, 0x66, 0x0A, 0x0C, 0xE7, 0x38, 0xAF, 0x1E, 0xBB, 0x9B, 0x6A, 0x91, 0x5D, 0x3F, + 0x1B, 0x3A, 0x62, 0xE7, 0x70, 0x40, 0x5F, 0xCE, 0x63, 0x5D, 0x9F, 0x8F, 0xFA, 0xED, 0x17, 0x6A, + 0xC7, 0x1C, 0xCE, 0xB9, 0x8E, 0xD2, 0x7B, 0xAB, 0x86, 0x03, 0x55, 0x8D, 0x00, 0x3C, 0x29, 0xE8, + 0xC9, 0x48, 0xFA, 0xB2, 0x72, 0xAA, 0xE8, 0xF1, 0x97, 0xEF, 0x28, 0xEF, 0xBB, 0xF9, 0xFE, 0xFA, + 0x52, 0x67, 0x10, 0x5C, 0xB6, 0xB6, 0xF7, 0xD7, 0x27, 0xC0, 0x39, 0xF8, 0xCA, 0xD3, 0x73, 0xF4, + 0xA8, 0xE8, 0xD4, 0xD9, 0xD8, 0xBB, 0xB9, 0x1A, 0xD9, 0x4D, 0x33, 0x2D, 0x43, 0xEC, 0x12, 0x37, + 0xF7, 0x94, 0xE0, 0xA4, 0xBE, 0x80, 0xBE, 0xAC, 0x24, 0x75, 0x86, 0xDF, 0x00, 0xDD, 0x02, 0x8D, + 0x1C, 0xB8, 0xF6, 0x24, 0xE2, 0xC0, 0x5A, 0x43, 0xD6, 0x4B, 0x94, 0x0A, 0x2D, 0x84, 0x56, 0xF2, + 0xEC, 0x64, 0x4C, 0x33, 0x76, 0x08, 0x01, 0x9E, 0x84, 0xDE, 0xAC, 0xA2, 0x3F, 0xA7, 0xC6, 0xCB, + 0x9E, 0xFD, 0x8F, 0x7B, 0x9B, 0xFE, 0xDD, 0x67, 0x97, 0xE6, 0x88, 0x1B, 0x35, 0x2E, 0x38, 0xED, + 0xC4, 0xD7, 0x4E, 0xC0, 0x37, 0x9F, 0x3C, 0x08, 0x52, 0x92, 0x51, 0xF4, 0x1F, 0x89, 0xBC, 0x2F, + 0x57, 0x43, 0x7B, 0xED, 0x54, 0xD3, 0x10, 0xA6, 0x48, 0x9D, 0x80, 0xBE, 0xAC, 0xE2, 0xA4, 0xBE, + 0x00, 0x29, 0x39, 0xFE, 0xA4, 0xFE, 0x5A, 0x80, 0x2F, 0x76, 0x0F, 0x07, 0xD6, 0x6A, 0x7A, 0x02, + 0x38, 0x7D, 0xB8, 0x40, 0x64, 0x0C, 0x4F, 0xBD, 0x54, 0x25, 0x72, 0x1E, 0xFB, 0xEB, 0x30, 0x56, + 0x35, 0x9D, 0xCB, 0x7D, 0x29, 0x18, 0xC8, 0x4B, 0x06, 0x72, 0xEA, 0xE9, 0x5E, 0xCF, 0xFC, 0x61, + 0x9D, 0xCC, 0xD6, 0xEB, 0x4F, 0x2E, 0x1C, 0xD7, 0x32, 0xC7, 0x55, 0xF5, 0xAE, 0x87, 0xB6, 0x60, + 0x72, 0x15, 0xCE, 0x29, 0x4F, 0xC9, 0x7B, 0xA6, 0x47, 0x6E, 0x9C, 0x0D, 0xED, 0xDF, 0x4E, 0x36, + 0xB4, 0xD7, 0xD0, 0xC9, 0xAF, 0x84, 0x4C, 0x7E, 0xBA, 0xB2, 0x12, 0xB0, 0xA4, 0xE8, 0xFD, 0x06, + 0x66, 0xEF, 0xC2, 0xED, 0x1C, 0xCE, 0x5A, 0x04, 0x0E, 0x87, 0x40, 0xC8, 0x34, 0xA1, 0x9A, 0x98, + 0xC1, 0xBC, 0xE4, 0x75, 0x4B, 0x0B, 0xE4, 0x14, 0x78, 0x4A, 0xB1, 0x7F, 0xA6, 0xC9, 0xD3, 0x2F, + 0x55, 0x99, 0x8C, 0x3C, 0x76, 0xCC, 0x58, 0x8C, 0x13, 0x1D, 0x40, 0x19, 0x4F, 0xB0, 0xA4, 0xE0, + 0x31, 0x90, 0x93, 0xB7, 0x0C, 0xFB, 0xD1, 0x0D, 0x4D, 0x2B, 0xAB, 0x9E, 0x89, 0xB8, 0x72, 0xE3, + 0xC8, 0x31, 0xE3, 0x1E, 0x37, 0x6A, 0xDF, 0xAA, 0x7F, 0xCA, 0x78, 0x5C, 0xE0, 0x47, 0x53, 0x43, + 0x6F, 0xAC, 0x85, 0xF6, 0xFD, 0xD3, 0xF5, 0xD8, 0xAB, 0xB6, 0x34, 0xDA, 0x18, 0x8C, 0xB5, 0x68, + 0x63, 0xC1, 0x39, 0x32, 0x0A, 0xB4, 0x71, 0xC4, 0xDA, 0xFE, 0x46, 0x12, 0x45, 0x31, 0x26, 0x0E, + 0x59, 0x5E, 0x70, 0x9C, 0x36, 0xE8, 0x51, 0x10, 0x21, 0xAD, 0x56, 0x83, 0x28, 0x6C, 0xB2, 0xB4, + 0x20, 0xD8, 0xB4, 0xAC, 0x40, 0xC9, 0x97, 0x6C, 0xDD, 0x77, 0x80, 0x7D, 0x13, 0x47, 0x58, 0x51, + 0xC9, 0xB1, 0x7E, 0x30, 0x4F, 0xC6, 0x85, 0x48, 0x13, 0xA1, 0xB5, 0xC6, 0x18, 0x83, 0x36, 0x86, + 0x46, 0xA8, 0x99, 0xA8, 0x45, 0xCC, 0xB6, 0xEC, 0x3B, 0x26, 0x63, 0x75, 0xFD, 0x77, 0xF4, 0x00, + 0x81, 0x6D, 0xBD, 0x7A, 0x0F, 0xF8, 0xC1, 0x63, 0xDB, 0x99, 0xB2, 0x25, 0xF2, 0x52, 0x17, 0xC7, + 0xE3, 0xDC, 0x57, 0x26, 0x6B, 0xFA, 0xFA, 0x89, 0xBA, 0x26, 0xC6, 0x21, 0xA4, 0x44, 0xC8, 0xA4, + 0xC0, 0xC9, 0xF9, 0x92, 0x93, 0x07, 0x32, 0x04, 0xF2, 0x37, 0x5B, 0x52, 0x58, 0x6B, 0xC8, 0x49, + 0xCD, 0xE9, 0x4B, 0x72, 0xAC, 0xEA, 0xCB, 0xE3, 0x49, 0xC1, 0x74, 0x23, 0xE2, 0xA9, 0x03, 0xD3, + 0x14, 0x32, 0x3E, 0xA7, 0x8F, 0x54, 0x08, 0x54, 0xB2, 0x72, 0x98, 0x6B, 0xB6, 0x70, 0xCE, 0x51, + 0x29, 0xE4, 0x70, 0x08, 0xB6, 0x1F, 0x9C, 0xE5, 0xB6, 0x2D, 0x87, 0x99, 0x8C, 0x33, 0x48, 0xCF, + 0x4F, 0x6D, 0xEA, 0xF0, 0x84, 0x60, 0xB0, 0xE0, 0x31, 0x52, 0xF2, 0x7F, 0x35, 0xE0, 0xC7, 0xD7, + 0xC5, 0x4E, 0xEE, 0x56, 0x71, 0x9D, 0xB7, 0x6F, 0x5A, 0xFD, 0xCA, 0x1E, 0x30, 0x68, 0x27, 0x19, + 0x0B, 0xB3, 0x4C, 0x84, 0xEA, 0xD2, 0x6A, 0x53, 0xBF, 0x65, 0xAA, 0x1E, 0xD2, 0x8C, 0x35, 0xDA, + 0xD8, 0x84, 0x65, 0x9D, 0x88, 0xB3, 0x16, 0x63, 0x1D, 0x91, 0xB1, 0xBF, 0xB6, 0xB4, 0xA2, 0x88, + 0x2C, 0x11, 0x67, 0x2E, 0xCD, 0xB1, 0xBA, 0x37, 0x07, 0xCE, 0x11, 0x6B, 0x43, 0x29, 0x50, 0x9C, + 0x73, 0x42, 0x1F, 0xA7, 0x2D, 0x2D, 0xA3, 0x70, 0x98, 0x74, 0xEC, 0x42, 0xE0, 0x53, 0xCA, 0x66, + 0x98, 0xAB, 0x37, 0xA9, 0x37, 0x5B, 0x9C, 0x3C, 0x54, 0xE2, 0xCC, 0x65, 0x79, 0x6C, 0x73, 0x96, + 0x38, 0x0C, 0xD1, 0x5A, 0xA3, 0xB5, 0x25, 0x8C, 0x0D, 0x93, 0xF5, 0x88, 0x99, 0xA6, 0x3E, 0xBD, + 0xAA, 0xE5, 0xBB, 0xAF, 0x7D, 0xF6, 0x1A, 0xA1, 0xCC, 0xB1, 0x5E, 0x70, 0x8C, 0xE9, 0xA6, 0x1B, + 0x31, 0xF7, 0x3E, 0x77, 0x84, 0xDE, 0x9C, 0x2A, 0x6E, 0x3B, 0x14, 0x7E, 0xFD, 0xE0, 0x5C, 0xF4, + 0x8E, 0x89, 0x5A, 0x8C, 0x41, 0x20, 0x94, 0x48, 0x62, 0x5F, 0x08, 0x1C, 0x82, 0x52, 0x46, 0x72, + 0x62, 0x7F, 0x8E, 0x5F, 0xCF, 0x01, 0x1C, 0xC6, 0x68, 0x7A, 0x7C, 0xC3, 0x79, 0x2B, 0x4A, 0x8C, + 0xF4, 0xE4, 0xB0, 0xCE, 0xE1, 0x52, 0xE9, 0x56, 0x31, 0x36, 0x1A, 0x29, 0x25, 0x9E, 0x94, 0x38, + 0xE7, 0x90, 0x52, 0x72, 0x60, 0x72, 0x8A, 0x17, 0xC6, 0x0E, 0x72, 0xEE, 0x29, 0xEB, 0x90, 0x42, + 0xF0, 0xBD, 0xAD, 0xE3, 0xDC, 0xFF, 0x62, 0x1D, 0x82, 0x22, 0x88, 0xA4, 0x1E, 0x51, 0x02, 0x06, + 0x0B, 0x3E, 0x2B, 0x2B, 0xC1, 0xF6, 0x01, 0x3F, 0xBE, 0x26, 0x76, 0x62, 0x97, 0x98, 0x1D, 0xE3, + 0x0F, 0x2E, 0x3D, 0xFB, 0xF8, 0x1E, 0xD0, 0x9B, 0xBF, 0x86, 0xC3, 0x35, 0xCD, 0x4B, 0x35, 0x73, + 0x66, 0xB5, 0x19, 0x5F, 0x38, 0x53, 0x0D, 0x09, 0x23, 0xDD, 0xB1, 0xBA, 0xD6, 0x36, 0x15, 0x43, + 0x14, 0x1B, 0xC2, 0x58, 0x13, 0xC5, 0xE6, 0x35, 0x8A, 0xA6, 0x15, 0x86, 0xE4, 0x08, 0x39, 0x67, + 0x24, 0xCF, 0xD2, 0x72, 0x06, 0x6D, 0x0C, 0xD6, 0xDA, 0x8E, 0x98, 0xF4, 0xBD, 0xB3, 0x06, 0x09, + 0x34, 0x5A, 0x2D, 0x9A, 0x61, 0x88, 0x73, 0x0E, 0xA3, 0x35, 0x4B, 0x2A, 0x3D, 0xAC, 0x18, 0x1A, + 0x24, 0xD6, 0x1A, 0xE1, 0x2C, 0x67, 0x8E, 0x56, 0x28, 0xAA, 0x98, 0x28, 0x6C, 0xA5, 0x5E, 0x60, + 0x08, 0x63, 0xC3, 0x54, 0x3D, 0x64, 0xBA, 0x19, 0xAF, 0x6B, 0x38, 0xEF, 0xF7, 0x0E, 0xAC, 0x18, + 0x81, 0xB0, 0x3E, 0x0F, 0xEF, 0x31, 0xA5, 0xDB, 0xE3, 0x7B, 0x9F, 0xE0, 0x6D, 0xA7, 0x0D, 0xCA, + 0x5F, 0xBC, 0x30, 0xF5, 0x81, 0xC3, 0x33, 0xAD, 0x4B, 0x27, 0x6B, 0x11, 0xB1, 0x4D, 0x0A, 0x1E, + 0xE7, 0x1C, 0xB6, 0x2D, 0xD6, 0x82, 0x75, 0x94, 0x32, 0x49, 0xCC, 0x69, 0x6B, 0x31, 0xAF, 0x52, + 0xE2, 0x58, 0x93, 0x17, 0x11, 0xE7, 0x9F, 0x50, 0x62, 0xB4, 0x92, 0xEF, 0x58, 0xBE, 0x9B, 0x80, + 0xB6, 0x27, 0xB4, 0xBF, 0x53, 0x42, 0xD2, 0x88, 0x22, 0xAC, 0x73, 0x28, 0x29, 0xB1, 0xC6, 0xD0, + 0x57, 0xCA, 0x03, 0x82, 0x5D, 0x07, 0x8F, 0xD0, 0x88, 0x2D, 0x4F, 0xEE, 0x9D, 0xA2, 0x6E, 0x14, + 0x4E, 0x48, 0xAC, 0x75, 0x29, 0x91, 0x16, 0x4F, 0x08, 0x59, 0x0C, 0x84, 0xBF, 0x7C, 0xF2, 0xC0, + 0x5D, 0x3A, 0xD7, 0xD7, 0x3A, 0xE3, 0xC4, 0xE5, 0xDC, 0xF7, 0x93, 0x9F, 0x00, 0x30, 0x6F, 0xFE, + 0xAA, 0xB6, 0x34, 0x77, 0x3E, 0x7D, 0x88, 0x83, 0x73, 0xE1, 0x92, 0x5A, 0x23, 0xBA, 0x64, 0xA6, + 0x16, 0xD2, 0x0A, 0x63, 0x9C, 0x92, 0x08, 0x27, 0x3B, 0x09, 0xB0, 0x3D, 0xA7, 0x5A, 0x63, 0xA9, + 0xB5, 0x62, 0x8A, 0x19, 0x85, 0x7B, 0x95, 0xC5, 0xBF, 0xB3, 0x86, 0x9C, 0x88, 0x79, 0xE3, 0xCA, + 0x32, 0x2B, 0x2A, 0x39, 0x8C, 0xB5, 0xC9, 0xE7, 0x29, 0x01, 0xC7, 0x86, 0x40, 0x5A, 0xFD, 0x09, + 0x41, 0xDE, 0x0F, 0x68, 0xE9, 0x98, 0x50, 0x08, 0x02, 0x25, 0xA9, 0xB7, 0x22, 0xB6, 0x1F, 0x38, + 0x48, 0x23, 0x76, 0x6C, 0xDE, 0x35, 0xC9, 0x44, 0xCD, 0x21, 0xB2, 0x60, 0xB5, 0x49, 0xA2, 0xDB, + 0x81, 0xC1, 0x31, 0x5D, 0x83, 0x5A, 0x5E, 0xBD, 0x3E, 0xEF, 0xAB, 0x0D, 0xDA, 0x8A, 0x07, 0x97, + 0xAE, 0xDF, 0xD4, 0xB9, 0xF7, 0x3C, 0x02, 0x4A, 0xD9, 0xA5, 0x7C, 0xFE, 0xBE, 0x47, 0x30, 0xC6, + 0x9E, 0x36, 0x5B, 0x0F, 0xD7, 0xD4, 0x1A, 0x21, 0x51, 0x6C, 0x91, 0x4E, 0x21, 0x9C, 0x03, 0xE9, + 0xD2, 0xF9, 0xBF, 0xDD, 0xC7, 0x11, 0xCC, 0xD4, 0x05, 0x81, 0x08, 0x5E, 0xD5, 0xE2, 0xC7, 0x59, + 0x43, 0x40, 0xC4, 0xD9, 0xAB, 0x4B, 0xAC, 0xEE, 0xCF, 0x77, 0x80, 0xB5, 0xDD, 0x5F, 0x00, 0xDA, + 0x18, 0x62, 0xAD, 0xF1, 0x3D, 0x6F, 0x1E, 0x78, 0x21, 0x04, 0xCE, 0x19, 0x7C, 0x21, 0xF0, 0x94, + 0x62, 0xA6, 0xD1, 0xE4, 0xC1, 0x67, 0x77, 0xD3, 0x34, 0x8A, 0xC7, 0xF6, 0xCE, 0xF2, 0x52, 0x1D, + 0xBC, 0x6C, 0x19, 0x61, 0x00, 0x6B, 0x8E, 0xA6, 0x37, 0xE7, 0xA8, 0x3A, 0xCB, 0x6C, 0xC3, 0xEF, + 0xAB, 0x54, 0x32, 0xE7, 0xE9, 0x33, 0x56, 0x3E, 0x68, 0x6F, 0x7F, 0x72, 0x71, 0x02, 0x76, 0x1E, + 0xDE, 0xC3, 0xDA, 0xB5, 0x9F, 0xE6, 0x33, 0xDF, 0x7E, 0xD7, 0x59, 0xD5, 0x7A, 0x58, 0x6A, 0x34, + 0x23, 0x34, 0x02, 0x89, 0x43, 0x38, 0x09, 0x52, 0x22, 0x84, 0x9C, 0xD7, 0xE0, 0x98, 0xAE, 0x59, + 0x8A, 0xBE, 0x40, 0xBD, 0x42, 0x26, 0x74, 0xD6, 0xA2, 0x6C, 0xC4, 0xA6, 0x55, 0x45, 0x4E, 0x19, + 0x2E, 0xE2, 0xAC, 0xE5, 0x70, 0xB5, 0xCE, 0xC1, 0xA9, 0x19, 0x96, 0x0F, 0xF6, 0x91, 0xF5, 0x3C, + 0xF6, 0x1F, 0x99, 0x62, 0xC7, 0xD8, 0x21, 0xF2, 0x19, 0x9F, 0xB3, 0xD7, 0xAD, 0x86, 0x2E, 0xF0, + 0x6D, 0x32, 0xA4, 0x94, 0x60, 0x0C, 0xB3, 0xF5, 0x26, 0xFB, 0xA7, 0x1A, 0xEC, 0x98, 0x74, 0x1C, + 0x6A, 0x2A, 0x94, 0x9F, 0xC7, 0x38, 0x0F, 0x8C, 0x65, 0xDE, 0x5A, 0xD4, 0x39, 0x9A, 0x06, 0x66, + 0x1A, 0xA1, 0x18, 0xCA, 0x8B, 0xB3, 0x46, 0x1E, 0xFE, 0x65, 0xBE, 0xB6, 0x6C, 0x6D, 0x63, 0xD1, + 0x24, 0xB8, 0xEB, 0x50, 0x95, 0xDD, 0xBB, 0x3F, 0x9C, 0x0B, 0xC3, 0xF8, 0xB4, 0x6A, 0xAD, 0x45, + 0x2B, 0x8C, 0x3A, 0x09, 0x25, 0x8E, 0x0D, 0x3A, 0xD6, 0xC9, 0xFB, 0x38, 0x11, 0x13, 0x6B, 0xAA, + 0x8D, 0x88, 0xC9, 0x6A, 0x8B, 0x28, 0xD6, 0x84, 0xD1, 0xF1, 0x24, 0x26, 0x6C, 0x35, 0xD8, 0x30, + 0xE4, 0xF3, 0xFA, 0x91, 0x12, 0xCE, 0x59, 0xB4, 0xB5, 0xFC, 0xEC, 0x99, 0xE7, 0xF8, 0x97, 0xFB, + 0x1F, 0xE7, 0xB1, 0x1D, 0xFB, 0x88, 0xB4, 0xE6, 0xBE, 0x67, 0x76, 0x72, 0xFF, 0x73, 0x63, 0x84, + 0x5A, 0xE0, 0x8C, 0xC1, 0xA6, 0x9E, 0x91, 0xE8, 0xA0, 0x3B, 0x7A, 0x5A, 0x6B, 0x29, 0xE7, 0x72, + 0x28, 0x95, 0xE1, 0x70, 0x55, 0x63, 0x45, 0x06, 0xE3, 0x64, 0x92, 0x9C, 0xDB, 0x7A, 0xB6, 0x45, + 0x27, 0x3A, 0xCC, 0xD5, 0x43, 0x42, 0xED, 0x4E, 0xCE, 0x0D, 0xAD, 0xEE, 0x0F, 0xCA, 0x83, 0x8B, + 0x7B, 0xC0, 0xBE, 0x23, 0x75, 0xE6, 0x9A, 0x71, 0xB9, 0xDE, 0x8C, 0x56, 0xD7, 0x9B, 0x11, 0x51, + 0xAC, 0xC1, 0x3A, 0xA4, 0x73, 0x08, 0xA5, 0x40, 0x0A, 0x84, 0xB4, 0x2C, 0x9C, 0x3D, 0x27, 0xE6, + 0x42, 0x3C, 0x01, 0xFE, 0x22, 0xCB, 0x41, 0xE7, 0x1C, 0x56, 0x87, 0x6C, 0x18, 0xF6, 0x39, 0x6F, + 0x55, 0x05, 0x81, 0xC3, 0x68, 0x8B, 0x13, 0x82, 0x6C, 0x90, 0x65, 0xC3, 0xAA, 0x13, 0x58, 0xBD, + 0x64, 0x80, 0x83, 0x33, 0x55, 0x7C, 0x3F, 0xE0, 0xCC, 0xB5, 0x2B, 0x58, 0xD6, 0x57, 0xC6, 0xA4, + 0x6E, 0xEC, 0x52, 0xE0, 0x5E, 0x1A, 0x12, 0x52, 0x0A, 0x0E, 0x4C, 0x4E, 0xF3, 0xC4, 0xCE, 0xFD, + 0xBC, 0xFE, 0x84, 0x11, 0x9E, 0x3A, 0xD0, 0xE0, 0x70, 0x2B, 0x46, 0xFA, 0x92, 0x45, 0xEB, 0xBA, + 0x34, 0xA7, 0xD4, 0x9A, 0x50, 0x6F, 0xC5, 0x4B, 0xAC, 0x63, 0xD4, 0x58, 0xB7, 0x3F, 0xD2, 0x86, + 0xC0, 0x53, 0xF3, 0x09, 0x68, 0x45, 0x31, 0x51, 0x20, 0x07, 0xEA, 0xAD, 0x78, 0xB8, 0xD1, 0x8C, + 0x88, 0x63, 0x8D, 0x74, 0x0E, 0x9B, 0xDE, 0xA8, 0x93, 0x04, 0x17, 0x0C, 0xA4, 0xB5, 0xE1, 0xB0, + 0x70, 0x0C, 0x14, 0x03, 0x04, 0xDD, 0x6D, 0x30, 0x87, 0xD1, 0x11, 0xAB, 0x7A, 0x04, 0x97, 0xAC, + 0xED, 0xC5, 0x17, 0x0E, 0xAD, 0x93, 0xE5, 0xAB, 0x76, 0x50, 0xCC, 0x7A, 0x5C, 0xBC, 0x71, 0x2D, + 0x47, 0xE6, 0x6A, 0xFC, 0x62, 0xEB, 0x6E, 0xCE, 0x5D, 0xB7, 0x92, 0x91, 0x4A, 0x21, 0x99, 0x51, + 0x8C, 0xED, 0xB8, 0xBC, 0x52, 0xAA, 0x13, 0x0A, 0x5B, 0x5F, 0x1C, 0xE3, 0xD1, 0x1D, 0xBB, 0x39, + 0xFF, 0xD4, 0x93, 0x18, 0x1D, 0x2A, 0x53, 0x50, 0x86, 0x28, 0x6C, 0xE1, 0x09, 0x6F, 0x71, 0x02, + 0x70, 0x38, 0xEB, 0x68, 0x86, 0x8E, 0x46, 0x18, 0xE7, 0x6B, 0xAD, 0x68, 0xB4, 0x15, 0xE9, 0x4E, + 0xD2, 0x9E, 0x47, 0x80, 0xB3, 0x0E, 0x9C, 0x1B, 0x6C, 0x85, 0x51, 0x3E, 0x0C, 0x23, 0x74, 0x6C, + 0x69, 0xF3, 0x2A, 0x9C, 0x4A, 0x92, 0xA0, 0x68, 0xCF, 0x02, 0xF3, 0xD3, 0xDE, 0x74, 0xD5, 0x60, + 0x8D, 0xA5, 0x27, 0xE7, 0xA7, 0x39, 0xD2, 0x61, 0x4D, 0xCC, 0x70, 0xCE, 0x72, 0xF9, 0xBA, 0x61, + 0x8A, 0x3E, 0x44, 0x71, 0xDC, 0x89, 0x67, 0x84, 0xC0, 0x13, 0x82, 0xF1, 0xA9, 0x59, 0x1E, 0x7A, + 0x76, 0x37, 0x67, 0x9D, 0x74, 0x02, 0x4B, 0x7A, 0x0A, 0x84, 0x5A, 0x23, 0x21, 0x99, 0xEE, 0x94, + 0x42, 0x4A, 0x89, 0x94, 0x02, 0x63, 0x2D, 0x0F, 0x6C, 0xDD, 0xC1, 0xF6, 0x7D, 0x2F, 0x71, 0xF9, + 0x1B, 0x36, 0xB0, 0x7A, 0xA8, 0x97, 0xF1, 0xD9, 0x1A, 0x47, 0x66, 0xAB, 0x18, 0x53, 0x80, 0xD8, + 0x2C, 0xA2, 0x97, 0xE8, 0x10, 0xD0, 0xC2, 0xD2, 0x0C, 0x75, 0x50, 0x6F, 0xE9, 0xC1, 0xBD, 0x13, + 0xB5, 0xCE, 0xE2, 0x70, 0x1E, 0x01, 0x49, 0xB9, 0xE9, 0x7A, 0x1A, 0xCD, 0xD8, 0x8F, 0xA2, 0x18, + 0x6D, 0xDC, 0xD1, 0xFE, 0xBD, 0x03, 0xA4, 0x4D, 0x93, 0xE0, 0xD1, 0x59, 0xA0, 0x9B, 0xE9, 0xC9, + 0xAA, 0x49, 0xCA, 0xD8, 0xAC, 0x87, 0xB3, 0x9A, 0xA2, 0x8C, 0xB8, 0xFC, 0xA4, 0x41, 0x86, 0xF2, + 0x8A, 0x28, 0xD6, 0x1D, 0xF0, 0xD6, 0x5A, 0x02, 0xDF, 0xA3, 0x11, 0xC5, 0xDC, 0xFD, 0xE8, 0x36, + 0xAE, 0xDA, 0x74, 0x2A, 0xFD, 0xA5, 0x1C, 0x5F, 0xFA, 0xE1, 0x66, 0x7A, 0xF3, 0x19, 0xAE, 0x3D, + 0xF7, 0x74, 0x02, 0xA5, 0x10, 0x29, 0xF8, 0x7A, 0x2B, 0xE2, 0x07, 0x8F, 0x6D, 0xE1, 0xF0, 0x4C, + 0x8D, 0xB7, 0x9D, 0xFB, 0x3A, 0x46, 0xFA, 0xCA, 0xEC, 0x99, 0x98, 0xE5, 0xAB, 0x3F, 0x7D, 0x9A, + 0xF1, 0x19, 0x8D, 0xCC, 0x95, 0x70, 0xC6, 0x1C, 0xA3, 0x4F, 0x32, 0x15, 0x3A, 0x9C, 0xB3, 0xC4, + 0x56, 0xD0, 0x0A, 0x63, 0xA9, 0xB5, 0xE9, 0xFD, 0xFB, 0x3B, 0xB7, 0xF2, 0xD7, 0xD7, 0x9C, 0x7A, + 0x2C, 0x01, 0x61, 0xA4, 0xD1, 0xC6, 0x64, 0xA7, 0xE7, 0x1A, 0xAA, 0x5E, 0x6F, 0xE1, 0x94, 0x4A, + 0x3C, 0xC0, 0x81, 0xB0, 0x0E, 0x94, 0x44, 0x08, 0x97, 0x8E, 0xB3, 0xB8, 0xBB, 0x4D, 0x6A, 0x4D, + 0xA3, 0x29, 0xE8, 0xCD, 0x68, 0x2E, 0xDE, 0xD8, 0xC7, 0xEA, 0xFE, 0x0C, 0xB1, 0x8E, 0x3B, 0xD7, + 0x0B, 0x21, 0xF0, 0x3C, 0x45, 0x23, 0xB6, 0x6C, 0xD9, 0x73, 0x08, 0x27, 0x3D, 0xEA, 0x51, 0xCC, + 0xB6, 0xAD, 0xE3, 0x4C, 0xD7, 0x22, 0x7A, 0x8B, 0x05, 0x3C, 0xCF, 0x47, 0x4A, 0x81, 0x92, 0x92, + 0xC3, 0xB3, 0x55, 0x6E, 0x7F, 0xE0, 0x71, 0x10, 0x8A, 0x3F, 0xB8, 0xF0, 0x0D, 0xF4, 0x17, 0xF3, + 0x3C, 0xB1, 0x73, 0x8C, 0xAF, 0xFD, 0xF4, 0x57, 0xEC, 0x99, 0x15, 0xF8, 0x85, 0x41, 0x9C, 0x93, + 0xA0, 0xCD, 0x22, 0x3A, 0x25, 0x5D, 0x1B, 0xE7, 0x2C, 0x42, 0xC0, 0x6C, 0x3D, 0xA4, 0x15, 0xE9, + 0x7C, 0xF4, 0xF5, 0x2F, 0xE3, 0xBE, 0x7A, 0xFD, 0xB1, 0x04, 0xE0, 0x2C, 0x38, 0x27, 0xC3, 0x48, + 0x73, 0x64, 0xA6, 0x4E, 0xA1, 0x90, 0x21, 0x48, 0xEF, 0x23, 0xAC, 0x43, 0xD8, 0xA4, 0x18, 0x7A, + 0xB9, 0xB6, 0x8F, 0x73, 0x96, 0xA8, 0xDE, 0xE4, 0xE2, 0x0D, 0x15, 0x36, 0xAD, 0x28, 0xA7, 0x45, + 0xCD, 0x51, 0xF0, 0x8D, 0x48, 0xF3, 0xE3, 0x87, 0xB7, 0x70, 0x70, 0xAE, 0xC5, 0x29, 0x2B, 0x47, + 0x58, 0xB3, 0x74, 0x80, 0x6A, 0xA3, 0xC9, 0x8A, 0xC1, 0x5E, 0xCE, 0x3B, 0x65, 0x35, 0xF9, 0xC0, + 0x43, 0x09, 0x90, 0x42, 0xB0, 0x63, 0xEC, 0x10, 0xB7, 0xFE, 0xEC, 0x51, 0x46, 0x06, 0xFB, 0xB8, + 0xEE, 0xFC, 0x33, 0x08, 0x3C, 0xC9, 0x77, 0x1F, 0xDE, 0xCA, 0x37, 0x1F, 0x7A, 0x9E, 0x19, 0x93, + 0xC7, 0xCF, 0xF7, 0x63, 0x44, 0x90, 0xEC, 0xA7, 0x61, 0x8E, 0xA7, 0x10, 0xCE, 0x5A, 0xEA, 0xA1, + 0xA6, 0x9A, 0xF7, 0xB0, 0xCE, 0x49, 0xD8, 0xDF, 0x89, 0x14, 0x6F, 0xE1, 0xC5, 0x02, 0x17, 0x49, + 0x9C, 0x0D, 0xC3, 0x88, 0x56, 0x6C, 0xE8, 0xED, 0x15, 0xF8, 0x90, 0x14, 0x42, 0x4E, 0x21, 0xE4, + 0xCB, 0xF4, 0xBD, 0x9C, 0xC5, 0xC4, 0x2D, 0xCE, 0x5D, 0x99, 0xE3, 0x9A, 0xD7, 0x2D, 0x45, 0x89, + 0x24, 0x61, 0x4A, 0x29, 0x13, 0xCB, 0x2B, 0xC5, 0x0B, 0x2F, 0x1D, 0xE1, 0xAE, 0x47, 0xB6, 0x93, + 0x2F, 0xF4, 0xF0, 0xEE, 0x8B, 0xCF, 0x66, 0x49, 0xC9, 0xC7, 0x51, 0x42, 0x2A, 0xD5, 0xF1, 0x5A, + 0x21, 0x24, 0x9B, 0xB7, 0xEE, 0xE0, 0xB6, 0x5F, 0x3C, 0xCE, 0xB9, 0xA7, 0x9E, 0xC4, 0x35, 0x6F, + 0x3C, 0x8D, 0xD9, 0x7A, 0x93, 0xAF, 0xFC, 0xE8, 0x49, 0xEE, 0xDD, 0x32, 0x86, 0x0E, 0xFA, 0xF0, + 0xB2, 0x3D, 0x18, 0x82, 0x14, 0xF7, 0xE2, 0xE0, 0x93, 0x54, 0xE4, 0xA8, 0x37, 0x23, 0xC2, 0x30, + 0x06, 0x5B, 0x40, 0x38, 0x17, 0x52, 0xBE, 0x36, 0x8D, 0xE9, 0x85, 0x04, 0xE0, 0x10, 0x82, 0x9A, + 0x12, 0x4E, 0x0B, 0x2C, 0xCD, 0x96, 0x66, 0x7A, 0x56, 0x50, 0x2E, 0x83, 0x9F, 0xF1, 0x93, 0x30, + 0x90, 0xB2, 0xD3, 0xA9, 0x59, 0xF8, 0x5B, 0x1D, 0x87, 0x9C, 0x3C, 0xA8, 0xF8, 0xE3, 0xF3, 0x57, + 0xD1, 0x5B, 0xCC, 0x62, 0xEC, 0xD1, 0x84, 0x24, 0x84, 0xC0, 0x5A, 0xCB, 0xCA, 0xE1, 0x01, 0xDE, + 0x79, 0xE1, 0x26, 0xF2, 0xF9, 0x1C, 0x7D, 0x85, 0x00, 0xEB, 0x1C, 0x52, 0x29, 0x84, 0x48, 0xE2, + 0x3D, 0xD2, 0x86, 0x6F, 0xDF, 0xFF, 0x4B, 0xEE, 0x7D, 0x62, 0x3B, 0xEF, 0xBA, 0xF4, 0x8D, 0x5C, + 0xF6, 0xFA, 0x93, 0xD9, 0xBA, 0x67, 0x9C, 0x2F, 0xFF, 0xF0, 0x31, 0x9E, 0x19, 0xAF, 0xA3, 0x72, + 0x03, 0x48, 0xBF, 0x84, 0xC1, 0x7B, 0x79, 0xCB, 0xA7, 0xE0, 0x9B, 0xA1, 0xA6, 0xDA, 0x08, 0xC9, + 0x28, 0xF0, 0xA4, 0x73, 0x52, 0x30, 0x77, 0xD5, 0x47, 0x2E, 0x46, 0xA4, 0x5E, 0x79, 0x8C, 0x07, + 0x38, 0xEB, 0x26, 0x03, 0x4F, 0x46, 0xCA, 0x39, 0x30, 0x9A, 0x30, 0x0C, 0x99, 0xAD, 0x42, 0xC1, + 0xE6, 0x08, 0x32, 0x3E, 0x42, 0x2A, 0x90, 0xB6, 0x8B, 0xE3, 0x24, 0x49, 0x58, 0x1D, 0x33, 0x98, + 0x33, 0xFC, 0xE9, 0xC5, 0xEB, 0x58, 0x31, 0x58, 0x46, 0x1B, 0x8B, 0x27, 0xE7, 0x13, 0x04, 0x82, + 0xA2, 0xE7, 0x71, 0xED, 0x79, 0x1B, 0xD3, 0x69, 0x2D, 0xB1, 0xB6, 0x10, 0x49, 0xBC, 0x4F, 0x57, + 0xEB, 0x7C, 0xE9, 0xCE, 0x9F, 0xF0, 0xFC, 0xFE, 0x43, 0xFC, 0xC5, 0x75, 0x57, 0xB0, 0x71, 0xF5, + 0x08, 0x77, 0x3F, 0xBC, 0x95, 0xFF, 0xFD, 0x93, 0xA7, 0x38, 0xD4, 0xF4, 0xF1, 0xF3, 0x43, 0x38, + 0x2F, 0x8F, 0x71, 0x32, 0xA9, 0xF8, 0xDC, 0xC2, 0x9A, 0x24, 0x19, 0x43, 0x08, 0xB0, 0xD6, 0xD1, + 0x8C, 0x74, 0xB2, 0x96, 0x31, 0x06, 0x25, 0x15, 0x81, 0x14, 0x71, 0xA0, 0xC4, 0x91, 0x37, 0x9D, + 0xBA, 0x94, 0xB6, 0x0D, 0xE7, 0x11, 0x90, 0xF1, 0x15, 0xD9, 0x40, 0x4D, 0xE4, 0x33, 0x6A, 0xCA, + 0x97, 0x0C, 0x38, 0xA3, 0x41, 0x0B, 0xE2, 0x50, 0x50, 0x75, 0x90, 0x33, 0x96, 0x20, 0xE3, 0x27, + 0xE5, 0x68, 0x57, 0x18, 0x58, 0x6B, 0xC8, 0x8A, 0x16, 0x7F, 0xF2, 0xA6, 0xF5, 0xBC, 0x61, 0xF5, + 0x10, 0xC6, 0x3A, 0x3C, 0x71, 0x14, 0xBD, 0x58, 0x10, 0x32, 0xF3, 0xE6, 0x76, 0x40, 0x29, 0xC5, + 0xCE, 0x03, 0x07, 0xF9, 0xEC, 0xAD, 0xF7, 0x20, 0xA4, 0xC7, 0x27, 0xDE, 0xF7, 0x4E, 0x0A, 0x19, + 0x9F, 0xCF, 0xDE, 0xFE, 0x33, 0xBE, 0xF7, 0xD8, 0x6E, 0x22, 0x59, 0xC6, 0xCB, 0x55, 0x30, 0x22, + 0x9B, 0xD4, 0xFA, 0x2F, 0x63, 0x75, 0x00, 0xE3, 0x1C, 0xAD, 0xC8, 0x10, 0xC7, 0x1A, 0x67, 0x1D, + 0xCE, 0x1A, 0x3C, 0x5F, 0x90, 0xF3, 0x65, 0xAB, 0xB7, 0x10, 0x8C, 0x6B, 0x63, 0x16, 0xAF, 0x03, + 0x86, 0x2B, 0x39, 0x56, 0x0E, 0xF7, 0xCC, 0x94, 0x72, 0xC1, 0xBE, 0x8C, 0x2F, 0x4F, 0x12, 0x46, + 0xE3, 0x84, 0xC0, 0x49, 0x81, 0x89, 0x05, 0x0D, 0xE7, 0x88, 0x8D, 0x21, 0x13, 0xF8, 0x48, 0x25, + 0x93, 0xA2, 0xC7, 0x59, 0x9C, 0x6E, 0xF2, 0xCE, 0x37, 0xAD, 0xE2, 0xF7, 0x36, 0xAD, 0x4A, 0x00, + 0x09, 0xD7, 0x01, 0xBD, 0x10, 0x7C, 0x1B, 0x78, 0xFB, 0x3B, 0x01, 0x6C, 0x7E, 0xE6, 0x59, 0x3E, + 0xFF, 0xED, 0x1F, 0xB2, 0x61, 0xCD, 0x4A, 0xDE, 0x7F, 0xED, 0x9B, 0xD9, 0x77, 0x68, 0x92, 0xBF, + 0xF9, 0xFA, 0x0F, 0x79, 0x62, 0xCF, 0x0C, 0x32, 0xDB, 0x87, 0x0C, 0x4A, 0x18, 0xFC, 0xE3, 0xBA, + 0x7C, 0x77, 0x43, 0x39, 0x36, 0x96, 0x58, 0x1B, 0xAC, 0x4D, 0x57, 0x95, 0xD6, 0x82, 0x31, 0x64, + 0x94, 0x4F, 0x39, 0xE7, 0xCF, 0x64, 0x7C, 0x6F, 0x6F, 0xE0, 0x29, 0x02, 0x4F, 0x1D, 0x4B, 0xC0, + 0x89, 0xCB, 0x7A, 0xD9, 0x74, 0xE2, 0x50, 0xF5, 0x8E, 0x9F, 0xFB, 0xCF, 0x16, 0x73, 0xFE, 0x65, + 0xC2, 0x59, 0xAC, 0x8E, 0x71, 0x32, 0x5D, 0x8D, 0x09, 0x88, 0xA3, 0xA4, 0x5E, 0xF0, 0x3C, 0x85, + 0xE7, 0x49, 0x4C, 0xDC, 0xE2, 0x8A, 0x8D, 0x43, 0xFC, 0xC9, 0x65, 0x1B, 0x08, 0x3C, 0x0F, 0xEB, + 0xE6, 0x83, 0x6F, 0x2F, 0x6D, 0x93, 0x82, 0xE6, 0xA8, 0x57, 0x48, 0x29, 0x89, 0xA2, 0x98, 0xDB, + 0xEE, 0xDB, 0xCC, 0x37, 0x7E, 0xFC, 0x20, 0xD7, 0x5D, 0xFC, 0x46, 0xAE, 0xBD, 0xF8, 0x2C, 0x7E, + 0xF4, 0xE8, 0x36, 0xBE, 0xF8, 0xBD, 0x87, 0x19, 0xAB, 0x82, 0x9F, 0x1B, 0xC4, 0x79, 0x79, 0x2C, + 0xAA, 0x03, 0xFE, 0x38, 0x5D, 0x73, 0xAC, 0x75, 0xC4, 0xC6, 0xA6, 0x79, 0xC7, 0xB5, 0xC3, 0x39, + 0x69, 0xA8, 0x58, 0x4B, 0x7F, 0x31, 0xA0, 0x9C, 0x95, 0x2F, 0xCE, 0x4E, 0x8C, 0x1F, 0x6E, 0x36, + 0x8F, 0x92, 0x38, 0x8F, 0x80, 0x4D, 0x27, 0x0E, 0xF1, 0xC7, 0xFF, 0xE3, 0xFB, 0x76, 0xDD, 0x8A, + 0xFE, 0xC7, 0x2B, 0xC5, 0x6C, 0xE4, 0x09, 0x02, 0xA3, 0x35, 0x4E, 0x26, 0xE0, 0x3B, 0x2E, 0xEF, + 0x1C, 0x91, 0xB5, 0xB4, 0x9A, 0x11, 0xA7, 0x8D, 0x16, 0xF9, 0xD0, 0x3B, 0x36, 0xD1, 0x5B, 0xCC, + 0x26, 0x71, 0xDF, 0x65, 0xF1, 0x76, 0x29, 0xDB, 0x9E, 0x05, 0x3A, 0x5E, 0x20, 0x25, 0xD3, 0xB3, + 0x73, 0x7C, 0xF1, 0xB6, 0xEF, 0xF3, 0xD0, 0x96, 0x17, 0xF8, 0x8B, 0xEB, 0xDF, 0xCA, 0xC6, 0x35, + 0xA3, 0xFC, 0xCF, 0x6F, 0xDD, 0xC7, 0xB7, 0x1F, 0x7C, 0x8E, 0x96, 0x28, 0xE2, 0x65, 0x2B, 0x58, + 0x99, 0x41, 0x58, 0x12, 0x2B, 0x2E, 0x38, 0x5C, 0x97, 0x2E, 0xD6, 0xBA, 0xA3, 0xC0, 0xA1, 0x33, + 0xF7, 0x63, 0x2D, 0xCE, 0x18, 0xF2, 0x81, 0x62, 0xA4, 0xBF, 0x40, 0x3E, 0x90, 0x4F, 0x7E, 0xEB, + 0x3F, 0x9F, 0x3B, 0xBB, 0xE6, 0xDD, 0x9F, 0x5A, 0x9C, 0x80, 0xC3, 0x33, 0x4D, 0x36, 0xAE, 0x1A, + 0x64, 0xA8, 0xAF, 0xF0, 0xC4, 0x40, 0x6F, 0xE1, 0x60, 0x36, 0x50, 0x2B, 0xC2, 0x30, 0xC2, 0xC5, + 0x02, 0x8B, 0x40, 0x72, 0x74, 0x1D, 0x60, 0x75, 0x4C, 0x7F, 0xC1, 0x71, 0xE3, 0x75, 0x67, 0xB2, + 0x7A, 0xA8, 0x27, 0xA9, 0xF1, 0x3B, 0xEB, 0xF6, 0xF9, 0x56, 0x5F, 0x08, 0x7E, 0xF7, 0x81, 0x71, + 0x3E, 0xFD, 0xF5, 0x3B, 0x98, 0x6D, 0x84, 0x7C, 0xF2, 0xCF, 0xDE, 0x4D, 0x6C, 0x1C, 0x1F, 0xFA, + 0xC7, 0x3B, 0xF8, 0xE5, 0x8E, 0x09, 0x44, 0xB6, 0x17, 0x15, 0x94, 0x92, 0x29, 0xCE, 0x42, 0xFA, + 0xE7, 0x18, 0xF4, 0x36, 0x2D, 0x71, 0xAD, 0x5B, 0xE4, 0xCB, 0xB6, 0xF5, 0x8D, 0xC1, 0x17, 0x8E, + 0x25, 0x3D, 0x39, 0xFA, 0x8B, 0x99, 0x66, 0x5F, 0xB9, 0xF8, 0xD0, 0x45, 0xFF, 0xF0, 0xA4, 0xDD, + 0xF7, 0xF0, 0x77, 0x17, 0x27, 0x60, 0xB8, 0x37, 0xCF, 0x77, 0x36, 0xEF, 0x60, 0xD3, 0xFA, 0xE5, + 0xBB, 0x1F, 0xDD, 0xBA, 0xFF, 0x91, 0x4A, 0x29, 0xB7, 0x62, 0x6E, 0xAE, 0x8E, 0xD5, 0x71, 0x52, + 0x55, 0x76, 0x7A, 0x0C, 0x86, 0x40, 0x69, 0xFE, 0xFC, 0xAD, 0x67, 0x73, 0xC1, 0xA9, 0xCB, 0x89, + 0xD3, 0x15, 0x5B, 0x27, 0xE6, 0x84, 0x40, 0x76, 0xAD, 0xE1, 0x9D, 0x4B, 0xAA, 0x47, 0x29, 0x04, + 0x8F, 0x3E, 0xB3, 0x9D, 0x4F, 0xFD, 0xEB, 0x77, 0x59, 0xB3, 0x7C, 0x29, 0x1F, 0x7C, 0xCF, 0xDB, + 0xF9, 0xE5, 0xB6, 0x17, 0xF9, 0x5F, 0xDF, 0xD9, 0xCC, 0xFE, 0x19, 0x83, 0x9F, 0x1B, 0x40, 0xB4, + 0x5D, 0x7E, 0xA1, 0xD5, 0xD3, 0xAD, 0x38, 0x97, 0xEE, 0x47, 0x1E, 0xFD, 0x23, 0xBA, 0x92, 0x80, + 0xEB, 0xAC, 0xFE, 0x9C, 0xB1, 0xF8, 0xD2, 0x31, 0x50, 0xCC, 0x30, 0x50, 0xCE, 0xD0, 0x5B, 0xCC, + 0xEC, 0x2A, 0x17, 0x82, 0x47, 0x85, 0x08, 0xF1, 0x8B, 0x95, 0xC5, 0x09, 0x00, 0xB8, 0xE2, 0x0D, + 0xAB, 0xB8, 0xEA, 0xC6, 0x5B, 0x9A, 0x97, 0x9F, 0xB9, 0xE6, 0x9E, 0xE1, 0x81, 0xD2, 0x35, 0x07, + 0x0F, 0x4E, 0x66, 0x9A, 0x51, 0x04, 0xC2, 0x75, 0xDC, 0xCE, 0xC4, 0x96, 0x6B, 0x2E, 0x58, 0xC3, + 0x1F, 0x5E, 0xB2, 0x01, 0x1D, 0xC7, 0xA9, 0x15, 0x5C, 0x7B, 0x12, 0x4A, 0x9E, 0x80, 0xEA, 0x02, + 0xDF, 0xF6, 0x8A, 0x1F, 0x3C, 0xF0, 0x18, 0x37, 0xDF, 0x79, 0x2F, 0x57, 0x5C, 0x70, 0x16, 0x6F, + 0x3A, 0x63, 0x03, 0x37, 0xDD, 0xFD, 0x10, 0xB7, 0xFE, 0x7C, 0x1B, 0x4D, 0x97, 0xC7, 0xCB, 0xF6, + 0x63, 0x65, 0x16, 0x61, 0x45, 0xE2, 0xBA, 0x8B, 0xB9, 0xFC, 0xF1, 0x1E, 0x3A, 0xE8, 0x5E, 0x03, + 0xB9, 0xD4, 0xF2, 0x0A, 0xFA, 0x0B, 0x19, 0xCA, 0x59, 0x45, 0x5F, 0x29, 0x4B, 0x4F, 0x21, 0xF3, + 0x93, 0xF7, 0x5C, 0xBC, 0x7E, 0xEC, 0xB6, 0x5F, 0xEC, 0xE0, 0xCF, 0xFE, 0xDB, 0x87, 0x8E, 0x4F, + 0xC0, 0xBE, 0xC3, 0x73, 0xFC, 0xFE, 0x9B, 0x4E, 0x61, 0xA0, 0x52, 0xB8, 0x6F, 0x74, 0xB8, 0xB2, + 0xED, 0xC5, 0x3D, 0xD9, 0x33, 0x5A, 0x47, 0x5A, 0x10, 0x77, 0x0F, 0x6D, 0x38, 0x30, 0x7E, 0x88, + 0xC3, 0xD3, 0x73, 0x0C, 0x57, 0x0A, 0x49, 0xB3, 0x22, 0xB5, 0xBA, 0x50, 0x2A, 0x59, 0x09, 0x76, + 0x85, 0x41, 0x18, 0xC5, 0xDC, 0x72, 0xCF, 0x7D, 0xFC, 0xE2, 0x89, 0xAD, 0xBC, 0xFF, 0xFA, 0xAB, + 0xC9, 0x64, 0x73, 0xFC, 0xD5, 0x97, 0xEE, 0xE4, 0xE1, 0xE7, 0x0F, 0x23, 0x32, 0x15, 0x54, 0xA6, + 0x88, 0x13, 0xFE, 0xD1, 0xD8, 0x7D, 0xAD, 0x47, 0x1A, 0x07, 0x6D, 0x0F, 0xCC, 0x7A, 0x92, 0xBE, + 0x62, 0x40, 0xCE, 0x13, 0x94, 0x32, 0x1E, 0x83, 0x3D, 0xB9, 0x89, 0x4A, 0x31, 0xFB, 0x9D, 0x4F, + 0x7F, 0xFB, 0x51, 0xF3, 0xF5, 0x9F, 0x1F, 0x9C, 0xF7, 0xD3, 0x63, 0x4A, 0xBA, 0x93, 0x57, 0xF4, + 0xB3, 0x62, 0xB8, 0xC2, 0xBB, 0x2E, 0x39, 0xE5, 0xC0, 0xC8, 0x50, 0xCF, 0xAD, 0x23, 0x4B, 0x7A, + 0x6D, 0xE0, 0x49, 0x9C, 0x8E, 0xB1, 0x71, 0x8C, 0x8B, 0x23, 0x84, 0x73, 0x3C, 0xBC, 0x65, 0x2F, + 0x9F, 0xFC, 0xDA, 0xF7, 0xA9, 0x35, 0x93, 0x56, 0xB5, 0x6B, 0x2B, 0x61, 0x8F, 0x6E, 0x62, 0x00, + 0xCC, 0x56, 0x6B, 0x7C, 0xE1, 0x5F, 0xEF, 0x60, 0xE7, 0xBE, 0x71, 0x3E, 0xFA, 0xBE, 0x7F, 0xC7, + 0xD8, 0x54, 0x9D, 0x0F, 0x7C, 0xEE, 0x76, 0x36, 0x3F, 0x37, 0x89, 0xCC, 0xF6, 0x23, 0xFD, 0x12, + 0x4E, 0x78, 0x09, 0x78, 0x6B, 0xE7, 0x09, 0xAF, 0x20, 0xDD, 0xD7, 0x38, 0x63, 0xC0, 0x18, 0x8A, + 0x81, 0x64, 0xB0, 0x14, 0x90, 0x55, 0xE0, 0x0B, 0x47, 0x7F, 0x4F, 0x8E, 0x81, 0x9E, 0xFC, 0x8F, + 0xD7, 0x2C, 0xEB, 0x7D, 0x6C, 0xB0, 0x27, 0xC7, 0x27, 0xDE, 0xB3, 0x7E, 0x1E, 0xDE, 0x45, 0x9F, + 0x68, 0x78, 0xDB, 0x7B, 0x6E, 0xE0, 0xEC, 0x2B, 0xDF, 0xC3, 0x60, 0x6F, 0x71, 0xAC, 0xD6, 0x08, + 0x2F, 0x9A, 0x98, 0x9C, 0x5D, 0x5A, 0xAF, 0x37, 0xD2, 0x8D, 0xCB, 0xA4, 0x06, 0x12, 0x52, 0xF2, + 0xC2, 0x9E, 0x71, 0xB0, 0x31, 0xE7, 0x9C, 0xB6, 0x16, 0x29, 0x8E, 0xBA, 0xBC, 0x73, 0x16, 0xA5, + 0x14, 0x63, 0x87, 0x27, 0xF9, 0xD2, 0xAD, 0x77, 0xB1, 0x6C, 0x68, 0x80, 0x6B, 0x2F, 0xBF, 0x88, + 0x7F, 0xFE, 0xFE, 0xC3, 0x7C, 0xEE, 0xF6, 0xCD, 0x4C, 0xB5, 0x02, 0xFC, 0x6C, 0x2F, 0x42, 0x65, + 0x93, 0x4D, 0x0C, 0x77, 0x34, 0x7E, 0x5F, 0xB3, 0xA4, 0x44, 0x28, 0x1C, 0xBD, 0x85, 0x80, 0xDE, + 0x82, 0x8F, 0x87, 0x45, 0x3A, 0x43, 0x4F, 0x21, 0x60, 0xF5, 0x48, 0xFF, 0xC4, 0xE8, 0x70, 0xE5, + 0xBF, 0xEE, 0x1A, 0x9B, 0x7A, 0xE1, 0x5D, 0x97, 0xAC, 0xE7, 0x8C, 0x13, 0x97, 0xBD, 0xBC, 0x07, + 0x00, 0xBC, 0xEB, 0xD2, 0x53, 0x39, 0x61, 0x49, 0x85, 0xF7, 0xFF, 0xF9, 0x97, 0xF7, 0xAC, 0x1C, + 0xE9, 0xFF, 0xA7, 0x55, 0xA3, 0x43, 0xAD, 0x5C, 0xC6, 0x07, 0x13, 0xE3, 0x74, 0x84, 0x8B, 0x63, + 0x30, 0x60, 0xC8, 0x72, 0xD3, 0x9D, 0x8F, 0x70, 0xF3, 0x5D, 0x9B, 0x41, 0xC8, 0xD4, 0xF2, 0x1A, + 0x29, 0x24, 0xDB, 0x76, 0xED, 0xE5, 0x96, 0xBB, 0x7F, 0xC2, 0x65, 0xE7, 0x9E, 0xC9, 0xC6, 0x53, + 0x4E, 0xE6, 0x23, 0x9F, 0xBF, 0x9D, 0xAF, 0xFE, 0xE0, 0x57, 0x84, 0xA2, 0x8C, 0x97, 0xE9, 0x01, + 0x19, 0x24, 0xC1, 0xFB, 0x2A, 0xAD, 0x8D, 0x4D, 0x4A, 0x5F, 0xD7, 0x65, 0x7D, 0x67, 0x4C, 0xD2, + 0x66, 0xF7, 0x04, 0xC3, 0x3D, 0x59, 0x2A, 0x39, 0x0F, 0x65, 0x0D, 0xC2, 0x18, 0xB2, 0x9E, 0x60, + 0x49, 0x5F, 0x89, 0xA1, 0x4A, 0xF1, 0xD6, 0xD3, 0x4F, 0x5C, 0xFA, 0xE0, 0xE8, 0x50, 0x99, 0x07, + 0xB6, 0x8C, 0x1D, 0x83, 0xF5, 0xB8, 0xCF, 0xB4, 0x5C, 0xF1, 0xCE, 0xF7, 0x71, 0xE9, 0xA5, 0x1B, + 0x59, 0x39, 0xD2, 0xBF, 0xAB, 0xD6, 0x08, 0xD7, 0xCF, 0xCC, 0xD5, 0x4F, 0x99, 0x9B, 0xAD, 0x61, + 0x8D, 0xE9, 0x2C, 0x71, 0x85, 0x90, 0xC4, 0x16, 0x1E, 0xDF, 0xF6, 0x02, 0xA5, 0xBC, 0xCF, 0xE9, + 0x27, 0xAD, 0x40, 0x08, 0xC1, 0xA3, 0x5B, 0x9F, 0x67, 0xDB, 0xCE, 0x3D, 0x5C, 0x7D, 0xE9, 0x05, + 0x3C, 0xBB, 0x77, 0x82, 0xBF, 0xFE, 0xE2, 0x77, 0xD9, 0xB6, 0x7F, 0x0E, 0x2F, 0xD7, 0x8B, 0xF4, + 0xF2, 0x20, 0xD5, 0xC2, 0xCC, 0xB6, 0xE0, 0x38, 0x4E, 0x93, 0xBD, 0x63, 0xF9, 0x84, 0x80, 0x40, + 0x0A, 0x7A, 0x0B, 0x01, 0x7D, 0xC5, 0x0C, 0x19, 0x05, 0xC2, 0x1A, 0xB0, 0x06, 0x5F, 0x3A, 0x06, + 0x7B, 0x0B, 0xAC, 0x5A, 0x3E, 0xF0, 0xCC, 0x09, 0x4B, 0x7B, 0xFF, 0x6A, 0xEF, 0x4B, 0xD3, 0x87, + 0x8E, 0xCC, 0x35, 0xF8, 0xD3, 0xAB, 0xDF, 0x70, 0xCC, 0x2D, 0x5F, 0xB6, 0x97, 0xED, 0x9C, 0xE3, + 0x23, 0x5F, 0xF8, 0x01, 0xC3, 0xFD, 0xE5, 0x33, 0x1E, 0x7B, 0x66, 0xF7, 0x2D, 0x0F, 0x3F, 0xF1, + 0xDC, 0xBA, 0x89, 0x89, 0x69, 0xAC, 0x13, 0xA0, 0x14, 0x42, 0x79, 0x08, 0x4F, 0x62, 0x6D, 0x4C, + 0xCE, 0x0B, 0xB9, 0xE1, 0xBA, 0xF3, 0x39, 0xF3, 0x94, 0x15, 0xF8, 0x9E, 0x60, 0x74, 0x64, 0x19, + 0x37, 0xDD, 0xFE, 0x33, 0x6E, 0xB9, 0xF7, 0x49, 0x42, 0x0A, 0xA8, 0x6C, 0x19, 0x21, 0x03, 0xE8, + 0xB4, 0xD5, 0x5F, 0xE5, 0x86, 0x62, 0x17, 0x49, 0xED, 0xFA, 0xC2, 0x93, 0x82, 0x62, 0xCE, 0xA7, + 0x9C, 0x0B, 0x08, 0x94, 0x40, 0xB8, 0xC4, 0x3B, 0x84, 0xB5, 0x28, 0x61, 0xA9, 0x14, 0x73, 0xAC, + 0x5D, 0xB9, 0x64, 0x76, 0xDD, 0xCA, 0xA1, 0x1B, 0x3E, 0xFD, 0xAD, 0x27, 0xBF, 0x79, 0xEB, 0xC7, + 0xAF, 0xE2, 0xE0, 0xAC, 0xE6, 0xDA, 0x0B, 0x4F, 0x7E, 0xF5, 0x1E, 0x00, 0xB0, 0xF6, 0xDC, 0x6B, + 0x19, 0x19, 0xAC, 0x70, 0xC3, 0xF5, 0x7F, 0xFB, 0xD2, 0x75, 0xEF, 0xB9, 0x6C, 0x3A, 0x36, 0xF6, + 0x92, 0xE9, 0xE9, 0x6A, 0x36, 0x6C, 0xB6, 0xDA, 0xFD, 0xC3, 0x64, 0xEA, 0x13, 0x8A, 0xD8, 0x08, + 0x1E, 0x79, 0x66, 0x27, 0xE3, 0x47, 0xA6, 0x59, 0x35, 0x3A, 0xC2, 0xA7, 0x6E, 0xBE, 0x9B, 0xEF, + 0x6D, 0x7E, 0x0E, 0xEB, 0xF5, 0x20, 0xFD, 0x22, 0x42, 0xFA, 0xB4, 0x5B, 0x54, 0x9D, 0x95, 0xC8, + 0xAB, 0x88, 0xEF, 0x76, 0x43, 0x03, 0xE7, 0xF0, 0xA4, 0xA0, 0x94, 0xF3, 0x18, 0x28, 0x65, 0x29, + 0x67, 0x3D, 0x3C, 0xE1, 0x10, 0x2E, 0xB1, 0xBA, 0xB0, 0x06, 0xE9, 0x0C, 0xA5, 0x5C, 0xC0, 0x8A, + 0x91, 0x7E, 0xBD, 0x72, 0xD9, 0xC0, 0x67, 0x2F, 0xD9, 0xB4, 0xE6, 0x4B, 0xAF, 0x5B, 0x3B, 0x60, + 0x9A, 0x91, 0xE6, 0xBA, 0x8B, 0x4E, 0x5D, 0x14, 0xE3, 0xCB, 0x12, 0xF0, 0x82, 0x38, 0x95, 0xB7, + 0x9F, 0xBF, 0x9E, 0xF3, 0xAF, 0x3C, 0x9B, 0x2B, 0xCE, 0x3B, 0xF5, 0xB9, 0x83, 0x93, 0x73, 0x26, + 0x36, 0xF6, 0xDC, 0xD9, 0xD9, 0xAA, 0x1F, 0x85, 0x61, 0x92, 0x14, 0xD3, 0x82, 0x45, 0x08, 0x09, + 0xD2, 0x63, 0xFF, 0xA1, 0x59, 0xEE, 0x7D, 0x78, 0x3B, 0x7B, 0x0F, 0xD7, 0xF1, 0x82, 0x12, 0xB2, + 0x93, 0xE8, 0x5C, 0x32, 0x5D, 0x39, 0x9B, 0x36, 0x57, 0xEC, 0xCB, 0x82, 0x4F, 0x4A, 0x59, 0x87, + 0xC4, 0x91, 0xF5, 0x25, 0x3D, 0xF9, 0xC4, 0xD5, 0x4B, 0x59, 0x2F, 0x59, 0x66, 0xBB, 0x04, 0xB4, + 0xE8, 0x80, 0xB7, 0x14, 0xB2, 0x3E, 0xA3, 0xCB, 0xFA, 0xDD, 0xE8, 0xB2, 0xFE, 0x7F, 0x1E, 0xEA, + 0x2F, 0xFF, 0x8D, 0xD1, 0xB6, 0xFE, 0xF4, 0xCE, 0x43, 0x7C, 0xF2, 0x5F, 0x1E, 0x60, 0xE4, 0x8C, + 0xB7, 0x52, 0x5C, 0x77, 0x19, 0xB3, 0xCF, 0xFE, 0xF8, 0xD5, 0x11, 0xD0, 0x73, 0xE5, 0x27, 0x31, + 0xD6, 0x32, 0x35, 0x53, 0xE7, 0xC7, 0x8F, 0xEF, 0xE2, 0xE3, 0xFF, 0xE1, 0x02, 0xBB, 0x7D, 0xFF, + 0xF4, 0x93, 0xBE, 0x92, 0xBE, 0xC5, 0x9D, 0x3D, 0x3B, 0x57, 0xF3, 0xA2, 0x56, 0x88, 0xB3, 0xA6, + 0xCB, 0xAA, 0x02, 0x21, 0x14, 0x0E, 0x0F, 0xA9, 0x32, 0x20, 0xD2, 0x32, 0xA3, 0x03, 0xD6, 0x76, + 0x48, 0xC0, 0x76, 0xC5, 0x73, 0x97, 0xE0, 0x2C, 0x12, 0x4B, 0xA0, 0x24, 0xC5, 0xAC, 0x47, 0x6F, + 0x21, 0xA0, 0x27, 0x1F, 0x90, 0x0B, 0x54, 0x62, 0x71, 0x6B, 0xBB, 0xC0, 0x5B, 0xB0, 0x1A, 0x89, + 0xA3, 0x90, 0xF5, 0x59, 0xBE, 0xB4, 0x8F, 0xE5, 0x4B, 0xFB, 0xEF, 0x40, 0x79, 0x37, 0x7E, 0xF4, + 0x8F, 0x2E, 0x3C, 0xFC, 0xC3, 0x83, 0x23, 0xF2, 0xF1, 0xE7, 0xC7, 0xC8, 0x67, 0x7C, 0x96, 0x0F, + 0x94, 0x78, 0xF1, 0xE0, 0x2C, 0x76, 0xF4, 0x42, 0xEC, 0x9E, 0xFB, 0x5F, 0x3E, 0x07, 0x8C, 0xBC, + 0xFD, 0xBF, 0x13, 0xC6, 0x86, 0xD8, 0x58, 0x02, 0x4F, 0x89, 0x30, 0xD2, 0x38, 0x10, 0xD5, 0x47, + 0x76, 0x8A, 0xF7, 0x7F, 0xFC, 0xBA, 0x12, 0x71, 0xF4, 0xD1, 0x67, 0x77, 0xEC, 0xFB, 0x4F, 0xDB, + 0x9F, 0x7B, 0x31, 0x37, 0x3B, 0x53, 0x4D, 0x16, 0x22, 0x52, 0xA5, 0x9B, 0x27, 0x5D, 0x67, 0xA9, + 0x40, 0x76, 0x6F, 0xA9, 0xB5, 0x5B, 0xEA, 0x47, 0x37, 0x58, 0x45, 0x5A, 0x40, 0x29, 0x25, 0xF1, + 0x3D, 0x45, 0x26, 0x50, 0x64, 0x03, 0x8F, 0xC0, 0x53, 0x28, 0x99, 0x36, 0x4D, 0xD2, 0x90, 0x11, + 0x38, 0x84, 0x73, 0x08, 0x12, 0x42, 0x85, 0xB3, 0x28, 0x01, 0xC5, 0x7C, 0x86, 0x91, 0xA5, 0x03, + 0x6E, 0xC9, 0x70, 0xDF, 0x9D, 0x73, 0x4D, 0x7D, 0xE3, 0x97, 0xBF, 0x76, 0xFF, 0xDE, 0xE2, 0x09, + 0x03, 0x90, 0x2C, 0x24, 0xAC, 0x00, 0x2B, 0xA5, 0x64, 0x76, 0xAE, 0xE1, 0xCE, 0x58, 0xBF, 0x9C, + 0xFE, 0x9E, 0x1C, 0xF7, 0x7E, 0xF6, 0xBD, 0xC7, 0xF7, 0x80, 0x81, 0x8D, 0x57, 0xB2, 0xB4, 0xAF, + 0xC8, 0x4C, 0x2D, 0x14, 0xAD, 0x48, 0x0B, 0x92, 0xE9, 0xD2, 0x0B, 0x46, 0xFA, 0x82, 0xCD, 0xCF, + 0xEC, 0xC5, 0xCF, 0x66, 0x9F, 0x3A, 0x69, 0xC5, 0x60, 0x54, 0x2C, 0x64, 0x4F, 0x0B, 0xC3, 0x28, + 0x17, 0xB6, 0x42, 0x9C, 0xD1, 0x47, 0x2D, 0x6B, 0xDB, 0x96, 0xB2, 0x88, 0xD4, 0xE5, 0x85, 0x4B, + 0xF6, 0x18, 0x14, 0xC9, 0xE3, 0x6C, 0x81, 0x92, 0xE4, 0x03, 0x45, 0x21, 0xA3, 0x28, 0xE5, 0x7C, + 0xCA, 0x39, 0x9F, 0x52, 0xC6, 0x23, 0xEB, 0x2B, 0x7C, 0x49, 0xBA, 0x1F, 0x69, 0x13, 0x4B, 0xBB, + 0x64, 0x5E, 0x17, 0xCE, 0x20, 0xAC, 0xEE, 0xC4, 0x7B, 0x20, 0x05, 0xBD, 0xE5, 0x02, 0xA3, 0xCB, + 0x06, 0xA3, 0x9E, 0x4A, 0xE9, 0xDB, 0x5B, 0xF6, 0x4C, 0xFE, 0xFD, 0x6D, 0x3F, 0x7F, 0xF6, 0x48, + 0x71, 0xA0, 0x94, 0xCE, 0xB1, 0x47, 0x0D, 0x6C, 0xAD, 0x25, 0x97, 0x0B, 0xB8, 0xEA, 0x9C, 0x93, + 0x68, 0x86, 0x9A, 0x0F, 0xDF, 0xF8, 0x5F, 0xB8, 0xEB, 0xFF, 0xDC, 0xB4, 0x88, 0x07, 0x9C, 0xFF, + 0x31, 0x0A, 0xD9, 0x00, 0x29, 0x05, 0xCE, 0x39, 0x91, 0xEA, 0xAC, 0x00, 0x1F, 0xC8, 0x00, 0x39, + 0x6D, 0x6C, 0xA6, 0x98, 0xCF, 0xE4, 0x2F, 0xDA, 0xB8, 0xFC, 0x2A, 0x11, 0x87, 0x37, 0xEC, 0xDD, + 0x3B, 0xBE, 0x6A, 0x7C, 0x7C, 0x82, 0x66, 0xB3, 0x99, 0xF6, 0x03, 0x12, 0xEB, 0x0B, 0x25, 0x91, + 0x4A, 0xCD, 0x93, 0xF6, 0x66, 0x87, 0x52, 0xE9, 0x76, 0x7B, 0xBB, 0x84, 0xEE, 0xB4, 0xC8, 0x44, + 0x47, 0x73, 0x21, 0xDA, 0x0F, 0x45, 0xBA, 0xA4, 0x35, 0x8F, 0x43, 0xE0, 0x50, 0x02, 0xB2, 0xD9, + 0x80, 0x81, 0xBE, 0x1E, 0x06, 0x06, 0x7B, 0xA7, 0x5B, 0x56, 0xDE, 0xF6, 0xC0, 0xD6, 0x03, 0xDF, + 0x7A, 0x69, 0xB2, 0x36, 0xE3, 0x7B, 0x32, 0x22, 0xF9, 0xEF, 0x93, 0x56, 0x7A, 0x0E, 0x81, 0x18, + 0xD0, 0x4A, 0x0A, 0x7B, 0xCE, 0xA9, 0xA3, 0xEE, 0x47, 0x9F, 0xF9, 0xA6, 0xBB, 0xEB, 0xA1, 0xCF, + 0x72, 0xF5, 0xB9, 0x27, 0x2F, 0xE2, 0x01, 0xA3, 0x17, 0x12, 0xCF, 0x35, 0x50, 0x59, 0x5F, 0xC8, + 0x64, 0x1D, 0xAB, 0x80, 0x00, 0xC8, 0x02, 0x45, 0xA0, 0x2C, 0xA5, 0xE8, 0x8D, 0xB5, 0xED, 0xDB, + 0x31, 0x36, 0x3D, 0xE3, 0x67, 0x33, 0x2F, 0xAE, 0x1C, 0x19, 0x2C, 0xF4, 0xF5, 0x14, 0x87, 0x04, + 0x78, 0xCE, 0x18, 0x04, 0x16, 0x25, 0x93, 0xAC, 0xED, 0x49, 0x50, 0x42, 0xA0, 0x64, 0xD2, 0x29, + 0x92, 0x24, 0x22, 0x52, 0x0B, 0xCB, 0xD4, 0xA5, 0x85, 0x33, 0xF3, 0x2C, 0x9E, 0x48, 0x12, 0xE7, + 0xC2, 0x26, 0xF7, 0x94, 0x58, 0xB2, 0xBE, 0x47, 0x6F, 0xA5, 0xC8, 0xB2, 0xA5, 0x03, 0xA6, 0x50, + 0x2E, 0xBD, 0xB0, 0xF3, 0x70, 0xED, 0xF6, 0x9F, 0x3D, 0xBD, 0xEF, 0xF1, 0x5A, 0x33, 0xCA, 0x78, + 0x4A, 0x16, 0x52, 0x23, 0xB5, 0x9F, 0x96, 0x4A, 0xD8, 0x4B, 0x43, 0xC1, 0x5A, 0xE7, 0xC2, 0x48, + 0xBB, 0xBF, 0xFC, 0xE8, 0x3B, 0xF9, 0xE5, 0x96, 0xFD, 0x3C, 0x75, 0xDF, 0xAD, 0xC7, 0x12, 0x50, + 0x38, 0xF9, 0xCD, 0x54, 0x7A, 0x8B, 0x44, 0xDA, 0x08, 0x29, 0x84, 0x24, 0x59, 0x30, 0x05, 0x40, + 0x1E, 0x28, 0x03, 0xBD, 0x40, 0xBF, 0x10, 0x0C, 0x48, 0x21, 0x06, 0x0F, 0x4D, 0x37, 0xBC, 0x03, + 0x53, 0x8D, 0x03, 0x95, 0x9E, 0xE2, 0xDC, 0x8A, 0x65, 0x03, 0xA5, 0x9E, 0x52, 0xBE, 0x20, 0x85, + 0x94, 0xAE, 0xAB, 0x7A, 0x4B, 0x2C, 0x67, 0x3B, 0xC0, 0x65, 0x1A, 0xCB, 0x12, 0xDB, 0x05, 0xD6, + 0xCE, 0x07, 0x9E, 0x82, 0x97, 0x24, 0x44, 0x66, 0x03, 0x9F, 0xDE, 0x9E, 0x22, 0x4B, 0x87, 0xFB, + 0xE9, 0x1B, 0xE8, 0x9D, 0x3E, 0xDC, 0x30, 0x8F, 0x6D, 0x7E, 0xEE, 0xE0, 0x43, 0xBB, 0xC6, 0x67, + 0x66, 0x85, 0xA0, 0x24, 0x84, 0x28, 0xA4, 0x46, 0x0A, 0xBA, 0x42, 0xDB, 0x92, 0xF4, 0xD0, 0x34, + 0x60, 0x85, 0x10, 0xB6, 0x15, 0x6A, 0xFA, 0x4A, 0x39, 0xB7, 0xEB, 0xC0, 0x24, 0xFB, 0x1E, 0xBF, + 0xEB, 0x58, 0x02, 0xD6, 0x5F, 0x70, 0x1D, 0x2B, 0x86, 0x7B, 0x38, 0x3C, 0x5D, 0x97, 0x2E, 0x8D, + 0xFD, 0x94, 0xD5, 0x36, 0x01, 0x15, 0xA0, 0xAF, 0x2D, 0x52, 0x88, 0x5E, 0xAD, 0x6D, 0x79, 0x7C, + 0xAA, 0xD6, 0x3C, 0x52, 0x8B, 0x0F, 0xF6, 0xF4, 0x94, 0x1A, 0xCB, 0x96, 0xF4, 0x65, 0x06, 0x7A, + 0xCB, 0x99, 0x6C, 0x36, 0x90, 0x2A, 0xDD, 0x5D, 0x92, 0x0B, 0xAC, 0xDF, 0x26, 0xA1, 0x9D, 0xD4, + 0xDA, 0x16, 0x4E, 0xBC, 0x24, 0x79, 0x04, 0x37, 0x1B, 0xF8, 0x14, 0x8B, 0x39, 0x06, 0xFA, 0x7A, + 0x18, 0x1E, 0xEE, 0xB7, 0xA5, 0x4A, 0xCF, 0xDC, 0x74, 0xC4, 0xCE, 0x27, 0x76, 0x4F, 0x3E, 0xB3, + 0x6D, 0xEF, 0xE4, 0xC1, 0x30, 0xD2, 0x9E, 0x94, 0x22, 0x9F, 0xEA, 0x17, 0xA4, 0xBA, 0xB6, 0x9F, + 0x59, 0x35, 0xA9, 0xEB, 0x47, 0xED, 0x10, 0x20, 0xE9, 0x9C, 0xB9, 0xB1, 0x23, 0x73, 0xEE, 0xE0, + 0x74, 0x83, 0xE6, 0x0B, 0xF7, 0x1D, 0xBB, 0x1C, 0x56, 0x69, 0x5C, 0x2E, 0xD8, 0x67, 0x6C, 0x27, + 0x42, 0x95, 0x0E, 0xE2, 0xA7, 0x03, 0x06, 0x40, 0x46, 0x08, 0x32, 0x02, 0x91, 0x99, 0xA9, 0x35, + 0x79, 0xF4, 0x85, 0xE6, 0xDE, 0x52, 0x3E, 0x33, 0x31, 0x3A, 0x50, 0x1C, 0x58, 0x32, 0xB4, 0x64, + 0xC9, 0xE0, 0x12, 0xD7, 0x6F, 0xA2, 0xB0, 0xD0, 0x6A, 0xB6, 0xBC, 0x56, 0x2B, 0x24, 0x8A, 0x22, + 0x74, 0x6C, 0xB0, 0xF6, 0x68, 0x67, 0x56, 0x4A, 0x81, 0x54, 0x12, 0xDF, 0xF3, 0x08, 0x02, 0x9F, + 0x4C, 0x26, 0x20, 0x9B, 0xCD, 0x90, 0xCB, 0x65, 0x8D, 0xF4, 0xFD, 0x56, 0xD3, 0x30, 0xB3, 0x6F, + 0xA6, 0x75, 0x68, 0xCF, 0xC4, 0xF4, 0x91, 0xA9, 0xB9, 0x56, 0xDD, 0xE1, 0xAC, 0x14, 0x22, 0x07, + 0x22, 0x4E, 0xC1, 0xB5, 0x5D, 0x3D, 0xEE, 0xD2, 0xCB, 0x4B, 0xF5, 0x95, 0xA9, 0x74, 0xF2, 0x9D, + 0x36, 0x4E, 0xD8, 0x74, 0xBD, 0x7E, 0x0C, 0x01, 0xA6, 0xF3, 0x9C, 0xCE, 0xBC, 0x8F, 0xDB, 0x71, + 0xD4, 0xCD, 0x6A, 0x98, 0x4A, 0x7B, 0x5F, 0xDA, 0x09, 0x21, 0xAC, 0x00, 0xAF, 0xD6, 0x88, 0xEC, + 0xB6, 0xBD, 0x93, 0x8D, 0xE7, 0x95, 0x1C, 0xAB, 0x14, 0x32, 0xB9, 0xC1, 0x9E, 0x5C, 0xB9, 0xBF, + 0x58, 0xAE, 0x94, 0xCB, 0xB2, 0xE4, 0x4B, 0xF2, 0x9E, 0x20, 0x27, 0x70, 0x7E, 0xB2, 0xA9, 0x97, + 0xF4, 0x4B, 0xA4, 0x94, 0x0E, 0x21, 0x63, 0xED, 0x68, 0xC5, 0x96, 0x66, 0x2B, 0xB6, 0xF5, 0xF1, + 0xE9, 0x70, 0xF6, 0xD0, 0xCC, 0xDC, 0xDC, 0x74, 0xAD, 0xD5, 0x88, 0x62, 0xA3, 0x11, 0x38, 0x29, + 0x84, 0x15, 0x49, 0x73, 0xBC, 0xAD, 0x4B, 0x9C, 0xEA, 0xD1, 0xEA, 0xD2, 0xA9, 0x93, 0xF8, 0xDA, + 0xF1, 0xDF, 0x6D, 0xCE, 0xC0, 0x57, 0xAE, 0xFD, 0xF6, 0x18, 0x02, 0x76, 0x8D, 0x4F, 0x93, 0xCF, + 0xD4, 0x88, 0x8D, 0x71, 0x4A, 0xCA, 0x36, 0x70, 0x9D, 0x82, 0x6E, 0x74, 0x25, 0x19, 0xD2, 0x41, + 0x9A, 0x69, 0xEC, 0x65, 0xD3, 0xCF, 0x93, 0xC7, 0x78, 0x84, 0xF0, 0x9C, 0x73, 0x72, 0xAA, 0xDA, + 0x94, 0x47, 0xE6, 0x9A, 0x07, 0x85, 0x40, 0x7A, 0x4A, 0xAA, 0x8C, 0xEF, 0x79, 0xB9, 0x8C, 0xE7, + 0x67, 0x7D, 0x15, 0x28, 0x21, 0x54, 0xBA, 0x45, 0xE3, 0xAC, 0xC5, 0x46, 0xDA, 0xE8, 0x46, 0x18, + 0xC7, 0xAD, 0xC8, 0xC4, 0xDA, 0x58, 0x6B, 0x9D, 0xB3, 0x49, 0x57, 0x5E, 0x38, 0x29, 0x85, 0x65, + 0x7E, 0x4C, 0xEB, 0x2E, 0xBD, 0xDA, 0x04, 0x34, 0x80, 0x2A, 0x30, 0x9B, 0x9E, 0x1B, 0xE9, 0x77, + 0x6D, 0x22, 0x9C, 0xA7, 0x04, 0x6F, 0x39, 0x7B, 0x2D, 0xBB, 0xC7, 0xA6, 0xF8, 0xE9, 0x62, 0x04, + 0xD4, 0x1B, 0x21, 0xF5, 0x23, 0x73, 0xE4, 0xFA, 0x8A, 0xDD, 0x96, 0x6F, 0x03, 0x6D, 0x67, 0x56, + 0x9D, 0xBE, 0xAF, 0x02, 0xB9, 0x14, 0x7C, 0x9B, 0x98, 0xB6, 0x78, 0x80, 0x12, 0x42, 0x28, 0x95, + 0xFC, 0xC3, 0x98, 0xB4, 0xD6, 0xC9, 0x46, 0x2B, 0x16, 0xF5, 0x56, 0x24, 0xE9, 0xD8, 0xE0, 0xA8, + 0x6B, 0x0A, 0x91, 0xB4, 0xD4, 0x84, 0x48, 0xB6, 0x23, 0x94, 0xE8, 0x80, 0xEE, 0x06, 0xDF, 0x4D, + 0x40, 0xDB, 0x1B, 0x23, 0x8E, 0x4E, 0x7B, 0x0D, 0xA0, 0x96, 0xEA, 0x56, 0x4D, 0x3F, 0x8B, 0x01, + 0xE3, 0x9C, 0x73, 0xC3, 0xBD, 0x25, 0xF7, 0xBA, 0x93, 0x96, 0x52, 0xC8, 0x07, 0x8B, 0x13, 0x80, + 0x10, 0xE4, 0xFB, 0x4B, 0x48, 0x21, 0x3A, 0x2D, 0xC0, 0x54, 0xC9, 0xB0, 0x2B, 0xB9, 0x84, 0xE9, + 0x20, 0x6D, 0xCB, 0xB7, 0xE3, 0xAE, 0x1B, 0x7C, 0x3B, 0x06, 0xDB, 0x71, 0xA8, 0x20, 0x9D, 0xF2, + 0x11, 0xB2, 0xB3, 0x39, 0x37, 0x9F, 0x04, 0xD7, 0x75, 0xB6, 0x5D, 0xE7, 0xE3, 0x59, 0x7F, 0x31, + 0x12, 0x42, 0xE6, 0xD7, 0x01, 0xED, 0x24, 0x68, 0x00, 0xE7, 0xFB, 0xCA, 0x7D, 0xE0, 0xBA, 0x73, + 0x78, 0x70, 0xCB, 0x5E, 0x3E, 0xB7, 0x28, 0x01, 0x0F, 0x7E, 0x02, 0xF9, 0xE6, 0x4F, 0x2C, 0x8C, + 0x7F, 0xDD, 0xA5, 0x8C, 0x4E, 0x6F, 0xEE, 0x2F, 0x22, 0x0B, 0x81, 0x77, 0x13, 0xD0, 0x9D, 0x8C, + 0xDA, 0x49, 0xF5, 0x78, 0xC7, 0xF1, 0x08, 0x68, 0x8F, 0x6F, 0xBA, 0xA4, 0x1D, 0xEB, 0x71, 0x97, + 0x44, 0x5D, 0x9F, 0xB5, 0xAF, 0x77, 0x80, 0xDB, 0xB6, 0x65, 0x3F, 0x1B, 0xFE, 0xE8, 0xF3, 0x8C, + 0x4D, 0xCC, 0xC1, 0xA2, 0x04, 0x1C, 0xAB, 0x48, 0xFB, 0xDC, 0x4D, 0x40, 0xDC, 0x65, 0xD5, 0xC5, + 0xC0, 0x76, 0xBF, 0x6E, 0x17, 0x53, 0x62, 0x81, 0xBC, 0x12, 0x01, 0xDD, 0x63, 0x2E, 0x46, 0x84, + 0x59, 0x40, 0x48, 0x77, 0x88, 0x98, 0x45, 0xAE, 0x47, 0x08, 0xE1, 0x0A, 0x03, 0x45, 0x76, 0x8D, + 0x4D, 0x71, 0xFD, 0x25, 0x1B, 0xE7, 0xB9, 0xDE, 0x31, 0x47, 0x71, 0xBE, 0x17, 0x74, 0x5F, 0xDB, + 0x0D, 0xA0, 0xFB, 0xB5, 0x5C, 0xE4, 0xBB, 0xEE, 0xCF, 0xBA, 0x85, 0x45, 0xCE, 0x0B, 0x09, 0x5F, + 0x48, 0xC4, 0x42, 0x42, 0x16, 0x92, 0xB3, 0xF0, 0xBC, 0xF0, 0xF7, 0x9D, 0xA3, 0x76, 0xEF, 0xC7, + 0x8E, 0x01, 0xF5, 0x6A, 0x49, 0x58, 0x4C, 0xF1, 0x85, 0xC4, 0x74, 0xBF, 0x7E, 0x25, 0xC0, 0xAF, + 0x74, 0x1C, 0x8F, 0x90, 0xC5, 0xC8, 0xE1, 0x65, 0xCE, 0x8B, 0x82, 0x07, 0xF8, 0xBF, 0xBC, 0x7A, + 0x38, 0x97, 0x7C, 0xD1, 0xFC, 0xA1, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, + 0x74, 0x65, 0x3A, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x32, 0x30, 0x2D, 0x30, + 0x33, 0x2D, 0x31, 0x39, 0x54, 0x31, 0x30, 0x3A, 0x35, 0x30, 0x3A, 0x35, 0x38, 0x2B, 0x30, 0x30, + 0x3A, 0x30, 0x30, 0x62, 0x40, 0x28, 0xF1, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, + 0x61, 0x74, 0x65, 0x3A, 0x6D, 0x6F, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x39, 0x2D, + 0x30, 0x31, 0x2D, 0x30, 0x38, 0x54, 0x31, 0x35, 0x3A, 0x35, 0x34, 0x3A, 0x32, 0x33, 0x2B, 0x30, + 0x30, 0x3A, 0x30, 0x30, 0x8A, 0xEF, 0xF9, 0x19, 0x00, 0x00, 0x00, 0x20, 0x74, 0x45, 0x58, 0x74, + 0x73, 0x6F, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x00, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3A, 0x2F, + 0x2F, 0x69, 0x6D, 0x61, 0x67, 0x65, 0x6D, 0x61, 0x67, 0x69, 0x63, 0x6B, 0x2E, 0x6F, 0x72, 0x67, + 0xBC, 0xCF, 0x1D, 0x9D, 0x00, 0x00, 0x00, 0x18, 0x74, 0x45, 0x58, 0x74, 0x54, 0x68, 0x75, 0x6D, + 0x62, 0x3A, 0x3A, 0x44, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3A, 0x3A, 0x50, 0x61, 0x67, + 0x65, 0x73, 0x00, 0x31, 0xA7, 0xFF, 0xBB, 0x2F, 0x00, 0x00, 0x00, 0x18, 0x74, 0x45, 0x58, 0x74, + 0x54, 0x68, 0x75, 0x6D, 0x62, 0x3A, 0x3A, 0x49, 0x6D, 0x61, 0x67, 0x65, 0x3A, 0x3A, 0x48, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x00, 0x31, 0x32, 0x38, 0x43, 0x7C, 0x41, 0x80, 0x00, 0x00, 0x00, 0x17, + 0x74, 0x45, 0x58, 0x74, 0x54, 0x68, 0x75, 0x6D, 0x62, 0x3A, 0x3A, 0x49, 0x6D, 0x61, 0x67, 0x65, + 0x3A, 0x3A, 0x57, 0x69, 0x64, 0x74, 0x68, 0x00, 0x31, 0x32, 0x38, 0xD0, 0x8D, 0x11, 0xDD, 0x00, + 0x00, 0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x54, 0x68, 0x75, 0x6D, 0x62, 0x3A, 0x3A, 0x4D, 0x69, + 0x6D, 0x65, 0x74, 0x79, 0x70, 0x65, 0x00, 0x69, 0x6D, 0x61, 0x67, 0x65, 0x2F, 0x70, 0x6E, 0x67, + 0x3F, 0xB2, 0x56, 0x4E, 0x00, 0x00, 0x00, 0x17, 0x74, 0x45, 0x58, 0x74, 0x54, 0x68, 0x75, 0x6D, + 0x62, 0x3A, 0x3A, 0x4D, 0x54, 0x69, 0x6D, 0x65, 0x00, 0x31, 0x35, 0x34, 0x36, 0x39, 0x36, 0x32, + 0x38, 0x36, 0x33, 0x1F, 0x1E, 0xB3, 0x01, 0x00, 0x00, 0x00, 0x12, 0x74, 0x45, 0x58, 0x74, 0x54, + 0x68, 0x75, 0x6D, 0x62, 0x3A, 0x3A, 0x53, 0x69, 0x7A, 0x65, 0x00, 0x31, 0x39, 0x32, 0x37, 0x34, + 0x42, 0x0A, 0x19, 0xAB, 0x42, 0x00, 0x00, 0x00, 0x56, 0x74, 0x45, 0x58, 0x74, 0x54, 0x68, 0x75, + 0x6D, 0x62, 0x3A, 0x3A, 0x55, 0x52, 0x49, 0x00, 0x66, 0x69, 0x6C, 0x65, 0x3A, 0x2F, 0x2F, 0x2F, + 0x64, 0x61, 0x74, 0x61, 0x2F, 0x77, 0x77, 0x77, 0x72, 0x6F, 0x6F, 0x74, 0x2F, 0x77, 0x77, 0x77, + 0x2E, 0x65, 0x61, 0x73, 0x79, 0x69, 0x63, 0x6F, 0x6E, 0x2E, 0x6E, 0x65, 0x74, 0x2F, 0x63, 0x64, + 0x6E, 0x2D, 0x69, 0x6D, 0x67, 0x2E, 0x65, 0x61, 0x73, 0x79, 0x69, 0x63, 0x6F, 0x6E, 0x2E, 0x63, + 0x6E, 0x2F, 0x66, 0x69, 0x6C, 0x65, 0x73, 0x2F, 0x32, 0x2F, 0x32, 0x39, 0x31, 0x36, 0x35, 0x2E, + 0x70, 0x6E, 0x67, 0xBF, 0x98, 0x5F, 0xE5, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, + 0x42, 0x60, 0x82 +}; + +void *get_window_icon_raw_data(int *len) +{ + *len = (int)sizeof(window_icon_hexData); + return window_icon_hexData; +} + diff --git a/LinuxGUI/Ventoy2Disk/Web/ventoy_http.c b/LinuxGUI/Ventoy2Disk/Web/ventoy_http.c new file mode 100644 index 0000000..88f0e95 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Web/ventoy_http.c @@ -0,0 +1,1700 @@ +/****************************************************************************** + * ventoy_http.c ---- ventoy http + * Copyright (c) 2021, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "fat_filelib.h" + +static char *g_pub_out_buf = NULL; +static int g_pub_out_max = 0; + +static pthread_mutex_t g_api_mutex; +static char g_cur_language[128]; +static int g_cur_part_style = 0; +static int g_cur_show_all = 0; +static char g_cur_server_token[64]; +static struct mg_context *g_ventoy_http_ctx = NULL; + +static uint32_t g_efi_part_offset = 0; +static uint8_t *g_efi_part_raw_img = NULL; +static uint8_t *g_grub_stg1_raw_img = NULL; + +static char g_cur_process_diskname[64]; +static char g_cur_process_type[64]; +static volatile int g_cur_process_result = 0; +static volatile PROGRESS_POINT g_current_progress = PT_FINISH; + +static int ventoy_load_mbr_template(void) +{ + FILE *fp = NULL; + + fp = fopen("boot/boot.img", "rb"); + if (fp == NULL) + { + vlog("Failed to open file boot/boot.img\n"); + return 1; + } + + fread(g_mbr_template, 1, 512, fp); + fclose(fp); + + ventoy_gen_preudo_uuid(g_mbr_template + 0x180); + return 0; +} + +static int ventoy_disk_xz_flush(void *src, unsigned int size) +{ + memcpy(g_efi_part_raw_img + g_efi_part_offset, src, size); + g_efi_part_offset += size; + + g_current_progress = PT_LOAD_DISK_IMG + (g_efi_part_offset / SIZE_1MB); + return (int)size; +} + +static int ventoy_unxz_efipart_img(void) +{ + int rc; + int inlen; + int xzlen; + void *xzbuf = NULL; + uint8_t *buf = NULL; + + rc = ventoy_read_file_to_buf(VENTOY_FILE_DISK_IMG, 0, &xzbuf, &xzlen); + vdebug("read disk.img.xz rc:%d len:%d\n", rc, xzlen); + + if (g_efi_part_raw_img) + { + buf = g_efi_part_raw_img; + } + else + { + buf = malloc(VTOYEFI_PART_BYTES); + if (!buf) + { + check_free(xzbuf); + return 1; + } + } + + g_efi_part_offset = 0; + g_efi_part_raw_img = buf; + + rc = unxz(xzbuf, xzlen, NULL, ventoy_disk_xz_flush, buf, &inlen, NULL); + vdebug("ventoy_unxz_efipart_img len:%d rc:%d unxzlen:%u\n", inlen, rc, g_efi_part_offset); + + check_free(xzbuf); + return 0; +} + +static int ventoy_unxz_stg1_img(void) +{ + int rc; + int inlen; + int xzlen; + void *xzbuf = NULL; + uint8_t *buf = NULL; + + rc = ventoy_read_file_to_buf(VENTOY_FILE_STG1_IMG, 0, &xzbuf, &xzlen); + vdebug("read core.img.xz rc:%d len:%d\n", rc, xzlen); + + if (g_grub_stg1_raw_img) + { + buf = g_grub_stg1_raw_img; + } + else + { + buf = zalloc(SIZE_1MB); + if (!buf) + { + check_free(xzbuf); + return 1; + } + } + + rc = unxz(xzbuf, xzlen, NULL, NULL, buf, &inlen, NULL); + vdebug("ventoy_unxz_stg1_img len:%d rc:%d\n", inlen, rc); + + g_grub_stg1_raw_img = buf; + + check_free(xzbuf); + return 0; +} + + +static int ventoy_http_save_cfg(void) +{ + FILE *fp; + + fp = fopen(g_ini_file, "w"); + if (!fp) + { + vlog("Failed to open %s code:%d\n", g_ini_file, errno); + return 0; + } + + fprintf(fp, "[Ventoy]\nLanguage=%s\nPartStyle=%d\nShowAllDevice=%d\n", + g_cur_language, g_cur_part_style, g_cur_show_all); + + fclose(fp); + return 0; +} + +static int ventoy_http_load_cfg(void) +{ + int i; + int len; + char line[256]; + FILE *fp; + + fp = fopen(g_ini_file, "r"); + if (!fp) + { + return 0; + } + + while (fgets(line, sizeof(line), fp)) + { + len = (int)strlen(line); + for (i = len - 1; i >= 0; i--) + { + if (line[i] == ' ' || line[i] == '\t' || line[i] == '\r' || line[i] == '\n') + { + line[i] = 0; + } + else + { + break; + } + } + + len = (int)strlen("Language="); + if (strncmp(line, "Language=", len) == 0) + { + scnprintf(g_cur_language, "%s", line + len); + } + else if (strncmp(line, "PartStyle=", strlen("PartStyle=")) == 0) + { + g_cur_part_style = (int)strtol(line + strlen("PartStyle="), NULL, 10); + } + else if (strncmp(line, "ShowAllDevice=", strlen("ShowAllDevice=")) == 0) + { + g_cur_show_all = (int)strtol(line + strlen("ShowAllDevice="), NULL, 10); + } + } + + fclose(fp); + return 0; +} + + +static int ventoy_json_result(struct mg_connection *conn, const char *err) +{ + if (conn) + { + mg_printf(conn, + "HTTP/1.1 200 OK \r\n" + "Content-Type: application/json\r\n" + "Content-Length: %d\r\n" + "\r\n%s", + (int)strlen(err), err); + } + else + { + memcpy(g_pub_out_buf, err, (int)strlen(err) + 1); + } + + return 0; +} + +static int ventoy_json_buffer(struct mg_connection *conn, const char *json_buf, int json_len) +{ + if (conn) + { + mg_printf(conn, + "HTTP/1.1 200 OK \r\n" + "Content-Type: application/json\r\n" + "Content-Length: %d\r\n" + "\r\n%s", + json_len, json_buf); + } + else + { + if (json_len >= g_pub_out_max) + { + vlog("json buffer overflow\n"); + } + else + { + memcpy(g_pub_out_buf, json_buf, json_len); + g_pub_out_buf[json_len] = 0; + } + } + + return 0; +} + +static int ventoy_api_sysinfo(struct mg_connection *conn, VTOY_JSON *json) +{ + int busy = 0; + int pos = 0; + int buflen = 0; + char buf[512]; + + (void)json; + + busy = (g_current_progress == PT_FINISH) ? 0 : 1; + + buflen = sizeof(buf) - 1; + VTOY_JSON_FMT_BEGIN(pos, buf, buflen); + VTOY_JSON_FMT_OBJ_BEGIN(); + VTOY_JSON_FMT_STRN("token", g_cur_server_token); + VTOY_JSON_FMT_STRN("language", g_cur_language); + VTOY_JSON_FMT_STRN("ventoy_ver", ventoy_get_local_version()); + VTOY_JSON_FMT_UINT("partstyle", g_cur_part_style); + VTOY_JSON_FMT_BOOL("busy", busy); + VTOY_JSON_FMT_STRN("process_disk", g_cur_process_diskname); + VTOY_JSON_FMT_STRN("process_type", g_cur_process_type); + VTOY_JSON_FMT_OBJ_END(); + VTOY_JSON_FMT_END(pos); + + ventoy_json_buffer(conn, buf, pos); + return 0; +} + +static int ventoy_api_get_percent(struct mg_connection *conn, VTOY_JSON *json) +{ + int pos = 0; + int buflen = 0; + int percent = 0; + char buf[128]; + + (void)json; + + percent = g_current_progress * 100 / PT_FINISH; + + buflen = sizeof(buf) - 1; + VTOY_JSON_FMT_BEGIN(pos, buf, buflen); + VTOY_JSON_FMT_OBJ_BEGIN(); + VTOY_JSON_FMT_STRN("result", g_cur_process_result ? "failed" : "success"); + VTOY_JSON_FMT_STRN("process_disk", g_cur_process_diskname); + VTOY_JSON_FMT_STRN("process_type", g_cur_process_type); + VTOY_JSON_FMT_UINT("percent", percent); + VTOY_JSON_FMT_OBJ_END(); + VTOY_JSON_FMT_END(pos); + + ventoy_json_buffer(conn, buf, pos); + return 0; +} + +static int ventoy_api_set_language(struct mg_connection *conn, VTOY_JSON *json) +{ + const char *lang = NULL; + + lang = vtoy_json_get_string_ex(json, "language"); + if (lang) + { + scnprintf(g_cur_language, "%s", lang); + ventoy_http_save_cfg(); + } + + ventoy_json_result(conn, VTOY_JSON_SUCCESS_RET); + return 0; +} + +static int ventoy_api_set_partstyle(struct mg_connection *conn, VTOY_JSON *json) +{ + int ret; + int style = 0; + + ret = vtoy_json_get_int(json, "partstyle", &style); + if (JSON_SUCCESS == ret) + { + if ((style == 0) || (style == 1)) + { + g_cur_part_style = style; + ventoy_http_save_cfg(); + } + } + + ventoy_json_result(conn, VTOY_JSON_SUCCESS_RET); + return 0; +} + +static int ventoy_clean_disk(int fd, uint64_t size) +{ + int zerolen; + ssize_t len; + off_t offset; + void *buf = NULL; + + vdebug("ventoy_clean_disk fd:%d size:%llu\n", fd, (_ull)size); + + zerolen = 64 * 1024; + buf = zalloc(zerolen); + if (!buf) + { + vlog("failed to alloc clean buffer\n"); + return 1; + } + + offset = lseek(fd, 0, SEEK_SET); + len = write(fd, buf, zerolen); + vdebug("write disk at off:%llu writelen:%lld datalen:%d\n", (_ull)offset, (_ll)len, zerolen); + + offset = lseek(fd, size - zerolen, SEEK_SET); + len = write(fd, buf, zerolen); + vdebug("write disk at off:%llu writelen:%lld datalen:%d\n", (_ull)offset, (_ll)len, zerolen); + + fsync(fd); + + free(buf); + return 0; +} + +static int ventoy_write_legacy_grub(int fd, int partstyle) +{ + ssize_t len; + off_t offset; + + if (partstyle) + { + vlog("Write GPT stage1 ...\n"); + + offset = lseek(fd, 512 * 34, SEEK_SET); + + g_grub_stg1_raw_img[500] = 35;//update blocklist + len = write(fd, g_grub_stg1_raw_img, SIZE_1MB - 512 * 34); + + vlog("lseek offset:%llu(%u) writelen:%llu(%u)\n", (_ull)offset, 512 * 34, (_ull)len, SIZE_1MB - 512 * 34); + if (SIZE_1MB - 512 * 34 != len) + { + vlog("write length error\n"); + return 1; + } + } + else + { + vlog("Write MBR stage1 ...\n"); + offset = lseek(fd, 512, SEEK_SET); + len = write(fd, g_grub_stg1_raw_img, SIZE_1MB - 512); + + vlog("lseek offset:%llu(%u) writelen:%llu(%u)\n", (_ull)offset, 512, (_ull)len, SIZE_1MB - 512); + if (SIZE_1MB - 512 != len) + { + vlog("write length error\n"); + return 1; + } + } + + return 0; +} + +static int VentoyFatMemRead(uint32 Sector, uint8 *Buffer, uint32 SectorCount) +{ + uint32 i; + uint32 offset; + + for (i = 0; i < SectorCount; i++) + { + offset = (Sector + i) * 512; + memcpy(Buffer + i * 512, g_efi_part_raw_img + offset, 512); + } + + return 1; +} + +static int VentoyFatMemWrite(uint32 Sector, uint8 *Buffer, uint32 SectorCount) +{ + uint32 i; + uint32 offset; + + for (i = 0; i < SectorCount; i++) + { + offset = (Sector + i) * 512; + memcpy(g_efi_part_raw_img + offset, Buffer + i * 512, 512); + } + + return 1; +} + +static int VentoyProcSecureBoot(int SecureBoot) +{ + int rc = 0; + int size; + char *filebuf = NULL; + void *file = NULL; + + vlog("VentoyProcSecureBoot %d ...\n", SecureBoot); + + if (SecureBoot) + { + vlog("Secure boot is enabled ...\n"); + return 0; + } + + fl_init(); + + if (0 == fl_attach_media(VentoyFatMemRead, VentoyFatMemWrite)) + { + file = fl_fopen("/EFI/BOOT/grubx64_real.efi", "rb"); + vlog("Open ventoy efi file %p \n", file); + if (file) + { + fl_fseek(file, 0, SEEK_END); + size = (int)fl_ftell(file); + fl_fseek(file, 0, SEEK_SET); + + vlog("ventoy efi file size %d ...\n", size); + + filebuf = (char *)malloc(size); + if (filebuf) + { + fl_fread(filebuf, 1, size, file); + } + + fl_fclose(file); + + vlog("Now delete all efi files ...\n"); + fl_remove("/EFI/BOOT/BOOTX64.EFI"); + fl_remove("/EFI/BOOT/grubx64.efi"); + fl_remove("/EFI/BOOT/grubx64_real.efi"); + fl_remove("/EFI/BOOT/MokManager.efi"); + fl_remove("/EFI/BOOT/mmx64.efi"); + fl_remove("/ENROLL_THIS_KEY_IN_MOKMANAGER.cer"); + + file = fl_fopen("/EFI/BOOT/BOOTX64.EFI", "wb"); + vlog("Open bootx64 efi file %p \n", file); + if (file) + { + if (filebuf) + { + fl_fwrite(filebuf, 1, size, file); + } + + fl_fflush(file); + fl_fclose(file); + } + + if (filebuf) + { + free(filebuf); + } + } + + file = fl_fopen("/EFI/BOOT/grubia32_real.efi", "rb"); + vlog("Open ventoy efi file %p\n", file); + if (file) + { + fl_fseek(file, 0, SEEK_END); + size = (int)fl_ftell(file); + fl_fseek(file, 0, SEEK_SET); + + vlog("ventoy efi file size %d ...\n", size); + + filebuf = (char *)malloc(size); + if (filebuf) + { + fl_fread(filebuf, 1, size, file); + } + + fl_fclose(file); + + vlog("Now delete all efi files ...\n"); + fl_remove("/EFI/BOOT/BOOTIA32.EFI"); + fl_remove("/EFI/BOOT/grubia32.efi"); + fl_remove("/EFI/BOOT/grubia32_real.efi"); + fl_remove("/EFI/BOOT/mmia32.efi"); + + file = fl_fopen("/EFI/BOOT/BOOTIA32.EFI", "wb"); + vlog("Open bootia32 efi file %p\n", file); + if (file) + { + if (filebuf) + { + fl_fwrite(filebuf, 1, size, file); + } + + fl_fflush(file); + fl_fclose(file); + } + + if (filebuf) + { + free(filebuf); + } + } + + } + else + { + rc = 1; + } + + fl_shutdown(); + + return rc; +} + +static int ventoy_check_efi_part_data(int fd, uint64_t offset) +{ + int i; + ssize_t len; + char *buf; + + buf = malloc(SIZE_1MB); + if (!buf) + { + return 0; + } + + lseek(fd, offset, SEEK_SET); + for (i = 0; i < 32; i++) + { + len = read(fd, buf, SIZE_1MB); + if (len != SIZE_1MB || memcmp(buf, g_efi_part_raw_img + i * SIZE_1MB, SIZE_1MB)) + { + vlog("part2 data check failed i=%d len:%llu\n", i, (_ull)len); + return 1; + } + + g_current_progress = PT_CHECK_PART2 + (i / 4); + } + + return 0; +} + +static int ventoy_write_efipart(int fd, uint64_t offset, uint32_t secureboot) +{ + int i; + ssize_t len; + + vlog("Formatting part2 EFI offset:%llu ...\n", (_ull)offset); + lseek(fd, offset, SEEK_SET); + + VentoyProcSecureBoot((int)secureboot); + + g_current_progress = PT_WRITE_VENTOY_START; + for (i = 0; i < 32; i++) + { + len = write(fd, g_efi_part_raw_img + i * SIZE_1MB, SIZE_1MB); + vlog("write disk writelen:%lld datalen:%d [ %s ]\n", + (_ll)len, SIZE_1MB, (len == SIZE_1MB) ? "success" : "failed"); + + if (len != SIZE_1MB) + { + vlog("failed to format part2 EFI\n"); + return 1; + } + + g_current_progress = PT_WRITE_VENTOY_START + i / 4; + } + + return 0; +} + +static int VentoyFillBackupGptHead(VTOY_GPT_INFO *pInfo, VTOY_GPT_HDR *pHead) +{ + uint64_t LBA; + uint64_t BackupLBA; + + memcpy(pHead, &pInfo->Head, sizeof(VTOY_GPT_HDR)); + + LBA = pHead->EfiStartLBA; + BackupLBA = pHead->EfiBackupLBA; + + pHead->EfiStartLBA = BackupLBA; + pHead->EfiBackupLBA = LBA; + pHead->PartTblStartLBA = BackupLBA + 1 - 33; + + pHead->Crc = 0; + pHead->Crc = ventoy_crc32(pHead, pHead->Length); + + return 0; +} + +static int ventoy_write_gpt_part_table(int fd, uint64_t disksize, VTOY_GPT_INFO *gpt) +{ + ssize_t len; + off_t offset; + VTOY_GPT_HDR BackupHead; + + VentoyFillBackupGptHead(gpt, &BackupHead); + + offset = lseek(fd, disksize - 512, SEEK_SET); + len = write(fd, &BackupHead, sizeof(VTOY_GPT_HDR)); + vlog("write backup gpt part table off:%llu len:%llu\n", (_ull)offset, (_ull)len); + if (offset != disksize - 512 || len != sizeof(VTOY_GPT_HDR)) + { + return 1; + } + + offset = lseek(fd, disksize - 512 * 33, SEEK_SET); + len = write(fd, gpt->PartTbl, sizeof(gpt->PartTbl)); + vlog("write main gpt part table off:%llu len:%llu\n", (_ull)offset, (_ull)len); + if (offset != disksize - 512 * 33 || len != sizeof(gpt->PartTbl)) + { + return 1; + } + + offset = lseek(fd, 0, SEEK_SET); + len = write(fd, gpt, sizeof(VTOY_GPT_INFO)); + vlog("write gpt part head off:%llu len:%llu\n", (_ull)offset, (_ull)len); + if (offset != 0 || len != sizeof(VTOY_GPT_INFO)) + { + return 1; + } + + return 0; +} + +static int ventoy_mbr_need_update(ventoy_disk *disk, MBR_HEAD *mbr) +{ + int update = 0; + int partition_style; + MBR_HEAD LocalMBR; + + partition_style = disk->vtoydata.partition_style; + memcpy(mbr, &(disk->vtoydata.gptinfo.MBR), 512); + + VentoyGetLocalBootImg(&LocalMBR); + memcpy(LocalMBR.BootCode + 0x180, mbr->BootCode + 0x180, 16); + if (partition_style) + { + LocalMBR.BootCode[92] = 0x22; + } + + if (memcmp(LocalMBR.BootCode, mbr->BootCode, 440)) + { + memcpy(mbr->BootCode, LocalMBR.BootCode, 440); + vlog("MBR boot code different, must update it.\n"); + update = 1; + } + + if (partition_style == 0 && mbr->PartTbl[0].Active == 0) + { + mbr->PartTbl[0].Active = 0x80; + mbr->PartTbl[1].Active = 0; + mbr->PartTbl[2].Active = 0; + mbr->PartTbl[3].Active = 0; + vlog("set MBR partition 1 active flag enabled\n"); + update = 1; + } + + return update; +} + +static void * ventoy_update_thread(void *data) +{ + int fd; + ssize_t len; + off_t offset; + MBR_HEAD MBR; + ventoy_disk *disk = NULL; + ventoy_thread_data *thread = (ventoy_thread_data *)data; + VTOY_GPT_INFO *pstGPT = NULL; + + vdebug("ventoy_update_thread run ...\n"); + + fd = thread->diskfd; + disk = thread->disk; + + g_current_progress = PT_PRAPARE_FOR_CLEAN; + vdebug("check disk %s\n", disk->disk_name); + if (ventoy_is_disk_mounted(disk->disk_path)) + { + vlog("disk is mounted, now try to unmount it ...\n"); + ventoy_try_umount_disk(disk->disk_path); + } + + if (ventoy_is_disk_mounted(disk->disk_path)) + { + vlog("%s is mounted and can't umount!\n", disk->disk_path); + goto err; + } + else + { + vlog("disk is not mounted now, we can do continue ...\n"); + } + + g_current_progress = PT_LOAD_CORE_IMG; + ventoy_unxz_stg1_img(); + + g_current_progress = PT_LOAD_DISK_IMG; + ventoy_unxz_efipart_img(); + + g_current_progress = PT_FORMAT_PART2; + + vlog("Formatting part2 EFI ...\n"); + if (0 != ventoy_write_efipart(fd, disk->vtoydata.part2_start_sector * 512, thread->secure_boot)) + { + vlog("Failed to format part2 efi ...\n"); + goto err; + } + + g_current_progress = PT_WRITE_STG1_IMG; + + vlog("Writing legacy grub ...\n"); + if (0 != ventoy_write_legacy_grub(fd, disk->vtoydata.partition_style)) + { + vlog("ventoy_write_legacy_grub failed ...\n"); + goto err; + } + + offset = lseek(fd, 512 * 2040, SEEK_SET); + len = write(fd, disk->vtoydata.rsvdata, sizeof(disk->vtoydata.rsvdata)); + vlog("Writing reserve data offset:%llu len:%llu ...\n", (_ull)offset, (_ull)len); + + if (ventoy_mbr_need_update(disk, &MBR)) + { + offset = lseek(fd, 0, SEEK_SET); + len = write(fd, &MBR, 512); + vlog("update MBR offset:%llu len:%llu\n", (_ull)offset, (_ull)len); + } + else + { + vlog("No need to update MBR\n"); + } + + + if (disk->vtoydata.partition_style) + { + pstGPT = (VTOY_GPT_INFO *)malloc(sizeof(VTOY_GPT_INFO)); + memset(pstGPT, 0, sizeof(VTOY_GPT_INFO)); + + offset = lseek(fd, 0, SEEK_SET); + len = read(fd, pstGPT, sizeof(VTOY_GPT_INFO)); + vlog("Read GPT table offset:%llu len:%llu ...\n", (_ull)offset, (_ull)len); + + if (pstGPT->PartTbl[1].Attr != 0x8000000000000000ULL) + { + vlog("Update EFI part attr from 0x%016llx to 0x%016llx\n", + pstGPT->PartTbl[1].Attr, 0x8000000000000000ULL); + + pstGPT->PartTbl[1].Attr = 0x8000000000000000ULL; + + pstGPT->Head.PartTblCrc = ventoy_crc32(pstGPT->PartTbl, sizeof(pstGPT->PartTbl)); + pstGPT->Head.Crc = 0; + pstGPT->Head.Crc = ventoy_crc32(&(pstGPT->Head), pstGPT->Head.Length); + ventoy_write_gpt_part_table(fd, disk->size_in_byte, pstGPT); + } + else + { + vlog("No need to update EFI part attr\n"); + } + free(pstGPT); + } + + + g_current_progress = PT_SYNC_DATA1; + + vlog("fsync data1...\n"); + fsync(fd); + vtoy_safe_close_fd(fd); + + g_current_progress = PT_SYNC_DATA2; + + vlog("====================================\n"); + vlog("====== ventoy update success ======\n"); + vlog("====================================\n"); + goto end; + +err: + g_cur_process_result = 1; + vtoy_safe_close_fd(fd); + +end: + g_current_progress = PT_FINISH; + + check_free(thread); + + return NULL; +} + +static void * ventoy_install_thread(void *data) +{ + int fd; + ssize_t len; + off_t offset; + MBR_HEAD MBR; + ventoy_disk *disk = NULL; + VTOY_GPT_INFO *gpt = NULL; + ventoy_thread_data *thread = (ventoy_thread_data *)data; + uint64_t Part1StartSector = 0; + uint64_t Part1SectorCount = 0; + uint64_t Part2StartSector = 0; + + vdebug("ventoy_install_thread run ...\n"); + + fd = thread->diskfd; + disk = thread->disk; + + g_current_progress = PT_PRAPARE_FOR_CLEAN; + vdebug("check disk %s\n", disk->disk_name); + if (ventoy_is_disk_mounted(disk->disk_path)) + { + vlog("disk is mounted, now try to unmount it ...\n"); + ventoy_try_umount_disk(disk->disk_path); + } + + if (ventoy_is_disk_mounted(disk->disk_path)) + { + vlog("%s is mounted and can't umount!\n", disk->disk_path); + goto err; + } + else + { + vlog("disk is not mounted now, we can do continue ...\n"); + } + + g_current_progress = PT_DEL_ALL_PART; + ventoy_clean_disk(fd, disk->size_in_byte); + + g_current_progress = PT_LOAD_CORE_IMG; + ventoy_unxz_stg1_img(); + + g_current_progress = PT_LOAD_DISK_IMG; + ventoy_unxz_efipart_img(); + + if (thread->partstyle) + { + vdebug("Fill GPT part table\n"); + gpt = zalloc(sizeof(VTOY_GPT_INFO)); + ventoy_fill_gpt(disk->size_in_byte, thread->reserveBytes, thread->align4kb, gpt); + Part1StartSector = gpt->PartTbl[0].StartLBA; + Part1SectorCount = gpt->PartTbl[0].LastLBA - Part1StartSector + 1; + Part2StartSector = gpt->PartTbl[1].StartLBA; + } + else + { + vdebug("Fill MBR part table\n"); + ventoy_fill_mbr(disk->size_in_byte, thread->reserveBytes, thread->align4kb, &MBR); + Part1StartSector = MBR.PartTbl[0].StartSectorId; + Part1SectorCount = MBR.PartTbl[0].SectorCount; + Part2StartSector = MBR.PartTbl[1].StartSectorId; + } + + vlog("Part1StartSector:%llu Part1SectorCount:%llu Part2StartSector:%llu\n", + (_ull)Part1StartSector, (_ull)Part1SectorCount, (_ull)Part2StartSector); + + if (thread->partstyle != disk->partstyle) + { + vlog("Wait for format part1 (partstyle changed) ...\n"); + sleep(1); + } + + g_current_progress = PT_FORMAT_PART1; + vlog("Formatting part1 exFAT %s ...\n", disk->disk_path); + if (0 != mkexfat_main(disk->disk_path, fd, Part1SectorCount)) + { + vlog("Failed to format exfat ...\n"); + goto err; + } + + g_current_progress = PT_FORMAT_PART2; + vlog("Formatting part2 EFI ...\n"); + if (0 != ventoy_write_efipart(fd, Part2StartSector * 512, thread->secure_boot)) + { + vlog("Failed to format part2 efi ...\n"); + goto err; + } + + g_current_progress = PT_WRITE_STG1_IMG; + vlog("Writing legacy grub ...\n"); + if (0 != ventoy_write_legacy_grub(fd, thread->partstyle)) + { + vlog("ventoy_write_legacy_grub failed ...\n"); + goto err; + } + + g_current_progress = PT_SYNC_DATA1; + vlog("fsync data1...\n"); + fsync(fd); + vtoy_safe_close_fd(fd); + + /* reopen for check part2 data */ + vlog("Checking part2 efi data %s ...\n", disk->disk_path); + g_current_progress = PT_CHECK_PART2; + fd = open(disk->disk_path, O_RDONLY | O_BINARY); + if (fd < 0) + { + vlog("failed to open %s for check fd:%d err:%d\n", disk->disk_path, fd, errno); + goto err; + } + + if (0 == ventoy_check_efi_part_data(fd, Part2StartSector * 512)) + { + vlog("efi part data check success\n"); + } + else + { + vlog("efi part data check failed\n"); + goto err; + } + + vtoy_safe_close_fd(fd); + + /* reopen for write part table */ + g_current_progress = PT_WRITE_PART_TABLE; + vlog("Writting Partition Table style:%d...\n", thread->partstyle); + + fd = open(disk->disk_path, O_RDWR | O_BINARY); + if (fd < 0) + { + vlog("failed to open %s for part table fd:%d err:%d\n", disk->disk_path, fd, errno); + goto err; + } + + if (thread->partstyle) + { + ventoy_write_gpt_part_table(fd, disk->size_in_byte, gpt); + } + else + { + offset = lseek(fd, 0, SEEK_SET); + len = write(fd, &MBR, 512); + vlog("Writting MBR Partition Table %llu %llu\n", (_ull)offset, (_ull)len); + if (offset != 0 || len != 512) + { + goto err; + } + } + + g_current_progress = PT_SYNC_DATA2; + vlog("fsync data2...\n"); + fsync(fd); + vtoy_safe_close_fd(fd); + + + vlog("====================================\n"); + vlog("====== ventoy install success ======\n"); + vlog("====================================\n"); + goto end; + +err: + g_cur_process_result = 1; + vtoy_safe_close_fd(fd); + +end: + g_current_progress = PT_FINISH; + + check_free(gpt); + check_free(thread); + + return NULL; +} + +static int ventoy_api_clean(struct mg_connection *conn, VTOY_JSON *json) +{ + int i = 0; + int fd = 0; + ventoy_disk *disk = NULL; + const char *diskname = NULL; + char path[128]; + + if (g_current_progress != PT_FINISH) + { + ventoy_json_result(conn, VTOY_JSON_BUSY_RET); + return 0; + } + + diskname = vtoy_json_get_string_ex(json, "disk"); + if (diskname == NULL) + { + ventoy_json_result(conn, VTOY_JSON_INVALID_RET); + return 0; + } + + for (i = 0; i < g_disk_num; i++) + { + if (strcmp(g_disk_list[i].disk_name, diskname) == 0) + { + disk = g_disk_list + i; + break; + } + } + + if (disk == NULL) + { + vlog("disk %s not found\n", diskname); + ventoy_json_result(conn, VTOY_JSON_NOTFOUND_RET); + return 0; + } + + scnprintf(path, "/sys/block/%s", diskname); + if (access(path, F_OK) < 0) + { + vlog("File %s not exist anymore\n", path); + ventoy_json_result(conn, VTOY_JSON_NOTFOUND_RET); + return 0; + } + + vlog("==================================\n"); + vlog("===== ventoy clean %s =====\n", disk->disk_path); + vlog("==================================\n"); + + if (ventoy_is_disk_mounted(disk->disk_path)) + { + vlog("disk is mounted, now try to unmount it ...\n"); + ventoy_try_umount_disk(disk->disk_path); + } + + if (ventoy_is_disk_mounted(disk->disk_path)) + { + vlog("%s is mounted and can't umount!\n", disk->disk_path); + ventoy_json_result(conn, VTOY_JSON_FAILED_RET); + return 0; + } + else + { + vlog("disk is not mounted now, we can do the clean ...\n"); + } + + fd = open(disk->disk_path, O_RDWR | O_BINARY); + if (fd < 0) + { + vlog("failed to open %s fd:%d err:%d\n", disk->disk_path, fd, errno); + ventoy_json_result(conn, VTOY_JSON_FAILED_RET); + return 0; + } + + vdebug("start clean %s ...\n", disk->disk_model); + ventoy_clean_disk(fd, disk->size_in_byte); + + vtoy_safe_close_fd(fd); + + ventoy_json_result(conn, VTOY_JSON_SUCCESS_RET); + return 0; +} + +static int ventoy_api_install(struct mg_connection *conn, VTOY_JSON *json) +{ + int i = 0; + int ret = 0; + int fd = 0; + uint32_t align4kb = 0; + uint32_t style = 0; + uint32_t secure_boot = 0; + uint64_t reserveBytes = 0; + ventoy_disk *disk = NULL; + const char *diskname = NULL; + const char *reserve_space = NULL; + ventoy_thread_data *thread = NULL; + char path[128]; + + if (g_current_progress != PT_FINISH) + { + ventoy_json_result(conn, VTOY_JSON_BUSY_RET); + return 0; + } + + diskname = vtoy_json_get_string_ex(json, "disk"); + reserve_space = vtoy_json_get_string_ex(json, "reserve_space"); + ret += vtoy_json_get_uint(json, "partstyle", &style); + ret += vtoy_json_get_uint(json, "secure_boot", &secure_boot); + ret += vtoy_json_get_uint(json, "align_4kb", &align4kb); + + if (diskname == NULL || reserve_space == NULL || ret != JSON_SUCCESS) + { + ventoy_json_result(conn, VTOY_JSON_INVALID_RET); + return 0; + } + + reserveBytes = (uint64_t)strtoull(reserve_space, NULL, 10); + + for (i = 0; i < g_disk_num; i++) + { + if (strcmp(g_disk_list[i].disk_name, diskname) == 0) + { + disk = g_disk_list + i; + break; + } + } + + if (disk == NULL) + { + vlog("disk %s not found\n", diskname); + ventoy_json_result(conn, VTOY_JSON_NOTFOUND_RET); + return 0; + } + + if (disk->is4kn) + { + vlog("disk %s is 4k native, not supported.\n", diskname); + ventoy_json_result(conn, VTOY_JSON_4KN_RET); + return 0; + } + + scnprintf(path, "/sys/block/%s", diskname); + if (access(path, F_OK) < 0) + { + vlog("File %s not exist anymore\n", path); + ventoy_json_result(conn, VTOY_JSON_NOTFOUND_RET); + return 0; + } + + if (disk->size_in_byte > 2199023255552ULL && style == 0) + { + vlog("disk %s is more than 2TB and GPT is needed\n", path); + ventoy_json_result(conn, VTOY_JSON_MBR_2TB_RET); + return 0; + } + + if ((reserveBytes + VTOYEFI_PART_BYTES * 2) > disk->size_in_byte) + { + vlog("reserve space %llu is too big for disk %s %llu\n", (_ull)reserveBytes, path, (_ull)disk->size_in_byte); + ventoy_json_result(conn, VTOY_JSON_INVALID_RSV_RET); + return 0; + } + + vlog("==================================================================================\n"); + vlog("===== ventoy install %s style:%s secureboot:%u align4K:%u reserve:%llu =========\n", + disk->disk_path, (style ? "GPT" : "MBR"), secure_boot, align4kb, (_ull)reserveBytes); + vlog("==================================================================================\n"); + + if (ventoy_is_disk_mounted(disk->disk_path)) + { + vlog("disk is mounted, now try to unmount it ...\n"); + ventoy_try_umount_disk(disk->disk_path); + } + + if (ventoy_is_disk_mounted(disk->disk_path)) + { + vlog("%s is mounted and can't umount!\n", disk->disk_path); + ventoy_json_result(conn, VTOY_JSON_FAILED_RET); + return 0; + } + else + { + vlog("disk is not mounted now, we can do the install ...\n"); + } + + fd = open(disk->disk_path, O_RDWR | O_BINARY); + if (fd < 0) + { + vlog("failed to open %s fd:%d err:%d\n", disk->disk_path, fd, errno); + ventoy_json_result(conn, VTOY_JSON_FAILED_RET); + return 0; + } + + vdebug("start install thread %s ...\n", disk->disk_model); + thread = zalloc(sizeof(ventoy_thread_data)); + if (!thread) + { + vtoy_safe_close_fd(fd); + vlog("failed to alloc thread data err:%d\n", errno); + ventoy_json_result(conn, VTOY_JSON_FAILED_RET); + return 0; + } + + g_current_progress = PT_START; + g_cur_process_result = 0; + scnprintf(g_cur_process_type, "%s", "install"); + scnprintf(g_cur_process_diskname, "%s", disk->disk_name); + + thread->disk = disk; + thread->diskfd = fd; + thread->align4kb = align4kb; + thread->partstyle = style; + thread->secure_boot = secure_boot; + thread->reserveBytes = reserveBytes; + + mg_start_thread(ventoy_install_thread, thread); + + ventoy_json_result(conn, VTOY_JSON_SUCCESS_RET); + return 0; +} + +static int ventoy_api_update(struct mg_connection *conn, VTOY_JSON *json) +{ + int i = 0; + int ret = 0; + int fd = 0; + uint32_t secure_boot = 0; + ventoy_disk *disk = NULL; + const char *diskname = NULL; + ventoy_thread_data *thread = NULL; + char path[128]; + + if (g_current_progress != PT_FINISH) + { + ventoy_json_result(conn, VTOY_JSON_BUSY_RET); + return 0; + } + + diskname = vtoy_json_get_string_ex(json, "disk"); + ret += vtoy_json_get_uint(json, "secure_boot", &secure_boot); + if (diskname == NULL || ret != JSON_SUCCESS) + { + ventoy_json_result(conn, VTOY_JSON_INVALID_RET); + return 0; + } + + for (i = 0; i < g_disk_num; i++) + { + if (strcmp(g_disk_list[i].disk_name, diskname) == 0) + { + disk = g_disk_list + i; + break; + } + } + + if (disk == NULL) + { + vlog("disk %s not found\n", diskname); + ventoy_json_result(conn, VTOY_JSON_NOTFOUND_RET); + return 0; + } + + if (disk->vtoydata.ventoy_valid == 0) + { + vlog("disk %s is not ventoy disk\n", diskname); + ventoy_json_result(conn, VTOY_JSON_FAILED_RET); + return 0; + } + + scnprintf(path, "/sys/block/%s", diskname); + if (access(path, F_OK) < 0) + { + vlog("File %s not exist anymore\n", path); + ventoy_json_result(conn, VTOY_JSON_NOTFOUND_RET); + return 0; + } + + vlog("==========================================================\n"); + vlog("===== ventoy update %s new_secureboot:%u =========\n", disk->disk_path, secure_boot); + vlog("==========================================================\n"); + + vlog("%s version:%s partstyle:%u oldsecureboot:%u reserve:%llu\n", + disk->disk_path, disk->vtoydata.ventoy_ver, + disk->vtoydata.partition_style, + disk->vtoydata.secure_boot_flag, + (_ull)(disk->vtoydata.preserved_space) + ); + + if (ventoy_is_disk_mounted(disk->disk_path)) + { + vlog("disk is mounted, now try to unmount it ...\n"); + ventoy_try_umount_disk(disk->disk_path); + } + + if (ventoy_is_disk_mounted(disk->disk_path)) + { + vlog("%s is mounted and can't umount!\n", disk->disk_path); + ventoy_json_result(conn, VTOY_JSON_FAILED_RET); + return 0; + } + else + { + vlog("disk is not mounted now, we can do the update ...\n"); + } + + fd = open(disk->disk_path, O_RDWR | O_BINARY); + if (fd < 0) + { + vlog("failed to open %s fd:%d err:%d\n", disk->disk_path, fd, errno); + ventoy_json_result(conn, VTOY_JSON_FAILED_RET); + return 0; + } + + vdebug("start update thread %s ...\n", disk->disk_model); + thread = zalloc(sizeof(ventoy_thread_data)); + if (!thread) + { + vtoy_safe_close_fd(fd); + vlog("failed to alloc thread data err:%d\n", errno); + ventoy_json_result(conn, VTOY_JSON_FAILED_RET); + return 0; + } + + g_current_progress = PT_START; + g_cur_process_result = 0; + scnprintf(g_cur_process_type, "%s", "update"); + scnprintf(g_cur_process_diskname, "%s", disk->disk_name); + + thread->disk = disk; + thread->diskfd = fd; + thread->secure_boot = secure_boot; + + mg_start_thread(ventoy_update_thread, thread); + + ventoy_json_result(conn, VTOY_JSON_SUCCESS_RET); + return 0; +} + + +static int ventoy_api_refresh_device(struct mg_connection *conn, VTOY_JSON *json) +{ + (void)json; + + if (g_current_progress == PT_FINISH) + { + g_disk_num = 0; + ventoy_disk_enumerate_all(); + } + + ventoy_json_result(conn, VTOY_JSON_SUCCESS_RET); + return 0; +} + +static int ventoy_api_get_dev_list(struct mg_connection *conn, VTOY_JSON *json) +{ + int i = 0; + int rc = 0; + int pos = 0; + int buflen = 0; + uint32_t alldev = 0; + char *buf = NULL; + ventoy_disk *cur = NULL; + + rc = vtoy_json_get_uint(json, "alldev", &alldev); + if (JSON_SUCCESS != rc) + { + alldev = 0; + } + + buflen = g_disk_num * 1024; + buf = (char *)malloc(buflen + 1024); + if (!buf) + { + ventoy_json_result(conn, VTOY_JSON_FAILED_RET); + return 0; + } + + VTOY_JSON_FMT_BEGIN(pos, buf, buflen); + VTOY_JSON_FMT_OBJ_BEGIN(); + VTOY_JSON_FMT_KEY("list"); + VTOY_JSON_FMT_ARY_BEGIN(); + + for (i = 0; i < g_disk_num; i++) + { + cur = g_disk_list + i; + + if (alldev == 0 && cur->type != VTOY_DEVICE_USB) + { + continue; + } + + VTOY_JSON_FMT_OBJ_BEGIN(); + VTOY_JSON_FMT_STRN("name", cur->disk_name); + VTOY_JSON_FMT_STRN("model", cur->disk_model); + VTOY_JSON_FMT_STRN("size", cur->human_readable_size); + VTOY_JSON_FMT_UINT("vtoy_valid", cur->vtoydata.ventoy_valid); + VTOY_JSON_FMT_STRN("vtoy_ver", cur->vtoydata.ventoy_ver); + VTOY_JSON_FMT_UINT("vtoy_secure_boot", cur->vtoydata.secure_boot_flag); + VTOY_JSON_FMT_UINT("vtoy_partstyle", cur->vtoydata.partition_style); + VTOY_JSON_FMT_OBJ_ENDEX(); + } + + VTOY_JSON_FMT_ARY_END(); + VTOY_JSON_FMT_OBJ_END(); + VTOY_JSON_FMT_END(pos); + + ventoy_json_buffer(conn, buf, pos); + return 0; +} + +static JSON_CB g_ventoy_json_cb[] = +{ + { "sysinfo", ventoy_api_sysinfo }, + { "sel_language", ventoy_api_set_language }, + { "sel_partstyle", ventoy_api_set_partstyle }, + { "refresh_device", ventoy_api_refresh_device }, + { "get_dev_list", ventoy_api_get_dev_list }, + { "install", ventoy_api_install }, + { "update", ventoy_api_update }, + { "clean", ventoy_api_clean }, + { "get_percent", ventoy_api_get_percent }, +}; + +static int ventoy_json_handler(struct mg_connection *conn, VTOY_JSON *json) +{ + int i; + const char *token = NULL; + const char *method = NULL; + + method = vtoy_json_get_string_ex(json, "method"); + if (!method) + { + ventoy_json_result(conn, VTOY_JSON_SUCCESS_RET); + return 0; + } + + if (strcmp(method, "sysinfo")) + { + token = vtoy_json_get_string_ex(json, "token"); + if (token == NULL || strcmp(token, g_cur_server_token)) + { + ventoy_json_result(conn, VTOY_JSON_TOKEN_ERR_RET); + return 0; + } + } + + for (i = 0; i < (int)(sizeof(g_ventoy_json_cb) / sizeof(g_ventoy_json_cb[0])); i++) + { + if (strcmp(method, g_ventoy_json_cb[i].method) == 0) + { + g_ventoy_json_cb[i].callback(conn, json); + break; + } + } + + return 0; +} + +int ventoy_func_handler(const char *jsonstr, char *jsonbuf, int buflen) +{ + int i; + const char *method = NULL; + VTOY_JSON *json = NULL; + + g_pub_out_buf = jsonbuf; + g_pub_out_max = buflen; + + json = vtoy_json_create(); + if (JSON_SUCCESS == vtoy_json_parse(json, jsonstr)) + { + pthread_mutex_lock(&g_api_mutex); + + method = vtoy_json_get_string_ex(json->pstChild, "method"); + for (i = 0; i < (int)(sizeof(g_ventoy_json_cb) / sizeof(g_ventoy_json_cb[0])); i++) + { + if (method && strcmp(method, g_ventoy_json_cb[i].method) == 0) + { + g_ventoy_json_cb[i].callback(NULL, json->pstChild); + break; + } + } + + pthread_mutex_unlock(&g_api_mutex); + } + else + { + ventoy_json_result(NULL, VTOY_JSON_INVALID_RET); + } + + vtoy_json_destroy(json); + return 0; +} + +static int ventoy_request_handler(struct mg_connection *conn) +{ + int post_data_len; + int post_buf_len; + VTOY_JSON *json = NULL; + char *post_data_buf = NULL; + const struct mg_request_info *ri = NULL; + char stack_buf[512]; + + ri = mg_get_request_info(conn); + + if (strcmp(ri->uri, "/vtoy/json") == 0) + { + if (ri->content_length > 500) + { + post_data_buf = malloc(ri->content_length + 4); + post_buf_len = ri->content_length + 1; + } + else + { + post_data_buf = stack_buf; + post_buf_len = sizeof(stack_buf); + } + + post_data_len = mg_read(conn, post_data_buf, post_buf_len); + post_data_buf[post_data_len] = 0; + + json = vtoy_json_create(); + if (JSON_SUCCESS == vtoy_json_parse(json, post_data_buf)) + { + pthread_mutex_lock(&g_api_mutex); + ventoy_json_handler(conn, json->pstChild); + pthread_mutex_unlock(&g_api_mutex); + } + else + { + ventoy_json_result(conn, VTOY_JSON_INVALID_RET); + } + + vtoy_json_destroy(json); + + if (post_data_buf != stack_buf) + { + free(post_data_buf); + } + return 1; + } + else + { + return 0; + } +} + +int ventoy_http_start(const char *ip, const char *port) +{ + uint8_t uuid[16]; + char addr[128]; + struct mg_callbacks callbacks; + const char *options[] = + { + "listening_ports", "24680", + "document_root", "WebUI", + "error_log_file", g_log_file, + "request_timeout_ms", "10000", + NULL + }; + + /* unique token */ + ventoy_gen_preudo_uuid(uuid); + scnprintf(g_cur_server_token, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7], + uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]); + + /* option */ + scnprintf(addr, "%s:%s", ip, port); + options[1] = addr; + + memset(&callbacks, 0, sizeof(callbacks)); + callbacks.begin_request = ventoy_request_handler; + g_ventoy_http_ctx = mg_start(&callbacks, NULL, options); + + return g_ventoy_http_ctx ? 0 : 1; +} + +int ventoy_http_stop(void) +{ + if (g_ventoy_http_ctx) + { + mg_stop(g_ventoy_http_ctx); + } + return 0; +} + +int ventoy_http_init(void) +{ + pthread_mutex_init(&g_api_mutex, NULL); + + ventoy_http_load_cfg(); + + ventoy_load_mbr_template(); + + return 0; +} + +void ventoy_http_exit(void) +{ + pthread_mutex_destroy(&g_api_mutex); + + check_free(g_efi_part_raw_img); + g_efi_part_raw_img = NULL; +} + + +const char * ventoy_code_get_cur_language(void) +{ + return g_cur_language; +} + +int ventoy_code_get_cur_part_style(void) +{ + return g_cur_part_style; +} + +void ventoy_code_set_cur_part_style(int style) +{ + pthread_mutex_lock(&g_api_mutex); + + g_cur_part_style = style; + ventoy_http_save_cfg(); + + pthread_mutex_unlock(&g_api_mutex); +} + +int ventoy_code_get_cur_show_all(void) +{ + return g_cur_show_all; +} + +void ventoy_code_set_cur_show_all(int show_all) +{ + pthread_mutex_lock(&g_api_mutex); + + g_cur_show_all = show_all; + ventoy_http_save_cfg(); + + pthread_mutex_unlock(&g_api_mutex); +} + +void ventoy_code_set_cur_language(const char *lang) +{ + pthread_mutex_lock(&g_api_mutex); + + scnprintf(g_cur_language, "%s", lang); + ventoy_http_save_cfg(); + + pthread_mutex_unlock(&g_api_mutex); +} + +void ventoy_code_refresh_device(void) +{ + if (g_current_progress == PT_FINISH) + { + g_disk_num = 0; + ventoy_disk_enumerate_all(); + } +} + +int ventoy_code_is_busy(void) +{ + return (g_current_progress == PT_FINISH) ? 0 : 1; +} + +int ventoy_code_get_percent(void) +{ + return g_current_progress * 100 / PT_FINISH; +} + +int ventoy_code_get_result(void) +{ + return g_cur_process_result; +} + +void ventoy_code_save_cfg(void) +{ + ventoy_http_save_cfg(); +} diff --git a/LinuxGUI/Ventoy2Disk/Web/ventoy_http.h b/LinuxGUI/Ventoy2Disk/Web/ventoy_http.h new file mode 100644 index 0000000..8c12c02 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Web/ventoy_http.h @@ -0,0 +1,82 @@ +/****************************************************************************** + * ventoy_http.h + * + * Copyright (c) 2021, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ +#ifndef __VENTOY_HTTP_H__ +#define __VENTOY_HTTP_H__ + +#include + +typedef enum PROGRESS_POINT +{ + PT_START = 1, + + PT_PRAPARE_FOR_CLEAN, + PT_DEL_ALL_PART, + + PT_LOAD_CORE_IMG, + PT_LOAD_DISK_IMG, + PT_UNXZ_DISK_IMG_FINISH = PT_LOAD_DISK_IMG + 32, + + PT_FORMAT_PART1, //10 + + PT_FORMAT_PART2, + + PT_WRITE_VENTOY_START, + PT_WRITE_VENTOY_FINISH = PT_WRITE_VENTOY_START + 8, + + PT_WRITE_STG1_IMG,//45 + PT_SYNC_DATA1, + + PT_CHECK_PART2, + PT_CHECK_PART2_FINISH = PT_CHECK_PART2 + 8, + + PT_WRITE_PART_TABLE,//52 + PT_SYNC_DATA2, + + PT_FINISH +}PROGRESS_POINT; + +typedef int (*ventoy_json_callback)(struct mg_connection *conn, VTOY_JSON *json); +typedef struct JSON_CB +{ + const char *method; + ventoy_json_callback callback; +}JSON_CB; + +typedef struct ventoy_thread_data +{ + int diskfd; + uint32_t align4kb; + uint32_t partstyle; + uint32_t secure_boot; + uint64_t reserveBytes; + ventoy_disk *disk; +}ventoy_thread_data; + +extern int g_vtoy_exfat_disk_fd; +extern uint64_t g_vtoy_exfat_part_size; + +int ventoy_http_init(void); +void ventoy_http_exit(void); +int ventoy_http_start(const char *ip, const char *port); +int ventoy_http_stop(void); +int mkexfat_main(const char *devpath, int fd, uint64_t part_sector_count); + +#endif /* __VENTOY_HTTP_H__ */ + diff --git a/LinuxGUI/Ventoy2Disk/main_gtk.c b/LinuxGUI/Ventoy2Disk/main_gtk.c new file mode 100644 index 0000000..a2b96aa --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/main_gtk.c @@ -0,0 +1,230 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ventoy_gtk.h" + +static int g_kiosk_mode = 0; +char g_log_file[PATH_MAX]; +char g_ini_file[PATH_MAX]; + +static int set_image_from_pixbuf(GtkBuilder *pBuilder, const char *id, const void *pData, int len) +{ + GtkImage *pImage = NULL; + GdkPixbuf *pPixbuf = NULL; + GInputStream *pStream = NULL; + + pImage = (GtkImage *)gtk_builder_get_object(pBuilder, id); + pStream = g_memory_input_stream_new_from_data(pData, len, NULL); + pPixbuf = gdk_pixbuf_new_from_stream(pStream, NULL, NULL); + gtk_image_set_from_pixbuf(pImage, pPixbuf); + + return 0; +} + +static int set_window_icon_from_pixbuf(GtkWindow *window, const void *pData, int len) +{ + GdkPixbuf *pPixbuf = NULL; + GInputStream *pStream = NULL; + + pStream = g_memory_input_stream_new_from_data(pData, len, NULL); + pPixbuf = gdk_pixbuf_new_from_stream(pStream, NULL, NULL); + + gtk_window_set_icon(window, pPixbuf); + return 0; +} + +int early_msgbox(GtkMessageType type, GtkButtonsType buttons, const char *str) +{ + int ret; + GtkWidget *pMsgBox = NULL; + + pMsgBox= gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, type, buttons, str); + + ret = gtk_dialog_run(GTK_DIALOG(pMsgBox)); + gtk_widget_destroy(pMsgBox); + + return ret; +} + +static int adjust_cur_dir(char *argv0) +{ + int ret = 2; + char c; + char *pos = NULL; + char *end = NULL; + + if (argv0[0] == '.') + { + return 1; + } + + for (pos = argv0; pos && *pos; pos++) + { + if (*pos == '/') + { + end = pos; + } + } + + if (end) + { + c = *end; + *end = 0; + + pos = strstr(argv0, "/tool/"); + if (pos) + { + *pos = 0; + } + + ret = chdir(argv0); + + *end = c; + if (pos) + { + *pos = '/'; + } + } + + return ret; +} + +int main(int argc, char *argv[]) +{ + int i; + int len; + const void *pData = NULL; + GtkWidget *pWidget = NULL; + GtkBuilder *pBuilder = NULL; + GError *error = NULL; + struct stat logstat; + + gtk_init(&argc, &argv); + + if (geteuid() != 0) + { + early_msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, + "Ventoy2Disk permission denied!\r\nPlease run with root privileges."); + return EACCES; + } + + if (access("./boot/boot.img", F_OK) == -1) + { + adjust_cur_dir(argv[0]); + } + + if (access("./boot/boot.img", F_OK) == -1) + { + early_msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "Please run under the correct directory."); + return 1; + } + + for (i = 0; i < argc; i++) + { + if (argv[i] && strcmp(argv[i], "--kiosk") == 0) + { + g_kiosk_mode = 1; + break; + } + } + + snprintf(g_log_file, sizeof(g_log_file), "log.txt"); + snprintf(g_ini_file, sizeof(g_ini_file), "./Ventoy2Disk.ini"); + for (i = 0; i < argc; i++) + { + if (argv[i] && argv[i + 1] && strcmp(argv[i], "-l") == 0) + { + snprintf(g_log_file, sizeof(g_log_file), "%s", argv[i + 1]); + } + else if (argv[i] && argv[i + 1] && strcmp(argv[i], "-i") == 0) + { + snprintf(g_ini_file, sizeof(g_ini_file), "%s", argv[i + 1]); + } + } + + memset(&logstat, 0, sizeof(logstat)); + if (0 == stat(g_log_file, &logstat)) + { + if (logstat.st_size >= 4 * SIZE_1MB) + { + remove(g_log_file); + } + } + + ventoy_log_init(); + + vlog("================================================\n"); + vlog("===== Ventoy2Disk %s powered by GTK%d.x =====\n", ventoy_get_local_version(), GTK_MAJOR_VERSION); + vlog("================================================\n"); + vlog("log file is <%s> lastsize:%lld\n", g_log_file, (long long)logstat.st_size); + vlog("ini file is <%s>\n", g_ini_file); + + ventoy_disk_init(); + + ventoy_http_init(); + + pBuilder = gtk_builder_new(); + if (!pBuilder) + { + vlog("failed to create builder\n"); + return 1; + } + + if (!gtk_builder_add_from_file(pBuilder, "./tool/VentoyGTK.glade", &error)) + { + vlog("gtk_builder_add_from_file failed:%s\n", error->message); + g_clear_error(&error); + return 1; + } + + if (g_kiosk_mode) + { + gtk_image_set_from_file((GtkImage *)gtk_builder_get_object(pBuilder, "image_refresh"), "/ventoy/refresh.png"); + gtk_image_set_from_file((GtkImage *)gtk_builder_get_object(pBuilder, "image_secure_local"), "/ventoy/secure.png"); + gtk_image_set_from_file((GtkImage *)gtk_builder_get_object(pBuilder, "image_secure_dev"), "/ventoy/secure.png"); + } + else + { + pData = get_refresh_icon_raw_data(&len); + set_image_from_pixbuf(pBuilder, "image_refresh", pData, len); + pData = get_secure_icon_raw_data(&len); + set_image_from_pixbuf(pBuilder, "image_secure_local", pData, len); + set_image_from_pixbuf(pBuilder, "image_secure_dev", pData, len); + } + + pWidget = GTK_WIDGET(gtk_builder_get_object(pBuilder, "window")); + gtk_widget_show_all(pWidget); + + pData = get_window_icon_raw_data(&len); + set_window_icon_from_pixbuf(GTK_WINDOW(pWidget), pData, len); + + on_init_window(pBuilder); + g_signal_connect(G_OBJECT(pWidget), "delete_event", G_CALLBACK(on_exit_window), NULL); + g_signal_connect(G_OBJECT(pWidget), "destroy", G_CALLBACK(gtk_main_quit), NULL); + + gtk_main(); + + ventoy_disk_exit(); + ventoy_http_exit(); + + g_object_unref (G_OBJECT(pBuilder)); + + vlog("######## Ventoy2Disk GTK %s exit ########\n", ventoy_get_local_version()); + + /* log exit must at the end */ + ventoy_log_exit(); + return 0; +} + diff --git a/LinuxGUI/Ventoy2Disk/main_webui.c b/LinuxGUI/Ventoy2Disk/main_webui.c new file mode 100644 index 0000000..2b782cc --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/main_webui.c @@ -0,0 +1,101 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char g_log_file[PATH_MAX]; +char g_ini_file[PATH_MAX]; + +int ventoy_log_init(void); +void ventoy_log_exit(void); + +void ventoy_signal_stop(int sig) +{ + vlog("ventoy server exit due to signal ...\n"); + printf("ventoy server exit ...\n"); + + ventoy_http_stop(); + ventoy_http_exit(); + ventoy_disk_exit(); + ventoy_log_exit(); + exit(0); +} + +int main(int argc, char **argv) +{ + int i; + int rc; + const char *ip = "127.0.0.1"; + const char *port = "24680"; + + if (argc != 3) + { + printf("Invalid argc %d\n", argc); + return 1; + } + + if (isdigit(argv[1][0])) + { + ip = argv[1]; + } + + if (isdigit(argv[2][0])) + { + port = argv[2]; + } + + snprintf(g_log_file, sizeof(g_log_file), "log.txt"); + snprintf(g_ini_file, sizeof(g_ini_file), "./Ventoy2Disk.ini"); + for (i = 0; i < argc; i++) + { + if (argv[i] && argv[i + 1] && strcmp(argv[i], "-l") == 0) + { + snprintf(g_log_file, sizeof(g_log_file), "%s", argv[i + 1]); + } + else if (argv[i] && argv[i + 1] && strcmp(argv[i], "-i") == 0) + { + snprintf(g_ini_file, sizeof(g_ini_file), "%s", argv[i + 1]); + } + } + + ventoy_log_init(); + + vlog("===============================================\n"); + vlog("===== Ventoy2Disk %s %s:%s =====\n", ventoy_get_local_version(), ip, port); + vlog("===============================================\n"); + + ventoy_disk_init(); + + ventoy_http_init(); + + rc = ventoy_http_start(ip, port); + if (rc) + { + printf("Ventoy failed to start http server, check log.txt for detail\n"); + } + else + { + signal(SIGINT, ventoy_signal_stop); + signal(SIGTSTP, ventoy_signal_stop); + signal(SIGQUIT, ventoy_signal_stop); + while (1) + { + sleep(100); + } + } + + return 0; +} + diff --git a/LinuxGUI/Ventoy2Disk/ventoy_gui.c b/LinuxGUI/Ventoy2Disk/ventoy_gui.c new file mode 100644 index 0000000..7c1bad8 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/ventoy_gui.c @@ -0,0 +1,1376 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ventoy_json.h" + +#define LIB_FLAG_GTK2 (1 << 0) +#define LIB_FLAG_GTK3 (1 << 1) +#define LIB_FLAG_GTK4 (1 << 2) +#define LIB_FLAG_QT4 (1 << 3) +#define LIB_FLAG_QT5 (1 << 4) +#define LIB_FLAG_QT6 (1 << 5) +#define LIB_FLAG_GLADE2 (1 << 30) + +#define LIB_FLAG_GTK (LIB_FLAG_GTK2 | LIB_FLAG_GTK3 | LIB_FLAG_GTK4) +#define LIB_FLAG_QT (LIB_FLAG_QT4 | LIB_FLAG_QT5 | LIB_FLAG_QT6) + +#define MAX_PARAS 64 +#define MAX_LOG_BUF (1024 * 1024) +#define VTOY_GUI_PATH "_vtoy_gui_path_=" +#define VTOY_ENV_STR "_vtoy_env_str_=" +#define LD_CACHE_FILE "/etc/ld.so.cache" +#define INT2STR_YN(a) ((a) == 0 ? "NO" : "YES") + +static int g_xdg_log = 0; +static int g_xdg_ini = 0; +static char g_log_file[PATH_MAX]; +static char g_ini_file[PATH_MAX]; +static char *g_log_buf = NULL; +extern char ** environ; + +#define CACHEMAGIC "ld.so-1.7.0" + +struct file_entry +{ + int flags; /* This is 1 for an ELF library. */ + unsigned int key, value; /* String table indices. */ +}; + +struct cache_file +{ + char magic[sizeof CACHEMAGIC - 1]; + unsigned int nlibs; + struct file_entry libs[0]; +}; + +#define CACHEMAGIC_NEW "glibc-ld.so.cache" +#define CACHE_VERSION "1.1" +#define CACHEMAGIC_VERSION_NEW CACHEMAGIC_NEW CACHE_VERSION + +struct file_entry_new +{ + int32_t flags; /* This is 1 for an ELF library. */ + uint32_t key, value; /* String table indices. */ + uint32_t osversion; /* Required OS version. */ + uint64_t hwcap; /* Hwcap entry. */ +}; + +struct cache_file_new +{ + char magic[sizeof CACHEMAGIC_NEW - 1]; + char version[sizeof CACHE_VERSION - 1]; + uint32_t nlibs; /* Number of entries. */ + uint32_t len_strings; /* Size of string table. */ + uint32_t unused[5]; /* Leave space for future extensions + and align to 8 byte boundary. */ + struct file_entry_new libs[0]; /* Entries describing libraries. */ + /* After this the string table of size len_strings is found. */ +}; + +/* Used to align cache_file_new. */ +#define ALIGN_CACHE(addr) \ +(((addr) + __alignof__ (struct cache_file_new) -1) \ + & (~(__alignof__ (struct cache_file_new) - 1))) + +#define vlog(fmt, args...) ventoy_syslog(0, fmt, ##args) + +void ventoy_syslog(int level, const char *Fmt, ...) +{ + int buflen; + char *buf = NULL; + char log[512]; + va_list arg; + time_t stamp; + struct tm ttm; + FILE *fp; + + (void)level; + + time(&stamp); + localtime_r(&stamp, &ttm); + + if (g_log_buf) + { + buf = g_log_buf; + buflen = MAX_LOG_BUF; + } + else + { + buf = log; + buflen = sizeof(log); + } + + va_start(arg, Fmt); + vsnprintf(buf, buflen, Fmt, arg); + va_end(arg); + + fp = fopen(g_log_file, "a+"); + if (fp) + { + fprintf(fp, "[%04u/%02u/%02u %02u:%02u:%02u] %s", + ttm.tm_year + 1900, ttm.tm_mon, ttm.tm_mday, + ttm.tm_hour, ttm.tm_min, ttm.tm_sec, + buf); + fclose(fp); + } + + #if 0 + printf("[%04u/%02u/%02u %02u:%02u:%02u] %s", + ttm.tm_year + 1900, ttm.tm_mon, ttm.tm_mday, + ttm.tm_hour, ttm.tm_min, ttm.tm_sec, + buf); + #endif +} + +static int is_gtk_env(void) +{ + const char *env = NULL; + + env = getenv("GNOME_SETUP_DISPLAY"); + if (env && env[0] == ':') + { + vlog("GNOME_SETUP_DISPLAY=%s\n", env); + return 1; + } + + env = getenv("DESKTOP_SESSION"); + if (env && strcasecmp(env, "xfce") == 0) + { + vlog("DESKTOP_SESSION=%s\n", env); + return 1; + } + + return 0; +} + +static int is_qt_env(void) +{ + return 0; +} + +static int detect_gtk_version(int libflag) +{ + int gtk2; + int gtk3; + int gtk4; + int glade2; + + gtk2 = libflag & LIB_FLAG_GTK2; + gtk3 = libflag & LIB_FLAG_GTK3; + gtk4 = libflag & LIB_FLAG_GTK4; + glade2 = libflag & LIB_FLAG_GLADE2; + + if (gtk2 > 0 && glade2 > 0 && (gtk3 == 0 && gtk4 == 0)) + { + return 2; + } + + if (gtk3 > 0 && (gtk2 == 0 && gtk4 == 0)) + { + return 3; + } + + if (gtk4 > 0 && (gtk2 == 0 && gtk3 == 0)) + { + return 4; + } + + if (gtk3 > 0) + { + return 3; + } + + if (gtk4 > 0) + { + return 4; + } + + if (gtk2 > 0 && glade2 > 0) + { + return 2; + } + + return 0; +} + +static int detect_qt_version(int libflag) +{ + int qt4; + int qt5; + int qt6; + + qt4 = libflag & LIB_FLAG_QT4; + qt5 = libflag & LIB_FLAG_QT5; + qt6 = libflag & LIB_FLAG_QT6; + + if (qt4 > 0 && (qt5 == 0 && qt6 == 0)) + { + return 4; + } + + if (qt5 > 0 && (qt4 == 0 && qt6 == 0)) + { + return 5; + } + + if (qt6 > 0 && (qt4 == 0 && qt5 == 0)) + { + return 6; + } + + if (qt5 > 0) + { + return 5; + } + + if (qt6 > 0) + { + return 6; + } + + if (qt4 > 0) + { + return 4; + } + + return 0; +} + +int bit_from_machine(const char *machine) +{ + if (strstr(machine, "64")) + { + return 64; + } + else + { + return 32; + } +} + +int get_os_bit(int *bit) +{ + int ret; + struct utsname unameData; + + memset(&unameData, 0, sizeof(unameData)); + ret = uname(&unameData); + if (ret != 0) + { + vlog("uname error, code: %d\n", errno); + return 1; + } + + *bit = strstr(unameData.machine, "64") ? 64 : 32; + vlog("uname -m <%s> %dbit\n", unameData.machine, *bit); + + return 0; +} + +int read_file_1st_line(const char *file, char *buffer, int buflen) +{ + FILE *fp = NULL; + + fp = fopen(file, "r"); + if (fp == NULL) + { + vlog("Failed to open file %s code:%d", file, errno); + return 1; + } + + fgets(buffer, buflen, fp); + fclose(fp); + return 0; +} + +static int read_pid_cmdline(long pid, char *Buffer, int BufLen) +{ + char path[256]; + + snprintf(path, sizeof(path), "/proc/%ld/cmdline", pid); + return read_file_1st_line(path, Buffer, BufLen); +} + +static int is_dir_exist(const char *fmt, ...) +{ + va_list arg; + struct stat st; + char path[4096]; + + va_start(arg, fmt); + vsnprintf(path, sizeof(path), fmt, arg); + va_end(arg); + + memset(&st, 0, sizeof(st)); + if (stat(path, &st) < 0) + { + return 0; + } + + if (st.st_mode & S_IFDIR) + { + return 1; + } + + return 0; +} + +static void touch_new_file(char *filename) +{ + char *pos = NULL; + FILE *fp = NULL; + + if (access(filename, F_OK) == -1) + { + for (pos = filename; *pos; pos++) + { + if (*pos == '/') + { + *pos = 0; + if (!is_dir_exist("%s", filename)) + { + mkdir(filename, 0755); + } + *pos = '/'; + } + } + + fp = fopen(filename, "w+"); + if (fp) + { + fclose(fp); + } + } +} + +static int find_exe_path(const char *exe, char *pathbuf, int buflen) +{ + int i; + char path[PATH_MAX]; + char *tmpptr = NULL; + char *saveptr = NULL; + char *newenv = NULL; + const char *env = getenv("PATH"); + + if (NULL == env) + { + return 0; + } + + newenv = strdup(env); + if (!newenv) + { + return 0; + } + + tmpptr = newenv; + while (NULL != (tmpptr = strtok_r(tmpptr, ":", &saveptr))) + { + snprintf(path, sizeof(path), "%s/%s", tmpptr, exe); + if (access(path, F_OK) != -1) + { + snprintf(pathbuf, buflen, "%s", path); + free(newenv); + return 1; + } + tmpptr = NULL; + } + + free(newenv); + return 0; +} + +void dump_args(const char *prefix, char **argv) +{ + int i = 0; + + vlog("=========%s ARGS BEGIN===========\n", prefix); + while (argv[i]) + { + vlog("argv[%d]=<%s>\n", i, argv[i]); + i++; + } + vlog("=========%s ARGS END===========\n", prefix); +} + +int pre_check(void) +{ + int ret; + int bit; + int buildbit; + const char *env = NULL; + + env = getenv("DISPLAY"); + if (NULL == env || env[0] != ':') + { + vlog("DISPLAY not exist(%p). Not in X environment.\n", env); + return 1; + } + + ret = get_os_bit(&bit); + if (ret) + { + vlog("Failed to get os bit.\n"); + return 1; + } + + buildbit = strstr(VTOY_GUI_ARCH, "64") ? 64 : 32; + vlog("Build bit is %d (%s)\n", buildbit, VTOY_GUI_ARCH); + + if (bit != buildbit) + { + vlog("Current system is %d bit (%s). Please run the correct VentoyGUI.\n", bit, VTOY_GUI_ARCH); + return 1; + } + + return 0; +} + +static char * find_argv(int argc, char **argv, char *key) +{ + int i; + int len; + + len = (int)strlen(key); + for (i = 0; i < argc; i++) + { + if (strncmp(argv[i], key, len) == 0) + { + return argv[i]; + } + } + + return NULL; +} + +static int adjust_cur_dir(char *argv0) +{ + int ret = 2; + char c; + char *pos = NULL; + char *end = NULL; + + if (argv0[0] == '.') + { + return 1; + } + + for (pos = argv0; pos && *pos; pos++) + { + if (*pos == '/') + { + end = pos; + } + } + + if (end) + { + c = *end; + *end = 0; + ret = chdir(argv0); + *end = c; + } + + return ret; +} + + + +static char **recover_environ_param(char *env) +{ + int i = 0; + int j = 0; + int k = 0; + int cnt = 0; + char **newenvs = NULL; + + for (i = 0; env[i]; i++) + { + if (env[i] == '\n') + { + cnt++; + } + } + + newenvs = malloc(sizeof(char *) * (cnt + 1)); + if (!newenvs) + { + vlog("malloc new envs fail %d\n", cnt + 1); + return NULL; + } + memset(newenvs, 0, sizeof(char *) * (cnt + 1)); + + for (j = i = 0; env[i]; i++) + { + if (env[i] == '\n') + { + env[i] = 0; + newenvs[k++] = env + j; + j = i + 1; + } + } + + vlog("recover environ %d %d\n", cnt, k); + return newenvs; +} + +static int restart_main(int argc, char **argv, char *guiexe) +{ + int i = 0; + int j = 0; + char *para = NULL; + char **envs = NULL; + char *newargv[MAX_PARAS + 1] = { NULL }; + + para = find_argv(argc, argv, VTOY_ENV_STR); + if (!para) + { + vlog("failed to find %s\n", VTOY_ENV_STR); + return 1; + } + + newargv[j++] = guiexe; + for (i = 1; i < argc && j < MAX_PARAS; i++) + { + if (strncmp(argv[i], "_vtoy_", 6) != 0) + { + newargv[j++] = argv[i]; + } + } + + envs = recover_environ_param(para + strlen(VTOY_ENV_STR)); + if (envs) + { + vlog("recover success, argc=%d evecve <%s>\n", j, guiexe); + dump_args("EXECVE", newargv); + execve(guiexe, newargv, envs); + } + else + { + vlog("recover failed, argc=%d evecv <%s>\n", j, guiexe); + execv(guiexe, newargv); + } + + return 1; +} + +static char *create_environ_param(const char *prefix, char **envs) +{ + int i = 0; + int cnt = 0; + int envlen = 0; + int prelen = 0; + char *cur = NULL; + char *para = NULL; + + prelen = strlen(prefix); + for (i = 0; envs[i]; i++) + { + cnt++; + envlen += strlen(envs[i]) + 1; + } + + para = malloc(prelen + envlen); + if (!para) + { + vlog("failed to malloc env str %d\n", prelen + envlen); + return NULL; + } + + cur = para; + memcpy(cur, prefix, prelen); + cur += prelen; + + for (i = 0; envs[i]; i++) + { + envlen = strlen(envs[i]); + memcpy(cur, envs[i], envlen); + + cur[envlen] = '\n'; + cur += envlen + 1; + } + + vlog("create environment param %d\n", cnt); + return para; +} + +static int restart_by_pkexec(int argc, char **argv, const char *curpath, const char *exe) +{ + int i = 0; + int j = 0; + char envcount[64]; + char path[PATH_MAX]; + char pkexec[PATH_MAX]; + char exepara[PATH_MAX]; + char *newargv[MAX_PARAS + 1] = { NULL }; + + vlog("try restart self by pkexec ...\n"); + + if (find_exe_path("pkexec", pkexec, sizeof(pkexec))) + { + vlog("Find pkexec at <%s>\n", pkexec); + } + else + { + vlog("pkexec not found\n"); + return 1; + } + + if (argv[0][0] != '/') + { + snprintf(path, sizeof(path), "%s/%s", curpath, argv[0]); + } + else + { + snprintf(path, sizeof(path), "%s", argv[0]); + } + snprintf(exepara, sizeof(exepara), "%s%s", VTOY_GUI_PATH, exe); + + newargv[j++] = pkexec; + newargv[j++] = path; + for (i = 1; i < argc && j < MAX_PARAS; i++) + { + if (strcmp(argv[i], "--xdg") == 0) + { + continue; + } + newargv[j++] = argv[i]; + } + + if (j < MAX_PARAS) + { + newargv[j++] = create_environ_param(VTOY_ENV_STR, environ); + } + + if (j < MAX_PARAS) + { + newargv[j++] = exepara; + } + + if (g_xdg_log && j + 1 < MAX_PARAS) + { + newargv[j++] = "-l"; + newargv[j++] = g_log_file; + } + + if (g_xdg_ini && j + 1 < MAX_PARAS) + { + newargv[j++] = "-i"; + newargv[j++] = g_ini_file; + } + + dump_args("PKEXEC", newargv); + execv(pkexec, newargv); + + return 1; +} + +static int ld_cache_lib_check(const char *lib, int *flag) +{ + if (((*flag) & LIB_FLAG_GTK3) == 0) + { + if (strncmp(lib, "libgtk-3.so", 11) == 0) + { + vlog("LIB:<%s>\n", lib); + *flag |= LIB_FLAG_GTK3; + return 0; + } + } + + if (((*flag) & LIB_FLAG_GTK2) == 0) + { + if (strncmp(lib, "libgtk-x11-2.0.so", 17) == 0) + { + vlog("LIB:<%s>\n", lib); + *flag |= LIB_FLAG_GTK2; + return 0; + } + } + + if (((*flag) & LIB_FLAG_GTK4) == 0) + { + if (strncmp(lib, "libgtk-4.so", 11) == 0) + { + vlog("LIB:<%s>\n", lib); + *flag |= LIB_FLAG_GTK4; + return 0; + } + } + + if (((*flag) & LIB_FLAG_QT4) == 0) + { + if (strncmp(lib, "libQt4", 6) == 0) + { + vlog("LIB:<%s>\n", lib); + *flag |= LIB_FLAG_QT4; + return 0; + } + } + + if (((*flag) & LIB_FLAG_QT5) == 0) + { + if (strncmp(lib, "libQt5", 6) == 0) + { + vlog("LIB:<%s>\n", lib); + *flag |= LIB_FLAG_QT5; + return 0; + } + } + + if (((*flag) & LIB_FLAG_QT6) == 0) + { + if (strncmp(lib, "libQt6", 6) == 0) + { + vlog("LIB:<%s>\n", lib); + *flag |= LIB_FLAG_QT6; + return 0; + } + } + + if (((*flag) & LIB_FLAG_GLADE2) == 0) + { + if (strncmp(lib, "libglade-2", 10) == 0) + { + vlog("LIB:<%s>\n", lib); + *flag |= LIB_FLAG_GLADE2; + return 0; + } + } + + return 0; +} + +static int parse_ld_cache(int *flag) +{ + int fd; + int format; + unsigned int i; + struct stat st; + size_t offset = 0; + size_t cache_size = 0; + const char *cache_data = NULL; + struct cache_file *cache = NULL; + struct cache_file_new *cache_new = NULL; + + *flag = 0; + + fd = open(LD_CACHE_FILE, O_RDONLY); + if (fd < 0) + { + vlog("failed to open %s err:%d\n", LD_CACHE_FILE, errno); + return 1; + } + + if (fstat(fd, &st) < 0 || st.st_size == 0) + { + close(fd); + return 1; + } + + cache = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + if (cache == MAP_FAILED) + { + close(fd); + return 1; + } + + cache_size = st.st_size; + if (cache_size < sizeof (struct cache_file)) + { + vlog("File is not a cache file.\n"); + munmap (cache, cache_size); + close(fd); + return 1; + } + + if (memcmp(cache->magic, CACHEMAGIC, sizeof CACHEMAGIC - 1)) + { + /* This can only be the new format without the old one. */ + cache_new = (struct cache_file_new *) cache; + + if (memcmp(cache_new->magic, CACHEMAGIC_NEW, sizeof CACHEMAGIC_NEW - 1) || + memcmp (cache_new->version, CACHE_VERSION, sizeof CACHE_VERSION - 1)) + { + munmap (cache, cache_size); + close(fd); + return 1; + } + + format = 1; + /* This is where the strings start. */ + cache_data = (const char *) cache_new; + } + else + { + /* Check for corruption, avoiding overflow. */ + if ((cache_size - sizeof (struct cache_file)) / sizeof (struct file_entry) < cache->nlibs) + { + vlog("File is not a cache file.\n"); + munmap (cache, cache_size); + close(fd); + return 1; + } + + offset = ALIGN_CACHE(sizeof (struct cache_file) + (cache->nlibs * sizeof (struct file_entry))); + + /* This is where the strings start. */ + cache_data = (const char *) &cache->libs[cache->nlibs]; + + /* Check for a new cache embedded in the old format. */ + if (cache_size > (offset + sizeof (struct cache_file_new))) + { + cache_new = (struct cache_file_new *) ((void *)cache + offset); + + if (memcmp(cache_new->magic, CACHEMAGIC_NEW, sizeof CACHEMAGIC_NEW - 1) == 0 && + memcmp(cache_new->version, CACHE_VERSION, sizeof CACHE_VERSION - 1) == 0) + { + cache_data = (const char *) cache_new; + format = 1; + } + } + } + + if (format == 0) + { + vlog("%d libs found in cache format 0\n", cache->nlibs); + for (i = 0; i < cache->nlibs; i++) + { + ld_cache_lib_check(cache_data + cache->libs[i].key, flag); + } + } + else if (format == 1) + { + vlog("%d libs found in cache format 1\n", cache_new->nlibs); + + for (i = 0; i < cache_new->nlibs; i++) + { + ld_cache_lib_check(cache_data + cache_new->libs[i].key, flag); + } + } + + vlog("ldconfig lib flags 0x%x\n", *flag); + vlog("lib flags GLADE2:[%s] GTK2:[%s] GTK3:[%s] GTK4:[%s] QT4:[%s] QT5:[%s] QT6:[%s]\n", + INT2STR_YN((*flag) & LIB_FLAG_GLADE2), INT2STR_YN((*flag) & LIB_FLAG_GTK2), + INT2STR_YN((*flag) & LIB_FLAG_GTK3), INT2STR_YN((*flag) & LIB_FLAG_GTK4), + INT2STR_YN((*flag) & LIB_FLAG_QT4), INT2STR_YN((*flag) & LIB_FLAG_QT5), + INT2STR_YN((*flag) & LIB_FLAG_QT6)); + + munmap (cache, cache_size); + close (fd); + return 0; +} + +static int gui_type_check(VTOY_JSON *pstNode) +{ + FILE *fp = NULL; + const char *env = NULL; + const char *arch = NULL; + const char *srctype = NULL; + const char *srcname = NULL; + const char *condition = NULL; + const char *expression = NULL; + char line[1024]; + + arch = vtoy_json_get_string_ex(pstNode, "arch"); + srctype = vtoy_json_get_string_ex(pstNode, "type"); + srcname = vtoy_json_get_string_ex(pstNode, "name"); + condition = vtoy_json_get_string_ex(pstNode, "condition"); + expression = vtoy_json_get_string_ex(pstNode, "expression"); + + if (srctype == NULL || srcname == NULL || condition == NULL) + { + return 0; + } + + if (arch && NULL == strstr(arch, VTOY_GUI_ARCH)) + { + return 0; + } + + vlog("check <%s> <%s> <%s>\n", srctype, srcname, condition); + + if (strcmp(srctype, "file") == 0) + { + if (access(srcname, F_OK) == -1) + { + return 0; + } + + if (strcmp(condition, "exist") == 0) + { + vlog("File %s exist\n", srcname); + return 1; + } + else if (strcmp(condition, "contains") == 0) + { + fp = fopen(srcname, "r"); + if (fp == NULL) + { + return 0; + } + + while (fgets(line, sizeof(line), fp)) + { + if (strstr(line, expression)) + { + vlog("File %s contains %s\n", srcname, expression); + fclose(fp); + return 1; + } + } + + fclose(fp); + return 0; + } + } + else if (strcmp(srctype, "env") == 0) + { + env = getenv(srcname); + if (env == NULL) + { + return 0; + } + + if (strcmp(condition, "exist") == 0) + { + vlog("env %s exist\n", srcname); + return 1; + } + else if (strcmp(condition, "equal") == 0) + { + if (strcmp(expression, env) == 0) + { + vlog("env %s is %s\n", srcname, env); + return 1; + } + return 0; + } + else if (strcmp(condition, "contains") == 0) + { + if (strstr(env, expression)) + { + vlog("env %s is %s contains %s\n", srcname, env, expression); + return 1; + } + return 0; + } + } + + return 0; +} + +static int read_file_to_buf(const char *FileName, int ExtLen, void **Bufer, int *BufLen) +{ + int FileSize; + FILE *fp = NULL; + void *Data = NULL; + + fp = fopen(FileName, "rb"); + if (fp == NULL) + { + vlog("Failed to open file %s", FileName); + return 1; + } + + fseek(fp, 0, SEEK_END); + FileSize = (int)ftell(fp); + + Data = malloc(FileSize + ExtLen); + if (!Data) + { + fclose(fp); + return 1; + } + + fseek(fp, 0, SEEK_SET); + fread(Data, 1, FileSize, fp); + + fclose(fp); + + *Bufer = Data; + *BufLen = FileSize; + + return 0; +} + +static int distro_check_gui_env(char *type, int len, int *pver) +{ + int size; + int length; + char *pBuf = NULL; + VTOY_JSON *pstNode = NULL; + VTOY_JSON *pstJson = NULL; + + vlog("distro_check_gui_env ...\n"); + + if (access("./tool/distro_gui_type.json", F_OK) == -1) + { + vlog("distro_gui_type.json file not exist\n"); + return 0; + } + + read_file_to_buf("./tool/distro_gui_type.json", 1, (void **)&pBuf, &size); + pBuf[size] = 0; + + pstJson = vtoy_json_create(); + vtoy_json_parse(pstJson, pBuf); + + for (pstNode = pstJson->pstChild; pstNode; pstNode = pstNode->pstNext) + { + if (gui_type_check(pstNode->pstChild)) + { + length = (int)snprintf(type, len, "%s", vtoy_json_get_string_ex(pstNode->pstChild, "gui")); + *pver = type[length - 1] - '0'; + type[length - 1] = 0; + break; + } + } + + vtoy_json_destroy(pstJson); + return pstNode ? 1 : 0; +} + +static int detect_gui_exe_path(int argc, char **argv, const char *curpath, char *pathbuf, int buflen) +{ + int i; + int ret; + int ver; + int libflag = 0; + const char *guitype = NULL; + char line[256]; + mode_t mode; + struct stat filestat; + + for (i = 1; i < argc; i++) + { + if (argv[i] && strcmp(argv[i], "--gtk2") == 0) + { + guitype = "gtk"; + ver = 2; + } + else if (argv[i] && strcmp(argv[i], "--gtk3") == 0) + { + guitype = "gtk"; + ver = 3; + } + else if (argv[i] && strcmp(argv[i], "--gtk4") == 0) + { + guitype = "gtk"; + ver = 4; + } + else if (argv[i] && strcmp(argv[i], "--qt4") == 0) + { + guitype = "qt"; + ver = 4; + } + else if (argv[i] && strcmp(argv[i], "--qt5") == 0) + { + guitype = "qt"; + ver = 5; + } + else if (argv[i] && strcmp(argv[i], "--qt6") == 0) + { + guitype = "qt"; + ver = 6; + } + } + + if (guitype) + { + vlog("Get GUI type from param <%s%d>.\n", guitype, ver); + } + else if (access("./ventoy_gui_type", F_OK) != -1) + { + vlog("Get GUI type from ventoy_gui_type file.\n"); + + line[0] = 0; + read_file_1st_line("./ventoy_gui_type", line, sizeof(line)); + if (strncmp(line, "gtk2", 4) == 0) + { + guitype = "gtk"; + ver = 2; + + parse_ld_cache(&libflag); + if ((libflag & LIB_FLAG_GLADE2) == 0) + { + vlog("libglade2 is necessary for GTK2, but not found.\n"); + return 1; + } + } + else if (strncmp(line, "gtk3", 4) == 0) + { + guitype = "gtk"; + ver = 3; + } + else if (strncmp(line, "gtk4", 4) == 0) + { + guitype = "gtk"; + ver = 4; + } + else if (strncmp(line, "qt4", 3) == 0) + { + guitype = "qt"; + ver = 4; + } + else if (strncmp(line, "qt5", 3) == 0) + { + guitype = "qt"; + ver = 5; + } + else if (strncmp(line, "qt6", 3) == 0) + { + guitype = "qt"; + ver = 6; + } + else + { + vlog("Current X environment is NOT supported.\n"); + return 1; + } + } + else + { + vlog("Now detect the GUI type ...\n"); + + parse_ld_cache(&libflag); + + if ((LIB_FLAG_GTK & libflag) > 0 && (LIB_FLAG_QT & libflag) == 0) + { + guitype = "gtk"; + ver = detect_gtk_version(libflag); + } + else if ((LIB_FLAG_GTK & libflag) == 0 && (LIB_FLAG_QT & libflag) > 0) + { + guitype = "qt"; + ver = detect_qt_version(libflag); + } + else if ((LIB_FLAG_GTK & libflag) > 0 && (LIB_FLAG_QT & libflag) > 0) + { + if (distro_check_gui_env(line, sizeof(line), &ver)) + { + guitype = line; + vlog("distro_check_gui <%s%d> ...\n", line, ver); + } + else if (is_gtk_env()) + { + guitype = "gtk"; + ver = detect_gtk_version(libflag); + } + else if (is_qt_env()) + { + guitype = "qt"; + ver = detect_qt_version(libflag); + } + else + { + vlog("Can not distinguish GTK and QT, default use GTK.\n"); + guitype = "gtk"; + ver = detect_gtk_version(libflag); + } + } + else + { + vlog("Current X environment is NOT supported.\n"); + return 1; + } + } + + snprintf(pathbuf, buflen, "%s/tool/%s/Ventoy2Disk.%s%d", curpath, VTOY_GUI_ARCH, guitype, ver); + + vlog("This is %s%d X environment.\n", guitype, ver); + vlog("exe = %s\n", pathbuf); + + if (access(pathbuf, F_OK) == -1) + { + vlog("%s is not exist.\n", pathbuf); + return 1; + } + + if (access(pathbuf, X_OK) == -1) + { + vlog("execute permission check fail, try chmod.\n", pathbuf); + if (stat(pathbuf, &filestat) == 0) + { + mode = filestat.st_mode | S_IXUSR | S_IXGRP | S_IXOTH; + ret = chmod(pathbuf, mode); + vlog("old mode=%o new mode=%o ret=%d\n", filestat.st_mode, mode, ret); + } + } + else + { + vlog("execute permission check success.\n"); + } + + return 0; +} + +int real_main(int argc, char **argv) +{ + int ret; + int euid; + char *exe = NULL; + const char *env = NULL; + char path[PATH_MAX]; + char curpath[PATH_MAX]; + + ret = adjust_cur_dir(argv[0]); + + vlog("\n"); + vlog("=========================================================\n"); + vlog("=========================================================\n"); + vlog("=============== VentoyGui %s ===============\n", VTOY_GUI_ARCH); + vlog("=========================================================\n"); + vlog("=========================================================\n"); + vlog("log file is <%s>\n", g_log_file); + + euid = geteuid(); + getcwd(curpath, sizeof(curpath)); + + vlog("pid:%ld ppid:%ld uid:%d euid:%d\n", (long)getpid(), (long)getppid(), getuid(), euid); + vlog("adjust dir:%d current path:%s\n", ret, curpath); + dump_args("RAW", argv); + + if (access("./boot/boot.img", F_OK) == -1) + { + vlog("Please run under the correct directory!\n"); + return 1; + } + + exe = find_argv(argc, argv, VTOY_GUI_PATH); + if (exe) + { + if (euid != 0) + { + vlog("Invalid euid %d when restart.\n", euid); + return 1; + } + + return restart_main(argc, argv, exe + strlen(VTOY_GUI_PATH)); + } + else + { + if (pre_check()) + { + return 1; + } + + if (detect_gui_exe_path(argc, argv, curpath, path, sizeof(path))) + { + return 1; + } + + if (strstr(path, "gtk")) + { + env = getenv("XDG_SESSION_TYPE"); + vlog("=== XDG_SESSION_TYPE is <%s> ===\n", env ? env : "NULL"); + + if (env && strncasecmp(env, "wayland", 7) == 0) + { + vlog("Force GDK_BACKEND from %s to x11 for better compatibility\n", env); + setenv("GDK_BACKEND", "x11", 1); + } + } + + if (euid == 0) + { + vlog("We have root privileges, just exec %s\n", path); + argv[0] = path; + execv(argv[0], argv); + } + else + { + vlog("EUID check failed.\n"); + + /* try pkexec */ + restart_by_pkexec(argc, argv, curpath, path); + + vlog("### Please run with root privileges. ###\n"); + return 1; + } + } + + return 1; +} + +int main(int argc, char **argv) +{ + int i; + int ret; + const char *env = NULL; + + snprintf(g_log_file, sizeof(g_log_file), "log.txt"); + for (i = 0; i < argc; i++) + { + if (argv[i] && argv[i + 1] && strcmp(argv[i], "-l") == 0) + { + touch_new_file(argv[i + 1]); + snprintf(g_log_file, sizeof(g_log_file), "%s", argv[i + 1]); + } + else if (argv[i] && argv[i + 1] && strcmp(argv[i], "-i") == 0) + { + touch_new_file(argv[i + 1]); + } + else if (argv[i] && strcmp(argv[i], "--xdg") == 0) + { + env = getenv("XDG_CACHE_HOME"); + if (env) + { + g_xdg_log = 1; + snprintf(g_log_file, sizeof(g_log_file), "%s/ventoy/ventoy.log", env); + touch_new_file(g_log_file); + } + else + { + env = getenv("HOME"); + if (env && is_dir_exist("%s/.cache", env)) + { + g_xdg_log = 1; + snprintf(g_log_file, sizeof(g_log_file), "%s/.cache/ventoy/ventoy.log", env); + touch_new_file(g_log_file); + } + } + + env = getenv("XDG_CONFIG_HOME"); + if (env) + { + g_xdg_ini = 1; + snprintf(g_ini_file, sizeof(g_ini_file), "%s/ventoy/Ventoy2Disk.ini", env); + touch_new_file(g_ini_file); + } + else + { + env = getenv("HOME"); + if (env && is_dir_exist("%s/.config", env)) + { + g_xdg_ini = 1; + snprintf(g_ini_file, sizeof(g_ini_file), "%s/.config/ventoy/Ventoy2Disk.ini", env); + touch_new_file(g_ini_file); + } + } + } + } + + g_log_buf = malloc(MAX_LOG_BUF); + if (!g_log_buf) + { + vlog("Failed to malloc log buffer %d\n", MAX_LOG_BUF); + return 1; + } + + ret = real_main(argc, argv); + free(g_log_buf); + return ret; +} + diff --git a/LinuxGUI/WebUI/favicon.ico b/LinuxGUI/WebUI/favicon.ico new file mode 100644 index 0000000..9c4273b Binary files /dev/null and b/LinuxGUI/WebUI/favicon.ico differ diff --git a/LinuxGUI/WebUI/index.html b/LinuxGUI/WebUI/index.html new file mode 100644 index 0000000..fa90c04 --- /dev/null +++ b/LinuxGUI/WebUI/index.html @@ -0,0 +1,1103 @@ + + + + + + + + + Ventoy2Disk + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + +
+
+ + +
+
+
+ 设备 +
+ +
+ +
+ +
+ +
+
+ +
+
+
+

安装包内 Ventoy 版本

+
+
+ + + +
+
+ +
+
+

设备内部 Ventoy 版本

+
+
+ + + +
+
+
+ +
+ 状态 - 准备就绪 +
+
+
+
+
+ +
+ + +
+
+ + + + + + + +
+
+ +
+ + +
+ + + + + diff --git a/LinuxGUI/WebUI/static/AdminLTE/css/AdminLTE.min.css b/LinuxGUI/WebUI/static/AdminLTE/css/AdminLTE.min.css new file mode 100644 index 0000000..fd35437 --- /dev/null +++ b/LinuxGUI/WebUI/static/AdminLTE/css/AdminLTE.min.css @@ -0,0 +1,8 @@ +/**@import url(https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic); **/ +/*! + * AdminLTE v2.3.0 + * Author: Almsaeed Studio + * Website: Almsaeed Studio + * License: Open source - MIT + * Please visit http://opensource.org/licenses/MIT for more information +!*/html,body{/*min-height:100%*/}.layout-boxed html,.layout-boxed body{height:100%}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:'Arial','Microsoft YaHei','ºÚÌå','ËÎÌå',sans-serif;font-weight:400;overflow-x:hidden;overflow-y:auto}.wrapper{min-height:100%;position:static;overflow:hidden}.wrapper:before,.wrapper:after{content:" ";display:table}.wrapper:after{clear:both}.layout-boxed .wrapper{max-width:1250px;margin:0 auto;min-height:100%;box-shadow:0 0 8px rgba(0,0,0,0.5);position:relative}.layout-boxed{background:url('../img/boxed-bg.jpg') repeat fixed}.content-wrapper,.right-side,.main-footer{-webkit-transition:-webkit-transform .3s ease-in-out,margin .3s ease-in-out;-moz-transition:-moz-transform .3s ease-in-out,margin .3s ease-in-out;-o-transition:-o-transform .3s ease-in-out,margin .3s ease-in-out;transition:transform .3s ease-in-out,margin .3s ease-in-out;margin-left:230px;z-index:820}.layout-top-nav .content-wrapper,.layout-top-nav .right-side,.layout-top-nav .main-footer{margin-left:0}@media (max-width:767px){.content-wrapper,.right-side,.main-footer{margin-left:0}}@media (min-width:768px){.sidebar-collapse .content-wrapper,.sidebar-collapse .right-side,.sidebar-collapse .main-footer{margin-left:0}}@media (max-width:767px){.sidebar-open .content-wrapper,.sidebar-open .right-side,.sidebar-open .main-footer{-webkit-transform:translate(230px, 0);-ms-transform:translate(230px, 0);-o-transform:translate(230px, 0);transform:translate(230px, 0)}}.content-wrapper,.right-side{min-height:100%;background-color:#ecf0f5;z-index:800}.main-footer{background:#fff;padding:15px;color:#444;border-top:1px solid #d2d6de}.fixed .main-header,.fixed .main-sidebar,.fixed .left-side{position:fixed}.fixed .main-header{top:0;right:0;left:0}.fixed .content-wrapper,.fixed .right-side{padding-top:50px}@media (max-width:767px){.fixed .content-wrapper,.fixed .right-side{padding-top:100px}}.fixed.layout-boxed .wrapper{max-width:100%}body.hold-transition .content-wrapper,body.hold-transition .right-side,body.hold-transition .main-footer,body.hold-transition .main-sidebar,body.hold-transition .left-side,body.hold-transition .main-header>.navbar,body.hold-transition .main-header .logo{-webkit-transition:none;-o-transition:none;transition:none}.content{min-height:250px;padding:15px;margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:'Arial','Microsoft YaHei','ºÚÌå','ËÎÌå',sans-serif}a{color:#3c8dbc}a:hover,a:active,a:focus{outline:none;text-decoration:none;color:#72afd2}.page-header{margin:10px 0 20px 0;font-size:22px}.page-header>small{color:#666;display:block;margin-top:5px}.main-header{position:relative;max-height:100px;z-index:1030}.main-header>.navbar{-webkit-transition:margin-left .3s ease-in-out;-o-transition:margin-left .3s ease-in-out;transition:margin-left .3s ease-in-out;margin-bottom:0;margin-left:230px;border:none;min-height:50px;border-radius:0}.layout-top-nav .main-header>.navbar{margin-left:0}.main-header #navbar-search-input.form-control{background:rgba(255,255,255,0.2);border-color:transparent}.main-header #navbar-search-input.form-control:focus,.main-header #navbar-search-input.form-control:active{border-color:rgba(0,0,0,0.1);background:rgba(255,255,255,0.9)}.main-header #navbar-search-input.form-control::-moz-placeholder{color:#ccc;opacity:1}.main-header #navbar-search-input.form-control:-ms-input-placeholder{color:#ccc}.main-header #navbar-search-input.form-control::-webkit-input-placeholder{color:#ccc}.main-header .navbar-custom-menu,.main-header .navbar-right{float:right}@media (max-width:991px){.main-header .navbar-custom-menu a,.main-header .navbar-right a{color:inherit;background:transparent}}@media (max-width:767px){.main-header .navbar-right{float:none}.navbar-collapse .main-header .navbar-right{margin:7.5px -15px}.main-header .navbar-right>li{color:inherit;border:0}}.main-header .sidebar-toggle{float:left;background-color:transparent;background-image:none;padding:15px 15px;font-family:fontAwesome}.main-header .sidebar-toggle:before{content:"\f0c9"}.main-header .sidebar-toggle:hover{color:#fff}.main-header .sidebar-toggle:focus,.main-header .sidebar-toggle:active{background:transparent}.main-header .sidebar-toggle .icon-bar{display:none}.main-header .navbar .nav>li.user>a>.fa,.main-header .navbar .nav>li.user>a>.glyphicon,.main-header .navbar .nav>li.user>a>.ion{margin-right:5px}.main-header .navbar .nav>li>a>.label{position:absolute;top:9px;right:7px;text-align:center;font-size:9px;padding:2px 3px;line-height:.9}.main-header .logo{-webkit-transition:width .3s ease-in-out;-o-transition:width .3s ease-in-out;transition:width .3s ease-in-out;display:block;float:left;height:50px;font-size:20px;line-height:50px;text-align:center;width:230px;font-family:'Arial','Microsoft YaHei','ºÚÌå','ËÎÌå',sans-serif;padding:0 15px;font-weight:300;overflow:hidden}.main-header .logo .logo-lg{display:block}.main-header .logo .logo-mini{display:none}.main-header .navbar-brand{color:#fff}.content-header{position:relative;padding:15px 15px 0 15px}.content-header>h1{margin:0;font-size:24px}.content-header>h1>small{font-size:15px;display:inline-block;padding-left:4px;font-weight:300}.content-header>.breadcrumb{float:right;background:transparent;margin-top:0;margin-bottom:0;font-size:12px;padding:7px 5px;position:absolute;top:15px;right:10px;border-radius:2px}.content-header>.breadcrumb>li>a{color:#444;text-decoration:none;display:inline-block}.content-header>.breadcrumb>li>a>.fa,.content-header>.breadcrumb>li>a>.glyphicon,.content-header>.breadcrumb>li>a>.ion{margin-right:5px}.content-header>.breadcrumb>li+li:before{content:'>\00a0'}@media (max-width:991px){.content-header>.breadcrumb{position:relative;margin-top:5px;top:0;right:0;float:none;background:#d2d6de;padding-left:10px}.content-header>.breadcrumb li:before{color:#97a0b3}}.navbar-toggle{color:#fff;border:0;margin:0;padding:15px 15px}@media (max-width:991px){.navbar-custom-menu .navbar-nav>li{float:left}.navbar-custom-menu .navbar-nav{margin:0;float:left}.navbar-custom-menu .navbar-nav>li>a{padding-top:15px;padding-bottom:15px;line-height:20px}}@media (max-width:767px){.main-header{position:relative}.main-header .logo,.main-header .navbar{width:100%;float:none}.main-header .navbar{margin:0}.main-header .navbar-custom-menu{float:right}}@media (max-width:991px){.navbar-collapse.pull-left{float:none!important}.navbar-collapse.pull-left+.navbar-custom-menu{display:block;position:absolute;top:0;right:40px}}.main-sidebar,.left-side{position:absolute;top:0;left:0;padding-top:50px;min-height:100%;width:230px;z-index:810;-webkit-transition:-webkit-transform .3s ease-in-out,width .3s ease-in-out;-moz-transition:-moz-transform .3s ease-in-out,width .3s ease-in-out;-o-transition:-o-transform .3s ease-in-out,width .3s ease-in-out;transition:transform .3s ease-in-out,width .3s ease-in-out}@media (max-width:767px){.main-sidebar,.left-side{padding-top:100px}}@media (max-width:767px){.main-sidebar,.left-side{-webkit-transform:translate(-230px, 0);-ms-transform:translate(-230px, 0);-o-transform:translate(-230px, 0);transform:translate(-230px, 0)}}@media (min-width:768px){.sidebar-collapse .main-sidebar,.sidebar-collapse .left-side{-webkit-transform:translate(-230px, 0);-ms-transform:translate(-230px, 0);-o-transform:translate(-230px, 0);transform:translate(-230px, 0)}}@media (max-width:767px){.sidebar-open .main-sidebar,.sidebar-open .left-side{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0)}}.sidebar{padding-bottom:10px}.sidebar-form input:focus{border-color:transparent}.user-panel{position:relative;width:100%;padding:10px;overflow:hidden}.user-panel:before,.user-panel:after{content:" ";display:table}.user-panel:after{clear:both}.user-panel>.image>img{width:100%;max-width:45px;height:auto}.user-panel>.info{padding:5px 5px 5px 15px;line-height:1;position:absolute;left:55px}.user-panel>.info>p{font-weight:600;margin-bottom:9px}.user-panel>.info>a{text-decoration:none;padding-right:5px;margin-top:3px;font-size:11px}.user-panel>.info>a>.fa,.user-panel>.info>a>.ion,.user-panel>.info>a>.glyphicon{margin-right:3px}.sidebar-menu{list-style:none;margin:0;padding:0}.sidebar-menu>li{position:relative;margin:0;padding:0}.sidebar-menu>li>a{padding:12px 5px 12px 15px;display:block}.sidebar-menu>li>a>.fa,.sidebar-menu>li>a>.glyphicon,.sidebar-menu>li>a>.ion{width:20px}.sidebar-menu>li .label,.sidebar-menu>li .badge{margin-top:3px;margin-right:5px}.sidebar-menu li.header{padding:10px 25px 10px 15px;font-size:12px}.sidebar-menu li>a>.fa-angle-left{width:auto;height:auto;padding:0;margin-right:10px;margin-top:3px}.sidebar-menu li.active>a>.fa-angle-left{-webkit-transform:rotate(-90deg);-ms-transform:rotate(-90deg);-o-transform:rotate(-90deg);transform:rotate(-90deg)}.sidebar-menu li.active>.treeview-menu{display:block}.sidebar-menu .treeview-menu{display:none;list-style:none;padding:0;margin:0;padding-left:5px}.sidebar-menu .treeview-menu .treeview-menu{padding-left:20px}.sidebar-menu .treeview-menu>li{margin:0}.sidebar-menu .treeview-menu>li>a{padding:5px 5px 5px 15px;display:block;font-size:14px}.sidebar-menu .treeview-menu>li>a>.fa,.sidebar-menu .treeview-menu>li>a>.glyphicon,.sidebar-menu .treeview-menu>li>a>.ion{width:20px}.sidebar-menu .treeview-menu>li>a>.fa-angle-left,.sidebar-menu .treeview-menu>li>a>.fa-angle-down{width:auto}@media (min-width:768px){.sidebar-mini.sidebar-collapse .content-wrapper,.sidebar-mini.sidebar-collapse .right-side,.sidebar-mini.sidebar-collapse .main-footer{margin-left:50px!important;z-index:840}.sidebar-mini.sidebar-collapse .main-sidebar{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0);width:50px!important;z-index:850}.sidebar-mini.sidebar-collapse .sidebar-menu>li{position:relative}.sidebar-mini.sidebar-collapse .sidebar-menu>li>a{margin-right:0}.sidebar-mini.sidebar-collapse .sidebar-menu>li>a>span{border-top-right-radius:4px}.sidebar-mini.sidebar-collapse .sidebar-menu>li:not(.treeview)>a>span{border-bottom-right-radius:4px}.sidebar-mini.sidebar-collapse .sidebar-menu>li>.treeview-menu{padding-top:5px;padding-bottom:5px;border-bottom-right-radius:4px}.sidebar-mini.sidebar-collapse .sidebar-menu>li:hover>a>span:not(.pull-right),.sidebar-mini.sidebar-collapse .sidebar-menu>li:hover>.treeview-menu{display:block!important;position:absolute;width:180px;left:50px}.sidebar-mini.sidebar-collapse .sidebar-menu>li:hover>a>span{top:0;margin-left:-3px;padding:12px 5px 12px 20px;background-color:inherit}.sidebar-mini.sidebar-collapse .sidebar-menu>li:hover>.treeview-menu{top:44px;margin-left:0}.sidebar-mini.sidebar-collapse .main-sidebar .user-panel>.info,.sidebar-mini.sidebar-collapse .sidebar-form,.sidebar-mini.sidebar-collapse .sidebar-menu>li>a>span,.sidebar-mini.sidebar-collapse .sidebar-menu>li>.treeview-menu,.sidebar-mini.sidebar-collapse .sidebar-menu>li>a>.pull-right,.sidebar-mini.sidebar-collapse .sidebar-menu li.header{display:none!important;-webkit-transform:translateZ(0)}.sidebar-mini.sidebar-collapse .main-header .logo{width:50px}.sidebar-mini.sidebar-collapse .main-header .logo>.logo-mini{display:block;margin-left:-15px;margin-right:-15px;font-size:18px}.sidebar-mini.sidebar-collapse .main-header .logo>.logo-lg{display:none}.sidebar-mini.sidebar-collapse .main-header .navbar{margin-left:50px}}.sidebar-menu,.main-sidebar .user-panel,.sidebar-menu>li.header{white-space:nowrap;overflow:hidden}.sidebar-menu:hover{overflow:visible}.sidebar-form,.sidebar-menu>li.header{overflow:hidden;text-overflow:clip}.sidebar-menu li>a{position:relative}.sidebar-menu li>a>.pull-right{position:absolute;top:50%;right:10px;margin-top:-7px}.control-sidebar-bg{position:fixed;z-index:1000;bottom:0}.control-sidebar-bg,.control-sidebar{top:0;right:-230px;width:230px;-webkit-transition:right .3s ease-in-out;-o-transition:right .3s ease-in-out;transition:right .3s ease-in-out}.control-sidebar{position:absolute;padding-top:50px;z-index:1010}@media (max-width:768px){.control-sidebar{padding-top:100px}}.control-sidebar>.tab-content{padding:10px 15px}.control-sidebar.control-sidebar-open,.control-sidebar.control-sidebar-open+.control-sidebar-bg{right:0}.control-sidebar-open .control-sidebar-bg,.control-sidebar-open .control-sidebar{right:0}@media (min-width:768px){.control-sidebar-open .content-wrapper,.control-sidebar-open .right-side,.control-sidebar-open .main-footer{margin-right:230px}}.nav-tabs.control-sidebar-tabs>li:first-of-type>a,.nav-tabs.control-sidebar-tabs>li:first-of-type>a:hover,.nav-tabs.control-sidebar-tabs>li:first-of-type>a:focus{border-left-width:0}.nav-tabs.control-sidebar-tabs>li>a{border-radius:0}.nav-tabs.control-sidebar-tabs>li>a,.nav-tabs.control-sidebar-tabs>li>a:hover{border-top:none;border-right:none;border-left:1px solid transparent;border-bottom:1px solid transparent}.nav-tabs.control-sidebar-tabs>li>a .icon{font-size:16px}.nav-tabs.control-sidebar-tabs>li.active>a,.nav-tabs.control-sidebar-tabs>li.active>a:hover,.nav-tabs.control-sidebar-tabs>li.active>a:focus,.nav-tabs.control-sidebar-tabs>li.active>a:active{border-top:none;border-right:none;border-bottom:none}@media (max-width:768px){.nav-tabs.control-sidebar-tabs{display:table}.nav-tabs.control-sidebar-tabs>li{display:table-cell}}.control-sidebar-heading{font-weight:400;font-size:16px;padding:10px 0;margin-bottom:10px}.control-sidebar-subheading{display:block;font-weight:400;font-size:14px}.control-sidebar-menu{list-style:none;padding:0;margin:0 -15px}.control-sidebar-menu>li>a{display:block;padding:10px 15px}.control-sidebar-menu>li>a:before,.control-sidebar-menu>li>a:after{content:" ";display:table}.control-sidebar-menu>li>a:after{clear:both}.control-sidebar-menu>li>a>.control-sidebar-subheading{margin-top:0}.control-sidebar-menu .menu-icon{float:left;width:35px;height:35px;border-radius:50%;text-align:center;line-height:35px}.control-sidebar-menu .menu-info{margin-left:45px;margin-top:3px}.control-sidebar-menu .menu-info>.control-sidebar-subheading{margin:0}.control-sidebar-menu .menu-info>p{margin:0;font-size:11px}.control-sidebar-menu .progress{margin:0}.control-sidebar-dark{color:#b8c7ce}.control-sidebar-dark,.control-sidebar-dark+.control-sidebar-bg{background:#222d32}.control-sidebar-dark .nav-tabs.control-sidebar-tabs{border-bottom:#1c2529}.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a{background:#181f23;color:#b8c7ce}.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a:hover,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a:focus{border-left-color:#141a1d;border-bottom-color:#141a1d}.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a:hover,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a:focus,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a:active{background:#1c2529}.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a:hover{color:#fff}.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li.active>a,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li.active>a:hover,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li.active>a:focus,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li.active>a:active{background:#222d32;color:#fff}.control-sidebar-dark .control-sidebar-heading,.control-sidebar-dark .control-sidebar-subheading{color:#fff}.control-sidebar-dark .control-sidebar-menu>li>a:hover{background:#1e282c}.control-sidebar-dark .control-sidebar-menu>li>a .menu-info>p{color:#b8c7ce}.control-sidebar-light{color:#5e5e5e}.control-sidebar-light,.control-sidebar-light+.control-sidebar-bg{background:#f9fafc;border-left:1px solid #d2d6de}.control-sidebar-light .nav-tabs.control-sidebar-tabs{border-bottom:#d2d6de}.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a{background:#e8ecf4;color:#444}.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a:hover,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a:focus{border-left-color:#d2d6de;border-bottom-color:#d2d6de}.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a:hover,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a:focus,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a:active{background:#eff1f7}.control-sidebar-light .nav-tabs.control-sidebar-tabs>li.active>a,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li.active>a:hover,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li.active>a:focus,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li.active>a:active{background:#f9fafc;color:#111}.control-sidebar-light .control-sidebar-heading,.control-sidebar-light .control-sidebar-subheading{color:#111}.control-sidebar-light .control-sidebar-menu{margin-left:-14px}.control-sidebar-light .control-sidebar-menu>li>a:hover{background:#f4f4f5}.control-sidebar-light .control-sidebar-menu>li>a .menu-info>p{color:#5e5e5e}.dropdown-menu{box-shadow:none;border-color:#eee}.dropdown-menu>li>a{color:#777}.dropdown-menu>li>a>.glyphicon,.dropdown-menu>li>a>.fa,.dropdown-menu>li>a>.ion{margin-right:10px}.dropdown-menu>li>a:hover{background-color:#e1e3e9;color:#333}.dropdown-menu>.divider{background-color:#eee}.navbar-nav>.notifications-menu>.dropdown-menu,.navbar-nav>.messages-menu>.dropdown-menu,.navbar-nav>.tasks-menu>.dropdown-menu{width:280px;padding:0 0 0 0;margin:0;top:100%}.navbar-nav>.notifications-menu>.dropdown-menu>li,.navbar-nav>.messages-menu>.dropdown-menu>li,.navbar-nav>.tasks-menu>.dropdown-menu>li{position:relative}.navbar-nav>.notifications-menu>.dropdown-menu>li.header,.navbar-nav>.messages-menu>.dropdown-menu>li.header,.navbar-nav>.tasks-menu>.dropdown-menu>li.header{border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0;background-color:#ffffff;padding:7px 10px;border-bottom:1px solid #f4f4f4;color:#444444;font-size:14px}.navbar-nav>.notifications-menu>.dropdown-menu>li.footer>a,.navbar-nav>.messages-menu>.dropdown-menu>li.footer>a,.navbar-nav>.tasks-menu>.dropdown-menu>li.footer>a{border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px;font-size:12px;background-color:#fff;padding:7px 10px;border-bottom:1px solid #eeeeee;color:#444!important;text-align:center}@media (max-width:991px){.navbar-nav>.notifications-menu>.dropdown-menu>li.footer>a,.navbar-nav>.messages-menu>.dropdown-menu>li.footer>a,.navbar-nav>.tasks-menu>.dropdown-menu>li.footer>a{background:#fff!important;color:#444!important}}.navbar-nav>.notifications-menu>.dropdown-menu>li.footer>a:hover,.navbar-nav>.messages-menu>.dropdown-menu>li.footer>a:hover,.navbar-nav>.tasks-menu>.dropdown-menu>li.footer>a:hover{text-decoration:none;font-weight:normal}.navbar-nav>.notifications-menu>.dropdown-menu>li .menu,.navbar-nav>.messages-menu>.dropdown-menu>li .menu,.navbar-nav>.tasks-menu>.dropdown-menu>li .menu{max-height:200px;margin:0;padding:0;list-style:none;overflow-x:hidden}.navbar-nav>.notifications-menu>.dropdown-menu>li .menu>li>a,.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a,.navbar-nav>.tasks-menu>.dropdown-menu>li .menu>li>a{display:block;white-space:nowrap;border-bottom:1px solid #f4f4f4}.navbar-nav>.notifications-menu>.dropdown-menu>li .menu>li>a:hover,.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a:hover,.navbar-nav>.tasks-menu>.dropdown-menu>li .menu>li>a:hover{background:#f4f4f4;text-decoration:none}.navbar-nav>.notifications-menu>.dropdown-menu>li .menu>li>a{color:#444444;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:10px}.navbar-nav>.notifications-menu>.dropdown-menu>li .menu>li>a>.glyphicon,.navbar-nav>.notifications-menu>.dropdown-menu>li .menu>li>a>.fa,.navbar-nav>.notifications-menu>.dropdown-menu>li .menu>li>a>.ion{width:20px}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a{margin:0;padding:10px 10px}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a>div>img{margin:auto 10px auto auto;width:40px;height:40px}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a>h4{padding:0;margin:0 0 0 45px;color:#444444;font-size:15px;position:relative}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a>h4>small{color:#999999;font-size:10px;position:absolute;top:0;right:0}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a>p{margin:0 0 0 45px;font-size:12px;color:#888888}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a:before,.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a:after{content:" ";display:table}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a:after{clear:both}.navbar-nav>.tasks-menu>.dropdown-menu>li .menu>li>a{padding:10px}.navbar-nav>.tasks-menu>.dropdown-menu>li .menu>li>a>h3{font-size:14px;padding:0;margin:0 0 10px 0;color:#666666}.navbar-nav>.tasks-menu>.dropdown-menu>li .menu>li>a>.progress{padding:0;margin:0}.navbar-nav>.user-menu>.dropdown-menu{border-top-right-radius:0;border-top-left-radius:0;padding:1px 0 0 0;border-top-width:0;width:280px}.navbar-nav>.user-menu>.dropdown-menu,.navbar-nav>.user-menu>.dropdown-menu>.user-body{border-bottom-right-radius:4px;border-bottom-left-radius:4px}.navbar-nav>.user-menu>.dropdown-menu>li.user-header{height:175px;padding:10px;text-align:center}.navbar-nav>.user-menu>.dropdown-menu>li.user-header>img{z-index:5;height:90px;width:90px;border:3px solid;border-color:transparent;border-color:rgba(255,255,255,0.2)}.navbar-nav>.user-menu>.dropdown-menu>li.user-header>p{z-index:5;color:#fff;color:rgba(255,255,255,0.8);font-size:17px;margin-top:10px}.navbar-nav>.user-menu>.dropdown-menu>li.user-header>p>small{display:block;font-size:12px}.navbar-nav>.user-menu>.dropdown-menu>.user-body{padding:15px;border-bottom:1px solid #f4f4f4;border-top:1px solid #dddddd}.navbar-nav>.user-menu>.dropdown-menu>.user-body:before,.navbar-nav>.user-menu>.dropdown-menu>.user-body:after{content:" ";display:table}.navbar-nav>.user-menu>.dropdown-menu>.user-body:after{clear:both}.navbar-nav>.user-menu>.dropdown-menu>.user-body a{color:#444 !important}@media (max-width:991px){.navbar-nav>.user-menu>.dropdown-menu>.user-body a{background:#fff !important;color:#444 !important}}.navbar-nav>.user-menu>.dropdown-menu>.user-footer{background-color:#f9f9f9;padding:10px}.navbar-nav>.user-menu>.dropdown-menu>.user-footer:before,.navbar-nav>.user-menu>.dropdown-menu>.user-footer:after{content:" ";display:table}.navbar-nav>.user-menu>.dropdown-menu>.user-footer:after{clear:both}.navbar-nav>.user-menu>.dropdown-menu>.user-footer .btn-default{color:#666666}@media (max-width:991px){.navbar-nav>.user-menu>.dropdown-menu>.user-footer .btn-default:hover{background-color:#f9f9f9}}.navbar-nav>.user-menu .user-image{float:left;width:25px;height:25px;border-radius:50%;margin-right:10px;margin-top:-2px}@media (max-width:767px){.navbar-nav>.user-menu .user-image{float:none;margin-right:0;margin-top:-8px;line-height:10px}}.open:not(.dropup)>.animated-dropdown-menu{backface-visibility:visible !important;-webkit-animation:flipInX .7s both;-o-animation:flipInX .7s both;animation:flipInX .7s both}@keyframes flipInX{0%{transform:perspective(400px) rotate3d(1, 0, 0, 90deg);transition-timing-function:ease-in;opacity:0}40%{transform:perspective(400px) rotate3d(1, 0, 0, -20deg);transition-timing-function:ease-in}60%{transform:perspective(400px) rotate3d(1, 0, 0, 10deg);opacity:1}80%{transform:perspective(400px) rotate3d(1, 0, 0, -5deg)}100%{transform:perspective(400px)}}@-webkit-keyframes flipInX{0%{-webkit-transform:perspective(400px) rotate3d(1, 0, 0, 90deg);-webkit-transition-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1, 0, 0, -20deg);-webkit-transition-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(1, 0, 0, 10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1, 0, 0, -5deg)}100%{-webkit-transform:perspective(400px)}}.navbar-custom-menu>.navbar-nav>li{position:relative}.navbar-custom-menu>.navbar-nav>li>.dropdown-menu{position:absolute;right:0;left:auto}@media (max-width:991px){.navbar-custom-menu>.navbar-nav{float:right}.navbar-custom-menu>.navbar-nav>li{position:static}.navbar-custom-menu>.navbar-nav>li>.dropdown-menu{position:absolute;right:5%;left:auto;border:1px solid #ddd;background:#fff}}.form-control{border-radius:0;box-shadow:none;border-color:#d2d6de}.form-control:focus{border-color:#3c8dbc;box-shadow:none}.form-control::-moz-placeholder,.form-control:-ms-input-placeholder,.form-control::-webkit-input-placeholder{color:#bbb;opacity:1}.form-control:not(select){-webkit-appearance:none;-moz-appearance:none;appearance:none}.form-group.has-success label{color:#00a65a}.form-group.has-success .form-control{border-color:#00a65a;box-shadow:none}.form-group.has-warning label{color:#f39c12}.form-group.has-warning .form-control{border-color:#f39c12;box-shadow:none}.form-group.has-error label{color:#dd4b39}.form-group.has-error .form-control{border-color:#dd4b39;box-shadow:none}.input-group .input-group-addon{border-radius:0;border-color:#d2d6de;background-color:#fff}.btn-group-vertical .btn.btn-flat:first-of-type,.btn-group-vertical .btn.btn-flat:last-of-type{border-radius:0}.icheck>label{padding-left:0}.form-control-feedback.fa{line-height:34px}.input-lg+.form-control-feedback.fa,.input-group-lg+.form-control-feedback.fa,.form-group-lg .form-control+.form-control-feedback.fa{line-height:46px}.input-sm+.form-control-feedback.fa,.input-group-sm+.form-control-feedback.fa,.form-group-sm .form-control+.form-control-feedback.fa{line-height:30px}.progress,.progress>.progress-bar{-webkit-box-shadow:none;box-shadow:none}.progress,.progress>.progress-bar,.progress .progress-bar,.progress>.progress-bar .progress-bar{border-radius:1px}.progress.sm,.progress-sm{height:10px}.progress.sm,.progress-sm,.progress.sm .progress-bar,.progress-sm .progress-bar{border-radius:1px}.progress.xs,.progress-xs{height:7px}.progress.xs,.progress-xs,.progress.xs .progress-bar,.progress-xs .progress-bar{border-radius:1px}.progress.xxs,.progress-xxs{height:3px}.progress.xxs,.progress-xxs,.progress.xxs .progress-bar,.progress-xxs .progress-bar{border-radius:1px}.progress.vertical{position:relative;width:30px;height:200px;display:inline-block;margin-right:10px}.progress.vertical>.progress-bar{width:100%;position:absolute;bottom:0}.progress.vertical.sm,.progress.vertical.progress-sm{width:20px}.progress.vertical.xs,.progress.vertical.progress-xs{width:10px}.progress.vertical.xxs,.progress.vertical.progress-xxs{width:3px}.progress-group .progress-text{font-weight:600}.progress-group .progress-number{float:right}.table tr>td .progress{margin:0}.progress-bar-light-blue,.progress-bar-primary{background-color:#3c8dbc}.progress-striped .progress-bar-light-blue,.progress-striped .progress-bar-primary{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-green,.progress-bar-success{background-color:#00a65a}.progress-striped .progress-bar-green,.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-aqua,.progress-bar-info{background-color:#00c0ef}.progress-striped .progress-bar-aqua,.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-yellow,.progress-bar-warning{background-color:#f39c12}.progress-striped .progress-bar-yellow,.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-red,.progress-bar-danger{background-color:#dd4b39}.progress-striped .progress-bar-red,.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.small-box{border-radius:2px;position:relative;display:block;margin-bottom:20px;box-shadow:0 1px 1px rgba(0,0,0,0.1)}.small-box>.inner{padding:10px}.small-box>.small-box-footer{position:relative;text-align:center;padding:3px 0;color:#fff;color:rgba(255,255,255,0.8);display:block;z-index:10;background:rgba(0,0,0,0.1);text-decoration:none}.small-box>.small-box-footer:hover{color:#fff;background:rgba(0,0,0,0.15)}.small-box h3{font-size:38px;font-weight:bold;margin:0 0 10px 0;white-space:nowrap;padding:0}.small-box p{font-size:15px}.small-box p>small{display:block;color:#f9f9f9;font-size:13px;margin-top:5px}.small-box h3,.small-box p{z-index:5px}.small-box .icon{-webkit-transition:all .3s linear;-o-transition:all .3s linear;transition:all .3s linear;position:absolute;top:-10px;right:10px;z-index:0;font-size:90px;color:rgba(0,0,0,0.15)}.small-box:hover{text-decoration:none;color:#f9f9f9}.small-box:hover .icon{font-size:95px}@media (max-width:767px){.small-box{text-align:center}.small-box .icon{display:none}.small-box p{font-size:12px}}.box{position:relative;border-radius:3px;background:#ffffff;border-top:3px solid #d2d6de;margin-bottom:20px;width:100%;box-shadow:0 1px 1px rgba(0,0,0,0.1)}.box.box-primary{border-top-color:#3c8dbc}.box.box-info{border-top-color:#00c0ef}.box.box-danger{border-top-color:#dd4b39}.box.box-warning{border-top-color:#f39c12}.box.box-success{border-top-color:#00a65a}.box.box-default{border-top-color:#d2d6de}.box.collapsed-box .box-body,.box.collapsed-box .box-footer{display:none}.box .nav-stacked>li{border-bottom:1px solid #f4f4f4;margin:0}.box .nav-stacked>li:last-of-type{border-bottom:none}.box.height-control .box-body{max-height:300px;overflow:auto}.box .border-right{border-right:1px solid #f4f4f4}.box .border-left{border-left:1px solid #f4f4f4}.box.box-solid{border-top:0}.box.box-solid>.box-header .btn.btn-default{background:transparent}.box.box-solid>.box-header .btn:hover,.box.box-solid>.box-header a:hover{background:rgba(0,0,0,0.1)}.box.box-solid.box-default{border:1px solid #d2d6de}.box.box-solid.box-default>.box-header{color:#444;background:#d2d6de;background-color:#d2d6de}.box.box-solid.box-default>.box-header a,.box.box-solid.box-default>.box-header .btn{color:#444}.box.box-solid.box-primary{border:1px solid #3c8dbc}.box.box-solid.box-primary>.box-header{color:#fff;background:#3c8dbc;background-color:#3c8dbc}.box.box-solid.box-primary>.box-header a,.box.box-solid.box-primary>.box-header .btn{color:#fff}.box.box-solid.box-info{border:1px solid #00c0ef}.box.box-solid.box-info>.box-header{color:#fff;background:#00c0ef;background-color:#00c0ef}.box.box-solid.box-info>.box-header a,.box.box-solid.box-info>.box-header .btn{color:#fff}.box.box-solid.box-danger{border:1px solid #dd4b39}.box.box-solid.box-danger>.box-header{color:#fff;background:#dd4b39;background-color:#dd4b39}.box.box-solid.box-danger>.box-header a,.box.box-solid.box-danger>.box-header .btn{color:#fff}.box.box-solid.box-warning{border:1px solid #f39c12}.box.box-solid.box-warning>.box-header{color:#fff;background:#f39c12;background-color:#f39c12}.box.box-solid.box-warning>.box-header a,.box.box-solid.box-warning>.box-header .btn{color:#fff}.box.box-solid.box-success{border:1px solid #00a65a}.box.box-solid.box-success>.box-header{color:#fff;background:#00a65a;background-color:#00a65a}.box.box-solid.box-success>.box-header a,.box.box-solid.box-success>.box-header .btn{color:#fff}.box.box-solid>.box-header>.box-tools .btn{border:0;box-shadow:none}.box.box-solid[class*='bg']>.box-header{color:#fff}.box .box-group>.box{margin-bottom:5px}.box .knob-label{text-align:center;color:#333;font-weight:100;font-size:12px;margin-bottom:0.3em}.box>.overlay,.overlay-wrapper>.overlay,.box>.loading-img,.overlay-wrapper>.loading-img{position:absolute;top:0;left:0;width:100%;height:100%}.box .overlay,.overlay-wrapper .overlay{z-index:50;background:rgba(255,255,255,0.7);border-radius:3px}.box .overlay>.fa,.overlay-wrapper .overlay>.fa{position:absolute;top:50%;left:50%;margin-left:-15px;margin-top:-15px;color:#000;font-size:30px}.box .overlay.dark,.overlay-wrapper .overlay.dark{background:rgba(0,0,0,0.5)}.box-header:before,.box-body:before,.box-footer:before,.box-header:after,.box-body:after,.box-footer:after{content:" ";display:table}.box-header:after,.box-body:after,.box-footer:after{clear:both}.box-header{color:#444;display:block;padding:10px;position:relative}.box-header.with-border{border-bottom:1px solid #f4f4f4}.collapsed-box .box-header.with-border{border-bottom:none}.box-header>.fa,.box-header>.glyphicon,.box-header>.ion,.box-header .box-title{display:inline-block;font-size:18px;margin:0;line-height:1}.box-header>.fa,.box-header>.glyphicon,.box-header>.ion{margin-right:5px}.box-header>.box-tools{position:absolute;right:10px;top:5px}.box-header>.box-tools [data-toggle="tooltip"]{position:relative}.box-header>.box-tools.pull-right .dropdown-menu{right:0;left:auto}.btn-box-tool{padding:5px;font-size:12px;background:transparent;color:#97a0b3}.open .btn-box-tool,.btn-box-tool:hover{color:#606c84}.btn-box-tool.btn:active{box-shadow:none}.box-body{border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px;padding:10px}.no-header .box-body{border-top-right-radius:3px;border-top-left-radius:3px}.box-body>.table{margin-bottom:0}.box-body .fc{margin-top:5px}.box-body .full-width-chart{margin:-19px}.box-body.no-padding .full-width-chart{margin:-9px}.box-body .box-pane{border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:3px}.box-body .box-pane-right{border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:3px;border-bottom-left-radius:0}.box-footer{border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px;border-top:1px solid #f4f4f4;padding:10px;background-color:#fff}.chart-legend{margin:10px 0}@media (max-width:991px){.chart-legend>li{float:left;margin-right:10px}}.box-comments{background:#f7f7f7}.box-comments .box-comment{padding:8px 0;border-bottom:1px solid #eee}.box-comments .box-comment:before,.box-comments .box-comment:after{content:" ";display:table}.box-comments .box-comment:after{clear:both}.box-comments .box-comment:last-of-type{border-bottom:0}.box-comments .box-comment:first-of-type{padding-top:0}.box-comments .box-comment img{float:left}.box-comments .comment-text{margin-left:40px;color:#555}.box-comments .username{color:#444;display:block;font-weight:600}.box-comments .text-muted{font-weight:400;font-size:12px}.todo-list{margin:0;padding:0;list-style:none;overflow:auto}.todo-list>li{border-radius:2px;padding:10px;background:#f4f4f4;margin-bottom:2px;border-left:2px solid #e6e7e8;color:#444}.todo-list>li:last-of-type{margin-bottom:0}.todo-list>li>input[type='checkbox']{margin:0 10px 0 5px}.todo-list>li .text{display:inline-block;margin-left:5px;font-weight:600}.todo-list>li .label{margin-left:10px;font-size:9px}.todo-list>li .tools{display:none;float:right;color:#dd4b39}.todo-list>li .tools>.fa,.todo-list>li .tools>.glyphicon,.todo-list>li .tools>.ion{margin-right:5px;cursor:pointer}.todo-list>li:hover .tools{display:inline-block}.todo-list>li.done{color:#999}.todo-list>li.done .text{text-decoration:line-through;font-weight:500}.todo-list>li.done .label{background:#d2d6de !important}.todo-list .danger{border-left-color:#dd4b39}.todo-list .warning{border-left-color:#f39c12}.todo-list .info{border-left-color:#00c0ef}.todo-list .success{border-left-color:#00a65a}.todo-list .primary{border-left-color:#3c8dbc}.todo-list .handle{display:inline-block;cursor:move;margin:0 5px}.chat{padding:5px 20px 5px 10px}.chat .item{margin-bottom:10px}.chat .item:before,.chat .item:after{content:" ";display:table}.chat .item:after{clear:both}.chat .item>img{width:40px;height:40px;border:2px solid transparent;border-radius:50%}.chat .item>.online{border:2px solid #00a65a}.chat .item>.offline{border:2px solid #dd4b39}.chat .item>.message{margin-left:55px;margin-top:-40px}.chat .item>.message>.name{display:block;font-weight:600}.chat .item>.attachment{border-radius:3px;background:#f4f4f4;margin-left:65px;margin-right:15px;padding:10px}.chat .item>.attachment>h4{margin:0 0 5px 0;font-weight:600;font-size:14px}.chat .item>.attachment>p,.chat .item>.attachment>.filename{font-weight:600;font-size:13px;font-style:italic;margin:0}.chat .item>.attachment:before,.chat .item>.attachment:after{content:" ";display:table}.chat .item>.attachment:after{clear:both}.box-input{max-width:200px}.modal .panel-body{color:#444}.info-box{display:block;min-height:90px;background:#fff;width:100%;box-shadow:0 1px 1px rgba(0,0,0,0.1);border-radius:2px;margin-bottom:15px}.info-box small{font-size:14px}.info-box .progress{background:rgba(0,0,0,0.2);margin:5px -10px 5px -10px;height:2px}.info-box .progress,.info-box .progress .progress-bar{border-radius:0}.info-box .progress .progress-bar{background:#fff}.info-box-icon{border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px;display:block;float:left;height:90px;width:90px;text-align:center;font-size:45px;line-height:90px;background:rgba(0,0,0,0.2)}.info-box-icon>img{max-width:100%}.info-box-content{padding:5px 10px;margin-left:90px}.info-box-number{display:block;font-weight:bold;font-size:18px}.progress-description,.info-box-text{display:block;font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.info-box-text{text-transform:uppercase}.info-box-more{display:block}.progress-description{margin:0}.timeline{position:relative;margin:0 0 30px 0;padding:0;list-style:none}.timeline:before{content:'';position:absolute;top:0;bottom:0;width:4px;background:#ddd;left:31px;margin:0;border-radius:2px}.timeline>li{position:relative;margin-right:10px;margin-bottom:15px}.timeline>li:before,.timeline>li:after{content:" ";display:table}.timeline>li:after{clear:both}.timeline>li>.timeline-item{-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.1);box-shadow:0 1px 1px rgba(0,0,0,0.1);border-radius:3px;margin-top:0;background:#fff;color:#444;margin-left:60px;margin-right:15px;padding:0;position:relative}.timeline>li>.timeline-item>.time{color:#999;float:right;padding:10px;font-size:12px}.timeline>li>.timeline-item>.timeline-header{margin:0;color:#555;border-bottom:1px solid #f4f4f4;padding:10px;font-size:16px;line-height:1.1}.timeline>li>.timeline-item>.timeline-header>a{font-weight:600}.timeline>li>.timeline-item>.timeline-body,.timeline>li>.timeline-item>.timeline-footer{padding:10px}.timeline>li>.fa,.timeline>li>.glyphicon,.timeline>li>.ion{width:30px;height:30px;font-size:15px;line-height:30px;position:absolute;color:#666;background:#d2d6de;border-radius:50%;text-align:center;left:18px;top:0}.timeline>.time-label>span{font-weight:600;padding:5px;display:inline-block;background-color:#fff;border-radius:4px}.timeline-inverse>li>.timeline-item{background:#f0f0f0;border:1px solid #ddd;-webkit-box-shadow:none;box-shadow:none}.timeline-inverse>li>.timeline-item>.timeline-header{border-bottom-color:#ddd}.btn{border-radius:3px;-webkit-box-shadow:none;box-shadow:none;border:1px solid transparent}.btn.uppercase{text-transform:uppercase}.btn.btn-flat{border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;border-width:1px}.btn:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn:focus{outline:none}.btn.btn-file{position:relative;overflow:hidden}.btn.btn-file>input[type='file']{position:absolute;top:0;right:0;min-width:100%;min-height:100%;font-size:100px;text-align:right;opacity:0;filter:alpha(opacity=0);outline:none;background:white;cursor:inherit;display:block}.btn-default{background-color:#f4f4f4;color:#444;border-color:#ddd}.btn-default:hover,.btn-default:active,.btn-default.hover{background-color:#e7e7e7}.btn-primary{background-color:#3c8dbc;border-color:#367fa9}.btn-primary:hover,.btn-primary:active,.btn-primary.hover{background-color:#367fa9}.btn-success{background-color:#00a65a;border-color:#008d4c}.btn-success:hover,.btn-success:active,.btn-success.hover{background-color:#008d4c}.btn-info{background-color:#00c0ef;border-color:#00acd6}.btn-info:hover,.btn-info:active,.btn-info.hover{background-color:#00acd6}.btn-danger{background-color:#dd4b39;border-color:#d73925}.btn-danger:hover,.btn-danger:active,.btn-danger.hover{background-color:#d73925}.btn-warning{background-color:#f39c12;border-color:#e08e0b}.btn-warning:hover,.btn-warning:active,.btn-warning.hover{background-color:#e08e0b}.btn-outline{border:1px solid #fff;background:transparent;color:#fff}.btn-outline:hover,.btn-outline:focus,.btn-outline:active{color:rgba(255,255,255,0.7);border-color:rgba(255,255,255,0.7)}.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn[class*='bg-']:hover{-webkit-box-shadow:inset 0 0 100px rgba(0,0,0,0.2);box-shadow:inset 0 0 100px rgba(0,0,0,0.2)}.btn-app{border-radius:3px;position:relative;padding:15px 5px;margin:0 0 10px 10px;min-width:80px;height:60px;text-align:center;color:#666;border:1px solid #ddd;background-color:#f4f4f4;font-size:12px}.btn-app>.fa,.btn-app>.glyphicon,.btn-app>.ion{font-size:20px;display:block}.btn-app:hover{background:#f4f4f4;color:#444;border-color:#aaa}.btn-app:active,.btn-app:focus{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn-app>.badge{position:absolute;top:-3px;right:-10px;font-size:10px;font-weight:400}.callout{border-radius:3px;margin:0 0 20px 0;padding:15px 30px 15px 15px;border-left:5px solid #eee}.callout a{color:#fff;text-decoration:underline}.callout a:hover{color:#eee}.callout h4{margin-top:0;font-weight:600}.callout p:last-child{margin-bottom:0}.callout code,.callout .highlight{background-color:#fff}.callout.callout-danger{border-color:#c23321}.callout.callout-warning{border-color:#c87f0a}.callout.callout-info{border-color:#0097bc}.callout.callout-success{border-color:#00733e}.alert{border-radius:3px}.alert h4{font-weight:600}.alert .icon{margin-right:10px}.alert .close{color:#000;opacity:.2;filter:alpha(opacity=20)}.alert .close:hover{opacity:.5;filter:alpha(opacity=50)}.alert a{color:#fff;text-decoration:underline}.alert-success{border-color:#008d4c}.alert-danger,.alert-error{border-color:#d73925}.alert-warning{border-color:#e08e0b}.alert-info{border-color:#00acd6}.nav>li>a:hover,.nav>li>a:active,.nav>li>a:focus{color:#444;background:#f7f7f7}.nav-pills>li>a{border-radius:0;border-top:3px solid transparent;color:#444}.nav-pills>li>a>.fa,.nav-pills>li>a>.glyphicon,.nav-pills>li>a>.ion{margin-right:5px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{border-top-color:#3c8dbc}.nav-pills>li.active>a{font-weight:600}.nav-stacked>li>a{border-radius:0;border-top:0;border-left:3px solid transparent;color:#444}.nav-stacked>li.active>a,.nav-stacked>li.active>a:hover{background:transparent;color:#444;border-top:0;border-left-color:#3c8dbc}.nav-stacked>li.header{border-bottom:1px solid #ddd;color:#777;margin-bottom:10px;padding:5px 10px;text-transform:uppercase}.nav-tabs-custom{margin-bottom:20px;background:#fff;box-shadow:0 1px 1px rgba(0,0,0,0.1);border-radius:3px}.nav-tabs-custom>.nav-tabs{margin:0;/* border-bottom-color: #3C8DBC /*#f4f4f4*/; */border-top-right-radius:3px;border-top-left-radius:3px}.nav-tabs-custom>.nav-tabs>li{border-top:3px solid transparent;/*margin-bottom:-2px;*/margin-right:5px}.nav-tabs-custom>.nav-tabs>li>a{color:#444;border-radius:0}.nav-tabs-custom>.nav-tabs>li>a.text-muted{color:#999}.nav-tabs-custom>.nav-tabs>li>a,.nav-tabs-custom>.nav-tabs>li>a:hover{background:transparent;margin:0}.nav-tabs-custom>.nav-tabs>li>a:hover{color:#999}.nav-tabs-custom>.nav-tabs>li:not(.active)>a:hover,.nav-tabs-custom>.nav-tabs>li:not(.active)>a:focus,.nav-tabs-custom>.nav-tabs>li:not(.active)>a:active{border-color:transparent}.nav-tabs-custom>.nav-tabs>li.active{border-top-color:#3c8dbc}.nav-tabs-custom>.nav-tabs>li.active>a,.nav-tabs-custom>.nav-tabs>li.active:hover>a{background-color:#fff;color:#444}.nav-tabs-custom>.nav-tabs>li.active>a{border-top:1px solid #3C8DBC;border-left:1px solid #3C8DBC;border-right:1px solid #3C8DBC;}.nav-tabs-custom>.nav-tabs>li:first-of-type{margin-left:0}.nav-tabs-custom>.nav-tabs>li:first-of-type.active>a{border-left-color:transparent}.nav-tabs-custom>.nav-tabs.pull-right{float:none!important}.nav-tabs-custom>.nav-tabs.pull-right>li{float:right}.nav-tabs-custom>.nav-tabs.pull-right>li:first-of-type{margin-right:0}.nav-tabs-custom>.nav-tabs.pull-right>li:first-of-type>a{border-left-width:1px}.nav-tabs-custom>.nav-tabs.pull-right>li:first-of-type.active>a{border-left-color:#f4f4f4;border-right-color:transparent}.nav-tabs-custom>.nav-tabs>li.header{line-height:35px;padding:0 10px;font-size:20px;color:#444}.nav-tabs-custom>.nav-tabs>li.header>.fa,.nav-tabs-custom>.nav-tabs>li.header>.glyphicon,.nav-tabs-custom>.nav-tabs>li.header>.ion{margin-right:5px}.nav-tabs-custom>.tab-content{background:#fff;padding:10px;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.nav-tabs-custom .dropdown.open>a:active,.nav-tabs-custom .dropdown.open>a:focus{background:transparent;color:#999}.pagination>li>a{background:#fafafa;color:#666}.pagination.pagination-flat>li>a{border-radius:0 !important}.products-list{list-style:none;margin:0;padding:0}.products-list>.item{border-radius:3px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.1);box-shadow:0 1px 1px rgba(0,0,0,0.1);padding:10px 0;background:#fff}.products-list>.item:before,.products-list>.item:after{content:" ";display:table}.products-list>.item:after{clear:both}.products-list .product-img{float:left}.products-list .product-img img{width:50px;height:50px}.products-list .product-info{margin-left:60px}.products-list .product-title{font-weight:600}.products-list .product-description{display:block;color:#999;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.product-list-in-box>.item{-webkit-box-shadow:none;box-shadow:none;border-radius:0;border-bottom:1px solid #f4f4f4}.product-list-in-box>.item:last-of-type{border-bottom-width:0}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{border-top:1px solid #f4f4f4}.table>thead>tr>th{border-bottom:2px solid #f4f4f4}.table tr td .progress{margin-top:5px}.table-bordered{border:1px solid #f4f4f4}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #f4f4f4}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table.no-border,.table.no-border td,.table.no-border th{border:0}table.text-center,table.text-center td,table.text-center th{text-align:center}.table.align th{text-align:left}.table.align td{text-align:right}.label-default{background-color:#d2d6de;color:#444}.direct-chat .box-body{border-bottom-right-radius:0;border-bottom-left-radius:0;position:relative;overflow-x:hidden;padding:0}.direct-chat.chat-pane-open .direct-chat-contacts{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0)}.direct-chat-messages{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0);padding:10px;height:250px;overflow:auto}.direct-chat-msg,.direct-chat-text{display:block}.direct-chat-msg{margin-bottom:10px}.direct-chat-msg:before,.direct-chat-msg:after{content:" ";display:table}.direct-chat-msg:after{clear:both}.direct-chat-messages,.direct-chat-contacts{-webkit-transition:-webkit-transform .5s ease-in-out;-moz-transition:-moz-transform .5s ease-in-out;-o-transition:-o-transform .5s ease-in-out;transition:transform .5s ease-in-out}.direct-chat-text{border-radius:5px;position:relative;padding:5px 10px;background:#d2d6de;border:1px solid #d2d6de;margin:5px 0 0 50px;color:#444}.direct-chat-text:after,.direct-chat-text:before{position:absolute;right:100%;top:15px;border:solid transparent;border-right-color:#d2d6de;content:' ';height:0;width:0;pointer-events:none}.direct-chat-text:after{border-width:5px;margin-top:-5px}.direct-chat-text:before{border-width:6px;margin-top:-6px}.right .direct-chat-text{margin-right:50px;margin-left:0}.right .direct-chat-text:after,.right .direct-chat-text:before{right:auto;left:100%;border-right-color:transparent;border-left-color:#d2d6de}.direct-chat-img{border-radius:50%;float:left;width:40px;height:40px}.right .direct-chat-img{float:right}.direct-chat-info{display:block;margin-bottom:2px;font-size:12px}.direct-chat-name{font-weight:600}.direct-chat-timestamp{color:#999}.direct-chat-contacts-open .direct-chat-contacts{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0)}.direct-chat-contacts{-webkit-transform:translate(101%, 0);-ms-transform:translate(101%, 0);-o-transform:translate(101%, 0);transform:translate(101%, 0);position:absolute;top:0;bottom:0;height:250px;width:100%;background:#222d32;color:#fff;overflow:auto}.contacts-list>li{border-bottom:1px solid rgba(0,0,0,0.2);padding:10px;margin:0}.contacts-list>li:before,.contacts-list>li:after{content:" ";display:table}.contacts-list>li:after{clear:both}.contacts-list>li:last-of-type{border-bottom:none}.contacts-list-img{border-radius:50%;width:40px;float:left}.contacts-list-info{margin-left:45px;color:#fff}.contacts-list-name,.contacts-list-status{display:block}.contacts-list-name{font-weight:600}.contacts-list-status{font-size:12px}.contacts-list-date{color:#aaa;font-weight:normal}.contacts-list-msg{color:#999}.direct-chat-danger .right>.direct-chat-text{background:#dd4b39;border-color:#dd4b39;color:#fff}.direct-chat-danger .right>.direct-chat-text:after,.direct-chat-danger .right>.direct-chat-text:before{border-left-color:#dd4b39}.direct-chat-primary .right>.direct-chat-text{background:#3c8dbc;border-color:#3c8dbc;color:#fff}.direct-chat-primary .right>.direct-chat-text:after,.direct-chat-primary .right>.direct-chat-text:before{border-left-color:#3c8dbc}.direct-chat-warning .right>.direct-chat-text{background:#f39c12;border-color:#f39c12;color:#fff}.direct-chat-warning .right>.direct-chat-text:after,.direct-chat-warning .right>.direct-chat-text:before{border-left-color:#f39c12}.direct-chat-info .right>.direct-chat-text{background:#00c0ef;border-color:#00c0ef;color:#fff}.direct-chat-info .right>.direct-chat-text:after,.direct-chat-info .right>.direct-chat-text:before{border-left-color:#00c0ef}.direct-chat-success .right>.direct-chat-text{background:#00a65a;border-color:#00a65a;color:#fff}.direct-chat-success .right>.direct-chat-text:after,.direct-chat-success .right>.direct-chat-text:before{border-left-color:#00a65a}.users-list>li{width:25%;float:left;padding:10px;text-align:center}.users-list>li img{border-radius:50%;max-width:100%;height:auto}.users-list>li>a:hover,.users-list>li>a:hover .users-list-name{color:#999}.users-list-name,.users-list-date{display:block}.users-list-name{font-weight:600;color:#444;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.users-list-date{color:#999;font-size:12px}.carousel-control.left,.carousel-control.right{background-image:none}.carousel-control>.fa{font-size:40px;position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-20px}.modal{background:rgba(0,0,0,0.3)}.modal-content{border-radius:0;-webkit-box-shadow:0 2px 3px rgba(0,0,0,0.125);box-shadow:0 2px 3px rgba(0,0,0,0.125);border:0}@media (min-width:768px){.modal-content{-webkit-box-shadow:0 2px 3px rgba(0,0,0,0.125);box-shadow:0 2px 3px rgba(0,0,0,0.125)}}.modal-header{border-bottom-color:#f4f4f4}.modal-footer{border-top-color:#f4f4f4}.modal-primary .modal-header,.modal-primary .modal-footer{border-color:#307095}.modal-warning .modal-header,.modal-warning .modal-footer{border-color:#c87f0a}.modal-info .modal-header,.modal-info .modal-footer{border-color:#0097bc}.modal-success .modal-header,.modal-success .modal-footer{border-color:#00733e}.modal-danger .modal-header,.modal-danger .modal-footer{border-color:#c23321}.box-widget{border:none;position:relative}.widget-user .widget-user-header{padding:20px;height:120px;border-top-right-radius:3px;border-top-left-radius:3px}.widget-user .widget-user-username{margin-top:0;margin-bottom:5px;font-size:25px;font-weight:300;text-shadow:0 1px 1px rgba(0,0,0,0.2)}.widget-user .widget-user-desc{margin-top:0}.widget-user .widget-user-image{position:absolute;top:65px;left:50%;margin-left:-45px}.widget-user .widget-user-image>img{width:90px;height:auto;border:3px solid #fff}.widget-user .box-footer{padding-top:30px}.widget-user-2 .widget-user-header{padding:20px;border-top-right-radius:3px;border-top-left-radius:3px}.widget-user-2 .widget-user-username{margin-top:5px;margin-bottom:5px;font-size:25px;font-weight:300}.widget-user-2 .widget-user-desc{margin-top:0}.widget-user-2 .widget-user-username,.widget-user-2 .widget-user-desc{margin-left:75px}.widget-user-2 .widget-user-image>img{width:65px;height:auto;float:left}.mailbox-messages>.table{margin:0}.mailbox-controls{padding:5px}.mailbox-controls.with-border{border-bottom:1px solid #f4f4f4}.mailbox-read-info{border-bottom:1px solid #f4f4f4;padding:10px}.mailbox-read-info h3{font-size:20px;margin:0}.mailbox-read-info h5{margin:0;padding:5px 0 0 0}.mailbox-read-time{color:#999;font-size:13px}.mailbox-read-message{padding:10px}.mailbox-attachments li{float:left;width:200px;border:1px solid #eee;margin-bottom:10px;margin-right:10px}.mailbox-attachment-name{font-weight:bold;color:#666}.mailbox-attachment-icon,.mailbox-attachment-info,.mailbox-attachment-size{display:block}.mailbox-attachment-info{padding:10px;background:#f4f4f4}.mailbox-attachment-size{color:#999;font-size:12px}.mailbox-attachment-icon{text-align:center;font-size:65px;color:#666;padding:20px 10px}.mailbox-attachment-icon.has-img{padding:0}.mailbox-attachment-icon.has-img>img{max-width:100%;height:auto}.lockscreen{background:#d2d6de}.lockscreen-logo{font-size:35px;text-align:center;margin-bottom:25px;font-weight:300}.lockscreen-logo a{color:#444}.lockscreen-wrapper{max-width:400px;margin:0 auto;margin-top:10%}.lockscreen .lockscreen-name{text-align:center;font-weight:600}.lockscreen-item{border-radius:4px;padding:0;background:#fff;position:relative;margin:10px auto 30px auto;width:290px}.lockscreen-image{border-radius:50%;position:absolute;left:-10px;top:-25px;background:#fff;padding:5px;z-index:10}.lockscreen-image>img{border-radius:50%;width:70px;height:70px}.lockscreen-credentials{margin-left:70px}.lockscreen-credentials .form-control{border:0}.lockscreen-credentials .btn{background-color:#fff;border:0;padding:0 10px}.lockscreen-footer{margin-top:10px}.login-logo,.register-logo{font-size:35px;text-align:center;margin-bottom:25px;font-weight:300}.login-logo a,.register-logo a{color:#444}.login-page,.register-page{background:#d2d6de}.login-box,.register-box{width:360px;margin:7% auto}@media (max-width:768px){.login-box,.register-box{width:90%;margin-top:20px}}.login-box-body,.register-box-body{background:#fff;padding:20px;border-top:0;color:#666}.login-box-body .form-control-feedback,.register-box-body .form-control-feedback{color:#777}.login-box-msg,.register-box-msg{margin:0;text-align:center;padding:0 20px 20px 20px}.social-auth-links{margin:10px 0}.error-page{width:600px;margin:20px auto 0 auto}@media (max-width:991px){.error-page{width:100%}}.error-page>.headline{float:left;font-size:100px;font-weight:300}@media (max-width:991px){.error-page>.headline{float:none;text-align:center}}.error-page>.error-content{margin-left:190px;display:block}@media (max-width:991px){.error-page>.error-content{margin-left:0}}.error-page>.error-content>h3{font-weight:300;font-size:25px}@media (max-width:991px){.error-page>.error-content>h3{text-align:center}}.invoice{position:relative;background:#fff;border:1px solid #f4f4f4;padding:20px;margin:10px 25px}.invoice-title{margin-top:0}.profile-user-img{margin:0 auto;width:100px;padding:3px;border:3px solid #d2d6de}.profile-username{font-size:21px;margin-top:5px}.post{border-bottom:1px solid #d2d6de;margin-bottom:15px;padding-bottom:15px;color:#666}.post:last-of-type{border-bottom:0;margin-bottom:0;padding-bottom:0}.post .user-block{margin-bottom:15px}.btn-social{position:relative;padding-left:44px;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.btn-social>:first-child{position:absolute;left:0;top:0;bottom:0;width:32px;line-height:34px;font-size:1.6em;text-align:center;border-right:1px solid rgba(0,0,0,0.2)}.btn-social.btn-lg{padding-left:61px}.btn-social.btn-lg>:first-child{line-height:45px;width:45px;font-size:1.8em}.btn-social.btn-sm{padding-left:38px}.btn-social.btn-sm>:first-child{line-height:28px;width:28px;font-size:1.4em}.btn-social.btn-xs{padding-left:30px}.btn-social.btn-xs>:first-child{line-height:20px;width:20px;font-size:1.2em}.btn-social-icon{position:relative;padding-left:44px;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:34px;width:34px;padding:0}.btn-social-icon>:first-child{position:absolute;left:0;top:0;bottom:0;width:32px;line-height:34px;font-size:1.6em;text-align:center;border-right:1px solid rgba(0,0,0,0.2)}.btn-social-icon.btn-lg{padding-left:61px}.btn-social-icon.btn-lg>:first-child{line-height:45px;width:45px;font-size:1.8em}.btn-social-icon.btn-sm{padding-left:38px}.btn-social-icon.btn-sm>:first-child{line-height:28px;width:28px;font-size:1.4em}.btn-social-icon.btn-xs{padding-left:30px}.btn-social-icon.btn-xs>:first-child{line-height:20px;width:20px;font-size:1.2em}.btn-social-icon>:first-child{border:none;text-align:center;width:100%}.btn-social-icon.btn-lg{height:45px;width:45px;padding-left:0;padding-right:0}.btn-social-icon.btn-sm{height:30px;width:30px;padding-left:0;padding-right:0}.btn-social-icon.btn-xs{height:22px;width:22px;padding-left:0;padding-right:0}.btn-adn{color:#fff;background-color:#d87a68;border-color:rgba(0,0,0,0.2)}.btn-adn:hover,.btn-adn:focus,.btn-adn.focus,.btn-adn:active,.btn-adn.active,.open>.dropdown-toggle.btn-adn{color:#fff;background-color:#ce563f;border-color:rgba(0,0,0,0.2)}.btn-adn:active,.btn-adn.active,.open>.dropdown-toggle.btn-adn{background-image:none}.btn-adn .badge{color:#d87a68;background-color:#fff}.btn-bitbucket{color:#fff;background-color:#205081;border-color:rgba(0,0,0,0.2)}.btn-bitbucket:hover,.btn-bitbucket:focus,.btn-bitbucket.focus,.btn-bitbucket:active,.btn-bitbucket.active,.open>.dropdown-toggle.btn-bitbucket{color:#fff;background-color:#163758;border-color:rgba(0,0,0,0.2)}.btn-bitbucket:active,.btn-bitbucket.active,.open>.dropdown-toggle.btn-bitbucket{background-image:none}.btn-bitbucket .badge{color:#205081;background-color:#fff}.btn-dropbox{color:#fff;background-color:#1087dd;border-color:rgba(0,0,0,0.2)}.btn-dropbox:hover,.btn-dropbox:focus,.btn-dropbox.focus,.btn-dropbox:active,.btn-dropbox.active,.open>.dropdown-toggle.btn-dropbox{color:#fff;background-color:#0d6aad;border-color:rgba(0,0,0,0.2)}.btn-dropbox:active,.btn-dropbox.active,.open>.dropdown-toggle.btn-dropbox{background-image:none}.btn-dropbox .badge{color:#1087dd;background-color:#fff}.btn-facebook{color:#fff;background-color:#3b5998;border-color:rgba(0,0,0,0.2)}.btn-facebook:hover,.btn-facebook:focus,.btn-facebook.focus,.btn-facebook:active,.btn-facebook.active,.open>.dropdown-toggle.btn-facebook{color:#fff;background-color:#2d4373;border-color:rgba(0,0,0,0.2)}.btn-facebook:active,.btn-facebook.active,.open>.dropdown-toggle.btn-facebook{background-image:none}.btn-facebook .badge{color:#3b5998;background-color:#fff}.btn-flickr{color:#fff;background-color:#ff0084;border-color:rgba(0,0,0,0.2)}.btn-flickr:hover,.btn-flickr:focus,.btn-flickr.focus,.btn-flickr:active,.btn-flickr.active,.open>.dropdown-toggle.btn-flickr{color:#fff;background-color:#cc006a;border-color:rgba(0,0,0,0.2)}.btn-flickr:active,.btn-flickr.active,.open>.dropdown-toggle.btn-flickr{background-image:none}.btn-flickr .badge{color:#ff0084;background-color:#fff}.btn-foursquare{color:#fff;background-color:#f94877;border-color:rgba(0,0,0,0.2)}.btn-foursquare:hover,.btn-foursquare:focus,.btn-foursquare.focus,.btn-foursquare:active,.btn-foursquare.active,.open>.dropdown-toggle.btn-foursquare{color:#fff;background-color:#f71752;border-color:rgba(0,0,0,0.2)}.btn-foursquare:active,.btn-foursquare.active,.open>.dropdown-toggle.btn-foursquare{background-image:none}.btn-foursquare .badge{color:#f94877;background-color:#fff}.btn-github{color:#fff;background-color:#444;border-color:rgba(0,0,0,0.2)}.btn-github:hover,.btn-github:focus,.btn-github.focus,.btn-github:active,.btn-github.active,.open>.dropdown-toggle.btn-github{color:#fff;background-color:#2b2b2b;border-color:rgba(0,0,0,0.2)}.btn-github:active,.btn-github.active,.open>.dropdown-toggle.btn-github{background-image:none}.btn-github .badge{color:#444;background-color:#fff}.btn-google{color:#fff;background-color:#dd4b39;border-color:rgba(0,0,0,0.2)}.btn-google:hover,.btn-google:focus,.btn-google.focus,.btn-google:active,.btn-google.active,.open>.dropdown-toggle.btn-google{color:#fff;background-color:#c23321;border-color:rgba(0,0,0,0.2)}.btn-google:active,.btn-google.active,.open>.dropdown-toggle.btn-google{background-image:none}.btn-google .badge{color:#dd4b39;background-color:#fff}.btn-instagram{color:#fff;background-color:#3f729b;border-color:rgba(0,0,0,0.2)}.btn-instagram:hover,.btn-instagram:focus,.btn-instagram.focus,.btn-instagram:active,.btn-instagram.active,.open>.dropdown-toggle.btn-instagram{color:#fff;background-color:#305777;border-color:rgba(0,0,0,0.2)}.btn-instagram:active,.btn-instagram.active,.open>.dropdown-toggle.btn-instagram{background-image:none}.btn-instagram .badge{color:#3f729b;background-color:#fff}.btn-linkedin{color:#fff;background-color:#007bb6;border-color:rgba(0,0,0,0.2)}.btn-linkedin:hover,.btn-linkedin:focus,.btn-linkedin.focus,.btn-linkedin:active,.btn-linkedin.active,.open>.dropdown-toggle.btn-linkedin{color:#fff;background-color:#005983;border-color:rgba(0,0,0,0.2)}.btn-linkedin:active,.btn-linkedin.active,.open>.dropdown-toggle.btn-linkedin{background-image:none}.btn-linkedin .badge{color:#007bb6;background-color:#fff}.btn-microsoft{color:#fff;background-color:#2672ec;border-color:rgba(0,0,0,0.2)}.btn-microsoft:hover,.btn-microsoft:focus,.btn-microsoft.focus,.btn-microsoft:active,.btn-microsoft.active,.open>.dropdown-toggle.btn-microsoft{color:#fff;background-color:#125acd;border-color:rgba(0,0,0,0.2)}.btn-microsoft:active,.btn-microsoft.active,.open>.dropdown-toggle.btn-microsoft{background-image:none}.btn-microsoft .badge{color:#2672ec;background-color:#fff}.btn-openid{color:#fff;background-color:#f7931e;border-color:rgba(0,0,0,0.2)}.btn-openid:hover,.btn-openid:focus,.btn-openid.focus,.btn-openid:active,.btn-openid.active,.open>.dropdown-toggle.btn-openid{color:#fff;background-color:#da7908;border-color:rgba(0,0,0,0.2)}.btn-openid:active,.btn-openid.active,.open>.dropdown-toggle.btn-openid{background-image:none}.btn-openid .badge{color:#f7931e;background-color:#fff}.btn-pinterest{color:#fff;background-color:#cb2027;border-color:rgba(0,0,0,0.2)}.btn-pinterest:hover,.btn-pinterest:focus,.btn-pinterest.focus,.btn-pinterest:active,.btn-pinterest.active,.open>.dropdown-toggle.btn-pinterest{color:#fff;background-color:#9f191f;border-color:rgba(0,0,0,0.2)}.btn-pinterest:active,.btn-pinterest.active,.open>.dropdown-toggle.btn-pinterest{background-image:none}.btn-pinterest .badge{color:#cb2027;background-color:#fff}.btn-reddit{color:#000;background-color:#eff7ff;border-color:rgba(0,0,0,0.2)}.btn-reddit:hover,.btn-reddit:focus,.btn-reddit.focus,.btn-reddit:active,.btn-reddit.active,.open>.dropdown-toggle.btn-reddit{color:#000;background-color:#bcddff;border-color:rgba(0,0,0,0.2)}.btn-reddit:active,.btn-reddit.active,.open>.dropdown-toggle.btn-reddit{background-image:none}.btn-reddit .badge{color:#eff7ff;background-color:#000}.btn-soundcloud{color:#fff;background-color:#f50;border-color:rgba(0,0,0,0.2)}.btn-soundcloud:hover,.btn-soundcloud:focus,.btn-soundcloud.focus,.btn-soundcloud:active,.btn-soundcloud.active,.open>.dropdown-toggle.btn-soundcloud{color:#fff;background-color:#c40;border-color:rgba(0,0,0,0.2)}.btn-soundcloud:active,.btn-soundcloud.active,.open>.dropdown-toggle.btn-soundcloud{background-image:none}.btn-soundcloud .badge{color:#f50;background-color:#fff}.btn-tumblr{color:#fff;background-color:#2c4762;border-color:rgba(0,0,0,0.2)}.btn-tumblr:hover,.btn-tumblr:focus,.btn-tumblr.focus,.btn-tumblr:active,.btn-tumblr.active,.open>.dropdown-toggle.btn-tumblr{color:#fff;background-color:#1c2d3f;border-color:rgba(0,0,0,0.2)}.btn-tumblr:active,.btn-tumblr.active,.open>.dropdown-toggle.btn-tumblr{background-image:none}.btn-tumblr .badge{color:#2c4762;background-color:#fff}.btn-twitter{color:#fff;background-color:#55acee;border-color:rgba(0,0,0,0.2)}.btn-twitter:hover,.btn-twitter:focus,.btn-twitter.focus,.btn-twitter:active,.btn-twitter.active,.open>.dropdown-toggle.btn-twitter{color:#fff;background-color:#2795e9;border-color:rgba(0,0,0,0.2)}.btn-twitter:active,.btn-twitter.active,.open>.dropdown-toggle.btn-twitter{background-image:none}.btn-twitter .badge{color:#55acee;background-color:#fff}.btn-vimeo{color:#fff;background-color:#1ab7ea;border-color:rgba(0,0,0,0.2)}.btn-vimeo:hover,.btn-vimeo:focus,.btn-vimeo.focus,.btn-vimeo:active,.btn-vimeo.active,.open>.dropdown-toggle.btn-vimeo{color:#fff;background-color:#1295bf;border-color:rgba(0,0,0,0.2)}.btn-vimeo:active,.btn-vimeo.active,.open>.dropdown-toggle.btn-vimeo{background-image:none}.btn-vimeo .badge{color:#1ab7ea;background-color:#fff}.btn-vk{color:#fff;background-color:#587ea3;border-color:rgba(0,0,0,0.2)}.btn-vk:hover,.btn-vk:focus,.btn-vk.focus,.btn-vk:active,.btn-vk.active,.open>.dropdown-toggle.btn-vk{color:#fff;background-color:#466482;border-color:rgba(0,0,0,0.2)}.btn-vk:active,.btn-vk.active,.open>.dropdown-toggle.btn-vk{background-image:none}.btn-vk .badge{color:#587ea3;background-color:#fff}.btn-yahoo{color:#fff;background-color:#720e9e;border-color:rgba(0,0,0,0.2)}.btn-yahoo:hover,.btn-yahoo:focus,.btn-yahoo.focus,.btn-yahoo:active,.btn-yahoo.active,.open>.dropdown-toggle.btn-yahoo{color:#fff;background-color:#500a6f;border-color:rgba(0,0,0,0.2)}.btn-yahoo:active,.btn-yahoo.active,.open>.dropdown-toggle.btn-yahoo{background-image:none}.btn-yahoo .badge{color:#720e9e;background-color:#fff}.fc-button{background:#f4f4f4;background-image:none;color:#444;border-color:#ddd;border-bottom-color:#ddd}.fc-button:hover,.fc-button:active,.fc-button.hover{background-color:#e9e9e9}.fc-header-title h2{font-size:15px;line-height:1.6em;color:#666;margin-left:10px}.fc-header-right{padding-right:10px}.fc-header-left{padding-left:10px}.fc-widget-header{background:#fafafa}.fc-grid{width:100%;border:0}.fc-widget-header:first-of-type,.fc-widget-content:first-of-type{border-left:0;border-right:0}.fc-widget-header:last-of-type,.fc-widget-content:last-of-type{border-right:0}.fc-toolbar{padding:10px;margin:0}.fc-day-number{font-size:20px;font-weight:300;padding-right:10px}.fc-color-picker{list-style:none;margin:0;padding:0}.fc-color-picker>li{float:left;font-size:30px;margin-right:5px;line-height:30px}.fc-color-picker>li .fa{-webkit-transition:-webkit-transform linear .3s;-moz-transition:-moz-transform linear .3s;-o-transition:-o-transform linear .3s;transition:transform linear .3s}.fc-color-picker>li .fa:hover{-webkit-transform:rotate(30deg);-ms-transform:rotate(30deg);-o-transform:rotate(30deg);transform:rotate(30deg)}#add-new-event{-webkit-transition:all linear .3s;-o-transition:all linear .3s;transition:all linear .3s}.external-event{padding:5px 10px;font-weight:bold;margin-bottom:4px;box-shadow:0 1px 1px rgba(0,0,0,0.1);text-shadow:0 1px 1px rgba(0,0,0,0.1);border-radius:3px;cursor:move}.external-event:hover{box-shadow:inset 0 0 90px rgba(0,0,0,0.2)}.select2-container--default.select2-container--focus,.select2-selection.select2-container--focus,.select2-container--default:focus,.select2-selection:focus,.select2-container--default:active,.select2-selection:active{outline:none}.select2-container--default .select2-selection--single,.select2-selection .select2-selection--single{border:1px solid #d2d6de;border-radius:0;padding:6px 12px;height:34px}.select2-container--default.select2-container--open{border-color:#3c8dbc}.select2-dropdown{border:1px solid #d2d6de;border-radius:0}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#3c8dbc;color:white}.select2-results__option{padding:6px 12px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{padding-left:0;padding-right:0;height:auto;margin-top:-4px}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:6px;padding-left:20px}.select2-container--default .select2-selection--single .select2-selection__arrow{height:28px;right:3px}.select2-container--default .select2-selection--single .select2-selection__arrow b{margin-top:0}.select2-dropdown .select2-search__field,.select2-search--inline .select2-search__field{border:1px solid #d2d6de}.select2-dropdown .select2-search__field:focus,.select2-search--inline .select2-search__field:focus{outline:none;border:1px solid #3c8dbc}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option[aria-selected=true],.select2-container--default .select2-results__option[aria-selected=true]:hover{color:#444}.select2-container--default .select2-selection--multiple{border:1px solid #d2d6de;border-radius:0}.select2-container--default .select2-selection--multiple:focus{border-color:#3c8dbc}.select2-container--default.select2-container--focus .select2-selection--multiple{border-color:#d2d6de}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#3c8dbc;border-color:#367fa9;padding:1px 10px;color:#fff}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{margin-right:5px;color:rgba(255,255,255,0.7)}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#fff}.select2-container .select2-selection--single .select2-selection__rendered{padding-right:10px}.pad{padding:10px}.margin{margin:10px}.margin-bottom{margin-bottom:20px}.margin-bottom-none{margin-bottom:0}.margin-r-5{margin-right:5px}.inline{display:inline}.description-block{display:block;margin:10px 0;text-align:center}.description-block.margin-bottom{margin-bottom:25px}.description-block>.description-header{margin:0;padding:0;font-weight:600;font-size:16px}.description-block>.description-text{text-transform:uppercase}.bg-red,.bg-yellow,.bg-aqua,.bg-blue,.bg-light-blue,.bg-green,.bg-navy,.bg-teal,.bg-olive,.bg-lime,.bg-orange,.bg-fuchsia,.bg-purple,.bg-maroon,.bg-black,.bg-red-active,.bg-yellow-active,.bg-aqua-active,.bg-blue-active,.bg-light-blue-active,.bg-green-active,.bg-navy-active,.bg-teal-active,.bg-olive-active,.bg-lime-active,.bg-orange-active,.bg-fuchsia-active,.bg-purple-active,.bg-maroon-active,.bg-black-active,.callout.callout-danger,.callout.callout-warning,.callout.callout-info,.callout.callout-success,.alert-success,.alert-danger,.alert-error,.alert-warning,.alert-info,.label-danger,.label-info,.label-warning,.label-primary,.label-success,.modal-primary .modal-body,.modal-primary .modal-header,.modal-primary .modal-footer,.modal-warning .modal-body,.modal-warning .modal-header,.modal-warning .modal-footer,.modal-info .modal-body,.modal-info .modal-header,.modal-info .modal-footer,.modal-success .modal-body,.modal-success .modal-header,.modal-success .modal-footer,.modal-danger .modal-body,.modal-danger .modal-header,.modal-danger .modal-footer{color:#fff !important}.bg-gray{color:#000;background-color:#d2d6de !important}.bg-gray-light{background-color:#f7f7f7}.bg-black{background-color:#111 !important}.bg-red,.callout.callout-danger,.alert-danger,.alert-error,.label-danger,.modal-danger .modal-body{background-color:#dd4b39 !important}.bg-yellow,.callout.callout-warning,.alert-warning,.label-warning,.modal-warning .modal-body{background-color:#f39c12 !important}.bg-aqua,.callout.callout-info,.alert-info,.label-info,.modal-info .modal-body{background-color:#00c0ef !important}.bg-blue{background-color:#0073b7 !important}.bg-light-blue,.label-primary,.modal-primary .modal-body{background-color:#3c8dbc !important}.bg-green,.callout.callout-success,.alert-success,.label-success,.modal-success .modal-body{background-color:#00a65a !important}.bg-navy{background-color:#001f3f !important}.bg-teal{background-color:#39cccc !important}.bg-olive{background-color:#3d9970 !important}.bg-lime{background-color:#01ff70 !important}.bg-orange{background-color:#ff851b !important}.bg-fuchsia{background-color:#f012be !important}.bg-purple{background-color:#605ca8 !important}.bg-maroon{background-color:#d81b60 !important}.bg-gray-active{color:#000;background-color:#b5bbc8 !important}.bg-black-active{background-color:#000 !important}.bg-red-active,.modal-danger .modal-header,.modal-danger .modal-footer{background-color:#d33724 !important}.bg-yellow-active,.modal-warning .modal-header,.modal-warning .modal-footer{background-color:#db8b0b !important}.bg-aqua-active,.modal-info .modal-header,.modal-info .modal-footer{background-color:#00a7d0 !important}.bg-blue-active{background-color:#005384 !important}.bg-light-blue-active,.modal-primary .modal-header,.modal-primary .modal-footer{background-color:#357ca5 !important}.bg-green-active,.modal-success .modal-header,.modal-success .modal-footer{background-color:#008d4c !important}.bg-navy-active{background-color:#001a35 !important}.bg-teal-active{background-color:#30bbbb !important}.bg-olive-active{background-color:#368763 !important}.bg-lime-active{background-color:#00e765 !important}.bg-orange-active{background-color:#ff7701 !important}.bg-fuchsia-active{background-color:#db0ead !important}.bg-purple-active{background-color:#555299 !important}.bg-maroon-active{background-color:#ca195a !important}[class^="bg-"].disabled{opacity:.65;filter:alpha(opacity=65)}.text-red{color:#dd4b39 !important}.text-yellow{color:#f39c12 !important}.text-aqua{color:#00c0ef !important}.text-blue{color:#0073b7 !important}.text-black{color:#111 !important}.text-light-blue{color:#3c8dbc !important}.text-green{color:#00a65a !important}.text-gray{color:#d2d6de !important}.text-navy{color:#001f3f !important}.text-teal{color:#39cccc !important}.text-olive{color:#3d9970 !important}.text-lime{color:#01ff70 !important}.text-orange{color:#ff851b !important}.text-fuchsia{color:#f012be !important}.text-purple{color:#605ca8 !important}.text-maroon{color:#d81b60 !important}.link-muted{color:#7a869d}.link-muted:hover,.link-muted:focus{color:#606c84}.link-black{color:#666}.link-black:hover,.link-black:focus{color:#999}.hide{display:none !important}.no-border{border:0 !important}.no-padding{padding:0 !important}.no-margin{margin:0 !important}.no-shadow{box-shadow:none!important}.list-unstyled,.chart-legend,.contacts-list,.users-list,.mailbox-attachments{list-style:none;margin:0;padding:0}.list-group-unbordered>.list-group-item{border-left:0;border-right:0;border-radius:0;padding-left:0;padding-right:0}.flat{border-radius:0 !important}.text-bold,.text-bold.table td,.text-bold.table th{font-weight:700}.text-sm{font-size:12px}.jqstooltip{padding:5px!important;width:auto!important;height:auto!important}.bg-teal-gradient{background:#39cccc !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #39cccc), color-stop(1, #7adddd)) !important;background:-ms-linear-gradient(bottom, #39cccc, #7adddd) !important;background:-moz-linear-gradient(center bottom, #39cccc 0, #7adddd 100%) !important;background:-o-linear-gradient(#7adddd, #39cccc) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#7adddd', endColorstr='#39cccc', GradientType=0) !important;color:#fff}.bg-light-blue-gradient{background:#3c8dbc !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #3c8dbc), color-stop(1, #67a8ce)) !important;background:-ms-linear-gradient(bottom, #3c8dbc, #67a8ce) !important;background:-moz-linear-gradient(center bottom, #3c8dbc 0, #67a8ce 100%) !important;background:-o-linear-gradient(#67a8ce, #3c8dbc) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#67a8ce', endColorstr='#3c8dbc', GradientType=0) !important;color:#fff}.bg-blue-gradient{background:#0073b7 !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #0073b7), color-stop(1, #0089db)) !important;background:-ms-linear-gradient(bottom, #0073b7, #0089db) !important;background:-moz-linear-gradient(center bottom, #0073b7 0, #0089db 100%) !important;background:-o-linear-gradient(#0089db, #0073b7) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#0089db', endColorstr='#0073b7', GradientType=0) !important;color:#fff}.bg-aqua-gradient{background:#00c0ef !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #00c0ef), color-stop(1, #14d1ff)) !important;background:-ms-linear-gradient(bottom, #00c0ef, #14d1ff) !important;background:-moz-linear-gradient(center bottom, #00c0ef 0, #14d1ff 100%) !important;background:-o-linear-gradient(#14d1ff, #00c0ef) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#14d1ff', endColorstr='#00c0ef', GradientType=0) !important;color:#fff}.bg-yellow-gradient{background:#f39c12 !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #f39c12), color-stop(1, #f7bc60)) !important;background:-ms-linear-gradient(bottom, #f39c12, #f7bc60) !important;background:-moz-linear-gradient(center bottom, #f39c12 0, #f7bc60 100%) !important;background:-o-linear-gradient(#f7bc60, #f39c12) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f7bc60', endColorstr='#f39c12', GradientType=0) !important;color:#fff}.bg-purple-gradient{background:#605ca8 !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #605ca8), color-stop(1, #9491c4)) !important;background:-ms-linear-gradient(bottom, #605ca8, #9491c4) !important;background:-moz-linear-gradient(center bottom, #605ca8 0, #9491c4 100%) !important;background:-o-linear-gradient(#9491c4, #605ca8) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#9491c4', endColorstr='#605ca8', GradientType=0) !important;color:#fff}.bg-green-gradient{background:#00a65a !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #00a65a), color-stop(1, #00ca6d)) !important;background:-ms-linear-gradient(bottom, #00a65a, #00ca6d) !important;background:-moz-linear-gradient(center bottom, #00a65a 0, #00ca6d 100%) !important;background:-o-linear-gradient(#00ca6d, #00a65a) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ca6d', endColorstr='#00a65a', GradientType=0) !important;color:#fff}.bg-red-gradient{background:#dd4b39 !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #dd4b39), color-stop(1, #e47365)) !important;background:-ms-linear-gradient(bottom, #dd4b39, #e47365) !important;background:-moz-linear-gradient(center bottom, #dd4b39 0, #e47365 100%) !important;background:-o-linear-gradient(#e47365, #dd4b39) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e47365', endColorstr='#dd4b39', GradientType=0) !important;color:#fff}.bg-black-gradient{background:#111 !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #111), color-stop(1, #2b2b2b)) !important;background:-ms-linear-gradient(bottom, #111, #2b2b2b) !important;background:-moz-linear-gradient(center bottom, #111 0, #2b2b2b 100%) !important;background:-o-linear-gradient(#2b2b2b, #111) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#2b2b2b', endColorstr='#111111', GradientType=0) !important;color:#fff}.bg-maroon-gradient{background:#d81b60 !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #d81b60), color-stop(1, #e73f7c)) !important;background:-ms-linear-gradient(bottom, #d81b60, #e73f7c) !important;background:-moz-linear-gradient(center bottom, #d81b60 0, #e73f7c 100%) !important;background:-o-linear-gradient(#e73f7c, #d81b60) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e73f7c', endColorstr='#d81b60', GradientType=0) !important;color:#fff}.description-block .description-icon{font-size:16px}.no-pad-top{padding-top:0}.position-static{position:static!important}.list-header{font-size:15px;padding:10px 4px;font-weight:bold;color:#666}.list-seperator{height:1px;background:#f4f4f4;margin:15px 0 9px 0}.list-link>a{padding:4px;color:#777}.list-link>a:hover{color:#222}.font-light{font-weight:300}.user-block:before,.user-block:after{content:" ";display:table}.user-block:after{clear:both}.user-block img{width:40px;height:40px;float:left}.user-block .username,.user-block .description,.user-block .comment{display:block;margin-left:50px}.user-block .username{font-size:16px;font-weight:600}.user-block .description{color:#999;font-size:13px}.user-block.user-block-sm .username,.user-block.user-block-sm .description,.user-block.user-block-sm .comment{margin-left:40px}.user-block.user-block-sm .username{font-size:14px}.img-sm,.img-md,.img-lg,.box-comments .box-comment img,.user-block.user-block-sm img{float:left}.img-sm,.box-comments .box-comment img,.user-block.user-block-sm img{width:30px!important;height:30px!important}.img-sm+.img-push{margin-left:40px}.img-md{width:60px;height:60px}.img-md+.img-push{margin-left:70px}.img-lg{width:100px;height:100px}.img-lg+.img-push{margin-left:110px}.img-bordered{border:3px solid #d2d6de;padding:3px}.img-bordered-sm{border:2px solid #d2d6de;padding:2px}.attachment-block{border:1px solid #f4f4f4;padding:5px;margin-bottom:10px;background:#f7f7f7}.attachment-block .attachment-img{max-width:100px;max-height:100px;height:auto;float:left}.attachment-block .attachment-pushed{margin-left:110px}.attachment-block .attachment-heading{margin:0}.attachment-block .attachment-text{color:#555}.connectedSortable{min-height:100px}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sort-highlight{background:#f4f4f4;border:1px dashed #ddd;margin-bottom:10px}.full-opacity-hover{opacity:.65;filter:alpha(opacity=65)}.full-opacity-hover:hover{opacity:1;filter:alpha(opacity=100)}.chart{position:relative;overflow:hidden;width:100%}.chart svg,.chart canvas{width:100%!important}@media print{.no-print,.main-sidebar,.left-side,.main-header,.content-header{display:none!important}.content-wrapper,.right-side,.main-footer{margin-left:0!important;min-height:0!important;-webkit-transform:translate(0, 0) !important;-ms-transform:translate(0, 0) !important;-o-transform:translate(0, 0) !important;transform:translate(0, 0) !important}.fixed .content-wrapper,.fixed .right-side{padding-top:0!important}.invoice{width:100%;border:0;margin:0;padding:0}.invoice-col{float:left;width:33.3333333%}.table-responsive{overflow:auto}.table-responsive>.table tr th,.table-responsive>.table tr td{white-space:normal!important}} \ No newline at end of file diff --git a/LinuxGUI/WebUI/static/AdminLTE/css/skins/skin-blue.min.css b/LinuxGUI/WebUI/static/AdminLTE/css/skins/skin-blue.min.css new file mode 100644 index 0000000..123c04f --- /dev/null +++ b/LinuxGUI/WebUI/static/AdminLTE/css/skins/skin-blue.min.css @@ -0,0 +1 @@ +.skin-blue .main-header .navbar{background-color:#3c8dbc}.skin-blue .main-header .navbar .nav>li>a{color:#fff}.skin-blue .main-header .navbar .nav>li>a:hover,.skin-blue .main-header .navbar .nav>li>a:active,.skin-blue .main-header .navbar .nav>li>a:focus,.skin-blue .main-header .navbar .nav .open>a,.skin-blue .main-header .navbar .nav .open>a:hover,.skin-blue .main-header .navbar .nav .open>a:focus,.skin-blue .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-blue .main-header .navbar .sidebar-toggle{color:#fff}.skin-blue .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-blue .main-header .navbar .sidebar-toggle{color:#fff}.skin-blue .main-header .navbar .sidebar-toggle:hover{background-color:#367fa9}@media (max-width:767px){.skin-blue .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-blue .main-header .navbar .dropdown-menu li a{color:#fff}.skin-blue .main-header .navbar .dropdown-menu li a:hover{background:#367fa9}}.skin-blue .main-header .logo{background-color:#367fa9;color:#fff;border-bottom:0 solid transparent}.skin-blue .main-header .logo:hover{background-color:#357ca5}.skin-blue .main-header li.user-header{background-color:#3c8dbc}.skin-blue .content-header{background:transparent}.skin-blue .wrapper,.skin-blue .main-sidebar,.skin-blue .left-side{background-color:#222d32}.skin-blue .user-panel>.info,.skin-blue .user-panel>.info>a{color:#fff}.skin-blue .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-blue .sidebar-menu>li>a{border-left:3px solid transparent}.skin-blue .sidebar-menu>li:hover>a,.skin-blue .sidebar-menu>li.active>a{color:#fff;background:#1e282c;border-left-color:#3c8dbc}.skin-blue .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-blue .sidebar a{color:#b8c7ce}.skin-blue .sidebar a:hover{text-decoration:none}.skin-blue .treeview-menu>li>a{color:#8aa4af}.skin-blue .treeview-menu>li.active>a,.skin-blue .treeview-menu>li>a:hover{color:#fff}.skin-blue .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px 10px}.skin-blue .sidebar-form input[type="text"],.skin-blue .sidebar-form .btn{box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px;-webkit-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;transition:all .3s ease-in-out}.skin-blue .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-blue .sidebar-form input[type="text"]:focus,.skin-blue .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-blue .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-blue .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}.skin-blue.layout-top-nav .main-header>.logo{background-color:#3c8dbc;color:#fff;border-bottom:0 solid transparent}.skin-blue.layout-top-nav .main-header>.logo:hover{background-color:#3b8ab8} \ No newline at end of file diff --git a/LinuxGUI/WebUI/static/AdminLTE/js/app.min.js b/LinuxGUI/WebUI/static/AdminLTE/js/app.min.js new file mode 100644 index 0000000..679f18f --- /dev/null +++ b/LinuxGUI/WebUI/static/AdminLTE/js/app.min.js @@ -0,0 +1,13 @@ +/*! AdminLTE app.js + * ================ + * Main JS application file for AdminLTE v2. This file + * should be included in all pages. It controls some layout + * options and implements exclusive AdminLTE plugins. + * + * @Author Almsaeed Studio + * @Support + * @Email + * @version 2.3.0 + * @license MIT + */ +function _init(){"use strict";$.AdminLTE.layout={activate:function(){var a=this;a.fix(),a.fixSidebar(),$(window,".wrapper").resize(function(){a.fix(),a.fixSidebar()})},fix:function(){var a=$(".main-header").outerHeight()+$(".main-footer").outerHeight(),b=$(window).height(),c=$(".sidebar").height();if($("body").hasClass("fixed"))$(".content-wrapper, .right-side").css("min-height",b-$(".main-footer").outerHeight());else{var d;b>=c?($(".content-wrapper, .right-side").css("min-height",b-a),d=b-a):($(".content-wrapper, .right-side").css("min-height",c),d=c);var e=$($.AdminLTE.options.controlSidebarOptions.selector);"undefined"!=typeof e&&e.height()>d&&$(".content-wrapper, .right-side").css("min-height",e.height())}},fixSidebar:function(){return $("body").hasClass("fixed")?("undefined"==typeof $.fn.slimScroll&&window.console&&window.console.error("Error: the fixed layout requires the slimscroll plugin!"),void($.AdminLTE.options.sidebarSlimScroll&&"undefined"!=typeof $.fn.slimScroll&&($(".sidebar").slimScroll({destroy:!0}).height("auto"),$(".sidebar").slimscroll({height:$(window).height()-$(".main-header").height()+"px",color:"rgba(0,0,0,0.2)",size:"3px"})))):void("undefined"!=typeof $.fn.slimScroll&&$(".sidebar").slimScroll({destroy:!0}).height("auto"))}},$.AdminLTE.pushMenu={activate:function(a){var b=$.AdminLTE.options.screenSizes;$(a).on("click",function(a){a.preventDefault(),$(window).width()>b.sm-1?$("body").hasClass("sidebar-collapse")?$("body").removeClass("sidebar-collapse").trigger("expanded.pushMenu"):$("body").addClass("sidebar-collapse").trigger("collapsed.pushMenu"):$("body").hasClass("sidebar-open")?$("body").removeClass("sidebar-open").removeClass("sidebar-collapse").trigger("collapsed.pushMenu"):$("body").addClass("sidebar-open").trigger("expanded.pushMenu")}),$(".content-wrapper").click(function(){$(window).width()<=b.sm-1&&$("body").hasClass("sidebar-open")&&$("body").removeClass("sidebar-open")}),($.AdminLTE.options.sidebarExpandOnHover||$("body").hasClass("fixed")&&$("body").hasClass("sidebar-mini"))&&this.expandOnHover()},expandOnHover:function(){var a=this,b=$.AdminLTE.options.screenSizes.sm-1;$(".main-sidebar").hover(function(){$("body").hasClass("sidebar-mini")&&$("body").hasClass("sidebar-collapse")&&$(window).width()>b&&a.expand()},function(){$("body").hasClass("sidebar-mini")&&$("body").hasClass("sidebar-expanded-on-hover")&&$(window).width()>b&&a.collapse()})},expand:function(){$("body").removeClass("sidebar-collapse").addClass("sidebar-expanded-on-hover")},collapse:function(){$("body").hasClass("sidebar-expanded-on-hover")&&$("body").removeClass("sidebar-expanded-on-hover").addClass("sidebar-collapse")}},$.AdminLTE.tree=function(a){var b=this,c=$.AdminLTE.options.animationSpeed;$(document).on("click",a+" li a",function(a){var d=$(this),e=d.next();if(e.is(".treeview-menu")&&e.is(":visible"))e.slideUp(c,function(){e.removeClass("menu-open")}),e.parent("li").removeClass("active");else if(e.is(".treeview-menu")&&!e.is(":visible")){var f=d.parents("ul").first(),g=f.find("ul:visible").slideUp(c);g.removeClass("menu-open");var h=d.parent("li");e.slideDown(c,function(){e.addClass("menu-open"),f.find("li.active").removeClass("active"),h.addClass("active"),b.layout.fix()})}e.is(".treeview-menu")&&a.preventDefault()})},$.AdminLTE.controlSidebar={activate:function(){var a=this,b=$.AdminLTE.options.controlSidebarOptions,c=$(b.selector),d=$(b.toggleBtnSelector);d.on("click",function(d){d.preventDefault(),c.hasClass("control-sidebar-open")||$("body").hasClass("control-sidebar-open")?a.close(c,b.slide):a.open(c,b.slide)});var e=$(".control-sidebar-bg");a._fix(e),$("body").hasClass("fixed")?a._fixForFixed(c):$(".content-wrapper, .right-side").height() .box-body, > .box-footer, > form >.box-body, > form > .box-footer");c.hasClass("collapsed-box")?(a.children(":first").removeClass(b.icons.open).addClass(b.icons.collapse),d.slideDown(b.animationSpeed,function(){c.removeClass("collapsed-box")})):(a.children(":first").removeClass(b.icons.collapse).addClass(b.icons.open),d.slideUp(b.animationSpeed,function(){c.addClass("collapsed-box")}))},remove:function(a){var b=a.parents(".box").first();b.slideUp(this.animationSpeed)}}}if("undefined"==typeof jQuery)throw new Error("AdminLTE requires jQuery");$.AdminLTE={},$.AdminLTE.options={navbarMenuSlimscroll:!0,navbarMenuSlimscrollWidth:"3px",navbarMenuHeight:"200px",animationSpeed:500,sidebarToggleSelector:"[data-toggle='offcanvas']",sidebarPushMenu:!0,sidebarSlimScroll:!0,sidebarExpandOnHover:!1,enableBoxRefresh:!0,enableBSToppltip:!0,BSTooltipSelector:"[data-toggle='tooltip']",enableFastclick:!0,enableControlSidebar:!0,controlSidebarOptions:{toggleBtnSelector:"[data-toggle='control-sidebar']",selector:".control-sidebar",slide:!0},enableBoxWidget:!0,boxWidgetOptions:{boxWidgetIcons:{collapse:"fa-minus",open:"fa-plus",remove:"fa-times"},boxWidgetSelectors:{remove:'[data-widget="remove"]',collapse:'[data-widget="collapse"]'}},directChat:{enable:!0,contactToggleSelector:'[data-widget="chat-pane-toggle"]'},colors:{lightBlue:"#3c8dbc",red:"#f56954",green:"#00a65a",aqua:"#00c0ef",yellow:"#f39c12",blue:"#0073b7",navy:"#001F3F",teal:"#39CCCC",olive:"#3D9970",lime:"#01FF70",orange:"#FF851B",fuchsia:"#F012BE",purple:"#8E24AA",maroon:"#D81B60",black:"#222222",gray:"#d2d6de"},screenSizes:{xs:480,sm:768,md:992,lg:1200}},$(function(){"use strict";$("body").removeClass("hold-transition"),"undefined"!=typeof AdminLTEOptions&&$.extend(!0,$.AdminLTE.options,AdminLTEOptions);var a=$.AdminLTE.options;_init(),$.AdminLTE.layout.activate(),$.AdminLTE.tree(".sidebar"),a.enableControlSidebar&&$.AdminLTE.controlSidebar.activate(),a.navbarMenuSlimscroll&&"undefined"!=typeof $.fn.slimscroll&&$(".navbar .menu").slimscroll({height:a.navbarMenuHeight,alwaysVisible:!1,size:a.navbarMenuSlimscrollWidth}).css("width","100%"),a.sidebarPushMenu&&$.AdminLTE.pushMenu.activate(a.sidebarToggleSelector),a.enableBSToppltip&&$("body").tooltip({selector:a.BSTooltipSelector}),a.enableBoxWidget&&$.AdminLTE.boxWidget.activate(),a.enableFastclick&&"undefined"!=typeof FastClick&&FastClick.attach(document.body),a.directChat.enable&&$(document).on("click",a.directChat.contactToggleSelector,function(){var a=$(this).parents(".direct-chat").first();a.toggleClass("direct-chat-contacts-open")}),$('.btn-group[data-toggle="btn-toggle"]').each(function(){var a=$(this);$(this).find(".btn").on("click",function(b){a.find(".btn.active").removeClass("active"),$(this).addClass("active"),b.preventDefault()})})}),function(a){"use strict";a.fn.boxRefresh=function(b){function c(a){a.append(f),e.onLoadStart.call(a)}function d(a){a.find(f).remove(),e.onLoadDone.call(a)}var e=a.extend({trigger:".refresh-btn",source:"",onLoadStart:function(a){return a},onLoadDone:function(a){return a}},b),f=a('
');return this.each(function(){if(""===e.source)return void(window.console&&window.console.log("Please specify a source first - boxRefresh()"));var b=a(this),f=b.find(e.trigger).first();f.on("click",function(a){a.preventDefault(),c(b),b.find(".box-body").load(e.source,function(){d(b)})})})}}(jQuery),function(a){"use strict";a.fn.activateBox=function(){a.AdminLTE.boxWidget.activate(this)}}(jQuery),function(a){"use strict";a.fn.todolist=function(b){var c=a.extend({onCheck:function(a){return a},onUncheck:function(a){return a}},b);return this.each(function(){"undefined"!=typeof a.fn.iCheck?(a("input",this).on("ifChecked",function(){var b=a(this).parents("li").first();b.toggleClass("done"),c.onCheck.call(b)}),a("input",this).on("ifUnchecked",function(){var b=a(this).parents("li").first();b.toggleClass("done"),c.onUncheck.call(b)})):a("input",this).on("change",function(){var b=a(this).parents("li").first();b.toggleClass("done"),a("input",b).is(":checked")?c.onCheck.call(b):c.onUncheck.call(b)})})}}(jQuery); \ No newline at end of file diff --git a/LinuxGUI/WebUI/static/bootstrap/css/bootstrap-theme.min.css b/LinuxGUI/WebUI/static/bootstrap/css/bootstrap-theme.min.css new file mode 100644 index 0000000..61358b1 --- /dev/null +++ b/LinuxGUI/WebUI/static/bootstrap/css/bootstrap-theme.min.css @@ -0,0 +1,5 @@ +/*! + * Bootstrap v3.3.5 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */.btn-danger,.btn-default,.btn-info,.btn-primary,.btn-success,.btn-warning{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-danger.active,.btn-danger:active,.btn-default.active,.btn-default:active,.btn-info.active,.btn-info:active,.btn-primary.active,.btn-primary:active,.btn-success.active,.btn-success:active,.btn-warning.active,.btn-warning:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-danger.disabled,.btn-danger[disabled],.btn-default.disabled,.btn-default[disabled],.btn-info.disabled,.btn-info[disabled],.btn-primary.disabled,.btn-primary[disabled],.btn-success.disabled,.btn-success[disabled],.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-danger,fieldset[disabled] .btn-default,fieldset[disabled] .btn-info,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-success,fieldset[disabled] .btn-warning{-webkit-box-shadow:none;box-shadow:none}.btn-danger .badge,.btn-default .badge,.btn-info .badge,.btn-primary .badge,.btn-success .badge,.btn-warning .badge{text-shadow:none}.btn.active,.btn:active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-o-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc}.btn-default:focus,.btn-default:hover{background-color:#e0e0e0;background-position:0 -15px}.btn-default.active,.btn-default:active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-o-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#265a88));background-image:linear-gradient(to bottom,#337ab7 0,#265a88 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#245580}.btn-primary:focus,.btn-primary:hover{background-color:#265a88;background-position:0 -15px}.btn-primary.active,.btn-primary:active{background-color:#265a88;border-color:#245580}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#265a88;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641));background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:focus,.btn-success:hover{background-color:#419641;background-position:0 -15px}.btn-success.active,.btn-success:active{background-color:#419641;border-color:#3e8f3e}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#2aabd2));background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:focus,.btn-info:hover{background-color:#2aabd2;background-position:0 -15px}.btn-info.active,.btn-info:active{background-color:#2aabd2;border-color:#28a4c9}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#eb9316));background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:focus,.btn-warning:hover{background-color:#eb9316;background-position:0 -15px}.btn-warning.active,.btn-warning:active{background-color:#eb9316;border-color:#e38d13}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c12e2a));background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:focus,.btn-danger:hover{background-color:#c12e2a;background-position:0 -15px}.btn-danger.active,.btn-danger:active{background-color:#c12e2a;border-color:#b92c28}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#c12e2a;background-image:none}.img-thumbnail,.thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{background-color:#2e6da4;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-o-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f8f8f8));background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-o-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dbdbdb),to(#e2e2e2));background-image:linear-gradient(to bottom,#dbdbdb 0,#e2e2e2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-o-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#222));background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-o-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#080808),to(#0f0f0f));background-image:linear-gradient(to bottom,#080808 0,#0f0f0f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-fixed-bottom,.navbar-fixed-top,.navbar-static-top{border-radius:0}@media (max-width:767px){.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#c8e5bc));background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);background-repeat:repeat-x;border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#b9def0));background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);background-repeat:repeat-x;border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#f8efc0));background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);background-repeat:repeat-x;border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-o-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#e7c3c3));background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);background-repeat:repeat-x;border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f5f5f5));background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x}.progress-bar{background-image:-webkit-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-o-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#286090));background-image:linear-gradient(to bottom,#337ab7 0,#286090 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);background-repeat:repeat-x}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#449d44));background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);background-repeat:repeat-x}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#31b0d5));background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);background-repeat:repeat-x}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#ec971f));background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);background-repeat:repeat-x}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c9302c));background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);background-repeat:repeat-x}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{text-shadow:0 -1px 0 #286090;background-image:-webkit-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2b669a));background-image:linear-gradient(to bottom,#337ab7 0,#2b669a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);background-repeat:repeat-x;border-color:#2b669a}.list-group-item.active .badge,.list-group-item.active:focus .badge,.list-group-item.active:hover .badge{text-shadow:none}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#d0e9c6));background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);background-repeat:repeat-x}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#c4e3f3));background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);background-repeat:repeat-x}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#faf2cc));background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);background-repeat:repeat-x}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-o-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#ebcccc));background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);background-repeat:repeat-x}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#e8e8e8),to(#f5f5f5));background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x;border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)} \ No newline at end of file diff --git a/LinuxGUI/WebUI/static/bootstrap/css/bootstrap.min.css b/LinuxGUI/WebUI/static/bootstrap/css/bootstrap.min.css new file mode 100644 index 0000000..be11b9f --- /dev/null +++ b/LinuxGUI/WebUI/static/bootstrap/css/bootstrap.min.css @@ -0,0 +1,5 @@ +/*! + * Bootstrap v3.3.5 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px;font-size:14px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.33px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:3;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:2;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} \ No newline at end of file diff --git a/LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.eot b/LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.eot new file mode 100644 index 0000000..b93a495 Binary files /dev/null and b/LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.eot differ diff --git a/LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.svg b/LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.svg new file mode 100644 index 0000000..94fb549 --- /dev/null +++ b/LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.svg @@ -0,0 +1,288 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.ttf b/LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.ttf new file mode 100644 index 0000000..1413fc6 Binary files /dev/null and b/LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.ttf differ diff --git a/LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.woff b/LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.woff new file mode 100644 index 0000000..9e61285 Binary files /dev/null and b/LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.woff differ diff --git a/LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.woff2 b/LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.woff2 new file mode 100644 index 0000000..64539b5 Binary files /dev/null and b/LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.woff2 differ diff --git a/LinuxGUI/WebUI/static/bootstrap/js/bootstrap.min.js b/LinuxGUI/WebUI/static/bootstrap/js/bootstrap.min.js new file mode 100644 index 0000000..133aeec --- /dev/null +++ b/LinuxGUI/WebUI/static/bootstrap/js/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v3.3.5 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under the MIT license + */ +if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.5",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.5",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),a(c.target).is('input[type="radio"]')||a(c.target).is('input[type="checkbox"]')||c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.5",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.5",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger("hidden.bs.dropdown",f))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.5",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger("shown.bs.dropdown",h)}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&jdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth
',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),c.isInStateTrue()?void 0:(clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide())},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.5",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.5",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.5",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); \ No newline at end of file diff --git a/LinuxGUI/WebUI/static/css/font-awesome.min.css b/LinuxGUI/WebUI/static/css/font-awesome.min.css new file mode 100644 index 0000000..aae88c4 --- /dev/null +++ b/LinuxGUI/WebUI/static/css/font-awesome.min.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.4.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.4.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.4.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.4.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.4.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.4.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.4.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"} diff --git a/LinuxGUI/WebUI/static/css/ionicons.min.css b/LinuxGUI/WebUI/static/css/ionicons.min.css new file mode 100644 index 0000000..e4bd1ef --- /dev/null +++ b/LinuxGUI/WebUI/static/css/ionicons.min.css @@ -0,0 +1,11 @@ +@charset "UTF-8";/*! + Ionicons, v2.0.1 + Created by Ben Sperry for the Ionic Framework, http://ionicons.com/ + https://twitter.com/benjsperry https://twitter.com/ionicframework + MIT License: https://github.com/driftyco/ionicons + + Android-style icons originally built by Google’s + Material Design Icons: https://github.com/google/material-design-icons + used under CC BY http://creativecommons.org/licenses/by/4.0/ + Modified icons to fit ionicon’s grid from original. +*/@font-face{font-family:"Ionicons";src:url("../fonts/ionicons.eot?v=2.0.1");src:url("../fonts/ionicons.eot?v=2.0.1#iefix") format("embedded-opentype"),url("../fonts/ionicons.ttf?v=2.0.1") format("truetype"),url("../fonts/ionicons.woff?v=2.0.1") format("woff"),url("../fonts/ionicons.svg?v=2.0.1#Ionicons") format("svg");font-weight:normal;font-style:normal}.ion,.ionicons,.ion-alert:before,.ion-alert-circled:before,.ion-android-add:before,.ion-android-add-circle:before,.ion-android-alarm-clock:before,.ion-android-alert:before,.ion-android-apps:before,.ion-android-archive:before,.ion-android-arrow-back:before,.ion-android-arrow-down:before,.ion-android-arrow-dropdown:before,.ion-android-arrow-dropdown-circle:before,.ion-android-arrow-dropleft:before,.ion-android-arrow-dropleft-circle:before,.ion-android-arrow-dropright:before,.ion-android-arrow-dropright-circle:before,.ion-android-arrow-dropup:before,.ion-android-arrow-dropup-circle:before,.ion-android-arrow-forward:before,.ion-android-arrow-up:before,.ion-android-attach:before,.ion-android-bar:before,.ion-android-bicycle:before,.ion-android-boat:before,.ion-android-bookmark:before,.ion-android-bulb:before,.ion-android-bus:before,.ion-android-calendar:before,.ion-android-call:before,.ion-android-camera:before,.ion-android-cancel:before,.ion-android-car:before,.ion-android-cart:before,.ion-android-chat:before,.ion-android-checkbox:before,.ion-android-checkbox-blank:before,.ion-android-checkbox-outline:before,.ion-android-checkbox-outline-blank:before,.ion-android-checkmark-circle:before,.ion-android-clipboard:before,.ion-android-close:before,.ion-android-cloud:before,.ion-android-cloud-circle:before,.ion-android-cloud-done:before,.ion-android-cloud-outline:before,.ion-android-color-palette:before,.ion-android-compass:before,.ion-android-contact:before,.ion-android-contacts:before,.ion-android-contract:before,.ion-android-create:before,.ion-android-delete:before,.ion-android-desktop:before,.ion-android-document:before,.ion-android-done:before,.ion-android-done-all:before,.ion-android-download:before,.ion-android-drafts:before,.ion-android-exit:before,.ion-android-expand:before,.ion-android-favorite:before,.ion-android-favorite-outline:before,.ion-android-film:before,.ion-android-folder:before,.ion-android-folder-open:before,.ion-android-funnel:before,.ion-android-globe:before,.ion-android-hand:before,.ion-android-hangout:before,.ion-android-happy:before,.ion-android-home:before,.ion-android-image:before,.ion-android-laptop:before,.ion-android-list:before,.ion-android-locate:before,.ion-android-lock:before,.ion-android-mail:before,.ion-android-map:before,.ion-android-menu:before,.ion-android-microphone:before,.ion-android-microphone-off:before,.ion-android-more-horizontal:before,.ion-android-more-vertical:before,.ion-android-navigate:before,.ion-android-notifications:before,.ion-android-notifications-none:before,.ion-android-notifications-off:before,.ion-android-open:before,.ion-android-options:before,.ion-android-people:before,.ion-android-person:before,.ion-android-person-add:before,.ion-android-phone-landscape:before,.ion-android-phone-portrait:before,.ion-android-pin:before,.ion-android-plane:before,.ion-android-playstore:before,.ion-android-print:before,.ion-android-radio-button-off:before,.ion-android-radio-button-on:before,.ion-android-refresh:before,.ion-android-remove:before,.ion-android-remove-circle:before,.ion-android-restaurant:before,.ion-android-sad:before,.ion-android-search:before,.ion-android-send:before,.ion-android-settings:before,.ion-android-share:before,.ion-android-share-alt:before,.ion-android-star:before,.ion-android-star-half:before,.ion-android-star-outline:before,.ion-android-stopwatch:before,.ion-android-subway:before,.ion-android-sunny:before,.ion-android-sync:before,.ion-android-textsms:before,.ion-android-time:before,.ion-android-train:before,.ion-android-unlock:before,.ion-android-upload:before,.ion-android-volume-down:before,.ion-android-volume-mute:before,.ion-android-volume-off:before,.ion-android-volume-up:before,.ion-android-walk:before,.ion-android-warning:before,.ion-android-watch:before,.ion-android-wifi:before,.ion-aperture:before,.ion-archive:before,.ion-arrow-down-a:before,.ion-arrow-down-b:before,.ion-arrow-down-c:before,.ion-arrow-expand:before,.ion-arrow-graph-down-left:before,.ion-arrow-graph-down-right:before,.ion-arrow-graph-up-left:before,.ion-arrow-graph-up-right:before,.ion-arrow-left-a:before,.ion-arrow-left-b:before,.ion-arrow-left-c:before,.ion-arrow-move:before,.ion-arrow-resize:before,.ion-arrow-return-left:before,.ion-arrow-return-right:before,.ion-arrow-right-a:before,.ion-arrow-right-b:before,.ion-arrow-right-c:before,.ion-arrow-shrink:before,.ion-arrow-swap:before,.ion-arrow-up-a:before,.ion-arrow-up-b:before,.ion-arrow-up-c:before,.ion-asterisk:before,.ion-at:before,.ion-backspace:before,.ion-backspace-outline:before,.ion-bag:before,.ion-battery-charging:before,.ion-battery-empty:before,.ion-battery-full:before,.ion-battery-half:before,.ion-battery-low:before,.ion-beaker:before,.ion-beer:before,.ion-bluetooth:before,.ion-bonfire:before,.ion-bookmark:before,.ion-bowtie:before,.ion-briefcase:before,.ion-bug:before,.ion-calculator:before,.ion-calendar:before,.ion-camera:before,.ion-card:before,.ion-cash:before,.ion-chatbox:before,.ion-chatbox-working:before,.ion-chatboxes:before,.ion-chatbubble:before,.ion-chatbubble-working:before,.ion-chatbubbles:before,.ion-checkmark:before,.ion-checkmark-circled:before,.ion-checkmark-round:before,.ion-chevron-down:before,.ion-chevron-left:before,.ion-chevron-right:before,.ion-chevron-up:before,.ion-clipboard:before,.ion-clock:before,.ion-close:before,.ion-close-circled:before,.ion-close-round:before,.ion-closed-captioning:before,.ion-cloud:before,.ion-code:before,.ion-code-download:before,.ion-code-working:before,.ion-coffee:before,.ion-compass:before,.ion-compose:before,.ion-connection-bars:before,.ion-contrast:before,.ion-crop:before,.ion-cube:before,.ion-disc:before,.ion-document:before,.ion-document-text:before,.ion-drag:before,.ion-earth:before,.ion-easel:before,.ion-edit:before,.ion-egg:before,.ion-eject:before,.ion-email:before,.ion-email-unread:before,.ion-erlenmeyer-flask:before,.ion-erlenmeyer-flask-bubbles:before,.ion-eye:before,.ion-eye-disabled:before,.ion-female:before,.ion-filing:before,.ion-film-marker:before,.ion-fireball:before,.ion-flag:before,.ion-flame:before,.ion-flash:before,.ion-flash-off:before,.ion-folder:before,.ion-fork:before,.ion-fork-repo:before,.ion-forward:before,.ion-funnel:before,.ion-gear-a:before,.ion-gear-b:before,.ion-grid:before,.ion-hammer:before,.ion-happy:before,.ion-happy-outline:before,.ion-headphone:before,.ion-heart:before,.ion-heart-broken:before,.ion-help:before,.ion-help-buoy:before,.ion-help-circled:before,.ion-home:before,.ion-icecream:before,.ion-image:before,.ion-images:before,.ion-information:before,.ion-information-circled:before,.ion-ionic:before,.ion-ios-alarm:before,.ion-ios-alarm-outline:before,.ion-ios-albums:before,.ion-ios-albums-outline:before,.ion-ios-americanfootball:before,.ion-ios-americanfootball-outline:before,.ion-ios-analytics:before,.ion-ios-analytics-outline:before,.ion-ios-arrow-back:before,.ion-ios-arrow-down:before,.ion-ios-arrow-forward:before,.ion-ios-arrow-left:before,.ion-ios-arrow-right:before,.ion-ios-arrow-thin-down:before,.ion-ios-arrow-thin-left:before,.ion-ios-arrow-thin-right:before,.ion-ios-arrow-thin-up:before,.ion-ios-arrow-up:before,.ion-ios-at:before,.ion-ios-at-outline:before,.ion-ios-barcode:before,.ion-ios-barcode-outline:before,.ion-ios-baseball:before,.ion-ios-baseball-outline:before,.ion-ios-basketball:before,.ion-ios-basketball-outline:before,.ion-ios-bell:before,.ion-ios-bell-outline:before,.ion-ios-body:before,.ion-ios-body-outline:before,.ion-ios-bolt:before,.ion-ios-bolt-outline:before,.ion-ios-book:before,.ion-ios-book-outline:before,.ion-ios-bookmarks:before,.ion-ios-bookmarks-outline:before,.ion-ios-box:before,.ion-ios-box-outline:before,.ion-ios-briefcase:before,.ion-ios-briefcase-outline:before,.ion-ios-browsers:before,.ion-ios-browsers-outline:before,.ion-ios-calculator:before,.ion-ios-calculator-outline:before,.ion-ios-calendar:before,.ion-ios-calendar-outline:before,.ion-ios-camera:before,.ion-ios-camera-outline:before,.ion-ios-cart:before,.ion-ios-cart-outline:before,.ion-ios-chatboxes:before,.ion-ios-chatboxes-outline:before,.ion-ios-chatbubble:before,.ion-ios-chatbubble-outline:before,.ion-ios-checkmark:before,.ion-ios-checkmark-empty:before,.ion-ios-checkmark-outline:before,.ion-ios-circle-filled:before,.ion-ios-circle-outline:before,.ion-ios-clock:before,.ion-ios-clock-outline:before,.ion-ios-close:before,.ion-ios-close-empty:before,.ion-ios-close-outline:before,.ion-ios-cloud:before,.ion-ios-cloud-download:before,.ion-ios-cloud-download-outline:before,.ion-ios-cloud-outline:before,.ion-ios-cloud-upload:before,.ion-ios-cloud-upload-outline:before,.ion-ios-cloudy:before,.ion-ios-cloudy-night:before,.ion-ios-cloudy-night-outline:before,.ion-ios-cloudy-outline:before,.ion-ios-cog:before,.ion-ios-cog-outline:before,.ion-ios-color-filter:before,.ion-ios-color-filter-outline:before,.ion-ios-color-wand:before,.ion-ios-color-wand-outline:before,.ion-ios-compose:before,.ion-ios-compose-outline:before,.ion-ios-contact:before,.ion-ios-contact-outline:before,.ion-ios-copy:before,.ion-ios-copy-outline:before,.ion-ios-crop:before,.ion-ios-crop-strong:before,.ion-ios-download:before,.ion-ios-download-outline:before,.ion-ios-drag:before,.ion-ios-email:before,.ion-ios-email-outline:before,.ion-ios-eye:before,.ion-ios-eye-outline:before,.ion-ios-fastforward:before,.ion-ios-fastforward-outline:before,.ion-ios-filing:before,.ion-ios-filing-outline:before,.ion-ios-film:before,.ion-ios-film-outline:before,.ion-ios-flag:before,.ion-ios-flag-outline:before,.ion-ios-flame:before,.ion-ios-flame-outline:before,.ion-ios-flask:before,.ion-ios-flask-outline:before,.ion-ios-flower:before,.ion-ios-flower-outline:before,.ion-ios-folder:before,.ion-ios-folder-outline:before,.ion-ios-football:before,.ion-ios-football-outline:before,.ion-ios-game-controller-a:before,.ion-ios-game-controller-a-outline:before,.ion-ios-game-controller-b:before,.ion-ios-game-controller-b-outline:before,.ion-ios-gear:before,.ion-ios-gear-outline:before,.ion-ios-glasses:before,.ion-ios-glasses-outline:before,.ion-ios-grid-view:before,.ion-ios-grid-view-outline:before,.ion-ios-heart:before,.ion-ios-heart-outline:before,.ion-ios-help:before,.ion-ios-help-empty:before,.ion-ios-help-outline:before,.ion-ios-home:before,.ion-ios-home-outline:before,.ion-ios-infinite:before,.ion-ios-infinite-outline:before,.ion-ios-information:before,.ion-ios-information-empty:before,.ion-ios-information-outline:before,.ion-ios-ionic-outline:before,.ion-ios-keypad:before,.ion-ios-keypad-outline:before,.ion-ios-lightbulb:before,.ion-ios-lightbulb-outline:before,.ion-ios-list:before,.ion-ios-list-outline:before,.ion-ios-location:before,.ion-ios-location-outline:before,.ion-ios-locked:before,.ion-ios-locked-outline:before,.ion-ios-loop:before,.ion-ios-loop-strong:before,.ion-ios-medical:before,.ion-ios-medical-outline:before,.ion-ios-medkit:before,.ion-ios-medkit-outline:before,.ion-ios-mic:before,.ion-ios-mic-off:before,.ion-ios-mic-outline:before,.ion-ios-minus:before,.ion-ios-minus-empty:before,.ion-ios-minus-outline:before,.ion-ios-monitor:before,.ion-ios-monitor-outline:before,.ion-ios-moon:before,.ion-ios-moon-outline:before,.ion-ios-more:before,.ion-ios-more-outline:before,.ion-ios-musical-note:before,.ion-ios-musical-notes:before,.ion-ios-navigate:before,.ion-ios-navigate-outline:before,.ion-ios-nutrition:before,.ion-ios-nutrition-outline:before,.ion-ios-paper:before,.ion-ios-paper-outline:before,.ion-ios-paperplane:before,.ion-ios-paperplane-outline:before,.ion-ios-partlysunny:before,.ion-ios-partlysunny-outline:before,.ion-ios-pause:before,.ion-ios-pause-outline:before,.ion-ios-paw:before,.ion-ios-paw-outline:before,.ion-ios-people:before,.ion-ios-people-outline:before,.ion-ios-person:before,.ion-ios-person-outline:before,.ion-ios-personadd:before,.ion-ios-personadd-outline:before,.ion-ios-photos:before,.ion-ios-photos-outline:before,.ion-ios-pie:before,.ion-ios-pie-outline:before,.ion-ios-pint:before,.ion-ios-pint-outline:before,.ion-ios-play:before,.ion-ios-play-outline:before,.ion-ios-plus:before,.ion-ios-plus-empty:before,.ion-ios-plus-outline:before,.ion-ios-pricetag:before,.ion-ios-pricetag-outline:before,.ion-ios-pricetags:before,.ion-ios-pricetags-outline:before,.ion-ios-printer:before,.ion-ios-printer-outline:before,.ion-ios-pulse:before,.ion-ios-pulse-strong:before,.ion-ios-rainy:before,.ion-ios-rainy-outline:before,.ion-ios-recording:before,.ion-ios-recording-outline:before,.ion-ios-redo:before,.ion-ios-redo-outline:before,.ion-ios-refresh:before,.ion-ios-refresh-empty:before,.ion-ios-refresh-outline:before,.ion-ios-reload:before,.ion-ios-reverse-camera:before,.ion-ios-reverse-camera-outline:before,.ion-ios-rewind:before,.ion-ios-rewind-outline:before,.ion-ios-rose:before,.ion-ios-rose-outline:before,.ion-ios-search:before,.ion-ios-search-strong:before,.ion-ios-settings:before,.ion-ios-settings-strong:before,.ion-ios-shuffle:before,.ion-ios-shuffle-strong:before,.ion-ios-skipbackward:before,.ion-ios-skipbackward-outline:before,.ion-ios-skipforward:before,.ion-ios-skipforward-outline:before,.ion-ios-snowy:before,.ion-ios-speedometer:before,.ion-ios-speedometer-outline:before,.ion-ios-star:before,.ion-ios-star-half:before,.ion-ios-star-outline:before,.ion-ios-stopwatch:before,.ion-ios-stopwatch-outline:before,.ion-ios-sunny:before,.ion-ios-sunny-outline:before,.ion-ios-telephone:before,.ion-ios-telephone-outline:before,.ion-ios-tennisball:before,.ion-ios-tennisball-outline:before,.ion-ios-thunderstorm:before,.ion-ios-thunderstorm-outline:before,.ion-ios-time:before,.ion-ios-time-outline:before,.ion-ios-timer:before,.ion-ios-timer-outline:before,.ion-ios-toggle:before,.ion-ios-toggle-outline:before,.ion-ios-trash:before,.ion-ios-trash-outline:before,.ion-ios-undo:before,.ion-ios-undo-outline:before,.ion-ios-unlocked:before,.ion-ios-unlocked-outline:before,.ion-ios-upload:before,.ion-ios-upload-outline:before,.ion-ios-videocam:before,.ion-ios-videocam-outline:before,.ion-ios-volume-high:before,.ion-ios-volume-low:before,.ion-ios-wineglass:before,.ion-ios-wineglass-outline:before,.ion-ios-world:before,.ion-ios-world-outline:before,.ion-ipad:before,.ion-iphone:before,.ion-ipod:before,.ion-jet:before,.ion-key:before,.ion-knife:before,.ion-laptop:before,.ion-leaf:before,.ion-levels:before,.ion-lightbulb:before,.ion-link:before,.ion-load-a:before,.ion-load-b:before,.ion-load-c:before,.ion-load-d:before,.ion-location:before,.ion-lock-combination:before,.ion-locked:before,.ion-log-in:before,.ion-log-out:before,.ion-loop:before,.ion-magnet:before,.ion-male:before,.ion-man:before,.ion-map:before,.ion-medkit:before,.ion-merge:before,.ion-mic-a:before,.ion-mic-b:before,.ion-mic-c:before,.ion-minus:before,.ion-minus-circled:before,.ion-minus-round:before,.ion-model-s:before,.ion-monitor:before,.ion-more:before,.ion-mouse:before,.ion-music-note:before,.ion-navicon:before,.ion-navicon-round:before,.ion-navigate:before,.ion-network:before,.ion-no-smoking:before,.ion-nuclear:before,.ion-outlet:before,.ion-paintbrush:before,.ion-paintbucket:before,.ion-paper-airplane:before,.ion-paperclip:before,.ion-pause:before,.ion-person:before,.ion-person-add:before,.ion-person-stalker:before,.ion-pie-graph:before,.ion-pin:before,.ion-pinpoint:before,.ion-pizza:before,.ion-plane:before,.ion-planet:before,.ion-play:before,.ion-playstation:before,.ion-plus:before,.ion-plus-circled:before,.ion-plus-round:before,.ion-podium:before,.ion-pound:before,.ion-power:before,.ion-pricetag:before,.ion-pricetags:before,.ion-printer:before,.ion-pull-request:before,.ion-qr-scanner:before,.ion-quote:before,.ion-radio-waves:before,.ion-record:before,.ion-refresh:before,.ion-reply:before,.ion-reply-all:before,.ion-ribbon-a:before,.ion-ribbon-b:before,.ion-sad:before,.ion-sad-outline:before,.ion-scissors:before,.ion-search:before,.ion-settings:before,.ion-share:before,.ion-shuffle:before,.ion-skip-backward:before,.ion-skip-forward:before,.ion-social-android:before,.ion-social-android-outline:before,.ion-social-angular:before,.ion-social-angular-outline:before,.ion-social-apple:before,.ion-social-apple-outline:before,.ion-social-bitcoin:before,.ion-social-bitcoin-outline:before,.ion-social-buffer:before,.ion-social-buffer-outline:before,.ion-social-chrome:before,.ion-social-chrome-outline:before,.ion-social-codepen:before,.ion-social-codepen-outline:before,.ion-social-css3:before,.ion-social-css3-outline:before,.ion-social-designernews:before,.ion-social-designernews-outline:before,.ion-social-dribbble:before,.ion-social-dribbble-outline:before,.ion-social-dropbox:before,.ion-social-dropbox-outline:before,.ion-social-euro:before,.ion-social-euro-outline:before,.ion-social-facebook:before,.ion-social-facebook-outline:before,.ion-social-foursquare:before,.ion-social-foursquare-outline:before,.ion-social-freebsd-devil:before,.ion-social-github:before,.ion-social-github-outline:before,.ion-social-google:before,.ion-social-google-outline:before,.ion-social-googleplus:before,.ion-social-googleplus-outline:before,.ion-social-hackernews:before,.ion-social-hackernews-outline:before,.ion-social-html5:before,.ion-social-html5-outline:before,.ion-social-instagram:before,.ion-social-instagram-outline:before,.ion-social-javascript:before,.ion-social-javascript-outline:before,.ion-social-linkedin:before,.ion-social-linkedin-outline:before,.ion-social-markdown:before,.ion-social-nodejs:before,.ion-social-octocat:before,.ion-social-pinterest:before,.ion-social-pinterest-outline:before,.ion-social-python:before,.ion-social-reddit:before,.ion-social-reddit-outline:before,.ion-social-rss:before,.ion-social-rss-outline:before,.ion-social-sass:before,.ion-social-skype:before,.ion-social-skype-outline:before,.ion-social-snapchat:before,.ion-social-snapchat-outline:before,.ion-social-tumblr:before,.ion-social-tumblr-outline:before,.ion-social-tux:before,.ion-social-twitch:before,.ion-social-twitch-outline:before,.ion-social-twitter:before,.ion-social-twitter-outline:before,.ion-social-usd:before,.ion-social-usd-outline:before,.ion-social-vimeo:before,.ion-social-vimeo-outline:before,.ion-social-whatsapp:before,.ion-social-whatsapp-outline:before,.ion-social-windows:before,.ion-social-windows-outline:before,.ion-social-wordpress:before,.ion-social-wordpress-outline:before,.ion-social-yahoo:before,.ion-social-yahoo-outline:before,.ion-social-yen:before,.ion-social-yen-outline:before,.ion-social-youtube:before,.ion-social-youtube-outline:before,.ion-soup-can:before,.ion-soup-can-outline:before,.ion-speakerphone:before,.ion-speedometer:before,.ion-spoon:before,.ion-star:before,.ion-stats-bars:before,.ion-steam:before,.ion-stop:before,.ion-thermometer:before,.ion-thumbsdown:before,.ion-thumbsup:before,.ion-toggle:before,.ion-toggle-filled:before,.ion-transgender:before,.ion-trash-a:before,.ion-trash-b:before,.ion-trophy:before,.ion-tshirt:before,.ion-tshirt-outline:before,.ion-umbrella:before,.ion-university:before,.ion-unlocked:before,.ion-upload:before,.ion-usb:before,.ion-videocamera:before,.ion-volume-high:before,.ion-volume-low:before,.ion-volume-medium:before,.ion-volume-mute:before,.ion-wand:before,.ion-waterdrop:before,.ion-wifi:before,.ion-wineglass:before,.ion-woman:before,.ion-wrench:before,.ion-xbox:before{display:inline-block;font-family:"Ionicons";speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;text-rendering:auto;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.ion-alert:before{content:"\f101"}.ion-alert-circled:before{content:"\f100"}.ion-android-add:before{content:"\f2c7"}.ion-android-add-circle:before{content:"\f359"}.ion-android-alarm-clock:before{content:"\f35a"}.ion-android-alert:before{content:"\f35b"}.ion-android-apps:before{content:"\f35c"}.ion-android-archive:before{content:"\f2c9"}.ion-android-arrow-back:before{content:"\f2ca"}.ion-android-arrow-down:before{content:"\f35d"}.ion-android-arrow-dropdown:before{content:"\f35f"}.ion-android-arrow-dropdown-circle:before{content:"\f35e"}.ion-android-arrow-dropleft:before{content:"\f361"}.ion-android-arrow-dropleft-circle:before{content:"\f360"}.ion-android-arrow-dropright:before{content:"\f363"}.ion-android-arrow-dropright-circle:before{content:"\f362"}.ion-android-arrow-dropup:before{content:"\f365"}.ion-android-arrow-dropup-circle:before{content:"\f364"}.ion-android-arrow-forward:before{content:"\f30f"}.ion-android-arrow-up:before{content:"\f366"}.ion-android-attach:before{content:"\f367"}.ion-android-bar:before{content:"\f368"}.ion-android-bicycle:before{content:"\f369"}.ion-android-boat:before{content:"\f36a"}.ion-android-bookmark:before{content:"\f36b"}.ion-android-bulb:before{content:"\f36c"}.ion-android-bus:before{content:"\f36d"}.ion-android-calendar:before{content:"\f2d1"}.ion-android-call:before{content:"\f2d2"}.ion-android-camera:before{content:"\f2d3"}.ion-android-cancel:before{content:"\f36e"}.ion-android-car:before{content:"\f36f"}.ion-android-cart:before{content:"\f370"}.ion-android-chat:before{content:"\f2d4"}.ion-android-checkbox:before{content:"\f374"}.ion-android-checkbox-blank:before{content:"\f371"}.ion-android-checkbox-outline:before{content:"\f373"}.ion-android-checkbox-outline-blank:before{content:"\f372"}.ion-android-checkmark-circle:before{content:"\f375"}.ion-android-clipboard:before{content:"\f376"}.ion-android-close:before{content:"\f2d7"}.ion-android-cloud:before{content:"\f37a"}.ion-android-cloud-circle:before{content:"\f377"}.ion-android-cloud-done:before{content:"\f378"}.ion-android-cloud-outline:before{content:"\f379"}.ion-android-color-palette:before{content:"\f37b"}.ion-android-compass:before{content:"\f37c"}.ion-android-contact:before{content:"\f2d8"}.ion-android-contacts:before{content:"\f2d9"}.ion-android-contract:before{content:"\f37d"}.ion-android-create:before{content:"\f37e"}.ion-android-delete:before{content:"\f37f"}.ion-android-desktop:before{content:"\f380"}.ion-android-document:before{content:"\f381"}.ion-android-done:before{content:"\f383"}.ion-android-done-all:before{content:"\f382"}.ion-android-download:before{content:"\f2dd"}.ion-android-drafts:before{content:"\f384"}.ion-android-exit:before{content:"\f385"}.ion-android-expand:before{content:"\f386"}.ion-android-favorite:before{content:"\f388"}.ion-android-favorite-outline:before{content:"\f387"}.ion-android-film:before{content:"\f389"}.ion-android-folder:before{content:"\f2e0"}.ion-android-folder-open:before{content:"\f38a"}.ion-android-funnel:before{content:"\f38b"}.ion-android-globe:before{content:"\f38c"}.ion-android-hand:before{content:"\f2e3"}.ion-android-hangout:before{content:"\f38d"}.ion-android-happy:before{content:"\f38e"}.ion-android-home:before{content:"\f38f"}.ion-android-image:before{content:"\f2e4"}.ion-android-laptop:before{content:"\f390"}.ion-android-list:before{content:"\f391"}.ion-android-locate:before{content:"\f2e9"}.ion-android-lock:before{content:"\f392"}.ion-android-mail:before{content:"\f2eb"}.ion-android-map:before{content:"\f393"}.ion-android-menu:before{content:"\f394"}.ion-android-microphone:before{content:"\f2ec"}.ion-android-microphone-off:before{content:"\f395"}.ion-android-more-horizontal:before{content:"\f396"}.ion-android-more-vertical:before{content:"\f397"}.ion-android-navigate:before{content:"\f398"}.ion-android-notifications:before{content:"\f39b"}.ion-android-notifications-none:before{content:"\f399"}.ion-android-notifications-off:before{content:"\f39a"}.ion-android-open:before{content:"\f39c"}.ion-android-options:before{content:"\f39d"}.ion-android-people:before{content:"\f39e"}.ion-android-person:before{content:"\f3a0"}.ion-android-person-add:before{content:"\f39f"}.ion-android-phone-landscape:before{content:"\f3a1"}.ion-android-phone-portrait:before{content:"\f3a2"}.ion-android-pin:before{content:"\f3a3"}.ion-android-plane:before{content:"\f3a4"}.ion-android-playstore:before{content:"\f2f0"}.ion-android-print:before{content:"\f3a5"}.ion-android-radio-button-off:before{content:"\f3a6"}.ion-android-radio-button-on:before{content:"\f3a7"}.ion-android-refresh:before{content:"\f3a8"}.ion-android-remove:before{content:"\f2f4"}.ion-android-remove-circle:before{content:"\f3a9"}.ion-android-restaurant:before{content:"\f3aa"}.ion-android-sad:before{content:"\f3ab"}.ion-android-search:before{content:"\f2f5"}.ion-android-send:before{content:"\f2f6"}.ion-android-settings:before{content:"\f2f7"}.ion-android-share:before{content:"\f2f8"}.ion-android-share-alt:before{content:"\f3ac"}.ion-android-star:before{content:"\f2fc"}.ion-android-star-half:before{content:"\f3ad"}.ion-android-star-outline:before{content:"\f3ae"}.ion-android-stopwatch:before{content:"\f2fd"}.ion-android-subway:before{content:"\f3af"}.ion-android-sunny:before{content:"\f3b0"}.ion-android-sync:before{content:"\f3b1"}.ion-android-textsms:before{content:"\f3b2"}.ion-android-time:before{content:"\f3b3"}.ion-android-train:before{content:"\f3b4"}.ion-android-unlock:before{content:"\f3b5"}.ion-android-upload:before{content:"\f3b6"}.ion-android-volume-down:before{content:"\f3b7"}.ion-android-volume-mute:before{content:"\f3b8"}.ion-android-volume-off:before{content:"\f3b9"}.ion-android-volume-up:before{content:"\f3ba"}.ion-android-walk:before{content:"\f3bb"}.ion-android-warning:before{content:"\f3bc"}.ion-android-watch:before{content:"\f3bd"}.ion-android-wifi:before{content:"\f305"}.ion-aperture:before{content:"\f313"}.ion-archive:before{content:"\f102"}.ion-arrow-down-a:before{content:"\f103"}.ion-arrow-down-b:before{content:"\f104"}.ion-arrow-down-c:before{content:"\f105"}.ion-arrow-expand:before{content:"\f25e"}.ion-arrow-graph-down-left:before{content:"\f25f"}.ion-arrow-graph-down-right:before{content:"\f260"}.ion-arrow-graph-up-left:before{content:"\f261"}.ion-arrow-graph-up-right:before{content:"\f262"}.ion-arrow-left-a:before{content:"\f106"}.ion-arrow-left-b:before{content:"\f107"}.ion-arrow-left-c:before{content:"\f108"}.ion-arrow-move:before{content:"\f263"}.ion-arrow-resize:before{content:"\f264"}.ion-arrow-return-left:before{content:"\f265"}.ion-arrow-return-right:before{content:"\f266"}.ion-arrow-right-a:before{content:"\f109"}.ion-arrow-right-b:before{content:"\f10a"}.ion-arrow-right-c:before{content:"\f10b"}.ion-arrow-shrink:before{content:"\f267"}.ion-arrow-swap:before{content:"\f268"}.ion-arrow-up-a:before{content:"\f10c"}.ion-arrow-up-b:before{content:"\f10d"}.ion-arrow-up-c:before{content:"\f10e"}.ion-asterisk:before{content:"\f314"}.ion-at:before{content:"\f10f"}.ion-backspace:before{content:"\f3bf"}.ion-backspace-outline:before{content:"\f3be"}.ion-bag:before{content:"\f110"}.ion-battery-charging:before{content:"\f111"}.ion-battery-empty:before{content:"\f112"}.ion-battery-full:before{content:"\f113"}.ion-battery-half:before{content:"\f114"}.ion-battery-low:before{content:"\f115"}.ion-beaker:before{content:"\f269"}.ion-beer:before{content:"\f26a"}.ion-bluetooth:before{content:"\f116"}.ion-bonfire:before{content:"\f315"}.ion-bookmark:before{content:"\f26b"}.ion-bowtie:before{content:"\f3c0"}.ion-briefcase:before{content:"\f26c"}.ion-bug:before{content:"\f2be"}.ion-calculator:before{content:"\f26d"}.ion-calendar:before{content:"\f117"}.ion-camera:before{content:"\f118"}.ion-card:before{content:"\f119"}.ion-cash:before{content:"\f316"}.ion-chatbox:before{content:"\f11b"}.ion-chatbox-working:before{content:"\f11a"}.ion-chatboxes:before{content:"\f11c"}.ion-chatbubble:before{content:"\f11e"}.ion-chatbubble-working:before{content:"\f11d"}.ion-chatbubbles:before{content:"\f11f"}.ion-checkmark:before{content:"\f122"}.ion-checkmark-circled:before{content:"\f120"}.ion-checkmark-round:before{content:"\f121"}.ion-chevron-down:before{content:"\f123"}.ion-chevron-left:before{content:"\f124"}.ion-chevron-right:before{content:"\f125"}.ion-chevron-up:before{content:"\f126"}.ion-clipboard:before{content:"\f127"}.ion-clock:before{content:"\f26e"}.ion-close:before{content:"\f12a"}.ion-close-circled:before{content:"\f128"}.ion-close-round:before{content:"\f129"}.ion-closed-captioning:before{content:"\f317"}.ion-cloud:before{content:"\f12b"}.ion-code:before{content:"\f271"}.ion-code-download:before{content:"\f26f"}.ion-code-working:before{content:"\f270"}.ion-coffee:before{content:"\f272"}.ion-compass:before{content:"\f273"}.ion-compose:before{content:"\f12c"}.ion-connection-bars:before{content:"\f274"}.ion-contrast:before{content:"\f275"}.ion-crop:before{content:"\f3c1"}.ion-cube:before{content:"\f318"}.ion-disc:before{content:"\f12d"}.ion-document:before{content:"\f12f"}.ion-document-text:before{content:"\f12e"}.ion-drag:before{content:"\f130"}.ion-earth:before{content:"\f276"}.ion-easel:before{content:"\f3c2"}.ion-edit:before{content:"\f2bf"}.ion-egg:before{content:"\f277"}.ion-eject:before{content:"\f131"}.ion-email:before{content:"\f132"}.ion-email-unread:before{content:"\f3c3"}.ion-erlenmeyer-flask:before{content:"\f3c5"}.ion-erlenmeyer-flask-bubbles:before{content:"\f3c4"}.ion-eye:before{content:"\f133"}.ion-eye-disabled:before{content:"\f306"}.ion-female:before{content:"\f278"}.ion-filing:before{content:"\f134"}.ion-film-marker:before{content:"\f135"}.ion-fireball:before{content:"\f319"}.ion-flag:before{content:"\f279"}.ion-flame:before{content:"\f31a"}.ion-flash:before{content:"\f137"}.ion-flash-off:before{content:"\f136"}.ion-folder:before{content:"\f139"}.ion-fork:before{content:"\f27a"}.ion-fork-repo:before{content:"\f2c0"}.ion-forward:before{content:"\f13a"}.ion-funnel:before{content:"\f31b"}.ion-gear-a:before{content:"\f13d"}.ion-gear-b:before{content:"\f13e"}.ion-grid:before{content:"\f13f"}.ion-hammer:before{content:"\f27b"}.ion-happy:before{content:"\f31c"}.ion-happy-outline:before{content:"\f3c6"}.ion-headphone:before{content:"\f140"}.ion-heart:before{content:"\f141"}.ion-heart-broken:before{content:"\f31d"}.ion-help:before{content:"\f143"}.ion-help-buoy:before{content:"\f27c"}.ion-help-circled:before{content:"\f142"}.ion-home:before{content:"\f144"}.ion-icecream:before{content:"\f27d"}.ion-image:before{content:"\f147"}.ion-images:before{content:"\f148"}.ion-information:before{content:"\f14a"}.ion-information-circled:before{content:"\f149"}.ion-ionic:before{content:"\f14b"}.ion-ios-alarm:before{content:"\f3c8"}.ion-ios-alarm-outline:before{content:"\f3c7"}.ion-ios-albums:before{content:"\f3ca"}.ion-ios-albums-outline:before{content:"\f3c9"}.ion-ios-americanfootball:before{content:"\f3cc"}.ion-ios-americanfootball-outline:before{content:"\f3cb"}.ion-ios-analytics:before{content:"\f3ce"}.ion-ios-analytics-outline:before{content:"\f3cd"}.ion-ios-arrow-back:before{content:"\f3cf"}.ion-ios-arrow-down:before{content:"\f3d0"}.ion-ios-arrow-forward:before{content:"\f3d1"}.ion-ios-arrow-left:before{content:"\f3d2"}.ion-ios-arrow-right:before{content:"\f3d3"}.ion-ios-arrow-thin-down:before{content:"\f3d4"}.ion-ios-arrow-thin-left:before{content:"\f3d5"}.ion-ios-arrow-thin-right:before{content:"\f3d6"}.ion-ios-arrow-thin-up:before{content:"\f3d7"}.ion-ios-arrow-up:before{content:"\f3d8"}.ion-ios-at:before{content:"\f3da"}.ion-ios-at-outline:before{content:"\f3d9"}.ion-ios-barcode:before{content:"\f3dc"}.ion-ios-barcode-outline:before{content:"\f3db"}.ion-ios-baseball:before{content:"\f3de"}.ion-ios-baseball-outline:before{content:"\f3dd"}.ion-ios-basketball:before{content:"\f3e0"}.ion-ios-basketball-outline:before{content:"\f3df"}.ion-ios-bell:before{content:"\f3e2"}.ion-ios-bell-outline:before{content:"\f3e1"}.ion-ios-body:before{content:"\f3e4"}.ion-ios-body-outline:before{content:"\f3e3"}.ion-ios-bolt:before{content:"\f3e6"}.ion-ios-bolt-outline:before{content:"\f3e5"}.ion-ios-book:before{content:"\f3e8"}.ion-ios-book-outline:before{content:"\f3e7"}.ion-ios-bookmarks:before{content:"\f3ea"}.ion-ios-bookmarks-outline:before{content:"\f3e9"}.ion-ios-box:before{content:"\f3ec"}.ion-ios-box-outline:before{content:"\f3eb"}.ion-ios-briefcase:before{content:"\f3ee"}.ion-ios-briefcase-outline:before{content:"\f3ed"}.ion-ios-browsers:before{content:"\f3f0"}.ion-ios-browsers-outline:before{content:"\f3ef"}.ion-ios-calculator:before{content:"\f3f2"}.ion-ios-calculator-outline:before{content:"\f3f1"}.ion-ios-calendar:before{content:"\f3f4"}.ion-ios-calendar-outline:before{content:"\f3f3"}.ion-ios-camera:before{content:"\f3f6"}.ion-ios-camera-outline:before{content:"\f3f5"}.ion-ios-cart:before{content:"\f3f8"}.ion-ios-cart-outline:before{content:"\f3f7"}.ion-ios-chatboxes:before{content:"\f3fa"}.ion-ios-chatboxes-outline:before{content:"\f3f9"}.ion-ios-chatbubble:before{content:"\f3fc"}.ion-ios-chatbubble-outline:before{content:"\f3fb"}.ion-ios-checkmark:before{content:"\f3ff"}.ion-ios-checkmark-empty:before{content:"\f3fd"}.ion-ios-checkmark-outline:before{content:"\f3fe"}.ion-ios-circle-filled:before{content:"\f400"}.ion-ios-circle-outline:before{content:"\f401"}.ion-ios-clock:before{content:"\f403"}.ion-ios-clock-outline:before{content:"\f402"}.ion-ios-close:before{content:"\f406"}.ion-ios-close-empty:before{content:"\f404"}.ion-ios-close-outline:before{content:"\f405"}.ion-ios-cloud:before{content:"\f40c"}.ion-ios-cloud-download:before{content:"\f408"}.ion-ios-cloud-download-outline:before{content:"\f407"}.ion-ios-cloud-outline:before{content:"\f409"}.ion-ios-cloud-upload:before{content:"\f40b"}.ion-ios-cloud-upload-outline:before{content:"\f40a"}.ion-ios-cloudy:before{content:"\f410"}.ion-ios-cloudy-night:before{content:"\f40e"}.ion-ios-cloudy-night-outline:before{content:"\f40d"}.ion-ios-cloudy-outline:before{content:"\f40f"}.ion-ios-cog:before{content:"\f412"}.ion-ios-cog-outline:before{content:"\f411"}.ion-ios-color-filter:before{content:"\f414"}.ion-ios-color-filter-outline:before{content:"\f413"}.ion-ios-color-wand:before{content:"\f416"}.ion-ios-color-wand-outline:before{content:"\f415"}.ion-ios-compose:before{content:"\f418"}.ion-ios-compose-outline:before{content:"\f417"}.ion-ios-contact:before{content:"\f41a"}.ion-ios-contact-outline:before{content:"\f419"}.ion-ios-copy:before{content:"\f41c"}.ion-ios-copy-outline:before{content:"\f41b"}.ion-ios-crop:before{content:"\f41e"}.ion-ios-crop-strong:before{content:"\f41d"}.ion-ios-download:before{content:"\f420"}.ion-ios-download-outline:before{content:"\f41f"}.ion-ios-drag:before{content:"\f421"}.ion-ios-email:before{content:"\f423"}.ion-ios-email-outline:before{content:"\f422"}.ion-ios-eye:before{content:"\f425"}.ion-ios-eye-outline:before{content:"\f424"}.ion-ios-fastforward:before{content:"\f427"}.ion-ios-fastforward-outline:before{content:"\f426"}.ion-ios-filing:before{content:"\f429"}.ion-ios-filing-outline:before{content:"\f428"}.ion-ios-film:before{content:"\f42b"}.ion-ios-film-outline:before{content:"\f42a"}.ion-ios-flag:before{content:"\f42d"}.ion-ios-flag-outline:before{content:"\f42c"}.ion-ios-flame:before{content:"\f42f"}.ion-ios-flame-outline:before{content:"\f42e"}.ion-ios-flask:before{content:"\f431"}.ion-ios-flask-outline:before{content:"\f430"}.ion-ios-flower:before{content:"\f433"}.ion-ios-flower-outline:before{content:"\f432"}.ion-ios-folder:before{content:"\f435"}.ion-ios-folder-outline:before{content:"\f434"}.ion-ios-football:before{content:"\f437"}.ion-ios-football-outline:before{content:"\f436"}.ion-ios-game-controller-a:before{content:"\f439"}.ion-ios-game-controller-a-outline:before{content:"\f438"}.ion-ios-game-controller-b:before{content:"\f43b"}.ion-ios-game-controller-b-outline:before{content:"\f43a"}.ion-ios-gear:before{content:"\f43d"}.ion-ios-gear-outline:before{content:"\f43c"}.ion-ios-glasses:before{content:"\f43f"}.ion-ios-glasses-outline:before{content:"\f43e"}.ion-ios-grid-view:before{content:"\f441"}.ion-ios-grid-view-outline:before{content:"\f440"}.ion-ios-heart:before{content:"\f443"}.ion-ios-heart-outline:before{content:"\f442"}.ion-ios-help:before{content:"\f446"}.ion-ios-help-empty:before{content:"\f444"}.ion-ios-help-outline:before{content:"\f445"}.ion-ios-home:before{content:"\f448"}.ion-ios-home-outline:before{content:"\f447"}.ion-ios-infinite:before{content:"\f44a"}.ion-ios-infinite-outline:before{content:"\f449"}.ion-ios-information:before{content:"\f44d"}.ion-ios-information-empty:before{content:"\f44b"}.ion-ios-information-outline:before{content:"\f44c"}.ion-ios-ionic-outline:before{content:"\f44e"}.ion-ios-keypad:before{content:"\f450"}.ion-ios-keypad-outline:before{content:"\f44f"}.ion-ios-lightbulb:before{content:"\f452"}.ion-ios-lightbulb-outline:before{content:"\f451"}.ion-ios-list:before{content:"\f454"}.ion-ios-list-outline:before{content:"\f453"}.ion-ios-location:before{content:"\f456"}.ion-ios-location-outline:before{content:"\f455"}.ion-ios-locked:before{content:"\f458"}.ion-ios-locked-outline:before{content:"\f457"}.ion-ios-loop:before{content:"\f45a"}.ion-ios-loop-strong:before{content:"\f459"}.ion-ios-medical:before{content:"\f45c"}.ion-ios-medical-outline:before{content:"\f45b"}.ion-ios-medkit:before{content:"\f45e"}.ion-ios-medkit-outline:before{content:"\f45d"}.ion-ios-mic:before{content:"\f461"}.ion-ios-mic-off:before{content:"\f45f"}.ion-ios-mic-outline:before{content:"\f460"}.ion-ios-minus:before{content:"\f464"}.ion-ios-minus-empty:before{content:"\f462"}.ion-ios-minus-outline:before{content:"\f463"}.ion-ios-monitor:before{content:"\f466"}.ion-ios-monitor-outline:before{content:"\f465"}.ion-ios-moon:before{content:"\f468"}.ion-ios-moon-outline:before{content:"\f467"}.ion-ios-more:before{content:"\f46a"}.ion-ios-more-outline:before{content:"\f469"}.ion-ios-musical-note:before{content:"\f46b"}.ion-ios-musical-notes:before{content:"\f46c"}.ion-ios-navigate:before{content:"\f46e"}.ion-ios-navigate-outline:before{content:"\f46d"}.ion-ios-nutrition:before{content:"\f470"}.ion-ios-nutrition-outline:before{content:"\f46f"}.ion-ios-paper:before{content:"\f472"}.ion-ios-paper-outline:before{content:"\f471"}.ion-ios-paperplane:before{content:"\f474"}.ion-ios-paperplane-outline:before{content:"\f473"}.ion-ios-partlysunny:before{content:"\f476"}.ion-ios-partlysunny-outline:before{content:"\f475"}.ion-ios-pause:before{content:"\f478"}.ion-ios-pause-outline:before{content:"\f477"}.ion-ios-paw:before{content:"\f47a"}.ion-ios-paw-outline:before{content:"\f479"}.ion-ios-people:before{content:"\f47c"}.ion-ios-people-outline:before{content:"\f47b"}.ion-ios-person:before{content:"\f47e"}.ion-ios-person-outline:before{content:"\f47d"}.ion-ios-personadd:before{content:"\f480"}.ion-ios-personadd-outline:before{content:"\f47f"}.ion-ios-photos:before{content:"\f482"}.ion-ios-photos-outline:before{content:"\f481"}.ion-ios-pie:before{content:"\f484"}.ion-ios-pie-outline:before{content:"\f483"}.ion-ios-pint:before{content:"\f486"}.ion-ios-pint-outline:before{content:"\f485"}.ion-ios-play:before{content:"\f488"}.ion-ios-play-outline:before{content:"\f487"}.ion-ios-plus:before{content:"\f48b"}.ion-ios-plus-empty:before{content:"\f489"}.ion-ios-plus-outline:before{content:"\f48a"}.ion-ios-pricetag:before{content:"\f48d"}.ion-ios-pricetag-outline:before{content:"\f48c"}.ion-ios-pricetags:before{content:"\f48f"}.ion-ios-pricetags-outline:before{content:"\f48e"}.ion-ios-printer:before{content:"\f491"}.ion-ios-printer-outline:before{content:"\f490"}.ion-ios-pulse:before{content:"\f493"}.ion-ios-pulse-strong:before{content:"\f492"}.ion-ios-rainy:before{content:"\f495"}.ion-ios-rainy-outline:before{content:"\f494"}.ion-ios-recording:before{content:"\f497"}.ion-ios-recording-outline:before{content:"\f496"}.ion-ios-redo:before{content:"\f499"}.ion-ios-redo-outline:before{content:"\f498"}.ion-ios-refresh:before{content:"\f49c"}.ion-ios-refresh-empty:before{content:"\f49a"}.ion-ios-refresh-outline:before{content:"\f49b"}.ion-ios-reload:before{content:"\f49d"}.ion-ios-reverse-camera:before{content:"\f49f"}.ion-ios-reverse-camera-outline:before{content:"\f49e"}.ion-ios-rewind:before{content:"\f4a1"}.ion-ios-rewind-outline:before{content:"\f4a0"}.ion-ios-rose:before{content:"\f4a3"}.ion-ios-rose-outline:before{content:"\f4a2"}.ion-ios-search:before{content:"\f4a5"}.ion-ios-search-strong:before{content:"\f4a4"}.ion-ios-settings:before{content:"\f4a7"}.ion-ios-settings-strong:before{content:"\f4a6"}.ion-ios-shuffle:before{content:"\f4a9"}.ion-ios-shuffle-strong:before{content:"\f4a8"}.ion-ios-skipbackward:before{content:"\f4ab"}.ion-ios-skipbackward-outline:before{content:"\f4aa"}.ion-ios-skipforward:before{content:"\f4ad"}.ion-ios-skipforward-outline:before{content:"\f4ac"}.ion-ios-snowy:before{content:"\f4ae"}.ion-ios-speedometer:before{content:"\f4b0"}.ion-ios-speedometer-outline:before{content:"\f4af"}.ion-ios-star:before{content:"\f4b3"}.ion-ios-star-half:before{content:"\f4b1"}.ion-ios-star-outline:before{content:"\f4b2"}.ion-ios-stopwatch:before{content:"\f4b5"}.ion-ios-stopwatch-outline:before{content:"\f4b4"}.ion-ios-sunny:before{content:"\f4b7"}.ion-ios-sunny-outline:before{content:"\f4b6"}.ion-ios-telephone:before{content:"\f4b9"}.ion-ios-telephone-outline:before{content:"\f4b8"}.ion-ios-tennisball:before{content:"\f4bb"}.ion-ios-tennisball-outline:before{content:"\f4ba"}.ion-ios-thunderstorm:before{content:"\f4bd"}.ion-ios-thunderstorm-outline:before{content:"\f4bc"}.ion-ios-time:before{content:"\f4bf"}.ion-ios-time-outline:before{content:"\f4be"}.ion-ios-timer:before{content:"\f4c1"}.ion-ios-timer-outline:before{content:"\f4c0"}.ion-ios-toggle:before{content:"\f4c3"}.ion-ios-toggle-outline:before{content:"\f4c2"}.ion-ios-trash:before{content:"\f4c5"}.ion-ios-trash-outline:before{content:"\f4c4"}.ion-ios-undo:before{content:"\f4c7"}.ion-ios-undo-outline:before{content:"\f4c6"}.ion-ios-unlocked:before{content:"\f4c9"}.ion-ios-unlocked-outline:before{content:"\f4c8"}.ion-ios-upload:before{content:"\f4cb"}.ion-ios-upload-outline:before{content:"\f4ca"}.ion-ios-videocam:before{content:"\f4cd"}.ion-ios-videocam-outline:before{content:"\f4cc"}.ion-ios-volume-high:before{content:"\f4ce"}.ion-ios-volume-low:before{content:"\f4cf"}.ion-ios-wineglass:before{content:"\f4d1"}.ion-ios-wineglass-outline:before{content:"\f4d0"}.ion-ios-world:before{content:"\f4d3"}.ion-ios-world-outline:before{content:"\f4d2"}.ion-ipad:before{content:"\f1f9"}.ion-iphone:before{content:"\f1fa"}.ion-ipod:before{content:"\f1fb"}.ion-jet:before{content:"\f295"}.ion-key:before{content:"\f296"}.ion-knife:before{content:"\f297"}.ion-laptop:before{content:"\f1fc"}.ion-leaf:before{content:"\f1fd"}.ion-levels:before{content:"\f298"}.ion-lightbulb:before{content:"\f299"}.ion-link:before{content:"\f1fe"}.ion-load-a:before{content:"\f29a"}.ion-load-b:before{content:"\f29b"}.ion-load-c:before{content:"\f29c"}.ion-load-d:before{content:"\f29d"}.ion-location:before{content:"\f1ff"}.ion-lock-combination:before{content:"\f4d4"}.ion-locked:before{content:"\f200"}.ion-log-in:before{content:"\f29e"}.ion-log-out:before{content:"\f29f"}.ion-loop:before{content:"\f201"}.ion-magnet:before{content:"\f2a0"}.ion-male:before{content:"\f2a1"}.ion-man:before{content:"\f202"}.ion-map:before{content:"\f203"}.ion-medkit:before{content:"\f2a2"}.ion-merge:before{content:"\f33f"}.ion-mic-a:before{content:"\f204"}.ion-mic-b:before{content:"\f205"}.ion-mic-c:before{content:"\f206"}.ion-minus:before{content:"\f209"}.ion-minus-circled:before{content:"\f207"}.ion-minus-round:before{content:"\f208"}.ion-model-s:before{content:"\f2c1"}.ion-monitor:before{content:"\f20a"}.ion-more:before{content:"\f20b"}.ion-mouse:before{content:"\f340"}.ion-music-note:before{content:"\f20c"}.ion-navicon:before{content:"\f20e"}.ion-navicon-round:before{content:"\f20d"}.ion-navigate:before{content:"\f2a3"}.ion-network:before{content:"\f341"}.ion-no-smoking:before{content:"\f2c2"}.ion-nuclear:before{content:"\f2a4"}.ion-outlet:before{content:"\f342"}.ion-paintbrush:before{content:"\f4d5"}.ion-paintbucket:before{content:"\f4d6"}.ion-paper-airplane:before{content:"\f2c3"}.ion-paperclip:before{content:"\f20f"}.ion-pause:before{content:"\f210"}.ion-person:before{content:"\f213"}.ion-person-add:before{content:"\f211"}.ion-person-stalker:before{content:"\f212"}.ion-pie-graph:before{content:"\f2a5"}.ion-pin:before{content:"\f2a6"}.ion-pinpoint:before{content:"\f2a7"}.ion-pizza:before{content:"\f2a8"}.ion-plane:before{content:"\f214"}.ion-planet:before{content:"\f343"}.ion-play:before{content:"\f215"}.ion-playstation:before{content:"\f30a"}.ion-plus:before{content:"\f218"}.ion-plus-circled:before{content:"\f216"}.ion-plus-round:before{content:"\f217"}.ion-podium:before{content:"\f344"}.ion-pound:before{content:"\f219"}.ion-power:before{content:"\f2a9"}.ion-pricetag:before{content:"\f2aa"}.ion-pricetags:before{content:"\f2ab"}.ion-printer:before{content:"\f21a"}.ion-pull-request:before{content:"\f345"}.ion-qr-scanner:before{content:"\f346"}.ion-quote:before{content:"\f347"}.ion-radio-waves:before{content:"\f2ac"}.ion-record:before{content:"\f21b"}.ion-refresh:before{content:"\f21c"}.ion-reply:before{content:"\f21e"}.ion-reply-all:before{content:"\f21d"}.ion-ribbon-a:before{content:"\f348"}.ion-ribbon-b:before{content:"\f349"}.ion-sad:before{content:"\f34a"}.ion-sad-outline:before{content:"\f4d7"}.ion-scissors:before{content:"\f34b"}.ion-search:before{content:"\f21f"}.ion-settings:before{content:"\f2ad"}.ion-share:before{content:"\f220"}.ion-shuffle:before{content:"\f221"}.ion-skip-backward:before{content:"\f222"}.ion-skip-forward:before{content:"\f223"}.ion-social-android:before{content:"\f225"}.ion-social-android-outline:before{content:"\f224"}.ion-social-angular:before{content:"\f4d9"}.ion-social-angular-outline:before{content:"\f4d8"}.ion-social-apple:before{content:"\f227"}.ion-social-apple-outline:before{content:"\f226"}.ion-social-bitcoin:before{content:"\f2af"}.ion-social-bitcoin-outline:before{content:"\f2ae"}.ion-social-buffer:before{content:"\f229"}.ion-social-buffer-outline:before{content:"\f228"}.ion-social-chrome:before{content:"\f4db"}.ion-social-chrome-outline:before{content:"\f4da"}.ion-social-codepen:before{content:"\f4dd"}.ion-social-codepen-outline:before{content:"\f4dc"}.ion-social-css3:before{content:"\f4df"}.ion-social-css3-outline:before{content:"\f4de"}.ion-social-designernews:before{content:"\f22b"}.ion-social-designernews-outline:before{content:"\f22a"}.ion-social-dribbble:before{content:"\f22d"}.ion-social-dribbble-outline:before{content:"\f22c"}.ion-social-dropbox:before{content:"\f22f"}.ion-social-dropbox-outline:before{content:"\f22e"}.ion-social-euro:before{content:"\f4e1"}.ion-social-euro-outline:before{content:"\f4e0"}.ion-social-facebook:before{content:"\f231"}.ion-social-facebook-outline:before{content:"\f230"}.ion-social-foursquare:before{content:"\f34d"}.ion-social-foursquare-outline:before{content:"\f34c"}.ion-social-freebsd-devil:before{content:"\f2c4"}.ion-social-github:before{content:"\f233"}.ion-social-github-outline:before{content:"\f232"}.ion-social-google:before{content:"\f34f"}.ion-social-google-outline:before{content:"\f34e"}.ion-social-googleplus:before{content:"\f235"}.ion-social-googleplus-outline:before{content:"\f234"}.ion-social-hackernews:before{content:"\f237"}.ion-social-hackernews-outline:before{content:"\f236"}.ion-social-html5:before{content:"\f4e3"}.ion-social-html5-outline:before{content:"\f4e2"}.ion-social-instagram:before{content:"\f351"}.ion-social-instagram-outline:before{content:"\f350"}.ion-social-javascript:before{content:"\f4e5"}.ion-social-javascript-outline:before{content:"\f4e4"}.ion-social-linkedin:before{content:"\f239"}.ion-social-linkedin-outline:before{content:"\f238"}.ion-social-markdown:before{content:"\f4e6"}.ion-social-nodejs:before{content:"\f4e7"}.ion-social-octocat:before{content:"\f4e8"}.ion-social-pinterest:before{content:"\f2b1"}.ion-social-pinterest-outline:before{content:"\f2b0"}.ion-social-python:before{content:"\f4e9"}.ion-social-reddit:before{content:"\f23b"}.ion-social-reddit-outline:before{content:"\f23a"}.ion-social-rss:before{content:"\f23d"}.ion-social-rss-outline:before{content:"\f23c"}.ion-social-sass:before{content:"\f4ea"}.ion-social-skype:before{content:"\f23f"}.ion-social-skype-outline:before{content:"\f23e"}.ion-social-snapchat:before{content:"\f4ec"}.ion-social-snapchat-outline:before{content:"\f4eb"}.ion-social-tumblr:before{content:"\f241"}.ion-social-tumblr-outline:before{content:"\f240"}.ion-social-tux:before{content:"\f2c5"}.ion-social-twitch:before{content:"\f4ee"}.ion-social-twitch-outline:before{content:"\f4ed"}.ion-social-twitter:before{content:"\f243"}.ion-social-twitter-outline:before{content:"\f242"}.ion-social-usd:before{content:"\f353"}.ion-social-usd-outline:before{content:"\f352"}.ion-social-vimeo:before{content:"\f245"}.ion-social-vimeo-outline:before{content:"\f244"}.ion-social-whatsapp:before{content:"\f4f0"}.ion-social-whatsapp-outline:before{content:"\f4ef"}.ion-social-windows:before{content:"\f247"}.ion-social-windows-outline:before{content:"\f246"}.ion-social-wordpress:before{content:"\f249"}.ion-social-wordpress-outline:before{content:"\f248"}.ion-social-yahoo:before{content:"\f24b"}.ion-social-yahoo-outline:before{content:"\f24a"}.ion-social-yen:before{content:"\f4f2"}.ion-social-yen-outline:before{content:"\f4f1"}.ion-social-youtube:before{content:"\f24d"}.ion-social-youtube-outline:before{content:"\f24c"}.ion-soup-can:before{content:"\f4f4"}.ion-soup-can-outline:before{content:"\f4f3"}.ion-speakerphone:before{content:"\f2b2"}.ion-speedometer:before{content:"\f2b3"}.ion-spoon:before{content:"\f2b4"}.ion-star:before{content:"\f24e"}.ion-stats-bars:before{content:"\f2b5"}.ion-steam:before{content:"\f30b"}.ion-stop:before{content:"\f24f"}.ion-thermometer:before{content:"\f2b6"}.ion-thumbsdown:before{content:"\f250"}.ion-thumbsup:before{content:"\f251"}.ion-toggle:before{content:"\f355"}.ion-toggle-filled:before{content:"\f354"}.ion-transgender:before{content:"\f4f5"}.ion-trash-a:before{content:"\f252"}.ion-trash-b:before{content:"\f253"}.ion-trophy:before{content:"\f356"}.ion-tshirt:before{content:"\f4f7"}.ion-tshirt-outline:before{content:"\f4f6"}.ion-umbrella:before{content:"\f2b7"}.ion-university:before{content:"\f357"}.ion-unlocked:before{content:"\f254"}.ion-upload:before{content:"\f255"}.ion-usb:before{content:"\f2b8"}.ion-videocamera:before{content:"\f256"}.ion-volume-high:before{content:"\f257"}.ion-volume-low:before{content:"\f258"}.ion-volume-medium:before{content:"\f259"}.ion-volume-mute:before{content:"\f25a"}.ion-wand:before{content:"\f358"}.ion-waterdrop:before{content:"\f25b"}.ion-wifi:before{content:"\f25c"}.ion-wineglass:before{content:"\f2b9"}.ion-woman:before{content:"\f25d"}.ion-wrench:before{content:"\f2ba"}.ion-xbox:before{content:"\f30c"} diff --git a/LinuxGUI/WebUI/static/css/vtoy.css b/LinuxGUI/WebUI/static/css/vtoy.css new file mode 100644 index 0000000..f9fcf4e --- /dev/null +++ b/LinuxGUI/WebUI/static/css/vtoy.css @@ -0,0 +1,357 @@ +/*loading ¶¯»­*/ +.loading { + width: 100%; + height: 100%; + position: fixed; + top:0; + left:0; + z-index: 999999; + background-color: rgba(0, 0, 0, 0); +} +.loading .title { + width: 300px; + text-align: center; + margin: 250px auto 0px; + color: #2F7095; + font-weight: 900; + font-size: 24px; +} +.loading .rectbox { + width: 150px; + height: 40px; + margin: 10px auto; +} +.loading .rectbox .title { + font-size: 14px; + font-family: 'Microsoft YaHei'; + font-weight: 900; + text-align: center; + color: rgba(68, 149, 57, 1); +} +.loading .rectbox .rect { + width: 25px; + height: 25px; + background-color: rgba(68, 149, 57, 1); + margin: 0 2px auto 3px; + float: left; + -webkit-animation: loading 0.48s infinite ease-in-out; + -o-animation: loading 0.48s infinite ease-in-out; + animation: loading 0.48s infinite ease-in-out; +} +.loading .rectbox .rect1 { + -webkit-animation-delay: 0s; + -moz-animation-delay: 0s; + -o-animation-delay: 0s; + animation-delay: 0s; +} +.loading .rectbox .rect2 { + -webkit-animation-delay: 0.12s; + -moz-animation-delay: 0.12s; + -o-animation-delay: 0.12s; + animation-delay: 0.12s; + background-color: rgba(68, 149, 57, 0.2); +} +.loading .rectbox .rect3 { + -webkit-animation-delay: 0.24s; + -moz-animation-delay: 0.24s; + -o-animation-delay: 0.24s; + animation-delay: 0.24s; + background-color: rgba(68, 149, 57, 0.4); +} +.loading .rectbox .rect4 { + -webkit-animation-delay: 0.36s; + -moz-animation-delay: 0.36s; + -o-animation-delay: 0.36s; + animation-delay: 0.36s; + background-color: rgba(68, 149, 57, 0.6); +} +.loading .rectbox .rect5 { + -webkit-animation-delay: 0.48s; + -moz-animation-delay: 0.48s; + -o-animation-delay: 0.48s; + animation-delay: 0.48s; + background-color: rgba(68, 149, 57, 0.8); +} +@keyframes loading { + 0% { + background-color: rgba(68, 149, 57, 1); + } + 25% { + background-color: rgba(68, 149, 57, 0.8); + } + 50% { + background-color: rgba(68, 149, 57, 0.6); + } + 75% { + background-color: rgba(68, 149, 57, 0.4); + } + 100% { + background-color: rgba(68, 149, 57, 0.2); + } +} +@-moz-keyframes loading { + 0% { + background-color: rgba(68, 149, 57, 1); + } + 25% { + background-color: rgba(68, 149, 57, 0.8); + } + 50% { + background-color: rgba(68, 149, 57, 0.6); + } + 75% { + background-color: rgba(68, 149, 57, 0.4); + } + 100% { + background-color: rgba(68, 149, 57, 0.2); + } +} +@-ms-keyframes loading { + 0% { + background-color: rgba(68, 149, 57, 1); + } + 25% { + background-color: rgba(68, 149, 57, 0.8); + } + 50% { + background-color: rgba(68, 149, 57, 0.6); + } + 75% { + background-color: rgba(68, 149, 57, 0.4); + } + 100% { + background-color: rgba(68, 149, 57, 0.2); + } +} +@-webkit-keyframes loading { + 0% { + background-color: rgba(68, 149, 57, 1); + } + 25% { + background-color: rgba(68, 149, 57, 0.8); + } + 50% { + background-color: rgba(68, 149, 57, 0.6); + } + 75% { + background-color: rgba(68, 149, 57, 0.4); + } + 100% { + background-color: rgba(68, 149, 57, 0.2); + } +} + +/*vtoy server is running*/ +#vtoy-main .loading { + width: 100%; + position: relative; + top:0; + left:0; + background-color: rgba(0, 0, 0, 0); +} +#vtoy-main .loading .title { + width: 300px; + text-align: center; + margin: 250px auto 0px; + color: #449539; + font-weight: 900; + font-size: 24px; +} +#vtoy-main .loading .rectbox { + width: 120px; + height: 40px; + margin: 10px auto; +} +#vtoy-main .loading .rectbox .title { + font-size: 14px; + font-family: 'Microsoft YaHei'; + font-weight: 900; + text-align: center; + color: rgba(68, 149, 57, 1); +} +#vtoy-main .loading .rectbox .rect { + width: 25px; + height: 25px; + background-color: rgba(68, 149, 57, 1); + margin: 0 2px auto 3px; + float: left; + -webkit-animation: loading 1.44s infinite ease-in-out; + -o-animation: loading 0.48s infinite ease-in-out; + animation: loading 0.48s infinite ease-in-out; +} +#vtoy-main .loading .rectbox .rect1 { + -webkit-animation-delay: 0s; + -moz-animation-delay: 0s; + -o-animation-delay: 0s; + animation-delay: 0s; +} +#vtoy-main .loading .rectbox .rect2 { + -webkit-animation-delay: 0.36s; + -moz-animation-delay: 0.12s; + -o-animation-delay: 0.12s; + animation-delay: 0.12s; + background-color: rgba(68, 149, 57, 0.2); +} +#vtoy-main .loading .rectbox .rect3 { + -webkit-animation-delay: 0.72s; + -moz-animation-delay: 0.24s; + -o-animation-delay: 0.24s; + animation-delay: 0.24s; + background-color: rgba(68, 149, 57, 0.4); +} +#vtoy-main .loading .rectbox .rect4 { + -webkit-animation-delay: 1.08s; + -moz-animation-delay: 0.36s; + -o-animation-delay: 0.36s; + animation-delay: 0.36s; + background-color: rgba(68, 149, 57, 0.6); +} +#vtoy-main .loading .rectbox .rect5 { + -webkit-animation-delay: 1.44s; + -moz-animation-delay: 0.48s; + -o-animation-delay: 0.48s; + animation-delay: 0.48s; + background-color: rgba(68, 149, 57, 0.8); +} +@keyframes running { + 0% { + background-color: rgba(68, 149, 57, 1); + } + 25% { + background-color: rgba(68, 149, 57, 0.8); + } + 50% { + background-color: rgba(68, 149, 57, 0.6); + } + 75% { + background-color: rgba(68, 149, 57, 0.4); + } + 100% { + background-color: rgba(68, 149, 57, 0.2); + } +} +@-moz-keyframes running { + 0% { + background-color: rgba(68, 149, 57, 1); + } + 25% { + background-color: rgba(68, 149, 57, 0.8); + } + 50% { + background-color: rgba(68, 149, 57, 0.6); + } + 75% { + background-color: rgba(68, 149, 57, 0.4); + } + 100% { + background-color: rgba(68, 149, 57, 0.2); + } +} +@-ms-keyframes running { + 0% { + background-color: rgba(68, 149, 57, 1); + } + 25% { + background-color: rgba(68, 149, 57, 0.8); + } + 50% { + background-color: rgba(68, 149, 57, 0.6); + } + 75% { + background-color: rgba(68, 149, 57, 0.4); + } + 100% { + background-color: rgba(68, 149, 57, 0.2); + } +} +@-webkit-keyframes running { + 0% { + background-color: rgba(68, 149, 57, 1); + } + 25% { + background-color: rgba(68, 149, 57, 0.8); + } + 50% { + background-color: rgba(68, 149, 57, 0.6); + } + 75% { + background-color: rgba(68, 149, 57, 0.4); + } + 100% { + background-color: rgba(68, 149, 57, 0.2); + } +} + + + +.loadEffect{ + width: 110px; + height: 110px; + position: relative; + margin: 0 auto; + margin-top:0 auto; +} +.loadEffect span{ + display: inline-block; + width: 20px; + height: 20px; + border-radius: 50%; + background: lightgreen; + position: absolute; + -webkit-animation: load 1.04s ease infinite; +} +@-webkit-keyframes load{ + 0%{ + opacity: 1; + } + 100%{ + opacity: 0.2; + } +} + + + + +.loadEffect span:nth-child(1){ + left: 40%; + top: -130%; + -webkit-animation-delay:0.13s; +} +.loadEffect span:nth-child(2){ + left: 90%; + top: 8%; + margin-top:-120%; + -webkit-animation-delay:0.26s; +} +.loadEffect span:nth-child(3){ + left: 110%; + top: -80%; + margin-left: %-100; + -webkit-animation-delay:0.39s; +} +.loadEffect span:nth-child(4){ + top: -40%; + left:110%; + -webkit-animation-delay:0.52s; +} +.loadEffect span:nth-child(5){ + left: 40%; + top: 0; + margin-top:10%; + -webkit-animation-delay:0.65s; +} +.loadEffect span:nth-child(6){ + left: -20%; + bottom:120%; + -webkit-animation-delay:0.78s; +} +.loadEffect span:nth-child(7){ + bottom: 160%; + left: -20%; + -webkit-animation-delay:0.91s; +} +.loadEffect span:nth-child(8){ + bottom: 200%; + left: -10%; + -webkit-animation-delay:1.04s; +} diff --git a/LinuxGUI/WebUI/static/fonts/fontawesome-webfont.ttf b/LinuxGUI/WebUI/static/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..d7994e1 Binary files /dev/null and b/LinuxGUI/WebUI/static/fonts/fontawesome-webfont.ttf differ diff --git a/LinuxGUI/WebUI/static/fonts/fontawesome-webfont.woff b/LinuxGUI/WebUI/static/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..6fd4ede Binary files /dev/null and b/LinuxGUI/WebUI/static/fonts/fontawesome-webfont.woff differ diff --git a/LinuxGUI/WebUI/static/fonts/fontawesome-webfont.woff2 b/LinuxGUI/WebUI/static/fonts/fontawesome-webfont.woff2 new file mode 100644 index 0000000..5560193 Binary files /dev/null and b/LinuxGUI/WebUI/static/fonts/fontawesome-webfont.woff2 differ diff --git a/LinuxGUI/WebUI/static/fonts/glyphicons-halflings-regular.ttf b/LinuxGUI/WebUI/static/fonts/glyphicons-halflings-regular.ttf new file mode 100644 index 0000000..1413fc6 Binary files /dev/null and b/LinuxGUI/WebUI/static/fonts/glyphicons-halflings-regular.ttf differ diff --git a/LinuxGUI/WebUI/static/fonts/glyphicons-halflings-regular.woff b/LinuxGUI/WebUI/static/fonts/glyphicons-halflings-regular.woff new file mode 100644 index 0000000..9e61285 Binary files /dev/null and b/LinuxGUI/WebUI/static/fonts/glyphicons-halflings-regular.woff differ diff --git a/LinuxGUI/WebUI/static/fonts/glyphicons-halflings-regular.woff2 b/LinuxGUI/WebUI/static/fonts/glyphicons-halflings-regular.woff2 new file mode 100644 index 0000000..64539b5 Binary files /dev/null and b/LinuxGUI/WebUI/static/fonts/glyphicons-halflings-regular.woff2 differ diff --git a/LinuxGUI/WebUI/static/fonts/ionicons.eot b/LinuxGUI/WebUI/static/fonts/ionicons.eot new file mode 100644 index 0000000..9caa348 Binary files /dev/null and b/LinuxGUI/WebUI/static/fonts/ionicons.eot differ diff --git a/LinuxGUI/WebUI/static/fonts/ionicons.ttf b/LinuxGUI/WebUI/static/fonts/ionicons.ttf new file mode 100644 index 0000000..180ce51 Binary files /dev/null and b/LinuxGUI/WebUI/static/fonts/ionicons.ttf differ diff --git a/LinuxGUI/WebUI/static/img/VentoyLogo.png b/LinuxGUI/WebUI/static/img/VentoyLogo.png new file mode 100644 index 0000000..a13884a Binary files /dev/null and b/LinuxGUI/WebUI/static/img/VentoyLogo.png differ diff --git a/LinuxGUI/WebUI/static/img/dropdown.png b/LinuxGUI/WebUI/static/img/dropdown.png new file mode 100644 index 0000000..201a4ca Binary files /dev/null and b/LinuxGUI/WebUI/static/img/dropdown.png differ diff --git a/LinuxGUI/WebUI/static/img/refresh.ico b/LinuxGUI/WebUI/static/img/refresh.ico new file mode 100644 index 0000000..c2bc338 Binary files /dev/null and b/LinuxGUI/WebUI/static/img/refresh.ico differ diff --git a/LinuxGUI/WebUI/static/js/jQuery-2.1.4.min.js b/LinuxGUI/WebUI/static/js/jQuery-2.1.4.min.js new file mode 100644 index 0000000..49990d6 --- /dev/null +++ b/LinuxGUI/WebUI/static/js/jQuery-2.1.4.min.js @@ -0,0 +1,4 @@ +/*! jQuery v2.1.4 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l=a.document,m="2.1.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)+1>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b="length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,aa=/[+~]/,ba=/'|\\/g,ca=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),da=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ea=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fa){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(ba,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+ra(o[l]);w=aa.test(a)&&pa(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",ea,!1):e.attachEvent&&e.attachEvent("onunload",ea)),p=!f(g),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?la(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ca,da),a[3]=(a[3]||a[4]||a[5]||"").replace(ca,da),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ca,da).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(ca,da),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return W.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(ca,da).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:oa(function(){return[0]}),last:oa(function(a,b){return[b-1]}),eq:oa(function(a,b,c){return[0>c?c+b:c]}),even:oa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:oa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:oa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:oa(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function sa(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function ta(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ua(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function va(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wa(a,b,c,d,e,f){return d&&!d[u]&&(d=wa(d)),e&&!e[u]&&(e=wa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ua(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:va(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=va(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=va(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sa(function(a){return a===b},h,!0),l=sa(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sa(ta(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wa(i>1&&ta(m),i>1&&ra(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xa(a.slice(i,e)),f>e&&xa(a=a.slice(e)),f>e&&ra(a))}m.push(c)}return ta(m)}function ya(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=va(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&ga.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,ya(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ca,da),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ca,da),aa.test(j[0].type)&&pa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&ra(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,aa.test(a)&&pa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+K.uid++}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){ +return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b)},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthx",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,ba=/<([\w:]+)/,ca=/<|&#?\w+;/,da=/<(?:script|style|link)/i,ea=/checked\s*(?:[^=]|=\s*.checked.)/i,fa=/^$|\/(?:java|ecma)script/i,ga=/^true\/(.*)/,ha=/^\s*\s*$/g,ia={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ia.optgroup=ia.option,ia.tbody=ia.tfoot=ia.colgroup=ia.caption=ia.thead,ia.th=ia.td;function ja(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function ka(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function la(a){var b=ga.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function ma(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function na(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function oa(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pa(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=oa(h),f=oa(a),d=0,e=f.length;e>d;d++)pa(f[d],g[d]);if(b)if(c)for(f=f||oa(a),g=g||oa(h),d=0,e=f.length;e>d;d++)na(f[d],g[d]);else na(a,h);return g=oa(h,"script"),g.length>0&&ma(g,!i&&oa(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(ca.test(e)){f=f||k.appendChild(b.createElement("div")),g=(ba.exec(e)||["",""])[1].toLowerCase(),h=ia[g]||ia._default,f.innerHTML=h[1]+e.replace(aa,"<$1>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=oa(k.appendChild(e),"script"),i&&ma(f),c)){j=0;while(e=f[j++])fa.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(oa(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&ma(oa(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(oa(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!da.test(a)&&!ia[(ba.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(aa,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(oa(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(oa(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&ea.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(oa(c,"script"),ka),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,oa(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,la),j=0;g>j;j++)h=f[j],fa.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(ha,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qa,ra={};function sa(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function ta(a){var b=l,c=ra[a];return c||(c=sa(a,b),"none"!==c&&c||(qa=(qa||n("